From 5bf6d9100772a68a1dfbf6edaabfd17d10f25126 Mon Sep 17 00:00:00 2001 From: echarp <manu@echarp.org> Date: Sun, 11 Sep 2016 17:56:34 +0200 Subject: [PATCH] Precompiled assets --- ...fest-ab661426d97300c73ef9f54813a90d69.json | 2 +- ...fest-cc0c9f43a35675d2248a689be654ce22.json | 2 +- ...244d8e144534286b6c72cecee9151938308901.css | 4 + ...d8e144534286b6c72cecee9151938308901.css.gz | Bin 0 -> 15301 bytes ...3e5f535aff487ef907952790491e39e34688a2f.js | 24677 +++++ ...f535aff487ef907952790491e39e34688a2f.js.gz | Bin 0 -> 203169 bytes ...c4dc31bd7d4489b6ad5f6331f1f42bbded33a50.js | 47 + ...c31bd7d4489b6ad5f6331f1f42bbded33a50.js.gz | Bin 0 -> 669 bytes ...33ef9b16048a46d710d6b766260ee4589d4840.css | 10 + ...f9b16048a46d710d6b766260ee4589d4840.css.gz | Bin 0 -> 32188 bytes ...933acaa65e9d2ec18d340e667afe68de5d750cc.js | 75399 ++++++++++++++++ ...acaa65e9d2ec18d340e667afe68de5d750cc.js.gz | Bin 0 -> 532298 bytes ...a9f8d6e5f41120414e0180765d28407dbdfb42d.js | 21 + ...8d6e5f41120414e0180765d28407dbdfb42d.js.gz | Bin 0 -> 552 bytes 14 files changed, 100160 insertions(+), 2 deletions(-) create mode 100644 public/assets/active_admin-5f05779513d42df8ed807ee625244d8e144534286b6c72cecee9151938308901.css create mode 100644 public/assets/active_admin-5f05779513d42df8ed807ee625244d8e144534286b6c72cecee9151938308901.css.gz create mode 100644 public/assets/active_admin-716bc3a1c121d8ebdfc555d143e5f535aff487ef907952790491e39e34688a2f.js create mode 100644 public/assets/active_admin-716bc3a1c121d8ebdfc555d143e5f535aff487ef907952790491e39e34688a2f.js.gz create mode 100644 public/assets/active_admin/application-3ee24c8b7a313a28f1352e08dc4dc31bd7d4489b6ad5f6331f1f42bbded33a50.js create mode 100644 public/assets/active_admin/application-3ee24c8b7a313a28f1352e08dc4dc31bd7d4489b6ad5f6331f1f42bbded33a50.js.gz create mode 100644 public/assets/application-2fb50a7174d540a1e61def8f3733ef9b16048a46d710d6b766260ee4589d4840.css create mode 100644 public/assets/application-2fb50a7174d540a1e61def8f3733ef9b16048a46d710d6b766260ee4589d4840.css.gz create mode 100644 public/assets/application-e0182820be578ba7db1bc56b9933acaa65e9d2ec18d340e667afe68de5d750cc.js create mode 100644 public/assets/application-e0182820be578ba7db1bc56b9933acaa65e9d2ec18d340e667afe68de5d750cc.js.gz create mode 100644 public/assets/tinymce-3c6fcceddcfff921cf167b4a7a9f8d6e5f41120414e0180765d28407dbdfb42d.js create mode 100644 public/assets/tinymce-3c6fcceddcfff921cf167b4a7a9f8d6e5f41120414e0180765d28407dbdfb42d.js.gz diff --git a/public/assets/.sprockets-manifest-ab661426d97300c73ef9f54813a90d69.json b/public/assets/.sprockets-manifest-ab661426d97300c73ef9f54813a90d69.json index ed84c27f7..476fa15c8 100644 --- a/public/assets/.sprockets-manifest-ab661426d97300c73ef9f54813a90d69.json +++ b/public/assets/.sprockets-manifest-ab661426d97300c73ef9f54813a90d69.json @@ -1 +1 @@ -{"files":{"active_admin-617b799bade586fce74b4e0121a99adb6ff69314ffc69f4e24529028a7b72538.css":{"logical_path":"active_admin.css","mtime":"2016-05-19T21:35:29+02:00","size":214498,"digest":"617b799bade586fce74b4e0121a99adb6ff69314ffc69f4e24529028a7b72538","integrity":"sha256-YXt5m63lhvznS04BIama22/2kxT/xp9OJFKQKKe3JTg="},"active_admin/nested_menu_arrow-15084d93c65c1964d7077700ea748bd2d70cfa2d4c19707c58a9c64e232dd442.gif":{"logical_path":"active_admin/nested_menu_arrow.gif","mtime":"2016-06-30T21:12:27+02:00","size":70,"digest":"15084d93c65c1964d7077700ea748bd2d70cfa2d4c19707c58a9c64e232dd442","integrity":"sha256-FQhNk8ZcGWTXB3cA6nSL0tcM+i1MGXB8WKnGTiMt1EI="},"active_admin/nested_menu_arrow_dark-7c43b8e0a5f8823875f49a093c9d7a6b374f885b6f9cc248ae9cd7e6e9b29034.gif":{"logical_path":"active_admin/nested_menu_arrow_dark.gif","mtime":"2016-06-30T21:12:27+02:00","size":70,"digest":"7c43b8e0a5f8823875f49a093c9d7a6b374f885b6f9cc248ae9cd7e6e9b29034","integrity":"sha256-fEO44KX4gjh19JoJPJ16azdPiFtvnMJIrpzX5umykDQ="},"active_admin/datepicker/datepicker-input-icon-d9c2bb73769af777c8a71720d29741f3a499aebd5a043e9a119bd0d9597aed47.png":{"logical_path":"active_admin/datepicker/datepicker-input-icon.png","mtime":"2016-06-30T21:12:27+02:00","size":1535,"digest":"d9c2bb73769af777c8a71720d29741f3a499aebd5a043e9a119bd0d9597aed47","integrity":"sha256-2cK7c3aa93fIpxcg0pdB86SZrr1aBD6aEZvQ2Vl67Uc="},"active_admin/orderable-29374dbb55b0012d78a37c614d573bb3474f0779849b478a147d0f1845ca6617.png":{"logical_path":"active_admin/orderable.png","mtime":"2016-06-30T21:12:27+02:00","size":220,"digest":"29374dbb55b0012d78a37c614d573bb3474f0779849b478a147d0f1845ca6617","integrity":"sha256-KTdNu1WwAS14o3xhTVc7s0dPB3mEm0eKFH0PGEXKZhc="},"active_admin_pagedown/wmd-buttons-c2040b12f2d6cb568ddc33587a070a29a18fed20099260c3ecbbfdbd62042f7b.png":{"logical_path":"active_admin_pagedown/wmd-buttons.png","mtime":"2016-05-04T17:49:02+02:00","size":7465,"digest":"c2040b12f2d6cb568ddc33587a070a29a18fed20099260c3ecbbfdbd62042f7b","integrity":"sha256-wgQLEvLWy1aN3DNYegcKKaGP7SAJkmDD7Lv9vWIEL3s="},"active_admin/print-cb755dcaacb896fb80d996ba6eee250ea19ee816526e5e5d0137ed2af34d08f1.css":{"logical_path":"active_admin/print.css","mtime":"2016-05-04T17:49:01+02:00","size":18961,"digest":"cb755dcaacb896fb80d996ba6eee250ea19ee816526e5e5d0137ed2af34d08f1","integrity":"sha256-y3Vdyqy4lvuA2Za6bu4lDqGe6BZSbl5dATftKvNNCPE="},"active_admin-3ac0f1eff2fd35f310a1bd2242c049f9d2cc006c7b1065541a5d855556e24393.js":{"logical_path":"active_admin.js","mtime":"2016-06-25T16:51:02+02:00","size":771406,"digest":"3ac0f1eff2fd35f310a1bd2242c049f9d2cc006c7b1065541a5d855556e24393","integrity":"sha256-OsDx7/L9NfMQob0iQsBJ+dLMAGx7EGVUGl2FVVbiQ5M="},"layers-2x-0c02a2388f637d21f86e6d4b314ec9a968e7b05ad4c3a005280a3f76c0fd3cb8.png":{"logical_path":"layers-2x.png","mtime":"2016-05-04T17:44:43+02:00","size":2898,"digest":"0c02a2388f637d21f86e6d4b314ec9a968e7b05ad4c3a005280a3f76c0fd3cb8","integrity":"sha256-DAKiOI9jfSH4bm1LMU7JqWjnsFrUw6AFKAo/dsD9PLg="},"layers-0908aa2a72a082fb2563a2427a5e4fb247571862b448b80fb6f720af1109923e.png":{"logical_path":"layers.png","mtime":"2016-05-04T17:44:43+02:00","size":1502,"digest":"0908aa2a72a082fb2563a2427a5e4fb247571862b448b80fb6f720af1109923e","integrity":"sha256-CQiqKnKggvslY6JCel5PskdXGGK0SLgPtvcgrxEJkj4="},"marker-icon-2x-454dc479e82b487529b6b93d6a9b29ac69ca7b4f5a9d5fdf8e01871f6d216113.png":{"logical_path":"marker-icon-2x.png","mtime":"2016-05-04T17:44:43+02:00","size":4033,"digest":"454dc479e82b487529b6b93d6a9b29ac69ca7b4f5a9d5fdf8e01871f6d216113","integrity":"sha256-RU3EeegrSHUptrk9apsprGnKe09anV/fjgGHH20hYRM="},"marker-icon-915e83a6fc798c599e5c9e3f759d6bc065d65151019acd0410d1f4731bcaaf72.png":{"logical_path":"marker-icon.png","mtime":"2016-05-04T17:44:43+02:00","size":1747,"digest":"915e83a6fc798c599e5c9e3f759d6bc065d65151019acd0410d1f4731bcaaf72","integrity":"sha256-kV6Dpvx5jFmeXJ4/dZ1rwGXWUVEBms0EENH0cxvKr3I="},"marker-shadow-4f340d2d61746333dffe056e074ce1704ae4e47fec5a7de98322fbdbcfcb2b6d.png":{"logical_path":"marker-shadow.png","mtime":"2016-05-04T17:44:43+02:00","size":797,"digest":"4f340d2d61746333dffe056e074ce1704ae4e47fec5a7de98322fbdbcfcb2b6d","integrity":"sha256-TzQNLWF0YzPf/gVuB0zhcErk5H/sWn3pgyL728/LK20="},"tinymce-851b4961ce4c9997bc39867507ab34eb00de363cb3aab1b32a6b1c91ebf6733b.js":{"logical_path":"tinymce.js","mtime":"2016-05-21T22:53:26+02:00","size":948,"digest":"851b4961ce4c9997bc39867507ab34eb00de363cb3aab1b32a6b1c91ebf6733b","integrity":"sha256-hRtJYc5MmZe8OYZ1B6s06wDeNjyzqrGzKmsckev2czs="},"application-ee82c1c962333e87dcfc9a0eb1abbc739ed57ba7b77732ece49ab08b6cedf706.css":{"logical_path":"application.css","mtime":"2016-05-21T19:55:46+02:00","size":548037,"digest":"ee82c1c962333e87dcfc9a0eb1abbc739ed57ba7b77732ece49ab08b6cedf706","integrity":"sha256-7oLByWIzPofc/JoOsau8c57Ve6e3dzLs5Jqwi2zt9wY="},"select2-d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8.png":{"logical_path":"select2.png","mtime":"2016-05-04T17:45:07+02:00","size":613,"digest":"d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8","integrity":"sha256-1rXY2D28GPuNd8h2HTMc2eUSPJaElQurBAbpiiSsWug="},"select2-spinner-f6ecff617ec2ba7f559e6f535cad9b70a3f91120737535dab4d4548a6c83576c.gif":{"logical_path":"select2-spinner.gif","mtime":"2016-05-04T17:45:07+02:00","size":1849,"digest":"f6ecff617ec2ba7f559e6f535cad9b70a3f91120737535dab4d4548a6c83576c","integrity":"sha256-9uz/YX7Cun9Vnm9TXK2bcKP5ESBzdTXatNRUimyDV2w="},"select2x2-6fe28d687dc0ed4d96016238c608ba1e7198c9c9accfa0b360b78018b9fb9bc2.png":{"logical_path":"select2x2.png","mtime":"2016-05-04T17:45:07+02:00","size":845,"digest":"6fe28d687dc0ed4d96016238c608ba1e7198c9c9accfa0b360b78018b9fb9bc2","integrity":"sha256-b+KNaH3A7U2WAWI4xgi6HnGYycmsz6CzYLeAGLn7m8I="},"font-awesome/fontawesome-webfont-a280856e20cc0af53390b729ca0ac3edbf8fc889a828a379c5d634c91e80c808.eot":{"logical_path":"font-awesome/fontawesome-webfont.eot","mtime":"2016-05-19T21:35:29+02:00","size":76204,"digest":"a280856e20cc0af53390b729ca0ac3edbf8fc889a828a379c5d634c91e80c808","integrity":"sha256-ooCFbiDMCvUzkLcpygrD7b+PyImoKKN5xdY0yR6AyAg="},"font-awesome/fontawesome-webfont-2932abf996373e87fbf2e950876b1962f1b57db954a1643ea68831d9fbb74da4.woff2":{"logical_path":"font-awesome/fontawesome-webfont.woff2","mtime":"2016-05-19T21:35:29+02:00","size":71760,"digest":"2932abf996373e87fbf2e950876b1962f1b57db954a1643ea68831d9fbb74da4","integrity":"sha256-KTKr+ZY3Pof78ulQh2sZYvG1fblUoWQ+pogx2fu3TaQ="},"font-awesome/fontawesome-webfont-35fa8302dd7d3d191ebb7acac543efcfa2b85a0da573b3ab45cc122ffcc45ce5.woff":{"logical_path":"font-awesome/fontawesome-webfont.woff","mtime":"2016-05-19T21:35:29+02:00","size":90144,"digest":"35fa8302dd7d3d191ebb7acac543efcfa2b85a0da573b3ab45cc122ffcc45ce5","integrity":"sha256-NfqDAt19PRkeu3rKxUPvz6K4Wg2lc7OrRcwSL/zEXOU="},"font-awesome/fontawesome-webfont-8630313bee77f64206067ed80eb6a7c721b0bbfc91c94210966969d4dcc43ba7.ttf":{"logical_path":"font-awesome/fontawesome-webfont.ttf","mtime":"2016-05-19T21:35:29+02:00","size":152364,"digest":"8630313bee77f64206067ed80eb6a7c721b0bbfc91c94210966969d4dcc43ba7","integrity":"sha256-hjAxO+539kIGBn7YDranxyGwu/yRyUIQlmlp1NzEO6c="},"font-awesome/fontawesome-webfont-6b0adce775f4d57ac800f23b05af72ced748ae51ba67a65b67b7316f1ed331b3.svg":{"logical_path":"font-awesome/fontawesome-webfont.svg","mtime":"2016-05-19T21:35:29+02:00","size":390452,"digest":"6b0adce775f4d57ac800f23b05af72ced748ae51ba67a65b67b7316f1ed331b3","integrity":"sha256-awrc53X01XrIAPI7Ba9yztdIrlG6Z6ZbZ7cxbx7TMbM="},"france-f4341a7ec8331161a9c8d5298f808014c3fc9c799b5a29ed95eb56a7f3ccd0df.png":{"logical_path":"france.png","mtime":"2014-07-04T14:08:56+02:00","size":276,"digest":"f4341a7ec8331161a9c8d5298f808014c3fc9c799b5a29ed95eb56a7f3ccd0df","integrity":"sha256-9DQafsgzEWGpyNUpj4CAFMP8nHmbWintletWp/PM0N8="},"quebec-776d563b6a4ac4312cae9f0bfe630c20711346e8dbddd41040998eba79f4b588.png":{"logical_path":"quebec.png","mtime":"2015-10-22T22:54:30+02:00","size":567,"digest":"776d563b6a4ac4312cae9f0bfe630c20711346e8dbddd41040998eba79f4b588","integrity":"sha256-d21WO2pKxDEsrp8L/mMMIHETRujb3dQQQJmOunn0tYg="},"belgique-3b8b772a522de2cbae7714b35a956faf2c394419b532a14bba982fed3f341091.png":{"logical_path":"belgique.png","mtime":"2014-07-04T14:08:56+02:00","size":187,"digest":"3b8b772a522de2cbae7714b35a956faf2c394419b532a14bba982fed3f341091","integrity":"sha256-O4t3KlIt4suudxSzWpVvryw5RBm1MqFLupgv7T80EJE="},"suisse-58d067f1c3fcdc4000fa13e95896cd5369a2b91aafd314475aa5e29da0b543d1.png":{"logical_path":"suisse.png","mtime":"2015-10-22T22:54:30+02:00","size":299,"digest":"58d067f1c3fcdc4000fa13e95896cd5369a2b91aafd314475aa5e29da0b543d1","integrity":"sha256-WNBn8cP83EAA+hPpWJbNU2miuRqv0xRHWqXinaC1Q9E="},"modernizr-654222debe8018b12f1993ceddff30dc163a7d5008d79869c399d6d167321f97.js":{"logical_path":"modernizr.js","mtime":"2016-05-04T17:44:47+02:00","size":51365,"digest":"654222debe8018b12f1993ceddff30dc163a7d5008d79869c399d6d167321f97","integrity":"sha256-ZUIi3r6AGLEvGZPO3f8w3BY6fVAI15hpw5nW0WcyH5c="},"agendadescommuns-cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6.png":{"logical_path":"agendadescommuns.png","mtime":"2015-10-22T22:54:30+02:00","size":2760,"digest":"cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6","integrity":"sha256-zUDjQgJL4Fh/jnoOOQLTLPZwCdNJtnwA9ofgSZ/en/Y="},"alert-762ace9479328243a44061346b64c4d6b997e963c68dfc6bddd9e4d241192906.png":{"logical_path":"alert.png","mtime":"2014-07-04T14:08:56+02:00","size":47876,"digest":"762ace9479328243a44061346b64c4d6b997e963c68dfc6bddd9e4d241192906","integrity":"sha256-dirOlHkygkOkQGE0a2TE1rmX6WPGjfxr3dnk0kEZKQY="},"baby_gnu_adl-ff3fa5912b3f9164dcdebca6f4fe3f4195e6dae5e3c22c8361bef1d79626ea07.png":{"logical_path":"baby_gnu_adl.png","mtime":"2015-10-22T22:54:17+02:00","size":11494,"digest":"ff3fa5912b3f9164dcdebca6f4fe3f4195e6dae5e3c22c8361bef1d79626ea07","integrity":"sha256-/z+lkSs/kWTc3rym9P4/QZXm2uXjwiyDYb7x15Ym6gc="},"communs-cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6.png":{"logical_path":"communs.png","mtime":"2015-10-22T22:54:30+02:00","size":2760,"digest":"cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6","integrity":"sha256-zUDjQgJL4Fh/jnoOOQLTLPZwCdNJtnwA9ofgSZ/en/Y="},"lef-small-160cf5b883add60c9c0f4361bd8425c75f6fb23b0e551a0b941fa0491c70e0c9.png":{"logical_path":"lef-small.png","mtime":"2015-03-29T11:07:15+02:00","size":1089,"digest":"160cf5b883add60c9c0f4361bd8425c75f6fb23b0e551a0b941fa0491c70e0c9","integrity":"sha256-Fgz1uIOt1gycD0NhvYQlx19vsjsOVRoLlB+gSRxw4Mk="},"lef-bec4081a11fbef165216827cf72c7a292ad772a77af6b8132e5bc0bbf83cb2d9.png":{"logical_path":"lef.png","mtime":"2016-01-24T11:38:05+01:00","size":8415,"digest":"bec4081a11fbef165216827cf72c7a292ad772a77af6b8132e5bc0bbf83cb2d9","integrity":"sha256-vsQIGhH77xZSFoJ89yx6KSrXcqd69rgTLlvAu/g8stk="},"priorite-logiciel-libre-je-soutiens-april_2_m-6442e454e96ed45cc1ebc40673a6c50bd286b9c28ea6a8b58572e94f7d6459fc.png":{"logical_path":"priorite-logiciel-libre-je-soutiens-april_2_m.png","mtime":"2015-10-22T22:54:30+02:00","size":16952,"digest":"6442e454e96ed45cc1ebc40673a6c50bd286b9c28ea6a8b58572e94f7d6459fc","integrity":"sha256-ZELkVOlu1FzB68QGc6bFC9KGucKOpqi1hXLpT31kWfw="},"team-cb04c7a311f7160c4eb6a281eae68be84f26991dde5d415bb4e205e6726ae275.png":{"logical_path":"team.png","mtime":"2014-07-04T14:08:56+02:00","size":3586,"digest":"cb04c7a311f7160c4eb6a281eae68be84f26991dde5d415bb4e205e6726ae275","integrity":"sha256-ywTHoxH3FgxOtqKB6uaL6E8mmR3eXUFbtOIF5nJq4nU="},"application-917844760c88ae708837ec664e229eebbd170afbde3cc0b9af7b37164545505d.js":{"logical_path":"application.js","mtime":"2016-05-21T22:53:26+02:00","size":2159880,"digest":"917844760c88ae708837ec664e229eebbd170afbde3cc0b9af7b37164545505d","integrity":"sha256-kXhEdgyIrnCIN+xmTiKe670XCvvePMC5r3s3FkVFUF0="},"active_admin/application-50ffc9f86e474cd52ffb7ce3b3572255ad6646ea17097a056f330b540eae402c.js":{"logical_path":"active_admin/application.js","mtime":"2016-05-04T17:49:01+02:00","size":1669,"digest":"50ffc9f86e474cd52ffb7ce3b3572255ad6646ea17097a056f330b540eae402c","integrity":"sha256-UP/J+G5HTNUv+3zjs1ciVa1mRuoXCXoFbzMLVA6uQCw="},"active_admin-68bb37e1af32798e8006da86254602580978bf587ad01d5ae98b3c8eedd8bca9.css":{"logical_path":"active_admin.css","mtime":"2016-05-21T23:41:15+02:00","size":214474,"digest":"68bb37e1af32798e8006da86254602580978bf587ad01d5ae98b3c8eedd8bca9","integrity":"sha256-aLs34a8yeY6ABtqGJUYCWAl4v1h60B1a6Ys8ju3YvKk="},"tinymce-c13c6df7f00dbbdc85771e880b8e9abf2f439376b72f484cd1d397bd6b68e96d.js":{"logical_path":"tinymce.js","mtime":"2016-05-21T23:41:15+02:00","size":944,"digest":"c13c6df7f00dbbdc85771e880b8e9abf2f439376b72f484cd1d397bd6b68e96d","integrity":"sha256-wTxt9/ANu9yFdx6IC46avy9Dk3a3L0hM0dOXvWto6W0="},"application-6670b0eea8f83814e96dbe243e5b8d2407e1db887d5495c5f02add0132ecf236.css":{"logical_path":"application.css","mtime":"2016-05-21T23:41:15+02:00","size":547833,"digest":"6670b0eea8f83814e96dbe243e5b8d2407e1db887d5495c5f02add0132ecf236","integrity":"sha256-ZnCw7qj4OBTpbb4kPluNJAfh24h9VJXF8CrdATLs8jY="},"application-45b9025ce219a47bb28597daeac0f5656ad0e16f5546c42f01dd4644a0f1c23c.js":{"logical_path":"application.js","mtime":"2016-05-21T23:41:15+02:00","size":2159860,"digest":"45b9025ce219a47bb28597daeac0f5656ad0e16f5546c42f01dd4644a0f1c23c","integrity":"sha256-RbkCXOIZpHuyhZfa6sD1ZWrQ4W9VRsQvAd1GRKDxwjw="},"markers-matte-497826545a90e09a240504d14530eba45823b19fd44175e09e27c47cd822ddb9.png":{"logical_path":"markers-matte.png","mtime":"2016-05-21T23:41:15+02:00","size":14323,"digest":"497826545a90e09a240504d14530eba45823b19fd44175e09e27c47cd822ddb9","integrity":"sha256-SXgmVFqQ4JokBQTRRTDrpFgjsZ/UQXXgnifEfNgi3bk="},"markers-matte@2x-948fc8c4426f04f60964ed20394247f45b0b60e575d02398b9b6810e7a29a823.png":{"logical_path":"markers-matte@2x.png","mtime":"2016-05-21T23:41:15+02:00","size":31113,"digest":"948fc8c4426f04f60964ed20394247f45b0b60e575d02398b9b6810e7a29a823","integrity":"sha256-lI/IxEJvBPYJZO0gOUJH9FsLYOV10COYubaBDnopqCM="},"markers-plain-cf233423aa44e75ac0031e77b8ba571cd3331010517e1197e63fb7b06856c1ff.png":{"logical_path":"markers-plain.png","mtime":"2016-05-21T23:41:15+02:00","size":7946,"digest":"cf233423aa44e75ac0031e77b8ba571cd3331010517e1197e63fb7b06856c1ff","integrity":"sha256-zyM0I6pE51rAAx53uLpXHNMzEBBRfhGX5j+3sGhWwf8="},"markers-shadow-8703a2262710f5e3d29e65d2acdf90d6512e159e119d27b8234731d8a6208a20.png":{"logical_path":"markers-shadow.png","mtime":"2016-05-21T23:41:15+02:00","size":535,"digest":"8703a2262710f5e3d29e65d2acdf90d6512e159e119d27b8234731d8a6208a20","integrity":"sha256-hwOiJicQ9ePSnmXSrN+Q1lEuFZ4RnSe4I0cx2KYgiiA="},"markers-shadow@2x-b21a536be27313fb504f69f5899ff0b1245b276571769ac08d6c32c35676e47a.png":{"logical_path":"markers-shadow@2x.png","mtime":"2016-05-21T23:41:15+02:00","size":1469,"digest":"b21a536be27313fb504f69f5899ff0b1245b276571769ac08d6c32c35676e47a","integrity":"sha256-shpTa+JzE/tQT2n1iZ/wsSRbJ2VxdprAjWwyw1Z25Ho="},"markers-soft-e78784e4ed70aaffddd73c315fab590233cc4e7b72388d7dd47a14796fc7c739.png":{"logical_path":"markers-soft.png","mtime":"2016-05-21T23:41:15+02:00","size":41226,"digest":"e78784e4ed70aaffddd73c315fab590233cc4e7b72388d7dd47a14796fc7c739","integrity":"sha256-54eE5O1wqv/d1zwxX6tZAjPMTntyOI191HoUeW/Hxzk="},"markers-soft@2x-c1e77253a8bfbe30cec24885d7046f443b76ebb66f4c961f77083b03f4a5cbaf.png":{"logical_path":"markers-soft@2x.png","mtime":"2016-05-21T23:41:15+02:00","size":66408,"digest":"c1e77253a8bfbe30cec24885d7046f443b76ebb66f4c961f77083b03f4a5cbaf","integrity":"sha256-wedyU6i/vjDOwkiF1wRvRDt267ZvTJYfdwg7A/Sly68="},"webshims/shims/jpicker/images/AlphaBar-34d23568a887827c654ed2ac63ed3857a2cbd690643c471ea4b21c08a1568454.png":{"logical_path":"webshims/shims/jpicker/images/AlphaBar.png","mtime":"2016-05-04T17:48:59+02:00","size":1622,"digest":"34d23568a887827c654ed2ac63ed3857a2cbd690643c471ea4b21c08a1568454","integrity":"sha256-NNI1aKiHgnxlTtKsY+04V6LL1pBkPEcepLIcCKFWhFQ="},"webshims/shims/jpicker/images/Bars-a697469b1a3828d81b3bdaf334ade0637dd6adf9bf45859aeb88a6ffc06b009f.png":{"logical_path":"webshims/shims/jpicker/images/Bars.png","mtime":"2016-05-04T17:48:59+02:00","size":1347,"digest":"a697469b1a3828d81b3bdaf334ade0637dd6adf9bf45859aeb88a6ffc06b009f","integrity":"sha256-ppdGmxo4KNgbO9rzNK3gY33Wrfm/RYWa64im/8BrAJ8="},"webshims/shims/jpicker/images/Maps-538873f6da4e3a26cd5bb92f305f01e0ca0680cd08d488aef3e1eb250d77a968.png":{"logical_path":"webshims/shims/jpicker/images/Maps.png","mtime":"2016-05-04T17:48:59+02:00","size":62011,"digest":"538873f6da4e3a26cd5bb92f305f01e0ca0680cd08d488aef3e1eb250d77a968","integrity":"sha256-U4hz9tpOOibNW7kvMF8B4MoGgM0I1Iiu8+HrJQ13qWg="},"webshims/shims/jpicker/images/NoColor-d266c220953f0b4fe96aeb868b82148e4c2ad380b1ed04d29214602851204e86.png":{"logical_path":"webshims/shims/jpicker/images/NoColor.png","mtime":"2016-05-04T17:48:59+02:00","size":491,"digest":"d266c220953f0b4fe96aeb868b82148e4c2ad380b1ed04d29214602851204e86","integrity":"sha256-0mbCIJU/C0/pauuGi4IUjkwq04Cx7QTSkhRgKFEgToY="},"webshims/shims/jpicker/images/bar-opacity-690f9f36c78c2ebdfe7510739082dd835cc940565b794617a2bcaf93a566d938.png":{"logical_path":"webshims/shims/jpicker/images/bar-opacity.png","mtime":"2016-05-04T17:48:59+02:00","size":96,"digest":"690f9f36c78c2ebdfe7510739082dd835cc940565b794617a2bcaf93a566d938","integrity":"sha256-aQ+fNseMLr3+dRBzkILdg1zJQFZbeUYXoryvk6Vm2Tg="},"webshims/shims/jpicker/images/map-opacity-00182478b4fc3dedc97b9d2c46d9917f82c321110cab01e0f2ad4725978c2fd3.png":{"logical_path":"webshims/shims/jpicker/images/map-opacity.png","mtime":"2016-05-04T17:48:59+02:00","size":139,"digest":"00182478b4fc3dedc97b9d2c46d9917f82c321110cab01e0f2ad4725978c2fd3","integrity":"sha256-ABgkeLT8Pe3Je50sRtmRf4LDIREMqwHg8q1HJZeML9M="},"webshims/shims/jpicker/images/mappoint-25687420458d1f31e399b1bc5a25e95a6dce8b898ed7f9d4361ff6cb430a7c45.gif":{"logical_path":"webshims/shims/jpicker/images/mappoint.gif","mtime":"2016-05-04T17:48:59+02:00","size":93,"digest":"25687420458d1f31e399b1bc5a25e95a6dce8b898ed7f9d4361ff6cb430a7c45","integrity":"sha256-JWh0IEWNHzHjmbG8WiXpWm3Oi4mO1/nUNh/2y0MKfEU="},"webshims/shims/jpicker/images/picker-3aa5592f4e753f0244866a40b9c48fced398d219b8bc5ee76d2d51f9f952c9b2.gif":{"logical_path":"webshims/shims/jpicker/images/picker.gif","mtime":"2016-05-04T17:48:59+02:00","size":146,"digest":"3aa5592f4e753f0244866a40b9c48fced398d219b8bc5ee76d2d51f9f952c9b2","integrity":"sha256-OqVZL051PwJEhmpAucSPztOY0hm4vF7nbS1R+flSybI="},"webshims/shims/jpicker/images/preview-opacity-12751bd440befc7037806e0451e2a2a8577655e3de1b702a2b50514ba2e9628d.png":{"logical_path":"webshims/shims/jpicker/images/preview-opacity.png","mtime":"2016-05-04T17:48:59+02:00","size":79,"digest":"12751bd440befc7037806e0451e2a2a8577655e3de1b702a2b50514ba2e9628d","integrity":"sha256-EnUb1EC+/HA3gG4EUeKiqFd2VePeG3AqK1BRS6LpYo0="},"webshims/shims/jpicker/images/rangearrows-d13aa5195095eb2e0d990d488ff4c5ed65052e6065d709463c97ed0d25cf652b.gif":{"logical_path":"webshims/shims/jpicker/images/rangearrows.gif","mtime":"2016-05-04T17:48:59+02:00","size":76,"digest":"d13aa5195095eb2e0d990d488ff4c5ed65052e6065d709463c97ed0d25cf652b","integrity":"sha256-0TqlGVCV6y4NmQ1Ij/TF7WUFLmBl1wlGPJftDSXPZSs="},"webshims/shims/styles/color-picker-2141bfffae7d9714b5260735c338beb44ed24c5982f267fc1e3158ac4b82079f.png":{"logical_path":"webshims/shims/styles/color-picker.png","mtime":"2016-05-04T17:48:59+02:00","size":338,"digest":"2141bfffae7d9714b5260735c338beb44ed24c5982f267fc1e3158ac4b82079f","integrity":"sha256-IUG//659lxS1Jgc1wzi+tE7STFmC8mf8HjFYrEuCB58="},"webshims/shims/styles/progress-8023960ce5bc957d1f0014859a51e55b9a3ce180bfd3d214a1a0629e2608a446.gif":{"logical_path":"webshims/shims/styles/progress.gif","mtime":"2016-05-04T17:48:59+02:00","size":35832,"digest":"8023960ce5bc957d1f0014859a51e55b9a3ce180bfd3d214a1a0629e2608a446","integrity":"sha256-gCOWDOW8lX0fABSFmlHlW5o84YC/09IUoaBiniYIpEY="},"webshims/shims/styles/progress-a9f7c78ea64c14559c7e683daaba141f50fac42e68e88232e416ca21645d0139.png":{"logical_path":"webshims/shims/styles/progress.png","mtime":"2016-05-04T17:48:59+02:00","size":299,"digest":"a9f7c78ea64c14559c7e683daaba141f50fac42e68e88232e416ca21645d0139","integrity":"sha256-qffHjqZMFFWcfmg9qroUH1D6xC5o6IIy5BbKIWRdATk="},"webshims/shims/styles/transparent-384a16eed212e680374ad9b8529fb3de3422e515b2e10fdc18d7afdba59a1fa9.png":{"logical_path":"webshims/shims/styles/transparent.png","mtime":"2016-05-04T17:48:59+02:00","size":93,"digest":"384a16eed212e680374ad9b8529fb3de3422e515b2e10fdc18d7afdba59a1fa9","integrity":"sha256-OEoW7tIS5oA3Stm4Up+z3jQi5RWy4Q/cGNev26WaH6k="},"jquery-ui/ui-bg_flat_0_aaaaaa_40x100-9a8492a580bf85d3e98ae8861fbd45567e5a1f83eeafcf9574da0399d5f602ab.png":{"logical_path":"jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png","mtime":"2016-05-04T17:48:40+02:00","size":180,"digest":"9a8492a580bf85d3e98ae8861fbd45567e5a1f83eeafcf9574da0399d5f602ab","integrity":"sha256-moSSpYC/hdPpiuiGH71FVn5aH4Pur8+VdNoDmdX2Aqs="},"jquery-ui/ui-bg_flat_75_ffffff_40x100-39ab7ccd9f4e82579da78a9241265df288d8eb65dbbd7cf48aed2d0129887df5.png":{"logical_path":"jquery-ui/ui-bg_flat_75_ffffff_40x100.png","mtime":"2016-05-04T17:48:40+02:00","size":178,"digest":"39ab7ccd9f4e82579da78a9241265df288d8eb65dbbd7cf48aed2d0129887df5","integrity":"sha256-Oat8zZ9Ogledp4qSQSZd8ojY62XbvXz0iu0tASmIffU="},"jquery-ui/ui-bg_glass_55_fbf9ee_1x400-691597e8a40a891ea94d3589976ecfc33e6145c49422443b00ac2b5a0022964c.png":{"logical_path":"jquery-ui/ui-bg_glass_55_fbf9ee_1x400.png","mtime":"2016-05-04T17:48:40+02:00","size":120,"digest":"691597e8a40a891ea94d3589976ecfc33e6145c49422443b00ac2b5a0022964c","integrity":"sha256-aRWX6KQKiR6pTTWJl27Pwz5hRcSUIkQ7AKwrWgAilkw="},"jquery-ui/ui-bg_glass_65_ffffff_1x400-f0e6cd91b837d5c5644d026e5ffeccd907953317cd5c0f689901733afda260b2.png":{"logical_path":"jquery-ui/ui-bg_glass_65_ffffff_1x400.png","mtime":"2016-05-04T17:48:40+02:00","size":105,"digest":"f0e6cd91b837d5c5644d026e5ffeccd907953317cd5c0f689901733afda260b2","integrity":"sha256-8ObNkbg31cVkTQJuX/7M2QeVMxfNXA9omQFzOv2iYLI="},"jquery-ui/ui-bg_glass_75_dadada_1x400-c108f5cbf2dd9ec07a26530695ddd95e1664597ce6c056ae44c162cc2e28cec4.png":{"logical_path":"jquery-ui/ui-bg_glass_75_dadada_1x400.png","mtime":"2016-05-04T17:48:40+02:00","size":111,"digest":"c108f5cbf2dd9ec07a26530695ddd95e1664597ce6c056ae44c162cc2e28cec4","integrity":"sha256-wQj1y/LdnsB6JlMGld3ZXhZkWXzmwFauRMFizC4ozsQ="},"jquery-ui/ui-bg_glass_75_e6e6e6_1x400-ddf5dd4e0ef2b185e8bb0af7b6e90ebe74a84384cb4700658e76e754c8bfe550.png":{"logical_path":"jquery-ui/ui-bg_glass_75_e6e6e6_1x400.png","mtime":"2016-05-04T17:48:40+02:00","size":110,"digest":"ddf5dd4e0ef2b185e8bb0af7b6e90ebe74a84384cb4700658e76e754c8bfe550","integrity":"sha256-3fXdTg7ysYXouwr3tukOvnSoQ4TLRwBljnbnVMi/5VA="},"jquery-ui/ui-bg_glass_95_fef1ec_1x400-f6f1c1bedf1a0f37cfef81d12f5f012869d1ee7c984775a569827a1784d34f5c.png":{"logical_path":"jquery-ui/ui-bg_glass_95_fef1ec_1x400.png","mtime":"2016-05-04T17:48:40+02:00","size":119,"digest":"f6f1c1bedf1a0f37cfef81d12f5f012869d1ee7c984775a569827a1784d34f5c","integrity":"sha256-9vHBvt8aDzfP74HRL18BKGnR7nyYR3WlaYJ6F4TTT1w="},"jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100-54270656df079c4da5182629a080fc633b6f84b87985eb016d25a560e2c38d4a.png":{"logical_path":"jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100.png","mtime":"2016-05-04T17:48:40+02:00","size":101,"digest":"54270656df079c4da5182629a080fc633b6f84b87985eb016d25a560e2c38d4a","integrity":"sha256-VCcGVt8HnE2lGCYpoID8YztvhLh5hesBbSWlYOLDjUo="},"jquery-ui/ui-icons_222222_256x240-57adb0d65f4e91dacfee975d9574422bee7486c8a182d60133728c672f2cdbbc.png":{"logical_path":"jquery-ui/ui-icons_222222_256x240.png","mtime":"2016-05-04T17:48:40+02:00","size":4369,"digest":"57adb0d65f4e91dacfee975d9574422bee7486c8a182d60133728c672f2cdbbc","integrity":"sha256-V62w1l9OkdrP7pddlXRCK+50hsihgtYBM3KMZy8s27w="},"jquery-ui/ui-icons_2e83ff_256x240-20f8c6667afc48aa433ee9eb6d8a0584bdbd6b4a4a9091ff1e6b3adb31e63bd9.png":{"logical_path":"jquery-ui/ui-icons_2e83ff_256x240.png","mtime":"2016-05-04T17:48:40+02:00","size":4369,"digest":"20f8c6667afc48aa433ee9eb6d8a0584bdbd6b4a4a9091ff1e6b3adb31e63bd9","integrity":"sha256-IPjGZnr8SKpDPunrbYoFhL29a0pKkJH/Hms62zHmO9k="},"jquery-ui/ui-icons_454545_256x240-07460e843c3e59aaadbb34231e699e856a2980753c7a47b66447da5d9f93fb7f.png":{"logical_path":"jquery-ui/ui-icons_454545_256x240.png","mtime":"2016-05-04T17:48:40+02:00","size":4369,"digest":"07460e843c3e59aaadbb34231e699e856a2980753c7a47b66447da5d9f93fb7f","integrity":"sha256-B0YOhDw+WaqtuzQjHmmehWopgHU8eke2ZEfaXZ+T+38="},"jquery-ui/ui-icons_888888_256x240-ea2e29625de3463465e93b002b065f5833e05b97f7a052b1c141e754d62e1a8b.png":{"logical_path":"jquery-ui/ui-icons_888888_256x240.png","mtime":"2016-05-04T17:48:40+02:00","size":4369,"digest":"ea2e29625de3463465e93b002b065f5833e05b97f7a052b1c141e754d62e1a8b","integrity":"sha256-6i4pYl3jRjRl6TsAKwZfWDPgW5f3oFKxwUHnVNYuGos="},"jquery-ui/ui-icons_cd0a0a_256x240-1e32c6dbf5d3fd342f27a78aa881550d6412aa207f48468724a6a15402b6041b.png":{"logical_path":"jquery-ui/ui-icons_cd0a0a_256x240.png","mtime":"2016-05-04T17:48:40+02:00","size":4369,"digest":"1e32c6dbf5d3fd342f27a78aa881550d6412aa207f48468724a6a15402b6041b","integrity":"sha256-HjLG2/XT/TQvJ6eKqIFVDWQSqiB/SEaHJKahVAK2BBs="},"tinymce-fce402ebf88064abbd8dc3ed0f0453c56500af684973911190523a24fd61befe.js":{"logical_path":"tinymce.js","mtime":"2016-05-22T00:16:21+02:00","size":944,"digest":"fce402ebf88064abbd8dc3ed0f0453c56500af684973911190523a24fd61befe","integrity":"sha256-/OQC6/iAZKu9jcPtDwRTxWUAr2hJc5ERkFI6JP1hvv4="},"application-d75ab3978be89f2612f0a6d34ebc36e5ff5906daaebebbf9d3e573ca27ad3421.css":{"logical_path":"application.css","mtime":"2016-05-22T00:16:21+02:00","size":548005,"digest":"d75ab3978be89f2612f0a6d34ebc36e5ff5906daaebebbf9d3e573ca27ad3421","integrity":"sha256-11qzl4vonyYS8KbTTrw25f9ZBtquvrv50+VzyietNCE="},"application-32637c5100b1bc8172748b0f9e886308afa905fdd8a0dbd35edc470682db9ce5.js":{"logical_path":"application.js","mtime":"2016-05-22T00:16:21+02:00","size":2159876,"digest":"32637c5100b1bc8172748b0f9e886308afa905fdd8a0dbd35edc470682db9ce5","integrity":"sha256-MmN8UQCxvIFydIsPnohjCK+pBf3YoNvTXtxHBoLbnOU="},"tinymce-981ca10e0cd26c1cc43bd7da0e8a43ced615d0b581f0a9e787cb269fc5a18099.js":{"logical_path":"tinymce.js","mtime":"2016-05-22T00:36:19+02:00","size":944,"digest":"981ca10e0cd26c1cc43bd7da0e8a43ced615d0b581f0a9e787cb269fc5a18099","integrity":"sha256-mByhDgzSbBzEO9faDopDztYV0LWB8Knnh8smn8WhgJk="},"application-99aba05d4f4b6154b108e3700a9a23d7b51b4c2e2c105bfc6ae63c9096a7673c.css":{"logical_path":"application.css","mtime":"2016-05-22T00:36:19+02:00","size":548162,"digest":"99aba05d4f4b6154b108e3700a9a23d7b51b4c2e2c105bfc6ae63c9096a7673c","integrity":"sha256-maugXU9LYVSxCONwCpoj17UbTC4sEFv8auY8kJanZzw="},"application-581c2f0ac27ca40e0308e3833791ce974d41aeaf75764d213928a691390d80ab.js":{"logical_path":"application.js","mtime":"2016-05-22T01:11:38+02:00","size":2160236,"digest":"581c2f0ac27ca40e0308e3833791ce974d41aeaf75764d213928a691390d80ab","integrity":"sha256-WBwvCsJ8pA4DCOODN5HOl01Brq91dk0hOSimkTkNgKs="},"application-a6c4db9b7bd87ad8f4f5f63ab3fce13c0237f4c78cb41140f9dcda4bc55cdcb0.js":{"logical_path":"application.js","mtime":"2016-05-22T01:22:14+02:00","size":2160516,"digest":"a6c4db9b7bd87ad8f4f5f63ab3fce13c0237f4c78cb41140f9dcda4bc55cdcb0","integrity":"sha256-psTbm3vYetj09fY6s/zhPAI39MeMtBFA+dzaS8Vc3LA="},"tinymce-c20f43bdccff8dec0a1ef3d13599f10779df6cd30cab663df34da817bc5383a6.js":{"logical_path":"tinymce.js","mtime":"2016-05-23T01:40:02+02:00","size":948,"digest":"c20f43bdccff8dec0a1ef3d13599f10779df6cd30cab663df34da817bc5383a6","integrity":"sha256-wg9Dvcz/jewKHvPRNZnxB3nfbNMMq2Y9802oF7xTg6Y="},"application-c34c3ba2010790dceea8b71dba0bf37f4895c79e2154218b2d7759d721fa1e59.css":{"logical_path":"application.css","mtime":"2016-05-23T01:40:02+02:00","size":548387,"digest":"c34c3ba2010790dceea8b71dba0bf37f4895c79e2154218b2d7759d721fa1e59","integrity":"sha256-w0w7ogEHkNzuqLcdugvzf0iVx54hVCGLLXdZ1yH6Hlk="},"application-12583549f910cb38404c7ed07661ca2eadbdea267cd3955575a8caffcca548bc.js":{"logical_path":"application.js","mtime":"2016-05-23T01:40:02+02:00","size":2160403,"digest":"12583549f910cb38404c7ed07661ca2eadbdea267cd3955575a8caffcca548bc","integrity":"sha256-Elg1SfkQyzhATH7QdmHKLq296iZ805VVdajK/8ylSLw="},"active_admin-bf38e2138315a470aef9b840765c137a33b1520312a5ef0a981c39addb52fbfb.css":{"logical_path":"active_admin.css","mtime":"2016-05-21T23:41:15+02:00","size":78112,"digest":"bf38e2138315a470aef9b840765c137a33b1520312a5ef0a981c39addb52fbfb","integrity":"sha256-vzjiE4MVpHCu+bhAdlwTejOxUgMSpe8KmBw5rdtS+/s="},"active_admin/print-87c5ffc1d869a919123bcc1dc5ec51b20bc79fd9aeab9eed77e3438c6acd4f68.css":{"logical_path":"active_admin/print.css","mtime":"2016-06-30T21:12:27+02:00","size":5494,"digest":"87c5ffc1d869a919123bcc1dc5ec51b20bc79fd9aeab9eed77e3438c6acd4f68","integrity":"sha256-h8X/wdhpqRkSO8wdxexRsgvHn9muq57td+NDjGrNT2g="},"tinymce-14411a8837640541cea84f572fa1c80fb639542b1155d7bb7b8d4820c6922b66.js":{"logical_path":"tinymce.js","mtime":"2016-06-25T16:51:02+02:00","size":944,"digest":"14411a8837640541cea84f572fa1c80fb639542b1155d7bb7b8d4820c6922b66","integrity":"sha256-FEEaiDdkBUHOqE9XL6HID7Y5VCsRVde7e41IIMaSK2Y="},"application-77ec43cc8949cbfe2e51114c6ca77a85624e6e817085cda6b03e46d9ebebdf25.css":{"logical_path":"application.css","mtime":"2016-07-02T17:04:13+02:00","size":147481,"digest":"77ec43cc8949cbfe2e51114c6ca77a85624e6e817085cda6b03e46d9ebebdf25","integrity":"sha256-d+xDzIlJy/4uURFMbKd6hWJOboFwhc2msD5G2evr3yU="},"application-2ff7281f89f0b69873f09aa96b2121b67d5c245d6be100b00998783e84d58f2d.js":{"logical_path":"application.js","mtime":"2016-06-25T16:51:02+02:00","size":2171260,"digest":"2ff7281f89f0b69873f09aa96b2121b67d5c245d6be100b00998783e84d58f2d","integrity":"sha256-L/coH4nwtphz8JqpayEhtn1cJF1r4QCwCZh4PoTVjy0="},"active_admin-5f668089bbe1957cd779eb439f2df899e5d66673d34ac94110e73ef0ac0e7313.css":{"logical_path":"active_admin.css","mtime":"2016-06-30T21:12:27+02:00","size":78116,"digest":"5f668089bbe1957cd779eb439f2df899e5d66673d34ac94110e73ef0ac0e7313","integrity":"sha256-X2aAibvhlXzXeetDny34meXWZnPTSslBEOc+8KwOcxM="},"active_admin-c99e2b41c14fcaa52c6ca770ae578392abc42e237158ed560ad73d118e502350.js":{"logical_path":"active_admin.js","mtime":"2016-07-02T17:04:13+02:00","size":780523,"digest":"c99e2b41c14fcaa52c6ca770ae578392abc42e237158ed560ad73d118e502350","integrity":"sha256-yZ4rQcFPyqUsbKdwrleDkqvELiNxWO1WCtc9EY5QI1A="},"tinymce-962059b7c757a94ab7ec4ee03bad9a9c4b565a3939172b7c307c72aa4b5ffefb.js":{"logical_path":"tinymce.js","mtime":"2016-07-02T17:04:13+02:00","size":971,"digest":"962059b7c757a94ab7ec4ee03bad9a9c4b565a3939172b7c307c72aa4b5ffefb","integrity":"sha256-liBZt8dXqUq37E7gO62anEtWWjk5Fyt8MHxyqktf/vs="},"baby_gnu_adl-232caf355c30740d5d9b30491887cd546b8849b33ca9bdb6cc71f8a47ea61815.png":{"logical_path":"baby_gnu_adl.png","mtime":"2016-07-02T16:52:58+02:00","size":10155,"digest":"232caf355c30740d5d9b30491887cd546b8849b33ca9bdb6cc71f8a47ea61815","integrity":"sha256-IyyvNVwwdA1dmzBJGIfNVGuISbM8qb22zHH4pH6mGBU="},"baby_gnu_adl-97251005d3225cf1d58b8c497d6b7905dbc9560cc8acd50118fcce60d0a2679e.svg":{"logical_path":"baby_gnu_adl.svg","mtime":"2016-07-02T16:52:57+02:00","size":109635,"digest":"97251005d3225cf1d58b8c497d6b7905dbc9560cc8acd50118fcce60d0a2679e","integrity":"sha256-lyUQBdMiXPHVi4xJfWt5BdvJVgzIrNUBGPzOYNCiZ54="},"application-307219623ded8fdc9ee285ad85d84051e026d5bfc9ff99ad749c917ab9dfcc76.js":{"logical_path":"application.js","mtime":"2016-07-02T17:04:13+02:00","size":2179851,"digest":"307219623ded8fdc9ee285ad85d84051e026d5bfc9ff99ad749c917ab9dfcc76","integrity":"sha256-MHIZYj3tj9ye4oWthdhAUeAm1b/J/5mtdJyRernfzHY="},"tinymce/jquery.tinymce.js":{"logical_path":"tinymce/jquery.tinymce.js","mtime":"2016-06-16T20:47:48+02:00","size":3591,"digest":null},"tinymce/langs/readme.md":{"logical_path":"tinymce/langs/readme.md","mtime":"2016-06-16T20:47:48+02:00","size":151,"digest":null},"tinymce/license.txt":{"logical_path":"tinymce/license.txt","mtime":"2016-06-16T20:47:48+02:00","size":26427,"digest":null},"tinymce/plugins/advlist/plugin.js":{"logical_path":"tinymce/plugins/advlist/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1303,"digest":null},"tinymce/plugins/anchor/plugin.js":{"logical_path":"tinymce/plugins/anchor/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":616,"digest":null},"tinymce/plugins/autolink/plugin.js":{"logical_path":"tinymce/plugins/autolink/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1961,"digest":null},"tinymce/plugins/autoresize/plugin.js":{"logical_path":"tinymce/plugins/autoresize/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1903,"digest":null},"tinymce/plugins/autosave/plugin.js":{"logical_path":"tinymce/plugins/autosave/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":2185,"digest":null},"tinymce/plugins/bbcode/plugin.js":{"logical_path":"tinymce/plugins/bbcode/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":3136,"digest":null},"tinymce/plugins/charmap/plugin.js":{"logical_path":"tinymce/plugins/charmap/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":8194,"digest":null},"tinymce/plugins/code/plugin.js":{"logical_path":"tinymce/plugins/code/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":721,"digest":null},"tinymce/plugins/codesample/css/prism.css":{"logical_path":"tinymce/plugins/codesample/css/prism.css","mtime":"2016-06-16T20:47:48+02:00","size":2289,"digest":null},"tinymce/plugins/codesample/plugin.js":{"logical_path":"tinymce/plugins/codesample/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":20002,"digest":null},"tinymce/plugins/colorpicker/plugin.js":{"logical_path":"tinymce/plugins/colorpicker/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1222,"digest":null},"tinymce/plugins/contextmenu/plugin.js":{"logical_path":"tinymce/plugins/contextmenu/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":891,"digest":null},"tinymce/plugins/directionality/plugin.js":{"logical_path":"tinymce/plugins/directionality/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":726,"digest":null},"tinymce/plugins/emoticons/img/smiley-cool.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-cool.gif","mtime":"2016-06-16T20:47:48+02:00","size":354,"digest":null},"tinymce/plugins/emoticons/img/smiley-cry.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-cry.gif","mtime":"2016-06-16T20:47:48+02:00","size":329,"digest":null},"tinymce/plugins/emoticons/img/smiley-embarassed.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-embarassed.gif","mtime":"2016-06-16T20:47:48+02:00","size":331,"digest":null},"tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif","mtime":"2016-06-16T20:47:48+02:00","size":342,"digest":null},"tinymce/plugins/emoticons/img/smiley-frown.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-frown.gif","mtime":"2016-06-16T20:47:48+02:00","size":340,"digest":null},"tinymce/plugins/emoticons/img/smiley-innocent.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-innocent.gif","mtime":"2016-06-16T20:47:48+02:00","size":336,"digest":null},"tinymce/plugins/emoticons/img/smiley-kiss.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-kiss.gif","mtime":"2016-06-16T20:47:48+02:00","size":338,"digest":null},"tinymce/plugins/emoticons/img/smiley-laughing.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-laughing.gif","mtime":"2016-06-16T20:47:48+02:00","size":343,"digest":null},"tinymce/plugins/emoticons/img/smiley-money-mouth.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-money-mouth.gif","mtime":"2016-06-16T20:47:48+02:00","size":321,"digest":null},"tinymce/plugins/emoticons/img/smiley-sealed.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-sealed.gif","mtime":"2016-06-16T20:47:48+02:00","size":323,"digest":null},"tinymce/plugins/emoticons/img/smiley-smile.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-smile.gif","mtime":"2016-06-16T20:47:48+02:00","size":344,"digest":null},"tinymce/plugins/emoticons/img/smiley-surprised.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-surprised.gif","mtime":"2016-06-16T20:47:48+02:00","size":338,"digest":null},"tinymce/plugins/emoticons/img/smiley-tongue-out.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-tongue-out.gif","mtime":"2016-06-16T20:47:48+02:00","size":328,"digest":null},"tinymce/plugins/emoticons/img/smiley-undecided.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-undecided.gif","mtime":"2016-06-16T20:47:48+02:00","size":337,"digest":null},"tinymce/plugins/emoticons/img/smiley-wink.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-wink.gif","mtime":"2016-06-16T20:47:48+02:00","size":350,"digest":null},"tinymce/plugins/emoticons/img/smiley-yell.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-yell.gif","mtime":"2016-06-16T20:47:48+02:00","size":336,"digest":null},"tinymce/plugins/emoticons/plugin.js":{"logical_path":"tinymce/plugins/emoticons/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":911,"digest":null},"tinymce/plugins/example/dialog.html":{"logical_path":"tinymce/plugins/example/dialog.html","mtime":"2016-06-16T20:47:48+02:00","size":213,"digest":null},"tinymce/plugins/example/plugin.js":{"logical_path":"tinymce/plugins/example/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":658,"digest":null},"tinymce/plugins/example_dependency/plugin.js":{"logical_path":"tinymce/plugins/example_dependency/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":73,"digest":null},"tinymce/plugins/fullpage/plugin.js":{"logical_path":"tinymce/plugins/fullpage/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":6291,"digest":null},"tinymce/plugins/fullscreen/plugin.js":{"logical_path":"tinymce/plugins/fullscreen/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1676,"digest":null},"tinymce/plugins/hr/plugin.js":{"logical_path":"tinymce/plugins/hr/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":322,"digest":null},"tinymce/plugins/image/plugin.js":{"logical_path":"tinymce/plugins/image/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":8169,"digest":null},"tinymce/plugins/imagetools/plugin.js":{"logical_path":"tinymce/plugins/imagetools/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":29669,"digest":null},"tinymce/plugins/importcss/plugin.js":{"logical_path":"tinymce/plugins/importcss/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":2223,"digest":null},"tinymce/plugins/insertdatetime/plugin.js":{"logical_path":"tinymce/plugins/insertdatetime/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1978,"digest":null},"tinymce/plugins/layer/plugin.js":{"logical_path":"tinymce/plugins/layer/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":2857,"digest":null},"tinymce/plugins/legacyoutput/plugin.js":{"logical_path":"tinymce/plugins/legacyoutput/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":3263,"digest":null},"tinymce/plugins/link/plugin.js":{"logical_path":"tinymce/plugins/link/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":4517,"digest":null},"tinymce/plugins/lists/plugin.js":{"logical_path":"tinymce/plugins/lists/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":8578,"digest":null},"tinymce/plugins/media/moxieplayer.swf":{"logical_path":"tinymce/plugins/media/moxieplayer.swf","mtime":"2016-06-16T20:47:48+02:00","size":20017,"digest":null},"tinymce/plugins/media/plugin.js":{"logical_path":"tinymce/plugins/media/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":11696,"digest":null},"tinymce/plugins/nonbreaking/plugin.js":{"logical_path":"tinymce/plugins/nonbreaking/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":655,"digest":null},"tinymce/plugins/noneditable/plugin.js":{"logical_path":"tinymce/plugins/noneditable/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1126,"digest":null},"tinymce/plugins/pagebreak/plugin.js":{"logical_path":"tinymce/plugins/pagebreak/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1230,"digest":null},"tinymce/plugins/paste/plugin.js":{"logical_path":"tinymce/plugins/paste/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":16286,"digest":null},"tinymce/plugins/preview/plugin.js":{"logical_path":"tinymce/plugins/preview/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1602,"digest":null},"tinymce/plugins/print/plugin.js":{"logical_path":"tinymce/plugins/print/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":293,"digest":null},"tinymce/plugins/save/plugin.js":{"logical_path":"tinymce/plugins/save/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1156,"digest":null},"tinymce/plugins/searchreplace/plugin.js":{"logical_path":"tinymce/plugins/searchreplace/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":6493,"digest":null},"tinymce/plugins/spellchecker/plugin.js":{"logical_path":"tinymce/plugins/spellchecker/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":9781,"digest":null},"tinymce/plugins/tabfocus/plugin.js":{"logical_path":"tinymce/plugins/tabfocus/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1270,"digest":null},"tinymce/plugins/table/plugin.js":{"logical_path":"tinymce/plugins/table/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":42808,"digest":null},"tinymce/plugins/template/plugin.js":{"logical_path":"tinymce/plugins/template/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":4445,"digest":null},"tinymce/plugins/textcolor/plugin.js":{"logical_path":"tinymce/plugins/textcolor/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":4145,"digest":null},"tinymce/plugins/textpattern/plugin.js":{"logical_path":"tinymce/plugins/textpattern/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":2751,"digest":null},"tinymce/plugins/visualblocks/css/visualblocks.css":{"logical_path":"tinymce/plugins/visualblocks/css/visualblocks.css","mtime":"2016-06-16T20:47:48+02:00","size":5092,"digest":null},"tinymce/plugins/visualblocks/plugin.js":{"logical_path":"tinymce/plugins/visualblocks/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1153,"digest":null},"tinymce/plugins/visualchars/plugin.js":{"logical_path":"tinymce/plugins/visualchars/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1259,"digest":null},"tinymce/plugins/wordcount/plugin.js":{"logical_path":"tinymce/plugins/wordcount/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":928,"digest":null},"tinymce/skins/lightgray/content.inline.min.css":{"logical_path":"tinymce/skins/lightgray/content.inline.min.css","mtime":"2016-06-16T20:47:48+02:00","size":2676,"digest":null},"tinymce/skins/lightgray/content.min.css":{"logical_path":"tinymce/skins/lightgray/content.min.css","mtime":"2016-06-16T20:47:48+02:00","size":3091,"digest":null},"tinymce/skins/lightgray/fonts/tinymce-small.eot":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce-small.eot","mtime":"2016-06-16T20:47:48+02:00","size":9492,"digest":null},"tinymce/skins/lightgray/fonts/tinymce-small.svg":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce-small.svg","mtime":"2016-06-16T20:47:48+02:00","size":24727,"digest":null},"tinymce/skins/lightgray/fonts/tinymce-small.ttf":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce-small.ttf","mtime":"2016-06-16T20:47:48+02:00","size":9304,"digest":null},"tinymce/skins/lightgray/fonts/tinymce-small.woff":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce-small.woff","mtime":"2016-06-16T20:47:48+02:00","size":9380,"digest":null},"tinymce/skins/lightgray/fonts/tinymce.eot":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce.eot","mtime":"2016-06-16T20:47:48+02:00","size":17292,"digest":null},"tinymce/skins/lightgray/fonts/tinymce.svg":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce.svg","mtime":"2016-06-16T20:47:48+02:00","size":45226,"digest":null},"tinymce/skins/lightgray/fonts/tinymce.ttf":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce.ttf","mtime":"2016-06-16T20:47:48+02:00","size":17128,"digest":null},"tinymce/skins/lightgray/fonts/tinymce.woff":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce.woff","mtime":"2016-06-16T20:47:48+02:00","size":17204,"digest":null},"tinymce/skins/lightgray/img/anchor.gif":{"logical_path":"tinymce/skins/lightgray/img/anchor.gif","mtime":"2016-06-16T20:47:48+02:00","size":53,"digest":null},"tinymce/skins/lightgray/img/loader.gif":{"logical_path":"tinymce/skins/lightgray/img/loader.gif","mtime":"2016-06-16T20:47:48+02:00","size":2608,"digest":null},"tinymce/skins/lightgray/img/object.gif":{"logical_path":"tinymce/skins/lightgray/img/object.gif","mtime":"2016-06-16T20:47:48+02:00","size":152,"digest":null},"tinymce/skins/lightgray/img/trans.gif":{"logical_path":"tinymce/skins/lightgray/img/trans.gif","mtime":"2016-06-16T20:47:48+02:00","size":43,"digest":null},"tinymce/skins/lightgray/skin.ie7.min.css":{"logical_path":"tinymce/skins/lightgray/skin.ie7.min.css","mtime":"2016-06-16T20:47:48+02:00","size":32423,"digest":null},"tinymce/skins/lightgray/skin.min.css":{"logical_path":"tinymce/skins/lightgray/skin.min.css","mtime":"2016-06-16T20:47:48+02:00","size":34503,"digest":null},"tinymce/themes/modern/theme.js":{"logical_path":"tinymce/themes/modern/theme.js","mtime":"2016-06-16T20:47:48+02:00","size":9923,"digest":null},"tinymce/tinymce.js":{"logical_path":"tinymce/tinymce.js","mtime":"2016-06-16T20:47:48+02:00","size":380255,"digest":null},"tinymce/langs/ar.js":{"logical_path":"tinymce/langs/ar.js","mtime":"2016-05-04T17:48:54+02:00","size":17775,"digest":null},"tinymce/langs/ar_SA.js":{"logical_path":"tinymce/langs/ar_SA.js","mtime":"2016-05-04T17:48:54+02:00","size":10002,"digest":null},"tinymce/langs/az.js":{"logical_path":"tinymce/langs/az.js","mtime":"2016-05-04T17:48:54+02:00","size":9679,"digest":null},"tinymce/langs/be.js":{"logical_path":"tinymce/langs/be.js","mtime":"2016-05-04T17:48:54+02:00","size":21063,"digest":null},"tinymce/langs/bg_BG.js":{"logical_path":"tinymce/langs/bg_BG.js","mtime":"2016-05-04T17:48:54+02:00","size":23944,"digest":null},"tinymce/langs/bn_BD.js":{"logical_path":"tinymce/langs/bn_BD.js","mtime":"2016-05-04T17:48:54+02:00","size":6845,"digest":null},"tinymce/langs/bs.js":{"logical_path":"tinymce/langs/bs.js","mtime":"2016-05-04T17:48:54+02:00","size":6969,"digest":null},"tinymce/langs/ca.js":{"logical_path":"tinymce/langs/ca.js","mtime":"2016-05-04T17:48:54+02:00","size":7786,"digest":null},"tinymce/langs/cs.js":{"logical_path":"tinymce/langs/cs.js","mtime":"2016-05-04T17:48:54+02:00","size":8750,"digest":null},"tinymce/langs/cs_CZ.js":{"logical_path":"tinymce/langs/cs_CZ.js","mtime":"2016-05-04T17:48:54+02:00","size":8398,"digest":null},"tinymce/langs/cy.js":{"logical_path":"tinymce/langs/cy.js","mtime":"2016-05-04T17:48:54+02:00","size":6141,"digest":null},"tinymce/langs/da.js":{"logical_path":"tinymce/langs/da.js","mtime":"2016-05-04T17:48:54+02:00","size":7512,"digest":null},"tinymce/langs/de.js":{"logical_path":"tinymce/langs/de.js","mtime":"2016-05-04T17:48:54+02:00","size":8279,"digest":null},"tinymce/langs/de_AT.js":{"logical_path":"tinymce/langs/de_AT.js","mtime":"2016-05-04T17:48:54+02:00","size":8307,"digest":null},"tinymce/langs/dv.js":{"logical_path":"tinymce/langs/dv.js","mtime":"2016-05-04T17:48:54+02:00","size":18099,"digest":null},"tinymce/langs/el.js":{"logical_path":"tinymce/langs/el.js","mtime":"2016-05-04T17:48:54+02:00","size":22972,"digest":null},"tinymce/langs/en_CA.js":{"logical_path":"tinymce/langs/en_CA.js","mtime":"2016-05-04T17:48:54+02:00","size":6915,"digest":null},"tinymce/langs/en_GB.js":{"logical_path":"tinymce/langs/en_GB.js","mtime":"2016-05-04T17:48:54+02:00","size":5906,"digest":null},"tinymce/langs/eo.js":{"logical_path":"tinymce/langs/eo.js","mtime":"2016-05-04T17:48:54+02:00","size":7465,"digest":null},"tinymce/langs/es.js":{"logical_path":"tinymce/langs/es.js","mtime":"2016-05-04T17:48:54+02:00","size":7808,"digest":null},"tinymce/langs/es_MX.js":{"logical_path":"tinymce/langs/es_MX.js","mtime":"2016-05-04T17:48:54+02:00","size":7893,"digest":null},"tinymce/langs/et.js":{"logical_path":"tinymce/langs/et.js","mtime":"2016-05-04T17:48:54+02:00","size":7783,"digest":null},"tinymce/langs/eu.js":{"logical_path":"tinymce/langs/eu.js","mtime":"2016-05-04T17:48:54+02:00","size":7010,"digest":null},"tinymce/langs/fa.js":{"logical_path":"tinymce/langs/fa.js","mtime":"2016-05-04T17:48:54+02:00","size":16461,"digest":null},"tinymce/langs/fa_IR.js":{"logical_path":"tinymce/langs/fa_IR.js","mtime":"2016-05-04T17:48:54+02:00","size":17724,"digest":null},"tinymce/langs/fi.js":{"logical_path":"tinymce/langs/fi.js","mtime":"2016-05-04T17:48:54+02:00","size":8142,"digest":null},"tinymce/langs/fo.js":{"logical_path":"tinymce/langs/fo.js","mtime":"2016-05-04T17:48:54+02:00","size":8043,"digest":null},"tinymce/langs/fr_CH.js":{"logical_path":"tinymce/langs/fr_CH.js","mtime":"2016-05-04T17:48:54+02:00","size":8073,"digest":null},"tinymce/langs/fr_FR.js":{"logical_path":"tinymce/langs/fr_FR.js","mtime":"2016-05-04T17:48:54+02:00","size":8008,"digest":null},"tinymce/langs/ga.js":{"logical_path":"tinymce/langs/ga.js","mtime":"2016-05-04T17:48:54+02:00","size":8590,"digest":null},"tinymce/langs/gd.js":{"logical_path":"tinymce/langs/gd.js","mtime":"2016-05-04T17:48:54+02:00","size":8807,"digest":null},"tinymce/langs/gl.js":{"logical_path":"tinymce/langs/gl.js","mtime":"2016-05-04T17:48:54+02:00","size":7065,"digest":null},"tinymce/langs/he_IL.js":{"logical_path":"tinymce/langs/he_IL.js","mtime":"2016-05-04T17:48:54+02:00","size":16080,"digest":null},"tinymce/langs/hi_IN.js":{"logical_path":"tinymce/langs/hi_IN.js","mtime":"2016-05-04T17:48:54+02:00","size":18457,"digest":null},"tinymce/langs/hr.js":{"logical_path":"tinymce/langs/hr.js","mtime":"2016-05-04T17:48:54+02:00","size":7576,"digest":null},"tinymce/langs/hu_HU.js":{"logical_path":"tinymce/langs/hu_HU.js","mtime":"2016-05-04T17:48:54+02:00","size":9409,"digest":null},"tinymce/langs/hy.js":{"logical_path":"tinymce/langs/hy.js","mtime":"2016-05-04T17:48:54+02:00","size":20374,"digest":null},"tinymce/langs/id.js":{"logical_path":"tinymce/langs/id.js","mtime":"2016-05-04T17:48:54+02:00","size":7140,"digest":null},"tinymce/langs/is_IS.js":{"logical_path":"tinymce/langs/is_IS.js","mtime":"2016-05-04T17:48:54+02:00","size":7927,"digest":null},"tinymce/langs/it.js":{"logical_path":"tinymce/langs/it.js","mtime":"2016-05-04T17:48:54+02:00","size":7597,"digest":null},"tinymce/langs/ja.js":{"logical_path":"tinymce/langs/ja.js","mtime":"2016-05-04T17:48:54+02:00","size":12289,"digest":null},"tinymce/langs/ka_GE.js":{"logical_path":"tinymce/langs/ka_GE.js","mtime":"2016-05-04T17:48:54+02:00","size":21283,"digest":null},"tinymce/langs/kab.js":{"logical_path":"tinymce/langs/kab.js","mtime":"2016-05-04T17:48:54+02:00","size":7390,"digest":null},"tinymce/langs/kk.js":{"logical_path":"tinymce/langs/kk.js","mtime":"2016-05-04T17:48:54+02:00","size":16680,"digest":null},"tinymce/langs/km_KH.js":{"logical_path":"tinymce/langs/km_KH.js","mtime":"2016-05-04T17:48:54+02:00","size":21395,"digest":null},"tinymce/langs/ko.js":{"logical_path":"tinymce/langs/ko.js","mtime":"2016-05-04T17:48:54+02:00","size":10104,"digest":null},"tinymce/langs/ko_KR.js":{"logical_path":"tinymce/langs/ko_KR.js","mtime":"2016-05-04T17:48:54+02:00","size":10004,"digest":null},"tinymce/langs/ku.js":{"logical_path":"tinymce/langs/ku.js","mtime":"2016-05-04T17:48:54+02:00","size":18273,"digest":null},"tinymce/langs/ku_IQ.js":{"logical_path":"tinymce/langs/ku_IQ.js","mtime":"2016-05-04T17:48:54+02:00","size":18363,"digest":null},"tinymce/langs/lb.js":{"logical_path":"tinymce/langs/lb.js","mtime":"2016-05-04T17:48:54+02:00","size":7466,"digest":null},"tinymce/langs/lt.js":{"logical_path":"tinymce/langs/lt.js","mtime":"2016-05-04T17:48:54+02:00","size":8898,"digest":null},"tinymce/langs/lv.js":{"logical_path":"tinymce/langs/lv.js","mtime":"2016-05-04T17:48:54+02:00","size":8281,"digest":null},"tinymce/langs/mk_MK.js":{"logical_path":"tinymce/langs/mk_MK.js","mtime":"2016-05-04T17:48:54+02:00","size":18732,"digest":null},"tinymce/langs/ml.js":{"logical_path":"tinymce/langs/ml.js","mtime":"2016-05-04T17:48:54+02:00","size":7338,"digest":null},"tinymce/langs/ml_IN.js":{"logical_path":"tinymce/langs/ml_IN.js","mtime":"2016-05-04T17:48:54+02:00","size":20018,"digest":null},"tinymce/langs/mn_MN.js":{"logical_path":"tinymce/langs/mn_MN.js","mtime":"2016-05-04T17:48:54+02:00","size":6876,"digest":null},"tinymce/langs/nb_NO.js":{"logical_path":"tinymce/langs/nb_NO.js","mtime":"2016-05-04T17:48:54+02:00","size":7527,"digest":null},"tinymce/langs/nl.js":{"logical_path":"tinymce/langs/nl.js","mtime":"2016-05-04T17:48:54+02:00","size":7234,"digest":null},"tinymce/langs/pl.js":{"logical_path":"tinymce/langs/pl.js","mtime":"2016-05-04T17:48:54+02:00","size":8128,"digest":null},"tinymce/langs/pt_BR.js":{"logical_path":"tinymce/langs/pt_BR.js","mtime":"2016-05-04T17:48:54+02:00","size":8001,"digest":null},"tinymce/langs/pt_PT.js":{"logical_path":"tinymce/langs/pt_PT.js","mtime":"2016-05-04T17:48:54+02:00","size":8144,"digest":null},"tinymce/langs/ro.js":{"logical_path":"tinymce/langs/ro.js","mtime":"2016-05-04T17:48:54+02:00","size":8274,"digest":null},"tinymce/langs/ru.js":{"logical_path":"tinymce/langs/ru.js","mtime":"2016-05-04T17:48:54+02:00","size":22289,"digest":null},"tinymce/langs/ru_RU.js":{"logical_path":"tinymce/langs/ru_RU.js","mtime":"2016-05-04T17:48:54+02:00","size":4954,"digest":null},"tinymce/langs/si_LK.js":{"logical_path":"tinymce/langs/si_LK.js","mtime":"2016-05-04T17:48:54+02:00","size":15855,"digest":null},"tinymce/langs/sk.js":{"logical_path":"tinymce/langs/sk.js","mtime":"2016-05-04T17:48:54+02:00","size":8957,"digest":null},"tinymce/langs/sl_SI.js":{"logical_path":"tinymce/langs/sl_SI.js","mtime":"2016-05-04T17:48:54+02:00","size":7038,"digest":null},"tinymce/langs/sr.js":{"logical_path":"tinymce/langs/sr.js","mtime":"2016-05-04T17:48:54+02:00","size":6335,"digest":null},"tinymce/langs/sv_SE.js":{"logical_path":"tinymce/langs/sv_SE.js","mtime":"2016-05-04T17:48:54+02:00","size":7495,"digest":null},"tinymce/langs/ta.js":{"logical_path":"tinymce/langs/ta.js","mtime":"2016-05-04T17:48:54+02:00","size":22616,"digest":null},"tinymce/langs/ta_IN.js":{"logical_path":"tinymce/langs/ta_IN.js","mtime":"2016-05-04T17:48:54+02:00","size":22619,"digest":null},"tinymce/langs/tg.js":{"logical_path":"tinymce/langs/tg.js","mtime":"2016-05-04T17:48:54+02:00","size":18182,"digest":null},"tinymce/langs/th_TH.js":{"logical_path":"tinymce/langs/th_TH.js","mtime":"2016-05-04T17:48:54+02:00","size":17296,"digest":null},"tinymce/langs/tr.js":{"logical_path":"tinymce/langs/tr.js","mtime":"2016-05-04T17:48:54+02:00","size":8704,"digest":null},"tinymce/langs/tr_TR.js":{"logical_path":"tinymce/langs/tr_TR.js","mtime":"2016-05-04T17:48:54+02:00","size":8140,"digest":null},"tinymce/langs/tt.js":{"logical_path":"tinymce/langs/tt.js","mtime":"2016-05-04T17:48:54+02:00","size":19034,"digest":null},"tinymce/langs/ug.js":{"logical_path":"tinymce/langs/ug.js","mtime":"2016-05-04T17:48:54+02:00","size":16887,"digest":null},"tinymce/langs/uk.js":{"logical_path":"tinymce/langs/uk.js","mtime":"2016-05-04T17:48:54+02:00","size":22263,"digest":null},"tinymce/langs/uk_UA.js":{"logical_path":"tinymce/langs/uk_UA.js","mtime":"2016-05-04T17:48:54+02:00","size":21690,"digest":null},"tinymce/langs/vi.js":{"logical_path":"tinymce/langs/vi.js","mtime":"2016-05-04T17:48:54+02:00","size":9900,"digest":null},"tinymce/langs/vi_VN.js":{"logical_path":"tinymce/langs/vi_VN.js","mtime":"2016-05-04T17:48:54+02:00","size":9898,"digest":null},"tinymce/langs/zh_CN.js":{"logical_path":"tinymce/langs/zh_CN.js","mtime":"2016-05-04T17:48:54+02:00","size":8482,"digest":null},"tinymce/langs/zh_TW.js":{"logical_path":"tinymce/langs/zh_TW.js","mtime":"2016-05-04T17:48:54+02:00","size":9378,"digest":null}},"assets":{"active_admin.css":"active_admin-5f668089bbe1957cd779eb439f2df899e5d66673d34ac94110e73ef0ac0e7313.css","active_admin/nested_menu_arrow.gif":"active_admin/nested_menu_arrow-15084d93c65c1964d7077700ea748bd2d70cfa2d4c19707c58a9c64e232dd442.gif","active_admin/nested_menu_arrow_dark.gif":"active_admin/nested_menu_arrow_dark-7c43b8e0a5f8823875f49a093c9d7a6b374f885b6f9cc248ae9cd7e6e9b29034.gif","active_admin/datepicker/datepicker-input-icon.png":"active_admin/datepicker/datepicker-input-icon-d9c2bb73769af777c8a71720d29741f3a499aebd5a043e9a119bd0d9597aed47.png","active_admin/orderable.png":"active_admin/orderable-29374dbb55b0012d78a37c614d573bb3474f0779849b478a147d0f1845ca6617.png","active_admin_pagedown/wmd-buttons.png":"active_admin_pagedown/wmd-buttons-c2040b12f2d6cb568ddc33587a070a29a18fed20099260c3ecbbfdbd62042f7b.png","active_admin/print.css":"active_admin/print-87c5ffc1d869a919123bcc1dc5ec51b20bc79fd9aeab9eed77e3438c6acd4f68.css","active_admin.js":"active_admin-c99e2b41c14fcaa52c6ca770ae578392abc42e237158ed560ad73d118e502350.js","layers-2x.png":"layers-2x-0c02a2388f637d21f86e6d4b314ec9a968e7b05ad4c3a005280a3f76c0fd3cb8.png","layers.png":"layers-0908aa2a72a082fb2563a2427a5e4fb247571862b448b80fb6f720af1109923e.png","marker-icon-2x.png":"marker-icon-2x-454dc479e82b487529b6b93d6a9b29ac69ca7b4f5a9d5fdf8e01871f6d216113.png","marker-icon.png":"marker-icon-915e83a6fc798c599e5c9e3f759d6bc065d65151019acd0410d1f4731bcaaf72.png","marker-shadow.png":"marker-shadow-4f340d2d61746333dffe056e074ce1704ae4e47fec5a7de98322fbdbcfcb2b6d.png","tinymce.js":"tinymce-962059b7c757a94ab7ec4ee03bad9a9c4b565a3939172b7c307c72aa4b5ffefb.js","application.css":"application-77ec43cc8949cbfe2e51114c6ca77a85624e6e817085cda6b03e46d9ebebdf25.css","select2.png":"select2-d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8.png","select2-spinner.gif":"select2-spinner-f6ecff617ec2ba7f559e6f535cad9b70a3f91120737535dab4d4548a6c83576c.gif","select2x2.png":"select2x2-6fe28d687dc0ed4d96016238c608ba1e7198c9c9accfa0b360b78018b9fb9bc2.png","font-awesome/fontawesome-webfont.eot":"font-awesome/fontawesome-webfont-a280856e20cc0af53390b729ca0ac3edbf8fc889a828a379c5d634c91e80c808.eot","font-awesome/fontawesome-webfont.woff2":"font-awesome/fontawesome-webfont-2932abf996373e87fbf2e950876b1962f1b57db954a1643ea68831d9fbb74da4.woff2","font-awesome/fontawesome-webfont.woff":"font-awesome/fontawesome-webfont-35fa8302dd7d3d191ebb7acac543efcfa2b85a0da573b3ab45cc122ffcc45ce5.woff","font-awesome/fontawesome-webfont.ttf":"font-awesome/fontawesome-webfont-8630313bee77f64206067ed80eb6a7c721b0bbfc91c94210966969d4dcc43ba7.ttf","font-awesome/fontawesome-webfont.svg":"font-awesome/fontawesome-webfont-6b0adce775f4d57ac800f23b05af72ced748ae51ba67a65b67b7316f1ed331b3.svg","france.png":"france-f4341a7ec8331161a9c8d5298f808014c3fc9c799b5a29ed95eb56a7f3ccd0df.png","quebec.png":"quebec-776d563b6a4ac4312cae9f0bfe630c20711346e8dbddd41040998eba79f4b588.png","belgique.png":"belgique-3b8b772a522de2cbae7714b35a956faf2c394419b532a14bba982fed3f341091.png","suisse.png":"suisse-58d067f1c3fcdc4000fa13e95896cd5369a2b91aafd314475aa5e29da0b543d1.png","modernizr.js":"modernizr-654222debe8018b12f1993ceddff30dc163a7d5008d79869c399d6d167321f97.js","agendadescommuns.png":"agendadescommuns-cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6.png","alert.png":"alert-762ace9479328243a44061346b64c4d6b997e963c68dfc6bddd9e4d241192906.png","baby_gnu_adl.png":"baby_gnu_adl-232caf355c30740d5d9b30491887cd546b8849b33ca9bdb6cc71f8a47ea61815.png","communs.png":"communs-cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6.png","lef-small.png":"lef-small-160cf5b883add60c9c0f4361bd8425c75f6fb23b0e551a0b941fa0491c70e0c9.png","lef.png":"lef-bec4081a11fbef165216827cf72c7a292ad772a77af6b8132e5bc0bbf83cb2d9.png","priorite-logiciel-libre-je-soutiens-april_2_m.png":"priorite-logiciel-libre-je-soutiens-april_2_m-6442e454e96ed45cc1ebc40673a6c50bd286b9c28ea6a8b58572e94f7d6459fc.png","team.png":"team-cb04c7a311f7160c4eb6a281eae68be84f26991dde5d415bb4e205e6726ae275.png","application.js":"application-307219623ded8fdc9ee285ad85d84051e026d5bfc9ff99ad749c917ab9dfcc76.js","active_admin/application.js":"active_admin/application-50ffc9f86e474cd52ffb7ce3b3572255ad6646ea17097a056f330b540eae402c.js","tinymce/jquery.tinymce.js":"tinymce/jquery.tinymce.js","tinymce/langs/readme.md":"tinymce/langs/readme.md","tinymce/license.txt":"tinymce/license.txt","tinymce/plugins/advlist/plugin.js":"tinymce/plugins/advlist/plugin.js","tinymce/plugins/anchor/plugin.js":"tinymce/plugins/anchor/plugin.js","tinymce/plugins/autolink/plugin.js":"tinymce/plugins/autolink/plugin.js","tinymce/plugins/autoresize/plugin.js":"tinymce/plugins/autoresize/plugin.js","tinymce/plugins/autosave/plugin.js":"tinymce/plugins/autosave/plugin.js","tinymce/plugins/bbcode/plugin.js":"tinymce/plugins/bbcode/plugin.js","tinymce/plugins/charmap/plugin.js":"tinymce/plugins/charmap/plugin.js","tinymce/plugins/code/plugin.js":"tinymce/plugins/code/plugin.js","tinymce/plugins/codesample/css/prism.css":"tinymce/plugins/codesample/css/prism.css","tinymce/plugins/codesample/plugin.js":"tinymce/plugins/codesample/plugin.js","tinymce/plugins/colorpicker/plugin.js":"tinymce/plugins/colorpicker/plugin.js","tinymce/plugins/contextmenu/plugin.js":"tinymce/plugins/contextmenu/plugin.js","tinymce/plugins/directionality/plugin.js":"tinymce/plugins/directionality/plugin.js","tinymce/plugins/emoticons/img/smiley-cool.gif":"tinymce/plugins/emoticons/img/smiley-cool.gif","tinymce/plugins/emoticons/img/smiley-cry.gif":"tinymce/plugins/emoticons/img/smiley-cry.gif","tinymce/plugins/emoticons/img/smiley-embarassed.gif":"tinymce/plugins/emoticons/img/smiley-embarassed.gif","tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif":"tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif","tinymce/plugins/emoticons/img/smiley-frown.gif":"tinymce/plugins/emoticons/img/smiley-frown.gif","tinymce/plugins/emoticons/img/smiley-innocent.gif":"tinymce/plugins/emoticons/img/smiley-innocent.gif","tinymce/plugins/emoticons/img/smiley-kiss.gif":"tinymce/plugins/emoticons/img/smiley-kiss.gif","tinymce/plugins/emoticons/img/smiley-laughing.gif":"tinymce/plugins/emoticons/img/smiley-laughing.gif","tinymce/plugins/emoticons/img/smiley-money-mouth.gif":"tinymce/plugins/emoticons/img/smiley-money-mouth.gif","tinymce/plugins/emoticons/img/smiley-sealed.gif":"tinymce/plugins/emoticons/img/smiley-sealed.gif","tinymce/plugins/emoticons/img/smiley-smile.gif":"tinymce/plugins/emoticons/img/smiley-smile.gif","tinymce/plugins/emoticons/img/smiley-surprised.gif":"tinymce/plugins/emoticons/img/smiley-surprised.gif","tinymce/plugins/emoticons/img/smiley-tongue-out.gif":"tinymce/plugins/emoticons/img/smiley-tongue-out.gif","tinymce/plugins/emoticons/img/smiley-undecided.gif":"tinymce/plugins/emoticons/img/smiley-undecided.gif","tinymce/plugins/emoticons/img/smiley-wink.gif":"tinymce/plugins/emoticons/img/smiley-wink.gif","tinymce/plugins/emoticons/img/smiley-yell.gif":"tinymce/plugins/emoticons/img/smiley-yell.gif","tinymce/plugins/emoticons/plugin.js":"tinymce/plugins/emoticons/plugin.js","tinymce/plugins/example/dialog.html":"tinymce/plugins/example/dialog.html","tinymce/plugins/example/plugin.js":"tinymce/plugins/example/plugin.js","tinymce/plugins/example_dependency/plugin.js":"tinymce/plugins/example_dependency/plugin.js","tinymce/plugins/fullpage/plugin.js":"tinymce/plugins/fullpage/plugin.js","tinymce/plugins/fullscreen/plugin.js":"tinymce/plugins/fullscreen/plugin.js","tinymce/plugins/hr/plugin.js":"tinymce/plugins/hr/plugin.js","tinymce/plugins/image/plugin.js":"tinymce/plugins/image/plugin.js","tinymce/plugins/imagetools/plugin.js":"tinymce/plugins/imagetools/plugin.js","tinymce/plugins/importcss/plugin.js":"tinymce/plugins/importcss/plugin.js","tinymce/plugins/insertdatetime/plugin.js":"tinymce/plugins/insertdatetime/plugin.js","tinymce/plugins/layer/plugin.js":"tinymce/plugins/layer/plugin.js","tinymce/plugins/legacyoutput/plugin.js":"tinymce/plugins/legacyoutput/plugin.js","tinymce/plugins/link/plugin.js":"tinymce/plugins/link/plugin.js","tinymce/plugins/lists/plugin.js":"tinymce/plugins/lists/plugin.js","tinymce/plugins/media/moxieplayer.swf":"tinymce/plugins/media/moxieplayer.swf","tinymce/plugins/media/plugin.js":"tinymce/plugins/media/plugin.js","tinymce/plugins/nonbreaking/plugin.js":"tinymce/plugins/nonbreaking/plugin.js","tinymce/plugins/noneditable/plugin.js":"tinymce/plugins/noneditable/plugin.js","tinymce/plugins/pagebreak/plugin.js":"tinymce/plugins/pagebreak/plugin.js","tinymce/plugins/paste/plugin.js":"tinymce/plugins/paste/plugin.js","tinymce/plugins/preview/plugin.js":"tinymce/plugins/preview/plugin.js","tinymce/plugins/print/plugin.js":"tinymce/plugins/print/plugin.js","tinymce/plugins/save/plugin.js":"tinymce/plugins/save/plugin.js","tinymce/plugins/searchreplace/plugin.js":"tinymce/plugins/searchreplace/plugin.js","tinymce/plugins/spellchecker/plugin.js":"tinymce/plugins/spellchecker/plugin.js","tinymce/plugins/tabfocus/plugin.js":"tinymce/plugins/tabfocus/plugin.js","tinymce/plugins/table/plugin.js":"tinymce/plugins/table/plugin.js","tinymce/plugins/template/plugin.js":"tinymce/plugins/template/plugin.js","tinymce/plugins/textcolor/plugin.js":"tinymce/plugins/textcolor/plugin.js","tinymce/plugins/textpattern/plugin.js":"tinymce/plugins/textpattern/plugin.js","tinymce/plugins/visualblocks/css/visualblocks.css":"tinymce/plugins/visualblocks/css/visualblocks.css","tinymce/plugins/visualblocks/plugin.js":"tinymce/plugins/visualblocks/plugin.js","tinymce/plugins/visualchars/plugin.js":"tinymce/plugins/visualchars/plugin.js","tinymce/plugins/wordcount/plugin.js":"tinymce/plugins/wordcount/plugin.js","tinymce/skins/lightgray/content.inline.min.css":"tinymce/skins/lightgray/content.inline.min.css","tinymce/skins/lightgray/content.min.css":"tinymce/skins/lightgray/content.min.css","tinymce/skins/lightgray/fonts/tinymce-small.eot":"tinymce/skins/lightgray/fonts/tinymce-small.eot","tinymce/skins/lightgray/fonts/tinymce-small.svg":"tinymce/skins/lightgray/fonts/tinymce-small.svg","tinymce/skins/lightgray/fonts/tinymce-small.ttf":"tinymce/skins/lightgray/fonts/tinymce-small.ttf","tinymce/skins/lightgray/fonts/tinymce-small.woff":"tinymce/skins/lightgray/fonts/tinymce-small.woff","tinymce/skins/lightgray/fonts/tinymce.eot":"tinymce/skins/lightgray/fonts/tinymce.eot","tinymce/skins/lightgray/fonts/tinymce.svg":"tinymce/skins/lightgray/fonts/tinymce.svg","tinymce/skins/lightgray/fonts/tinymce.ttf":"tinymce/skins/lightgray/fonts/tinymce.ttf","tinymce/skins/lightgray/fonts/tinymce.woff":"tinymce/skins/lightgray/fonts/tinymce.woff","tinymce/skins/lightgray/img/anchor.gif":"tinymce/skins/lightgray/img/anchor.gif","tinymce/skins/lightgray/img/loader.gif":"tinymce/skins/lightgray/img/loader.gif","tinymce/skins/lightgray/img/object.gif":"tinymce/skins/lightgray/img/object.gif","tinymce/skins/lightgray/img/trans.gif":"tinymce/skins/lightgray/img/trans.gif","tinymce/skins/lightgray/skin.ie7.min.css":"tinymce/skins/lightgray/skin.ie7.min.css","tinymce/skins/lightgray/skin.min.css":"tinymce/skins/lightgray/skin.min.css","tinymce/themes/modern/theme.js":"tinymce/themes/modern/theme.js","tinymce/tinymce.js":"tinymce/tinymce.js","tinymce/langs/ar.js":"tinymce/langs/ar.js","tinymce/langs/ar_SA.js":"tinymce/langs/ar_SA.js","tinymce/langs/az.js":"tinymce/langs/az.js","tinymce/langs/be.js":"tinymce/langs/be.js","tinymce/langs/bg_BG.js":"tinymce/langs/bg_BG.js","tinymce/langs/bn_BD.js":"tinymce/langs/bn_BD.js","tinymce/langs/bs.js":"tinymce/langs/bs.js","tinymce/langs/ca.js":"tinymce/langs/ca.js","tinymce/langs/cs.js":"tinymce/langs/cs.js","tinymce/langs/cs_CZ.js":"tinymce/langs/cs_CZ.js","tinymce/langs/cy.js":"tinymce/langs/cy.js","tinymce/langs/da.js":"tinymce/langs/da.js","tinymce/langs/de.js":"tinymce/langs/de.js","tinymce/langs/de_AT.js":"tinymce/langs/de_AT.js","tinymce/langs/dv.js":"tinymce/langs/dv.js","tinymce/langs/el.js":"tinymce/langs/el.js","tinymce/langs/en_CA.js":"tinymce/langs/en_CA.js","tinymce/langs/en_GB.js":"tinymce/langs/en_GB.js","tinymce/langs/eo.js":"tinymce/langs/eo.js","tinymce/langs/es.js":"tinymce/langs/es.js","tinymce/langs/es_MX.js":"tinymce/langs/es_MX.js","tinymce/langs/et.js":"tinymce/langs/et.js","tinymce/langs/eu.js":"tinymce/langs/eu.js","tinymce/langs/fa.js":"tinymce/langs/fa.js","tinymce/langs/fa_IR.js":"tinymce/langs/fa_IR.js","tinymce/langs/fi.js":"tinymce/langs/fi.js","tinymce/langs/fo.js":"tinymce/langs/fo.js","tinymce/langs/fr_CH.js":"tinymce/langs/fr_CH.js","tinymce/langs/fr_FR.js":"tinymce/langs/fr_FR.js","tinymce/langs/ga.js":"tinymce/langs/ga.js","tinymce/langs/gd.js":"tinymce/langs/gd.js","tinymce/langs/gl.js":"tinymce/langs/gl.js","tinymce/langs/he_IL.js":"tinymce/langs/he_IL.js","tinymce/langs/hi_IN.js":"tinymce/langs/hi_IN.js","tinymce/langs/hr.js":"tinymce/langs/hr.js","tinymce/langs/hu_HU.js":"tinymce/langs/hu_HU.js","tinymce/langs/hy.js":"tinymce/langs/hy.js","tinymce/langs/id.js":"tinymce/langs/id.js","tinymce/langs/is_IS.js":"tinymce/langs/is_IS.js","tinymce/langs/it.js":"tinymce/langs/it.js","tinymce/langs/ja.js":"tinymce/langs/ja.js","tinymce/langs/ka_GE.js":"tinymce/langs/ka_GE.js","tinymce/langs/kab.js":"tinymce/langs/kab.js","tinymce/langs/kk.js":"tinymce/langs/kk.js","tinymce/langs/km_KH.js":"tinymce/langs/km_KH.js","tinymce/langs/ko.js":"tinymce/langs/ko.js","tinymce/langs/ko_KR.js":"tinymce/langs/ko_KR.js","tinymce/langs/ku.js":"tinymce/langs/ku.js","tinymce/langs/ku_IQ.js":"tinymce/langs/ku_IQ.js","tinymce/langs/lb.js":"tinymce/langs/lb.js","tinymce/langs/lt.js":"tinymce/langs/lt.js","tinymce/langs/lv.js":"tinymce/langs/lv.js","tinymce/langs/mk_MK.js":"tinymce/langs/mk_MK.js","tinymce/langs/ml.js":"tinymce/langs/ml.js","tinymce/langs/ml_IN.js":"tinymce/langs/ml_IN.js","tinymce/langs/mn_MN.js":"tinymce/langs/mn_MN.js","tinymce/langs/nb_NO.js":"tinymce/langs/nb_NO.js","tinymce/langs/nl.js":"tinymce/langs/nl.js","tinymce/langs/pl.js":"tinymce/langs/pl.js","tinymce/langs/pt_BR.js":"tinymce/langs/pt_BR.js","tinymce/langs/pt_PT.js":"tinymce/langs/pt_PT.js","tinymce/langs/ro.js":"tinymce/langs/ro.js","tinymce/langs/ru.js":"tinymce/langs/ru.js","tinymce/langs/ru_RU.js":"tinymce/langs/ru_RU.js","tinymce/langs/si_LK.js":"tinymce/langs/si_LK.js","tinymce/langs/sk.js":"tinymce/langs/sk.js","tinymce/langs/sl_SI.js":"tinymce/langs/sl_SI.js","tinymce/langs/sr.js":"tinymce/langs/sr.js","tinymce/langs/sv_SE.js":"tinymce/langs/sv_SE.js","tinymce/langs/ta.js":"tinymce/langs/ta.js","tinymce/langs/ta_IN.js":"tinymce/langs/ta_IN.js","tinymce/langs/tg.js":"tinymce/langs/tg.js","tinymce/langs/th_TH.js":"tinymce/langs/th_TH.js","tinymce/langs/tr.js":"tinymce/langs/tr.js","tinymce/langs/tr_TR.js":"tinymce/langs/tr_TR.js","tinymce/langs/tt.js":"tinymce/langs/tt.js","tinymce/langs/ug.js":"tinymce/langs/ug.js","tinymce/langs/uk.js":"tinymce/langs/uk.js","tinymce/langs/uk_UA.js":"tinymce/langs/uk_UA.js","tinymce/langs/vi.js":"tinymce/langs/vi.js","tinymce/langs/vi_VN.js":"tinymce/langs/vi_VN.js","tinymce/langs/zh_CN.js":"tinymce/langs/zh_CN.js","tinymce/langs/zh_TW.js":"tinymce/langs/zh_TW.js","markers-matte.png":"markers-matte-497826545a90e09a240504d14530eba45823b19fd44175e09e27c47cd822ddb9.png","markers-matte@2x.png":"markers-matte@2x-948fc8c4426f04f60964ed20394247f45b0b60e575d02398b9b6810e7a29a823.png","markers-plain.png":"markers-plain-cf233423aa44e75ac0031e77b8ba571cd3331010517e1197e63fb7b06856c1ff.png","markers-shadow.png":"markers-shadow-8703a2262710f5e3d29e65d2acdf90d6512e159e119d27b8234731d8a6208a20.png","markers-shadow@2x.png":"markers-shadow@2x-b21a536be27313fb504f69f5899ff0b1245b276571769ac08d6c32c35676e47a.png","markers-soft.png":"markers-soft-e78784e4ed70aaffddd73c315fab590233cc4e7b72388d7dd47a14796fc7c739.png","markers-soft@2x.png":"markers-soft@2x-c1e77253a8bfbe30cec24885d7046f443b76ebb66f4c961f77083b03f4a5cbaf.png","webshims/shims/jpicker/images/AlphaBar.png":"webshims/shims/jpicker/images/AlphaBar-34d23568a887827c654ed2ac63ed3857a2cbd690643c471ea4b21c08a1568454.png","webshims/shims/jpicker/images/Bars.png":"webshims/shims/jpicker/images/Bars-a697469b1a3828d81b3bdaf334ade0637dd6adf9bf45859aeb88a6ffc06b009f.png","webshims/shims/jpicker/images/Maps.png":"webshims/shims/jpicker/images/Maps-538873f6da4e3a26cd5bb92f305f01e0ca0680cd08d488aef3e1eb250d77a968.png","webshims/shims/jpicker/images/NoColor.png":"webshims/shims/jpicker/images/NoColor-d266c220953f0b4fe96aeb868b82148e4c2ad380b1ed04d29214602851204e86.png","webshims/shims/jpicker/images/bar-opacity.png":"webshims/shims/jpicker/images/bar-opacity-690f9f36c78c2ebdfe7510739082dd835cc940565b794617a2bcaf93a566d938.png","webshims/shims/jpicker/images/map-opacity.png":"webshims/shims/jpicker/images/map-opacity-00182478b4fc3dedc97b9d2c46d9917f82c321110cab01e0f2ad4725978c2fd3.png","webshims/shims/jpicker/images/mappoint.gif":"webshims/shims/jpicker/images/mappoint-25687420458d1f31e399b1bc5a25e95a6dce8b898ed7f9d4361ff6cb430a7c45.gif","webshims/shims/jpicker/images/picker.gif":"webshims/shims/jpicker/images/picker-3aa5592f4e753f0244866a40b9c48fced398d219b8bc5ee76d2d51f9f952c9b2.gif","webshims/shims/jpicker/images/preview-opacity.png":"webshims/shims/jpicker/images/preview-opacity-12751bd440befc7037806e0451e2a2a8577655e3de1b702a2b50514ba2e9628d.png","webshims/shims/jpicker/images/rangearrows.gif":"webshims/shims/jpicker/images/rangearrows-d13aa5195095eb2e0d990d488ff4c5ed65052e6065d709463c97ed0d25cf652b.gif","webshims/shims/styles/color-picker.png":"webshims/shims/styles/color-picker-2141bfffae7d9714b5260735c338beb44ed24c5982f267fc1e3158ac4b82079f.png","webshims/shims/styles/progress.gif":"webshims/shims/styles/progress-8023960ce5bc957d1f0014859a51e55b9a3ce180bfd3d214a1a0629e2608a446.gif","webshims/shims/styles/progress.png":"webshims/shims/styles/progress-a9f7c78ea64c14559c7e683daaba141f50fac42e68e88232e416ca21645d0139.png","webshims/shims/styles/transparent.png":"webshims/shims/styles/transparent-384a16eed212e680374ad9b8529fb3de3422e515b2e10fdc18d7afdba59a1fa9.png","jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png":"jquery-ui/ui-bg_flat_0_aaaaaa_40x100-9a8492a580bf85d3e98ae8861fbd45567e5a1f83eeafcf9574da0399d5f602ab.png","jquery-ui/ui-bg_flat_75_ffffff_40x100.png":"jquery-ui/ui-bg_flat_75_ffffff_40x100-39ab7ccd9f4e82579da78a9241265df288d8eb65dbbd7cf48aed2d0129887df5.png","jquery-ui/ui-bg_glass_55_fbf9ee_1x400.png":"jquery-ui/ui-bg_glass_55_fbf9ee_1x400-691597e8a40a891ea94d3589976ecfc33e6145c49422443b00ac2b5a0022964c.png","jquery-ui/ui-bg_glass_65_ffffff_1x400.png":"jquery-ui/ui-bg_glass_65_ffffff_1x400-f0e6cd91b837d5c5644d026e5ffeccd907953317cd5c0f689901733afda260b2.png","jquery-ui/ui-bg_glass_75_dadada_1x400.png":"jquery-ui/ui-bg_glass_75_dadada_1x400-c108f5cbf2dd9ec07a26530695ddd95e1664597ce6c056ae44c162cc2e28cec4.png","jquery-ui/ui-bg_glass_75_e6e6e6_1x400.png":"jquery-ui/ui-bg_glass_75_e6e6e6_1x400-ddf5dd4e0ef2b185e8bb0af7b6e90ebe74a84384cb4700658e76e754c8bfe550.png","jquery-ui/ui-bg_glass_95_fef1ec_1x400.png":"jquery-ui/ui-bg_glass_95_fef1ec_1x400-f6f1c1bedf1a0f37cfef81d12f5f012869d1ee7c984775a569827a1784d34f5c.png","jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100.png":"jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100-54270656df079c4da5182629a080fc633b6f84b87985eb016d25a560e2c38d4a.png","jquery-ui/ui-icons_222222_256x240.png":"jquery-ui/ui-icons_222222_256x240-57adb0d65f4e91dacfee975d9574422bee7486c8a182d60133728c672f2cdbbc.png","jquery-ui/ui-icons_2e83ff_256x240.png":"jquery-ui/ui-icons_2e83ff_256x240-20f8c6667afc48aa433ee9eb6d8a0584bdbd6b4a4a9091ff1e6b3adb31e63bd9.png","jquery-ui/ui-icons_454545_256x240.png":"jquery-ui/ui-icons_454545_256x240-07460e843c3e59aaadbb34231e699e856a2980753c7a47b66447da5d9f93fb7f.png","jquery-ui/ui-icons_888888_256x240.png":"jquery-ui/ui-icons_888888_256x240-ea2e29625de3463465e93b002b065f5833e05b97f7a052b1c141e754d62e1a8b.png","jquery-ui/ui-icons_cd0a0a_256x240.png":"jquery-ui/ui-icons_cd0a0a_256x240-1e32c6dbf5d3fd342f27a78aa881550d6412aa207f48468724a6a15402b6041b.png","baby_gnu_adl.svg":"baby_gnu_adl-97251005d3225cf1d58b8c497d6b7905dbc9560cc8acd50118fcce60d0a2679e.svg"}} \ No newline at end of file +{"files":{"active_admin-617b799bade586fce74b4e0121a99adb6ff69314ffc69f4e24529028a7b72538.css":{"logical_path":"active_admin.css","mtime":"2016-05-19T21:35:29+02:00","size":214498,"digest":"617b799bade586fce74b4e0121a99adb6ff69314ffc69f4e24529028a7b72538","integrity":"sha256-YXt5m63lhvznS04BIama22/2kxT/xp9OJFKQKKe3JTg="},"active_admin/nested_menu_arrow-15084d93c65c1964d7077700ea748bd2d70cfa2d4c19707c58a9c64e232dd442.gif":{"logical_path":"active_admin/nested_menu_arrow.gif","mtime":"2016-07-02T17:35:57+02:00","size":70,"digest":"15084d93c65c1964d7077700ea748bd2d70cfa2d4c19707c58a9c64e232dd442","integrity":"sha256-FQhNk8ZcGWTXB3cA6nSL0tcM+i1MGXB8WKnGTiMt1EI="},"active_admin/nested_menu_arrow_dark-7c43b8e0a5f8823875f49a093c9d7a6b374f885b6f9cc248ae9cd7e6e9b29034.gif":{"logical_path":"active_admin/nested_menu_arrow_dark.gif","mtime":"2016-07-02T17:35:57+02:00","size":70,"digest":"7c43b8e0a5f8823875f49a093c9d7a6b374f885b6f9cc248ae9cd7e6e9b29034","integrity":"sha256-fEO44KX4gjh19JoJPJ16azdPiFtvnMJIrpzX5umykDQ="},"active_admin/datepicker/datepicker-input-icon-d9c2bb73769af777c8a71720d29741f3a499aebd5a043e9a119bd0d9597aed47.png":{"logical_path":"active_admin/datepicker/datepicker-input-icon.png","mtime":"2016-07-02T17:35:57+02:00","size":1535,"digest":"d9c2bb73769af777c8a71720d29741f3a499aebd5a043e9a119bd0d9597aed47","integrity":"sha256-2cK7c3aa93fIpxcg0pdB86SZrr1aBD6aEZvQ2Vl67Uc="},"active_admin/orderable-29374dbb55b0012d78a37c614d573bb3474f0779849b478a147d0f1845ca6617.png":{"logical_path":"active_admin/orderable.png","mtime":"2016-07-02T17:35:57+02:00","size":220,"digest":"29374dbb55b0012d78a37c614d573bb3474f0779849b478a147d0f1845ca6617","integrity":"sha256-KTdNu1WwAS14o3xhTVc7s0dPB3mEm0eKFH0PGEXKZhc="},"active_admin_pagedown/wmd-buttons-c2040b12f2d6cb568ddc33587a070a29a18fed20099260c3ecbbfdbd62042f7b.png":{"logical_path":"active_admin_pagedown/wmd-buttons.png","mtime":"2016-05-04T17:49:02+02:00","size":7465,"digest":"c2040b12f2d6cb568ddc33587a070a29a18fed20099260c3ecbbfdbd62042f7b","integrity":"sha256-wgQLEvLWy1aN3DNYegcKKaGP7SAJkmDD7Lv9vWIEL3s="},"active_admin/print-cb755dcaacb896fb80d996ba6eee250ea19ee816526e5e5d0137ed2af34d08f1.css":{"logical_path":"active_admin/print.css","mtime":"2016-05-04T17:49:01+02:00","size":18961,"digest":"cb755dcaacb896fb80d996ba6eee250ea19ee816526e5e5d0137ed2af34d08f1","integrity":"sha256-y3Vdyqy4lvuA2Za6bu4lDqGe6BZSbl5dATftKvNNCPE="},"active_admin-3ac0f1eff2fd35f310a1bd2242c049f9d2cc006c7b1065541a5d855556e24393.js":{"logical_path":"active_admin.js","mtime":"2016-06-25T16:51:02+02:00","size":771406,"digest":"3ac0f1eff2fd35f310a1bd2242c049f9d2cc006c7b1065541a5d855556e24393","integrity":"sha256-OsDx7/L9NfMQob0iQsBJ+dLMAGx7EGVUGl2FVVbiQ5M="},"layers-2x-0c02a2388f637d21f86e6d4b314ec9a968e7b05ad4c3a005280a3f76c0fd3cb8.png":{"logical_path":"layers-2x.png","mtime":"2016-05-04T17:44:43+02:00","size":2898,"digest":"0c02a2388f637d21f86e6d4b314ec9a968e7b05ad4c3a005280a3f76c0fd3cb8","integrity":"sha256-DAKiOI9jfSH4bm1LMU7JqWjnsFrUw6AFKAo/dsD9PLg="},"layers-0908aa2a72a082fb2563a2427a5e4fb247571862b448b80fb6f720af1109923e.png":{"logical_path":"layers.png","mtime":"2016-05-04T17:44:43+02:00","size":1502,"digest":"0908aa2a72a082fb2563a2427a5e4fb247571862b448b80fb6f720af1109923e","integrity":"sha256-CQiqKnKggvslY6JCel5PskdXGGK0SLgPtvcgrxEJkj4="},"marker-icon-2x-454dc479e82b487529b6b93d6a9b29ac69ca7b4f5a9d5fdf8e01871f6d216113.png":{"logical_path":"marker-icon-2x.png","mtime":"2016-05-04T17:44:43+02:00","size":4033,"digest":"454dc479e82b487529b6b93d6a9b29ac69ca7b4f5a9d5fdf8e01871f6d216113","integrity":"sha256-RU3EeegrSHUptrk9apsprGnKe09anV/fjgGHH20hYRM="},"marker-icon-915e83a6fc798c599e5c9e3f759d6bc065d65151019acd0410d1f4731bcaaf72.png":{"logical_path":"marker-icon.png","mtime":"2016-05-04T17:44:43+02:00","size":1747,"digest":"915e83a6fc798c599e5c9e3f759d6bc065d65151019acd0410d1f4731bcaaf72","integrity":"sha256-kV6Dpvx5jFmeXJ4/dZ1rwGXWUVEBms0EENH0cxvKr3I="},"marker-shadow-4f340d2d61746333dffe056e074ce1704ae4e47fec5a7de98322fbdbcfcb2b6d.png":{"logical_path":"marker-shadow.png","mtime":"2016-05-04T17:44:43+02:00","size":797,"digest":"4f340d2d61746333dffe056e074ce1704ae4e47fec5a7de98322fbdbcfcb2b6d","integrity":"sha256-TzQNLWF0YzPf/gVuB0zhcErk5H/sWn3pgyL728/LK20="},"tinymce-851b4961ce4c9997bc39867507ab34eb00de363cb3aab1b32a6b1c91ebf6733b.js":{"logical_path":"tinymce.js","mtime":"2016-05-21T22:53:26+02:00","size":948,"digest":"851b4961ce4c9997bc39867507ab34eb00de363cb3aab1b32a6b1c91ebf6733b","integrity":"sha256-hRtJYc5MmZe8OYZ1B6s06wDeNjyzqrGzKmsckev2czs="},"application-ee82c1c962333e87dcfc9a0eb1abbc739ed57ba7b77732ece49ab08b6cedf706.css":{"logical_path":"application.css","mtime":"2016-05-21T19:55:46+02:00","size":548037,"digest":"ee82c1c962333e87dcfc9a0eb1abbc739ed57ba7b77732ece49ab08b6cedf706","integrity":"sha256-7oLByWIzPofc/JoOsau8c57Ve6e3dzLs5Jqwi2zt9wY="},"select2-d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8.png":{"logical_path":"select2.png","mtime":"2016-05-04T17:45:07+02:00","size":613,"digest":"d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8","integrity":"sha256-1rXY2D28GPuNd8h2HTMc2eUSPJaElQurBAbpiiSsWug="},"select2-spinner-f6ecff617ec2ba7f559e6f535cad9b70a3f91120737535dab4d4548a6c83576c.gif":{"logical_path":"select2-spinner.gif","mtime":"2016-05-04T17:45:07+02:00","size":1849,"digest":"f6ecff617ec2ba7f559e6f535cad9b70a3f91120737535dab4d4548a6c83576c","integrity":"sha256-9uz/YX7Cun9Vnm9TXK2bcKP5ESBzdTXatNRUimyDV2w="},"select2x2-6fe28d687dc0ed4d96016238c608ba1e7198c9c9accfa0b360b78018b9fb9bc2.png":{"logical_path":"select2x2.png","mtime":"2016-05-04T17:45:07+02:00","size":845,"digest":"6fe28d687dc0ed4d96016238c608ba1e7198c9c9accfa0b360b78018b9fb9bc2","integrity":"sha256-b+KNaH3A7U2WAWI4xgi6HnGYycmsz6CzYLeAGLn7m8I="},"font-awesome/fontawesome-webfont-a280856e20cc0af53390b729ca0ac3edbf8fc889a828a379c5d634c91e80c808.eot":{"logical_path":"font-awesome/fontawesome-webfont.eot","mtime":"2016-05-19T21:35:29+02:00","size":76204,"digest":"a280856e20cc0af53390b729ca0ac3edbf8fc889a828a379c5d634c91e80c808","integrity":"sha256-ooCFbiDMCvUzkLcpygrD7b+PyImoKKN5xdY0yR6AyAg="},"font-awesome/fontawesome-webfont-2932abf996373e87fbf2e950876b1962f1b57db954a1643ea68831d9fbb74da4.woff2":{"logical_path":"font-awesome/fontawesome-webfont.woff2","mtime":"2016-05-19T21:35:29+02:00","size":71760,"digest":"2932abf996373e87fbf2e950876b1962f1b57db954a1643ea68831d9fbb74da4","integrity":"sha256-KTKr+ZY3Pof78ulQh2sZYvG1fblUoWQ+pogx2fu3TaQ="},"font-awesome/fontawesome-webfont-35fa8302dd7d3d191ebb7acac543efcfa2b85a0da573b3ab45cc122ffcc45ce5.woff":{"logical_path":"font-awesome/fontawesome-webfont.woff","mtime":"2016-05-19T21:35:29+02:00","size":90144,"digest":"35fa8302dd7d3d191ebb7acac543efcfa2b85a0da573b3ab45cc122ffcc45ce5","integrity":"sha256-NfqDAt19PRkeu3rKxUPvz6K4Wg2lc7OrRcwSL/zEXOU="},"font-awesome/fontawesome-webfont-8630313bee77f64206067ed80eb6a7c721b0bbfc91c94210966969d4dcc43ba7.ttf":{"logical_path":"font-awesome/fontawesome-webfont.ttf","mtime":"2016-05-19T21:35:29+02:00","size":152364,"digest":"8630313bee77f64206067ed80eb6a7c721b0bbfc91c94210966969d4dcc43ba7","integrity":"sha256-hjAxO+539kIGBn7YDranxyGwu/yRyUIQlmlp1NzEO6c="},"font-awesome/fontawesome-webfont-6b0adce775f4d57ac800f23b05af72ced748ae51ba67a65b67b7316f1ed331b3.svg":{"logical_path":"font-awesome/fontawesome-webfont.svg","mtime":"2016-05-19T21:35:29+02:00","size":390452,"digest":"6b0adce775f4d57ac800f23b05af72ced748ae51ba67a65b67b7316f1ed331b3","integrity":"sha256-awrc53X01XrIAPI7Ba9yztdIrlG6Z6ZbZ7cxbx7TMbM="},"france-f4341a7ec8331161a9c8d5298f808014c3fc9c799b5a29ed95eb56a7f3ccd0df.png":{"logical_path":"france.png","mtime":"2014-07-04T14:08:56+02:00","size":276,"digest":"f4341a7ec8331161a9c8d5298f808014c3fc9c799b5a29ed95eb56a7f3ccd0df","integrity":"sha256-9DQafsgzEWGpyNUpj4CAFMP8nHmbWintletWp/PM0N8="},"quebec-776d563b6a4ac4312cae9f0bfe630c20711346e8dbddd41040998eba79f4b588.png":{"logical_path":"quebec.png","mtime":"2015-10-22T22:54:30+02:00","size":567,"digest":"776d563b6a4ac4312cae9f0bfe630c20711346e8dbddd41040998eba79f4b588","integrity":"sha256-d21WO2pKxDEsrp8L/mMMIHETRujb3dQQQJmOunn0tYg="},"belgique-3b8b772a522de2cbae7714b35a956faf2c394419b532a14bba982fed3f341091.png":{"logical_path":"belgique.png","mtime":"2014-07-04T14:08:56+02:00","size":187,"digest":"3b8b772a522de2cbae7714b35a956faf2c394419b532a14bba982fed3f341091","integrity":"sha256-O4t3KlIt4suudxSzWpVvryw5RBm1MqFLupgv7T80EJE="},"suisse-58d067f1c3fcdc4000fa13e95896cd5369a2b91aafd314475aa5e29da0b543d1.png":{"logical_path":"suisse.png","mtime":"2015-10-22T22:54:30+02:00","size":299,"digest":"58d067f1c3fcdc4000fa13e95896cd5369a2b91aafd314475aa5e29da0b543d1","integrity":"sha256-WNBn8cP83EAA+hPpWJbNU2miuRqv0xRHWqXinaC1Q9E="},"modernizr-654222debe8018b12f1993ceddff30dc163a7d5008d79869c399d6d167321f97.js":{"logical_path":"modernizr.js","mtime":"2016-05-04T17:44:47+02:00","size":51365,"digest":"654222debe8018b12f1993ceddff30dc163a7d5008d79869c399d6d167321f97","integrity":"sha256-ZUIi3r6AGLEvGZPO3f8w3BY6fVAI15hpw5nW0WcyH5c="},"agendadescommuns-cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6.png":{"logical_path":"agendadescommuns.png","mtime":"2015-10-22T22:54:30+02:00","size":2760,"digest":"cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6","integrity":"sha256-zUDjQgJL4Fh/jnoOOQLTLPZwCdNJtnwA9ofgSZ/en/Y="},"alert-762ace9479328243a44061346b64c4d6b997e963c68dfc6bddd9e4d241192906.png":{"logical_path":"alert.png","mtime":"2014-07-04T14:08:56+02:00","size":47876,"digest":"762ace9479328243a44061346b64c4d6b997e963c68dfc6bddd9e4d241192906","integrity":"sha256-dirOlHkygkOkQGE0a2TE1rmX6WPGjfxr3dnk0kEZKQY="},"baby_gnu_adl-ff3fa5912b3f9164dcdebca6f4fe3f4195e6dae5e3c22c8361bef1d79626ea07.png":{"logical_path":"baby_gnu_adl.png","mtime":"2015-10-22T22:54:17+02:00","size":11494,"digest":"ff3fa5912b3f9164dcdebca6f4fe3f4195e6dae5e3c22c8361bef1d79626ea07","integrity":"sha256-/z+lkSs/kWTc3rym9P4/QZXm2uXjwiyDYb7x15Ym6gc="},"communs-cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6.png":{"logical_path":"communs.png","mtime":"2015-10-22T22:54:30+02:00","size":2760,"digest":"cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6","integrity":"sha256-zUDjQgJL4Fh/jnoOOQLTLPZwCdNJtnwA9ofgSZ/en/Y="},"lef-small-160cf5b883add60c9c0f4361bd8425c75f6fb23b0e551a0b941fa0491c70e0c9.png":{"logical_path":"lef-small.png","mtime":"2015-03-29T11:07:15+02:00","size":1089,"digest":"160cf5b883add60c9c0f4361bd8425c75f6fb23b0e551a0b941fa0491c70e0c9","integrity":"sha256-Fgz1uIOt1gycD0NhvYQlx19vsjsOVRoLlB+gSRxw4Mk="},"lef-bec4081a11fbef165216827cf72c7a292ad772a77af6b8132e5bc0bbf83cb2d9.png":{"logical_path":"lef.png","mtime":"2016-01-24T11:38:05+01:00","size":8415,"digest":"bec4081a11fbef165216827cf72c7a292ad772a77af6b8132e5bc0bbf83cb2d9","integrity":"sha256-vsQIGhH77xZSFoJ89yx6KSrXcqd69rgTLlvAu/g8stk="},"priorite-logiciel-libre-je-soutiens-april_2_m-6442e454e96ed45cc1ebc40673a6c50bd286b9c28ea6a8b58572e94f7d6459fc.png":{"logical_path":"priorite-logiciel-libre-je-soutiens-april_2_m.png","mtime":"2015-10-22T22:54:30+02:00","size":16952,"digest":"6442e454e96ed45cc1ebc40673a6c50bd286b9c28ea6a8b58572e94f7d6459fc","integrity":"sha256-ZELkVOlu1FzB68QGc6bFC9KGucKOpqi1hXLpT31kWfw="},"team-cb04c7a311f7160c4eb6a281eae68be84f26991dde5d415bb4e205e6726ae275.png":{"logical_path":"team.png","mtime":"2014-07-04T14:08:56+02:00","size":3586,"digest":"cb04c7a311f7160c4eb6a281eae68be84f26991dde5d415bb4e205e6726ae275","integrity":"sha256-ywTHoxH3FgxOtqKB6uaL6E8mmR3eXUFbtOIF5nJq4nU="},"application-917844760c88ae708837ec664e229eebbd170afbde3cc0b9af7b37164545505d.js":{"logical_path":"application.js","mtime":"2016-05-21T22:53:26+02:00","size":2159880,"digest":"917844760c88ae708837ec664e229eebbd170afbde3cc0b9af7b37164545505d","integrity":"sha256-kXhEdgyIrnCIN+xmTiKe670XCvvePMC5r3s3FkVFUF0="},"active_admin/application-50ffc9f86e474cd52ffb7ce3b3572255ad6646ea17097a056f330b540eae402c.js":{"logical_path":"active_admin/application.js","mtime":"2016-05-04T17:49:01+02:00","size":1669,"digest":"50ffc9f86e474cd52ffb7ce3b3572255ad6646ea17097a056f330b540eae402c","integrity":"sha256-UP/J+G5HTNUv+3zjs1ciVa1mRuoXCXoFbzMLVA6uQCw="},"active_admin-68bb37e1af32798e8006da86254602580978bf587ad01d5ae98b3c8eedd8bca9.css":{"logical_path":"active_admin.css","mtime":"2016-05-21T23:41:15+02:00","size":214474,"digest":"68bb37e1af32798e8006da86254602580978bf587ad01d5ae98b3c8eedd8bca9","integrity":"sha256-aLs34a8yeY6ABtqGJUYCWAl4v1h60B1a6Ys8ju3YvKk="},"tinymce-c13c6df7f00dbbdc85771e880b8e9abf2f439376b72f484cd1d397bd6b68e96d.js":{"logical_path":"tinymce.js","mtime":"2016-05-21T23:41:15+02:00","size":944,"digest":"c13c6df7f00dbbdc85771e880b8e9abf2f439376b72f484cd1d397bd6b68e96d","integrity":"sha256-wTxt9/ANu9yFdx6IC46avy9Dk3a3L0hM0dOXvWto6W0="},"application-6670b0eea8f83814e96dbe243e5b8d2407e1db887d5495c5f02add0132ecf236.css":{"logical_path":"application.css","mtime":"2016-05-21T23:41:15+02:00","size":547833,"digest":"6670b0eea8f83814e96dbe243e5b8d2407e1db887d5495c5f02add0132ecf236","integrity":"sha256-ZnCw7qj4OBTpbb4kPluNJAfh24h9VJXF8CrdATLs8jY="},"application-45b9025ce219a47bb28597daeac0f5656ad0e16f5546c42f01dd4644a0f1c23c.js":{"logical_path":"application.js","mtime":"2016-05-21T23:41:15+02:00","size":2159860,"digest":"45b9025ce219a47bb28597daeac0f5656ad0e16f5546c42f01dd4644a0f1c23c","integrity":"sha256-RbkCXOIZpHuyhZfa6sD1ZWrQ4W9VRsQvAd1GRKDxwjw="},"markers-matte-497826545a90e09a240504d14530eba45823b19fd44175e09e27c47cd822ddb9.png":{"logical_path":"markers-matte.png","mtime":"2016-05-21T23:41:15+02:00","size":14323,"digest":"497826545a90e09a240504d14530eba45823b19fd44175e09e27c47cd822ddb9","integrity":"sha256-SXgmVFqQ4JokBQTRRTDrpFgjsZ/UQXXgnifEfNgi3bk="},"markers-matte@2x-948fc8c4426f04f60964ed20394247f45b0b60e575d02398b9b6810e7a29a823.png":{"logical_path":"markers-matte@2x.png","mtime":"2016-05-21T23:41:15+02:00","size":31113,"digest":"948fc8c4426f04f60964ed20394247f45b0b60e575d02398b9b6810e7a29a823","integrity":"sha256-lI/IxEJvBPYJZO0gOUJH9FsLYOV10COYubaBDnopqCM="},"markers-plain-cf233423aa44e75ac0031e77b8ba571cd3331010517e1197e63fb7b06856c1ff.png":{"logical_path":"markers-plain.png","mtime":"2016-05-21T23:41:15+02:00","size":7946,"digest":"cf233423aa44e75ac0031e77b8ba571cd3331010517e1197e63fb7b06856c1ff","integrity":"sha256-zyM0I6pE51rAAx53uLpXHNMzEBBRfhGX5j+3sGhWwf8="},"markers-shadow-8703a2262710f5e3d29e65d2acdf90d6512e159e119d27b8234731d8a6208a20.png":{"logical_path":"markers-shadow.png","mtime":"2016-05-21T23:41:15+02:00","size":535,"digest":"8703a2262710f5e3d29e65d2acdf90d6512e159e119d27b8234731d8a6208a20","integrity":"sha256-hwOiJicQ9ePSnmXSrN+Q1lEuFZ4RnSe4I0cx2KYgiiA="},"markers-shadow@2x-b21a536be27313fb504f69f5899ff0b1245b276571769ac08d6c32c35676e47a.png":{"logical_path":"markers-shadow@2x.png","mtime":"2016-05-21T23:41:15+02:00","size":1469,"digest":"b21a536be27313fb504f69f5899ff0b1245b276571769ac08d6c32c35676e47a","integrity":"sha256-shpTa+JzE/tQT2n1iZ/wsSRbJ2VxdprAjWwyw1Z25Ho="},"markers-soft-e78784e4ed70aaffddd73c315fab590233cc4e7b72388d7dd47a14796fc7c739.png":{"logical_path":"markers-soft.png","mtime":"2016-05-21T23:41:15+02:00","size":41226,"digest":"e78784e4ed70aaffddd73c315fab590233cc4e7b72388d7dd47a14796fc7c739","integrity":"sha256-54eE5O1wqv/d1zwxX6tZAjPMTntyOI191HoUeW/Hxzk="},"markers-soft@2x-c1e77253a8bfbe30cec24885d7046f443b76ebb66f4c961f77083b03f4a5cbaf.png":{"logical_path":"markers-soft@2x.png","mtime":"2016-05-21T23:41:15+02:00","size":66408,"digest":"c1e77253a8bfbe30cec24885d7046f443b76ebb66f4c961f77083b03f4a5cbaf","integrity":"sha256-wedyU6i/vjDOwkiF1wRvRDt267ZvTJYfdwg7A/Sly68="},"webshims/shims/jpicker/images/AlphaBar-34d23568a887827c654ed2ac63ed3857a2cbd690643c471ea4b21c08a1568454.png":{"logical_path":"webshims/shims/jpicker/images/AlphaBar.png","mtime":"2016-05-04T17:48:59+02:00","size":1622,"digest":"34d23568a887827c654ed2ac63ed3857a2cbd690643c471ea4b21c08a1568454","integrity":"sha256-NNI1aKiHgnxlTtKsY+04V6LL1pBkPEcepLIcCKFWhFQ="},"webshims/shims/jpicker/images/Bars-a697469b1a3828d81b3bdaf334ade0637dd6adf9bf45859aeb88a6ffc06b009f.png":{"logical_path":"webshims/shims/jpicker/images/Bars.png","mtime":"2016-05-04T17:48:59+02:00","size":1347,"digest":"a697469b1a3828d81b3bdaf334ade0637dd6adf9bf45859aeb88a6ffc06b009f","integrity":"sha256-ppdGmxo4KNgbO9rzNK3gY33Wrfm/RYWa64im/8BrAJ8="},"webshims/shims/jpicker/images/Maps-538873f6da4e3a26cd5bb92f305f01e0ca0680cd08d488aef3e1eb250d77a968.png":{"logical_path":"webshims/shims/jpicker/images/Maps.png","mtime":"2016-05-04T17:48:59+02:00","size":62011,"digest":"538873f6da4e3a26cd5bb92f305f01e0ca0680cd08d488aef3e1eb250d77a968","integrity":"sha256-U4hz9tpOOibNW7kvMF8B4MoGgM0I1Iiu8+HrJQ13qWg="},"webshims/shims/jpicker/images/NoColor-d266c220953f0b4fe96aeb868b82148e4c2ad380b1ed04d29214602851204e86.png":{"logical_path":"webshims/shims/jpicker/images/NoColor.png","mtime":"2016-05-04T17:48:59+02:00","size":491,"digest":"d266c220953f0b4fe96aeb868b82148e4c2ad380b1ed04d29214602851204e86","integrity":"sha256-0mbCIJU/C0/pauuGi4IUjkwq04Cx7QTSkhRgKFEgToY="},"webshims/shims/jpicker/images/bar-opacity-690f9f36c78c2ebdfe7510739082dd835cc940565b794617a2bcaf93a566d938.png":{"logical_path":"webshims/shims/jpicker/images/bar-opacity.png","mtime":"2016-05-04T17:48:59+02:00","size":96,"digest":"690f9f36c78c2ebdfe7510739082dd835cc940565b794617a2bcaf93a566d938","integrity":"sha256-aQ+fNseMLr3+dRBzkILdg1zJQFZbeUYXoryvk6Vm2Tg="},"webshims/shims/jpicker/images/map-opacity-00182478b4fc3dedc97b9d2c46d9917f82c321110cab01e0f2ad4725978c2fd3.png":{"logical_path":"webshims/shims/jpicker/images/map-opacity.png","mtime":"2016-05-04T17:48:59+02:00","size":139,"digest":"00182478b4fc3dedc97b9d2c46d9917f82c321110cab01e0f2ad4725978c2fd3","integrity":"sha256-ABgkeLT8Pe3Je50sRtmRf4LDIREMqwHg8q1HJZeML9M="},"webshims/shims/jpicker/images/mappoint-25687420458d1f31e399b1bc5a25e95a6dce8b898ed7f9d4361ff6cb430a7c45.gif":{"logical_path":"webshims/shims/jpicker/images/mappoint.gif","mtime":"2016-05-04T17:48:59+02:00","size":93,"digest":"25687420458d1f31e399b1bc5a25e95a6dce8b898ed7f9d4361ff6cb430a7c45","integrity":"sha256-JWh0IEWNHzHjmbG8WiXpWm3Oi4mO1/nUNh/2y0MKfEU="},"webshims/shims/jpicker/images/picker-3aa5592f4e753f0244866a40b9c48fced398d219b8bc5ee76d2d51f9f952c9b2.gif":{"logical_path":"webshims/shims/jpicker/images/picker.gif","mtime":"2016-05-04T17:48:59+02:00","size":146,"digest":"3aa5592f4e753f0244866a40b9c48fced398d219b8bc5ee76d2d51f9f952c9b2","integrity":"sha256-OqVZL051PwJEhmpAucSPztOY0hm4vF7nbS1R+flSybI="},"webshims/shims/jpicker/images/preview-opacity-12751bd440befc7037806e0451e2a2a8577655e3de1b702a2b50514ba2e9628d.png":{"logical_path":"webshims/shims/jpicker/images/preview-opacity.png","mtime":"2016-05-04T17:48:59+02:00","size":79,"digest":"12751bd440befc7037806e0451e2a2a8577655e3de1b702a2b50514ba2e9628d","integrity":"sha256-EnUb1EC+/HA3gG4EUeKiqFd2VePeG3AqK1BRS6LpYo0="},"webshims/shims/jpicker/images/rangearrows-d13aa5195095eb2e0d990d488ff4c5ed65052e6065d709463c97ed0d25cf652b.gif":{"logical_path":"webshims/shims/jpicker/images/rangearrows.gif","mtime":"2016-05-04T17:48:59+02:00","size":76,"digest":"d13aa5195095eb2e0d990d488ff4c5ed65052e6065d709463c97ed0d25cf652b","integrity":"sha256-0TqlGVCV6y4NmQ1Ij/TF7WUFLmBl1wlGPJftDSXPZSs="},"webshims/shims/styles/color-picker-2141bfffae7d9714b5260735c338beb44ed24c5982f267fc1e3158ac4b82079f.png":{"logical_path":"webshims/shims/styles/color-picker.png","mtime":"2016-05-04T17:48:59+02:00","size":338,"digest":"2141bfffae7d9714b5260735c338beb44ed24c5982f267fc1e3158ac4b82079f","integrity":"sha256-IUG//659lxS1Jgc1wzi+tE7STFmC8mf8HjFYrEuCB58="},"webshims/shims/styles/progress-8023960ce5bc957d1f0014859a51e55b9a3ce180bfd3d214a1a0629e2608a446.gif":{"logical_path":"webshims/shims/styles/progress.gif","mtime":"2016-05-04T17:48:59+02:00","size":35832,"digest":"8023960ce5bc957d1f0014859a51e55b9a3ce180bfd3d214a1a0629e2608a446","integrity":"sha256-gCOWDOW8lX0fABSFmlHlW5o84YC/09IUoaBiniYIpEY="},"webshims/shims/styles/progress-a9f7c78ea64c14559c7e683daaba141f50fac42e68e88232e416ca21645d0139.png":{"logical_path":"webshims/shims/styles/progress.png","mtime":"2016-05-04T17:48:59+02:00","size":299,"digest":"a9f7c78ea64c14559c7e683daaba141f50fac42e68e88232e416ca21645d0139","integrity":"sha256-qffHjqZMFFWcfmg9qroUH1D6xC5o6IIy5BbKIWRdATk="},"webshims/shims/styles/transparent-384a16eed212e680374ad9b8529fb3de3422e515b2e10fdc18d7afdba59a1fa9.png":{"logical_path":"webshims/shims/styles/transparent.png","mtime":"2016-05-04T17:48:59+02:00","size":93,"digest":"384a16eed212e680374ad9b8529fb3de3422e515b2e10fdc18d7afdba59a1fa9","integrity":"sha256-OEoW7tIS5oA3Stm4Up+z3jQi5RWy4Q/cGNev26WaH6k="},"jquery-ui/ui-bg_flat_0_aaaaaa_40x100-9a8492a580bf85d3e98ae8861fbd45567e5a1f83eeafcf9574da0399d5f602ab.png":{"logical_path":"jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png","mtime":"2016-05-04T17:48:40+02:00","size":180,"digest":"9a8492a580bf85d3e98ae8861fbd45567e5a1f83eeafcf9574da0399d5f602ab","integrity":"sha256-moSSpYC/hdPpiuiGH71FVn5aH4Pur8+VdNoDmdX2Aqs="},"jquery-ui/ui-bg_flat_75_ffffff_40x100-39ab7ccd9f4e82579da78a9241265df288d8eb65dbbd7cf48aed2d0129887df5.png":{"logical_path":"jquery-ui/ui-bg_flat_75_ffffff_40x100.png","mtime":"2016-05-04T17:48:40+02:00","size":178,"digest":"39ab7ccd9f4e82579da78a9241265df288d8eb65dbbd7cf48aed2d0129887df5","integrity":"sha256-Oat8zZ9Ogledp4qSQSZd8ojY62XbvXz0iu0tASmIffU="},"jquery-ui/ui-bg_glass_55_fbf9ee_1x400-691597e8a40a891ea94d3589976ecfc33e6145c49422443b00ac2b5a0022964c.png":{"logical_path":"jquery-ui/ui-bg_glass_55_fbf9ee_1x400.png","mtime":"2016-05-04T17:48:40+02:00","size":120,"digest":"691597e8a40a891ea94d3589976ecfc33e6145c49422443b00ac2b5a0022964c","integrity":"sha256-aRWX6KQKiR6pTTWJl27Pwz5hRcSUIkQ7AKwrWgAilkw="},"jquery-ui/ui-bg_glass_65_ffffff_1x400-f0e6cd91b837d5c5644d026e5ffeccd907953317cd5c0f689901733afda260b2.png":{"logical_path":"jquery-ui/ui-bg_glass_65_ffffff_1x400.png","mtime":"2016-05-04T17:48:40+02:00","size":105,"digest":"f0e6cd91b837d5c5644d026e5ffeccd907953317cd5c0f689901733afda260b2","integrity":"sha256-8ObNkbg31cVkTQJuX/7M2QeVMxfNXA9omQFzOv2iYLI="},"jquery-ui/ui-bg_glass_75_dadada_1x400-c108f5cbf2dd9ec07a26530695ddd95e1664597ce6c056ae44c162cc2e28cec4.png":{"logical_path":"jquery-ui/ui-bg_glass_75_dadada_1x400.png","mtime":"2016-05-04T17:48:40+02:00","size":111,"digest":"c108f5cbf2dd9ec07a26530695ddd95e1664597ce6c056ae44c162cc2e28cec4","integrity":"sha256-wQj1y/LdnsB6JlMGld3ZXhZkWXzmwFauRMFizC4ozsQ="},"jquery-ui/ui-bg_glass_75_e6e6e6_1x400-ddf5dd4e0ef2b185e8bb0af7b6e90ebe74a84384cb4700658e76e754c8bfe550.png":{"logical_path":"jquery-ui/ui-bg_glass_75_e6e6e6_1x400.png","mtime":"2016-05-04T17:48:40+02:00","size":110,"digest":"ddf5dd4e0ef2b185e8bb0af7b6e90ebe74a84384cb4700658e76e754c8bfe550","integrity":"sha256-3fXdTg7ysYXouwr3tukOvnSoQ4TLRwBljnbnVMi/5VA="},"jquery-ui/ui-bg_glass_95_fef1ec_1x400-f6f1c1bedf1a0f37cfef81d12f5f012869d1ee7c984775a569827a1784d34f5c.png":{"logical_path":"jquery-ui/ui-bg_glass_95_fef1ec_1x400.png","mtime":"2016-05-04T17:48:40+02:00","size":119,"digest":"f6f1c1bedf1a0f37cfef81d12f5f012869d1ee7c984775a569827a1784d34f5c","integrity":"sha256-9vHBvt8aDzfP74HRL18BKGnR7nyYR3WlaYJ6F4TTT1w="},"jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100-54270656df079c4da5182629a080fc633b6f84b87985eb016d25a560e2c38d4a.png":{"logical_path":"jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100.png","mtime":"2016-05-04T17:48:40+02:00","size":101,"digest":"54270656df079c4da5182629a080fc633b6f84b87985eb016d25a560e2c38d4a","integrity":"sha256-VCcGVt8HnE2lGCYpoID8YztvhLh5hesBbSWlYOLDjUo="},"jquery-ui/ui-icons_222222_256x240-57adb0d65f4e91dacfee975d9574422bee7486c8a182d60133728c672f2cdbbc.png":{"logical_path":"jquery-ui/ui-icons_222222_256x240.png","mtime":"2016-05-04T17:48:40+02:00","size":4369,"digest":"57adb0d65f4e91dacfee975d9574422bee7486c8a182d60133728c672f2cdbbc","integrity":"sha256-V62w1l9OkdrP7pddlXRCK+50hsihgtYBM3KMZy8s27w="},"jquery-ui/ui-icons_2e83ff_256x240-20f8c6667afc48aa433ee9eb6d8a0584bdbd6b4a4a9091ff1e6b3adb31e63bd9.png":{"logical_path":"jquery-ui/ui-icons_2e83ff_256x240.png","mtime":"2016-05-04T17:48:40+02:00","size":4369,"digest":"20f8c6667afc48aa433ee9eb6d8a0584bdbd6b4a4a9091ff1e6b3adb31e63bd9","integrity":"sha256-IPjGZnr8SKpDPunrbYoFhL29a0pKkJH/Hms62zHmO9k="},"jquery-ui/ui-icons_454545_256x240-07460e843c3e59aaadbb34231e699e856a2980753c7a47b66447da5d9f93fb7f.png":{"logical_path":"jquery-ui/ui-icons_454545_256x240.png","mtime":"2016-05-04T17:48:40+02:00","size":4369,"digest":"07460e843c3e59aaadbb34231e699e856a2980753c7a47b66447da5d9f93fb7f","integrity":"sha256-B0YOhDw+WaqtuzQjHmmehWopgHU8eke2ZEfaXZ+T+38="},"jquery-ui/ui-icons_888888_256x240-ea2e29625de3463465e93b002b065f5833e05b97f7a052b1c141e754d62e1a8b.png":{"logical_path":"jquery-ui/ui-icons_888888_256x240.png","mtime":"2016-05-04T17:48:40+02:00","size":4369,"digest":"ea2e29625de3463465e93b002b065f5833e05b97f7a052b1c141e754d62e1a8b","integrity":"sha256-6i4pYl3jRjRl6TsAKwZfWDPgW5f3oFKxwUHnVNYuGos="},"jquery-ui/ui-icons_cd0a0a_256x240-1e32c6dbf5d3fd342f27a78aa881550d6412aa207f48468724a6a15402b6041b.png":{"logical_path":"jquery-ui/ui-icons_cd0a0a_256x240.png","mtime":"2016-05-04T17:48:40+02:00","size":4369,"digest":"1e32c6dbf5d3fd342f27a78aa881550d6412aa207f48468724a6a15402b6041b","integrity":"sha256-HjLG2/XT/TQvJ6eKqIFVDWQSqiB/SEaHJKahVAK2BBs="},"tinymce-fce402ebf88064abbd8dc3ed0f0453c56500af684973911190523a24fd61befe.js":{"logical_path":"tinymce.js","mtime":"2016-05-22T00:16:21+02:00","size":944,"digest":"fce402ebf88064abbd8dc3ed0f0453c56500af684973911190523a24fd61befe","integrity":"sha256-/OQC6/iAZKu9jcPtDwRTxWUAr2hJc5ERkFI6JP1hvv4="},"application-d75ab3978be89f2612f0a6d34ebc36e5ff5906daaebebbf9d3e573ca27ad3421.css":{"logical_path":"application.css","mtime":"2016-05-22T00:16:21+02:00","size":548005,"digest":"d75ab3978be89f2612f0a6d34ebc36e5ff5906daaebebbf9d3e573ca27ad3421","integrity":"sha256-11qzl4vonyYS8KbTTrw25f9ZBtquvrv50+VzyietNCE="},"application-32637c5100b1bc8172748b0f9e886308afa905fdd8a0dbd35edc470682db9ce5.js":{"logical_path":"application.js","mtime":"2016-05-22T00:16:21+02:00","size":2159876,"digest":"32637c5100b1bc8172748b0f9e886308afa905fdd8a0dbd35edc470682db9ce5","integrity":"sha256-MmN8UQCxvIFydIsPnohjCK+pBf3YoNvTXtxHBoLbnOU="},"tinymce-981ca10e0cd26c1cc43bd7da0e8a43ced615d0b581f0a9e787cb269fc5a18099.js":{"logical_path":"tinymce.js","mtime":"2016-05-22T00:36:19+02:00","size":944,"digest":"981ca10e0cd26c1cc43bd7da0e8a43ced615d0b581f0a9e787cb269fc5a18099","integrity":"sha256-mByhDgzSbBzEO9faDopDztYV0LWB8Knnh8smn8WhgJk="},"application-99aba05d4f4b6154b108e3700a9a23d7b51b4c2e2c105bfc6ae63c9096a7673c.css":{"logical_path":"application.css","mtime":"2016-05-22T00:36:19+02:00","size":548162,"digest":"99aba05d4f4b6154b108e3700a9a23d7b51b4c2e2c105bfc6ae63c9096a7673c","integrity":"sha256-maugXU9LYVSxCONwCpoj17UbTC4sEFv8auY8kJanZzw="},"application-581c2f0ac27ca40e0308e3833791ce974d41aeaf75764d213928a691390d80ab.js":{"logical_path":"application.js","mtime":"2016-05-22T01:11:38+02:00","size":2160236,"digest":"581c2f0ac27ca40e0308e3833791ce974d41aeaf75764d213928a691390d80ab","integrity":"sha256-WBwvCsJ8pA4DCOODN5HOl01Brq91dk0hOSimkTkNgKs="},"application-a6c4db9b7bd87ad8f4f5f63ab3fce13c0237f4c78cb41140f9dcda4bc55cdcb0.js":{"logical_path":"application.js","mtime":"2016-05-22T01:22:14+02:00","size":2160516,"digest":"a6c4db9b7bd87ad8f4f5f63ab3fce13c0237f4c78cb41140f9dcda4bc55cdcb0","integrity":"sha256-psTbm3vYetj09fY6s/zhPAI39MeMtBFA+dzaS8Vc3LA="},"tinymce-c20f43bdccff8dec0a1ef3d13599f10779df6cd30cab663df34da817bc5383a6.js":{"logical_path":"tinymce.js","mtime":"2016-05-23T01:40:02+02:00","size":948,"digest":"c20f43bdccff8dec0a1ef3d13599f10779df6cd30cab663df34da817bc5383a6","integrity":"sha256-wg9Dvcz/jewKHvPRNZnxB3nfbNMMq2Y9802oF7xTg6Y="},"application-c34c3ba2010790dceea8b71dba0bf37f4895c79e2154218b2d7759d721fa1e59.css":{"logical_path":"application.css","mtime":"2016-05-23T01:40:02+02:00","size":548387,"digest":"c34c3ba2010790dceea8b71dba0bf37f4895c79e2154218b2d7759d721fa1e59","integrity":"sha256-w0w7ogEHkNzuqLcdugvzf0iVx54hVCGLLXdZ1yH6Hlk="},"application-12583549f910cb38404c7ed07661ca2eadbdea267cd3955575a8caffcca548bc.js":{"logical_path":"application.js","mtime":"2016-05-23T01:40:02+02:00","size":2160403,"digest":"12583549f910cb38404c7ed07661ca2eadbdea267cd3955575a8caffcca548bc","integrity":"sha256-Elg1SfkQyzhATH7QdmHKLq296iZ805VVdajK/8ylSLw="},"active_admin-bf38e2138315a470aef9b840765c137a33b1520312a5ef0a981c39addb52fbfb.css":{"logical_path":"active_admin.css","mtime":"2016-05-21T23:41:15+02:00","size":78112,"digest":"bf38e2138315a470aef9b840765c137a33b1520312a5ef0a981c39addb52fbfb","integrity":"sha256-vzjiE4MVpHCu+bhAdlwTejOxUgMSpe8KmBw5rdtS+/s="},"active_admin/print-87c5ffc1d869a919123bcc1dc5ec51b20bc79fd9aeab9eed77e3438c6acd4f68.css":{"logical_path":"active_admin/print.css","mtime":"2016-07-02T17:35:57+02:00","size":5494,"digest":"87c5ffc1d869a919123bcc1dc5ec51b20bc79fd9aeab9eed77e3438c6acd4f68","integrity":"sha256-h8X/wdhpqRkSO8wdxexRsgvHn9muq57td+NDjGrNT2g="},"tinymce-14411a8837640541cea84f572fa1c80fb639542b1155d7bb7b8d4820c6922b66.js":{"logical_path":"tinymce.js","mtime":"2016-06-25T16:51:02+02:00","size":944,"digest":"14411a8837640541cea84f572fa1c80fb639542b1155d7bb7b8d4820c6922b66","integrity":"sha256-FEEaiDdkBUHOqE9XL6HID7Y5VCsRVde7e41IIMaSK2Y="},"application-77ec43cc8949cbfe2e51114c6ca77a85624e6e817085cda6b03e46d9ebebdf25.css":{"logical_path":"application.css","mtime":"2016-07-02T17:04:13+02:00","size":147481,"digest":"77ec43cc8949cbfe2e51114c6ca77a85624e6e817085cda6b03e46d9ebebdf25","integrity":"sha256-d+xDzIlJy/4uURFMbKd6hWJOboFwhc2msD5G2evr3yU="},"application-2ff7281f89f0b69873f09aa96b2121b67d5c245d6be100b00998783e84d58f2d.js":{"logical_path":"application.js","mtime":"2016-06-25T16:51:02+02:00","size":2171260,"digest":"2ff7281f89f0b69873f09aa96b2121b67d5c245d6be100b00998783e84d58f2d","integrity":"sha256-L/coH4nwtphz8JqpayEhtn1cJF1r4QCwCZh4PoTVjy0="},"active_admin-5f668089bbe1957cd779eb439f2df899e5d66673d34ac94110e73ef0ac0e7313.css":{"logical_path":"active_admin.css","mtime":"2016-06-30T21:12:27+02:00","size":78116,"digest":"5f668089bbe1957cd779eb439f2df899e5d66673d34ac94110e73ef0ac0e7313","integrity":"sha256-X2aAibvhlXzXeetDny34meXWZnPTSslBEOc+8KwOcxM="},"active_admin-c99e2b41c14fcaa52c6ca770ae578392abc42e237158ed560ad73d118e502350.js":{"logical_path":"active_admin.js","mtime":"2016-07-02T17:04:13+02:00","size":780523,"digest":"c99e2b41c14fcaa52c6ca770ae578392abc42e237158ed560ad73d118e502350","integrity":"sha256-yZ4rQcFPyqUsbKdwrleDkqvELiNxWO1WCtc9EY5QI1A="},"tinymce-962059b7c757a94ab7ec4ee03bad9a9c4b565a3939172b7c307c72aa4b5ffefb.js":{"logical_path":"tinymce.js","mtime":"2016-07-02T17:04:13+02:00","size":971,"digest":"962059b7c757a94ab7ec4ee03bad9a9c4b565a3939172b7c307c72aa4b5ffefb","integrity":"sha256-liBZt8dXqUq37E7gO62anEtWWjk5Fyt8MHxyqktf/vs="},"baby_gnu_adl-232caf355c30740d5d9b30491887cd546b8849b33ca9bdb6cc71f8a47ea61815.png":{"logical_path":"baby_gnu_adl.png","mtime":"2016-09-11T17:42:49+02:00","size":10155,"digest":"232caf355c30740d5d9b30491887cd546b8849b33ca9bdb6cc71f8a47ea61815","integrity":"sha256-IyyvNVwwdA1dmzBJGIfNVGuISbM8qb22zHH4pH6mGBU="},"baby_gnu_adl-97251005d3225cf1d58b8c497d6b7905dbc9560cc8acd50118fcce60d0a2679e.svg":{"logical_path":"baby_gnu_adl.svg","mtime":"2016-09-11T17:42:49+02:00","size":109635,"digest":"97251005d3225cf1d58b8c497d6b7905dbc9560cc8acd50118fcce60d0a2679e","integrity":"sha256-lyUQBdMiXPHVi4xJfWt5BdvJVgzIrNUBGPzOYNCiZ54="},"application-307219623ded8fdc9ee285ad85d84051e026d5bfc9ff99ad749c917ab9dfcc76.js":{"logical_path":"application.js","mtime":"2016-07-02T17:04:13+02:00","size":2179851,"digest":"307219623ded8fdc9ee285ad85d84051e026d5bfc9ff99ad749c917ab9dfcc76","integrity":"sha256-MHIZYj3tj9ye4oWthdhAUeAm1b/J/5mtdJyRernfzHY="},"tinymce/jquery.tinymce.js":{"logical_path":"tinymce/jquery.tinymce.js","mtime":"2016-06-16T20:47:48+02:00","size":3591,"digest":null},"tinymce/langs/readme.md":{"logical_path":"tinymce/langs/readme.md","mtime":"2016-06-16T20:47:48+02:00","size":151,"digest":null},"tinymce/license.txt":{"logical_path":"tinymce/license.txt","mtime":"2016-06-16T20:47:48+02:00","size":26427,"digest":null},"tinymce/plugins/advlist/plugin.js":{"logical_path":"tinymce/plugins/advlist/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1303,"digest":null},"tinymce/plugins/anchor/plugin.js":{"logical_path":"tinymce/plugins/anchor/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":616,"digest":null},"tinymce/plugins/autolink/plugin.js":{"logical_path":"tinymce/plugins/autolink/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1961,"digest":null},"tinymce/plugins/autoresize/plugin.js":{"logical_path":"tinymce/plugins/autoresize/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1903,"digest":null},"tinymce/plugins/autosave/plugin.js":{"logical_path":"tinymce/plugins/autosave/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":2185,"digest":null},"tinymce/plugins/bbcode/plugin.js":{"logical_path":"tinymce/plugins/bbcode/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":3136,"digest":null},"tinymce/plugins/charmap/plugin.js":{"logical_path":"tinymce/plugins/charmap/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":8194,"digest":null},"tinymce/plugins/code/plugin.js":{"logical_path":"tinymce/plugins/code/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":721,"digest":null},"tinymce/plugins/codesample/css/prism.css":{"logical_path":"tinymce/plugins/codesample/css/prism.css","mtime":"2016-06-16T20:47:48+02:00","size":2289,"digest":null},"tinymce/plugins/codesample/plugin.js":{"logical_path":"tinymce/plugins/codesample/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":20002,"digest":null},"tinymce/plugins/colorpicker/plugin.js":{"logical_path":"tinymce/plugins/colorpicker/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1222,"digest":null},"tinymce/plugins/contextmenu/plugin.js":{"logical_path":"tinymce/plugins/contextmenu/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":891,"digest":null},"tinymce/plugins/directionality/plugin.js":{"logical_path":"tinymce/plugins/directionality/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":726,"digest":null},"tinymce/plugins/emoticons/img/smiley-cool.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-cool.gif","mtime":"2016-06-16T20:47:48+02:00","size":354,"digest":null},"tinymce/plugins/emoticons/img/smiley-cry.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-cry.gif","mtime":"2016-06-16T20:47:48+02:00","size":329,"digest":null},"tinymce/plugins/emoticons/img/smiley-embarassed.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-embarassed.gif","mtime":"2016-06-16T20:47:48+02:00","size":331,"digest":null},"tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif","mtime":"2016-06-16T20:47:48+02:00","size":342,"digest":null},"tinymce/plugins/emoticons/img/smiley-frown.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-frown.gif","mtime":"2016-06-16T20:47:48+02:00","size":340,"digest":null},"tinymce/plugins/emoticons/img/smiley-innocent.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-innocent.gif","mtime":"2016-06-16T20:47:48+02:00","size":336,"digest":null},"tinymce/plugins/emoticons/img/smiley-kiss.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-kiss.gif","mtime":"2016-06-16T20:47:48+02:00","size":338,"digest":null},"tinymce/plugins/emoticons/img/smiley-laughing.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-laughing.gif","mtime":"2016-06-16T20:47:48+02:00","size":343,"digest":null},"tinymce/plugins/emoticons/img/smiley-money-mouth.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-money-mouth.gif","mtime":"2016-06-16T20:47:48+02:00","size":321,"digest":null},"tinymce/plugins/emoticons/img/smiley-sealed.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-sealed.gif","mtime":"2016-06-16T20:47:48+02:00","size":323,"digest":null},"tinymce/plugins/emoticons/img/smiley-smile.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-smile.gif","mtime":"2016-06-16T20:47:48+02:00","size":344,"digest":null},"tinymce/plugins/emoticons/img/smiley-surprised.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-surprised.gif","mtime":"2016-06-16T20:47:48+02:00","size":338,"digest":null},"tinymce/plugins/emoticons/img/smiley-tongue-out.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-tongue-out.gif","mtime":"2016-06-16T20:47:48+02:00","size":328,"digest":null},"tinymce/plugins/emoticons/img/smiley-undecided.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-undecided.gif","mtime":"2016-06-16T20:47:48+02:00","size":337,"digest":null},"tinymce/plugins/emoticons/img/smiley-wink.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-wink.gif","mtime":"2016-06-16T20:47:48+02:00","size":350,"digest":null},"tinymce/plugins/emoticons/img/smiley-yell.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-yell.gif","mtime":"2016-06-16T20:47:48+02:00","size":336,"digest":null},"tinymce/plugins/emoticons/plugin.js":{"logical_path":"tinymce/plugins/emoticons/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":911,"digest":null},"tinymce/plugins/example/dialog.html":{"logical_path":"tinymce/plugins/example/dialog.html","mtime":"2016-06-16T20:47:48+02:00","size":213,"digest":null},"tinymce/plugins/example/plugin.js":{"logical_path":"tinymce/plugins/example/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":658,"digest":null},"tinymce/plugins/example_dependency/plugin.js":{"logical_path":"tinymce/plugins/example_dependency/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":73,"digest":null},"tinymce/plugins/fullpage/plugin.js":{"logical_path":"tinymce/plugins/fullpage/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":6291,"digest":null},"tinymce/plugins/fullscreen/plugin.js":{"logical_path":"tinymce/plugins/fullscreen/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1676,"digest":null},"tinymce/plugins/hr/plugin.js":{"logical_path":"tinymce/plugins/hr/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":322,"digest":null},"tinymce/plugins/image/plugin.js":{"logical_path":"tinymce/plugins/image/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":8169,"digest":null},"tinymce/plugins/imagetools/plugin.js":{"logical_path":"tinymce/plugins/imagetools/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":29669,"digest":null},"tinymce/plugins/importcss/plugin.js":{"logical_path":"tinymce/plugins/importcss/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":2223,"digest":null},"tinymce/plugins/insertdatetime/plugin.js":{"logical_path":"tinymce/plugins/insertdatetime/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1978,"digest":null},"tinymce/plugins/layer/plugin.js":{"logical_path":"tinymce/plugins/layer/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":2857,"digest":null},"tinymce/plugins/legacyoutput/plugin.js":{"logical_path":"tinymce/plugins/legacyoutput/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":3263,"digest":null},"tinymce/plugins/link/plugin.js":{"logical_path":"tinymce/plugins/link/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":4517,"digest":null},"tinymce/plugins/lists/plugin.js":{"logical_path":"tinymce/plugins/lists/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":8578,"digest":null},"tinymce/plugins/media/moxieplayer.swf":{"logical_path":"tinymce/plugins/media/moxieplayer.swf","mtime":"2016-06-16T20:47:48+02:00","size":20017,"digest":null},"tinymce/plugins/media/plugin.js":{"logical_path":"tinymce/plugins/media/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":11696,"digest":null},"tinymce/plugins/nonbreaking/plugin.js":{"logical_path":"tinymce/plugins/nonbreaking/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":655,"digest":null},"tinymce/plugins/noneditable/plugin.js":{"logical_path":"tinymce/plugins/noneditable/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1126,"digest":null},"tinymce/plugins/pagebreak/plugin.js":{"logical_path":"tinymce/plugins/pagebreak/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1230,"digest":null},"tinymce/plugins/paste/plugin.js":{"logical_path":"tinymce/plugins/paste/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":16286,"digest":null},"tinymce/plugins/preview/plugin.js":{"logical_path":"tinymce/plugins/preview/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1602,"digest":null},"tinymce/plugins/print/plugin.js":{"logical_path":"tinymce/plugins/print/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":293,"digest":null},"tinymce/plugins/save/plugin.js":{"logical_path":"tinymce/plugins/save/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1156,"digest":null},"tinymce/plugins/searchreplace/plugin.js":{"logical_path":"tinymce/plugins/searchreplace/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":6493,"digest":null},"tinymce/plugins/spellchecker/plugin.js":{"logical_path":"tinymce/plugins/spellchecker/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":9781,"digest":null},"tinymce/plugins/tabfocus/plugin.js":{"logical_path":"tinymce/plugins/tabfocus/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1270,"digest":null},"tinymce/plugins/table/plugin.js":{"logical_path":"tinymce/plugins/table/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":42808,"digest":null},"tinymce/plugins/template/plugin.js":{"logical_path":"tinymce/plugins/template/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":4445,"digest":null},"tinymce/plugins/textcolor/plugin.js":{"logical_path":"tinymce/plugins/textcolor/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":4145,"digest":null},"tinymce/plugins/textpattern/plugin.js":{"logical_path":"tinymce/plugins/textpattern/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":2751,"digest":null},"tinymce/plugins/visualblocks/css/visualblocks.css":{"logical_path":"tinymce/plugins/visualblocks/css/visualblocks.css","mtime":"2016-06-16T20:47:48+02:00","size":5092,"digest":null},"tinymce/plugins/visualblocks/plugin.js":{"logical_path":"tinymce/plugins/visualblocks/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1153,"digest":null},"tinymce/plugins/visualchars/plugin.js":{"logical_path":"tinymce/plugins/visualchars/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1259,"digest":null},"tinymce/plugins/wordcount/plugin.js":{"logical_path":"tinymce/plugins/wordcount/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":928,"digest":null},"tinymce/skins/lightgray/content.inline.min.css":{"logical_path":"tinymce/skins/lightgray/content.inline.min.css","mtime":"2016-06-16T20:47:48+02:00","size":2676,"digest":null},"tinymce/skins/lightgray/content.min.css":{"logical_path":"tinymce/skins/lightgray/content.min.css","mtime":"2016-06-16T20:47:48+02:00","size":3091,"digest":null},"tinymce/skins/lightgray/fonts/tinymce-small.eot":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce-small.eot","mtime":"2016-06-16T20:47:48+02:00","size":9492,"digest":null},"tinymce/skins/lightgray/fonts/tinymce-small.svg":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce-small.svg","mtime":"2016-06-16T20:47:48+02:00","size":24727,"digest":null},"tinymce/skins/lightgray/fonts/tinymce-small.ttf":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce-small.ttf","mtime":"2016-06-16T20:47:48+02:00","size":9304,"digest":null},"tinymce/skins/lightgray/fonts/tinymce-small.woff":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce-small.woff","mtime":"2016-06-16T20:47:48+02:00","size":9380,"digest":null},"tinymce/skins/lightgray/fonts/tinymce.eot":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce.eot","mtime":"2016-06-16T20:47:48+02:00","size":17292,"digest":null},"tinymce/skins/lightgray/fonts/tinymce.svg":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce.svg","mtime":"2016-06-16T20:47:48+02:00","size":45226,"digest":null},"tinymce/skins/lightgray/fonts/tinymce.ttf":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce.ttf","mtime":"2016-06-16T20:47:48+02:00","size":17128,"digest":null},"tinymce/skins/lightgray/fonts/tinymce.woff":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce.woff","mtime":"2016-06-16T20:47:48+02:00","size":17204,"digest":null},"tinymce/skins/lightgray/img/anchor.gif":{"logical_path":"tinymce/skins/lightgray/img/anchor.gif","mtime":"2016-06-16T20:47:48+02:00","size":53,"digest":null},"tinymce/skins/lightgray/img/loader.gif":{"logical_path":"tinymce/skins/lightgray/img/loader.gif","mtime":"2016-06-16T20:47:48+02:00","size":2608,"digest":null},"tinymce/skins/lightgray/img/object.gif":{"logical_path":"tinymce/skins/lightgray/img/object.gif","mtime":"2016-06-16T20:47:48+02:00","size":152,"digest":null},"tinymce/skins/lightgray/img/trans.gif":{"logical_path":"tinymce/skins/lightgray/img/trans.gif","mtime":"2016-06-16T20:47:48+02:00","size":43,"digest":null},"tinymce/skins/lightgray/skin.ie7.min.css":{"logical_path":"tinymce/skins/lightgray/skin.ie7.min.css","mtime":"2016-06-16T20:47:48+02:00","size":32423,"digest":null},"tinymce/skins/lightgray/skin.min.css":{"logical_path":"tinymce/skins/lightgray/skin.min.css","mtime":"2016-06-16T20:47:48+02:00","size":34503,"digest":null},"tinymce/themes/modern/theme.js":{"logical_path":"tinymce/themes/modern/theme.js","mtime":"2016-06-16T20:47:48+02:00","size":9923,"digest":null},"tinymce/tinymce.js":{"logical_path":"tinymce/tinymce.js","mtime":"2016-06-16T20:47:48+02:00","size":380255,"digest":null},"tinymce/langs/ar.js":{"logical_path":"tinymce/langs/ar.js","mtime":"2016-05-04T17:48:54+02:00","size":17775,"digest":null},"tinymce/langs/ar_SA.js":{"logical_path":"tinymce/langs/ar_SA.js","mtime":"2016-05-04T17:48:54+02:00","size":10002,"digest":null},"tinymce/langs/az.js":{"logical_path":"tinymce/langs/az.js","mtime":"2016-05-04T17:48:54+02:00","size":9679,"digest":null},"tinymce/langs/be.js":{"logical_path":"tinymce/langs/be.js","mtime":"2016-05-04T17:48:54+02:00","size":21063,"digest":null},"tinymce/langs/bg_BG.js":{"logical_path":"tinymce/langs/bg_BG.js","mtime":"2016-05-04T17:48:54+02:00","size":23944,"digest":null},"tinymce/langs/bn_BD.js":{"logical_path":"tinymce/langs/bn_BD.js","mtime":"2016-05-04T17:48:54+02:00","size":6845,"digest":null},"tinymce/langs/bs.js":{"logical_path":"tinymce/langs/bs.js","mtime":"2016-05-04T17:48:54+02:00","size":6969,"digest":null},"tinymce/langs/ca.js":{"logical_path":"tinymce/langs/ca.js","mtime":"2016-05-04T17:48:54+02:00","size":7786,"digest":null},"tinymce/langs/cs.js":{"logical_path":"tinymce/langs/cs.js","mtime":"2016-05-04T17:48:54+02:00","size":8750,"digest":null},"tinymce/langs/cs_CZ.js":{"logical_path":"tinymce/langs/cs_CZ.js","mtime":"2016-05-04T17:48:54+02:00","size":8398,"digest":null},"tinymce/langs/cy.js":{"logical_path":"tinymce/langs/cy.js","mtime":"2016-05-04T17:48:54+02:00","size":6141,"digest":null},"tinymce/langs/da.js":{"logical_path":"tinymce/langs/da.js","mtime":"2016-05-04T17:48:54+02:00","size":7512,"digest":null},"tinymce/langs/de.js":{"logical_path":"tinymce/langs/de.js","mtime":"2016-05-04T17:48:54+02:00","size":8279,"digest":null},"tinymce/langs/de_AT.js":{"logical_path":"tinymce/langs/de_AT.js","mtime":"2016-05-04T17:48:54+02:00","size":8307,"digest":null},"tinymce/langs/dv.js":{"logical_path":"tinymce/langs/dv.js","mtime":"2016-05-04T17:48:54+02:00","size":18099,"digest":null},"tinymce/langs/el.js":{"logical_path":"tinymce/langs/el.js","mtime":"2016-05-04T17:48:54+02:00","size":22972,"digest":null},"tinymce/langs/en_CA.js":{"logical_path":"tinymce/langs/en_CA.js","mtime":"2016-05-04T17:48:54+02:00","size":6915,"digest":null},"tinymce/langs/en_GB.js":{"logical_path":"tinymce/langs/en_GB.js","mtime":"2016-05-04T17:48:54+02:00","size":5906,"digest":null},"tinymce/langs/eo.js":{"logical_path":"tinymce/langs/eo.js","mtime":"2016-05-04T17:48:54+02:00","size":7465,"digest":null},"tinymce/langs/es.js":{"logical_path":"tinymce/langs/es.js","mtime":"2016-05-04T17:48:54+02:00","size":7808,"digest":null},"tinymce/langs/es_MX.js":{"logical_path":"tinymce/langs/es_MX.js","mtime":"2016-05-04T17:48:54+02:00","size":7893,"digest":null},"tinymce/langs/et.js":{"logical_path":"tinymce/langs/et.js","mtime":"2016-05-04T17:48:54+02:00","size":7783,"digest":null},"tinymce/langs/eu.js":{"logical_path":"tinymce/langs/eu.js","mtime":"2016-05-04T17:48:54+02:00","size":7010,"digest":null},"tinymce/langs/fa.js":{"logical_path":"tinymce/langs/fa.js","mtime":"2016-05-04T17:48:54+02:00","size":16461,"digest":null},"tinymce/langs/fa_IR.js":{"logical_path":"tinymce/langs/fa_IR.js","mtime":"2016-05-04T17:48:54+02:00","size":17724,"digest":null},"tinymce/langs/fi.js":{"logical_path":"tinymce/langs/fi.js","mtime":"2016-05-04T17:48:54+02:00","size":8142,"digest":null},"tinymce/langs/fo.js":{"logical_path":"tinymce/langs/fo.js","mtime":"2016-05-04T17:48:54+02:00","size":8043,"digest":null},"tinymce/langs/fr_CH.js":{"logical_path":"tinymce/langs/fr_CH.js","mtime":"2016-05-04T17:48:54+02:00","size":8073,"digest":null},"tinymce/langs/fr_FR.js":{"logical_path":"tinymce/langs/fr_FR.js","mtime":"2016-05-04T17:48:54+02:00","size":8008,"digest":null},"tinymce/langs/ga.js":{"logical_path":"tinymce/langs/ga.js","mtime":"2016-05-04T17:48:54+02:00","size":8590,"digest":null},"tinymce/langs/gd.js":{"logical_path":"tinymce/langs/gd.js","mtime":"2016-05-04T17:48:54+02:00","size":8807,"digest":null},"tinymce/langs/gl.js":{"logical_path":"tinymce/langs/gl.js","mtime":"2016-05-04T17:48:54+02:00","size":7065,"digest":null},"tinymce/langs/he_IL.js":{"logical_path":"tinymce/langs/he_IL.js","mtime":"2016-05-04T17:48:54+02:00","size":16080,"digest":null},"tinymce/langs/hi_IN.js":{"logical_path":"tinymce/langs/hi_IN.js","mtime":"2016-05-04T17:48:54+02:00","size":18457,"digest":null},"tinymce/langs/hr.js":{"logical_path":"tinymce/langs/hr.js","mtime":"2016-05-04T17:48:54+02:00","size":7576,"digest":null},"tinymce/langs/hu_HU.js":{"logical_path":"tinymce/langs/hu_HU.js","mtime":"2016-05-04T17:48:54+02:00","size":9409,"digest":null},"tinymce/langs/hy.js":{"logical_path":"tinymce/langs/hy.js","mtime":"2016-05-04T17:48:54+02:00","size":20374,"digest":null},"tinymce/langs/id.js":{"logical_path":"tinymce/langs/id.js","mtime":"2016-05-04T17:48:54+02:00","size":7140,"digest":null},"tinymce/langs/is_IS.js":{"logical_path":"tinymce/langs/is_IS.js","mtime":"2016-05-04T17:48:54+02:00","size":7927,"digest":null},"tinymce/langs/it.js":{"logical_path":"tinymce/langs/it.js","mtime":"2016-05-04T17:48:54+02:00","size":7597,"digest":null},"tinymce/langs/ja.js":{"logical_path":"tinymce/langs/ja.js","mtime":"2016-05-04T17:48:54+02:00","size":12289,"digest":null},"tinymce/langs/ka_GE.js":{"logical_path":"tinymce/langs/ka_GE.js","mtime":"2016-05-04T17:48:54+02:00","size":21283,"digest":null},"tinymce/langs/kab.js":{"logical_path":"tinymce/langs/kab.js","mtime":"2016-05-04T17:48:54+02:00","size":7390,"digest":null},"tinymce/langs/kk.js":{"logical_path":"tinymce/langs/kk.js","mtime":"2016-05-04T17:48:54+02:00","size":16680,"digest":null},"tinymce/langs/km_KH.js":{"logical_path":"tinymce/langs/km_KH.js","mtime":"2016-05-04T17:48:54+02:00","size":21395,"digest":null},"tinymce/langs/ko.js":{"logical_path":"tinymce/langs/ko.js","mtime":"2016-05-04T17:48:54+02:00","size":10104,"digest":null},"tinymce/langs/ko_KR.js":{"logical_path":"tinymce/langs/ko_KR.js","mtime":"2016-05-04T17:48:54+02:00","size":10004,"digest":null},"tinymce/langs/ku.js":{"logical_path":"tinymce/langs/ku.js","mtime":"2016-05-04T17:48:54+02:00","size":18273,"digest":null},"tinymce/langs/ku_IQ.js":{"logical_path":"tinymce/langs/ku_IQ.js","mtime":"2016-05-04T17:48:54+02:00","size":18363,"digest":null},"tinymce/langs/lb.js":{"logical_path":"tinymce/langs/lb.js","mtime":"2016-05-04T17:48:54+02:00","size":7466,"digest":null},"tinymce/langs/lt.js":{"logical_path":"tinymce/langs/lt.js","mtime":"2016-05-04T17:48:54+02:00","size":8898,"digest":null},"tinymce/langs/lv.js":{"logical_path":"tinymce/langs/lv.js","mtime":"2016-05-04T17:48:54+02:00","size":8281,"digest":null},"tinymce/langs/mk_MK.js":{"logical_path":"tinymce/langs/mk_MK.js","mtime":"2016-05-04T17:48:54+02:00","size":18732,"digest":null},"tinymce/langs/ml.js":{"logical_path":"tinymce/langs/ml.js","mtime":"2016-05-04T17:48:54+02:00","size":7338,"digest":null},"tinymce/langs/ml_IN.js":{"logical_path":"tinymce/langs/ml_IN.js","mtime":"2016-05-04T17:48:54+02:00","size":20018,"digest":null},"tinymce/langs/mn_MN.js":{"logical_path":"tinymce/langs/mn_MN.js","mtime":"2016-05-04T17:48:54+02:00","size":6876,"digest":null},"tinymce/langs/nb_NO.js":{"logical_path":"tinymce/langs/nb_NO.js","mtime":"2016-05-04T17:48:54+02:00","size":7527,"digest":null},"tinymce/langs/nl.js":{"logical_path":"tinymce/langs/nl.js","mtime":"2016-05-04T17:48:54+02:00","size":7234,"digest":null},"tinymce/langs/pl.js":{"logical_path":"tinymce/langs/pl.js","mtime":"2016-05-04T17:48:54+02:00","size":8128,"digest":null},"tinymce/langs/pt_BR.js":{"logical_path":"tinymce/langs/pt_BR.js","mtime":"2016-05-04T17:48:54+02:00","size":8001,"digest":null},"tinymce/langs/pt_PT.js":{"logical_path":"tinymce/langs/pt_PT.js","mtime":"2016-05-04T17:48:54+02:00","size":8144,"digest":null},"tinymce/langs/ro.js":{"logical_path":"tinymce/langs/ro.js","mtime":"2016-05-04T17:48:54+02:00","size":8274,"digest":null},"tinymce/langs/ru.js":{"logical_path":"tinymce/langs/ru.js","mtime":"2016-05-04T17:48:54+02:00","size":22289,"digest":null},"tinymce/langs/ru_RU.js":{"logical_path":"tinymce/langs/ru_RU.js","mtime":"2016-05-04T17:48:54+02:00","size":4954,"digest":null},"tinymce/langs/si_LK.js":{"logical_path":"tinymce/langs/si_LK.js","mtime":"2016-05-04T17:48:54+02:00","size":15855,"digest":null},"tinymce/langs/sk.js":{"logical_path":"tinymce/langs/sk.js","mtime":"2016-05-04T17:48:54+02:00","size":8957,"digest":null},"tinymce/langs/sl_SI.js":{"logical_path":"tinymce/langs/sl_SI.js","mtime":"2016-05-04T17:48:54+02:00","size":7038,"digest":null},"tinymce/langs/sr.js":{"logical_path":"tinymce/langs/sr.js","mtime":"2016-05-04T17:48:54+02:00","size":6335,"digest":null},"tinymce/langs/sv_SE.js":{"logical_path":"tinymce/langs/sv_SE.js","mtime":"2016-05-04T17:48:54+02:00","size":7495,"digest":null},"tinymce/langs/ta.js":{"logical_path":"tinymce/langs/ta.js","mtime":"2016-05-04T17:48:54+02:00","size":22616,"digest":null},"tinymce/langs/ta_IN.js":{"logical_path":"tinymce/langs/ta_IN.js","mtime":"2016-05-04T17:48:54+02:00","size":22619,"digest":null},"tinymce/langs/tg.js":{"logical_path":"tinymce/langs/tg.js","mtime":"2016-05-04T17:48:54+02:00","size":18182,"digest":null},"tinymce/langs/th_TH.js":{"logical_path":"tinymce/langs/th_TH.js","mtime":"2016-05-04T17:48:54+02:00","size":17296,"digest":null},"tinymce/langs/tr.js":{"logical_path":"tinymce/langs/tr.js","mtime":"2016-05-04T17:48:54+02:00","size":8704,"digest":null},"tinymce/langs/tr_TR.js":{"logical_path":"tinymce/langs/tr_TR.js","mtime":"2016-05-04T17:48:54+02:00","size":8140,"digest":null},"tinymce/langs/tt.js":{"logical_path":"tinymce/langs/tt.js","mtime":"2016-05-04T17:48:54+02:00","size":19034,"digest":null},"tinymce/langs/ug.js":{"logical_path":"tinymce/langs/ug.js","mtime":"2016-05-04T17:48:54+02:00","size":16887,"digest":null},"tinymce/langs/uk.js":{"logical_path":"tinymce/langs/uk.js","mtime":"2016-05-04T17:48:54+02:00","size":22263,"digest":null},"tinymce/langs/uk_UA.js":{"logical_path":"tinymce/langs/uk_UA.js","mtime":"2016-05-04T17:48:54+02:00","size":21690,"digest":null},"tinymce/langs/vi.js":{"logical_path":"tinymce/langs/vi.js","mtime":"2016-05-04T17:48:54+02:00","size":9900,"digest":null},"tinymce/langs/vi_VN.js":{"logical_path":"tinymce/langs/vi_VN.js","mtime":"2016-05-04T17:48:54+02:00","size":9898,"digest":null},"tinymce/langs/zh_CN.js":{"logical_path":"tinymce/langs/zh_CN.js","mtime":"2016-05-04T17:48:54+02:00","size":8482,"digest":null},"tinymce/langs/zh_TW.js":{"logical_path":"tinymce/langs/zh_TW.js","mtime":"2016-05-04T17:48:54+02:00","size":9378,"digest":null},"active_admin-5f05779513d42df8ed807ee625244d8e144534286b6c72cecee9151938308901.css":{"logical_path":"active_admin.css","mtime":"2016-09-05T15:15:02+02:00","size":83245,"digest":"5f05779513d42df8ed807ee625244d8e144534286b6c72cecee9151938308901","integrity":"sha256-XwV3lRPULfjtgH7mJSRNjhRFNChrbHLOzukVGTgwiQE="},"active_admin-716bc3a1c121d8ebdfc555d143e5f535aff487ef907952790491e39e34688a2f.js":{"logical_path":"active_admin.js","mtime":"2016-09-11T17:47:25+02:00","size":782423,"digest":"716bc3a1c121d8ebdfc555d143e5f535aff487ef907952790491e39e34688a2f","integrity":"sha256-cWvDocEh2OvfxVXRQ+X1Na/0h++QeVJ5BJHjnjRoii8="},"tinymce-3c6fcceddcfff921cf167b4a7a9f8d6e5f41120414e0180765d28407dbdfb42d.js":{"logical_path":"tinymce.js","mtime":"2016-09-11T17:47:25+02:00","size":971,"digest":"3c6fcceddcfff921cf167b4a7a9f8d6e5f41120414e0180765d28407dbdfb42d","integrity":"sha256-PG/M7dz/+SHPFntKep+Nbl9BEgQU4BgHZdKEB9vftC0="},"application-2fb50a7174d540a1e61def8f3733ef9b16048a46d710d6b766260ee4589d4840.css":{"logical_path":"application.css","mtime":"2016-09-11T17:47:25+02:00","size":147821,"digest":"2fb50a7174d540a1e61def8f3733ef9b16048a46d710d6b766260ee4589d4840","integrity":"sha256-L7UKcXTVQKHmHe+PNzPvmxYEikbXENa3ZiYO5FidSEA="},"application-e0182820be578ba7db1bc56b9933acaa65e9d2ec18d340e667afe68de5d750cc.js":{"logical_path":"application.js","mtime":"2016-09-11T17:47:25+02:00","size":2180166,"digest":"e0182820be578ba7db1bc56b9933acaa65e9d2ec18d340e667afe68de5d750cc","integrity":"sha256-4BgoIL5Xi6fbG8VrmTOsqmXp0uwY00DmZ6/mjeXXUMw="},"tinymce/plugins/emoticons/img/smiley-cool-bb0e93a050a32df7913e4026b3c88a176998e0e3e073ba06e9b73f6c24227c9c.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-cool.gif","mtime":"2016-06-16T20:47:48+02:00","size":354,"digest":"bb0e93a050a32df7913e4026b3c88a176998e0e3e073ba06e9b73f6c24227c9c","integrity":"sha256-uw6ToFCjLfeRPkAms8iKF2mY4OPgc7oG6bc/bCQifJw="},"tinymce/plugins/emoticons/img/smiley-cry-a0c5f3e7a682449c973c9d9f7c46342081c46920686d2353f57aff91ab907f68.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-cry.gif","mtime":"2016-06-16T20:47:48+02:00","size":329,"digest":"a0c5f3e7a682449c973c9d9f7c46342081c46920686d2353f57aff91ab907f68","integrity":"sha256-oMXz56aCRJyXPJ2ffEY0IIHEaSBobSNT9Xr/kauQf2g="},"tinymce/plugins/emoticons/img/smiley-embarassed-d3cafcb50b335672cb5e9f4600ea9ea261dac7828dd28844d4927c393a25618f.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-embarassed.gif","mtime":"2016-06-16T20:47:48+02:00","size":331,"digest":"d3cafcb50b335672cb5e9f4600ea9ea261dac7828dd28844d4927c393a25618f","integrity":"sha256-08r8tQszVnLLXp9GAOqeomHax4KN0ohE1JJ8OTolYY8="},"tinymce/plugins/emoticons/img/smiley-foot-in-mouth-03fe04d3ed533423ac81f05146584b0c451be3d4a30e76687ceef283ed07071f.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif","mtime":"2016-06-16T20:47:48+02:00","size":342,"digest":"03fe04d3ed533423ac81f05146584b0c451be3d4a30e76687ceef283ed07071f","integrity":"sha256-A/4E0+1TNCOsgfBRRlhLDEUb49SjDnZofO7yg+0HBx8="},"tinymce/plugins/emoticons/img/smiley-frown-1b984bf98931dd1debb54461eb9d83e985f2b2999fe14bcb556d6c0921bc83b0.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-frown.gif","mtime":"2016-06-16T20:47:48+02:00","size":340,"digest":"1b984bf98931dd1debb54461eb9d83e985f2b2999fe14bcb556d6c0921bc83b0","integrity":"sha256-G5hL+Ykx3R3rtURh652D6YXyspmf4UvLVW1sCSG8g7A="},"tinymce/plugins/emoticons/img/smiley-innocent-8db353ef102196f2c6ddf5c4666446de955d7b14fc0957c806c9dbfb48fb0c29.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-innocent.gif","mtime":"2016-06-16T20:47:48+02:00","size":336,"digest":"8db353ef102196f2c6ddf5c4666446de955d7b14fc0957c806c9dbfb48fb0c29","integrity":"sha256-jbNT7xAhlvLG3fXEZmRG3pVdexT8CVfIBsnb+0j7DCk="},"tinymce/plugins/emoticons/img/smiley-kiss-3154c3665356c13ab10fefdbac1fe187fff978a0052037c99cdc4a97103413f2.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-kiss.gif","mtime":"2016-06-16T20:47:48+02:00","size":338,"digest":"3154c3665356c13ab10fefdbac1fe187fff978a0052037c99cdc4a97103413f2","integrity":"sha256-MVTDZlNWwTqxD+/brB/hh//5eKAFIDfJnNxKlxA0E/I="},"tinymce/plugins/emoticons/img/smiley-laughing-8f6adedcd091975ffead171867a6304d908bb6541a6ccb4919286ec6b7d4551e.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-laughing.gif","mtime":"2016-06-16T20:47:48+02:00","size":343,"digest":"8f6adedcd091975ffead171867a6304d908bb6541a6ccb4919286ec6b7d4551e","integrity":"sha256-j2re3NCRl1/+rRcYZ6YwTZCLtlQabMtJGShuxrfUVR4="},"tinymce/plugins/emoticons/img/smiley-money-mouth-f0b9f4f22e237f5dbc851f900fed8d7eca4c954ae6fbc606c0cd8be431d0ac80.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-money-mouth.gif","mtime":"2016-06-16T20:47:48+02:00","size":321,"digest":"f0b9f4f22e237f5dbc851f900fed8d7eca4c954ae6fbc606c0cd8be431d0ac80","integrity":"sha256-8Ln08i4jf128hR+QD+2NfspMlUrm+8YGwM2L5DHQrIA="},"tinymce/plugins/emoticons/img/smiley-sealed-9933b442636b6e537df7b564e2c3f7a2873526eea6b022a98eb1e468e5204c32.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-sealed.gif","mtime":"2016-06-16T20:47:48+02:00","size":323,"digest":"9933b442636b6e537df7b564e2c3f7a2873526eea6b022a98eb1e468e5204c32","integrity":"sha256-mTO0QmNrblN997Vk4sP3ooc1Ju6msCKpjrHkaOUgTDI="},"tinymce/plugins/emoticons/img/smiley-smile-fd89cd460ffcacb7e725e00c0275ef5b3924ce468248e5ff4fb43545571cfa65.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-smile.gif","mtime":"2016-06-16T20:47:48+02:00","size":344,"digest":"fd89cd460ffcacb7e725e00c0275ef5b3924ce468248e5ff4fb43545571cfa65","integrity":"sha256-/YnNRg/8rLfnJeAMAnXvWzkkzkaCSOX/T7Q1RVcc+mU="},"tinymce/plugins/emoticons/img/smiley-surprised-3871f356cb41976d7ae8a5f005e8739e4d014352a8adef9b33f773d81b6e6c01.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-surprised.gif","mtime":"2016-06-16T20:47:48+02:00","size":338,"digest":"3871f356cb41976d7ae8a5f005e8739e4d014352a8adef9b33f773d81b6e6c01","integrity":"sha256-OHHzVstBl2166KXwBehznk0BQ1Kore+bM/dz2BtubAE="},"tinymce/plugins/emoticons/img/smiley-tongue-out-5843c85667a8226dc43be83749fd9fbbc5d20b1577de2b763915d99815d37d47.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-tongue-out.gif","mtime":"2016-06-16T20:47:48+02:00","size":328,"digest":"5843c85667a8226dc43be83749fd9fbbc5d20b1577de2b763915d99815d37d47","integrity":"sha256-WEPIVmeoIm3EO+g3Sf2fu8XSCxV33it2ORXZmBXTfUc="},"tinymce/plugins/emoticons/img/smiley-undecided-d8b9bcbb433951ff3c4ca8dd959ac3844239b98e6d52218833e1485a91f67347.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-undecided.gif","mtime":"2016-06-16T20:47:48+02:00","size":337,"digest":"d8b9bcbb433951ff3c4ca8dd959ac3844239b98e6d52218833e1485a91f67347","integrity":"sha256-2Lm8u0M5Uf88TKjdlZrDhEI5uY5tUiGIM+FIWpH2c0c="},"tinymce/plugins/emoticons/img/smiley-wink-2af75ad7b1c08488505513503e34b15f40005e04a2a9568f698f0945d2d8ba1f.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-wink.gif","mtime":"2016-06-16T20:47:48+02:00","size":350,"digest":"2af75ad7b1c08488505513503e34b15f40005e04a2a9568f698f0945d2d8ba1f","integrity":"sha256-Kvda17HAhIhQVRNQPjSxX0AAXgSiqVaPaY8JRdLYuh8="},"tinymce/plugins/emoticons/img/smiley-yell-bba903fbcb46fce8c68b9e01863fd095b3b1d0e6aa72161f3a88d762a5f90a79.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-yell.gif","mtime":"2016-06-16T20:47:48+02:00","size":336,"digest":"bba903fbcb46fce8c68b9e01863fd095b3b1d0e6aa72161f3a88d762a5f90a79","integrity":"sha256-u6kD+8tG/OjGi54Bhj/QlbOx0OaqchYfOojXYqX5Cnk="},"tinymce/skins/lightgray/img/anchor-2861666fd107d278d4449970615136d06d7f746be9bb19072cf9c8f30e565e1e.gif":{"logical_path":"tinymce/skins/lightgray/img/anchor.gif","mtime":"2016-06-16T20:47:48+02:00","size":53,"digest":"2861666fd107d278d4449970615136d06d7f746be9bb19072cf9c8f30e565e1e","integrity":"sha256-KGFmb9EH0njURJlwYVE20G1/dGvpuxkHLPnI8w5WXh4="},"tinymce/skins/lightgray/img/loader-eb7cfd3d959b2e09c170f532e29f8b825f9bc770b2279fde58e595617753e244.gif":{"logical_path":"tinymce/skins/lightgray/img/loader.gif","mtime":"2016-06-16T20:47:48+02:00","size":2608,"digest":"eb7cfd3d959b2e09c170f532e29f8b825f9bc770b2279fde58e595617753e244","integrity":"sha256-63z9PZWbLgnBcPUy4p+Lgl+bx3CyJ5/eWOWVYXdT4kQ="},"tinymce/skins/lightgray/img/object-e6a15e52bc4a17b085073ba8debd4708ead6ae3d4cbeb3880c65cb7afc489777.gif":{"logical_path":"tinymce/skins/lightgray/img/object.gif","mtime":"2016-06-16T20:47:48+02:00","size":152,"digest":"e6a15e52bc4a17b085073ba8debd4708ead6ae3d4cbeb3880c65cb7afc489777","integrity":"sha256-5qFeUrxKF7CFBzuo3r1HCOrWrj1MvrOIDGXLevxIl3c="},"tinymce/skins/lightgray/img/trans-9cf020d7c3bba7f5ab10cda54aabef934f906d4f9a3acf99e9e7dc6c98579635.gif":{"logical_path":"tinymce/skins/lightgray/img/trans.gif","mtime":"2016-06-16T20:47:48+02:00","size":43,"digest":"9cf020d7c3bba7f5ab10cda54aabef934f906d4f9a3acf99e9e7dc6c98579635","integrity":"sha256-nPAg18O7p/WrEM2lSqvvk0+QbU+aOs+Z6efcbJhXljU="},"active_admin/application-3ee24c8b7a313a28f1352e08dc4dc31bd7d4489b6ad5f6331f1f42bbded33a50.js":{"logical_path":"active_admin/application.js","mtime":"2016-07-02T17:35:57+02:00","size":1571,"digest":"3ee24c8b7a313a28f1352e08dc4dc31bd7d4489b6ad5f6331f1f42bbded33a50","integrity":"sha256-PuJMi3oxOijxNS4I3E3DG9fUSJtq1fYzHx9Cu97TOlA="}},"assets":{"active_admin.css":"active_admin-5f05779513d42df8ed807ee625244d8e144534286b6c72cecee9151938308901.css","active_admin/nested_menu_arrow.gif":"active_admin/nested_menu_arrow-15084d93c65c1964d7077700ea748bd2d70cfa2d4c19707c58a9c64e232dd442.gif","active_admin/nested_menu_arrow_dark.gif":"active_admin/nested_menu_arrow_dark-7c43b8e0a5f8823875f49a093c9d7a6b374f885b6f9cc248ae9cd7e6e9b29034.gif","active_admin/datepicker/datepicker-input-icon.png":"active_admin/datepicker/datepicker-input-icon-d9c2bb73769af777c8a71720d29741f3a499aebd5a043e9a119bd0d9597aed47.png","active_admin/orderable.png":"active_admin/orderable-29374dbb55b0012d78a37c614d573bb3474f0779849b478a147d0f1845ca6617.png","active_admin_pagedown/wmd-buttons.png":"active_admin_pagedown/wmd-buttons-c2040b12f2d6cb568ddc33587a070a29a18fed20099260c3ecbbfdbd62042f7b.png","active_admin/print.css":"active_admin/print-87c5ffc1d869a919123bcc1dc5ec51b20bc79fd9aeab9eed77e3438c6acd4f68.css","active_admin.js":"active_admin-716bc3a1c121d8ebdfc555d143e5f535aff487ef907952790491e39e34688a2f.js","layers-2x.png":"layers-2x-0c02a2388f637d21f86e6d4b314ec9a968e7b05ad4c3a005280a3f76c0fd3cb8.png","layers.png":"layers-0908aa2a72a082fb2563a2427a5e4fb247571862b448b80fb6f720af1109923e.png","marker-icon-2x.png":"marker-icon-2x-454dc479e82b487529b6b93d6a9b29ac69ca7b4f5a9d5fdf8e01871f6d216113.png","marker-icon.png":"marker-icon-915e83a6fc798c599e5c9e3f759d6bc065d65151019acd0410d1f4731bcaaf72.png","marker-shadow.png":"marker-shadow-4f340d2d61746333dffe056e074ce1704ae4e47fec5a7de98322fbdbcfcb2b6d.png","tinymce.js":"tinymce-3c6fcceddcfff921cf167b4a7a9f8d6e5f41120414e0180765d28407dbdfb42d.js","application.css":"application-2fb50a7174d540a1e61def8f3733ef9b16048a46d710d6b766260ee4589d4840.css","select2.png":"select2-d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8.png","select2-spinner.gif":"select2-spinner-f6ecff617ec2ba7f559e6f535cad9b70a3f91120737535dab4d4548a6c83576c.gif","select2x2.png":"select2x2-6fe28d687dc0ed4d96016238c608ba1e7198c9c9accfa0b360b78018b9fb9bc2.png","font-awesome/fontawesome-webfont.eot":"font-awesome/fontawesome-webfont-a280856e20cc0af53390b729ca0ac3edbf8fc889a828a379c5d634c91e80c808.eot","font-awesome/fontawesome-webfont.woff2":"font-awesome/fontawesome-webfont-2932abf996373e87fbf2e950876b1962f1b57db954a1643ea68831d9fbb74da4.woff2","font-awesome/fontawesome-webfont.woff":"font-awesome/fontawesome-webfont-35fa8302dd7d3d191ebb7acac543efcfa2b85a0da573b3ab45cc122ffcc45ce5.woff","font-awesome/fontawesome-webfont.ttf":"font-awesome/fontawesome-webfont-8630313bee77f64206067ed80eb6a7c721b0bbfc91c94210966969d4dcc43ba7.ttf","font-awesome/fontawesome-webfont.svg":"font-awesome/fontawesome-webfont-6b0adce775f4d57ac800f23b05af72ced748ae51ba67a65b67b7316f1ed331b3.svg","france.png":"france-f4341a7ec8331161a9c8d5298f808014c3fc9c799b5a29ed95eb56a7f3ccd0df.png","quebec.png":"quebec-776d563b6a4ac4312cae9f0bfe630c20711346e8dbddd41040998eba79f4b588.png","belgique.png":"belgique-3b8b772a522de2cbae7714b35a956faf2c394419b532a14bba982fed3f341091.png","suisse.png":"suisse-58d067f1c3fcdc4000fa13e95896cd5369a2b91aafd314475aa5e29da0b543d1.png","modernizr.js":"modernizr-654222debe8018b12f1993ceddff30dc163a7d5008d79869c399d6d167321f97.js","agendadescommuns.png":"agendadescommuns-cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6.png","alert.png":"alert-762ace9479328243a44061346b64c4d6b997e963c68dfc6bddd9e4d241192906.png","baby_gnu_adl.png":"baby_gnu_adl-232caf355c30740d5d9b30491887cd546b8849b33ca9bdb6cc71f8a47ea61815.png","communs.png":"communs-cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6.png","lef-small.png":"lef-small-160cf5b883add60c9c0f4361bd8425c75f6fb23b0e551a0b941fa0491c70e0c9.png","lef.png":"lef-bec4081a11fbef165216827cf72c7a292ad772a77af6b8132e5bc0bbf83cb2d9.png","priorite-logiciel-libre-je-soutiens-april_2_m.png":"priorite-logiciel-libre-je-soutiens-april_2_m-6442e454e96ed45cc1ebc40673a6c50bd286b9c28ea6a8b58572e94f7d6459fc.png","team.png":"team-cb04c7a311f7160c4eb6a281eae68be84f26991dde5d415bb4e205e6726ae275.png","application.js":"application-e0182820be578ba7db1bc56b9933acaa65e9d2ec18d340e667afe68de5d750cc.js","active_admin/application.js":"active_admin/application-3ee24c8b7a313a28f1352e08dc4dc31bd7d4489b6ad5f6331f1f42bbded33a50.js","tinymce/jquery.tinymce.js":"tinymce/jquery.tinymce.js","tinymce/langs/readme.md":"tinymce/langs/readme.md","tinymce/license.txt":"tinymce/license.txt","tinymce/plugins/advlist/plugin.js":"tinymce/plugins/advlist/plugin.js","tinymce/plugins/anchor/plugin.js":"tinymce/plugins/anchor/plugin.js","tinymce/plugins/autolink/plugin.js":"tinymce/plugins/autolink/plugin.js","tinymce/plugins/autoresize/plugin.js":"tinymce/plugins/autoresize/plugin.js","tinymce/plugins/autosave/plugin.js":"tinymce/plugins/autosave/plugin.js","tinymce/plugins/bbcode/plugin.js":"tinymce/plugins/bbcode/plugin.js","tinymce/plugins/charmap/plugin.js":"tinymce/plugins/charmap/plugin.js","tinymce/plugins/code/plugin.js":"tinymce/plugins/code/plugin.js","tinymce/plugins/codesample/css/prism.css":"tinymce/plugins/codesample/css/prism.css","tinymce/plugins/codesample/plugin.js":"tinymce/plugins/codesample/plugin.js","tinymce/plugins/colorpicker/plugin.js":"tinymce/plugins/colorpicker/plugin.js","tinymce/plugins/contextmenu/plugin.js":"tinymce/plugins/contextmenu/plugin.js","tinymce/plugins/directionality/plugin.js":"tinymce/plugins/directionality/plugin.js","tinymce/plugins/emoticons/img/smiley-cool.gif":"tinymce/plugins/emoticons/img/smiley-cool-bb0e93a050a32df7913e4026b3c88a176998e0e3e073ba06e9b73f6c24227c9c.gif","tinymce/plugins/emoticons/img/smiley-cry.gif":"tinymce/plugins/emoticons/img/smiley-cry-a0c5f3e7a682449c973c9d9f7c46342081c46920686d2353f57aff91ab907f68.gif","tinymce/plugins/emoticons/img/smiley-embarassed.gif":"tinymce/plugins/emoticons/img/smiley-embarassed-d3cafcb50b335672cb5e9f4600ea9ea261dac7828dd28844d4927c393a25618f.gif","tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif":"tinymce/plugins/emoticons/img/smiley-foot-in-mouth-03fe04d3ed533423ac81f05146584b0c451be3d4a30e76687ceef283ed07071f.gif","tinymce/plugins/emoticons/img/smiley-frown.gif":"tinymce/plugins/emoticons/img/smiley-frown-1b984bf98931dd1debb54461eb9d83e985f2b2999fe14bcb556d6c0921bc83b0.gif","tinymce/plugins/emoticons/img/smiley-innocent.gif":"tinymce/plugins/emoticons/img/smiley-innocent-8db353ef102196f2c6ddf5c4666446de955d7b14fc0957c806c9dbfb48fb0c29.gif","tinymce/plugins/emoticons/img/smiley-kiss.gif":"tinymce/plugins/emoticons/img/smiley-kiss-3154c3665356c13ab10fefdbac1fe187fff978a0052037c99cdc4a97103413f2.gif","tinymce/plugins/emoticons/img/smiley-laughing.gif":"tinymce/plugins/emoticons/img/smiley-laughing-8f6adedcd091975ffead171867a6304d908bb6541a6ccb4919286ec6b7d4551e.gif","tinymce/plugins/emoticons/img/smiley-money-mouth.gif":"tinymce/plugins/emoticons/img/smiley-money-mouth-f0b9f4f22e237f5dbc851f900fed8d7eca4c954ae6fbc606c0cd8be431d0ac80.gif","tinymce/plugins/emoticons/img/smiley-sealed.gif":"tinymce/plugins/emoticons/img/smiley-sealed-9933b442636b6e537df7b564e2c3f7a2873526eea6b022a98eb1e468e5204c32.gif","tinymce/plugins/emoticons/img/smiley-smile.gif":"tinymce/plugins/emoticons/img/smiley-smile-fd89cd460ffcacb7e725e00c0275ef5b3924ce468248e5ff4fb43545571cfa65.gif","tinymce/plugins/emoticons/img/smiley-surprised.gif":"tinymce/plugins/emoticons/img/smiley-surprised-3871f356cb41976d7ae8a5f005e8739e4d014352a8adef9b33f773d81b6e6c01.gif","tinymce/plugins/emoticons/img/smiley-tongue-out.gif":"tinymce/plugins/emoticons/img/smiley-tongue-out-5843c85667a8226dc43be83749fd9fbbc5d20b1577de2b763915d99815d37d47.gif","tinymce/plugins/emoticons/img/smiley-undecided.gif":"tinymce/plugins/emoticons/img/smiley-undecided-d8b9bcbb433951ff3c4ca8dd959ac3844239b98e6d52218833e1485a91f67347.gif","tinymce/plugins/emoticons/img/smiley-wink.gif":"tinymce/plugins/emoticons/img/smiley-wink-2af75ad7b1c08488505513503e34b15f40005e04a2a9568f698f0945d2d8ba1f.gif","tinymce/plugins/emoticons/img/smiley-yell.gif":"tinymce/plugins/emoticons/img/smiley-yell-bba903fbcb46fce8c68b9e01863fd095b3b1d0e6aa72161f3a88d762a5f90a79.gif","tinymce/plugins/emoticons/plugin.js":"tinymce/plugins/emoticons/plugin.js","tinymce/plugins/example/dialog.html":"tinymce/plugins/example/dialog.html","tinymce/plugins/example/plugin.js":"tinymce/plugins/example/plugin.js","tinymce/plugins/example_dependency/plugin.js":"tinymce/plugins/example_dependency/plugin.js","tinymce/plugins/fullpage/plugin.js":"tinymce/plugins/fullpage/plugin.js","tinymce/plugins/fullscreen/plugin.js":"tinymce/plugins/fullscreen/plugin.js","tinymce/plugins/hr/plugin.js":"tinymce/plugins/hr/plugin.js","tinymce/plugins/image/plugin.js":"tinymce/plugins/image/plugin.js","tinymce/plugins/imagetools/plugin.js":"tinymce/plugins/imagetools/plugin.js","tinymce/plugins/importcss/plugin.js":"tinymce/plugins/importcss/plugin.js","tinymce/plugins/insertdatetime/plugin.js":"tinymce/plugins/insertdatetime/plugin.js","tinymce/plugins/layer/plugin.js":"tinymce/plugins/layer/plugin.js","tinymce/plugins/legacyoutput/plugin.js":"tinymce/plugins/legacyoutput/plugin.js","tinymce/plugins/link/plugin.js":"tinymce/plugins/link/plugin.js","tinymce/plugins/lists/plugin.js":"tinymce/plugins/lists/plugin.js","tinymce/plugins/media/moxieplayer.swf":"tinymce/plugins/media/moxieplayer.swf","tinymce/plugins/media/plugin.js":"tinymce/plugins/media/plugin.js","tinymce/plugins/nonbreaking/plugin.js":"tinymce/plugins/nonbreaking/plugin.js","tinymce/plugins/noneditable/plugin.js":"tinymce/plugins/noneditable/plugin.js","tinymce/plugins/pagebreak/plugin.js":"tinymce/plugins/pagebreak/plugin.js","tinymce/plugins/paste/plugin.js":"tinymce/plugins/paste/plugin.js","tinymce/plugins/preview/plugin.js":"tinymce/plugins/preview/plugin.js","tinymce/plugins/print/plugin.js":"tinymce/plugins/print/plugin.js","tinymce/plugins/save/plugin.js":"tinymce/plugins/save/plugin.js","tinymce/plugins/searchreplace/plugin.js":"tinymce/plugins/searchreplace/plugin.js","tinymce/plugins/spellchecker/plugin.js":"tinymce/plugins/spellchecker/plugin.js","tinymce/plugins/tabfocus/plugin.js":"tinymce/plugins/tabfocus/plugin.js","tinymce/plugins/table/plugin.js":"tinymce/plugins/table/plugin.js","tinymce/plugins/template/plugin.js":"tinymce/plugins/template/plugin.js","tinymce/plugins/textcolor/plugin.js":"tinymce/plugins/textcolor/plugin.js","tinymce/plugins/textpattern/plugin.js":"tinymce/plugins/textpattern/plugin.js","tinymce/plugins/visualblocks/css/visualblocks.css":"tinymce/plugins/visualblocks/css/visualblocks.css","tinymce/plugins/visualblocks/plugin.js":"tinymce/plugins/visualblocks/plugin.js","tinymce/plugins/visualchars/plugin.js":"tinymce/plugins/visualchars/plugin.js","tinymce/plugins/wordcount/plugin.js":"tinymce/plugins/wordcount/plugin.js","tinymce/skins/lightgray/content.inline.min.css":"tinymce/skins/lightgray/content.inline.min.css","tinymce/skins/lightgray/content.min.css":"tinymce/skins/lightgray/content.min.css","tinymce/skins/lightgray/fonts/tinymce-small.eot":"tinymce/skins/lightgray/fonts/tinymce-small.eot","tinymce/skins/lightgray/fonts/tinymce-small.svg":"tinymce/skins/lightgray/fonts/tinymce-small.svg","tinymce/skins/lightgray/fonts/tinymce-small.ttf":"tinymce/skins/lightgray/fonts/tinymce-small.ttf","tinymce/skins/lightgray/fonts/tinymce-small.woff":"tinymce/skins/lightgray/fonts/tinymce-small.woff","tinymce/skins/lightgray/fonts/tinymce.eot":"tinymce/skins/lightgray/fonts/tinymce.eot","tinymce/skins/lightgray/fonts/tinymce.svg":"tinymce/skins/lightgray/fonts/tinymce.svg","tinymce/skins/lightgray/fonts/tinymce.ttf":"tinymce/skins/lightgray/fonts/tinymce.ttf","tinymce/skins/lightgray/fonts/tinymce.woff":"tinymce/skins/lightgray/fonts/tinymce.woff","tinymce/skins/lightgray/img/anchor.gif":"tinymce/skins/lightgray/img/anchor-2861666fd107d278d4449970615136d06d7f746be9bb19072cf9c8f30e565e1e.gif","tinymce/skins/lightgray/img/loader.gif":"tinymce/skins/lightgray/img/loader-eb7cfd3d959b2e09c170f532e29f8b825f9bc770b2279fde58e595617753e244.gif","tinymce/skins/lightgray/img/object.gif":"tinymce/skins/lightgray/img/object-e6a15e52bc4a17b085073ba8debd4708ead6ae3d4cbeb3880c65cb7afc489777.gif","tinymce/skins/lightgray/img/trans.gif":"tinymce/skins/lightgray/img/trans-9cf020d7c3bba7f5ab10cda54aabef934f906d4f9a3acf99e9e7dc6c98579635.gif","tinymce/skins/lightgray/skin.ie7.min.css":"tinymce/skins/lightgray/skin.ie7.min.css","tinymce/skins/lightgray/skin.min.css":"tinymce/skins/lightgray/skin.min.css","tinymce/themes/modern/theme.js":"tinymce/themes/modern/theme.js","tinymce/tinymce.js":"tinymce/tinymce.js","tinymce/langs/ar.js":"tinymce/langs/ar.js","tinymce/langs/ar_SA.js":"tinymce/langs/ar_SA.js","tinymce/langs/az.js":"tinymce/langs/az.js","tinymce/langs/be.js":"tinymce/langs/be.js","tinymce/langs/bg_BG.js":"tinymce/langs/bg_BG.js","tinymce/langs/bn_BD.js":"tinymce/langs/bn_BD.js","tinymce/langs/bs.js":"tinymce/langs/bs.js","tinymce/langs/ca.js":"tinymce/langs/ca.js","tinymce/langs/cs.js":"tinymce/langs/cs.js","tinymce/langs/cs_CZ.js":"tinymce/langs/cs_CZ.js","tinymce/langs/cy.js":"tinymce/langs/cy.js","tinymce/langs/da.js":"tinymce/langs/da.js","tinymce/langs/de.js":"tinymce/langs/de.js","tinymce/langs/de_AT.js":"tinymce/langs/de_AT.js","tinymce/langs/dv.js":"tinymce/langs/dv.js","tinymce/langs/el.js":"tinymce/langs/el.js","tinymce/langs/en_CA.js":"tinymce/langs/en_CA.js","tinymce/langs/en_GB.js":"tinymce/langs/en_GB.js","tinymce/langs/eo.js":"tinymce/langs/eo.js","tinymce/langs/es.js":"tinymce/langs/es.js","tinymce/langs/es_MX.js":"tinymce/langs/es_MX.js","tinymce/langs/et.js":"tinymce/langs/et.js","tinymce/langs/eu.js":"tinymce/langs/eu.js","tinymce/langs/fa.js":"tinymce/langs/fa.js","tinymce/langs/fa_IR.js":"tinymce/langs/fa_IR.js","tinymce/langs/fi.js":"tinymce/langs/fi.js","tinymce/langs/fo.js":"tinymce/langs/fo.js","tinymce/langs/fr_CH.js":"tinymce/langs/fr_CH.js","tinymce/langs/fr_FR.js":"tinymce/langs/fr_FR.js","tinymce/langs/ga.js":"tinymce/langs/ga.js","tinymce/langs/gd.js":"tinymce/langs/gd.js","tinymce/langs/gl.js":"tinymce/langs/gl.js","tinymce/langs/he_IL.js":"tinymce/langs/he_IL.js","tinymce/langs/hi_IN.js":"tinymce/langs/hi_IN.js","tinymce/langs/hr.js":"tinymce/langs/hr.js","tinymce/langs/hu_HU.js":"tinymce/langs/hu_HU.js","tinymce/langs/hy.js":"tinymce/langs/hy.js","tinymce/langs/id.js":"tinymce/langs/id.js","tinymce/langs/is_IS.js":"tinymce/langs/is_IS.js","tinymce/langs/it.js":"tinymce/langs/it.js","tinymce/langs/ja.js":"tinymce/langs/ja.js","tinymce/langs/ka_GE.js":"tinymce/langs/ka_GE.js","tinymce/langs/kab.js":"tinymce/langs/kab.js","tinymce/langs/kk.js":"tinymce/langs/kk.js","tinymce/langs/km_KH.js":"tinymce/langs/km_KH.js","tinymce/langs/ko.js":"tinymce/langs/ko.js","tinymce/langs/ko_KR.js":"tinymce/langs/ko_KR.js","tinymce/langs/ku.js":"tinymce/langs/ku.js","tinymce/langs/ku_IQ.js":"tinymce/langs/ku_IQ.js","tinymce/langs/lb.js":"tinymce/langs/lb.js","tinymce/langs/lt.js":"tinymce/langs/lt.js","tinymce/langs/lv.js":"tinymce/langs/lv.js","tinymce/langs/mk_MK.js":"tinymce/langs/mk_MK.js","tinymce/langs/ml.js":"tinymce/langs/ml.js","tinymce/langs/ml_IN.js":"tinymce/langs/ml_IN.js","tinymce/langs/mn_MN.js":"tinymce/langs/mn_MN.js","tinymce/langs/nb_NO.js":"tinymce/langs/nb_NO.js","tinymce/langs/nl.js":"tinymce/langs/nl.js","tinymce/langs/pl.js":"tinymce/langs/pl.js","tinymce/langs/pt_BR.js":"tinymce/langs/pt_BR.js","tinymce/langs/pt_PT.js":"tinymce/langs/pt_PT.js","tinymce/langs/ro.js":"tinymce/langs/ro.js","tinymce/langs/ru.js":"tinymce/langs/ru.js","tinymce/langs/ru_RU.js":"tinymce/langs/ru_RU.js","tinymce/langs/si_LK.js":"tinymce/langs/si_LK.js","tinymce/langs/sk.js":"tinymce/langs/sk.js","tinymce/langs/sl_SI.js":"tinymce/langs/sl_SI.js","tinymce/langs/sr.js":"tinymce/langs/sr.js","tinymce/langs/sv_SE.js":"tinymce/langs/sv_SE.js","tinymce/langs/ta.js":"tinymce/langs/ta.js","tinymce/langs/ta_IN.js":"tinymce/langs/ta_IN.js","tinymce/langs/tg.js":"tinymce/langs/tg.js","tinymce/langs/th_TH.js":"tinymce/langs/th_TH.js","tinymce/langs/tr.js":"tinymce/langs/tr.js","tinymce/langs/tr_TR.js":"tinymce/langs/tr_TR.js","tinymce/langs/tt.js":"tinymce/langs/tt.js","tinymce/langs/ug.js":"tinymce/langs/ug.js","tinymce/langs/uk.js":"tinymce/langs/uk.js","tinymce/langs/uk_UA.js":"tinymce/langs/uk_UA.js","tinymce/langs/vi.js":"tinymce/langs/vi.js","tinymce/langs/vi_VN.js":"tinymce/langs/vi_VN.js","tinymce/langs/zh_CN.js":"tinymce/langs/zh_CN.js","tinymce/langs/zh_TW.js":"tinymce/langs/zh_TW.js","markers-matte.png":"markers-matte-497826545a90e09a240504d14530eba45823b19fd44175e09e27c47cd822ddb9.png","markers-matte@2x.png":"markers-matte@2x-948fc8c4426f04f60964ed20394247f45b0b60e575d02398b9b6810e7a29a823.png","markers-plain.png":"markers-plain-cf233423aa44e75ac0031e77b8ba571cd3331010517e1197e63fb7b06856c1ff.png","markers-shadow.png":"markers-shadow-8703a2262710f5e3d29e65d2acdf90d6512e159e119d27b8234731d8a6208a20.png","markers-shadow@2x.png":"markers-shadow@2x-b21a536be27313fb504f69f5899ff0b1245b276571769ac08d6c32c35676e47a.png","markers-soft.png":"markers-soft-e78784e4ed70aaffddd73c315fab590233cc4e7b72388d7dd47a14796fc7c739.png","markers-soft@2x.png":"markers-soft@2x-c1e77253a8bfbe30cec24885d7046f443b76ebb66f4c961f77083b03f4a5cbaf.png","webshims/shims/jpicker/images/AlphaBar.png":"webshims/shims/jpicker/images/AlphaBar-34d23568a887827c654ed2ac63ed3857a2cbd690643c471ea4b21c08a1568454.png","webshims/shims/jpicker/images/Bars.png":"webshims/shims/jpicker/images/Bars-a697469b1a3828d81b3bdaf334ade0637dd6adf9bf45859aeb88a6ffc06b009f.png","webshims/shims/jpicker/images/Maps.png":"webshims/shims/jpicker/images/Maps-538873f6da4e3a26cd5bb92f305f01e0ca0680cd08d488aef3e1eb250d77a968.png","webshims/shims/jpicker/images/NoColor.png":"webshims/shims/jpicker/images/NoColor-d266c220953f0b4fe96aeb868b82148e4c2ad380b1ed04d29214602851204e86.png","webshims/shims/jpicker/images/bar-opacity.png":"webshims/shims/jpicker/images/bar-opacity-690f9f36c78c2ebdfe7510739082dd835cc940565b794617a2bcaf93a566d938.png","webshims/shims/jpicker/images/map-opacity.png":"webshims/shims/jpicker/images/map-opacity-00182478b4fc3dedc97b9d2c46d9917f82c321110cab01e0f2ad4725978c2fd3.png","webshims/shims/jpicker/images/mappoint.gif":"webshims/shims/jpicker/images/mappoint-25687420458d1f31e399b1bc5a25e95a6dce8b898ed7f9d4361ff6cb430a7c45.gif","webshims/shims/jpicker/images/picker.gif":"webshims/shims/jpicker/images/picker-3aa5592f4e753f0244866a40b9c48fced398d219b8bc5ee76d2d51f9f952c9b2.gif","webshims/shims/jpicker/images/preview-opacity.png":"webshims/shims/jpicker/images/preview-opacity-12751bd440befc7037806e0451e2a2a8577655e3de1b702a2b50514ba2e9628d.png","webshims/shims/jpicker/images/rangearrows.gif":"webshims/shims/jpicker/images/rangearrows-d13aa5195095eb2e0d990d488ff4c5ed65052e6065d709463c97ed0d25cf652b.gif","webshims/shims/styles/color-picker.png":"webshims/shims/styles/color-picker-2141bfffae7d9714b5260735c338beb44ed24c5982f267fc1e3158ac4b82079f.png","webshims/shims/styles/progress.gif":"webshims/shims/styles/progress-8023960ce5bc957d1f0014859a51e55b9a3ce180bfd3d214a1a0629e2608a446.gif","webshims/shims/styles/progress.png":"webshims/shims/styles/progress-a9f7c78ea64c14559c7e683daaba141f50fac42e68e88232e416ca21645d0139.png","webshims/shims/styles/transparent.png":"webshims/shims/styles/transparent-384a16eed212e680374ad9b8529fb3de3422e515b2e10fdc18d7afdba59a1fa9.png","jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png":"jquery-ui/ui-bg_flat_0_aaaaaa_40x100-9a8492a580bf85d3e98ae8861fbd45567e5a1f83eeafcf9574da0399d5f602ab.png","jquery-ui/ui-bg_flat_75_ffffff_40x100.png":"jquery-ui/ui-bg_flat_75_ffffff_40x100-39ab7ccd9f4e82579da78a9241265df288d8eb65dbbd7cf48aed2d0129887df5.png","jquery-ui/ui-bg_glass_55_fbf9ee_1x400.png":"jquery-ui/ui-bg_glass_55_fbf9ee_1x400-691597e8a40a891ea94d3589976ecfc33e6145c49422443b00ac2b5a0022964c.png","jquery-ui/ui-bg_glass_65_ffffff_1x400.png":"jquery-ui/ui-bg_glass_65_ffffff_1x400-f0e6cd91b837d5c5644d026e5ffeccd907953317cd5c0f689901733afda260b2.png","jquery-ui/ui-bg_glass_75_dadada_1x400.png":"jquery-ui/ui-bg_glass_75_dadada_1x400-c108f5cbf2dd9ec07a26530695ddd95e1664597ce6c056ae44c162cc2e28cec4.png","jquery-ui/ui-bg_glass_75_e6e6e6_1x400.png":"jquery-ui/ui-bg_glass_75_e6e6e6_1x400-ddf5dd4e0ef2b185e8bb0af7b6e90ebe74a84384cb4700658e76e754c8bfe550.png","jquery-ui/ui-bg_glass_95_fef1ec_1x400.png":"jquery-ui/ui-bg_glass_95_fef1ec_1x400-f6f1c1bedf1a0f37cfef81d12f5f012869d1ee7c984775a569827a1784d34f5c.png","jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100.png":"jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100-54270656df079c4da5182629a080fc633b6f84b87985eb016d25a560e2c38d4a.png","jquery-ui/ui-icons_222222_256x240.png":"jquery-ui/ui-icons_222222_256x240-57adb0d65f4e91dacfee975d9574422bee7486c8a182d60133728c672f2cdbbc.png","jquery-ui/ui-icons_2e83ff_256x240.png":"jquery-ui/ui-icons_2e83ff_256x240-20f8c6667afc48aa433ee9eb6d8a0584bdbd6b4a4a9091ff1e6b3adb31e63bd9.png","jquery-ui/ui-icons_454545_256x240.png":"jquery-ui/ui-icons_454545_256x240-07460e843c3e59aaadbb34231e699e856a2980753c7a47b66447da5d9f93fb7f.png","jquery-ui/ui-icons_888888_256x240.png":"jquery-ui/ui-icons_888888_256x240-ea2e29625de3463465e93b002b065f5833e05b97f7a052b1c141e754d62e1a8b.png","jquery-ui/ui-icons_cd0a0a_256x240.png":"jquery-ui/ui-icons_cd0a0a_256x240-1e32c6dbf5d3fd342f27a78aa881550d6412aa207f48468724a6a15402b6041b.png","baby_gnu_adl.svg":"baby_gnu_adl-97251005d3225cf1d58b8c497d6b7905dbc9560cc8acd50118fcce60d0a2679e.svg"}} \ No newline at end of file diff --git a/public/assets/.sprockets-manifest-cc0c9f43a35675d2248a689be654ce22.json b/public/assets/.sprockets-manifest-cc0c9f43a35675d2248a689be654ce22.json index cd2e8de42..e7613eb35 100644 --- a/public/assets/.sprockets-manifest-cc0c9f43a35675d2248a689be654ce22.json +++ b/public/assets/.sprockets-manifest-cc0c9f43a35675d2248a689be654ce22.json @@ -1 +1 @@ -{"files":{"active_admin-617b799bade586fce74b4e0121a99adb6ff69314ffc69f4e24529028a7b72538.css":{"logical_path":"active_admin.css","mtime":"2016-05-19T21:35:29+02:00","size":214498,"digest":"617b799bade586fce74b4e0121a99adb6ff69314ffc69f4e24529028a7b72538","integrity":"sha256-YXt5m63lhvznS04BIama22/2kxT/xp9OJFKQKKe3JTg="},"active_admin/nested_menu_arrow-15084d93c65c1964d7077700ea748bd2d70cfa2d4c19707c58a9c64e232dd442.gif":{"logical_path":"active_admin/nested_menu_arrow.gif","mtime":"2016-06-30T21:12:27+02:00","size":70,"digest":"15084d93c65c1964d7077700ea748bd2d70cfa2d4c19707c58a9c64e232dd442","integrity":"sha256-FQhNk8ZcGWTXB3cA6nSL0tcM+i1MGXB8WKnGTiMt1EI="},"active_admin/nested_menu_arrow_dark-7c43b8e0a5f8823875f49a093c9d7a6b374f885b6f9cc248ae9cd7e6e9b29034.gif":{"logical_path":"active_admin/nested_menu_arrow_dark.gif","mtime":"2016-06-30T21:12:27+02:00","size":70,"digest":"7c43b8e0a5f8823875f49a093c9d7a6b374f885b6f9cc248ae9cd7e6e9b29034","integrity":"sha256-fEO44KX4gjh19JoJPJ16azdPiFtvnMJIrpzX5umykDQ="},"active_admin/datepicker/datepicker-input-icon-d9c2bb73769af777c8a71720d29741f3a499aebd5a043e9a119bd0d9597aed47.png":{"logical_path":"active_admin/datepicker/datepicker-input-icon.png","mtime":"2016-06-30T21:12:27+02:00","size":1535,"digest":"d9c2bb73769af777c8a71720d29741f3a499aebd5a043e9a119bd0d9597aed47","integrity":"sha256-2cK7c3aa93fIpxcg0pdB86SZrr1aBD6aEZvQ2Vl67Uc="},"active_admin/orderable-29374dbb55b0012d78a37c614d573bb3474f0779849b478a147d0f1845ca6617.png":{"logical_path":"active_admin/orderable.png","mtime":"2016-06-30T21:12:27+02:00","size":220,"digest":"29374dbb55b0012d78a37c614d573bb3474f0779849b478a147d0f1845ca6617","integrity":"sha256-KTdNu1WwAS14o3xhTVc7s0dPB3mEm0eKFH0PGEXKZhc="},"active_admin_pagedown/wmd-buttons-c2040b12f2d6cb568ddc33587a070a29a18fed20099260c3ecbbfdbd62042f7b.png":{"logical_path":"active_admin_pagedown/wmd-buttons.png","mtime":"2016-05-04T17:49:02+02:00","size":7465,"digest":"c2040b12f2d6cb568ddc33587a070a29a18fed20099260c3ecbbfdbd62042f7b","integrity":"sha256-wgQLEvLWy1aN3DNYegcKKaGP7SAJkmDD7Lv9vWIEL3s="},"active_admin/print-cb755dcaacb896fb80d996ba6eee250ea19ee816526e5e5d0137ed2af34d08f1.css":{"logical_path":"active_admin/print.css","mtime":"2016-05-04T17:49:01+02:00","size":18961,"digest":"cb755dcaacb896fb80d996ba6eee250ea19ee816526e5e5d0137ed2af34d08f1","integrity":"sha256-y3Vdyqy4lvuA2Za6bu4lDqGe6BZSbl5dATftKvNNCPE="},"active_admin-3ac0f1eff2fd35f310a1bd2242c049f9d2cc006c7b1065541a5d855556e24393.js":{"logical_path":"active_admin.js","mtime":"2016-06-25T16:51:02+02:00","size":771406,"digest":"3ac0f1eff2fd35f310a1bd2242c049f9d2cc006c7b1065541a5d855556e24393","integrity":"sha256-OsDx7/L9NfMQob0iQsBJ+dLMAGx7EGVUGl2FVVbiQ5M="},"layers-2x-0c02a2388f637d21f86e6d4b314ec9a968e7b05ad4c3a005280a3f76c0fd3cb8.png":{"logical_path":"layers-2x.png","mtime":"2016-05-04T17:44:43+02:00","size":2898,"digest":"0c02a2388f637d21f86e6d4b314ec9a968e7b05ad4c3a005280a3f76c0fd3cb8","integrity":"sha256-DAKiOI9jfSH4bm1LMU7JqWjnsFrUw6AFKAo/dsD9PLg="},"layers-0908aa2a72a082fb2563a2427a5e4fb247571862b448b80fb6f720af1109923e.png":{"logical_path":"layers.png","mtime":"2016-05-04T17:44:43+02:00","size":1502,"digest":"0908aa2a72a082fb2563a2427a5e4fb247571862b448b80fb6f720af1109923e","integrity":"sha256-CQiqKnKggvslY6JCel5PskdXGGK0SLgPtvcgrxEJkj4="},"marker-icon-2x-454dc479e82b487529b6b93d6a9b29ac69ca7b4f5a9d5fdf8e01871f6d216113.png":{"logical_path":"marker-icon-2x.png","mtime":"2016-05-04T17:44:43+02:00","size":4033,"digest":"454dc479e82b487529b6b93d6a9b29ac69ca7b4f5a9d5fdf8e01871f6d216113","integrity":"sha256-RU3EeegrSHUptrk9apsprGnKe09anV/fjgGHH20hYRM="},"marker-icon-915e83a6fc798c599e5c9e3f759d6bc065d65151019acd0410d1f4731bcaaf72.png":{"logical_path":"marker-icon.png","mtime":"2016-05-04T17:44:43+02:00","size":1747,"digest":"915e83a6fc798c599e5c9e3f759d6bc065d65151019acd0410d1f4731bcaaf72","integrity":"sha256-kV6Dpvx5jFmeXJ4/dZ1rwGXWUVEBms0EENH0cxvKr3I="},"marker-shadow-4f340d2d61746333dffe056e074ce1704ae4e47fec5a7de98322fbdbcfcb2b6d.png":{"logical_path":"marker-shadow.png","mtime":"2016-05-04T17:44:43+02:00","size":797,"digest":"4f340d2d61746333dffe056e074ce1704ae4e47fec5a7de98322fbdbcfcb2b6d","integrity":"sha256-TzQNLWF0YzPf/gVuB0zhcErk5H/sWn3pgyL728/LK20="},"tinymce-fe1156fd03b1a543924116118d1f4e0607f5f5c93ae1c7fc3f6715678aeafa22.js":{"logical_path":"tinymce.js","mtime":"2016-05-19T21:35:43+02:00","size":948,"digest":"fe1156fd03b1a543924116118d1f4e0607f5f5c93ae1c7fc3f6715678aeafa22","integrity":"sha256-/hFW/QOxpUOSQRYRjR9OBgf19ck64cf8P2cVZ4rq+iI="},"application-04dae2e3e83d47a4e01f16d1fd7598a83a4d7c9c52947b77c44f3203a27ea744.css":{"logical_path":"application.css","mtime":"2016-05-19T21:35:43+02:00","size":435929,"digest":"04dae2e3e83d47a4e01f16d1fd7598a83a4d7c9c52947b77c44f3203a27ea744","integrity":"sha256-BNri4+g9R6TgHxbR/XWYqDpNfJxSlHt3xE8yA6J+p0Q="},"select2-d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8.png":{"logical_path":"select2.png","mtime":"2016-05-04T17:45:07+02:00","size":613,"digest":"d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8","integrity":"sha256-1rXY2D28GPuNd8h2HTMc2eUSPJaElQurBAbpiiSsWug="},"select2-spinner-f6ecff617ec2ba7f559e6f535cad9b70a3f91120737535dab4d4548a6c83576c.gif":{"logical_path":"select2-spinner.gif","mtime":"2016-05-04T17:45:07+02:00","size":1849,"digest":"f6ecff617ec2ba7f559e6f535cad9b70a3f91120737535dab4d4548a6c83576c","integrity":"sha256-9uz/YX7Cun9Vnm9TXK2bcKP5ESBzdTXatNRUimyDV2w="},"select2x2-6fe28d687dc0ed4d96016238c608ba1e7198c9c9accfa0b360b78018b9fb9bc2.png":{"logical_path":"select2x2.png","mtime":"2016-05-04T17:45:07+02:00","size":845,"digest":"6fe28d687dc0ed4d96016238c608ba1e7198c9c9accfa0b360b78018b9fb9bc2","integrity":"sha256-b+KNaH3A7U2WAWI4xgi6HnGYycmsz6CzYLeAGLn7m8I="},"font-awesome/fontawesome-webfont-a280856e20cc0af53390b729ca0ac3edbf8fc889a828a379c5d634c91e80c808.eot":{"logical_path":"font-awesome/fontawesome-webfont.eot","mtime":"2016-05-19T21:35:29+02:00","size":76204,"digest":"a280856e20cc0af53390b729ca0ac3edbf8fc889a828a379c5d634c91e80c808","integrity":"sha256-ooCFbiDMCvUzkLcpygrD7b+PyImoKKN5xdY0yR6AyAg="},"font-awesome/fontawesome-webfont-2932abf996373e87fbf2e950876b1962f1b57db954a1643ea68831d9fbb74da4.woff2":{"logical_path":"font-awesome/fontawesome-webfont.woff2","mtime":"2016-05-19T21:35:29+02:00","size":71760,"digest":"2932abf996373e87fbf2e950876b1962f1b57db954a1643ea68831d9fbb74da4","integrity":"sha256-KTKr+ZY3Pof78ulQh2sZYvG1fblUoWQ+pogx2fu3TaQ="},"font-awesome/fontawesome-webfont-35fa8302dd7d3d191ebb7acac543efcfa2b85a0da573b3ab45cc122ffcc45ce5.woff":{"logical_path":"font-awesome/fontawesome-webfont.woff","mtime":"2016-05-19T21:35:29+02:00","size":90144,"digest":"35fa8302dd7d3d191ebb7acac543efcfa2b85a0da573b3ab45cc122ffcc45ce5","integrity":"sha256-NfqDAt19PRkeu3rKxUPvz6K4Wg2lc7OrRcwSL/zEXOU="},"font-awesome/fontawesome-webfont-8630313bee77f64206067ed80eb6a7c721b0bbfc91c94210966969d4dcc43ba7.ttf":{"logical_path":"font-awesome/fontawesome-webfont.ttf","mtime":"2016-05-19T21:35:29+02:00","size":152364,"digest":"8630313bee77f64206067ed80eb6a7c721b0bbfc91c94210966969d4dcc43ba7","integrity":"sha256-hjAxO+539kIGBn7YDranxyGwu/yRyUIQlmlp1NzEO6c="},"font-awesome/fontawesome-webfont-6b0adce775f4d57ac800f23b05af72ced748ae51ba67a65b67b7316f1ed331b3.svg":{"logical_path":"font-awesome/fontawesome-webfont.svg","mtime":"2016-05-19T21:35:29+02:00","size":390452,"digest":"6b0adce775f4d57ac800f23b05af72ced748ae51ba67a65b67b7316f1ed331b3","integrity":"sha256-awrc53X01XrIAPI7Ba9yztdIrlG6Z6ZbZ7cxbx7TMbM="},"france-f4341a7ec8331161a9c8d5298f808014c3fc9c799b5a29ed95eb56a7f3ccd0df.png":{"logical_path":"france.png","mtime":"2014-07-04T14:08:56+02:00","size":276,"digest":"f4341a7ec8331161a9c8d5298f808014c3fc9c799b5a29ed95eb56a7f3ccd0df","integrity":"sha256-9DQafsgzEWGpyNUpj4CAFMP8nHmbWintletWp/PM0N8="},"quebec-776d563b6a4ac4312cae9f0bfe630c20711346e8dbddd41040998eba79f4b588.png":{"logical_path":"quebec.png","mtime":"2015-10-22T22:54:30+02:00","size":567,"digest":"776d563b6a4ac4312cae9f0bfe630c20711346e8dbddd41040998eba79f4b588","integrity":"sha256-d21WO2pKxDEsrp8L/mMMIHETRujb3dQQQJmOunn0tYg="},"belgique-3b8b772a522de2cbae7714b35a956faf2c394419b532a14bba982fed3f341091.png":{"logical_path":"belgique.png","mtime":"2014-07-04T14:08:56+02:00","size":187,"digest":"3b8b772a522de2cbae7714b35a956faf2c394419b532a14bba982fed3f341091","integrity":"sha256-O4t3KlIt4suudxSzWpVvryw5RBm1MqFLupgv7T80EJE="},"suisse-58d067f1c3fcdc4000fa13e95896cd5369a2b91aafd314475aa5e29da0b543d1.png":{"logical_path":"suisse.png","mtime":"2015-10-22T22:54:30+02:00","size":299,"digest":"58d067f1c3fcdc4000fa13e95896cd5369a2b91aafd314475aa5e29da0b543d1","integrity":"sha256-WNBn8cP83EAA+hPpWJbNU2miuRqv0xRHWqXinaC1Q9E="},"modernizr-654222debe8018b12f1993ceddff30dc163a7d5008d79869c399d6d167321f97.js":{"logical_path":"modernizr.js","mtime":"2016-05-04T17:44:47+02:00","size":51365,"digest":"654222debe8018b12f1993ceddff30dc163a7d5008d79869c399d6d167321f97","integrity":"sha256-ZUIi3r6AGLEvGZPO3f8w3BY6fVAI15hpw5nW0WcyH5c="},"agendadescommuns-cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6.png":{"logical_path":"agendadescommuns.png","mtime":"2015-10-22T22:54:30+02:00","size":2760,"digest":"cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6","integrity":"sha256-zUDjQgJL4Fh/jnoOOQLTLPZwCdNJtnwA9ofgSZ/en/Y="},"alert-762ace9479328243a44061346b64c4d6b997e963c68dfc6bddd9e4d241192906.png":{"logical_path":"alert.png","mtime":"2014-07-04T14:08:56+02:00","size":47876,"digest":"762ace9479328243a44061346b64c4d6b997e963c68dfc6bddd9e4d241192906","integrity":"sha256-dirOlHkygkOkQGE0a2TE1rmX6WPGjfxr3dnk0kEZKQY="},"baby_gnu_adl-ff3fa5912b3f9164dcdebca6f4fe3f4195e6dae5e3c22c8361bef1d79626ea07.png":{"logical_path":"baby_gnu_adl.png","mtime":"2015-10-22T22:54:17+02:00","size":11494,"digest":"ff3fa5912b3f9164dcdebca6f4fe3f4195e6dae5e3c22c8361bef1d79626ea07","integrity":"sha256-/z+lkSs/kWTc3rym9P4/QZXm2uXjwiyDYb7x15Ym6gc="},"communs-cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6.png":{"logical_path":"communs.png","mtime":"2015-10-22T22:54:30+02:00","size":2760,"digest":"cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6","integrity":"sha256-zUDjQgJL4Fh/jnoOOQLTLPZwCdNJtnwA9ofgSZ/en/Y="},"lef-small-160cf5b883add60c9c0f4361bd8425c75f6fb23b0e551a0b941fa0491c70e0c9.png":{"logical_path":"lef-small.png","mtime":"2015-03-29T11:07:15+02:00","size":1089,"digest":"160cf5b883add60c9c0f4361bd8425c75f6fb23b0e551a0b941fa0491c70e0c9","integrity":"sha256-Fgz1uIOt1gycD0NhvYQlx19vsjsOVRoLlB+gSRxw4Mk="},"lef-bec4081a11fbef165216827cf72c7a292ad772a77af6b8132e5bc0bbf83cb2d9.png":{"logical_path":"lef.png","mtime":"2016-01-24T11:38:05+01:00","size":8415,"digest":"bec4081a11fbef165216827cf72c7a292ad772a77af6b8132e5bc0bbf83cb2d9","integrity":"sha256-vsQIGhH77xZSFoJ89yx6KSrXcqd69rgTLlvAu/g8stk="},"priorite-logiciel-libre-je-soutiens-april_2_m-6442e454e96ed45cc1ebc40673a6c50bd286b9c28ea6a8b58572e94f7d6459fc.png":{"logical_path":"priorite-logiciel-libre-je-soutiens-april_2_m.png","mtime":"2015-10-22T22:54:30+02:00","size":16952,"digest":"6442e454e96ed45cc1ebc40673a6c50bd286b9c28ea6a8b58572e94f7d6459fc","integrity":"sha256-ZELkVOlu1FzB68QGc6bFC9KGucKOpqi1hXLpT31kWfw="},"team-cb04c7a311f7160c4eb6a281eae68be84f26991dde5d415bb4e205e6726ae275.png":{"logical_path":"team.png","mtime":"2014-07-04T14:08:56+02:00","size":3586,"digest":"cb04c7a311f7160c4eb6a281eae68be84f26991dde5d415bb4e205e6726ae275","integrity":"sha256-ywTHoxH3FgxOtqKB6uaL6E8mmR3eXUFbtOIF5nJq4nU="},"application-0df2b8e7bf544e75ad6a6bdcc25bc16667215248d72850df1c004024352f9bfb.js":{"logical_path":"application.js","mtime":"2016-05-19T21:35:43+02:00","size":2155420,"digest":"0df2b8e7bf544e75ad6a6bdcc25bc16667215248d72850df1c004024352f9bfb","integrity":"sha256-DfK4579UTnWtamvcwlvBZmchUkjXKFDfHABAJDUvm/s="},"active_admin/application-50ffc9f86e474cd52ffb7ce3b3572255ad6646ea17097a056f330b540eae402c.js":{"logical_path":"active_admin/application.js","mtime":"2016-05-04T17:49:01+02:00","size":1669,"digest":"50ffc9f86e474cd52ffb7ce3b3572255ad6646ea17097a056f330b540eae402c","integrity":"sha256-UP/J+G5HTNUv+3zjs1ciVa1mRuoXCXoFbzMLVA6uQCw="},"tinymce-851b4961ce4c9997bc39867507ab34eb00de363cb3aab1b32a6b1c91ebf6733b.js":{"logical_path":"tinymce.js","mtime":"2016-05-21T22:53:26+02:00","size":948,"digest":"851b4961ce4c9997bc39867507ab34eb00de363cb3aab1b32a6b1c91ebf6733b","integrity":"sha256-hRtJYc5MmZe8OYZ1B6s06wDeNjyzqrGzKmsckev2czs="},"application-ee82c1c962333e87dcfc9a0eb1abbc739ed57ba7b77732ece49ab08b6cedf706.css":{"logical_path":"application.css","mtime":"2016-05-21T19:55:46+02:00","size":548037,"digest":"ee82c1c962333e87dcfc9a0eb1abbc739ed57ba7b77732ece49ab08b6cedf706","integrity":"sha256-7oLByWIzPofc/JoOsau8c57Ve6e3dzLs5Jqwi2zt9wY="},"application-917844760c88ae708837ec664e229eebbd170afbde3cc0b9af7b37164545505d.js":{"logical_path":"application.js","mtime":"2016-05-21T22:53:26+02:00","size":2159880,"digest":"917844760c88ae708837ec664e229eebbd170afbde3cc0b9af7b37164545505d","integrity":"sha256-kXhEdgyIrnCIN+xmTiKe670XCvvePMC5r3s3FkVFUF0="},"tinymce-b27c22af98a4be3cb8e2bc170a3dbc1f0c616e5405f637b9576f1a7f7ce13e00.js":{"logical_path":"tinymce.js","mtime":"2016-05-21T23:41:15+02:00","size":944,"digest":"b27c22af98a4be3cb8e2bc170a3dbc1f0c616e5405f637b9576f1a7f7ce13e00","integrity":"sha256-snwir5ikvjy44rwXCj28HwxhblQF9je5V28af3zhPgA="},"application-49e7e5af3b02eaa9e0c86ce8722922fd79170115d3e29f8696296467642c48f3.css":{"logical_path":"application.css","mtime":"2016-05-21T23:41:15+02:00","size":547973,"digest":"49e7e5af3b02eaa9e0c86ce8722922fd79170115d3e29f8696296467642c48f3","integrity":"sha256-SeflrzsC6qngyGzociki/XkXARXT4p+GlilkZ2QsSPM="},"application-5ec5b625b2030b1eb3f3370cfae1c263b197bd007490ab6251a3056a1583cb1f.js":{"logical_path":"application.js","mtime":"2016-05-21T23:41:15+02:00","size":2159876,"digest":"5ec5b625b2030b1eb3f3370cfae1c263b197bd007490ab6251a3056a1583cb1f","integrity":"sha256-XsW2JbIDCx6z8zcM+uHCY7GXvQB0kKtiUaMFahWDyx8="},"active_admin-68bb37e1af32798e8006da86254602580978bf587ad01d5ae98b3c8eedd8bca9.css":{"logical_path":"active_admin.css","mtime":"2016-05-21T23:41:15+02:00","size":214474,"digest":"68bb37e1af32798e8006da86254602580978bf587ad01d5ae98b3c8eedd8bca9","integrity":"sha256-aLs34a8yeY6ABtqGJUYCWAl4v1h60B1a6Ys8ju3YvKk="},"tinymce-c13c6df7f00dbbdc85771e880b8e9abf2f439376b72f484cd1d397bd6b68e96d.js":{"logical_path":"tinymce.js","mtime":"2016-05-21T23:41:15+02:00","size":944,"digest":"c13c6df7f00dbbdc85771e880b8e9abf2f439376b72f484cd1d397bd6b68e96d","integrity":"sha256-wTxt9/ANu9yFdx6IC46avy9Dk3a3L0hM0dOXvWto6W0="},"application-6670b0eea8f83814e96dbe243e5b8d2407e1db887d5495c5f02add0132ecf236.css":{"logical_path":"application.css","mtime":"2016-05-21T23:41:15+02:00","size":547833,"digest":"6670b0eea8f83814e96dbe243e5b8d2407e1db887d5495c5f02add0132ecf236","integrity":"sha256-ZnCw7qj4OBTpbb4kPluNJAfh24h9VJXF8CrdATLs8jY="},"application-45b9025ce219a47bb28597daeac0f5656ad0e16f5546c42f01dd4644a0f1c23c.js":{"logical_path":"application.js","mtime":"2016-05-21T23:41:15+02:00","size":2159860,"digest":"45b9025ce219a47bb28597daeac0f5656ad0e16f5546c42f01dd4644a0f1c23c","integrity":"sha256-RbkCXOIZpHuyhZfa6sD1ZWrQ4W9VRsQvAd1GRKDxwjw="},"markers-matte-497826545a90e09a240504d14530eba45823b19fd44175e09e27c47cd822ddb9.png":{"logical_path":"markers-matte.png","mtime":"2016-05-21T23:41:15+02:00","size":14323,"digest":"497826545a90e09a240504d14530eba45823b19fd44175e09e27c47cd822ddb9","integrity":"sha256-SXgmVFqQ4JokBQTRRTDrpFgjsZ/UQXXgnifEfNgi3bk="},"markers-matte@2x-948fc8c4426f04f60964ed20394247f45b0b60e575d02398b9b6810e7a29a823.png":{"logical_path":"markers-matte@2x.png","mtime":"2016-05-21T23:41:15+02:00","size":31113,"digest":"948fc8c4426f04f60964ed20394247f45b0b60e575d02398b9b6810e7a29a823","integrity":"sha256-lI/IxEJvBPYJZO0gOUJH9FsLYOV10COYubaBDnopqCM="},"markers-plain-cf233423aa44e75ac0031e77b8ba571cd3331010517e1197e63fb7b06856c1ff.png":{"logical_path":"markers-plain.png","mtime":"2016-05-21T23:41:15+02:00","size":7946,"digest":"cf233423aa44e75ac0031e77b8ba571cd3331010517e1197e63fb7b06856c1ff","integrity":"sha256-zyM0I6pE51rAAx53uLpXHNMzEBBRfhGX5j+3sGhWwf8="},"markers-shadow-8703a2262710f5e3d29e65d2acdf90d6512e159e119d27b8234731d8a6208a20.png":{"logical_path":"markers-shadow.png","mtime":"2016-05-21T23:41:15+02:00","size":535,"digest":"8703a2262710f5e3d29e65d2acdf90d6512e159e119d27b8234731d8a6208a20","integrity":"sha256-hwOiJicQ9ePSnmXSrN+Q1lEuFZ4RnSe4I0cx2KYgiiA="},"markers-shadow@2x-b21a536be27313fb504f69f5899ff0b1245b276571769ac08d6c32c35676e47a.png":{"logical_path":"markers-shadow@2x.png","mtime":"2016-05-21T23:41:15+02:00","size":1469,"digest":"b21a536be27313fb504f69f5899ff0b1245b276571769ac08d6c32c35676e47a","integrity":"sha256-shpTa+JzE/tQT2n1iZ/wsSRbJ2VxdprAjWwyw1Z25Ho="},"markers-soft-e78784e4ed70aaffddd73c315fab590233cc4e7b72388d7dd47a14796fc7c739.png":{"logical_path":"markers-soft.png","mtime":"2016-05-21T23:41:15+02:00","size":41226,"digest":"e78784e4ed70aaffddd73c315fab590233cc4e7b72388d7dd47a14796fc7c739","integrity":"sha256-54eE5O1wqv/d1zwxX6tZAjPMTntyOI191HoUeW/Hxzk="},"markers-soft@2x-c1e77253a8bfbe30cec24885d7046f443b76ebb66f4c961f77083b03f4a5cbaf.png":{"logical_path":"markers-soft@2x.png","mtime":"2016-05-21T23:41:15+02:00","size":66408,"digest":"c1e77253a8bfbe30cec24885d7046f443b76ebb66f4c961f77083b03f4a5cbaf","integrity":"sha256-wedyU6i/vjDOwkiF1wRvRDt267ZvTJYfdwg7A/Sly68="},"webshims/shims/jpicker/images/AlphaBar-34d23568a887827c654ed2ac63ed3857a2cbd690643c471ea4b21c08a1568454.png":{"logical_path":"webshims/shims/jpicker/images/AlphaBar.png","mtime":"2016-05-04T17:48:59+02:00","size":1622,"digest":"34d23568a887827c654ed2ac63ed3857a2cbd690643c471ea4b21c08a1568454","integrity":"sha256-NNI1aKiHgnxlTtKsY+04V6LL1pBkPEcepLIcCKFWhFQ="},"webshims/shims/jpicker/images/Bars-a697469b1a3828d81b3bdaf334ade0637dd6adf9bf45859aeb88a6ffc06b009f.png":{"logical_path":"webshims/shims/jpicker/images/Bars.png","mtime":"2016-05-04T17:48:59+02:00","size":1347,"digest":"a697469b1a3828d81b3bdaf334ade0637dd6adf9bf45859aeb88a6ffc06b009f","integrity":"sha256-ppdGmxo4KNgbO9rzNK3gY33Wrfm/RYWa64im/8BrAJ8="},"webshims/shims/jpicker/images/Maps-538873f6da4e3a26cd5bb92f305f01e0ca0680cd08d488aef3e1eb250d77a968.png":{"logical_path":"webshims/shims/jpicker/images/Maps.png","mtime":"2016-05-04T17:48:59+02:00","size":62011,"digest":"538873f6da4e3a26cd5bb92f305f01e0ca0680cd08d488aef3e1eb250d77a968","integrity":"sha256-U4hz9tpOOibNW7kvMF8B4MoGgM0I1Iiu8+HrJQ13qWg="},"webshims/shims/jpicker/images/NoColor-d266c220953f0b4fe96aeb868b82148e4c2ad380b1ed04d29214602851204e86.png":{"logical_path":"webshims/shims/jpicker/images/NoColor.png","mtime":"2016-05-04T17:48:59+02:00","size":491,"digest":"d266c220953f0b4fe96aeb868b82148e4c2ad380b1ed04d29214602851204e86","integrity":"sha256-0mbCIJU/C0/pauuGi4IUjkwq04Cx7QTSkhRgKFEgToY="},"webshims/shims/jpicker/images/bar-opacity-690f9f36c78c2ebdfe7510739082dd835cc940565b794617a2bcaf93a566d938.png":{"logical_path":"webshims/shims/jpicker/images/bar-opacity.png","mtime":"2016-05-04T17:48:59+02:00","size":96,"digest":"690f9f36c78c2ebdfe7510739082dd835cc940565b794617a2bcaf93a566d938","integrity":"sha256-aQ+fNseMLr3+dRBzkILdg1zJQFZbeUYXoryvk6Vm2Tg="},"webshims/shims/jpicker/images/map-opacity-00182478b4fc3dedc97b9d2c46d9917f82c321110cab01e0f2ad4725978c2fd3.png":{"logical_path":"webshims/shims/jpicker/images/map-opacity.png","mtime":"2016-05-04T17:48:59+02:00","size":139,"digest":"00182478b4fc3dedc97b9d2c46d9917f82c321110cab01e0f2ad4725978c2fd3","integrity":"sha256-ABgkeLT8Pe3Je50sRtmRf4LDIREMqwHg8q1HJZeML9M="},"webshims/shims/jpicker/images/mappoint-25687420458d1f31e399b1bc5a25e95a6dce8b898ed7f9d4361ff6cb430a7c45.gif":{"logical_path":"webshims/shims/jpicker/images/mappoint.gif","mtime":"2016-05-04T17:48:59+02:00","size":93,"digest":"25687420458d1f31e399b1bc5a25e95a6dce8b898ed7f9d4361ff6cb430a7c45","integrity":"sha256-JWh0IEWNHzHjmbG8WiXpWm3Oi4mO1/nUNh/2y0MKfEU="},"webshims/shims/jpicker/images/picker-3aa5592f4e753f0244866a40b9c48fced398d219b8bc5ee76d2d51f9f952c9b2.gif":{"logical_path":"webshims/shims/jpicker/images/picker.gif","mtime":"2016-05-04T17:48:59+02:00","size":146,"digest":"3aa5592f4e753f0244866a40b9c48fced398d219b8bc5ee76d2d51f9f952c9b2","integrity":"sha256-OqVZL051PwJEhmpAucSPztOY0hm4vF7nbS1R+flSybI="},"webshims/shims/jpicker/images/preview-opacity-12751bd440befc7037806e0451e2a2a8577655e3de1b702a2b50514ba2e9628d.png":{"logical_path":"webshims/shims/jpicker/images/preview-opacity.png","mtime":"2016-05-04T17:48:59+02:00","size":79,"digest":"12751bd440befc7037806e0451e2a2a8577655e3de1b702a2b50514ba2e9628d","integrity":"sha256-EnUb1EC+/HA3gG4EUeKiqFd2VePeG3AqK1BRS6LpYo0="},"webshims/shims/jpicker/images/rangearrows-d13aa5195095eb2e0d990d488ff4c5ed65052e6065d709463c97ed0d25cf652b.gif":{"logical_path":"webshims/shims/jpicker/images/rangearrows.gif","mtime":"2016-05-04T17:48:59+02:00","size":76,"digest":"d13aa5195095eb2e0d990d488ff4c5ed65052e6065d709463c97ed0d25cf652b","integrity":"sha256-0TqlGVCV6y4NmQ1Ij/TF7WUFLmBl1wlGPJftDSXPZSs="},"webshims/shims/styles/color-picker-2141bfffae7d9714b5260735c338beb44ed24c5982f267fc1e3158ac4b82079f.png":{"logical_path":"webshims/shims/styles/color-picker.png","mtime":"2016-05-04T17:48:59+02:00","size":338,"digest":"2141bfffae7d9714b5260735c338beb44ed24c5982f267fc1e3158ac4b82079f","integrity":"sha256-IUG//659lxS1Jgc1wzi+tE7STFmC8mf8HjFYrEuCB58="},"webshims/shims/styles/progress-8023960ce5bc957d1f0014859a51e55b9a3ce180bfd3d214a1a0629e2608a446.gif":{"logical_path":"webshims/shims/styles/progress.gif","mtime":"2016-05-04T17:48:59+02:00","size":35832,"digest":"8023960ce5bc957d1f0014859a51e55b9a3ce180bfd3d214a1a0629e2608a446","integrity":"sha256-gCOWDOW8lX0fABSFmlHlW5o84YC/09IUoaBiniYIpEY="},"webshims/shims/styles/progress-a9f7c78ea64c14559c7e683daaba141f50fac42e68e88232e416ca21645d0139.png":{"logical_path":"webshims/shims/styles/progress.png","mtime":"2016-05-04T17:48:59+02:00","size":299,"digest":"a9f7c78ea64c14559c7e683daaba141f50fac42e68e88232e416ca21645d0139","integrity":"sha256-qffHjqZMFFWcfmg9qroUH1D6xC5o6IIy5BbKIWRdATk="},"webshims/shims/styles/transparent-384a16eed212e680374ad9b8529fb3de3422e515b2e10fdc18d7afdba59a1fa9.png":{"logical_path":"webshims/shims/styles/transparent.png","mtime":"2016-05-04T17:48:59+02:00","size":93,"digest":"384a16eed212e680374ad9b8529fb3de3422e515b2e10fdc18d7afdba59a1fa9","integrity":"sha256-OEoW7tIS5oA3Stm4Up+z3jQi5RWy4Q/cGNev26WaH6k="},"jquery-ui/ui-bg_flat_0_aaaaaa_40x100-9a8492a580bf85d3e98ae8861fbd45567e5a1f83eeafcf9574da0399d5f602ab.png":{"logical_path":"jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png","mtime":"2016-05-04T17:48:40+02:00","size":180,"digest":"9a8492a580bf85d3e98ae8861fbd45567e5a1f83eeafcf9574da0399d5f602ab","integrity":"sha256-moSSpYC/hdPpiuiGH71FVn5aH4Pur8+VdNoDmdX2Aqs="},"jquery-ui/ui-bg_flat_75_ffffff_40x100-39ab7ccd9f4e82579da78a9241265df288d8eb65dbbd7cf48aed2d0129887df5.png":{"logical_path":"jquery-ui/ui-bg_flat_75_ffffff_40x100.png","mtime":"2016-05-04T17:48:40+02:00","size":178,"digest":"39ab7ccd9f4e82579da78a9241265df288d8eb65dbbd7cf48aed2d0129887df5","integrity":"sha256-Oat8zZ9Ogledp4qSQSZd8ojY62XbvXz0iu0tASmIffU="},"jquery-ui/ui-bg_glass_55_fbf9ee_1x400-691597e8a40a891ea94d3589976ecfc33e6145c49422443b00ac2b5a0022964c.png":{"logical_path":"jquery-ui/ui-bg_glass_55_fbf9ee_1x400.png","mtime":"2016-05-04T17:48:40+02:00","size":120,"digest":"691597e8a40a891ea94d3589976ecfc33e6145c49422443b00ac2b5a0022964c","integrity":"sha256-aRWX6KQKiR6pTTWJl27Pwz5hRcSUIkQ7AKwrWgAilkw="},"jquery-ui/ui-bg_glass_65_ffffff_1x400-f0e6cd91b837d5c5644d026e5ffeccd907953317cd5c0f689901733afda260b2.png":{"logical_path":"jquery-ui/ui-bg_glass_65_ffffff_1x400.png","mtime":"2016-05-04T17:48:40+02:00","size":105,"digest":"f0e6cd91b837d5c5644d026e5ffeccd907953317cd5c0f689901733afda260b2","integrity":"sha256-8ObNkbg31cVkTQJuX/7M2QeVMxfNXA9omQFzOv2iYLI="},"jquery-ui/ui-bg_glass_75_dadada_1x400-c108f5cbf2dd9ec07a26530695ddd95e1664597ce6c056ae44c162cc2e28cec4.png":{"logical_path":"jquery-ui/ui-bg_glass_75_dadada_1x400.png","mtime":"2016-05-04T17:48:40+02:00","size":111,"digest":"c108f5cbf2dd9ec07a26530695ddd95e1664597ce6c056ae44c162cc2e28cec4","integrity":"sha256-wQj1y/LdnsB6JlMGld3ZXhZkWXzmwFauRMFizC4ozsQ="},"jquery-ui/ui-bg_glass_75_e6e6e6_1x400-ddf5dd4e0ef2b185e8bb0af7b6e90ebe74a84384cb4700658e76e754c8bfe550.png":{"logical_path":"jquery-ui/ui-bg_glass_75_e6e6e6_1x400.png","mtime":"2016-05-04T17:48:40+02:00","size":110,"digest":"ddf5dd4e0ef2b185e8bb0af7b6e90ebe74a84384cb4700658e76e754c8bfe550","integrity":"sha256-3fXdTg7ysYXouwr3tukOvnSoQ4TLRwBljnbnVMi/5VA="},"jquery-ui/ui-bg_glass_95_fef1ec_1x400-f6f1c1bedf1a0f37cfef81d12f5f012869d1ee7c984775a569827a1784d34f5c.png":{"logical_path":"jquery-ui/ui-bg_glass_95_fef1ec_1x400.png","mtime":"2016-05-04T17:48:40+02:00","size":119,"digest":"f6f1c1bedf1a0f37cfef81d12f5f012869d1ee7c984775a569827a1784d34f5c","integrity":"sha256-9vHBvt8aDzfP74HRL18BKGnR7nyYR3WlaYJ6F4TTT1w="},"jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100-54270656df079c4da5182629a080fc633b6f84b87985eb016d25a560e2c38d4a.png":{"logical_path":"jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100.png","mtime":"2016-05-04T17:48:40+02:00","size":101,"digest":"54270656df079c4da5182629a080fc633b6f84b87985eb016d25a560e2c38d4a","integrity":"sha256-VCcGVt8HnE2lGCYpoID8YztvhLh5hesBbSWlYOLDjUo="},"jquery-ui/ui-icons_222222_256x240-57adb0d65f4e91dacfee975d9574422bee7486c8a182d60133728c672f2cdbbc.png":{"logical_path":"jquery-ui/ui-icons_222222_256x240.png","mtime":"2016-05-04T17:48:40+02:00","size":4369,"digest":"57adb0d65f4e91dacfee975d9574422bee7486c8a182d60133728c672f2cdbbc","integrity":"sha256-V62w1l9OkdrP7pddlXRCK+50hsihgtYBM3KMZy8s27w="},"jquery-ui/ui-icons_2e83ff_256x240-20f8c6667afc48aa433ee9eb6d8a0584bdbd6b4a4a9091ff1e6b3adb31e63bd9.png":{"logical_path":"jquery-ui/ui-icons_2e83ff_256x240.png","mtime":"2016-05-04T17:48:40+02:00","size":4369,"digest":"20f8c6667afc48aa433ee9eb6d8a0584bdbd6b4a4a9091ff1e6b3adb31e63bd9","integrity":"sha256-IPjGZnr8SKpDPunrbYoFhL29a0pKkJH/Hms62zHmO9k="},"jquery-ui/ui-icons_454545_256x240-07460e843c3e59aaadbb34231e699e856a2980753c7a47b66447da5d9f93fb7f.png":{"logical_path":"jquery-ui/ui-icons_454545_256x240.png","mtime":"2016-05-04T17:48:40+02:00","size":4369,"digest":"07460e843c3e59aaadbb34231e699e856a2980753c7a47b66447da5d9f93fb7f","integrity":"sha256-B0YOhDw+WaqtuzQjHmmehWopgHU8eke2ZEfaXZ+T+38="},"jquery-ui/ui-icons_888888_256x240-ea2e29625de3463465e93b002b065f5833e05b97f7a052b1c141e754d62e1a8b.png":{"logical_path":"jquery-ui/ui-icons_888888_256x240.png","mtime":"2016-05-04T17:48:40+02:00","size":4369,"digest":"ea2e29625de3463465e93b002b065f5833e05b97f7a052b1c141e754d62e1a8b","integrity":"sha256-6i4pYl3jRjRl6TsAKwZfWDPgW5f3oFKxwUHnVNYuGos="},"jquery-ui/ui-icons_cd0a0a_256x240-1e32c6dbf5d3fd342f27a78aa881550d6412aa207f48468724a6a15402b6041b.png":{"logical_path":"jquery-ui/ui-icons_cd0a0a_256x240.png","mtime":"2016-05-04T17:48:40+02:00","size":4369,"digest":"1e32c6dbf5d3fd342f27a78aa881550d6412aa207f48468724a6a15402b6041b","integrity":"sha256-HjLG2/XT/TQvJ6eKqIFVDWQSqiB/SEaHJKahVAK2BBs="},"tinymce-981ca10e0cd26c1cc43bd7da0e8a43ced615d0b581f0a9e787cb269fc5a18099.js":{"logical_path":"tinymce.js","mtime":"2016-05-22T00:36:19+02:00","size":944,"digest":"981ca10e0cd26c1cc43bd7da0e8a43ced615d0b581f0a9e787cb269fc5a18099","integrity":"sha256-mByhDgzSbBzEO9faDopDztYV0LWB8Knnh8smn8WhgJk="},"application-99aba05d4f4b6154b108e3700a9a23d7b51b4c2e2c105bfc6ae63c9096a7673c.css":{"logical_path":"application.css","mtime":"2016-05-22T00:36:19+02:00","size":548162,"digest":"99aba05d4f4b6154b108e3700a9a23d7b51b4c2e2c105bfc6ae63c9096a7673c","integrity":"sha256-maugXU9LYVSxCONwCpoj17UbTC4sEFv8auY8kJanZzw="},"application-63a95002fb2ccebf3d68fea3f0f10416cfd47507986067ce8347c38ce27ce979.js":{"logical_path":"application.js","mtime":"2016-05-22T00:36:19+02:00","size":2159864,"digest":"63a95002fb2ccebf3d68fea3f0f10416cfd47507986067ce8347c38ce27ce979","integrity":"sha256-Y6lQAvsszr89aP6j8PEEFs/UdQeYYGfOg0fDjOJ86Xk="},"application-581c2f0ac27ca40e0308e3833791ce974d41aeaf75764d213928a691390d80ab.js":{"logical_path":"application.js","mtime":"2016-05-22T01:11:38+02:00","size":2160236,"digest":"581c2f0ac27ca40e0308e3833791ce974d41aeaf75764d213928a691390d80ab","integrity":"sha256-WBwvCsJ8pA4DCOODN5HOl01Brq91dk0hOSimkTkNgKs="},"application-ceb501d45d7cebd76cdd8791833794188d63d249eb8d9ca2aeebf0926df320e5.js":{"logical_path":"application.js","mtime":"2016-05-23T01:08:04+02:00","size":2160399,"digest":"ceb501d45d7cebd76cdd8791833794188d63d249eb8d9ca2aeebf0926df320e5","integrity":"sha256-zrUB1F1869ds3YeRgzeUGI1j0knrjZyiruvwkm3zIOU="},"tinymce-554c95b1d24ee6cb338ed339233a70e15cf0074eacec99de99cc2a4136d60b4d.js":{"logical_path":"tinymce.js","mtime":"2016-05-23T01:54:18+02:00","size":948,"digest":"554c95b1d24ee6cb338ed339233a70e15cf0074eacec99de99cc2a4136d60b4d","integrity":"sha256-VUyVsdJO5sszjtM5Izpw4VzwB06s7JnemcwqQTbWC00="},"application-80267254eb940edca206faebfaaef536c10bb76d2332249a101cb05f18e6f833.css":{"logical_path":"application.css","mtime":"2016-05-23T01:54:18+02:00","size":548420,"digest":"80267254eb940edca206faebfaaef536c10bb76d2332249a101cb05f18e6f833","integrity":"sha256-gCZyVOuUDtyiBvrr+q71NsELt20jMiSaEBywXxjm+DM="},"application-e27bec40e6bb2cfe06df32012d5880f505ed57526d9d2714aea50f102d776763.js":{"logical_path":"application.js","mtime":"2016-05-23T01:54:18+02:00","size":2160403,"digest":"e27bec40e6bb2cfe06df32012d5880f505ed57526d9d2714aea50f102d776763","integrity":"sha256-4nvsQOa7LP4G3zIBLViA9QXtV1JtnScUrqUPEC13Z2M="},"active_admin-bf38e2138315a470aef9b840765c137a33b1520312a5ef0a981c39addb52fbfb.css":{"logical_path":"active_admin.css","mtime":"2016-05-21T23:41:15+02:00","size":78112,"digest":"bf38e2138315a470aef9b840765c137a33b1520312a5ef0a981c39addb52fbfb","integrity":"sha256-vzjiE4MVpHCu+bhAdlwTejOxUgMSpe8KmBw5rdtS+/s="},"active_admin/print-87c5ffc1d869a919123bcc1dc5ec51b20bc79fd9aeab9eed77e3438c6acd4f68.css":{"logical_path":"active_admin/print.css","mtime":"2016-06-30T21:12:27+02:00","size":5494,"digest":"87c5ffc1d869a919123bcc1dc5ec51b20bc79fd9aeab9eed77e3438c6acd4f68","integrity":"sha256-h8X/wdhpqRkSO8wdxexRsgvHn9muq57td+NDjGrNT2g="},"tinymce-14411a8837640541cea84f572fa1c80fb639542b1155d7bb7b8d4820c6922b66.js":{"logical_path":"tinymce.js","mtime":"2016-06-25T16:51:02+02:00","size":944,"digest":"14411a8837640541cea84f572fa1c80fb639542b1155d7bb7b8d4820c6922b66","integrity":"sha256-FEEaiDdkBUHOqE9XL6HID7Y5VCsRVde7e41IIMaSK2Y="},"application-77ec43cc8949cbfe2e51114c6ca77a85624e6e817085cda6b03e46d9ebebdf25.css":{"logical_path":"application.css","mtime":"2016-07-02T17:04:13+02:00","size":147481,"digest":"77ec43cc8949cbfe2e51114c6ca77a85624e6e817085cda6b03e46d9ebebdf25","integrity":"sha256-d+xDzIlJy/4uURFMbKd6hWJOboFwhc2msD5G2evr3yU="},"application-2ff7281f89f0b69873f09aa96b2121b67d5c245d6be100b00998783e84d58f2d.js":{"logical_path":"application.js","mtime":"2016-06-25T16:51:02+02:00","size":2171260,"digest":"2ff7281f89f0b69873f09aa96b2121b67d5c245d6be100b00998783e84d58f2d","integrity":"sha256-L/coH4nwtphz8JqpayEhtn1cJF1r4QCwCZh4PoTVjy0="},"tinymce/jquery.tinymce.js":{"logical_path":"tinymce/jquery.tinymce.js","mtime":"2016-06-16T20:47:48+02:00","size":3591,"digest":null},"tinymce/langs/readme.md":{"logical_path":"tinymce/langs/readme.md","mtime":"2016-06-16T20:47:48+02:00","size":151,"digest":null},"tinymce/license.txt":{"logical_path":"tinymce/license.txt","mtime":"2016-06-16T20:47:48+02:00","size":26427,"digest":null},"tinymce/plugins/advlist/plugin.js":{"logical_path":"tinymce/plugins/advlist/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1303,"digest":null},"tinymce/plugins/anchor/plugin.js":{"logical_path":"tinymce/plugins/anchor/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":616,"digest":null},"tinymce/plugins/autolink/plugin.js":{"logical_path":"tinymce/plugins/autolink/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1961,"digest":null},"tinymce/plugins/autoresize/plugin.js":{"logical_path":"tinymce/plugins/autoresize/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1903,"digest":null},"tinymce/plugins/autosave/plugin.js":{"logical_path":"tinymce/plugins/autosave/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":2185,"digest":null},"tinymce/plugins/bbcode/plugin.js":{"logical_path":"tinymce/plugins/bbcode/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":3136,"digest":null},"tinymce/plugins/charmap/plugin.js":{"logical_path":"tinymce/plugins/charmap/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":8194,"digest":null},"tinymce/plugins/code/plugin.js":{"logical_path":"tinymce/plugins/code/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":721,"digest":null},"tinymce/plugins/codesample/css/prism.css":{"logical_path":"tinymce/plugins/codesample/css/prism.css","mtime":"2016-06-16T20:47:48+02:00","size":2289,"digest":null},"tinymce/plugins/codesample/plugin.js":{"logical_path":"tinymce/plugins/codesample/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":20002,"digest":null},"tinymce/plugins/colorpicker/plugin.js":{"logical_path":"tinymce/plugins/colorpicker/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1222,"digest":null},"tinymce/plugins/contextmenu/plugin.js":{"logical_path":"tinymce/plugins/contextmenu/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":891,"digest":null},"tinymce/plugins/directionality/plugin.js":{"logical_path":"tinymce/plugins/directionality/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":726,"digest":null},"tinymce/plugins/emoticons/img/smiley-cool.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-cool.gif","mtime":"2016-06-16T20:47:48+02:00","size":354,"digest":null},"tinymce/plugins/emoticons/img/smiley-cry.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-cry.gif","mtime":"2016-06-16T20:47:48+02:00","size":329,"digest":null},"tinymce/plugins/emoticons/img/smiley-embarassed.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-embarassed.gif","mtime":"2016-06-16T20:47:48+02:00","size":331,"digest":null},"tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif","mtime":"2016-06-16T20:47:48+02:00","size":342,"digest":null},"tinymce/plugins/emoticons/img/smiley-frown.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-frown.gif","mtime":"2016-06-16T20:47:48+02:00","size":340,"digest":null},"tinymce/plugins/emoticons/img/smiley-innocent.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-innocent.gif","mtime":"2016-06-16T20:47:48+02:00","size":336,"digest":null},"tinymce/plugins/emoticons/img/smiley-kiss.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-kiss.gif","mtime":"2016-06-16T20:47:48+02:00","size":338,"digest":null},"tinymce/plugins/emoticons/img/smiley-laughing.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-laughing.gif","mtime":"2016-06-16T20:47:48+02:00","size":343,"digest":null},"tinymce/plugins/emoticons/img/smiley-money-mouth.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-money-mouth.gif","mtime":"2016-06-16T20:47:48+02:00","size":321,"digest":null},"tinymce/plugins/emoticons/img/smiley-sealed.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-sealed.gif","mtime":"2016-06-16T20:47:48+02:00","size":323,"digest":null},"tinymce/plugins/emoticons/img/smiley-smile.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-smile.gif","mtime":"2016-06-16T20:47:48+02:00","size":344,"digest":null},"tinymce/plugins/emoticons/img/smiley-surprised.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-surprised.gif","mtime":"2016-06-16T20:47:48+02:00","size":338,"digest":null},"tinymce/plugins/emoticons/img/smiley-tongue-out.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-tongue-out.gif","mtime":"2016-06-16T20:47:48+02:00","size":328,"digest":null},"tinymce/plugins/emoticons/img/smiley-undecided.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-undecided.gif","mtime":"2016-06-16T20:47:48+02:00","size":337,"digest":null},"tinymce/plugins/emoticons/img/smiley-wink.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-wink.gif","mtime":"2016-06-16T20:47:48+02:00","size":350,"digest":null},"tinymce/plugins/emoticons/img/smiley-yell.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-yell.gif","mtime":"2016-06-16T20:47:48+02:00","size":336,"digest":null},"tinymce/plugins/emoticons/plugin.js":{"logical_path":"tinymce/plugins/emoticons/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":911,"digest":null},"tinymce/plugins/example/dialog.html":{"logical_path":"tinymce/plugins/example/dialog.html","mtime":"2016-06-16T20:47:48+02:00","size":213,"digest":null},"tinymce/plugins/example/plugin.js":{"logical_path":"tinymce/plugins/example/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":658,"digest":null},"tinymce/plugins/example_dependency/plugin.js":{"logical_path":"tinymce/plugins/example_dependency/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":73,"digest":null},"tinymce/plugins/fullpage/plugin.js":{"logical_path":"tinymce/plugins/fullpage/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":6291,"digest":null},"tinymce/plugins/fullscreen/plugin.js":{"logical_path":"tinymce/plugins/fullscreen/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1676,"digest":null},"tinymce/plugins/hr/plugin.js":{"logical_path":"tinymce/plugins/hr/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":322,"digest":null},"tinymce/plugins/image/plugin.js":{"logical_path":"tinymce/plugins/image/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":8169,"digest":null},"tinymce/plugins/imagetools/plugin.js":{"logical_path":"tinymce/plugins/imagetools/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":29669,"digest":null},"tinymce/plugins/importcss/plugin.js":{"logical_path":"tinymce/plugins/importcss/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":2223,"digest":null},"tinymce/plugins/insertdatetime/plugin.js":{"logical_path":"tinymce/plugins/insertdatetime/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1978,"digest":null},"tinymce/plugins/layer/plugin.js":{"logical_path":"tinymce/plugins/layer/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":2857,"digest":null},"tinymce/plugins/legacyoutput/plugin.js":{"logical_path":"tinymce/plugins/legacyoutput/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":3263,"digest":null},"tinymce/plugins/link/plugin.js":{"logical_path":"tinymce/plugins/link/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":4517,"digest":null},"tinymce/plugins/lists/plugin.js":{"logical_path":"tinymce/plugins/lists/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":8578,"digest":null},"tinymce/plugins/media/moxieplayer.swf":{"logical_path":"tinymce/plugins/media/moxieplayer.swf","mtime":"2016-06-16T20:47:48+02:00","size":20017,"digest":null},"tinymce/plugins/media/plugin.js":{"logical_path":"tinymce/plugins/media/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":11696,"digest":null},"tinymce/plugins/nonbreaking/plugin.js":{"logical_path":"tinymce/plugins/nonbreaking/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":655,"digest":null},"tinymce/plugins/noneditable/plugin.js":{"logical_path":"tinymce/plugins/noneditable/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1126,"digest":null},"tinymce/plugins/pagebreak/plugin.js":{"logical_path":"tinymce/plugins/pagebreak/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1230,"digest":null},"tinymce/plugins/paste/plugin.js":{"logical_path":"tinymce/plugins/paste/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":16286,"digest":null},"tinymce/plugins/preview/plugin.js":{"logical_path":"tinymce/plugins/preview/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1602,"digest":null},"tinymce/plugins/print/plugin.js":{"logical_path":"tinymce/plugins/print/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":293,"digest":null},"tinymce/plugins/save/plugin.js":{"logical_path":"tinymce/plugins/save/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1156,"digest":null},"tinymce/plugins/searchreplace/plugin.js":{"logical_path":"tinymce/plugins/searchreplace/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":6493,"digest":null},"tinymce/plugins/spellchecker/plugin.js":{"logical_path":"tinymce/plugins/spellchecker/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":9781,"digest":null},"tinymce/plugins/tabfocus/plugin.js":{"logical_path":"tinymce/plugins/tabfocus/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1270,"digest":null},"tinymce/plugins/table/plugin.js":{"logical_path":"tinymce/plugins/table/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":42808,"digest":null},"tinymce/plugins/template/plugin.js":{"logical_path":"tinymce/plugins/template/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":4445,"digest":null},"tinymce/plugins/textcolor/plugin.js":{"logical_path":"tinymce/plugins/textcolor/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":4145,"digest":null},"tinymce/plugins/textpattern/plugin.js":{"logical_path":"tinymce/plugins/textpattern/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":2751,"digest":null},"tinymce/plugins/visualblocks/css/visualblocks.css":{"logical_path":"tinymce/plugins/visualblocks/css/visualblocks.css","mtime":"2016-06-16T20:47:48+02:00","size":5092,"digest":null},"tinymce/plugins/visualblocks/plugin.js":{"logical_path":"tinymce/plugins/visualblocks/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1153,"digest":null},"tinymce/plugins/visualchars/plugin.js":{"logical_path":"tinymce/plugins/visualchars/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1259,"digest":null},"tinymce/plugins/wordcount/plugin.js":{"logical_path":"tinymce/plugins/wordcount/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":928,"digest":null},"tinymce/skins/lightgray/content.inline.min.css":{"logical_path":"tinymce/skins/lightgray/content.inline.min.css","mtime":"2016-06-16T20:47:48+02:00","size":2676,"digest":null},"tinymce/skins/lightgray/content.min.css":{"logical_path":"tinymce/skins/lightgray/content.min.css","mtime":"2016-06-16T20:47:48+02:00","size":3091,"digest":null},"tinymce/skins/lightgray/fonts/tinymce-small.eot":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce-small.eot","mtime":"2016-06-16T20:47:48+02:00","size":9492,"digest":null},"tinymce/skins/lightgray/fonts/tinymce-small.svg":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce-small.svg","mtime":"2016-06-16T20:47:48+02:00","size":24727,"digest":null},"tinymce/skins/lightgray/fonts/tinymce-small.ttf":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce-small.ttf","mtime":"2016-06-16T20:47:48+02:00","size":9304,"digest":null},"tinymce/skins/lightgray/fonts/tinymce-small.woff":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce-small.woff","mtime":"2016-06-16T20:47:48+02:00","size":9380,"digest":null},"tinymce/skins/lightgray/fonts/tinymce.eot":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce.eot","mtime":"2016-06-16T20:47:48+02:00","size":17292,"digest":null},"tinymce/skins/lightgray/fonts/tinymce.svg":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce.svg","mtime":"2016-06-16T20:47:48+02:00","size":45226,"digest":null},"tinymce/skins/lightgray/fonts/tinymce.ttf":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce.ttf","mtime":"2016-06-16T20:47:48+02:00","size":17128,"digest":null},"tinymce/skins/lightgray/fonts/tinymce.woff":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce.woff","mtime":"2016-06-16T20:47:48+02:00","size":17204,"digest":null},"tinymce/skins/lightgray/img/anchor.gif":{"logical_path":"tinymce/skins/lightgray/img/anchor.gif","mtime":"2016-06-16T20:47:48+02:00","size":53,"digest":null},"tinymce/skins/lightgray/img/loader.gif":{"logical_path":"tinymce/skins/lightgray/img/loader.gif","mtime":"2016-06-16T20:47:48+02:00","size":2608,"digest":null},"tinymce/skins/lightgray/img/object.gif":{"logical_path":"tinymce/skins/lightgray/img/object.gif","mtime":"2016-06-16T20:47:48+02:00","size":152,"digest":null},"tinymce/skins/lightgray/img/trans.gif":{"logical_path":"tinymce/skins/lightgray/img/trans.gif","mtime":"2016-06-16T20:47:48+02:00","size":43,"digest":null},"tinymce/skins/lightgray/skin.ie7.min.css":{"logical_path":"tinymce/skins/lightgray/skin.ie7.min.css","mtime":"2016-06-16T20:47:48+02:00","size":32423,"digest":null},"tinymce/skins/lightgray/skin.min.css":{"logical_path":"tinymce/skins/lightgray/skin.min.css","mtime":"2016-06-16T20:47:48+02:00","size":34503,"digest":null},"tinymce/themes/modern/theme.js":{"logical_path":"tinymce/themes/modern/theme.js","mtime":"2016-06-16T20:47:48+02:00","size":9923,"digest":null},"tinymce/tinymce.js":{"logical_path":"tinymce/tinymce.js","mtime":"2016-06-16T20:47:48+02:00","size":380255,"digest":null},"tinymce/langs/ar.js":{"logical_path":"tinymce/langs/ar.js","mtime":"2016-05-04T17:48:54+02:00","size":17775,"digest":null},"tinymce/langs/ar_SA.js":{"logical_path":"tinymce/langs/ar_SA.js","mtime":"2016-05-04T17:48:54+02:00","size":10002,"digest":null},"tinymce/langs/az.js":{"logical_path":"tinymce/langs/az.js","mtime":"2016-05-04T17:48:54+02:00","size":9679,"digest":null},"tinymce/langs/be.js":{"logical_path":"tinymce/langs/be.js","mtime":"2016-05-04T17:48:54+02:00","size":21063,"digest":null},"tinymce/langs/bg_BG.js":{"logical_path":"tinymce/langs/bg_BG.js","mtime":"2016-05-04T17:48:54+02:00","size":23944,"digest":null},"tinymce/langs/bn_BD.js":{"logical_path":"tinymce/langs/bn_BD.js","mtime":"2016-05-04T17:48:54+02:00","size":6845,"digest":null},"tinymce/langs/bs.js":{"logical_path":"tinymce/langs/bs.js","mtime":"2016-05-04T17:48:54+02:00","size":6969,"digest":null},"tinymce/langs/ca.js":{"logical_path":"tinymce/langs/ca.js","mtime":"2016-05-04T17:48:54+02:00","size":7786,"digest":null},"tinymce/langs/cs.js":{"logical_path":"tinymce/langs/cs.js","mtime":"2016-05-04T17:48:54+02:00","size":8750,"digest":null},"tinymce/langs/cs_CZ.js":{"logical_path":"tinymce/langs/cs_CZ.js","mtime":"2016-05-04T17:48:54+02:00","size":8398,"digest":null},"tinymce/langs/cy.js":{"logical_path":"tinymce/langs/cy.js","mtime":"2016-05-04T17:48:54+02:00","size":6141,"digest":null},"tinymce/langs/da.js":{"logical_path":"tinymce/langs/da.js","mtime":"2016-05-04T17:48:54+02:00","size":7512,"digest":null},"tinymce/langs/de.js":{"logical_path":"tinymce/langs/de.js","mtime":"2016-05-04T17:48:54+02:00","size":8279,"digest":null},"tinymce/langs/de_AT.js":{"logical_path":"tinymce/langs/de_AT.js","mtime":"2016-05-04T17:48:54+02:00","size":8307,"digest":null},"tinymce/langs/dv.js":{"logical_path":"tinymce/langs/dv.js","mtime":"2016-05-04T17:48:54+02:00","size":18099,"digest":null},"tinymce/langs/el.js":{"logical_path":"tinymce/langs/el.js","mtime":"2016-05-04T17:48:54+02:00","size":22972,"digest":null},"tinymce/langs/en_CA.js":{"logical_path":"tinymce/langs/en_CA.js","mtime":"2016-05-04T17:48:54+02:00","size":6915,"digest":null},"tinymce/langs/en_GB.js":{"logical_path":"tinymce/langs/en_GB.js","mtime":"2016-05-04T17:48:54+02:00","size":5906,"digest":null},"tinymce/langs/eo.js":{"logical_path":"tinymce/langs/eo.js","mtime":"2016-05-04T17:48:54+02:00","size":7465,"digest":null},"tinymce/langs/es.js":{"logical_path":"tinymce/langs/es.js","mtime":"2016-05-04T17:48:54+02:00","size":7808,"digest":null},"tinymce/langs/es_MX.js":{"logical_path":"tinymce/langs/es_MX.js","mtime":"2016-05-04T17:48:54+02:00","size":7893,"digest":null},"tinymce/langs/et.js":{"logical_path":"tinymce/langs/et.js","mtime":"2016-05-04T17:48:54+02:00","size":7783,"digest":null},"tinymce/langs/eu.js":{"logical_path":"tinymce/langs/eu.js","mtime":"2016-05-04T17:48:54+02:00","size":7010,"digest":null},"tinymce/langs/fa.js":{"logical_path":"tinymce/langs/fa.js","mtime":"2016-05-04T17:48:54+02:00","size":16461,"digest":null},"tinymce/langs/fa_IR.js":{"logical_path":"tinymce/langs/fa_IR.js","mtime":"2016-05-04T17:48:54+02:00","size":17724,"digest":null},"tinymce/langs/fi.js":{"logical_path":"tinymce/langs/fi.js","mtime":"2016-05-04T17:48:54+02:00","size":8142,"digest":null},"tinymce/langs/fo.js":{"logical_path":"tinymce/langs/fo.js","mtime":"2016-05-04T17:48:54+02:00","size":8043,"digest":null},"tinymce/langs/fr_CH.js":{"logical_path":"tinymce/langs/fr_CH.js","mtime":"2016-05-04T17:48:54+02:00","size":8073,"digest":null},"tinymce/langs/fr_FR.js":{"logical_path":"tinymce/langs/fr_FR.js","mtime":"2016-05-04T17:48:54+02:00","size":8008,"digest":null},"tinymce/langs/ga.js":{"logical_path":"tinymce/langs/ga.js","mtime":"2016-05-04T17:48:54+02:00","size":8590,"digest":null},"tinymce/langs/gd.js":{"logical_path":"tinymce/langs/gd.js","mtime":"2016-05-04T17:48:54+02:00","size":8807,"digest":null},"tinymce/langs/gl.js":{"logical_path":"tinymce/langs/gl.js","mtime":"2016-05-04T17:48:54+02:00","size":7065,"digest":null},"tinymce/langs/he_IL.js":{"logical_path":"tinymce/langs/he_IL.js","mtime":"2016-05-04T17:48:54+02:00","size":16080,"digest":null},"tinymce/langs/hi_IN.js":{"logical_path":"tinymce/langs/hi_IN.js","mtime":"2016-05-04T17:48:54+02:00","size":18457,"digest":null},"tinymce/langs/hr.js":{"logical_path":"tinymce/langs/hr.js","mtime":"2016-05-04T17:48:54+02:00","size":7576,"digest":null},"tinymce/langs/hu_HU.js":{"logical_path":"tinymce/langs/hu_HU.js","mtime":"2016-05-04T17:48:54+02:00","size":9409,"digest":null},"tinymce/langs/hy.js":{"logical_path":"tinymce/langs/hy.js","mtime":"2016-05-04T17:48:54+02:00","size":20374,"digest":null},"tinymce/langs/id.js":{"logical_path":"tinymce/langs/id.js","mtime":"2016-05-04T17:48:54+02:00","size":7140,"digest":null},"tinymce/langs/is_IS.js":{"logical_path":"tinymce/langs/is_IS.js","mtime":"2016-05-04T17:48:54+02:00","size":7927,"digest":null},"tinymce/langs/it.js":{"logical_path":"tinymce/langs/it.js","mtime":"2016-05-04T17:48:54+02:00","size":7597,"digest":null},"tinymce/langs/ja.js":{"logical_path":"tinymce/langs/ja.js","mtime":"2016-05-04T17:48:54+02:00","size":12289,"digest":null},"tinymce/langs/ka_GE.js":{"logical_path":"tinymce/langs/ka_GE.js","mtime":"2016-05-04T17:48:54+02:00","size":21283,"digest":null},"tinymce/langs/kab.js":{"logical_path":"tinymce/langs/kab.js","mtime":"2016-05-04T17:48:54+02:00","size":7390,"digest":null},"tinymce/langs/kk.js":{"logical_path":"tinymce/langs/kk.js","mtime":"2016-05-04T17:48:54+02:00","size":16680,"digest":null},"tinymce/langs/km_KH.js":{"logical_path":"tinymce/langs/km_KH.js","mtime":"2016-05-04T17:48:54+02:00","size":21395,"digest":null},"tinymce/langs/ko.js":{"logical_path":"tinymce/langs/ko.js","mtime":"2016-05-04T17:48:54+02:00","size":10104,"digest":null},"tinymce/langs/ko_KR.js":{"logical_path":"tinymce/langs/ko_KR.js","mtime":"2016-05-04T17:48:54+02:00","size":10004,"digest":null},"tinymce/langs/ku.js":{"logical_path":"tinymce/langs/ku.js","mtime":"2016-05-04T17:48:54+02:00","size":18273,"digest":null},"tinymce/langs/ku_IQ.js":{"logical_path":"tinymce/langs/ku_IQ.js","mtime":"2016-05-04T17:48:54+02:00","size":18363,"digest":null},"tinymce/langs/lb.js":{"logical_path":"tinymce/langs/lb.js","mtime":"2016-05-04T17:48:54+02:00","size":7466,"digest":null},"tinymce/langs/lt.js":{"logical_path":"tinymce/langs/lt.js","mtime":"2016-05-04T17:48:54+02:00","size":8898,"digest":null},"tinymce/langs/lv.js":{"logical_path":"tinymce/langs/lv.js","mtime":"2016-05-04T17:48:54+02:00","size":8281,"digest":null},"tinymce/langs/mk_MK.js":{"logical_path":"tinymce/langs/mk_MK.js","mtime":"2016-05-04T17:48:54+02:00","size":18732,"digest":null},"tinymce/langs/ml.js":{"logical_path":"tinymce/langs/ml.js","mtime":"2016-05-04T17:48:54+02:00","size":7338,"digest":null},"tinymce/langs/ml_IN.js":{"logical_path":"tinymce/langs/ml_IN.js","mtime":"2016-05-04T17:48:54+02:00","size":20018,"digest":null},"tinymce/langs/mn_MN.js":{"logical_path":"tinymce/langs/mn_MN.js","mtime":"2016-05-04T17:48:54+02:00","size":6876,"digest":null},"tinymce/langs/nb_NO.js":{"logical_path":"tinymce/langs/nb_NO.js","mtime":"2016-05-04T17:48:54+02:00","size":7527,"digest":null},"tinymce/langs/nl.js":{"logical_path":"tinymce/langs/nl.js","mtime":"2016-05-04T17:48:54+02:00","size":7234,"digest":null},"tinymce/langs/pl.js":{"logical_path":"tinymce/langs/pl.js","mtime":"2016-05-04T17:48:54+02:00","size":8128,"digest":null},"tinymce/langs/pt_BR.js":{"logical_path":"tinymce/langs/pt_BR.js","mtime":"2016-05-04T17:48:54+02:00","size":8001,"digest":null},"tinymce/langs/pt_PT.js":{"logical_path":"tinymce/langs/pt_PT.js","mtime":"2016-05-04T17:48:54+02:00","size":8144,"digest":null},"tinymce/langs/ro.js":{"logical_path":"tinymce/langs/ro.js","mtime":"2016-05-04T17:48:54+02:00","size":8274,"digest":null},"tinymce/langs/ru.js":{"logical_path":"tinymce/langs/ru.js","mtime":"2016-05-04T17:48:54+02:00","size":22289,"digest":null},"tinymce/langs/ru_RU.js":{"logical_path":"tinymce/langs/ru_RU.js","mtime":"2016-05-04T17:48:54+02:00","size":4954,"digest":null},"tinymce/langs/si_LK.js":{"logical_path":"tinymce/langs/si_LK.js","mtime":"2016-05-04T17:48:54+02:00","size":15855,"digest":null},"tinymce/langs/sk.js":{"logical_path":"tinymce/langs/sk.js","mtime":"2016-05-04T17:48:54+02:00","size":8957,"digest":null},"tinymce/langs/sl_SI.js":{"logical_path":"tinymce/langs/sl_SI.js","mtime":"2016-05-04T17:48:54+02:00","size":7038,"digest":null},"tinymce/langs/sr.js":{"logical_path":"tinymce/langs/sr.js","mtime":"2016-05-04T17:48:54+02:00","size":6335,"digest":null},"tinymce/langs/sv_SE.js":{"logical_path":"tinymce/langs/sv_SE.js","mtime":"2016-05-04T17:48:54+02:00","size":7495,"digest":null},"tinymce/langs/ta.js":{"logical_path":"tinymce/langs/ta.js","mtime":"2016-05-04T17:48:54+02:00","size":22616,"digest":null},"tinymce/langs/ta_IN.js":{"logical_path":"tinymce/langs/ta_IN.js","mtime":"2016-05-04T17:48:54+02:00","size":22619,"digest":null},"tinymce/langs/tg.js":{"logical_path":"tinymce/langs/tg.js","mtime":"2016-05-04T17:48:54+02:00","size":18182,"digest":null},"tinymce/langs/th_TH.js":{"logical_path":"tinymce/langs/th_TH.js","mtime":"2016-05-04T17:48:54+02:00","size":17296,"digest":null},"tinymce/langs/tr.js":{"logical_path":"tinymce/langs/tr.js","mtime":"2016-05-04T17:48:54+02:00","size":8704,"digest":null},"tinymce/langs/tr_TR.js":{"logical_path":"tinymce/langs/tr_TR.js","mtime":"2016-05-04T17:48:54+02:00","size":8140,"digest":null},"tinymce/langs/tt.js":{"logical_path":"tinymce/langs/tt.js","mtime":"2016-05-04T17:48:54+02:00","size":19034,"digest":null},"tinymce/langs/ug.js":{"logical_path":"tinymce/langs/ug.js","mtime":"2016-05-04T17:48:54+02:00","size":16887,"digest":null},"tinymce/langs/uk.js":{"logical_path":"tinymce/langs/uk.js","mtime":"2016-05-04T17:48:54+02:00","size":22263,"digest":null},"tinymce/langs/uk_UA.js":{"logical_path":"tinymce/langs/uk_UA.js","mtime":"2016-05-04T17:48:54+02:00","size":21690,"digest":null},"tinymce/langs/vi.js":{"logical_path":"tinymce/langs/vi.js","mtime":"2016-05-04T17:48:54+02:00","size":9900,"digest":null},"tinymce/langs/vi_VN.js":{"logical_path":"tinymce/langs/vi_VN.js","mtime":"2016-05-04T17:48:54+02:00","size":9898,"digest":null},"tinymce/langs/zh_CN.js":{"logical_path":"tinymce/langs/zh_CN.js","mtime":"2016-05-04T17:48:54+02:00","size":8482,"digest":null},"tinymce/langs/zh_TW.js":{"logical_path":"tinymce/langs/zh_TW.js","mtime":"2016-05-04T17:48:54+02:00","size":9378,"digest":null},"active_admin-5f668089bbe1957cd779eb439f2df899e5d66673d34ac94110e73ef0ac0e7313.css":{"logical_path":"active_admin.css","mtime":"2016-06-30T21:12:27+02:00","size":78116,"digest":"5f668089bbe1957cd779eb439f2df899e5d66673d34ac94110e73ef0ac0e7313","integrity":"sha256-X2aAibvhlXzXeetDny34meXWZnPTSslBEOc+8KwOcxM="},"active_admin-c99e2b41c14fcaa52c6ca770ae578392abc42e237158ed560ad73d118e502350.js":{"logical_path":"active_admin.js","mtime":"2016-07-02T17:04:13+02:00","size":780523,"digest":"c99e2b41c14fcaa52c6ca770ae578392abc42e237158ed560ad73d118e502350","integrity":"sha256-yZ4rQcFPyqUsbKdwrleDkqvELiNxWO1WCtc9EY5QI1A="},"tinymce-962059b7c757a94ab7ec4ee03bad9a9c4b565a3939172b7c307c72aa4b5ffefb.js":{"logical_path":"tinymce.js","mtime":"2016-07-02T17:04:13+02:00","size":971,"digest":"962059b7c757a94ab7ec4ee03bad9a9c4b565a3939172b7c307c72aa4b5ffefb","integrity":"sha256-liBZt8dXqUq37E7gO62anEtWWjk5Fyt8MHxyqktf/vs="},"baby_gnu_adl-232caf355c30740d5d9b30491887cd546b8849b33ca9bdb6cc71f8a47ea61815.png":{"logical_path":"baby_gnu_adl.png","mtime":"2016-07-02T16:52:58+02:00","size":10155,"digest":"232caf355c30740d5d9b30491887cd546b8849b33ca9bdb6cc71f8a47ea61815","integrity":"sha256-IyyvNVwwdA1dmzBJGIfNVGuISbM8qb22zHH4pH6mGBU="},"baby_gnu_adl-97251005d3225cf1d58b8c497d6b7905dbc9560cc8acd50118fcce60d0a2679e.svg":{"logical_path":"baby_gnu_adl.svg","mtime":"2016-07-02T16:52:57+02:00","size":109635,"digest":"97251005d3225cf1d58b8c497d6b7905dbc9560cc8acd50118fcce60d0a2679e","integrity":"sha256-lyUQBdMiXPHVi4xJfWt5BdvJVgzIrNUBGPzOYNCiZ54="},"application-307219623ded8fdc9ee285ad85d84051e026d5bfc9ff99ad749c917ab9dfcc76.js":{"logical_path":"application.js","mtime":"2016-07-02T17:04:13+02:00","size":2179851,"digest":"307219623ded8fdc9ee285ad85d84051e026d5bfc9ff99ad749c917ab9dfcc76","integrity":"sha256-MHIZYj3tj9ye4oWthdhAUeAm1b/J/5mtdJyRernfzHY="},"tinymce/plugins/emoticons/img/smiley-cool-bb0e93a050a32df7913e4026b3c88a176998e0e3e073ba06e9b73f6c24227c9c.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-cool.gif","mtime":"2016-06-16T20:47:48+02:00","size":354,"digest":"bb0e93a050a32df7913e4026b3c88a176998e0e3e073ba06e9b73f6c24227c9c","integrity":"sha256-uw6ToFCjLfeRPkAms8iKF2mY4OPgc7oG6bc/bCQifJw="},"tinymce/plugins/emoticons/img/smiley-cry-a0c5f3e7a682449c973c9d9f7c46342081c46920686d2353f57aff91ab907f68.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-cry.gif","mtime":"2016-06-16T20:47:48+02:00","size":329,"digest":"a0c5f3e7a682449c973c9d9f7c46342081c46920686d2353f57aff91ab907f68","integrity":"sha256-oMXz56aCRJyXPJ2ffEY0IIHEaSBobSNT9Xr/kauQf2g="},"tinymce/plugins/emoticons/img/smiley-embarassed-d3cafcb50b335672cb5e9f4600ea9ea261dac7828dd28844d4927c393a25618f.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-embarassed.gif","mtime":"2016-06-16T20:47:48+02:00","size":331,"digest":"d3cafcb50b335672cb5e9f4600ea9ea261dac7828dd28844d4927c393a25618f","integrity":"sha256-08r8tQszVnLLXp9GAOqeomHax4KN0ohE1JJ8OTolYY8="},"tinymce/plugins/emoticons/img/smiley-foot-in-mouth-03fe04d3ed533423ac81f05146584b0c451be3d4a30e76687ceef283ed07071f.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif","mtime":"2016-06-16T20:47:48+02:00","size":342,"digest":"03fe04d3ed533423ac81f05146584b0c451be3d4a30e76687ceef283ed07071f","integrity":"sha256-A/4E0+1TNCOsgfBRRlhLDEUb49SjDnZofO7yg+0HBx8="},"tinymce/plugins/emoticons/img/smiley-frown-1b984bf98931dd1debb54461eb9d83e985f2b2999fe14bcb556d6c0921bc83b0.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-frown.gif","mtime":"2016-06-16T20:47:48+02:00","size":340,"digest":"1b984bf98931dd1debb54461eb9d83e985f2b2999fe14bcb556d6c0921bc83b0","integrity":"sha256-G5hL+Ykx3R3rtURh652D6YXyspmf4UvLVW1sCSG8g7A="},"tinymce/plugins/emoticons/img/smiley-innocent-8db353ef102196f2c6ddf5c4666446de955d7b14fc0957c806c9dbfb48fb0c29.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-innocent.gif","mtime":"2016-06-16T20:47:48+02:00","size":336,"digest":"8db353ef102196f2c6ddf5c4666446de955d7b14fc0957c806c9dbfb48fb0c29","integrity":"sha256-jbNT7xAhlvLG3fXEZmRG3pVdexT8CVfIBsnb+0j7DCk="},"tinymce/plugins/emoticons/img/smiley-kiss-3154c3665356c13ab10fefdbac1fe187fff978a0052037c99cdc4a97103413f2.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-kiss.gif","mtime":"2016-06-16T20:47:48+02:00","size":338,"digest":"3154c3665356c13ab10fefdbac1fe187fff978a0052037c99cdc4a97103413f2","integrity":"sha256-MVTDZlNWwTqxD+/brB/hh//5eKAFIDfJnNxKlxA0E/I="},"tinymce/plugins/emoticons/img/smiley-laughing-8f6adedcd091975ffead171867a6304d908bb6541a6ccb4919286ec6b7d4551e.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-laughing.gif","mtime":"2016-06-16T20:47:48+02:00","size":343,"digest":"8f6adedcd091975ffead171867a6304d908bb6541a6ccb4919286ec6b7d4551e","integrity":"sha256-j2re3NCRl1/+rRcYZ6YwTZCLtlQabMtJGShuxrfUVR4="},"tinymce/plugins/emoticons/img/smiley-money-mouth-f0b9f4f22e237f5dbc851f900fed8d7eca4c954ae6fbc606c0cd8be431d0ac80.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-money-mouth.gif","mtime":"2016-06-16T20:47:48+02:00","size":321,"digest":"f0b9f4f22e237f5dbc851f900fed8d7eca4c954ae6fbc606c0cd8be431d0ac80","integrity":"sha256-8Ln08i4jf128hR+QD+2NfspMlUrm+8YGwM2L5DHQrIA="},"tinymce/plugins/emoticons/img/smiley-sealed-9933b442636b6e537df7b564e2c3f7a2873526eea6b022a98eb1e468e5204c32.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-sealed.gif","mtime":"2016-06-16T20:47:48+02:00","size":323,"digest":"9933b442636b6e537df7b564e2c3f7a2873526eea6b022a98eb1e468e5204c32","integrity":"sha256-mTO0QmNrblN997Vk4sP3ooc1Ju6msCKpjrHkaOUgTDI="},"tinymce/plugins/emoticons/img/smiley-smile-fd89cd460ffcacb7e725e00c0275ef5b3924ce468248e5ff4fb43545571cfa65.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-smile.gif","mtime":"2016-06-16T20:47:48+02:00","size":344,"digest":"fd89cd460ffcacb7e725e00c0275ef5b3924ce468248e5ff4fb43545571cfa65","integrity":"sha256-/YnNRg/8rLfnJeAMAnXvWzkkzkaCSOX/T7Q1RVcc+mU="},"tinymce/plugins/emoticons/img/smiley-surprised-3871f356cb41976d7ae8a5f005e8739e4d014352a8adef9b33f773d81b6e6c01.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-surprised.gif","mtime":"2016-06-16T20:47:48+02:00","size":338,"digest":"3871f356cb41976d7ae8a5f005e8739e4d014352a8adef9b33f773d81b6e6c01","integrity":"sha256-OHHzVstBl2166KXwBehznk0BQ1Kore+bM/dz2BtubAE="},"tinymce/plugins/emoticons/img/smiley-tongue-out-5843c85667a8226dc43be83749fd9fbbc5d20b1577de2b763915d99815d37d47.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-tongue-out.gif","mtime":"2016-06-16T20:47:48+02:00","size":328,"digest":"5843c85667a8226dc43be83749fd9fbbc5d20b1577de2b763915d99815d37d47","integrity":"sha256-WEPIVmeoIm3EO+g3Sf2fu8XSCxV33it2ORXZmBXTfUc="},"tinymce/plugins/emoticons/img/smiley-undecided-d8b9bcbb433951ff3c4ca8dd959ac3844239b98e6d52218833e1485a91f67347.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-undecided.gif","mtime":"2016-06-16T20:47:48+02:00","size":337,"digest":"d8b9bcbb433951ff3c4ca8dd959ac3844239b98e6d52218833e1485a91f67347","integrity":"sha256-2Lm8u0M5Uf88TKjdlZrDhEI5uY5tUiGIM+FIWpH2c0c="},"tinymce/plugins/emoticons/img/smiley-wink-2af75ad7b1c08488505513503e34b15f40005e04a2a9568f698f0945d2d8ba1f.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-wink.gif","mtime":"2016-06-16T20:47:48+02:00","size":350,"digest":"2af75ad7b1c08488505513503e34b15f40005e04a2a9568f698f0945d2d8ba1f","integrity":"sha256-Kvda17HAhIhQVRNQPjSxX0AAXgSiqVaPaY8JRdLYuh8="},"tinymce/plugins/emoticons/img/smiley-yell-bba903fbcb46fce8c68b9e01863fd095b3b1d0e6aa72161f3a88d762a5f90a79.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-yell.gif","mtime":"2016-06-16T20:47:48+02:00","size":336,"digest":"bba903fbcb46fce8c68b9e01863fd095b3b1d0e6aa72161f3a88d762a5f90a79","integrity":"sha256-u6kD+8tG/OjGi54Bhj/QlbOx0OaqchYfOojXYqX5Cnk="},"tinymce/skins/lightgray/img/anchor-2861666fd107d278d4449970615136d06d7f746be9bb19072cf9c8f30e565e1e.gif":{"logical_path":"tinymce/skins/lightgray/img/anchor.gif","mtime":"2016-06-16T20:47:48+02:00","size":53,"digest":"2861666fd107d278d4449970615136d06d7f746be9bb19072cf9c8f30e565e1e","integrity":"sha256-KGFmb9EH0njURJlwYVE20G1/dGvpuxkHLPnI8w5WXh4="},"tinymce/skins/lightgray/img/loader-eb7cfd3d959b2e09c170f532e29f8b825f9bc770b2279fde58e595617753e244.gif":{"logical_path":"tinymce/skins/lightgray/img/loader.gif","mtime":"2016-06-16T20:47:48+02:00","size":2608,"digest":"eb7cfd3d959b2e09c170f532e29f8b825f9bc770b2279fde58e595617753e244","integrity":"sha256-63z9PZWbLgnBcPUy4p+Lgl+bx3CyJ5/eWOWVYXdT4kQ="},"tinymce/skins/lightgray/img/object-e6a15e52bc4a17b085073ba8debd4708ead6ae3d4cbeb3880c65cb7afc489777.gif":{"logical_path":"tinymce/skins/lightgray/img/object.gif","mtime":"2016-06-16T20:47:48+02:00","size":152,"digest":"e6a15e52bc4a17b085073ba8debd4708ead6ae3d4cbeb3880c65cb7afc489777","integrity":"sha256-5qFeUrxKF7CFBzuo3r1HCOrWrj1MvrOIDGXLevxIl3c="},"tinymce/skins/lightgray/img/trans-9cf020d7c3bba7f5ab10cda54aabef934f906d4f9a3acf99e9e7dc6c98579635.gif":{"logical_path":"tinymce/skins/lightgray/img/trans.gif","mtime":"2016-06-16T20:47:48+02:00","size":43,"digest":"9cf020d7c3bba7f5ab10cda54aabef934f906d4f9a3acf99e9e7dc6c98579635","integrity":"sha256-nPAg18O7p/WrEM2lSqvvk0+QbU+aOs+Z6efcbJhXljU="}},"assets":{"active_admin.css":"active_admin-5f668089bbe1957cd779eb439f2df899e5d66673d34ac94110e73ef0ac0e7313.css","active_admin/nested_menu_arrow.gif":"active_admin/nested_menu_arrow-15084d93c65c1964d7077700ea748bd2d70cfa2d4c19707c58a9c64e232dd442.gif","active_admin/nested_menu_arrow_dark.gif":"active_admin/nested_menu_arrow_dark-7c43b8e0a5f8823875f49a093c9d7a6b374f885b6f9cc248ae9cd7e6e9b29034.gif","active_admin/datepicker/datepicker-input-icon.png":"active_admin/datepicker/datepicker-input-icon-d9c2bb73769af777c8a71720d29741f3a499aebd5a043e9a119bd0d9597aed47.png","active_admin/orderable.png":"active_admin/orderable-29374dbb55b0012d78a37c614d573bb3474f0779849b478a147d0f1845ca6617.png","active_admin_pagedown/wmd-buttons.png":"active_admin_pagedown/wmd-buttons-c2040b12f2d6cb568ddc33587a070a29a18fed20099260c3ecbbfdbd62042f7b.png","active_admin/print.css":"active_admin/print-87c5ffc1d869a919123bcc1dc5ec51b20bc79fd9aeab9eed77e3438c6acd4f68.css","active_admin.js":"active_admin-c99e2b41c14fcaa52c6ca770ae578392abc42e237158ed560ad73d118e502350.js","layers-2x.png":"layers-2x-0c02a2388f637d21f86e6d4b314ec9a968e7b05ad4c3a005280a3f76c0fd3cb8.png","layers.png":"layers-0908aa2a72a082fb2563a2427a5e4fb247571862b448b80fb6f720af1109923e.png","marker-icon-2x.png":"marker-icon-2x-454dc479e82b487529b6b93d6a9b29ac69ca7b4f5a9d5fdf8e01871f6d216113.png","marker-icon.png":"marker-icon-915e83a6fc798c599e5c9e3f759d6bc065d65151019acd0410d1f4731bcaaf72.png","marker-shadow.png":"marker-shadow-4f340d2d61746333dffe056e074ce1704ae4e47fec5a7de98322fbdbcfcb2b6d.png","tinymce.js":"tinymce-962059b7c757a94ab7ec4ee03bad9a9c4b565a3939172b7c307c72aa4b5ffefb.js","application.css":"application-77ec43cc8949cbfe2e51114c6ca77a85624e6e817085cda6b03e46d9ebebdf25.css","select2.png":"select2-d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8.png","select2-spinner.gif":"select2-spinner-f6ecff617ec2ba7f559e6f535cad9b70a3f91120737535dab4d4548a6c83576c.gif","select2x2.png":"select2x2-6fe28d687dc0ed4d96016238c608ba1e7198c9c9accfa0b360b78018b9fb9bc2.png","font-awesome/fontawesome-webfont.eot":"font-awesome/fontawesome-webfont-a280856e20cc0af53390b729ca0ac3edbf8fc889a828a379c5d634c91e80c808.eot","font-awesome/fontawesome-webfont.woff2":"font-awesome/fontawesome-webfont-2932abf996373e87fbf2e950876b1962f1b57db954a1643ea68831d9fbb74da4.woff2","font-awesome/fontawesome-webfont.woff":"font-awesome/fontawesome-webfont-35fa8302dd7d3d191ebb7acac543efcfa2b85a0da573b3ab45cc122ffcc45ce5.woff","font-awesome/fontawesome-webfont.ttf":"font-awesome/fontawesome-webfont-8630313bee77f64206067ed80eb6a7c721b0bbfc91c94210966969d4dcc43ba7.ttf","font-awesome/fontawesome-webfont.svg":"font-awesome/fontawesome-webfont-6b0adce775f4d57ac800f23b05af72ced748ae51ba67a65b67b7316f1ed331b3.svg","france.png":"france-f4341a7ec8331161a9c8d5298f808014c3fc9c799b5a29ed95eb56a7f3ccd0df.png","quebec.png":"quebec-776d563b6a4ac4312cae9f0bfe630c20711346e8dbddd41040998eba79f4b588.png","belgique.png":"belgique-3b8b772a522de2cbae7714b35a956faf2c394419b532a14bba982fed3f341091.png","suisse.png":"suisse-58d067f1c3fcdc4000fa13e95896cd5369a2b91aafd314475aa5e29da0b543d1.png","modernizr.js":"modernizr-654222debe8018b12f1993ceddff30dc163a7d5008d79869c399d6d167321f97.js","agendadescommuns.png":"agendadescommuns-cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6.png","alert.png":"alert-762ace9479328243a44061346b64c4d6b997e963c68dfc6bddd9e4d241192906.png","baby_gnu_adl.png":"baby_gnu_adl-232caf355c30740d5d9b30491887cd546b8849b33ca9bdb6cc71f8a47ea61815.png","communs.png":"communs-cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6.png","lef-small.png":"lef-small-160cf5b883add60c9c0f4361bd8425c75f6fb23b0e551a0b941fa0491c70e0c9.png","lef.png":"lef-bec4081a11fbef165216827cf72c7a292ad772a77af6b8132e5bc0bbf83cb2d9.png","priorite-logiciel-libre-je-soutiens-april_2_m.png":"priorite-logiciel-libre-je-soutiens-april_2_m-6442e454e96ed45cc1ebc40673a6c50bd286b9c28ea6a8b58572e94f7d6459fc.png","team.png":"team-cb04c7a311f7160c4eb6a281eae68be84f26991dde5d415bb4e205e6726ae275.png","application.js":"application-307219623ded8fdc9ee285ad85d84051e026d5bfc9ff99ad749c917ab9dfcc76.js","active_admin/application.js":"active_admin/application-50ffc9f86e474cd52ffb7ce3b3572255ad6646ea17097a056f330b540eae402c.js","tinymce/jquery.tinymce.js":"tinymce/jquery.tinymce.js","tinymce/langs/readme.md":"tinymce/langs/readme.md","tinymce/license.txt":"tinymce/license.txt","tinymce/plugins/advlist/plugin.js":"tinymce/plugins/advlist/plugin.js","tinymce/plugins/anchor/plugin.js":"tinymce/plugins/anchor/plugin.js","tinymce/plugins/autolink/plugin.js":"tinymce/plugins/autolink/plugin.js","tinymce/plugins/autoresize/plugin.js":"tinymce/plugins/autoresize/plugin.js","tinymce/plugins/autosave/plugin.js":"tinymce/plugins/autosave/plugin.js","tinymce/plugins/bbcode/plugin.js":"tinymce/plugins/bbcode/plugin.js","tinymce/plugins/charmap/plugin.js":"tinymce/plugins/charmap/plugin.js","tinymce/plugins/code/plugin.js":"tinymce/plugins/code/plugin.js","tinymce/plugins/codesample/css/prism.css":"tinymce/plugins/codesample/css/prism.css","tinymce/plugins/codesample/plugin.js":"tinymce/plugins/codesample/plugin.js","tinymce/plugins/colorpicker/plugin.js":"tinymce/plugins/colorpicker/plugin.js","tinymce/plugins/contextmenu/plugin.js":"tinymce/plugins/contextmenu/plugin.js","tinymce/plugins/directionality/plugin.js":"tinymce/plugins/directionality/plugin.js","tinymce/plugins/emoticons/img/smiley-cool.gif":"tinymce/plugins/emoticons/img/smiley-cool-bb0e93a050a32df7913e4026b3c88a176998e0e3e073ba06e9b73f6c24227c9c.gif","tinymce/plugins/emoticons/img/smiley-cry.gif":"tinymce/plugins/emoticons/img/smiley-cry-a0c5f3e7a682449c973c9d9f7c46342081c46920686d2353f57aff91ab907f68.gif","tinymce/plugins/emoticons/img/smiley-embarassed.gif":"tinymce/plugins/emoticons/img/smiley-embarassed-d3cafcb50b335672cb5e9f4600ea9ea261dac7828dd28844d4927c393a25618f.gif","tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif":"tinymce/plugins/emoticons/img/smiley-foot-in-mouth-03fe04d3ed533423ac81f05146584b0c451be3d4a30e76687ceef283ed07071f.gif","tinymce/plugins/emoticons/img/smiley-frown.gif":"tinymce/plugins/emoticons/img/smiley-frown-1b984bf98931dd1debb54461eb9d83e985f2b2999fe14bcb556d6c0921bc83b0.gif","tinymce/plugins/emoticons/img/smiley-innocent.gif":"tinymce/plugins/emoticons/img/smiley-innocent-8db353ef102196f2c6ddf5c4666446de955d7b14fc0957c806c9dbfb48fb0c29.gif","tinymce/plugins/emoticons/img/smiley-kiss.gif":"tinymce/plugins/emoticons/img/smiley-kiss-3154c3665356c13ab10fefdbac1fe187fff978a0052037c99cdc4a97103413f2.gif","tinymce/plugins/emoticons/img/smiley-laughing.gif":"tinymce/plugins/emoticons/img/smiley-laughing-8f6adedcd091975ffead171867a6304d908bb6541a6ccb4919286ec6b7d4551e.gif","tinymce/plugins/emoticons/img/smiley-money-mouth.gif":"tinymce/plugins/emoticons/img/smiley-money-mouth-f0b9f4f22e237f5dbc851f900fed8d7eca4c954ae6fbc606c0cd8be431d0ac80.gif","tinymce/plugins/emoticons/img/smiley-sealed.gif":"tinymce/plugins/emoticons/img/smiley-sealed-9933b442636b6e537df7b564e2c3f7a2873526eea6b022a98eb1e468e5204c32.gif","tinymce/plugins/emoticons/img/smiley-smile.gif":"tinymce/plugins/emoticons/img/smiley-smile-fd89cd460ffcacb7e725e00c0275ef5b3924ce468248e5ff4fb43545571cfa65.gif","tinymce/plugins/emoticons/img/smiley-surprised.gif":"tinymce/plugins/emoticons/img/smiley-surprised-3871f356cb41976d7ae8a5f005e8739e4d014352a8adef9b33f773d81b6e6c01.gif","tinymce/plugins/emoticons/img/smiley-tongue-out.gif":"tinymce/plugins/emoticons/img/smiley-tongue-out-5843c85667a8226dc43be83749fd9fbbc5d20b1577de2b763915d99815d37d47.gif","tinymce/plugins/emoticons/img/smiley-undecided.gif":"tinymce/plugins/emoticons/img/smiley-undecided-d8b9bcbb433951ff3c4ca8dd959ac3844239b98e6d52218833e1485a91f67347.gif","tinymce/plugins/emoticons/img/smiley-wink.gif":"tinymce/plugins/emoticons/img/smiley-wink-2af75ad7b1c08488505513503e34b15f40005e04a2a9568f698f0945d2d8ba1f.gif","tinymce/plugins/emoticons/img/smiley-yell.gif":"tinymce/plugins/emoticons/img/smiley-yell-bba903fbcb46fce8c68b9e01863fd095b3b1d0e6aa72161f3a88d762a5f90a79.gif","tinymce/plugins/emoticons/plugin.js":"tinymce/plugins/emoticons/plugin.js","tinymce/plugins/example/dialog.html":"tinymce/plugins/example/dialog.html","tinymce/plugins/example/plugin.js":"tinymce/plugins/example/plugin.js","tinymce/plugins/example_dependency/plugin.js":"tinymce/plugins/example_dependency/plugin.js","tinymce/plugins/fullpage/plugin.js":"tinymce/plugins/fullpage/plugin.js","tinymce/plugins/fullscreen/plugin.js":"tinymce/plugins/fullscreen/plugin.js","tinymce/plugins/hr/plugin.js":"tinymce/plugins/hr/plugin.js","tinymce/plugins/image/plugin.js":"tinymce/plugins/image/plugin.js","tinymce/plugins/imagetools/plugin.js":"tinymce/plugins/imagetools/plugin.js","tinymce/plugins/importcss/plugin.js":"tinymce/plugins/importcss/plugin.js","tinymce/plugins/insertdatetime/plugin.js":"tinymce/plugins/insertdatetime/plugin.js","tinymce/plugins/layer/plugin.js":"tinymce/plugins/layer/plugin.js","tinymce/plugins/legacyoutput/plugin.js":"tinymce/plugins/legacyoutput/plugin.js","tinymce/plugins/link/plugin.js":"tinymce/plugins/link/plugin.js","tinymce/plugins/lists/plugin.js":"tinymce/plugins/lists/plugin.js","tinymce/plugins/media/moxieplayer.swf":"tinymce/plugins/media/moxieplayer.swf","tinymce/plugins/media/plugin.js":"tinymce/plugins/media/plugin.js","tinymce/plugins/nonbreaking/plugin.js":"tinymce/plugins/nonbreaking/plugin.js","tinymce/plugins/noneditable/plugin.js":"tinymce/plugins/noneditable/plugin.js","tinymce/plugins/pagebreak/plugin.js":"tinymce/plugins/pagebreak/plugin.js","tinymce/plugins/paste/plugin.js":"tinymce/plugins/paste/plugin.js","tinymce/plugins/preview/plugin.js":"tinymce/plugins/preview/plugin.js","tinymce/plugins/print/plugin.js":"tinymce/plugins/print/plugin.js","tinymce/plugins/save/plugin.js":"tinymce/plugins/save/plugin.js","tinymce/plugins/searchreplace/plugin.js":"tinymce/plugins/searchreplace/plugin.js","tinymce/plugins/spellchecker/plugin.js":"tinymce/plugins/spellchecker/plugin.js","tinymce/plugins/tabfocus/plugin.js":"tinymce/plugins/tabfocus/plugin.js","tinymce/plugins/table/plugin.js":"tinymce/plugins/table/plugin.js","tinymce/plugins/template/plugin.js":"tinymce/plugins/template/plugin.js","tinymce/plugins/textcolor/plugin.js":"tinymce/plugins/textcolor/plugin.js","tinymce/plugins/textpattern/plugin.js":"tinymce/plugins/textpattern/plugin.js","tinymce/plugins/visualblocks/css/visualblocks.css":"tinymce/plugins/visualblocks/css/visualblocks.css","tinymce/plugins/visualblocks/plugin.js":"tinymce/plugins/visualblocks/plugin.js","tinymce/plugins/visualchars/plugin.js":"tinymce/plugins/visualchars/plugin.js","tinymce/plugins/wordcount/plugin.js":"tinymce/plugins/wordcount/plugin.js","tinymce/skins/lightgray/content.inline.min.css":"tinymce/skins/lightgray/content.inline.min.css","tinymce/skins/lightgray/content.min.css":"tinymce/skins/lightgray/content.min.css","tinymce/skins/lightgray/fonts/tinymce-small.eot":"tinymce/skins/lightgray/fonts/tinymce-small.eot","tinymce/skins/lightgray/fonts/tinymce-small.svg":"tinymce/skins/lightgray/fonts/tinymce-small.svg","tinymce/skins/lightgray/fonts/tinymce-small.ttf":"tinymce/skins/lightgray/fonts/tinymce-small.ttf","tinymce/skins/lightgray/fonts/tinymce-small.woff":"tinymce/skins/lightgray/fonts/tinymce-small.woff","tinymce/skins/lightgray/fonts/tinymce.eot":"tinymce/skins/lightgray/fonts/tinymce.eot","tinymce/skins/lightgray/fonts/tinymce.svg":"tinymce/skins/lightgray/fonts/tinymce.svg","tinymce/skins/lightgray/fonts/tinymce.ttf":"tinymce/skins/lightgray/fonts/tinymce.ttf","tinymce/skins/lightgray/fonts/tinymce.woff":"tinymce/skins/lightgray/fonts/tinymce.woff","tinymce/skins/lightgray/img/anchor.gif":"tinymce/skins/lightgray/img/anchor-2861666fd107d278d4449970615136d06d7f746be9bb19072cf9c8f30e565e1e.gif","tinymce/skins/lightgray/img/loader.gif":"tinymce/skins/lightgray/img/loader-eb7cfd3d959b2e09c170f532e29f8b825f9bc770b2279fde58e595617753e244.gif","tinymce/skins/lightgray/img/object.gif":"tinymce/skins/lightgray/img/object-e6a15e52bc4a17b085073ba8debd4708ead6ae3d4cbeb3880c65cb7afc489777.gif","tinymce/skins/lightgray/img/trans.gif":"tinymce/skins/lightgray/img/trans-9cf020d7c3bba7f5ab10cda54aabef934f906d4f9a3acf99e9e7dc6c98579635.gif","tinymce/skins/lightgray/skin.ie7.min.css":"tinymce/skins/lightgray/skin.ie7.min.css","tinymce/skins/lightgray/skin.min.css":"tinymce/skins/lightgray/skin.min.css","tinymce/themes/modern/theme.js":"tinymce/themes/modern/theme.js","tinymce/tinymce.js":"tinymce/tinymce.js","tinymce/langs/ar.js":"tinymce/langs/ar.js","tinymce/langs/ar_SA.js":"tinymce/langs/ar_SA.js","tinymce/langs/az.js":"tinymce/langs/az.js","tinymce/langs/be.js":"tinymce/langs/be.js","tinymce/langs/bg_BG.js":"tinymce/langs/bg_BG.js","tinymce/langs/bn_BD.js":"tinymce/langs/bn_BD.js","tinymce/langs/bs.js":"tinymce/langs/bs.js","tinymce/langs/ca.js":"tinymce/langs/ca.js","tinymce/langs/cs.js":"tinymce/langs/cs.js","tinymce/langs/cs_CZ.js":"tinymce/langs/cs_CZ.js","tinymce/langs/cy.js":"tinymce/langs/cy.js","tinymce/langs/da.js":"tinymce/langs/da.js","tinymce/langs/de.js":"tinymce/langs/de.js","tinymce/langs/de_AT.js":"tinymce/langs/de_AT.js","tinymce/langs/dv.js":"tinymce/langs/dv.js","tinymce/langs/el.js":"tinymce/langs/el.js","tinymce/langs/en_CA.js":"tinymce/langs/en_CA.js","tinymce/langs/en_GB.js":"tinymce/langs/en_GB.js","tinymce/langs/eo.js":"tinymce/langs/eo.js","tinymce/langs/es.js":"tinymce/langs/es.js","tinymce/langs/es_MX.js":"tinymce/langs/es_MX.js","tinymce/langs/et.js":"tinymce/langs/et.js","tinymce/langs/eu.js":"tinymce/langs/eu.js","tinymce/langs/fa.js":"tinymce/langs/fa.js","tinymce/langs/fa_IR.js":"tinymce/langs/fa_IR.js","tinymce/langs/fi.js":"tinymce/langs/fi.js","tinymce/langs/fo.js":"tinymce/langs/fo.js","tinymce/langs/fr_CH.js":"tinymce/langs/fr_CH.js","tinymce/langs/fr_FR.js":"tinymce/langs/fr_FR.js","tinymce/langs/ga.js":"tinymce/langs/ga.js","tinymce/langs/gd.js":"tinymce/langs/gd.js","tinymce/langs/gl.js":"tinymce/langs/gl.js","tinymce/langs/he_IL.js":"tinymce/langs/he_IL.js","tinymce/langs/hi_IN.js":"tinymce/langs/hi_IN.js","tinymce/langs/hr.js":"tinymce/langs/hr.js","tinymce/langs/hu_HU.js":"tinymce/langs/hu_HU.js","tinymce/langs/hy.js":"tinymce/langs/hy.js","tinymce/langs/id.js":"tinymce/langs/id.js","tinymce/langs/is_IS.js":"tinymce/langs/is_IS.js","tinymce/langs/it.js":"tinymce/langs/it.js","tinymce/langs/ja.js":"tinymce/langs/ja.js","tinymce/langs/ka_GE.js":"tinymce/langs/ka_GE.js","tinymce/langs/kab.js":"tinymce/langs/kab.js","tinymce/langs/kk.js":"tinymce/langs/kk.js","tinymce/langs/km_KH.js":"tinymce/langs/km_KH.js","tinymce/langs/ko.js":"tinymce/langs/ko.js","tinymce/langs/ko_KR.js":"tinymce/langs/ko_KR.js","tinymce/langs/ku.js":"tinymce/langs/ku.js","tinymce/langs/ku_IQ.js":"tinymce/langs/ku_IQ.js","tinymce/langs/lb.js":"tinymce/langs/lb.js","tinymce/langs/lt.js":"tinymce/langs/lt.js","tinymce/langs/lv.js":"tinymce/langs/lv.js","tinymce/langs/mk_MK.js":"tinymce/langs/mk_MK.js","tinymce/langs/ml.js":"tinymce/langs/ml.js","tinymce/langs/ml_IN.js":"tinymce/langs/ml_IN.js","tinymce/langs/mn_MN.js":"tinymce/langs/mn_MN.js","tinymce/langs/nb_NO.js":"tinymce/langs/nb_NO.js","tinymce/langs/nl.js":"tinymce/langs/nl.js","tinymce/langs/pl.js":"tinymce/langs/pl.js","tinymce/langs/pt_BR.js":"tinymce/langs/pt_BR.js","tinymce/langs/pt_PT.js":"tinymce/langs/pt_PT.js","tinymce/langs/ro.js":"tinymce/langs/ro.js","tinymce/langs/ru.js":"tinymce/langs/ru.js","tinymce/langs/ru_RU.js":"tinymce/langs/ru_RU.js","tinymce/langs/si_LK.js":"tinymce/langs/si_LK.js","tinymce/langs/sk.js":"tinymce/langs/sk.js","tinymce/langs/sl_SI.js":"tinymce/langs/sl_SI.js","tinymce/langs/sr.js":"tinymce/langs/sr.js","tinymce/langs/sv_SE.js":"tinymce/langs/sv_SE.js","tinymce/langs/ta.js":"tinymce/langs/ta.js","tinymce/langs/ta_IN.js":"tinymce/langs/ta_IN.js","tinymce/langs/tg.js":"tinymce/langs/tg.js","tinymce/langs/th_TH.js":"tinymce/langs/th_TH.js","tinymce/langs/tr.js":"tinymce/langs/tr.js","tinymce/langs/tr_TR.js":"tinymce/langs/tr_TR.js","tinymce/langs/tt.js":"tinymce/langs/tt.js","tinymce/langs/ug.js":"tinymce/langs/ug.js","tinymce/langs/uk.js":"tinymce/langs/uk.js","tinymce/langs/uk_UA.js":"tinymce/langs/uk_UA.js","tinymce/langs/vi.js":"tinymce/langs/vi.js","tinymce/langs/vi_VN.js":"tinymce/langs/vi_VN.js","tinymce/langs/zh_CN.js":"tinymce/langs/zh_CN.js","tinymce/langs/zh_TW.js":"tinymce/langs/zh_TW.js","markers-matte.png":"markers-matte-497826545a90e09a240504d14530eba45823b19fd44175e09e27c47cd822ddb9.png","markers-matte@2x.png":"markers-matte@2x-948fc8c4426f04f60964ed20394247f45b0b60e575d02398b9b6810e7a29a823.png","markers-plain.png":"markers-plain-cf233423aa44e75ac0031e77b8ba571cd3331010517e1197e63fb7b06856c1ff.png","markers-shadow.png":"markers-shadow-8703a2262710f5e3d29e65d2acdf90d6512e159e119d27b8234731d8a6208a20.png","markers-shadow@2x.png":"markers-shadow@2x-b21a536be27313fb504f69f5899ff0b1245b276571769ac08d6c32c35676e47a.png","markers-soft.png":"markers-soft-e78784e4ed70aaffddd73c315fab590233cc4e7b72388d7dd47a14796fc7c739.png","markers-soft@2x.png":"markers-soft@2x-c1e77253a8bfbe30cec24885d7046f443b76ebb66f4c961f77083b03f4a5cbaf.png","webshims/shims/jpicker/images/AlphaBar.png":"webshims/shims/jpicker/images/AlphaBar-34d23568a887827c654ed2ac63ed3857a2cbd690643c471ea4b21c08a1568454.png","webshims/shims/jpicker/images/Bars.png":"webshims/shims/jpicker/images/Bars-a697469b1a3828d81b3bdaf334ade0637dd6adf9bf45859aeb88a6ffc06b009f.png","webshims/shims/jpicker/images/Maps.png":"webshims/shims/jpicker/images/Maps-538873f6da4e3a26cd5bb92f305f01e0ca0680cd08d488aef3e1eb250d77a968.png","webshims/shims/jpicker/images/NoColor.png":"webshims/shims/jpicker/images/NoColor-d266c220953f0b4fe96aeb868b82148e4c2ad380b1ed04d29214602851204e86.png","webshims/shims/jpicker/images/bar-opacity.png":"webshims/shims/jpicker/images/bar-opacity-690f9f36c78c2ebdfe7510739082dd835cc940565b794617a2bcaf93a566d938.png","webshims/shims/jpicker/images/map-opacity.png":"webshims/shims/jpicker/images/map-opacity-00182478b4fc3dedc97b9d2c46d9917f82c321110cab01e0f2ad4725978c2fd3.png","webshims/shims/jpicker/images/mappoint.gif":"webshims/shims/jpicker/images/mappoint-25687420458d1f31e399b1bc5a25e95a6dce8b898ed7f9d4361ff6cb430a7c45.gif","webshims/shims/jpicker/images/picker.gif":"webshims/shims/jpicker/images/picker-3aa5592f4e753f0244866a40b9c48fced398d219b8bc5ee76d2d51f9f952c9b2.gif","webshims/shims/jpicker/images/preview-opacity.png":"webshims/shims/jpicker/images/preview-opacity-12751bd440befc7037806e0451e2a2a8577655e3de1b702a2b50514ba2e9628d.png","webshims/shims/jpicker/images/rangearrows.gif":"webshims/shims/jpicker/images/rangearrows-d13aa5195095eb2e0d990d488ff4c5ed65052e6065d709463c97ed0d25cf652b.gif","webshims/shims/styles/color-picker.png":"webshims/shims/styles/color-picker-2141bfffae7d9714b5260735c338beb44ed24c5982f267fc1e3158ac4b82079f.png","webshims/shims/styles/progress.gif":"webshims/shims/styles/progress-8023960ce5bc957d1f0014859a51e55b9a3ce180bfd3d214a1a0629e2608a446.gif","webshims/shims/styles/progress.png":"webshims/shims/styles/progress-a9f7c78ea64c14559c7e683daaba141f50fac42e68e88232e416ca21645d0139.png","webshims/shims/styles/transparent.png":"webshims/shims/styles/transparent-384a16eed212e680374ad9b8529fb3de3422e515b2e10fdc18d7afdba59a1fa9.png","jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png":"jquery-ui/ui-bg_flat_0_aaaaaa_40x100-9a8492a580bf85d3e98ae8861fbd45567e5a1f83eeafcf9574da0399d5f602ab.png","jquery-ui/ui-bg_flat_75_ffffff_40x100.png":"jquery-ui/ui-bg_flat_75_ffffff_40x100-39ab7ccd9f4e82579da78a9241265df288d8eb65dbbd7cf48aed2d0129887df5.png","jquery-ui/ui-bg_glass_55_fbf9ee_1x400.png":"jquery-ui/ui-bg_glass_55_fbf9ee_1x400-691597e8a40a891ea94d3589976ecfc33e6145c49422443b00ac2b5a0022964c.png","jquery-ui/ui-bg_glass_65_ffffff_1x400.png":"jquery-ui/ui-bg_glass_65_ffffff_1x400-f0e6cd91b837d5c5644d026e5ffeccd907953317cd5c0f689901733afda260b2.png","jquery-ui/ui-bg_glass_75_dadada_1x400.png":"jquery-ui/ui-bg_glass_75_dadada_1x400-c108f5cbf2dd9ec07a26530695ddd95e1664597ce6c056ae44c162cc2e28cec4.png","jquery-ui/ui-bg_glass_75_e6e6e6_1x400.png":"jquery-ui/ui-bg_glass_75_e6e6e6_1x400-ddf5dd4e0ef2b185e8bb0af7b6e90ebe74a84384cb4700658e76e754c8bfe550.png","jquery-ui/ui-bg_glass_95_fef1ec_1x400.png":"jquery-ui/ui-bg_glass_95_fef1ec_1x400-f6f1c1bedf1a0f37cfef81d12f5f012869d1ee7c984775a569827a1784d34f5c.png","jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100.png":"jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100-54270656df079c4da5182629a080fc633b6f84b87985eb016d25a560e2c38d4a.png","jquery-ui/ui-icons_222222_256x240.png":"jquery-ui/ui-icons_222222_256x240-57adb0d65f4e91dacfee975d9574422bee7486c8a182d60133728c672f2cdbbc.png","jquery-ui/ui-icons_2e83ff_256x240.png":"jquery-ui/ui-icons_2e83ff_256x240-20f8c6667afc48aa433ee9eb6d8a0584bdbd6b4a4a9091ff1e6b3adb31e63bd9.png","jquery-ui/ui-icons_454545_256x240.png":"jquery-ui/ui-icons_454545_256x240-07460e843c3e59aaadbb34231e699e856a2980753c7a47b66447da5d9f93fb7f.png","jquery-ui/ui-icons_888888_256x240.png":"jquery-ui/ui-icons_888888_256x240-ea2e29625de3463465e93b002b065f5833e05b97f7a052b1c141e754d62e1a8b.png","jquery-ui/ui-icons_cd0a0a_256x240.png":"jquery-ui/ui-icons_cd0a0a_256x240-1e32c6dbf5d3fd342f27a78aa881550d6412aa207f48468724a6a15402b6041b.png","baby_gnu_adl.svg":"baby_gnu_adl-97251005d3225cf1d58b8c497d6b7905dbc9560cc8acd50118fcce60d0a2679e.svg"}} \ No newline at end of file +{"files":{"active_admin-617b799bade586fce74b4e0121a99adb6ff69314ffc69f4e24529028a7b72538.css":{"logical_path":"active_admin.css","mtime":"2016-05-19T21:35:29+02:00","size":214498,"digest":"617b799bade586fce74b4e0121a99adb6ff69314ffc69f4e24529028a7b72538","integrity":"sha256-YXt5m63lhvznS04BIama22/2kxT/xp9OJFKQKKe3JTg="},"active_admin/nested_menu_arrow-15084d93c65c1964d7077700ea748bd2d70cfa2d4c19707c58a9c64e232dd442.gif":{"logical_path":"active_admin/nested_menu_arrow.gif","mtime":"2016-06-30T21:12:27+02:00","size":70,"digest":"15084d93c65c1964d7077700ea748bd2d70cfa2d4c19707c58a9c64e232dd442","integrity":"sha256-FQhNk8ZcGWTXB3cA6nSL0tcM+i1MGXB8WKnGTiMt1EI="},"active_admin/nested_menu_arrow_dark-7c43b8e0a5f8823875f49a093c9d7a6b374f885b6f9cc248ae9cd7e6e9b29034.gif":{"logical_path":"active_admin/nested_menu_arrow_dark.gif","mtime":"2016-06-30T21:12:27+02:00","size":70,"digest":"7c43b8e0a5f8823875f49a093c9d7a6b374f885b6f9cc248ae9cd7e6e9b29034","integrity":"sha256-fEO44KX4gjh19JoJPJ16azdPiFtvnMJIrpzX5umykDQ="},"active_admin/datepicker/datepicker-input-icon-d9c2bb73769af777c8a71720d29741f3a499aebd5a043e9a119bd0d9597aed47.png":{"logical_path":"active_admin/datepicker/datepicker-input-icon.png","mtime":"2016-06-30T21:12:27+02:00","size":1535,"digest":"d9c2bb73769af777c8a71720d29741f3a499aebd5a043e9a119bd0d9597aed47","integrity":"sha256-2cK7c3aa93fIpxcg0pdB86SZrr1aBD6aEZvQ2Vl67Uc="},"active_admin/orderable-29374dbb55b0012d78a37c614d573bb3474f0779849b478a147d0f1845ca6617.png":{"logical_path":"active_admin/orderable.png","mtime":"2016-06-30T21:12:27+02:00","size":220,"digest":"29374dbb55b0012d78a37c614d573bb3474f0779849b478a147d0f1845ca6617","integrity":"sha256-KTdNu1WwAS14o3xhTVc7s0dPB3mEm0eKFH0PGEXKZhc="},"active_admin_pagedown/wmd-buttons-c2040b12f2d6cb568ddc33587a070a29a18fed20099260c3ecbbfdbd62042f7b.png":{"logical_path":"active_admin_pagedown/wmd-buttons.png","mtime":"2016-05-04T17:49:02+02:00","size":7465,"digest":"c2040b12f2d6cb568ddc33587a070a29a18fed20099260c3ecbbfdbd62042f7b","integrity":"sha256-wgQLEvLWy1aN3DNYegcKKaGP7SAJkmDD7Lv9vWIEL3s="},"active_admin/print-cb755dcaacb896fb80d996ba6eee250ea19ee816526e5e5d0137ed2af34d08f1.css":{"logical_path":"active_admin/print.css","mtime":"2016-05-04T17:49:01+02:00","size":18961,"digest":"cb755dcaacb896fb80d996ba6eee250ea19ee816526e5e5d0137ed2af34d08f1","integrity":"sha256-y3Vdyqy4lvuA2Za6bu4lDqGe6BZSbl5dATftKvNNCPE="},"active_admin-3ac0f1eff2fd35f310a1bd2242c049f9d2cc006c7b1065541a5d855556e24393.js":{"logical_path":"active_admin.js","mtime":"2016-06-25T16:51:02+02:00","size":771406,"digest":"3ac0f1eff2fd35f310a1bd2242c049f9d2cc006c7b1065541a5d855556e24393","integrity":"sha256-OsDx7/L9NfMQob0iQsBJ+dLMAGx7EGVUGl2FVVbiQ5M="},"layers-2x-0c02a2388f637d21f86e6d4b314ec9a968e7b05ad4c3a005280a3f76c0fd3cb8.png":{"logical_path":"layers-2x.png","mtime":"2016-05-04T17:44:43+02:00","size":2898,"digest":"0c02a2388f637d21f86e6d4b314ec9a968e7b05ad4c3a005280a3f76c0fd3cb8","integrity":"sha256-DAKiOI9jfSH4bm1LMU7JqWjnsFrUw6AFKAo/dsD9PLg="},"layers-0908aa2a72a082fb2563a2427a5e4fb247571862b448b80fb6f720af1109923e.png":{"logical_path":"layers.png","mtime":"2016-05-04T17:44:43+02:00","size":1502,"digest":"0908aa2a72a082fb2563a2427a5e4fb247571862b448b80fb6f720af1109923e","integrity":"sha256-CQiqKnKggvslY6JCel5PskdXGGK0SLgPtvcgrxEJkj4="},"marker-icon-2x-454dc479e82b487529b6b93d6a9b29ac69ca7b4f5a9d5fdf8e01871f6d216113.png":{"logical_path":"marker-icon-2x.png","mtime":"2016-05-04T17:44:43+02:00","size":4033,"digest":"454dc479e82b487529b6b93d6a9b29ac69ca7b4f5a9d5fdf8e01871f6d216113","integrity":"sha256-RU3EeegrSHUptrk9apsprGnKe09anV/fjgGHH20hYRM="},"marker-icon-915e83a6fc798c599e5c9e3f759d6bc065d65151019acd0410d1f4731bcaaf72.png":{"logical_path":"marker-icon.png","mtime":"2016-05-04T17:44:43+02:00","size":1747,"digest":"915e83a6fc798c599e5c9e3f759d6bc065d65151019acd0410d1f4731bcaaf72","integrity":"sha256-kV6Dpvx5jFmeXJ4/dZ1rwGXWUVEBms0EENH0cxvKr3I="},"marker-shadow-4f340d2d61746333dffe056e074ce1704ae4e47fec5a7de98322fbdbcfcb2b6d.png":{"logical_path":"marker-shadow.png","mtime":"2016-05-04T17:44:43+02:00","size":797,"digest":"4f340d2d61746333dffe056e074ce1704ae4e47fec5a7de98322fbdbcfcb2b6d","integrity":"sha256-TzQNLWF0YzPf/gVuB0zhcErk5H/sWn3pgyL728/LK20="},"tinymce-fe1156fd03b1a543924116118d1f4e0607f5f5c93ae1c7fc3f6715678aeafa22.js":{"logical_path":"tinymce.js","mtime":"2016-05-19T21:35:43+02:00","size":948,"digest":"fe1156fd03b1a543924116118d1f4e0607f5f5c93ae1c7fc3f6715678aeafa22","integrity":"sha256-/hFW/QOxpUOSQRYRjR9OBgf19ck64cf8P2cVZ4rq+iI="},"application-04dae2e3e83d47a4e01f16d1fd7598a83a4d7c9c52947b77c44f3203a27ea744.css":{"logical_path":"application.css","mtime":"2016-05-19T21:35:43+02:00","size":435929,"digest":"04dae2e3e83d47a4e01f16d1fd7598a83a4d7c9c52947b77c44f3203a27ea744","integrity":"sha256-BNri4+g9R6TgHxbR/XWYqDpNfJxSlHt3xE8yA6J+p0Q="},"select2-d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8.png":{"logical_path":"select2.png","mtime":"2016-05-04T17:45:07+02:00","size":613,"digest":"d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8","integrity":"sha256-1rXY2D28GPuNd8h2HTMc2eUSPJaElQurBAbpiiSsWug="},"select2-spinner-f6ecff617ec2ba7f559e6f535cad9b70a3f91120737535dab4d4548a6c83576c.gif":{"logical_path":"select2-spinner.gif","mtime":"2016-05-04T17:45:07+02:00","size":1849,"digest":"f6ecff617ec2ba7f559e6f535cad9b70a3f91120737535dab4d4548a6c83576c","integrity":"sha256-9uz/YX7Cun9Vnm9TXK2bcKP5ESBzdTXatNRUimyDV2w="},"select2x2-6fe28d687dc0ed4d96016238c608ba1e7198c9c9accfa0b360b78018b9fb9bc2.png":{"logical_path":"select2x2.png","mtime":"2016-05-04T17:45:07+02:00","size":845,"digest":"6fe28d687dc0ed4d96016238c608ba1e7198c9c9accfa0b360b78018b9fb9bc2","integrity":"sha256-b+KNaH3A7U2WAWI4xgi6HnGYycmsz6CzYLeAGLn7m8I="},"font-awesome/fontawesome-webfont-a280856e20cc0af53390b729ca0ac3edbf8fc889a828a379c5d634c91e80c808.eot":{"logical_path":"font-awesome/fontawesome-webfont.eot","mtime":"2016-05-19T21:35:29+02:00","size":76204,"digest":"a280856e20cc0af53390b729ca0ac3edbf8fc889a828a379c5d634c91e80c808","integrity":"sha256-ooCFbiDMCvUzkLcpygrD7b+PyImoKKN5xdY0yR6AyAg="},"font-awesome/fontawesome-webfont-2932abf996373e87fbf2e950876b1962f1b57db954a1643ea68831d9fbb74da4.woff2":{"logical_path":"font-awesome/fontawesome-webfont.woff2","mtime":"2016-05-19T21:35:29+02:00","size":71760,"digest":"2932abf996373e87fbf2e950876b1962f1b57db954a1643ea68831d9fbb74da4","integrity":"sha256-KTKr+ZY3Pof78ulQh2sZYvG1fblUoWQ+pogx2fu3TaQ="},"font-awesome/fontawesome-webfont-35fa8302dd7d3d191ebb7acac543efcfa2b85a0da573b3ab45cc122ffcc45ce5.woff":{"logical_path":"font-awesome/fontawesome-webfont.woff","mtime":"2016-05-19T21:35:29+02:00","size":90144,"digest":"35fa8302dd7d3d191ebb7acac543efcfa2b85a0da573b3ab45cc122ffcc45ce5","integrity":"sha256-NfqDAt19PRkeu3rKxUPvz6K4Wg2lc7OrRcwSL/zEXOU="},"font-awesome/fontawesome-webfont-8630313bee77f64206067ed80eb6a7c721b0bbfc91c94210966969d4dcc43ba7.ttf":{"logical_path":"font-awesome/fontawesome-webfont.ttf","mtime":"2016-05-19T21:35:29+02:00","size":152364,"digest":"8630313bee77f64206067ed80eb6a7c721b0bbfc91c94210966969d4dcc43ba7","integrity":"sha256-hjAxO+539kIGBn7YDranxyGwu/yRyUIQlmlp1NzEO6c="},"font-awesome/fontawesome-webfont-6b0adce775f4d57ac800f23b05af72ced748ae51ba67a65b67b7316f1ed331b3.svg":{"logical_path":"font-awesome/fontawesome-webfont.svg","mtime":"2016-05-19T21:35:29+02:00","size":390452,"digest":"6b0adce775f4d57ac800f23b05af72ced748ae51ba67a65b67b7316f1ed331b3","integrity":"sha256-awrc53X01XrIAPI7Ba9yztdIrlG6Z6ZbZ7cxbx7TMbM="},"france-f4341a7ec8331161a9c8d5298f808014c3fc9c799b5a29ed95eb56a7f3ccd0df.png":{"logical_path":"france.png","mtime":"2014-07-04T14:08:56+02:00","size":276,"digest":"f4341a7ec8331161a9c8d5298f808014c3fc9c799b5a29ed95eb56a7f3ccd0df","integrity":"sha256-9DQafsgzEWGpyNUpj4CAFMP8nHmbWintletWp/PM0N8="},"quebec-776d563b6a4ac4312cae9f0bfe630c20711346e8dbddd41040998eba79f4b588.png":{"logical_path":"quebec.png","mtime":"2015-10-22T22:54:30+02:00","size":567,"digest":"776d563b6a4ac4312cae9f0bfe630c20711346e8dbddd41040998eba79f4b588","integrity":"sha256-d21WO2pKxDEsrp8L/mMMIHETRujb3dQQQJmOunn0tYg="},"belgique-3b8b772a522de2cbae7714b35a956faf2c394419b532a14bba982fed3f341091.png":{"logical_path":"belgique.png","mtime":"2014-07-04T14:08:56+02:00","size":187,"digest":"3b8b772a522de2cbae7714b35a956faf2c394419b532a14bba982fed3f341091","integrity":"sha256-O4t3KlIt4suudxSzWpVvryw5RBm1MqFLupgv7T80EJE="},"suisse-58d067f1c3fcdc4000fa13e95896cd5369a2b91aafd314475aa5e29da0b543d1.png":{"logical_path":"suisse.png","mtime":"2015-10-22T22:54:30+02:00","size":299,"digest":"58d067f1c3fcdc4000fa13e95896cd5369a2b91aafd314475aa5e29da0b543d1","integrity":"sha256-WNBn8cP83EAA+hPpWJbNU2miuRqv0xRHWqXinaC1Q9E="},"modernizr-654222debe8018b12f1993ceddff30dc163a7d5008d79869c399d6d167321f97.js":{"logical_path":"modernizr.js","mtime":"2016-05-04T17:44:47+02:00","size":51365,"digest":"654222debe8018b12f1993ceddff30dc163a7d5008d79869c399d6d167321f97","integrity":"sha256-ZUIi3r6AGLEvGZPO3f8w3BY6fVAI15hpw5nW0WcyH5c="},"agendadescommuns-cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6.png":{"logical_path":"agendadescommuns.png","mtime":"2015-10-22T22:54:30+02:00","size":2760,"digest":"cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6","integrity":"sha256-zUDjQgJL4Fh/jnoOOQLTLPZwCdNJtnwA9ofgSZ/en/Y="},"alert-762ace9479328243a44061346b64c4d6b997e963c68dfc6bddd9e4d241192906.png":{"logical_path":"alert.png","mtime":"2014-07-04T14:08:56+02:00","size":47876,"digest":"762ace9479328243a44061346b64c4d6b997e963c68dfc6bddd9e4d241192906","integrity":"sha256-dirOlHkygkOkQGE0a2TE1rmX6WPGjfxr3dnk0kEZKQY="},"baby_gnu_adl-ff3fa5912b3f9164dcdebca6f4fe3f4195e6dae5e3c22c8361bef1d79626ea07.png":{"logical_path":"baby_gnu_adl.png","mtime":"2015-10-22T22:54:17+02:00","size":11494,"digest":"ff3fa5912b3f9164dcdebca6f4fe3f4195e6dae5e3c22c8361bef1d79626ea07","integrity":"sha256-/z+lkSs/kWTc3rym9P4/QZXm2uXjwiyDYb7x15Ym6gc="},"communs-cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6.png":{"logical_path":"communs.png","mtime":"2015-10-22T22:54:30+02:00","size":2760,"digest":"cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6","integrity":"sha256-zUDjQgJL4Fh/jnoOOQLTLPZwCdNJtnwA9ofgSZ/en/Y="},"lef-small-160cf5b883add60c9c0f4361bd8425c75f6fb23b0e551a0b941fa0491c70e0c9.png":{"logical_path":"lef-small.png","mtime":"2015-03-29T11:07:15+02:00","size":1089,"digest":"160cf5b883add60c9c0f4361bd8425c75f6fb23b0e551a0b941fa0491c70e0c9","integrity":"sha256-Fgz1uIOt1gycD0NhvYQlx19vsjsOVRoLlB+gSRxw4Mk="},"lef-bec4081a11fbef165216827cf72c7a292ad772a77af6b8132e5bc0bbf83cb2d9.png":{"logical_path":"lef.png","mtime":"2016-01-24T11:38:05+01:00","size":8415,"digest":"bec4081a11fbef165216827cf72c7a292ad772a77af6b8132e5bc0bbf83cb2d9","integrity":"sha256-vsQIGhH77xZSFoJ89yx6KSrXcqd69rgTLlvAu/g8stk="},"priorite-logiciel-libre-je-soutiens-april_2_m-6442e454e96ed45cc1ebc40673a6c50bd286b9c28ea6a8b58572e94f7d6459fc.png":{"logical_path":"priorite-logiciel-libre-je-soutiens-april_2_m.png","mtime":"2015-10-22T22:54:30+02:00","size":16952,"digest":"6442e454e96ed45cc1ebc40673a6c50bd286b9c28ea6a8b58572e94f7d6459fc","integrity":"sha256-ZELkVOlu1FzB68QGc6bFC9KGucKOpqi1hXLpT31kWfw="},"team-cb04c7a311f7160c4eb6a281eae68be84f26991dde5d415bb4e205e6726ae275.png":{"logical_path":"team.png","mtime":"2014-07-04T14:08:56+02:00","size":3586,"digest":"cb04c7a311f7160c4eb6a281eae68be84f26991dde5d415bb4e205e6726ae275","integrity":"sha256-ywTHoxH3FgxOtqKB6uaL6E8mmR3eXUFbtOIF5nJq4nU="},"application-0df2b8e7bf544e75ad6a6bdcc25bc16667215248d72850df1c004024352f9bfb.js":{"logical_path":"application.js","mtime":"2016-05-19T21:35:43+02:00","size":2155420,"digest":"0df2b8e7bf544e75ad6a6bdcc25bc16667215248d72850df1c004024352f9bfb","integrity":"sha256-DfK4579UTnWtamvcwlvBZmchUkjXKFDfHABAJDUvm/s="},"active_admin/application-50ffc9f86e474cd52ffb7ce3b3572255ad6646ea17097a056f330b540eae402c.js":{"logical_path":"active_admin/application.js","mtime":"2016-05-04T17:49:01+02:00","size":1669,"digest":"50ffc9f86e474cd52ffb7ce3b3572255ad6646ea17097a056f330b540eae402c","integrity":"sha256-UP/J+G5HTNUv+3zjs1ciVa1mRuoXCXoFbzMLVA6uQCw="},"tinymce-851b4961ce4c9997bc39867507ab34eb00de363cb3aab1b32a6b1c91ebf6733b.js":{"logical_path":"tinymce.js","mtime":"2016-05-21T22:53:26+02:00","size":948,"digest":"851b4961ce4c9997bc39867507ab34eb00de363cb3aab1b32a6b1c91ebf6733b","integrity":"sha256-hRtJYc5MmZe8OYZ1B6s06wDeNjyzqrGzKmsckev2czs="},"application-ee82c1c962333e87dcfc9a0eb1abbc739ed57ba7b77732ece49ab08b6cedf706.css":{"logical_path":"application.css","mtime":"2016-05-21T19:55:46+02:00","size":548037,"digest":"ee82c1c962333e87dcfc9a0eb1abbc739ed57ba7b77732ece49ab08b6cedf706","integrity":"sha256-7oLByWIzPofc/JoOsau8c57Ve6e3dzLs5Jqwi2zt9wY="},"application-917844760c88ae708837ec664e229eebbd170afbde3cc0b9af7b37164545505d.js":{"logical_path":"application.js","mtime":"2016-05-21T22:53:26+02:00","size":2159880,"digest":"917844760c88ae708837ec664e229eebbd170afbde3cc0b9af7b37164545505d","integrity":"sha256-kXhEdgyIrnCIN+xmTiKe670XCvvePMC5r3s3FkVFUF0="},"tinymce-b27c22af98a4be3cb8e2bc170a3dbc1f0c616e5405f637b9576f1a7f7ce13e00.js":{"logical_path":"tinymce.js","mtime":"2016-05-21T23:41:15+02:00","size":944,"digest":"b27c22af98a4be3cb8e2bc170a3dbc1f0c616e5405f637b9576f1a7f7ce13e00","integrity":"sha256-snwir5ikvjy44rwXCj28HwxhblQF9je5V28af3zhPgA="},"application-49e7e5af3b02eaa9e0c86ce8722922fd79170115d3e29f8696296467642c48f3.css":{"logical_path":"application.css","mtime":"2016-05-21T23:41:15+02:00","size":547973,"digest":"49e7e5af3b02eaa9e0c86ce8722922fd79170115d3e29f8696296467642c48f3","integrity":"sha256-SeflrzsC6qngyGzociki/XkXARXT4p+GlilkZ2QsSPM="},"application-5ec5b625b2030b1eb3f3370cfae1c263b197bd007490ab6251a3056a1583cb1f.js":{"logical_path":"application.js","mtime":"2016-05-21T23:41:15+02:00","size":2159876,"digest":"5ec5b625b2030b1eb3f3370cfae1c263b197bd007490ab6251a3056a1583cb1f","integrity":"sha256-XsW2JbIDCx6z8zcM+uHCY7GXvQB0kKtiUaMFahWDyx8="},"active_admin-68bb37e1af32798e8006da86254602580978bf587ad01d5ae98b3c8eedd8bca9.css":{"logical_path":"active_admin.css","mtime":"2016-05-21T23:41:15+02:00","size":214474,"digest":"68bb37e1af32798e8006da86254602580978bf587ad01d5ae98b3c8eedd8bca9","integrity":"sha256-aLs34a8yeY6ABtqGJUYCWAl4v1h60B1a6Ys8ju3YvKk="},"tinymce-c13c6df7f00dbbdc85771e880b8e9abf2f439376b72f484cd1d397bd6b68e96d.js":{"logical_path":"tinymce.js","mtime":"2016-05-21T23:41:15+02:00","size":944,"digest":"c13c6df7f00dbbdc85771e880b8e9abf2f439376b72f484cd1d397bd6b68e96d","integrity":"sha256-wTxt9/ANu9yFdx6IC46avy9Dk3a3L0hM0dOXvWto6W0="},"application-6670b0eea8f83814e96dbe243e5b8d2407e1db887d5495c5f02add0132ecf236.css":{"logical_path":"application.css","mtime":"2016-05-21T23:41:15+02:00","size":547833,"digest":"6670b0eea8f83814e96dbe243e5b8d2407e1db887d5495c5f02add0132ecf236","integrity":"sha256-ZnCw7qj4OBTpbb4kPluNJAfh24h9VJXF8CrdATLs8jY="},"application-45b9025ce219a47bb28597daeac0f5656ad0e16f5546c42f01dd4644a0f1c23c.js":{"logical_path":"application.js","mtime":"2016-05-21T23:41:15+02:00","size":2159860,"digest":"45b9025ce219a47bb28597daeac0f5656ad0e16f5546c42f01dd4644a0f1c23c","integrity":"sha256-RbkCXOIZpHuyhZfa6sD1ZWrQ4W9VRsQvAd1GRKDxwjw="},"markers-matte-497826545a90e09a240504d14530eba45823b19fd44175e09e27c47cd822ddb9.png":{"logical_path":"markers-matte.png","mtime":"2016-05-21T23:41:15+02:00","size":14323,"digest":"497826545a90e09a240504d14530eba45823b19fd44175e09e27c47cd822ddb9","integrity":"sha256-SXgmVFqQ4JokBQTRRTDrpFgjsZ/UQXXgnifEfNgi3bk="},"markers-matte@2x-948fc8c4426f04f60964ed20394247f45b0b60e575d02398b9b6810e7a29a823.png":{"logical_path":"markers-matte@2x.png","mtime":"2016-05-21T23:41:15+02:00","size":31113,"digest":"948fc8c4426f04f60964ed20394247f45b0b60e575d02398b9b6810e7a29a823","integrity":"sha256-lI/IxEJvBPYJZO0gOUJH9FsLYOV10COYubaBDnopqCM="},"markers-plain-cf233423aa44e75ac0031e77b8ba571cd3331010517e1197e63fb7b06856c1ff.png":{"logical_path":"markers-plain.png","mtime":"2016-05-21T23:41:15+02:00","size":7946,"digest":"cf233423aa44e75ac0031e77b8ba571cd3331010517e1197e63fb7b06856c1ff","integrity":"sha256-zyM0I6pE51rAAx53uLpXHNMzEBBRfhGX5j+3sGhWwf8="},"markers-shadow-8703a2262710f5e3d29e65d2acdf90d6512e159e119d27b8234731d8a6208a20.png":{"logical_path":"markers-shadow.png","mtime":"2016-05-21T23:41:15+02:00","size":535,"digest":"8703a2262710f5e3d29e65d2acdf90d6512e159e119d27b8234731d8a6208a20","integrity":"sha256-hwOiJicQ9ePSnmXSrN+Q1lEuFZ4RnSe4I0cx2KYgiiA="},"markers-shadow@2x-b21a536be27313fb504f69f5899ff0b1245b276571769ac08d6c32c35676e47a.png":{"logical_path":"markers-shadow@2x.png","mtime":"2016-05-21T23:41:15+02:00","size":1469,"digest":"b21a536be27313fb504f69f5899ff0b1245b276571769ac08d6c32c35676e47a","integrity":"sha256-shpTa+JzE/tQT2n1iZ/wsSRbJ2VxdprAjWwyw1Z25Ho="},"markers-soft-e78784e4ed70aaffddd73c315fab590233cc4e7b72388d7dd47a14796fc7c739.png":{"logical_path":"markers-soft.png","mtime":"2016-05-21T23:41:15+02:00","size":41226,"digest":"e78784e4ed70aaffddd73c315fab590233cc4e7b72388d7dd47a14796fc7c739","integrity":"sha256-54eE5O1wqv/d1zwxX6tZAjPMTntyOI191HoUeW/Hxzk="},"markers-soft@2x-c1e77253a8bfbe30cec24885d7046f443b76ebb66f4c961f77083b03f4a5cbaf.png":{"logical_path":"markers-soft@2x.png","mtime":"2016-05-21T23:41:15+02:00","size":66408,"digest":"c1e77253a8bfbe30cec24885d7046f443b76ebb66f4c961f77083b03f4a5cbaf","integrity":"sha256-wedyU6i/vjDOwkiF1wRvRDt267ZvTJYfdwg7A/Sly68="},"webshims/shims/jpicker/images/AlphaBar-34d23568a887827c654ed2ac63ed3857a2cbd690643c471ea4b21c08a1568454.png":{"logical_path":"webshims/shims/jpicker/images/AlphaBar.png","mtime":"2016-05-04T17:48:59+02:00","size":1622,"digest":"34d23568a887827c654ed2ac63ed3857a2cbd690643c471ea4b21c08a1568454","integrity":"sha256-NNI1aKiHgnxlTtKsY+04V6LL1pBkPEcepLIcCKFWhFQ="},"webshims/shims/jpicker/images/Bars-a697469b1a3828d81b3bdaf334ade0637dd6adf9bf45859aeb88a6ffc06b009f.png":{"logical_path":"webshims/shims/jpicker/images/Bars.png","mtime":"2016-05-04T17:48:59+02:00","size":1347,"digest":"a697469b1a3828d81b3bdaf334ade0637dd6adf9bf45859aeb88a6ffc06b009f","integrity":"sha256-ppdGmxo4KNgbO9rzNK3gY33Wrfm/RYWa64im/8BrAJ8="},"webshims/shims/jpicker/images/Maps-538873f6da4e3a26cd5bb92f305f01e0ca0680cd08d488aef3e1eb250d77a968.png":{"logical_path":"webshims/shims/jpicker/images/Maps.png","mtime":"2016-05-04T17:48:59+02:00","size":62011,"digest":"538873f6da4e3a26cd5bb92f305f01e0ca0680cd08d488aef3e1eb250d77a968","integrity":"sha256-U4hz9tpOOibNW7kvMF8B4MoGgM0I1Iiu8+HrJQ13qWg="},"webshims/shims/jpicker/images/NoColor-d266c220953f0b4fe96aeb868b82148e4c2ad380b1ed04d29214602851204e86.png":{"logical_path":"webshims/shims/jpicker/images/NoColor.png","mtime":"2016-05-04T17:48:59+02:00","size":491,"digest":"d266c220953f0b4fe96aeb868b82148e4c2ad380b1ed04d29214602851204e86","integrity":"sha256-0mbCIJU/C0/pauuGi4IUjkwq04Cx7QTSkhRgKFEgToY="},"webshims/shims/jpicker/images/bar-opacity-690f9f36c78c2ebdfe7510739082dd835cc940565b794617a2bcaf93a566d938.png":{"logical_path":"webshims/shims/jpicker/images/bar-opacity.png","mtime":"2016-05-04T17:48:59+02:00","size":96,"digest":"690f9f36c78c2ebdfe7510739082dd835cc940565b794617a2bcaf93a566d938","integrity":"sha256-aQ+fNseMLr3+dRBzkILdg1zJQFZbeUYXoryvk6Vm2Tg="},"webshims/shims/jpicker/images/map-opacity-00182478b4fc3dedc97b9d2c46d9917f82c321110cab01e0f2ad4725978c2fd3.png":{"logical_path":"webshims/shims/jpicker/images/map-opacity.png","mtime":"2016-05-04T17:48:59+02:00","size":139,"digest":"00182478b4fc3dedc97b9d2c46d9917f82c321110cab01e0f2ad4725978c2fd3","integrity":"sha256-ABgkeLT8Pe3Je50sRtmRf4LDIREMqwHg8q1HJZeML9M="},"webshims/shims/jpicker/images/mappoint-25687420458d1f31e399b1bc5a25e95a6dce8b898ed7f9d4361ff6cb430a7c45.gif":{"logical_path":"webshims/shims/jpicker/images/mappoint.gif","mtime":"2016-05-04T17:48:59+02:00","size":93,"digest":"25687420458d1f31e399b1bc5a25e95a6dce8b898ed7f9d4361ff6cb430a7c45","integrity":"sha256-JWh0IEWNHzHjmbG8WiXpWm3Oi4mO1/nUNh/2y0MKfEU="},"webshims/shims/jpicker/images/picker-3aa5592f4e753f0244866a40b9c48fced398d219b8bc5ee76d2d51f9f952c9b2.gif":{"logical_path":"webshims/shims/jpicker/images/picker.gif","mtime":"2016-05-04T17:48:59+02:00","size":146,"digest":"3aa5592f4e753f0244866a40b9c48fced398d219b8bc5ee76d2d51f9f952c9b2","integrity":"sha256-OqVZL051PwJEhmpAucSPztOY0hm4vF7nbS1R+flSybI="},"webshims/shims/jpicker/images/preview-opacity-12751bd440befc7037806e0451e2a2a8577655e3de1b702a2b50514ba2e9628d.png":{"logical_path":"webshims/shims/jpicker/images/preview-opacity.png","mtime":"2016-05-04T17:48:59+02:00","size":79,"digest":"12751bd440befc7037806e0451e2a2a8577655e3de1b702a2b50514ba2e9628d","integrity":"sha256-EnUb1EC+/HA3gG4EUeKiqFd2VePeG3AqK1BRS6LpYo0="},"webshims/shims/jpicker/images/rangearrows-d13aa5195095eb2e0d990d488ff4c5ed65052e6065d709463c97ed0d25cf652b.gif":{"logical_path":"webshims/shims/jpicker/images/rangearrows.gif","mtime":"2016-05-04T17:48:59+02:00","size":76,"digest":"d13aa5195095eb2e0d990d488ff4c5ed65052e6065d709463c97ed0d25cf652b","integrity":"sha256-0TqlGVCV6y4NmQ1Ij/TF7WUFLmBl1wlGPJftDSXPZSs="},"webshims/shims/styles/color-picker-2141bfffae7d9714b5260735c338beb44ed24c5982f267fc1e3158ac4b82079f.png":{"logical_path":"webshims/shims/styles/color-picker.png","mtime":"2016-05-04T17:48:59+02:00","size":338,"digest":"2141bfffae7d9714b5260735c338beb44ed24c5982f267fc1e3158ac4b82079f","integrity":"sha256-IUG//659lxS1Jgc1wzi+tE7STFmC8mf8HjFYrEuCB58="},"webshims/shims/styles/progress-8023960ce5bc957d1f0014859a51e55b9a3ce180bfd3d214a1a0629e2608a446.gif":{"logical_path":"webshims/shims/styles/progress.gif","mtime":"2016-05-04T17:48:59+02:00","size":35832,"digest":"8023960ce5bc957d1f0014859a51e55b9a3ce180bfd3d214a1a0629e2608a446","integrity":"sha256-gCOWDOW8lX0fABSFmlHlW5o84YC/09IUoaBiniYIpEY="},"webshims/shims/styles/progress-a9f7c78ea64c14559c7e683daaba141f50fac42e68e88232e416ca21645d0139.png":{"logical_path":"webshims/shims/styles/progress.png","mtime":"2016-05-04T17:48:59+02:00","size":299,"digest":"a9f7c78ea64c14559c7e683daaba141f50fac42e68e88232e416ca21645d0139","integrity":"sha256-qffHjqZMFFWcfmg9qroUH1D6xC5o6IIy5BbKIWRdATk="},"webshims/shims/styles/transparent-384a16eed212e680374ad9b8529fb3de3422e515b2e10fdc18d7afdba59a1fa9.png":{"logical_path":"webshims/shims/styles/transparent.png","mtime":"2016-05-04T17:48:59+02:00","size":93,"digest":"384a16eed212e680374ad9b8529fb3de3422e515b2e10fdc18d7afdba59a1fa9","integrity":"sha256-OEoW7tIS5oA3Stm4Up+z3jQi5RWy4Q/cGNev26WaH6k="},"jquery-ui/ui-bg_flat_0_aaaaaa_40x100-9a8492a580bf85d3e98ae8861fbd45567e5a1f83eeafcf9574da0399d5f602ab.png":{"logical_path":"jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png","mtime":"2016-05-04T17:48:40+02:00","size":180,"digest":"9a8492a580bf85d3e98ae8861fbd45567e5a1f83eeafcf9574da0399d5f602ab","integrity":"sha256-moSSpYC/hdPpiuiGH71FVn5aH4Pur8+VdNoDmdX2Aqs="},"jquery-ui/ui-bg_flat_75_ffffff_40x100-39ab7ccd9f4e82579da78a9241265df288d8eb65dbbd7cf48aed2d0129887df5.png":{"logical_path":"jquery-ui/ui-bg_flat_75_ffffff_40x100.png","mtime":"2016-05-04T17:48:40+02:00","size":178,"digest":"39ab7ccd9f4e82579da78a9241265df288d8eb65dbbd7cf48aed2d0129887df5","integrity":"sha256-Oat8zZ9Ogledp4qSQSZd8ojY62XbvXz0iu0tASmIffU="},"jquery-ui/ui-bg_glass_55_fbf9ee_1x400-691597e8a40a891ea94d3589976ecfc33e6145c49422443b00ac2b5a0022964c.png":{"logical_path":"jquery-ui/ui-bg_glass_55_fbf9ee_1x400.png","mtime":"2016-05-04T17:48:40+02:00","size":120,"digest":"691597e8a40a891ea94d3589976ecfc33e6145c49422443b00ac2b5a0022964c","integrity":"sha256-aRWX6KQKiR6pTTWJl27Pwz5hRcSUIkQ7AKwrWgAilkw="},"jquery-ui/ui-bg_glass_65_ffffff_1x400-f0e6cd91b837d5c5644d026e5ffeccd907953317cd5c0f689901733afda260b2.png":{"logical_path":"jquery-ui/ui-bg_glass_65_ffffff_1x400.png","mtime":"2016-05-04T17:48:40+02:00","size":105,"digest":"f0e6cd91b837d5c5644d026e5ffeccd907953317cd5c0f689901733afda260b2","integrity":"sha256-8ObNkbg31cVkTQJuX/7M2QeVMxfNXA9omQFzOv2iYLI="},"jquery-ui/ui-bg_glass_75_dadada_1x400-c108f5cbf2dd9ec07a26530695ddd95e1664597ce6c056ae44c162cc2e28cec4.png":{"logical_path":"jquery-ui/ui-bg_glass_75_dadada_1x400.png","mtime":"2016-05-04T17:48:40+02:00","size":111,"digest":"c108f5cbf2dd9ec07a26530695ddd95e1664597ce6c056ae44c162cc2e28cec4","integrity":"sha256-wQj1y/LdnsB6JlMGld3ZXhZkWXzmwFauRMFizC4ozsQ="},"jquery-ui/ui-bg_glass_75_e6e6e6_1x400-ddf5dd4e0ef2b185e8bb0af7b6e90ebe74a84384cb4700658e76e754c8bfe550.png":{"logical_path":"jquery-ui/ui-bg_glass_75_e6e6e6_1x400.png","mtime":"2016-05-04T17:48:40+02:00","size":110,"digest":"ddf5dd4e0ef2b185e8bb0af7b6e90ebe74a84384cb4700658e76e754c8bfe550","integrity":"sha256-3fXdTg7ysYXouwr3tukOvnSoQ4TLRwBljnbnVMi/5VA="},"jquery-ui/ui-bg_glass_95_fef1ec_1x400-f6f1c1bedf1a0f37cfef81d12f5f012869d1ee7c984775a569827a1784d34f5c.png":{"logical_path":"jquery-ui/ui-bg_glass_95_fef1ec_1x400.png","mtime":"2016-05-04T17:48:40+02:00","size":119,"digest":"f6f1c1bedf1a0f37cfef81d12f5f012869d1ee7c984775a569827a1784d34f5c","integrity":"sha256-9vHBvt8aDzfP74HRL18BKGnR7nyYR3WlaYJ6F4TTT1w="},"jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100-54270656df079c4da5182629a080fc633b6f84b87985eb016d25a560e2c38d4a.png":{"logical_path":"jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100.png","mtime":"2016-05-04T17:48:40+02:00","size":101,"digest":"54270656df079c4da5182629a080fc633b6f84b87985eb016d25a560e2c38d4a","integrity":"sha256-VCcGVt8HnE2lGCYpoID8YztvhLh5hesBbSWlYOLDjUo="},"jquery-ui/ui-icons_222222_256x240-57adb0d65f4e91dacfee975d9574422bee7486c8a182d60133728c672f2cdbbc.png":{"logical_path":"jquery-ui/ui-icons_222222_256x240.png","mtime":"2016-05-04T17:48:40+02:00","size":4369,"digest":"57adb0d65f4e91dacfee975d9574422bee7486c8a182d60133728c672f2cdbbc","integrity":"sha256-V62w1l9OkdrP7pddlXRCK+50hsihgtYBM3KMZy8s27w="},"jquery-ui/ui-icons_2e83ff_256x240-20f8c6667afc48aa433ee9eb6d8a0584bdbd6b4a4a9091ff1e6b3adb31e63bd9.png":{"logical_path":"jquery-ui/ui-icons_2e83ff_256x240.png","mtime":"2016-05-04T17:48:40+02:00","size":4369,"digest":"20f8c6667afc48aa433ee9eb6d8a0584bdbd6b4a4a9091ff1e6b3adb31e63bd9","integrity":"sha256-IPjGZnr8SKpDPunrbYoFhL29a0pKkJH/Hms62zHmO9k="},"jquery-ui/ui-icons_454545_256x240-07460e843c3e59aaadbb34231e699e856a2980753c7a47b66447da5d9f93fb7f.png":{"logical_path":"jquery-ui/ui-icons_454545_256x240.png","mtime":"2016-05-04T17:48:40+02:00","size":4369,"digest":"07460e843c3e59aaadbb34231e699e856a2980753c7a47b66447da5d9f93fb7f","integrity":"sha256-B0YOhDw+WaqtuzQjHmmehWopgHU8eke2ZEfaXZ+T+38="},"jquery-ui/ui-icons_888888_256x240-ea2e29625de3463465e93b002b065f5833e05b97f7a052b1c141e754d62e1a8b.png":{"logical_path":"jquery-ui/ui-icons_888888_256x240.png","mtime":"2016-05-04T17:48:40+02:00","size":4369,"digest":"ea2e29625de3463465e93b002b065f5833e05b97f7a052b1c141e754d62e1a8b","integrity":"sha256-6i4pYl3jRjRl6TsAKwZfWDPgW5f3oFKxwUHnVNYuGos="},"jquery-ui/ui-icons_cd0a0a_256x240-1e32c6dbf5d3fd342f27a78aa881550d6412aa207f48468724a6a15402b6041b.png":{"logical_path":"jquery-ui/ui-icons_cd0a0a_256x240.png","mtime":"2016-05-04T17:48:40+02:00","size":4369,"digest":"1e32c6dbf5d3fd342f27a78aa881550d6412aa207f48468724a6a15402b6041b","integrity":"sha256-HjLG2/XT/TQvJ6eKqIFVDWQSqiB/SEaHJKahVAK2BBs="},"tinymce-981ca10e0cd26c1cc43bd7da0e8a43ced615d0b581f0a9e787cb269fc5a18099.js":{"logical_path":"tinymce.js","mtime":"2016-05-22T00:36:19+02:00","size":944,"digest":"981ca10e0cd26c1cc43bd7da0e8a43ced615d0b581f0a9e787cb269fc5a18099","integrity":"sha256-mByhDgzSbBzEO9faDopDztYV0LWB8Knnh8smn8WhgJk="},"application-99aba05d4f4b6154b108e3700a9a23d7b51b4c2e2c105bfc6ae63c9096a7673c.css":{"logical_path":"application.css","mtime":"2016-05-22T00:36:19+02:00","size":548162,"digest":"99aba05d4f4b6154b108e3700a9a23d7b51b4c2e2c105bfc6ae63c9096a7673c","integrity":"sha256-maugXU9LYVSxCONwCpoj17UbTC4sEFv8auY8kJanZzw="},"application-63a95002fb2ccebf3d68fea3f0f10416cfd47507986067ce8347c38ce27ce979.js":{"logical_path":"application.js","mtime":"2016-05-22T00:36:19+02:00","size":2159864,"digest":"63a95002fb2ccebf3d68fea3f0f10416cfd47507986067ce8347c38ce27ce979","integrity":"sha256-Y6lQAvsszr89aP6j8PEEFs/UdQeYYGfOg0fDjOJ86Xk="},"application-581c2f0ac27ca40e0308e3833791ce974d41aeaf75764d213928a691390d80ab.js":{"logical_path":"application.js","mtime":"2016-05-22T01:11:38+02:00","size":2160236,"digest":"581c2f0ac27ca40e0308e3833791ce974d41aeaf75764d213928a691390d80ab","integrity":"sha256-WBwvCsJ8pA4DCOODN5HOl01Brq91dk0hOSimkTkNgKs="},"application-ceb501d45d7cebd76cdd8791833794188d63d249eb8d9ca2aeebf0926df320e5.js":{"logical_path":"application.js","mtime":"2016-05-23T01:08:04+02:00","size":2160399,"digest":"ceb501d45d7cebd76cdd8791833794188d63d249eb8d9ca2aeebf0926df320e5","integrity":"sha256-zrUB1F1869ds3YeRgzeUGI1j0knrjZyiruvwkm3zIOU="},"tinymce-554c95b1d24ee6cb338ed339233a70e15cf0074eacec99de99cc2a4136d60b4d.js":{"logical_path":"tinymce.js","mtime":"2016-05-23T01:54:18+02:00","size":948,"digest":"554c95b1d24ee6cb338ed339233a70e15cf0074eacec99de99cc2a4136d60b4d","integrity":"sha256-VUyVsdJO5sszjtM5Izpw4VzwB06s7JnemcwqQTbWC00="},"application-80267254eb940edca206faebfaaef536c10bb76d2332249a101cb05f18e6f833.css":{"logical_path":"application.css","mtime":"2016-05-23T01:54:18+02:00","size":548420,"digest":"80267254eb940edca206faebfaaef536c10bb76d2332249a101cb05f18e6f833","integrity":"sha256-gCZyVOuUDtyiBvrr+q71NsELt20jMiSaEBywXxjm+DM="},"application-e27bec40e6bb2cfe06df32012d5880f505ed57526d9d2714aea50f102d776763.js":{"logical_path":"application.js","mtime":"2016-05-23T01:54:18+02:00","size":2160403,"digest":"e27bec40e6bb2cfe06df32012d5880f505ed57526d9d2714aea50f102d776763","integrity":"sha256-4nvsQOa7LP4G3zIBLViA9QXtV1JtnScUrqUPEC13Z2M="},"active_admin-bf38e2138315a470aef9b840765c137a33b1520312a5ef0a981c39addb52fbfb.css":{"logical_path":"active_admin.css","mtime":"2016-05-21T23:41:15+02:00","size":78112,"digest":"bf38e2138315a470aef9b840765c137a33b1520312a5ef0a981c39addb52fbfb","integrity":"sha256-vzjiE4MVpHCu+bhAdlwTejOxUgMSpe8KmBw5rdtS+/s="},"active_admin/print-87c5ffc1d869a919123bcc1dc5ec51b20bc79fd9aeab9eed77e3438c6acd4f68.css":{"logical_path":"active_admin/print.css","mtime":"2016-06-30T21:12:27+02:00","size":5494,"digest":"87c5ffc1d869a919123bcc1dc5ec51b20bc79fd9aeab9eed77e3438c6acd4f68","integrity":"sha256-h8X/wdhpqRkSO8wdxexRsgvHn9muq57td+NDjGrNT2g="},"tinymce-14411a8837640541cea84f572fa1c80fb639542b1155d7bb7b8d4820c6922b66.js":{"logical_path":"tinymce.js","mtime":"2016-06-25T16:51:02+02:00","size":944,"digest":"14411a8837640541cea84f572fa1c80fb639542b1155d7bb7b8d4820c6922b66","integrity":"sha256-FEEaiDdkBUHOqE9XL6HID7Y5VCsRVde7e41IIMaSK2Y="},"application-77ec43cc8949cbfe2e51114c6ca77a85624e6e817085cda6b03e46d9ebebdf25.css":{"logical_path":"application.css","mtime":"2016-07-02T17:04:13+02:00","size":147481,"digest":"77ec43cc8949cbfe2e51114c6ca77a85624e6e817085cda6b03e46d9ebebdf25","integrity":"sha256-d+xDzIlJy/4uURFMbKd6hWJOboFwhc2msD5G2evr3yU="},"application-2ff7281f89f0b69873f09aa96b2121b67d5c245d6be100b00998783e84d58f2d.js":{"logical_path":"application.js","mtime":"2016-06-25T16:51:02+02:00","size":2171260,"digest":"2ff7281f89f0b69873f09aa96b2121b67d5c245d6be100b00998783e84d58f2d","integrity":"sha256-L/coH4nwtphz8JqpayEhtn1cJF1r4QCwCZh4PoTVjy0="},"active_admin-5f668089bbe1957cd779eb439f2df899e5d66673d34ac94110e73ef0ac0e7313.css":{"logical_path":"active_admin.css","mtime":"2016-06-30T21:12:27+02:00","size":78116,"digest":"5f668089bbe1957cd779eb439f2df899e5d66673d34ac94110e73ef0ac0e7313","integrity":"sha256-X2aAibvhlXzXeetDny34meXWZnPTSslBEOc+8KwOcxM="},"active_admin-c99e2b41c14fcaa52c6ca770ae578392abc42e237158ed560ad73d118e502350.js":{"logical_path":"active_admin.js","mtime":"2016-07-02T17:04:13+02:00","size":780523,"digest":"c99e2b41c14fcaa52c6ca770ae578392abc42e237158ed560ad73d118e502350","integrity":"sha256-yZ4rQcFPyqUsbKdwrleDkqvELiNxWO1WCtc9EY5QI1A="},"tinymce-962059b7c757a94ab7ec4ee03bad9a9c4b565a3939172b7c307c72aa4b5ffefb.js":{"logical_path":"tinymce.js","mtime":"2016-07-02T17:04:13+02:00","size":971,"digest":"962059b7c757a94ab7ec4ee03bad9a9c4b565a3939172b7c307c72aa4b5ffefb","integrity":"sha256-liBZt8dXqUq37E7gO62anEtWWjk5Fyt8MHxyqktf/vs="},"baby_gnu_adl-232caf355c30740d5d9b30491887cd546b8849b33ca9bdb6cc71f8a47ea61815.png":{"logical_path":"baby_gnu_adl.png","mtime":"2016-07-02T16:52:58+02:00","size":10155,"digest":"232caf355c30740d5d9b30491887cd546b8849b33ca9bdb6cc71f8a47ea61815","integrity":"sha256-IyyvNVwwdA1dmzBJGIfNVGuISbM8qb22zHH4pH6mGBU="},"baby_gnu_adl-97251005d3225cf1d58b8c497d6b7905dbc9560cc8acd50118fcce60d0a2679e.svg":{"logical_path":"baby_gnu_adl.svg","mtime":"2016-07-02T16:52:57+02:00","size":109635,"digest":"97251005d3225cf1d58b8c497d6b7905dbc9560cc8acd50118fcce60d0a2679e","integrity":"sha256-lyUQBdMiXPHVi4xJfWt5BdvJVgzIrNUBGPzOYNCiZ54="},"application-307219623ded8fdc9ee285ad85d84051e026d5bfc9ff99ad749c917ab9dfcc76.js":{"logical_path":"application.js","mtime":"2016-07-02T17:04:13+02:00","size":2179851,"digest":"307219623ded8fdc9ee285ad85d84051e026d5bfc9ff99ad749c917ab9dfcc76","integrity":"sha256-MHIZYj3tj9ye4oWthdhAUeAm1b/J/5mtdJyRernfzHY="},"tinymce/jquery.tinymce.js":{"logical_path":"tinymce/jquery.tinymce.js","mtime":"2016-06-16T20:47:48+02:00","size":3591,"digest":null},"tinymce/langs/readme.md":{"logical_path":"tinymce/langs/readme.md","mtime":"2016-06-16T20:47:48+02:00","size":151,"digest":null},"tinymce/license.txt":{"logical_path":"tinymce/license.txt","mtime":"2016-06-16T20:47:48+02:00","size":26427,"digest":null},"tinymce/plugins/advlist/plugin.js":{"logical_path":"tinymce/plugins/advlist/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1303,"digest":null},"tinymce/plugins/anchor/plugin.js":{"logical_path":"tinymce/plugins/anchor/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":616,"digest":null},"tinymce/plugins/autolink/plugin.js":{"logical_path":"tinymce/plugins/autolink/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1961,"digest":null},"tinymce/plugins/autoresize/plugin.js":{"logical_path":"tinymce/plugins/autoresize/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1903,"digest":null},"tinymce/plugins/autosave/plugin.js":{"logical_path":"tinymce/plugins/autosave/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":2185,"digest":null},"tinymce/plugins/bbcode/plugin.js":{"logical_path":"tinymce/plugins/bbcode/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":3136,"digest":null},"tinymce/plugins/charmap/plugin.js":{"logical_path":"tinymce/plugins/charmap/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":8194,"digest":null},"tinymce/plugins/code/plugin.js":{"logical_path":"tinymce/plugins/code/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":721,"digest":null},"tinymce/plugins/codesample/css/prism.css":{"logical_path":"tinymce/plugins/codesample/css/prism.css","mtime":"2016-06-16T20:47:48+02:00","size":2289,"digest":null},"tinymce/plugins/codesample/plugin.js":{"logical_path":"tinymce/plugins/codesample/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":20002,"digest":null},"tinymce/plugins/colorpicker/plugin.js":{"logical_path":"tinymce/plugins/colorpicker/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1222,"digest":null},"tinymce/plugins/contextmenu/plugin.js":{"logical_path":"tinymce/plugins/contextmenu/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":891,"digest":null},"tinymce/plugins/directionality/plugin.js":{"logical_path":"tinymce/plugins/directionality/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":726,"digest":null},"tinymce/plugins/emoticons/img/smiley-cool.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-cool.gif","mtime":"2016-06-16T20:47:48+02:00","size":354,"digest":null},"tinymce/plugins/emoticons/img/smiley-cry.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-cry.gif","mtime":"2016-06-16T20:47:48+02:00","size":329,"digest":null},"tinymce/plugins/emoticons/img/smiley-embarassed.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-embarassed.gif","mtime":"2016-06-16T20:47:48+02:00","size":331,"digest":null},"tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif","mtime":"2016-06-16T20:47:48+02:00","size":342,"digest":null},"tinymce/plugins/emoticons/img/smiley-frown.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-frown.gif","mtime":"2016-06-16T20:47:48+02:00","size":340,"digest":null},"tinymce/plugins/emoticons/img/smiley-innocent.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-innocent.gif","mtime":"2016-06-16T20:47:48+02:00","size":336,"digest":null},"tinymce/plugins/emoticons/img/smiley-kiss.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-kiss.gif","mtime":"2016-06-16T20:47:48+02:00","size":338,"digest":null},"tinymce/plugins/emoticons/img/smiley-laughing.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-laughing.gif","mtime":"2016-06-16T20:47:48+02:00","size":343,"digest":null},"tinymce/plugins/emoticons/img/smiley-money-mouth.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-money-mouth.gif","mtime":"2016-06-16T20:47:48+02:00","size":321,"digest":null},"tinymce/plugins/emoticons/img/smiley-sealed.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-sealed.gif","mtime":"2016-06-16T20:47:48+02:00","size":323,"digest":null},"tinymce/plugins/emoticons/img/smiley-smile.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-smile.gif","mtime":"2016-06-16T20:47:48+02:00","size":344,"digest":null},"tinymce/plugins/emoticons/img/smiley-surprised.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-surprised.gif","mtime":"2016-06-16T20:47:48+02:00","size":338,"digest":null},"tinymce/plugins/emoticons/img/smiley-tongue-out.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-tongue-out.gif","mtime":"2016-06-16T20:47:48+02:00","size":328,"digest":null},"tinymce/plugins/emoticons/img/smiley-undecided.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-undecided.gif","mtime":"2016-06-16T20:47:48+02:00","size":337,"digest":null},"tinymce/plugins/emoticons/img/smiley-wink.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-wink.gif","mtime":"2016-06-16T20:47:48+02:00","size":350,"digest":null},"tinymce/plugins/emoticons/img/smiley-yell.gif":{"logical_path":"tinymce/plugins/emoticons/img/smiley-yell.gif","mtime":"2016-06-16T20:47:48+02:00","size":336,"digest":null},"tinymce/plugins/emoticons/plugin.js":{"logical_path":"tinymce/plugins/emoticons/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":911,"digest":null},"tinymce/plugins/example/dialog.html":{"logical_path":"tinymce/plugins/example/dialog.html","mtime":"2016-06-16T20:47:48+02:00","size":213,"digest":null},"tinymce/plugins/example/plugin.js":{"logical_path":"tinymce/plugins/example/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":658,"digest":null},"tinymce/plugins/example_dependency/plugin.js":{"logical_path":"tinymce/plugins/example_dependency/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":73,"digest":null},"tinymce/plugins/fullpage/plugin.js":{"logical_path":"tinymce/plugins/fullpage/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":6291,"digest":null},"tinymce/plugins/fullscreen/plugin.js":{"logical_path":"tinymce/plugins/fullscreen/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1676,"digest":null},"tinymce/plugins/hr/plugin.js":{"logical_path":"tinymce/plugins/hr/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":322,"digest":null},"tinymce/plugins/image/plugin.js":{"logical_path":"tinymce/plugins/image/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":8169,"digest":null},"tinymce/plugins/imagetools/plugin.js":{"logical_path":"tinymce/plugins/imagetools/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":29669,"digest":null},"tinymce/plugins/importcss/plugin.js":{"logical_path":"tinymce/plugins/importcss/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":2223,"digest":null},"tinymce/plugins/insertdatetime/plugin.js":{"logical_path":"tinymce/plugins/insertdatetime/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1978,"digest":null},"tinymce/plugins/layer/plugin.js":{"logical_path":"tinymce/plugins/layer/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":2857,"digest":null},"tinymce/plugins/legacyoutput/plugin.js":{"logical_path":"tinymce/plugins/legacyoutput/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":3263,"digest":null},"tinymce/plugins/link/plugin.js":{"logical_path":"tinymce/plugins/link/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":4517,"digest":null},"tinymce/plugins/lists/plugin.js":{"logical_path":"tinymce/plugins/lists/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":8578,"digest":null},"tinymce/plugins/media/moxieplayer.swf":{"logical_path":"tinymce/plugins/media/moxieplayer.swf","mtime":"2016-06-16T20:47:48+02:00","size":20017,"digest":null},"tinymce/plugins/media/plugin.js":{"logical_path":"tinymce/plugins/media/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":11696,"digest":null},"tinymce/plugins/nonbreaking/plugin.js":{"logical_path":"tinymce/plugins/nonbreaking/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":655,"digest":null},"tinymce/plugins/noneditable/plugin.js":{"logical_path":"tinymce/plugins/noneditable/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1126,"digest":null},"tinymce/plugins/pagebreak/plugin.js":{"logical_path":"tinymce/plugins/pagebreak/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1230,"digest":null},"tinymce/plugins/paste/plugin.js":{"logical_path":"tinymce/plugins/paste/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":16286,"digest":null},"tinymce/plugins/preview/plugin.js":{"logical_path":"tinymce/plugins/preview/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1602,"digest":null},"tinymce/plugins/print/plugin.js":{"logical_path":"tinymce/plugins/print/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":293,"digest":null},"tinymce/plugins/save/plugin.js":{"logical_path":"tinymce/plugins/save/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1156,"digest":null},"tinymce/plugins/searchreplace/plugin.js":{"logical_path":"tinymce/plugins/searchreplace/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":6493,"digest":null},"tinymce/plugins/spellchecker/plugin.js":{"logical_path":"tinymce/plugins/spellchecker/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":9781,"digest":null},"tinymce/plugins/tabfocus/plugin.js":{"logical_path":"tinymce/plugins/tabfocus/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1270,"digest":null},"tinymce/plugins/table/plugin.js":{"logical_path":"tinymce/plugins/table/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":42808,"digest":null},"tinymce/plugins/template/plugin.js":{"logical_path":"tinymce/plugins/template/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":4445,"digest":null},"tinymce/plugins/textcolor/plugin.js":{"logical_path":"tinymce/plugins/textcolor/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":4145,"digest":null},"tinymce/plugins/textpattern/plugin.js":{"logical_path":"tinymce/plugins/textpattern/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":2751,"digest":null},"tinymce/plugins/visualblocks/css/visualblocks.css":{"logical_path":"tinymce/plugins/visualblocks/css/visualblocks.css","mtime":"2016-06-16T20:47:48+02:00","size":5092,"digest":null},"tinymce/plugins/visualblocks/plugin.js":{"logical_path":"tinymce/plugins/visualblocks/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1153,"digest":null},"tinymce/plugins/visualchars/plugin.js":{"logical_path":"tinymce/plugins/visualchars/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":1259,"digest":null},"tinymce/plugins/wordcount/plugin.js":{"logical_path":"tinymce/plugins/wordcount/plugin.js","mtime":"2016-06-16T20:47:48+02:00","size":928,"digest":null},"tinymce/skins/lightgray/content.inline.min.css":{"logical_path":"tinymce/skins/lightgray/content.inline.min.css","mtime":"2016-06-16T20:47:48+02:00","size":2676,"digest":null},"tinymce/skins/lightgray/content.min.css":{"logical_path":"tinymce/skins/lightgray/content.min.css","mtime":"2016-06-16T20:47:48+02:00","size":3091,"digest":null},"tinymce/skins/lightgray/fonts/tinymce-small.eot":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce-small.eot","mtime":"2016-06-16T20:47:48+02:00","size":9492,"digest":null},"tinymce/skins/lightgray/fonts/tinymce-small.svg":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce-small.svg","mtime":"2016-06-16T20:47:48+02:00","size":24727,"digest":null},"tinymce/skins/lightgray/fonts/tinymce-small.ttf":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce-small.ttf","mtime":"2016-06-16T20:47:48+02:00","size":9304,"digest":null},"tinymce/skins/lightgray/fonts/tinymce-small.woff":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce-small.woff","mtime":"2016-06-16T20:47:48+02:00","size":9380,"digest":null},"tinymce/skins/lightgray/fonts/tinymce.eot":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce.eot","mtime":"2016-06-16T20:47:48+02:00","size":17292,"digest":null},"tinymce/skins/lightgray/fonts/tinymce.svg":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce.svg","mtime":"2016-06-16T20:47:48+02:00","size":45226,"digest":null},"tinymce/skins/lightgray/fonts/tinymce.ttf":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce.ttf","mtime":"2016-06-16T20:47:48+02:00","size":17128,"digest":null},"tinymce/skins/lightgray/fonts/tinymce.woff":{"logical_path":"tinymce/skins/lightgray/fonts/tinymce.woff","mtime":"2016-06-16T20:47:48+02:00","size":17204,"digest":null},"tinymce/skins/lightgray/img/anchor.gif":{"logical_path":"tinymce/skins/lightgray/img/anchor.gif","mtime":"2016-06-16T20:47:48+02:00","size":53,"digest":null},"tinymce/skins/lightgray/img/loader.gif":{"logical_path":"tinymce/skins/lightgray/img/loader.gif","mtime":"2016-06-16T20:47:48+02:00","size":2608,"digest":null},"tinymce/skins/lightgray/img/object.gif":{"logical_path":"tinymce/skins/lightgray/img/object.gif","mtime":"2016-06-16T20:47:48+02:00","size":152,"digest":null},"tinymce/skins/lightgray/img/trans.gif":{"logical_path":"tinymce/skins/lightgray/img/trans.gif","mtime":"2016-06-16T20:47:48+02:00","size":43,"digest":null},"tinymce/skins/lightgray/skin.ie7.min.css":{"logical_path":"tinymce/skins/lightgray/skin.ie7.min.css","mtime":"2016-06-16T20:47:48+02:00","size":32423,"digest":null},"tinymce/skins/lightgray/skin.min.css":{"logical_path":"tinymce/skins/lightgray/skin.min.css","mtime":"2016-06-16T20:47:48+02:00","size":34503,"digest":null},"tinymce/themes/modern/theme.js":{"logical_path":"tinymce/themes/modern/theme.js","mtime":"2016-06-16T20:47:48+02:00","size":9923,"digest":null},"tinymce/tinymce.js":{"logical_path":"tinymce/tinymce.js","mtime":"2016-06-16T20:47:48+02:00","size":380255,"digest":null},"tinymce/langs/ar.js":{"logical_path":"tinymce/langs/ar.js","mtime":"2016-05-04T17:48:54+02:00","size":17775,"digest":null},"tinymce/langs/ar_SA.js":{"logical_path":"tinymce/langs/ar_SA.js","mtime":"2016-05-04T17:48:54+02:00","size":10002,"digest":null},"tinymce/langs/az.js":{"logical_path":"tinymce/langs/az.js","mtime":"2016-05-04T17:48:54+02:00","size":9679,"digest":null},"tinymce/langs/be.js":{"logical_path":"tinymce/langs/be.js","mtime":"2016-05-04T17:48:54+02:00","size":21063,"digest":null},"tinymce/langs/bg_BG.js":{"logical_path":"tinymce/langs/bg_BG.js","mtime":"2016-05-04T17:48:54+02:00","size":23944,"digest":null},"tinymce/langs/bn_BD.js":{"logical_path":"tinymce/langs/bn_BD.js","mtime":"2016-05-04T17:48:54+02:00","size":6845,"digest":null},"tinymce/langs/bs.js":{"logical_path":"tinymce/langs/bs.js","mtime":"2016-05-04T17:48:54+02:00","size":6969,"digest":null},"tinymce/langs/ca.js":{"logical_path":"tinymce/langs/ca.js","mtime":"2016-05-04T17:48:54+02:00","size":7786,"digest":null},"tinymce/langs/cs.js":{"logical_path":"tinymce/langs/cs.js","mtime":"2016-05-04T17:48:54+02:00","size":8750,"digest":null},"tinymce/langs/cs_CZ.js":{"logical_path":"tinymce/langs/cs_CZ.js","mtime":"2016-05-04T17:48:54+02:00","size":8398,"digest":null},"tinymce/langs/cy.js":{"logical_path":"tinymce/langs/cy.js","mtime":"2016-05-04T17:48:54+02:00","size":6141,"digest":null},"tinymce/langs/da.js":{"logical_path":"tinymce/langs/da.js","mtime":"2016-05-04T17:48:54+02:00","size":7512,"digest":null},"tinymce/langs/de.js":{"logical_path":"tinymce/langs/de.js","mtime":"2016-05-04T17:48:54+02:00","size":8279,"digest":null},"tinymce/langs/de_AT.js":{"logical_path":"tinymce/langs/de_AT.js","mtime":"2016-05-04T17:48:54+02:00","size":8307,"digest":null},"tinymce/langs/dv.js":{"logical_path":"tinymce/langs/dv.js","mtime":"2016-05-04T17:48:54+02:00","size":18099,"digest":null},"tinymce/langs/el.js":{"logical_path":"tinymce/langs/el.js","mtime":"2016-05-04T17:48:54+02:00","size":22972,"digest":null},"tinymce/langs/en_CA.js":{"logical_path":"tinymce/langs/en_CA.js","mtime":"2016-05-04T17:48:54+02:00","size":6915,"digest":null},"tinymce/langs/en_GB.js":{"logical_path":"tinymce/langs/en_GB.js","mtime":"2016-05-04T17:48:54+02:00","size":5906,"digest":null},"tinymce/langs/eo.js":{"logical_path":"tinymce/langs/eo.js","mtime":"2016-05-04T17:48:54+02:00","size":7465,"digest":null},"tinymce/langs/es.js":{"logical_path":"tinymce/langs/es.js","mtime":"2016-05-04T17:48:54+02:00","size":7808,"digest":null},"tinymce/langs/es_MX.js":{"logical_path":"tinymce/langs/es_MX.js","mtime":"2016-05-04T17:48:54+02:00","size":7893,"digest":null},"tinymce/langs/et.js":{"logical_path":"tinymce/langs/et.js","mtime":"2016-05-04T17:48:54+02:00","size":7783,"digest":null},"tinymce/langs/eu.js":{"logical_path":"tinymce/langs/eu.js","mtime":"2016-05-04T17:48:54+02:00","size":7010,"digest":null},"tinymce/langs/fa.js":{"logical_path":"tinymce/langs/fa.js","mtime":"2016-05-04T17:48:54+02:00","size":16461,"digest":null},"tinymce/langs/fa_IR.js":{"logical_path":"tinymce/langs/fa_IR.js","mtime":"2016-05-04T17:48:54+02:00","size":17724,"digest":null},"tinymce/langs/fi.js":{"logical_path":"tinymce/langs/fi.js","mtime":"2016-05-04T17:48:54+02:00","size":8142,"digest":null},"tinymce/langs/fo.js":{"logical_path":"tinymce/langs/fo.js","mtime":"2016-05-04T17:48:54+02:00","size":8043,"digest":null},"tinymce/langs/fr_CH.js":{"logical_path":"tinymce/langs/fr_CH.js","mtime":"2016-05-04T17:48:54+02:00","size":8073,"digest":null},"tinymce/langs/fr_FR.js":{"logical_path":"tinymce/langs/fr_FR.js","mtime":"2016-05-04T17:48:54+02:00","size":8008,"digest":null},"tinymce/langs/ga.js":{"logical_path":"tinymce/langs/ga.js","mtime":"2016-05-04T17:48:54+02:00","size":8590,"digest":null},"tinymce/langs/gd.js":{"logical_path":"tinymce/langs/gd.js","mtime":"2016-05-04T17:48:54+02:00","size":8807,"digest":null},"tinymce/langs/gl.js":{"logical_path":"tinymce/langs/gl.js","mtime":"2016-05-04T17:48:54+02:00","size":7065,"digest":null},"tinymce/langs/he_IL.js":{"logical_path":"tinymce/langs/he_IL.js","mtime":"2016-05-04T17:48:54+02:00","size":16080,"digest":null},"tinymce/langs/hi_IN.js":{"logical_path":"tinymce/langs/hi_IN.js","mtime":"2016-05-04T17:48:54+02:00","size":18457,"digest":null},"tinymce/langs/hr.js":{"logical_path":"tinymce/langs/hr.js","mtime":"2016-05-04T17:48:54+02:00","size":7576,"digest":null},"tinymce/langs/hu_HU.js":{"logical_path":"tinymce/langs/hu_HU.js","mtime":"2016-05-04T17:48:54+02:00","size":9409,"digest":null},"tinymce/langs/hy.js":{"logical_path":"tinymce/langs/hy.js","mtime":"2016-05-04T17:48:54+02:00","size":20374,"digest":null},"tinymce/langs/id.js":{"logical_path":"tinymce/langs/id.js","mtime":"2016-05-04T17:48:54+02:00","size":7140,"digest":null},"tinymce/langs/is_IS.js":{"logical_path":"tinymce/langs/is_IS.js","mtime":"2016-05-04T17:48:54+02:00","size":7927,"digest":null},"tinymce/langs/it.js":{"logical_path":"tinymce/langs/it.js","mtime":"2016-05-04T17:48:54+02:00","size":7597,"digest":null},"tinymce/langs/ja.js":{"logical_path":"tinymce/langs/ja.js","mtime":"2016-05-04T17:48:54+02:00","size":12289,"digest":null},"tinymce/langs/ka_GE.js":{"logical_path":"tinymce/langs/ka_GE.js","mtime":"2016-05-04T17:48:54+02:00","size":21283,"digest":null},"tinymce/langs/kab.js":{"logical_path":"tinymce/langs/kab.js","mtime":"2016-05-04T17:48:54+02:00","size":7390,"digest":null},"tinymce/langs/kk.js":{"logical_path":"tinymce/langs/kk.js","mtime":"2016-05-04T17:48:54+02:00","size":16680,"digest":null},"tinymce/langs/km_KH.js":{"logical_path":"tinymce/langs/km_KH.js","mtime":"2016-05-04T17:48:54+02:00","size":21395,"digest":null},"tinymce/langs/ko.js":{"logical_path":"tinymce/langs/ko.js","mtime":"2016-05-04T17:48:54+02:00","size":10104,"digest":null},"tinymce/langs/ko_KR.js":{"logical_path":"tinymce/langs/ko_KR.js","mtime":"2016-05-04T17:48:54+02:00","size":10004,"digest":null},"tinymce/langs/ku.js":{"logical_path":"tinymce/langs/ku.js","mtime":"2016-05-04T17:48:54+02:00","size":18273,"digest":null},"tinymce/langs/ku_IQ.js":{"logical_path":"tinymce/langs/ku_IQ.js","mtime":"2016-05-04T17:48:54+02:00","size":18363,"digest":null},"tinymce/langs/lb.js":{"logical_path":"tinymce/langs/lb.js","mtime":"2016-05-04T17:48:54+02:00","size":7466,"digest":null},"tinymce/langs/lt.js":{"logical_path":"tinymce/langs/lt.js","mtime":"2016-05-04T17:48:54+02:00","size":8898,"digest":null},"tinymce/langs/lv.js":{"logical_path":"tinymce/langs/lv.js","mtime":"2016-05-04T17:48:54+02:00","size":8281,"digest":null},"tinymce/langs/mk_MK.js":{"logical_path":"tinymce/langs/mk_MK.js","mtime":"2016-05-04T17:48:54+02:00","size":18732,"digest":null},"tinymce/langs/ml.js":{"logical_path":"tinymce/langs/ml.js","mtime":"2016-05-04T17:48:54+02:00","size":7338,"digest":null},"tinymce/langs/ml_IN.js":{"logical_path":"tinymce/langs/ml_IN.js","mtime":"2016-05-04T17:48:54+02:00","size":20018,"digest":null},"tinymce/langs/mn_MN.js":{"logical_path":"tinymce/langs/mn_MN.js","mtime":"2016-05-04T17:48:54+02:00","size":6876,"digest":null},"tinymce/langs/nb_NO.js":{"logical_path":"tinymce/langs/nb_NO.js","mtime":"2016-05-04T17:48:54+02:00","size":7527,"digest":null},"tinymce/langs/nl.js":{"logical_path":"tinymce/langs/nl.js","mtime":"2016-05-04T17:48:54+02:00","size":7234,"digest":null},"tinymce/langs/pl.js":{"logical_path":"tinymce/langs/pl.js","mtime":"2016-05-04T17:48:54+02:00","size":8128,"digest":null},"tinymce/langs/pt_BR.js":{"logical_path":"tinymce/langs/pt_BR.js","mtime":"2016-05-04T17:48:54+02:00","size":8001,"digest":null},"tinymce/langs/pt_PT.js":{"logical_path":"tinymce/langs/pt_PT.js","mtime":"2016-05-04T17:48:54+02:00","size":8144,"digest":null},"tinymce/langs/ro.js":{"logical_path":"tinymce/langs/ro.js","mtime":"2016-05-04T17:48:54+02:00","size":8274,"digest":null},"tinymce/langs/ru.js":{"logical_path":"tinymce/langs/ru.js","mtime":"2016-05-04T17:48:54+02:00","size":22289,"digest":null},"tinymce/langs/ru_RU.js":{"logical_path":"tinymce/langs/ru_RU.js","mtime":"2016-05-04T17:48:54+02:00","size":4954,"digest":null},"tinymce/langs/si_LK.js":{"logical_path":"tinymce/langs/si_LK.js","mtime":"2016-05-04T17:48:54+02:00","size":15855,"digest":null},"tinymce/langs/sk.js":{"logical_path":"tinymce/langs/sk.js","mtime":"2016-05-04T17:48:54+02:00","size":8957,"digest":null},"tinymce/langs/sl_SI.js":{"logical_path":"tinymce/langs/sl_SI.js","mtime":"2016-05-04T17:48:54+02:00","size":7038,"digest":null},"tinymce/langs/sr.js":{"logical_path":"tinymce/langs/sr.js","mtime":"2016-05-04T17:48:54+02:00","size":6335,"digest":null},"tinymce/langs/sv_SE.js":{"logical_path":"tinymce/langs/sv_SE.js","mtime":"2016-05-04T17:48:54+02:00","size":7495,"digest":null},"tinymce/langs/ta.js":{"logical_path":"tinymce/langs/ta.js","mtime":"2016-05-04T17:48:54+02:00","size":22616,"digest":null},"tinymce/langs/ta_IN.js":{"logical_path":"tinymce/langs/ta_IN.js","mtime":"2016-05-04T17:48:54+02:00","size":22619,"digest":null},"tinymce/langs/tg.js":{"logical_path":"tinymce/langs/tg.js","mtime":"2016-05-04T17:48:54+02:00","size":18182,"digest":null},"tinymce/langs/th_TH.js":{"logical_path":"tinymce/langs/th_TH.js","mtime":"2016-05-04T17:48:54+02:00","size":17296,"digest":null},"tinymce/langs/tr.js":{"logical_path":"tinymce/langs/tr.js","mtime":"2016-05-04T17:48:54+02:00","size":8704,"digest":null},"tinymce/langs/tr_TR.js":{"logical_path":"tinymce/langs/tr_TR.js","mtime":"2016-05-04T17:48:54+02:00","size":8140,"digest":null},"tinymce/langs/tt.js":{"logical_path":"tinymce/langs/tt.js","mtime":"2016-05-04T17:48:54+02:00","size":19034,"digest":null},"tinymce/langs/ug.js":{"logical_path":"tinymce/langs/ug.js","mtime":"2016-05-04T17:48:54+02:00","size":16887,"digest":null},"tinymce/langs/uk.js":{"logical_path":"tinymce/langs/uk.js","mtime":"2016-05-04T17:48:54+02:00","size":22263,"digest":null},"tinymce/langs/uk_UA.js":{"logical_path":"tinymce/langs/uk_UA.js","mtime":"2016-05-04T17:48:54+02:00","size":21690,"digest":null},"tinymce/langs/vi.js":{"logical_path":"tinymce/langs/vi.js","mtime":"2016-05-04T17:48:54+02:00","size":9900,"digest":null},"tinymce/langs/vi_VN.js":{"logical_path":"tinymce/langs/vi_VN.js","mtime":"2016-05-04T17:48:54+02:00","size":9898,"digest":null},"tinymce/langs/zh_CN.js":{"logical_path":"tinymce/langs/zh_CN.js","mtime":"2016-05-04T17:48:54+02:00","size":8482,"digest":null},"tinymce/langs/zh_TW.js":{"logical_path":"tinymce/langs/zh_TW.js","mtime":"2016-05-04T17:48:54+02:00","size":9378,"digest":null}},"assets":{"active_admin.css":"active_admin-5f668089bbe1957cd779eb439f2df899e5d66673d34ac94110e73ef0ac0e7313.css","active_admin/nested_menu_arrow.gif":"active_admin/nested_menu_arrow-15084d93c65c1964d7077700ea748bd2d70cfa2d4c19707c58a9c64e232dd442.gif","active_admin/nested_menu_arrow_dark.gif":"active_admin/nested_menu_arrow_dark-7c43b8e0a5f8823875f49a093c9d7a6b374f885b6f9cc248ae9cd7e6e9b29034.gif","active_admin/datepicker/datepicker-input-icon.png":"active_admin/datepicker/datepicker-input-icon-d9c2bb73769af777c8a71720d29741f3a499aebd5a043e9a119bd0d9597aed47.png","active_admin/orderable.png":"active_admin/orderable-29374dbb55b0012d78a37c614d573bb3474f0779849b478a147d0f1845ca6617.png","active_admin_pagedown/wmd-buttons.png":"active_admin_pagedown/wmd-buttons-c2040b12f2d6cb568ddc33587a070a29a18fed20099260c3ecbbfdbd62042f7b.png","active_admin/print.css":"active_admin/print-87c5ffc1d869a919123bcc1dc5ec51b20bc79fd9aeab9eed77e3438c6acd4f68.css","active_admin.js":"active_admin-c99e2b41c14fcaa52c6ca770ae578392abc42e237158ed560ad73d118e502350.js","layers-2x.png":"layers-2x-0c02a2388f637d21f86e6d4b314ec9a968e7b05ad4c3a005280a3f76c0fd3cb8.png","layers.png":"layers-0908aa2a72a082fb2563a2427a5e4fb247571862b448b80fb6f720af1109923e.png","marker-icon-2x.png":"marker-icon-2x-454dc479e82b487529b6b93d6a9b29ac69ca7b4f5a9d5fdf8e01871f6d216113.png","marker-icon.png":"marker-icon-915e83a6fc798c599e5c9e3f759d6bc065d65151019acd0410d1f4731bcaaf72.png","marker-shadow.png":"marker-shadow-4f340d2d61746333dffe056e074ce1704ae4e47fec5a7de98322fbdbcfcb2b6d.png","tinymce.js":"tinymce-962059b7c757a94ab7ec4ee03bad9a9c4b565a3939172b7c307c72aa4b5ffefb.js","application.css":"application-77ec43cc8949cbfe2e51114c6ca77a85624e6e817085cda6b03e46d9ebebdf25.css","select2.png":"select2-d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8.png","select2-spinner.gif":"select2-spinner-f6ecff617ec2ba7f559e6f535cad9b70a3f91120737535dab4d4548a6c83576c.gif","select2x2.png":"select2x2-6fe28d687dc0ed4d96016238c608ba1e7198c9c9accfa0b360b78018b9fb9bc2.png","font-awesome/fontawesome-webfont.eot":"font-awesome/fontawesome-webfont-a280856e20cc0af53390b729ca0ac3edbf8fc889a828a379c5d634c91e80c808.eot","font-awesome/fontawesome-webfont.woff2":"font-awesome/fontawesome-webfont-2932abf996373e87fbf2e950876b1962f1b57db954a1643ea68831d9fbb74da4.woff2","font-awesome/fontawesome-webfont.woff":"font-awesome/fontawesome-webfont-35fa8302dd7d3d191ebb7acac543efcfa2b85a0da573b3ab45cc122ffcc45ce5.woff","font-awesome/fontawesome-webfont.ttf":"font-awesome/fontawesome-webfont-8630313bee77f64206067ed80eb6a7c721b0bbfc91c94210966969d4dcc43ba7.ttf","font-awesome/fontawesome-webfont.svg":"font-awesome/fontawesome-webfont-6b0adce775f4d57ac800f23b05af72ced748ae51ba67a65b67b7316f1ed331b3.svg","france.png":"france-f4341a7ec8331161a9c8d5298f808014c3fc9c799b5a29ed95eb56a7f3ccd0df.png","quebec.png":"quebec-776d563b6a4ac4312cae9f0bfe630c20711346e8dbddd41040998eba79f4b588.png","belgique.png":"belgique-3b8b772a522de2cbae7714b35a956faf2c394419b532a14bba982fed3f341091.png","suisse.png":"suisse-58d067f1c3fcdc4000fa13e95896cd5369a2b91aafd314475aa5e29da0b543d1.png","modernizr.js":"modernizr-654222debe8018b12f1993ceddff30dc163a7d5008d79869c399d6d167321f97.js","agendadescommuns.png":"agendadescommuns-cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6.png","alert.png":"alert-762ace9479328243a44061346b64c4d6b997e963c68dfc6bddd9e4d241192906.png","baby_gnu_adl.png":"baby_gnu_adl-232caf355c30740d5d9b30491887cd546b8849b33ca9bdb6cc71f8a47ea61815.png","communs.png":"communs-cd40e342024be0587f8e7a0e3902d32cf67009d349b67c00f687e0499fde9ff6.png","lef-small.png":"lef-small-160cf5b883add60c9c0f4361bd8425c75f6fb23b0e551a0b941fa0491c70e0c9.png","lef.png":"lef-bec4081a11fbef165216827cf72c7a292ad772a77af6b8132e5bc0bbf83cb2d9.png","priorite-logiciel-libre-je-soutiens-april_2_m.png":"priorite-logiciel-libre-je-soutiens-april_2_m-6442e454e96ed45cc1ebc40673a6c50bd286b9c28ea6a8b58572e94f7d6459fc.png","team.png":"team-cb04c7a311f7160c4eb6a281eae68be84f26991dde5d415bb4e205e6726ae275.png","application.js":"application-307219623ded8fdc9ee285ad85d84051e026d5bfc9ff99ad749c917ab9dfcc76.js","active_admin/application.js":"active_admin/application-50ffc9f86e474cd52ffb7ce3b3572255ad6646ea17097a056f330b540eae402c.js","tinymce/jquery.tinymce.js":"tinymce/jquery.tinymce.js","tinymce/langs/readme.md":"tinymce/langs/readme.md","tinymce/license.txt":"tinymce/license.txt","tinymce/plugins/advlist/plugin.js":"tinymce/plugins/advlist/plugin.js","tinymce/plugins/anchor/plugin.js":"tinymce/plugins/anchor/plugin.js","tinymce/plugins/autolink/plugin.js":"tinymce/plugins/autolink/plugin.js","tinymce/plugins/autoresize/plugin.js":"tinymce/plugins/autoresize/plugin.js","tinymce/plugins/autosave/plugin.js":"tinymce/plugins/autosave/plugin.js","tinymce/plugins/bbcode/plugin.js":"tinymce/plugins/bbcode/plugin.js","tinymce/plugins/charmap/plugin.js":"tinymce/plugins/charmap/plugin.js","tinymce/plugins/code/plugin.js":"tinymce/plugins/code/plugin.js","tinymce/plugins/codesample/css/prism.css":"tinymce/plugins/codesample/css/prism.css","tinymce/plugins/codesample/plugin.js":"tinymce/plugins/codesample/plugin.js","tinymce/plugins/colorpicker/plugin.js":"tinymce/plugins/colorpicker/plugin.js","tinymce/plugins/contextmenu/plugin.js":"tinymce/plugins/contextmenu/plugin.js","tinymce/plugins/directionality/plugin.js":"tinymce/plugins/directionality/plugin.js","tinymce/plugins/emoticons/img/smiley-cool.gif":"tinymce/plugins/emoticons/img/smiley-cool.gif","tinymce/plugins/emoticons/img/smiley-cry.gif":"tinymce/plugins/emoticons/img/smiley-cry.gif","tinymce/plugins/emoticons/img/smiley-embarassed.gif":"tinymce/plugins/emoticons/img/smiley-embarassed.gif","tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif":"tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif","tinymce/plugins/emoticons/img/smiley-frown.gif":"tinymce/plugins/emoticons/img/smiley-frown.gif","tinymce/plugins/emoticons/img/smiley-innocent.gif":"tinymce/plugins/emoticons/img/smiley-innocent.gif","tinymce/plugins/emoticons/img/smiley-kiss.gif":"tinymce/plugins/emoticons/img/smiley-kiss.gif","tinymce/plugins/emoticons/img/smiley-laughing.gif":"tinymce/plugins/emoticons/img/smiley-laughing.gif","tinymce/plugins/emoticons/img/smiley-money-mouth.gif":"tinymce/plugins/emoticons/img/smiley-money-mouth.gif","tinymce/plugins/emoticons/img/smiley-sealed.gif":"tinymce/plugins/emoticons/img/smiley-sealed.gif","tinymce/plugins/emoticons/img/smiley-smile.gif":"tinymce/plugins/emoticons/img/smiley-smile.gif","tinymce/plugins/emoticons/img/smiley-surprised.gif":"tinymce/plugins/emoticons/img/smiley-surprised.gif","tinymce/plugins/emoticons/img/smiley-tongue-out.gif":"tinymce/plugins/emoticons/img/smiley-tongue-out.gif","tinymce/plugins/emoticons/img/smiley-undecided.gif":"tinymce/plugins/emoticons/img/smiley-undecided.gif","tinymce/plugins/emoticons/img/smiley-wink.gif":"tinymce/plugins/emoticons/img/smiley-wink.gif","tinymce/plugins/emoticons/img/smiley-yell.gif":"tinymce/plugins/emoticons/img/smiley-yell.gif","tinymce/plugins/emoticons/plugin.js":"tinymce/plugins/emoticons/plugin.js","tinymce/plugins/example/dialog.html":"tinymce/plugins/example/dialog.html","tinymce/plugins/example/plugin.js":"tinymce/plugins/example/plugin.js","tinymce/plugins/example_dependency/plugin.js":"tinymce/plugins/example_dependency/plugin.js","tinymce/plugins/fullpage/plugin.js":"tinymce/plugins/fullpage/plugin.js","tinymce/plugins/fullscreen/plugin.js":"tinymce/plugins/fullscreen/plugin.js","tinymce/plugins/hr/plugin.js":"tinymce/plugins/hr/plugin.js","tinymce/plugins/image/plugin.js":"tinymce/plugins/image/plugin.js","tinymce/plugins/imagetools/plugin.js":"tinymce/plugins/imagetools/plugin.js","tinymce/plugins/importcss/plugin.js":"tinymce/plugins/importcss/plugin.js","tinymce/plugins/insertdatetime/plugin.js":"tinymce/plugins/insertdatetime/plugin.js","tinymce/plugins/layer/plugin.js":"tinymce/plugins/layer/plugin.js","tinymce/plugins/legacyoutput/plugin.js":"tinymce/plugins/legacyoutput/plugin.js","tinymce/plugins/link/plugin.js":"tinymce/plugins/link/plugin.js","tinymce/plugins/lists/plugin.js":"tinymce/plugins/lists/plugin.js","tinymce/plugins/media/moxieplayer.swf":"tinymce/plugins/media/moxieplayer.swf","tinymce/plugins/media/plugin.js":"tinymce/plugins/media/plugin.js","tinymce/plugins/nonbreaking/plugin.js":"tinymce/plugins/nonbreaking/plugin.js","tinymce/plugins/noneditable/plugin.js":"tinymce/plugins/noneditable/plugin.js","tinymce/plugins/pagebreak/plugin.js":"tinymce/plugins/pagebreak/plugin.js","tinymce/plugins/paste/plugin.js":"tinymce/plugins/paste/plugin.js","tinymce/plugins/preview/plugin.js":"tinymce/plugins/preview/plugin.js","tinymce/plugins/print/plugin.js":"tinymce/plugins/print/plugin.js","tinymce/plugins/save/plugin.js":"tinymce/plugins/save/plugin.js","tinymce/plugins/searchreplace/plugin.js":"tinymce/plugins/searchreplace/plugin.js","tinymce/plugins/spellchecker/plugin.js":"tinymce/plugins/spellchecker/plugin.js","tinymce/plugins/tabfocus/plugin.js":"tinymce/plugins/tabfocus/plugin.js","tinymce/plugins/table/plugin.js":"tinymce/plugins/table/plugin.js","tinymce/plugins/template/plugin.js":"tinymce/plugins/template/plugin.js","tinymce/plugins/textcolor/plugin.js":"tinymce/plugins/textcolor/plugin.js","tinymce/plugins/textpattern/plugin.js":"tinymce/plugins/textpattern/plugin.js","tinymce/plugins/visualblocks/css/visualblocks.css":"tinymce/plugins/visualblocks/css/visualblocks.css","tinymce/plugins/visualblocks/plugin.js":"tinymce/plugins/visualblocks/plugin.js","tinymce/plugins/visualchars/plugin.js":"tinymce/plugins/visualchars/plugin.js","tinymce/plugins/wordcount/plugin.js":"tinymce/plugins/wordcount/plugin.js","tinymce/skins/lightgray/content.inline.min.css":"tinymce/skins/lightgray/content.inline.min.css","tinymce/skins/lightgray/content.min.css":"tinymce/skins/lightgray/content.min.css","tinymce/skins/lightgray/fonts/tinymce-small.eot":"tinymce/skins/lightgray/fonts/tinymce-small.eot","tinymce/skins/lightgray/fonts/tinymce-small.svg":"tinymce/skins/lightgray/fonts/tinymce-small.svg","tinymce/skins/lightgray/fonts/tinymce-small.ttf":"tinymce/skins/lightgray/fonts/tinymce-small.ttf","tinymce/skins/lightgray/fonts/tinymce-small.woff":"tinymce/skins/lightgray/fonts/tinymce-small.woff","tinymce/skins/lightgray/fonts/tinymce.eot":"tinymce/skins/lightgray/fonts/tinymce.eot","tinymce/skins/lightgray/fonts/tinymce.svg":"tinymce/skins/lightgray/fonts/tinymce.svg","tinymce/skins/lightgray/fonts/tinymce.ttf":"tinymce/skins/lightgray/fonts/tinymce.ttf","tinymce/skins/lightgray/fonts/tinymce.woff":"tinymce/skins/lightgray/fonts/tinymce.woff","tinymce/skins/lightgray/img/anchor.gif":"tinymce/skins/lightgray/img/anchor.gif","tinymce/skins/lightgray/img/loader.gif":"tinymce/skins/lightgray/img/loader.gif","tinymce/skins/lightgray/img/object.gif":"tinymce/skins/lightgray/img/object.gif","tinymce/skins/lightgray/img/trans.gif":"tinymce/skins/lightgray/img/trans.gif","tinymce/skins/lightgray/skin.ie7.min.css":"tinymce/skins/lightgray/skin.ie7.min.css","tinymce/skins/lightgray/skin.min.css":"tinymce/skins/lightgray/skin.min.css","tinymce/themes/modern/theme.js":"tinymce/themes/modern/theme.js","tinymce/tinymce.js":"tinymce/tinymce.js","tinymce/langs/ar.js":"tinymce/langs/ar.js","tinymce/langs/ar_SA.js":"tinymce/langs/ar_SA.js","tinymce/langs/az.js":"tinymce/langs/az.js","tinymce/langs/be.js":"tinymce/langs/be.js","tinymce/langs/bg_BG.js":"tinymce/langs/bg_BG.js","tinymce/langs/bn_BD.js":"tinymce/langs/bn_BD.js","tinymce/langs/bs.js":"tinymce/langs/bs.js","tinymce/langs/ca.js":"tinymce/langs/ca.js","tinymce/langs/cs.js":"tinymce/langs/cs.js","tinymce/langs/cs_CZ.js":"tinymce/langs/cs_CZ.js","tinymce/langs/cy.js":"tinymce/langs/cy.js","tinymce/langs/da.js":"tinymce/langs/da.js","tinymce/langs/de.js":"tinymce/langs/de.js","tinymce/langs/de_AT.js":"tinymce/langs/de_AT.js","tinymce/langs/dv.js":"tinymce/langs/dv.js","tinymce/langs/el.js":"tinymce/langs/el.js","tinymce/langs/en_CA.js":"tinymce/langs/en_CA.js","tinymce/langs/en_GB.js":"tinymce/langs/en_GB.js","tinymce/langs/eo.js":"tinymce/langs/eo.js","tinymce/langs/es.js":"tinymce/langs/es.js","tinymce/langs/es_MX.js":"tinymce/langs/es_MX.js","tinymce/langs/et.js":"tinymce/langs/et.js","tinymce/langs/eu.js":"tinymce/langs/eu.js","tinymce/langs/fa.js":"tinymce/langs/fa.js","tinymce/langs/fa_IR.js":"tinymce/langs/fa_IR.js","tinymce/langs/fi.js":"tinymce/langs/fi.js","tinymce/langs/fo.js":"tinymce/langs/fo.js","tinymce/langs/fr_CH.js":"tinymce/langs/fr_CH.js","tinymce/langs/fr_FR.js":"tinymce/langs/fr_FR.js","tinymce/langs/ga.js":"tinymce/langs/ga.js","tinymce/langs/gd.js":"tinymce/langs/gd.js","tinymce/langs/gl.js":"tinymce/langs/gl.js","tinymce/langs/he_IL.js":"tinymce/langs/he_IL.js","tinymce/langs/hi_IN.js":"tinymce/langs/hi_IN.js","tinymce/langs/hr.js":"tinymce/langs/hr.js","tinymce/langs/hu_HU.js":"tinymce/langs/hu_HU.js","tinymce/langs/hy.js":"tinymce/langs/hy.js","tinymce/langs/id.js":"tinymce/langs/id.js","tinymce/langs/is_IS.js":"tinymce/langs/is_IS.js","tinymce/langs/it.js":"tinymce/langs/it.js","tinymce/langs/ja.js":"tinymce/langs/ja.js","tinymce/langs/ka_GE.js":"tinymce/langs/ka_GE.js","tinymce/langs/kab.js":"tinymce/langs/kab.js","tinymce/langs/kk.js":"tinymce/langs/kk.js","tinymce/langs/km_KH.js":"tinymce/langs/km_KH.js","tinymce/langs/ko.js":"tinymce/langs/ko.js","tinymce/langs/ko_KR.js":"tinymce/langs/ko_KR.js","tinymce/langs/ku.js":"tinymce/langs/ku.js","tinymce/langs/ku_IQ.js":"tinymce/langs/ku_IQ.js","tinymce/langs/lb.js":"tinymce/langs/lb.js","tinymce/langs/lt.js":"tinymce/langs/lt.js","tinymce/langs/lv.js":"tinymce/langs/lv.js","tinymce/langs/mk_MK.js":"tinymce/langs/mk_MK.js","tinymce/langs/ml.js":"tinymce/langs/ml.js","tinymce/langs/ml_IN.js":"tinymce/langs/ml_IN.js","tinymce/langs/mn_MN.js":"tinymce/langs/mn_MN.js","tinymce/langs/nb_NO.js":"tinymce/langs/nb_NO.js","tinymce/langs/nl.js":"tinymce/langs/nl.js","tinymce/langs/pl.js":"tinymce/langs/pl.js","tinymce/langs/pt_BR.js":"tinymce/langs/pt_BR.js","tinymce/langs/pt_PT.js":"tinymce/langs/pt_PT.js","tinymce/langs/ro.js":"tinymce/langs/ro.js","tinymce/langs/ru.js":"tinymce/langs/ru.js","tinymce/langs/ru_RU.js":"tinymce/langs/ru_RU.js","tinymce/langs/si_LK.js":"tinymce/langs/si_LK.js","tinymce/langs/sk.js":"tinymce/langs/sk.js","tinymce/langs/sl_SI.js":"tinymce/langs/sl_SI.js","tinymce/langs/sr.js":"tinymce/langs/sr.js","tinymce/langs/sv_SE.js":"tinymce/langs/sv_SE.js","tinymce/langs/ta.js":"tinymce/langs/ta.js","tinymce/langs/ta_IN.js":"tinymce/langs/ta_IN.js","tinymce/langs/tg.js":"tinymce/langs/tg.js","tinymce/langs/th_TH.js":"tinymce/langs/th_TH.js","tinymce/langs/tr.js":"tinymce/langs/tr.js","tinymce/langs/tr_TR.js":"tinymce/langs/tr_TR.js","tinymce/langs/tt.js":"tinymce/langs/tt.js","tinymce/langs/ug.js":"tinymce/langs/ug.js","tinymce/langs/uk.js":"tinymce/langs/uk.js","tinymce/langs/uk_UA.js":"tinymce/langs/uk_UA.js","tinymce/langs/vi.js":"tinymce/langs/vi.js","tinymce/langs/vi_VN.js":"tinymce/langs/vi_VN.js","tinymce/langs/zh_CN.js":"tinymce/langs/zh_CN.js","tinymce/langs/zh_TW.js":"tinymce/langs/zh_TW.js","markers-matte.png":"markers-matte-497826545a90e09a240504d14530eba45823b19fd44175e09e27c47cd822ddb9.png","markers-matte@2x.png":"markers-matte@2x-948fc8c4426f04f60964ed20394247f45b0b60e575d02398b9b6810e7a29a823.png","markers-plain.png":"markers-plain-cf233423aa44e75ac0031e77b8ba571cd3331010517e1197e63fb7b06856c1ff.png","markers-shadow.png":"markers-shadow-8703a2262710f5e3d29e65d2acdf90d6512e159e119d27b8234731d8a6208a20.png","markers-shadow@2x.png":"markers-shadow@2x-b21a536be27313fb504f69f5899ff0b1245b276571769ac08d6c32c35676e47a.png","markers-soft.png":"markers-soft-e78784e4ed70aaffddd73c315fab590233cc4e7b72388d7dd47a14796fc7c739.png","markers-soft@2x.png":"markers-soft@2x-c1e77253a8bfbe30cec24885d7046f443b76ebb66f4c961f77083b03f4a5cbaf.png","webshims/shims/jpicker/images/AlphaBar.png":"webshims/shims/jpicker/images/AlphaBar-34d23568a887827c654ed2ac63ed3857a2cbd690643c471ea4b21c08a1568454.png","webshims/shims/jpicker/images/Bars.png":"webshims/shims/jpicker/images/Bars-a697469b1a3828d81b3bdaf334ade0637dd6adf9bf45859aeb88a6ffc06b009f.png","webshims/shims/jpicker/images/Maps.png":"webshims/shims/jpicker/images/Maps-538873f6da4e3a26cd5bb92f305f01e0ca0680cd08d488aef3e1eb250d77a968.png","webshims/shims/jpicker/images/NoColor.png":"webshims/shims/jpicker/images/NoColor-d266c220953f0b4fe96aeb868b82148e4c2ad380b1ed04d29214602851204e86.png","webshims/shims/jpicker/images/bar-opacity.png":"webshims/shims/jpicker/images/bar-opacity-690f9f36c78c2ebdfe7510739082dd835cc940565b794617a2bcaf93a566d938.png","webshims/shims/jpicker/images/map-opacity.png":"webshims/shims/jpicker/images/map-opacity-00182478b4fc3dedc97b9d2c46d9917f82c321110cab01e0f2ad4725978c2fd3.png","webshims/shims/jpicker/images/mappoint.gif":"webshims/shims/jpicker/images/mappoint-25687420458d1f31e399b1bc5a25e95a6dce8b898ed7f9d4361ff6cb430a7c45.gif","webshims/shims/jpicker/images/picker.gif":"webshims/shims/jpicker/images/picker-3aa5592f4e753f0244866a40b9c48fced398d219b8bc5ee76d2d51f9f952c9b2.gif","webshims/shims/jpicker/images/preview-opacity.png":"webshims/shims/jpicker/images/preview-opacity-12751bd440befc7037806e0451e2a2a8577655e3de1b702a2b50514ba2e9628d.png","webshims/shims/jpicker/images/rangearrows.gif":"webshims/shims/jpicker/images/rangearrows-d13aa5195095eb2e0d990d488ff4c5ed65052e6065d709463c97ed0d25cf652b.gif","webshims/shims/styles/color-picker.png":"webshims/shims/styles/color-picker-2141bfffae7d9714b5260735c338beb44ed24c5982f267fc1e3158ac4b82079f.png","webshims/shims/styles/progress.gif":"webshims/shims/styles/progress-8023960ce5bc957d1f0014859a51e55b9a3ce180bfd3d214a1a0629e2608a446.gif","webshims/shims/styles/progress.png":"webshims/shims/styles/progress-a9f7c78ea64c14559c7e683daaba141f50fac42e68e88232e416ca21645d0139.png","webshims/shims/styles/transparent.png":"webshims/shims/styles/transparent-384a16eed212e680374ad9b8529fb3de3422e515b2e10fdc18d7afdba59a1fa9.png","jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png":"jquery-ui/ui-bg_flat_0_aaaaaa_40x100-9a8492a580bf85d3e98ae8861fbd45567e5a1f83eeafcf9574da0399d5f602ab.png","jquery-ui/ui-bg_flat_75_ffffff_40x100.png":"jquery-ui/ui-bg_flat_75_ffffff_40x100-39ab7ccd9f4e82579da78a9241265df288d8eb65dbbd7cf48aed2d0129887df5.png","jquery-ui/ui-bg_glass_55_fbf9ee_1x400.png":"jquery-ui/ui-bg_glass_55_fbf9ee_1x400-691597e8a40a891ea94d3589976ecfc33e6145c49422443b00ac2b5a0022964c.png","jquery-ui/ui-bg_glass_65_ffffff_1x400.png":"jquery-ui/ui-bg_glass_65_ffffff_1x400-f0e6cd91b837d5c5644d026e5ffeccd907953317cd5c0f689901733afda260b2.png","jquery-ui/ui-bg_glass_75_dadada_1x400.png":"jquery-ui/ui-bg_glass_75_dadada_1x400-c108f5cbf2dd9ec07a26530695ddd95e1664597ce6c056ae44c162cc2e28cec4.png","jquery-ui/ui-bg_glass_75_e6e6e6_1x400.png":"jquery-ui/ui-bg_glass_75_e6e6e6_1x400-ddf5dd4e0ef2b185e8bb0af7b6e90ebe74a84384cb4700658e76e754c8bfe550.png","jquery-ui/ui-bg_glass_95_fef1ec_1x400.png":"jquery-ui/ui-bg_glass_95_fef1ec_1x400-f6f1c1bedf1a0f37cfef81d12f5f012869d1ee7c984775a569827a1784d34f5c.png","jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100.png":"jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100-54270656df079c4da5182629a080fc633b6f84b87985eb016d25a560e2c38d4a.png","jquery-ui/ui-icons_222222_256x240.png":"jquery-ui/ui-icons_222222_256x240-57adb0d65f4e91dacfee975d9574422bee7486c8a182d60133728c672f2cdbbc.png","jquery-ui/ui-icons_2e83ff_256x240.png":"jquery-ui/ui-icons_2e83ff_256x240-20f8c6667afc48aa433ee9eb6d8a0584bdbd6b4a4a9091ff1e6b3adb31e63bd9.png","jquery-ui/ui-icons_454545_256x240.png":"jquery-ui/ui-icons_454545_256x240-07460e843c3e59aaadbb34231e699e856a2980753c7a47b66447da5d9f93fb7f.png","jquery-ui/ui-icons_888888_256x240.png":"jquery-ui/ui-icons_888888_256x240-ea2e29625de3463465e93b002b065f5833e05b97f7a052b1c141e754d62e1a8b.png","jquery-ui/ui-icons_cd0a0a_256x240.png":"jquery-ui/ui-icons_cd0a0a_256x240-1e32c6dbf5d3fd342f27a78aa881550d6412aa207f48468724a6a15402b6041b.png","baby_gnu_adl.svg":"baby_gnu_adl-97251005d3225cf1d58b8c497d6b7905dbc9560cc8acd50118fcce60d0a2679e.svg"}} \ No newline at end of file diff --git a/public/assets/active_admin-5f05779513d42df8ed807ee625244d8e144534286b6c72cecee9151938308901.css b/public/assets/active_admin-5f05779513d42df8ed807ee625244d8e144534286b6c72cecee9151938308901.css new file mode 100644 index 000000000..fa4f8494a --- /dev/null +++ b/public/assets/active_admin-5f05779513d42df8ed807ee625244d8e144534286b6c72cecee9151938308901.css @@ -0,0 +1,4 @@ +span.icon{vertical-align:middle;display:inline-block}span.icon svg{vertical-align:baseline}span.icon{width:0.8em;height:0.8em}html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline}body{line-height:1;color:black;background:white}ol,ul{list-style:none}table{border-collapse:separate;border-spacing:0;vertical-align:middle}caption,th,td{text-align:left;font-weight:normal;vertical-align:middle}q,blockquote{quotes:"" ""}q:before,q:after,blockquote:before,blockquote:after{content:""}a img{border:none}html{font-size:100.01%}body{font-size:75%;font-family:"Helvetica Neue", Arial, Helvetica, sans-serif}h1,h2,h3,h4,h5,h6{font-weight:normal;color:#5E6469}h1 img,h2 img,h3 img,h4 img,h5 img,h6 img{margin:0}h1{font-size:3em;line-height:1;margin-bottom:0.5em}h2{font-size:2em;margin-bottom:0.75em}h3{font-size:1.5em;line-height:1;margin-bottom:1em}h4{font-size:1.2em;line-height:1.25;margin-bottom:1.25em}h5{font-size:1em;font-weight:bold;margin-bottom:1.5em}h6{font-size:1em;font-weight:bold}p{margin:0 0 1.5em}p .left{margin:1.5em 1.5em 1.5em 0;padding:0}p .right{margin:1.5em 0 1.5em 1.5em;padding:0}.left{float:left !important}.right{float:right !important}blockquote{margin:1.5em;color:#666;font-style:italic}strong,dfn{font-weight:bold}em,dfn{font-style:italic}sup,sub{line-height:0}abbr,acronym{border-bottom:1px dotted #666}address{margin:0 0 1.5em;font-style:italic}del{color:#666}pre{margin:1.5em 0;white-space:pre}pre,code,tt{font:1em 'andale mono', 'lucida console', monospace;line-height:1.5}li ul,li ol{margin:0}ul,ol{margin:0 1.5em 1.5em 0;padding-left:1.5em}ul{list-style-type:disc}ol{list-style-type:decimal}dl{margin:0 0 1.5em 0}dl dt{font-weight:bold}dd{margin-left:1.5em}table{margin-bottom:1.4em;width:100%}th{font-weight:bold}thead th{background:#c3d9ff}th,td,caption{padding:4px 10px 4px 5px}.small{font-size:.8em;margin-bottom:1.875em;line-height:1.875em}.large{font-size:1.2em;line-height:2.5em;margin-bottom:1.25em}.hide{display:none}.quiet{color:#666}.loud{color:#000}.highlight{background:#ff0}.added{background:#060;color:#fff}.removed{background:#900;color:#fff}.first{margin-left:0;padding-left:0}.last{margin-right:0;padding-right:0}.top{margin-top:0;padding-top:0}.bottom{margin-bottom:0;padding-bottom:0}#header{background-color:#6a7176;background-image:linear-gradient(180deg, #6a7176, #4d5256);border-bottom:1px solid #44484b;box-shadow:0 1px 2px rgba(0,0,0,0.37);text-shadow:#000 0 1px 0;display:table;height:20px;width:100%;overflow:visible;position:inherit;padding:5px 0;z-index:900}#header h1{display:table-cell;vertical-align:middle;white-space:nowrap;color:#cdcdcd;margin-right:20px;margin-bottom:0px;padding:3px 30px 0 30px;font-size:1.3em;font-weight:normal;line-height:1.2}#header h1 a{text-decoration:none}#header h1 a:hover{color:#fff}#header h1 img{position:relative;top:-2px}#header a,#header a:link{color:#cdcdcd}#header .header-item{top:2px;position:relative;height:20px}#header ul.tabs{display:table-cell;vertical-align:middle;height:100%;margin:0;padding:0}#header ul.tabs>li{display:inline-block;margin-right:4px;margin-top:5px;margin-bottom:5px;font-size:1.0em;position:relative}#header ul.tabs>li a{text-decoration:none;padding:6px 10px 4px 10px;position:relative;border-radius:10px}#header ul.tabs>li.current>a{background:#7b8389;color:#fff}#header ul.tabs>li.has_nested>a{background:url(/assets/active_admin/nested_menu_arrow-15084d93c65c1964d7077700ea748bd2d70cfa2d4c19707c58a9c64e232dd442.gif) no-repeat calc(100% - 7px) 50%;padding-right:20px}#header ul.tabs>li.has_nested.current>a{background:#7b8389 url(/assets/active_admin/nested_menu_arrow_dark-7c43b8e0a5f8823875f49a093c9d7a6b374f885b6f9cc248ae9cd7e6e9b29034.gif) no-repeat calc(100% - 7px) 50%;padding-right:20px}#header ul.tabs>li:hover>a{background:#7b8389;color:#fff}#header ul.tabs>li.has_nested:hover>a{border-radius:0;border-top-right-radius:10px;border-top-left-radius:10px;border-bottom:5px solid #7b8389;background:#7b8389 url(/assets/active_admin/nested_menu_arrow_dark-7c43b8e0a5f8823875f49a093c9d7a6b374f885b6f9cc248ae9cd7e6e9b29034.gif) no-repeat calc(100% - 7px) 50%;z-index:1020}#header ul.tabs>li:hover ul{display:block}#header ul.tabs>li ul{background:#7b8389;border-top-right-radius:10px;border-top-left-radius:0;border-bottom-right-radius:10px;border-bottom-left-radius:10px;box-shadow:0 1px 3px #444;position:absolute;width:120%;min-width:175px;max-width:calc(100% + 20px);margin-top:5px;float:left;display:none;padding:3px 0px 5px 0;list-style:none;z-index:1010}#header ul.tabs>li ul li{margin:0px}#header ul.tabs>li ul li a{background:none;display:block}#header ul.tabs>li ul li a:hover{color:#fff;background:none}#header ul.tabs>li ul li.current a{border-radius:0}#header #tabs{width:100%}#header #utility_nav{color:#aaa;display:table-cell;white-space:nowrap;margin:0;padding:0;padding-right:26px;text-align:right}#header #utility_nav a{text-decoration:none}#header #utility_nav a:hover{color:#fff}#header #utility_nav li{display:inline}form ul,form ol,form li,form fieldset,form legend,form input,form textarea,form select,form p{margin:0;padding:0}form ol,form ul{list-style:none}form fieldset{border:0;padding:10px 0;margin-bottom:20px}form fieldset.inputs{background:#f4f4f4;border-radius:4px;box-shadow:inset 0 1px 4px #ddd}form fieldset legend{width:100%}form fieldset legend span{display:block;background-color:#efefef;background-image:linear-gradient(180deg, #efefef, #dfe1e2);text-shadow:#fff 0 1px 0;border:solid 1px #cdcdcd;border-color:#d4d4d4;border-top-color:#e6e6e6;border-right-color:#d4d4d4;border-bottom-color:#cdcdcd;border-left-color:#d4d4d4;box-shadow:0 1px 3px rgba(0,0,0,0.12),0 0 1px #FFF inset;font-size:1em;font-weight:bold;line-height:18px;margin-bottom:0.5em;color:#5E6469;padding:5px 10px 3px 10px}form fieldset legend span span.icon svg path,form fieldset legend span span.icon svg polygon,form fieldset legend span span.icon svg rect,form fieldset legend span span.icon svg circle{fill:#5E6469}form fieldset legend span span.icon{width:1em;height:1em}form fieldset ol>li{padding:10px}form fieldset ol>li label{display:block;width:20%;float:left;font-size:1.0em;font-weight:bold;color:#5E6469}form fieldset ol>li label abbr{border:none;color:#aaa}form fieldset ol>li.has_many_container{padding:20px 10px}form fieldset ol>li.has_many_container h3{font-size:12px;font-weight:bold}form fieldset ol>li.has_many_container .has_many_fields{margin:10px 0}form fieldset ol>li>li label{line-height:100%;padding-top:0}form fieldset ol>li>li label input{line-height:100%;vertical-align:middle;margin-top:-0.1em}form .has_many_fields{position:relative}form .has_many_container .handle{position:absolute;top:calc(50% - 3em / 2);right:2px;padding:0;cursor:move}form .has_many_container .handle span.icon{width:3em;height:3em}form .has_many_container.ui-sortable .has_many_container{margin-right:2em}form .ui-sortable input[type=text],form .ui-sortable input[type=password],form .ui-sortable input[type=email],form .ui-sortable input[type=number],form .ui-sortable input[type=url],form .ui-sortable input[type=tel],form .ui-sortable textarea{width:calc(80% - 22px - 2em - 1px)}form fieldset>ol>li fieldset{position:relative;padding:0;margin-bottom:0}form fieldset>ol>li fieldset legend{position:absolute;width:95%;padding-top:0.1em;left:0px;font-size:100%;font-weight:normal}form fieldset>ol>li fieldset legend span{position:absolute}form fieldset>ol>li fieldset legend.label label{position:absolute}form fieldset>ol>li fieldset:not(.has_many_fields) ol{float:left;width:74%;margin:0;padding:0 0 0 20%}form fieldset>ol>li fieldset:not(.has_many_fields) ol li{padding:0;border:0}form fieldset>ol>li fieldset.has_many_fields ol{float:left;width:100%;margin:0}form input[type=text],form input[type=password],form input[type=email],form input[type=number],form input[type=url],form input[type=tel],form textarea{width:calc(80% - 22px);border:1px solid #c9d0d6;border-radius:3px;font-size:0.95em;font-family:Helvetica, Arial, sans-serif;outline:none;padding:8px 10px 7px}form input[type=text]:focus,form input[type=password]:focus,form input[type=email]:focus,form input[type=number]:focus,form input[type=url]:focus,form input[type=tel]:focus,form textarea:focus{border:1px solid #99a2aa;box-shadow:0 0 4px #99a2aa}form fieldset>ol>li p.inline-hints{font-size:0.95em;font-style:italic;color:#666;margin:0.5em 0 0 20%}form fieldset>ol>li.date_select fieldset ol li,form fieldset>ol>li.time_select fieldset ol li,form fieldset>ol>li.datetime_select fieldset ol li{float:left;width:auto;margin:0 0.5em 0 0}form fieldset>ol>li.date_select fieldset ol li label,form fieldset>ol>li.time_select fieldset ol li label,form fieldset>ol>li.datetime_select fieldset ol li label{display:none}form fieldset>ol>li.date_select fieldset ol li input,form fieldset>ol>li.time_select fieldset ol li input,form fieldset>ol>li.datetime_select fieldset ol li input{display:inline;margin:0;padding:0}form fieldset>ol>li.check_boxes fieldset ol,form fieldset>ol>li.radio fieldset ol{margin-bottom:-0.6em}form fieldset>ol>li.check_boxes fieldset ol li,form fieldset>ol>li.radio fieldset ol li{margin:0.1em 0 0.5em 0}form fieldset>ol>li.check_boxes fieldset ol li label,form fieldset>ol>li.radio fieldset ol li label{float:none;width:100%}form fieldset>ol>li.check_boxes fieldset ol li label input,form fieldset>ol>li.radio fieldset ol li label input{margin-right:0.2em}form fieldset>ol>li.boolean{height:1.1em}form fieldset>ol>li.boolean label{width:80%;padding-left:20%;padding-right:10px;text-transform:none !important;font-weight:normal}form fieldset>ol>li.boolean label input{margin:0 0.5em 0 0.2em}form fieldset>ol>li.hidden{padding:0}form fieldset>ol>li p.inline-errors{color:#932419;font-weight:bold;margin:0.3em 0 0 20%}form fieldset>ol>li ul.errors{color:#932419;margin:0.5em 0 0 20%;list-style:square}form fieldset>ol>li ul.errors li{padding:0;border:none;display:list-item}form fieldset>ol>li.error input[type=text],form fieldset>ol>li.error input[type=password],form fieldset>ol>li.error input[type=email],form fieldset>ol>li.error input[type=number],form fieldset>ol>li.error input[type=url],form fieldset>ol>li.error input[type=tel],form fieldset>ol>li.error textarea{border:1px solid #932419}form ul.errors{background:#fae6e4;border-radius:4px;color:#932419;font-weight:bold;margin-bottom:10px;padding:10px;list-style:square}form ul.errors li{margin-left:15px;padding:0;border:none;display:list-item}form input[type=submit],form input[type=button],form button{border-radius:200px;display:inline-block;font-weight:bold;font-size:1.0em;font-family:Helvetica, Arial, sans-serif;line-height:12px;margin-right:3px;padding:7px 16px 6px;text-decoration:none;background-color:#838a90;background-image:linear-gradient(180deg, #838a90, #414549);text-shadow:#000 0 1px 0;box-shadow:0 1px 1px rgba(0,0,0,0.1),0 1px 0 0px rgba(255,255,255,0.2) inset;border:solid 1px #484e53;border-color:#484e53;border-top-color:#616a71;border-right-color:#484e53;border-bottom-color:#363b3f;border-left-color:#484e53;color:#efefef;cursor:pointer}form input[type=submit].disabled,form input[type=button].disabled,form button.disabled{opacity:0.5;cursor:default}form input[type=submit]:not(.disabled):hover,form input[type=button]:not(.disabled):hover,form button:not(.disabled):hover{background-color:#8b9297;background-image:linear-gradient(180deg, #8b9297, #484d51)}form input[type=submit]:not(.disabled):active,form input[type=button]:not(.disabled):active,form button:not(.disabled):active{box-shadow:0 1px 3px rgba(0,0,0,0.4) inset,0 1px 0 0px #FFF;background-color:#71797f;background-image:linear-gradient(180deg, #71797f, #35383b)}form .buttons,form .actions{margin-top:15px}form .buttons input[type=submit],form .buttons input[type=button],form .buttons button,form .actions input[type=submit],form .actions input[type=button],form .actions button{margin-right:10px}form fieldset.buttons li,form fieldset.actions li{float:left;padding:0}form fieldset.buttons li.cancel a,form fieldset.actions li.cancel a{border-radius:200px;display:inline-block;font-weight:bold;font-size:1.0em;font-family:Helvetica, Arial, sans-serif;line-height:12px;margin-right:3px;padding:7px 16px 6px;text-decoration:none;background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #E7E7E7);box-shadow:0 1px 1px rgba(0,0,0,0.1),0 1px 0 0 rgba(255,255,255,0.8) inset;border:solid 1px #c7c7c7;border-color:#c7c7c7;border-top-color:#d3d3d3;border-right-color:#c7c7c7;border-bottom-color:#c2c2c2;border-left-color:#c7c7c7;text-shadow:#fff 0 1px 0;color:#5E6469}form fieldset.buttons li.cancel a.disabled,form fieldset.actions li.cancel a.disabled{opacity:0.5;cursor:default}form fieldset.buttons li.cancel a:not(.disabled):hover,form fieldset.actions li.cancel a:not(.disabled):hover{background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #F1F1F1)}form fieldset.buttons li.cancel a:not(.disabled):active,form fieldset.actions li.cancel a:not(.disabled):active{box-shadow:0 1px 2px rgba(0,0,0,0.22) inset,0 1px 0 0px #EEE;border-color:#b9b9b9;border-top-color:#c2c2c2;border-right-color:#b9b9b9;border-bottom-color:#b7b7b7;border-left-color:#b9b9b9;background-color:#F3F3F3;background-image:linear-gradient(180deg, #F3F3F3, #D8D8D8)}form fieldset.buttons li.cancel a span.icon svg path,form fieldset.buttons li.cancel a span.icon svg polygon,form fieldset.buttons li.cancel a span.icon svg rect,form fieldset.buttons li.cancel a span.icon svg circle,form fieldset.actions li.cancel a span.icon svg path,form fieldset.actions li.cancel a span.icon svg polygon,form fieldset.actions li.cancel a span.icon svg rect,form fieldset.actions li.cancel a span.icon svg circle{fill:#777}form fieldset.buttons li.cancel a span.icon,form fieldset.actions li.cancel a span.icon{width:9px;height:9px}.sidebar_section label{display:block;text-transform:uppercase;color:#5E6469;font-size:0.9em;font-weight:bold}.sidebar_section select{width:240px}.sidebar_section input[type=text],.sidebar_section input[type=password],.sidebar_section input[type=email],.sidebar_section input[type=url],.sidebar_section input[type=tel],.sidebar_section textarea{width:220px}form.filter_form .filter_form_field{margin-bottom:10px;clear:both}form.filter_form .filter_form_field.select_and_search input[type=text]{margin-left:16px;width:88px}form.filter_form .filter_form_field.select_and_search select{width:108px}form.filter_form .filter_form_field.filter_check_boxes label{margin-bottom:3px}form.filter_form .filter_form_field.filter_check_boxes fieldset{margin-bottom:0px;padding-bottom:0px}form.filter_form .filter_form_field.filter_check_boxes .check_boxes_wrapper label{font-weight:normal;margin-bottom:3px;text-transform:none;font-size:1.0em}form.filter_form .filter_form_field.filter_check_boxes .check_boxes_wrapper label input{vertical-align:baseline}form.filter_form .filter_form_field.filter_date_range .seperator{display:inline-block;text-align:center;width:12px}form.filter_form .filter_form_field.filter_date_range input[type=text]{background:#fff url(/assets/active_admin/datepicker/datepicker-input-icon-d9c2bb73769af777c8a71720d29741f3a499aebd5a043e9a119bd0d9597aed47.png) no-repeat 100% 7px;padding-right:27px;width:71px}form.filter_form a.clear_filters_btn{border-radius:200px;display:inline-block;font-weight:bold;font-size:1.0em;font-family:Helvetica, Arial, sans-serif;line-height:12px;margin-right:3px;padding:7px 16px 6px;text-decoration:none;background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #E7E7E7);box-shadow:0 1px 1px rgba(0,0,0,0.1),0 1px 0 0 rgba(255,255,255,0.8) inset;border:solid 1px #c7c7c7;border-color:#c7c7c7;border-top-color:#d3d3d3;border-right-color:#c7c7c7;border-bottom-color:#c2c2c2;border-left-color:#c7c7c7;text-shadow:#fff 0 1px 0;color:#5E6469}form.filter_form a.clear_filters_btn.disabled{opacity:0.5;cursor:default}form.filter_form a.clear_filters_btn:not(.disabled):hover{background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #F1F1F1)}form.filter_form a.clear_filters_btn:not(.disabled):active{box-shadow:0 1px 2px rgba(0,0,0,0.22) inset,0 1px 0 0px #EEE;border-color:#b9b9b9;border-top-color:#c2c2c2;border-right-color:#b9b9b9;border-bottom-color:#b7b7b7;border-left-color:#b9b9b9;background-color:#F3F3F3;background-image:linear-gradient(180deg, #F3F3F3, #D8D8D8)}.comments .active_admin_comment{clear:both;margin-top:10px;margin-bottom:40px;max-width:700px}.comments .active_admin_comment .active_admin_comment_meta{width:130px;float:left;overflow:hidden;font-size:0.9em;color:#767e84}.comments .active_admin_comment .active_admin_comment_meta .active_admin_comment_author{font-size:1.2em;font-weight:bold;margin:0;color:#5E6469}.comments .active_admin_comment .active_admin_comment_body{margin-left:150px}.comments form.active_admin_comment{margin:0;padding:0;margin-left:150px}.comments form.active_admin_comment fieldset.inputs{margin:0;padding:0;background:none;box-shadow:none}.comments form.active_admin_comment li{padding:0}.comments form.active_admin_comment fieldset.buttons{padding:0;margin-top:5px}body.logged_in .flash{background-color:#f7f1d3;background-image:linear-gradient(180deg, #f7f1d3, #f5edc5);text-shadow:#fafafa 0 1px 0;border-bottom:1px solid #eee098;color:#cb9810;font-weight:bold;font-size:1.1em;line-height:1.0em;padding:13px 30px 11px;position:relative}body.logged_in .flash.flash_notice{background-color:#dce9dd;background-image:linear-gradient(180deg, #dce9dd, #ccdfcd);border-bottom:1px solid #adcbaf;color:#416347}body.logged_in .flash.flash_error{background-color:#f5e4e4;background-image:linear-gradient(180deg, #f5e4e4, #f1dcdc);border-bottom:1px solid #e0c2c0;color:#b33c33}body.logged_out .flash{box-shadow:none;text-shadow:#fff 0 1px 0;background:none;color:#666;font-weight:bold;line-height:1.0em;padding:0;margin-bottom:8px}.ui-datepicker{background:#fff;background-clip:padding-box;color:#fff;display:none;margin-top:2px;padding:0;text-align:center;width:160px}.ui-datepicker a{text-decoration:none}.ui-datepicker a:hover{cursor:pointer}.ui-datepicker .ui-datepicker-header{height:14px;background-color:#6a7176;background-image:linear-gradient(180deg, #6a7176, #4d5256);border-bottom:1px solid #44484b;padding:12px 5px 7px 4px;margin:0px 0px 2px 2px;width:147px;border-top-left-radius:7px;border-top-right-radius:7px;position:relative;z-index:2000}.ui-datepicker .ui-datepicker-header:before{content:"";position:absolute;right:45%;top:-6px;width:0px;height:0px;border-left:8.5px solid transparent;border-right:8.5px solid transparent;border-bottom:10px solid #676e73}.ui-datepicker .ui-datepicker-header .ui-datepicker-title{text-shadow:#000 0 1px 0;color:#fff;display:block;font-size:1.1em;font-weight:bold;line-height:0.8em;text-align:center}.ui-datepicker .ui-datepicker-header .ui-datepicker-title .ui-datepicker-month{margin:-4px 0 0 0}.ui-datepicker .ui-datepicker-header .ui-datepicker-title .ui-datepicker-year{margin:-4px 0 0 0}.ui-datepicker .ui-datepicker-header a{color:#fff;display:block;height:19px;margin-top:-4px;width:10px}.ui-datepicker .ui-datepicker-header a.ui-datepicker-prev{float:left;width:0;height:0;margin:0px 0px 0px 4px;border-top:5px solid transparent;border-right:5px solid white;border-bottom:5px solid transparent}.ui-datepicker .ui-datepicker-header a.ui-datepicker-next{float:right;width:0;height:0;margin:0px 4px 0px 0px;border-top:5px solid transparent;border-left:5px solid white;border-bottom:5px solid transparent}.ui-datepicker .ui-datepicker-header a span{display:none}.ui-datepicker table.ui-datepicker-calendar{border-radius:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px;box-shadow:0 1px 6px rgba(0,0,0,0.26);background-color:#f4f4f4;border:solid 1px #63686e;left:2px;margin-bottom:0px;position:relative;top:-2px;width:156px}.ui-datepicker table.ui-datepicker-calendar td,.ui-datepicker table.ui-datepicker-calendar th{padding:0px;text-align:center}.ui-datepicker table.ui-datepicker-calendar thead th{background-color:#dbdddf;color:#333333;font-weight:normal;font-size:0.8em;padding-top:1px}.ui-datepicker table.ui-datepicker-calendar tbody{color:#666666}.ui-datepicker table.ui-datepicker-calendar tbody td{border:none;height:24px;width:22px}.ui-datepicker table.ui-datepicker-calendar tbody td a{border-radius:3px;color:#666666;font-weight:bold;font-size:0.85em;padding:4px}.ui-datepicker table.ui-datepicker-calendar tbody td a.ui-state-active{background-color:#5a5f64;color:#fff}.ui-datepicker table.ui-datepicker-calendar tbody td a.ui-state-active.ui-state-hover{background-color:#5a5f64;color:#fff}.ui-datepicker table.ui-datepicker-calendar tbody td a.ui-state-hover{background-color:#eceef0}.ui-datepicker table.ui-datepicker-calendar tbody td a.ui-state-highlight{background-color:#dbdddf}.popover{display:inline-block;position:absolute;background-color:white;padding:2px;box-shadow:rgba(0,0,0,0.4) 0 1px 3px,#838a90 0px 1px 0px 0px inset;background-color:#5E6469;background-color:#686e74;background-image:linear-gradient(180deg, #686e74, #52575c);border:solid 1px #464a4e;border-top-color:#545a5e;border-bottom-color:#35383b;border-radius:4px}.popover .popover_nipple{content:"";position:absolute;top:-6px;display:block;width:0;height:0;border-width:0 6px 6px;border-style:solid;border-color:#545a5e transparent;z-index:100}.popover .popover_nipple:before{content:' ';position:absolute;width:0;height:0;border-width:0 5px 5px;border-style:solid;border-color:#838a90 transparent;left:-5px;top:1px}.popover .popover_nipple:after{content:' ';position:absolute;width:0;height:0;border-width:0 5px 5px;border-style:solid;border-color:#686e74 transparent;left:-5px;top:2px}.popover .popover_contents{display:block;background-color:#FFF;border:solid 1px #464a4e;box-shadow:#6a7176 0px 1px 0px 0px;border-radius:3px;margin:0;overflow:hidden;padding:8px}.popover ul.popover_contents{list-style-type:none;padding:0}.popover ul.popover_contents li{display:block;border-bottom:solid 1px #ebebeb;box-sizing:border-box}.popover ul.popover_contents li a{display:block;box-sizing:padding-box;font-size:0.95em;font-weight:bold;padding:7px 16px 5px;text-decoration:none;text-align:center}.popover ul.popover_contents li a:hover{background-color:#75a1c2;background-image:linear-gradient(180deg, #75a1c2, #608cb4);text-shadow:#5a83aa 0 1px 0;color:#FFF}.popover ul.popover_contents li a:active{background-color:#608cb4;background-image:linear-gradient(180deg, #608cb4, #75a1c2);color:#FFF}.popover ul.popover_contents li:first-child a{border-top-left-radius:2px;border-top-right-radius:2px}.popover ul.popover_contents li:last-child{border:none}.popover ul.popover_contents li:last-child a{border-bottom-left-radius:2px;border-bottom-right-radius:2px}table tr td{vertical-align:top}table.index_table{width:100%;margin-bottom:10px;border:0;border-spacing:0}table.index_table th{background-color:#efefef;background-image:linear-gradient(180deg, #efefef, #dfe1e2);text-shadow:#fff 0 1px 0;border:solid 1px #cdcdcd;border-color:#d4d4d4;border-top-color:#e6e6e6;border-right-color:#d4d4d4;border-bottom-color:#cdcdcd;border-left-color:#d4d4d4;box-shadow:0 1px 3px rgba(0,0,0,0.12),0 0 1px #FFF inset;font-size:1em;font-weight:bold;line-height:18px;margin-bottom:0.5em;color:#5E6469;padding:5px 10px 3px 10px;border-right:none;text-align:left;padding-left:12px;padding-right:12px}table.index_table th span.icon svg path,table.index_table th span.icon svg polygon,table.index_table th span.icon svg rect,table.index_table th span.icon svg circle{fill:#5E6469}table.index_table th span.icon{width:1em;height:1em}table.index_table th a,table.index_table th a:link,table.index_table th a:visited{color:#5E6469;text-decoration:none;display:block;white-space:nowrap}table.index_table th.sortable a{background:url(/assets/active_admin/orderable-29374dbb55b0012d78a37c614d573bb3474f0779849b478a147d0f1845ca6617.png) no-repeat 0 4px;padding-left:13px}table.index_table th.sorted-asc a{background-position:0 -27px}table.index_table th.sorted-desc a{background-position:0 -56px}table.index_table th.sorted-asc,table.index_table th.sorted-desc{background-color:#e2e2e2;background-image:linear-gradient(180deg, #e2e2e2, #d2d4d6)}table.index_table th:last-child{border-right:solid 1px #d4d4d4}table.index_table tr.even td{background:#f4f5f5}table.index_table tr.selected td{background:#d9e4ec}table.index_table td{padding:10px 12px 8px 12px;border-bottom:1px solid #e8e8e8;vertical-align:top}.panel_contents table{margin-top:5px}.panel_contents table th{padding-top:10px;background:none;color:#5E6469;box-shadow:none;text-shadow:#fff 0 1px 0;text-transform:uppercase;border-bottom:1px solid #ccc}.panel_contents table tr.odd td{background:#ecedee}.panel_contents table tr.even td{background:#f4f5f5}.attributes_table{overflow:hidden}.attributes_table table col.even{background:#f4f5f5}.attributes_table table col.odd{background:#ecedee}.attributes_table table th,.attributes_table table td{padding:8px 12px 6px 12px;vertical-align:top;border-bottom:1px solid #e8e8e8}.attributes_table table th{box-shadow:none;background-color:none;width:150px;font-size:0.9em;padding-left:0;text-transform:uppercase;color:#5E6469;text-shadow:#fff 0 1px 0}.attributes_table table td .empty{color:#bbb;font-size:0.8em;text-transform:uppercase;letter-spacing:0.2em}.sidebar_section .attributes_table th{width:50px}#collection_selection_toggle_panel::after{clear:both;content:"";display:table}#collection_selection_toggle_panel>.resource_selection_toggle_cell{float:left}#collection_selection_toggle_panel #collection_selection_toggle_explaination{float:left;margin-left:5px;font-style:italic}.ui-widget-overlay{position:fixed;background:rgba(0,0,0,0.2);top:0;left:0;right:0;bottom:0;z-index:1001}.ui-dialog{position:fixed;z-index:1002;background:#f4f4f4;border-radius:4px;box-shadow:inset 0 1px 4px #ddd;box-shadow:rgba(0,0,0,0.5) 0 0 10px}.ui-dialog .ui-dialog-titlebar{background-color:#efefef;background-image:linear-gradient(180deg, #efefef, #dfe1e2);text-shadow:#fff 0 1px 0;border:solid 1px #cdcdcd;border-color:#d4d4d4;border-top-color:#e6e6e6;border-right-color:#d4d4d4;border-bottom-color:#cdcdcd;border-left-color:#d4d4d4;box-shadow:0 1px 3px rgba(0,0,0,0.12),0 0 1px #FFF inset;font-size:1em;font-weight:bold;line-height:18px;margin-bottom:0.5em;color:#5E6469;padding:5px 10px 3px 10px}.ui-dialog .ui-dialog-titlebar span.icon svg path,.ui-dialog .ui-dialog-titlebar span.icon svg polygon,.ui-dialog .ui-dialog-titlebar span.icon svg rect,.ui-dialog .ui-dialog-titlebar span.icon svg circle{fill:#5E6469}.ui-dialog .ui-dialog-titlebar span.icon{width:1em;height:1em}.ui-dialog .ui-dialog-titlebar span{font-size:1.1em}.ui-dialog ul{list-style-type:none}.ui-dialog li{margin:10px 0}.ui-dialog label{margin-right:10px}.ui-dialog .ui-dialog-buttonpane,.ui-dialog form{padding:7px 15px 13px}.ui-dialog .ui-dialog-buttonpane button{border-radius:200px;display:inline-block;font-weight:bold;font-size:1.0em;font-family:Helvetica, Arial, sans-serif;line-height:12px;margin-right:3px;padding:7px 16px 6px;text-decoration:none;background-color:#838a90;background-image:linear-gradient(180deg, #838a90, #414549);text-shadow:#000 0 1px 0;box-shadow:0 1px 1px rgba(0,0,0,0.1),0 1px 0 0px rgba(255,255,255,0.2) inset;border:solid 1px #484e53;border-color:#484e53;border-top-color:#616a71;border-right-color:#484e53;border-bottom-color:#363b3f;border-left-color:#484e53;color:#efefef}.ui-dialog .ui-dialog-buttonpane button.disabled{opacity:0.5;cursor:default}.ui-dialog .ui-dialog-buttonpane button:not(.disabled):hover{background-color:#8b9297;background-image:linear-gradient(180deg, #8b9297, #484d51)}.ui-dialog .ui-dialog-buttonpane button:not(.disabled):active{box-shadow:0 1px 3px rgba(0,0,0,0.4) inset,0 1px 0 0px #FFF;background-color:#71797f;background-image:linear-gradient(180deg, #71797f, #35383b)}.ui-dialog .ui-dialog-buttonpane button:last-child{border-radius:200px;display:inline-block;font-weight:bold;font-size:1.0em;font-family:Helvetica, Arial, sans-serif;line-height:12px;margin-right:3px;padding:7px 16px 6px;text-decoration:none;background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #E7E7E7);box-shadow:0 1px 1px rgba(0,0,0,0.1),0 1px 0 0 rgba(255,255,255,0.8) inset;border:solid 1px #c7c7c7;border-color:#c7c7c7;border-top-color:#d3d3d3;border-right-color:#c7c7c7;border-bottom-color:#c2c2c2;border-left-color:#c7c7c7;text-shadow:#fff 0 1px 0;color:#5E6469}.ui-dialog .ui-dialog-buttonpane button:last-child.disabled{opacity:0.5;cursor:default}.ui-dialog .ui-dialog-buttonpane button:last-child:not(.disabled):hover{background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #F1F1F1)}.ui-dialog .ui-dialog-buttonpane button:last-child:not(.disabled):active{box-shadow:0 1px 2px rgba(0,0,0,0.22) inset,0 1px 0 0px #EEE;border-color:#b9b9b9;border-top-color:#c2c2c2;border-right-color:#b9b9b9;border-bottom-color:#b7b7b7;border-left-color:#b9b9b9;background-color:#F3F3F3;background-image:linear-gradient(180deg, #F3F3F3, #D8D8D8)}.active_admin_dialog.ui-dialog .ui-dialog-titlebar-close{display:none}.blank_slate_container{clear:both;text-align:center}.blank_slate_container .blank_slate{border-radius:3px;border:1px dashed #DADADA;color:#AAA;display:inline-block;font-size:1.2em;font-weight:bold;padding:14px 25px;text-align:center}.blank_slate_container .blank_slate small{display:block;font-size:0.9em;font-weight:normal}.admin_dashboard .blank_slate_container .blank_slate{margin-top:40px;margin-bottom:40px}.with_sidebar .blank_slate_container .blank_slate{margin-top:80px}.breadcrumb{display:block;font-size:0.9em;font-weight:normal;line-height:1.0em;margin-bottom:12px;text-transform:uppercase}.breadcrumb a,.breadcrumb a:link,.breadcrumb a:visited,.breadcrumb a:active{color:#8a949e;text-decoration:none}.breadcrumb a:hover{text-decoration:underline}.breadcrumb .breadcrumb_sep{margin:0 2px;color:#aab2ba}.dropdown_menu{display:inline}.dropdown_menu .dropdown_menu_button{border-radius:200px;display:inline-block;font-weight:bold;font-size:1.0em;font-family:Helvetica, Arial, sans-serif;line-height:12px;margin-right:3px;padding:7px 16px 6px;text-decoration:none;background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #E7E7E7);box-shadow:0 1px 1px rgba(0,0,0,0.1),0 1px 0 0 rgba(255,255,255,0.8) inset;border:solid 1px #c7c7c7;border-color:#c7c7c7;border-top-color:#d3d3d3;border-right-color:#c7c7c7;border-bottom-color:#c2c2c2;border-left-color:#c7c7c7;text-shadow:#fff 0 1px 0;color:#5E6469;position:relative;padding-right:22px !important;cursor:pointer}.dropdown_menu .dropdown_menu_button.disabled{opacity:0.5;cursor:default}.dropdown_menu .dropdown_menu_button:not(.disabled):hover{background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #F1F1F1)}.dropdown_menu .dropdown_menu_button:not(.disabled):active{box-shadow:0 1px 2px rgba(0,0,0,0.22) inset,0 1px 0 0px #EEE;border-color:#b9b9b9;border-top-color:#c2c2c2;border-right-color:#b9b9b9;border-bottom-color:#b7b7b7;border-left-color:#b9b9b9;background-color:#F3F3F3;background-image:linear-gradient(180deg, #F3F3F3, #D8D8D8)}.dropdown_menu .dropdown_menu_button:before{content:' ';position:absolute;width:0;height:0;border-width:3px 3px 0;border-style:solid;border-color:#FFF transparent;right:12px;top:45%}.dropdown_menu .dropdown_menu_button:after{content:' ';position:absolute;width:0;height:0;border-width:3px 3px 0;border-style:solid;border-color:#777 transparent;right:12px;top:45%}.dropdown_menu .dropdown_menu_nipple{content:"";position:absolute;top:-6px;display:block;width:0;height:0;border-width:0 6px 6px;border-style:solid;border-color:#545a5e transparent;z-index:100}.dropdown_menu .dropdown_menu_nipple:before{content:' ';position:absolute;width:0;height:0;border-width:0 5px 5px;border-style:solid;border-color:#838a90 transparent;left:-5px;top:1px}.dropdown_menu .dropdown_menu_nipple:after{content:' ';position:absolute;width:0;height:0;border-width:0 5px 5px;border-style:solid;border-color:#686e74 transparent;left:-5px;top:2px}.dropdown_menu .dropdown_menu_list_wrapper{display:inline-block;position:absolute;background-color:white;padding:2px;box-shadow:rgba(0,0,0,0.4) 0 1px 3px,#838a90 0px 1px 0px 0px inset;background-color:#5E6469;background-color:#686e74;background-image:linear-gradient(180deg, #686e74, #52575c);border:solid 1px #464a4e;border-top-color:#545a5e;border-bottom-color:#35383b;border-radius:4px;z-index:2000;display:none}.dropdown_menu .dropdown_menu_list_wrapper .dropdown_menu_list{display:block;background-color:#FFF;border:solid 1px #464a4e;box-shadow:#6a7176 0px 1px 0px 0px;border-radius:3px;margin:0;overflow:hidden;padding:8px;list-style-type:none;padding:0}.dropdown_menu .dropdown_menu_list_wrapper .dropdown_menu_list li{display:block;border-bottom:solid 1px #ebebeb;box-sizing:border-box}.dropdown_menu .dropdown_menu_list_wrapper .dropdown_menu_list li a{display:block;box-sizing:padding-box;font-size:0.95em;font-weight:bold;padding:7px 16px 5px;text-decoration:none;text-align:center;white-space:nowrap}.dropdown_menu .dropdown_menu_list_wrapper .dropdown_menu_list li a:hover{background-color:#75a1c2;background-image:linear-gradient(180deg, #75a1c2, #608cb4);text-shadow:#5a83aa 0 1px 0;color:#FFF}.dropdown_menu .dropdown_menu_list_wrapper .dropdown_menu_list li a:active{background-color:#608cb4;background-image:linear-gradient(180deg, #608cb4, #75a1c2);color:#FFF}.dropdown_menu .dropdown_menu_list_wrapper .dropdown_menu_list li:first-child a{border-top-left-radius:2px;border-top-right-radius:2px}.dropdown_menu .dropdown_menu_list_wrapper .dropdown_menu_list li:last-child{border:none}.dropdown_menu .dropdown_menu_list_wrapper .dropdown_menu_list li:last-child a{border-bottom-left-radius:2px;border-bottom-right-radius:2px}td span.icon svg path,td span.icon svg polygon,td span.icon svg rect,td span.icon svg circle,p span.icon svg path,p span.icon svg polygon,p span.icon svg rect,p span.icon svg circle{fill:#B3BCC1}td span.icon,p span.icon{width:0.8em;height:0.8em}td span.icon,p span.icon{margin:0 3px}a.member_link{margin-right:7px;white-space:nowrap}a.button,a:link.button,a:visited.button,input[type=submit],input[type=button],button{border-radius:200px;display:inline-block;font-weight:bold;font-size:1.0em;font-family:Helvetica, Arial, sans-serif;line-height:12px;margin-right:3px;padding:7px 16px 6px;text-decoration:none;background-color:#838a90;background-image:linear-gradient(180deg, #838a90, #414549);text-shadow:#000 0 1px 0;box-shadow:0 1px 1px rgba(0,0,0,0.1),0 1px 0 0px rgba(255,255,255,0.2) inset;border:solid 1px #484e53;border-color:#484e53;border-top-color:#616a71;border-right-color:#484e53;border-bottom-color:#363b3f;border-left-color:#484e53;color:#efefef}a.button.disabled,a:link.button.disabled,a:visited.button.disabled,input[type=submit].disabled,input[type=button].disabled,button.disabled{opacity:0.5;cursor:default}a.button:not(.disabled):hover,a:link.button:not(.disabled):hover,a:visited.button:not(.disabled):hover,input[type=submit]:not(.disabled):hover,input[type=button]:not(.disabled):hover,button:not(.disabled):hover{background-color:#8b9297;background-image:linear-gradient(180deg, #8b9297, #484d51)}a.button:not(.disabled):active,a:link.button:not(.disabled):active,a:visited.button:not(.disabled):active,input[type=submit]:not(.disabled):active,input[type=button]:not(.disabled):active,button:not(.disabled):active{box-shadow:0 1px 3px rgba(0,0,0,0.4) inset,0 1px 0 0px #FFF;background-color:#71797f;background-image:linear-gradient(180deg, #71797f, #35383b)}table.index_grid td{border:none;background:none;padding:0 20px 20px 0;margin:0}.columns{clear:both;padding:0}.columns .column{float:left}a,a:link,a:visited{color:#38678b;text-decoration:underline}a:hover{text-decoration:none}.paginated_collection_contents{clear:both}.pagination{float:right;font-size:0.9em;margin-left:10px}.pagination a{border-radius:200px;display:inline-block;font-weight:bold;font-size:1.0em;font-family:Helvetica, Arial, sans-serif;line-height:12px;margin-right:3px;padding:7px 16px 6px;text-decoration:none;background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #E7E7E7);box-shadow:0 1px 1px rgba(0,0,0,0.1),0 1px 0 0 rgba(255,255,255,0.8) inset;border:solid 1px #c7c7c7;border-color:#c7c7c7;border-top-color:#d3d3d3;border-right-color:#c7c7c7;border-bottom-color:#c2c2c2;border-left-color:#c7c7c7;text-shadow:#fff 0 1px 0;color:#5E6469}.pagination a.disabled{opacity:0.5;cursor:default}.pagination a:not(.disabled):hover{background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #F1F1F1)}.pagination a:not(.disabled):active{box-shadow:0 1px 2px rgba(0,0,0,0.22) inset,0 1px 0 0px #EEE;border-color:#b9b9b9;border-top-color:#c2c2c2;border-right-color:#b9b9b9;border-bottom-color:#b7b7b7;border-left-color:#b9b9b9;background-color:#F3F3F3;background-image:linear-gradient(180deg, #F3F3F3, #D8D8D8)}.pagination span.page.current{border-radius:200px;display:inline-block;font-weight:bold;font-size:1.0em;font-family:Helvetica, Arial, sans-serif;line-height:12px;margin-right:3px;padding:7px 16px 6px;text-decoration:none;background-color:#838a90;background-image:linear-gradient(180deg, #838a90, #414549);text-shadow:#000 0 1px 0;box-shadow:0 1px 1px rgba(0,0,0,0.1),0 1px 0 0px rgba(255,255,255,0.2) inset;border:solid 1px #484e53;border-color:#484e53;border-top-color:#616a71;border-right-color:#484e53;border-bottom-color:#363b3f;border-left-color:#484e53;color:#efefef}.pagination span.page.current.disabled{opacity:0.5;cursor:default}.pagination span.page.current:not(.disabled):hover{background-color:#8b9297;background-image:linear-gradient(180deg, #8b9297, #484d51)}.pagination span.page.current:not(.disabled):active{box-shadow:0 1px 3px rgba(0,0,0,0.4) inset,0 1px 0 0px #FFF;background-color:#71797f;background-image:linear-gradient(180deg, #71797f, #35383b)}.pagination a,.pagination span.page.current{border-radius:0px;margin-right:4px;padding:2px 5px}.pagination_information{float:right;margin-bottom:5px;color:#b3bcc1}.pagination_information b{color:#5c6469}.download_links{float:left}.pagination_per_page{float:right;margin-left:4px}.pagination_per_page select{border-radius:200px;display:inline-block;font-weight:bold;font-size:1.0em;font-family:Helvetica, Arial, sans-serif;line-height:12px;margin-right:3px;padding:7px 16px 6px;text-decoration:none;background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #E7E7E7);box-shadow:0 1px 1px rgba(0,0,0,0.1),0 1px 0 0 rgba(255,255,255,0.8) inset;border:solid 1px #c7c7c7;border-color:#c7c7c7;border-top-color:#d3d3d3;border-right-color:#c7c7c7;border-bottom-color:#c2c2c2;border-left-color:#c7c7c7;text-shadow:#fff 0 1px 0;color:#5E6469;border-radius:0px;padding:1px 5px}.pagination_per_page select.disabled{opacity:0.5;cursor:default}.pagination_per_page select:not(.disabled):hover{background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #F1F1F1)}.pagination_per_page select:not(.disabled):active{box-shadow:0 1px 2px rgba(0,0,0,0.22) inset,0 1px 0 0px #EEE;border-color:#b9b9b9;border-top-color:#c2c2c2;border-right-color:#b9b9b9;border-bottom-color:#b7b7b7;border-left-color:#b9b9b9;background-color:#F3F3F3;background-image:linear-gradient(180deg, #F3F3F3, #D8D8D8)}.section,.panel{background:#f4f4f4;border-radius:4px;box-shadow:inset 0 1px 4px #ddd;margin-bottom:20px}.section>h3,.panel>h3{background-color:#efefef;background-image:linear-gradient(180deg, #efefef, #dfe1e2);text-shadow:#fff 0 1px 0;border:solid 1px #cdcdcd;border-color:#d4d4d4;border-top-color:#e6e6e6;border-right-color:#d4d4d4;border-bottom-color:#cdcdcd;border-left-color:#d4d4d4;box-shadow:0 1px 3px rgba(0,0,0,0.12),0 0 1px #FFF inset;font-size:1em;font-weight:bold;line-height:18px;margin-bottom:0.5em;color:#5E6469;padding:5px 10px 3px 10px}.section>h3 span.icon svg path,.section>h3 span.icon svg polygon,.section>h3 span.icon svg rect,.section>h3 span.icon svg circle,.panel>h3 span.icon svg path,.panel>h3 span.icon svg polygon,.panel>h3 span.icon svg rect,.panel>h3 span.icon svg circle{fill:#5E6469}.section>h3 span.icon,.panel>h3 span.icon{width:1em;height:1em}.section>h3 .header_action,.panel>h3 .header_action{float:right}.section>div,.panel>div{padding:3px 15px 15px 15px}.section hr,.panel hr{border:none;border-bottom:1px solid #E8E8E8}.sidebar_section{background:#f4f4f4;border-radius:4px;box-shadow:inset 0 1px 4px #ddd;margin-bottom:20px}.sidebar_section>h3{background-color:#efefef;background-image:linear-gradient(180deg, #efefef, #dfe1e2);text-shadow:#fff 0 1px 0;border:solid 1px #cdcdcd;border-color:#d4d4d4;border-top-color:#e6e6e6;border-right-color:#d4d4d4;border-bottom-color:#cdcdcd;border-left-color:#d4d4d4;box-shadow:0 1px 3px rgba(0,0,0,0.12),0 0 1px #FFF inset;font-size:1em;font-weight:bold;line-height:18px;margin-bottom:0.5em;color:#5E6469;padding:5px 10px 3px 10px}.sidebar_section>h3 span.icon svg path,.sidebar_section>h3 span.icon svg polygon,.sidebar_section>h3 span.icon svg rect,.sidebar_section>h3 span.icon svg circle{fill:#5E6469}.sidebar_section>h3 span.icon{width:1em;height:1em}.sidebar_section>h3 .header_action{float:right}.sidebar_section>div{padding:3px 15px 15px 15px}.sidebar_section hr{border:none;border-bottom:1px solid #E8E8E8}.columns{margin-bottom:10px}.scopes li .count{color:#8e979e;font-weight:normal;font-size:0.9em;line-height:10px}.status_tag{background:#cacaca;color:#fff;text-transform:uppercase;letter-spacing:0.15em;padding:3px 5px 2px 5px;font-size:0.8em}.status_tag.ok,.status_tag.published,.status_tag.complete,.status_tag.completed,.status_tag.green{background:#8daa92}.status_tag.warn,.status_tag.warning,.status_tag.orange{background:#e29b20}.status_tag.error,.status_tag.errored,.status_tag.red{background:#d45f53}.status_tag.yes{background:#6090DB}.status_tag.no{background:grey}.table_tools{margin-bottom:16px}.table_tools::after{clear:both;content:"";display:table}.table_tools .dropdown_menu{float:left}a.table_tools_button,.table_tools .dropdown_menu_button{border-radius:200px;display:inline-block;font-weight:bold;font-size:1.0em;font-family:Helvetica, Arial, sans-serif;line-height:12px;margin-right:3px;padding:7px 16px 6px;text-decoration:none;background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #E7E7E7);box-shadow:0 1px 1px rgba(0,0,0,0.1),0 1px 0 0 rgba(255,255,255,0.8) inset;border:solid 1px #c7c7c7;border-color:#c7c7c7;border-top-color:#d3d3d3;border-right-color:#c7c7c7;border-bottom-color:#c2c2c2;border-left-color:#c7c7c7;text-shadow:#fff 0 1px 0;color:#5E6469;background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #F0F0F0);border-color:#d0d0d0;border-top-color:#d9d9d9;border-right-color:#d0d0d0;border-bottom-color:#c5c5c5;border-left-color:#d0d0d0;font-size:0.9em;padding:4px 14px 4px;margin:0}a.table_tools_button.disabled,.table_tools .dropdown_menu_button.disabled{opacity:0.5;cursor:default}a.table_tools_button:not(.disabled):hover,.table_tools .dropdown_menu_button:not(.disabled):hover{background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #F1F1F1)}a.table_tools_button:not(.disabled):active,.table_tools .dropdown_menu_button:not(.disabled):active{box-shadow:0 1px 2px rgba(0,0,0,0.22) inset,0 1px 0 0px #EEE;border-color:#b9b9b9;border-top-color:#c2c2c2;border-right-color:#b9b9b9;border-bottom-color:#b7b7b7;border-left-color:#b9b9b9;background-color:#F3F3F3;background-image:linear-gradient(180deg, #F3F3F3, #D8D8D8)}a.table_tools_button:not(.disabled):hover,.table_tools .dropdown_menu_button:not(.disabled):hover{background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #F6F6F6)}a.table_tools_button:not(.disabled):active,.table_tools .dropdown_menu_button:not(.disabled):active{border-color:#c8c8c8;border-top-color:#d7d7d7;border-right-color:#c8c8c8;border-bottom-color:#c3c3c3;border-left-color:#c8c8c8;box-shadow:0 1px 1px 0 rgba(0,0,0,0.17) inset;background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #E8E8E8)}.table_tools_segmented_control{list-style-type:none;padding:0;margin:0}.table_tools_segmented_control li{float:left}.table_tools_segmented_control li a{border-width:1px .5px 1px .5px;border-radius:0}.table_tools_segmented_control li:first-child a{border-left-width:1px;border-top-left-radius:12px;border-bottom-left-radius:12px}.table_tools_segmented_control li:last-child a{border-right-width:1px;border-top-right-radius:12px;border-bottom-right-radius:12px}.table_tools_segmented_control li.selected a{background-color:#F0F0F0;background-image:linear-gradient(180deg, #F0F0F0, #FDFDFD);box-shadow:0 1px 1px 0 rgba(0,0,0,0.1) inset;cursor:default}.table_tools_segmented_control li.selected a:hover{background-color:#F0F0F0;background-image:linear-gradient(180deg, #F0F0F0, #FDFDFD)}.indexes{float:right}.indexes li .count{color:#8e979e;font-weight:normal;font-size:0.9em;line-height:10px}.unsupported_browser{padding:10px 30px;color:#211e14;background-color:#fae692;background-color:#feefae;background-image:linear-gradient(180deg, #feefae, #fae692);border-bottom:1px solid #b3a569}.unsupported_browser h1{font-size:13px;font-weight:bold}.unsupported_browser p{margin-bottom:0.5em}.ui-tabs-nav{list-style:none;display:block;width:auto;margin-bottom:-12px;padding-left:0;overflow:auto;margin-left:15px}.ui-tabs-nav li{display:block;position:relative;margin:0;padding:0;float:left}.ui-tabs-nav li:first-child a{border-left-width:1px;border-top-left-radius:12px;border-bottom-left-radius:12px}.ui-tabs-nav li:last-child a{border-right-width:1px;border-top-right-radius:12px;border-bottom-right-radius:12px}.ui-tabs-nav li a{border-radius:200px;display:inline-block;font-weight:bold;font-size:1.0em;font-family:Helvetica, Arial, sans-serif;line-height:12px;margin-right:3px;padding:7px 16px 6px;text-decoration:none;background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #E7E7E7);box-shadow:0 1px 1px rgba(0,0,0,0.1),0 1px 0 0 rgba(255,255,255,0.8) inset;border:solid 1px #c7c7c7;border-color:#c7c7c7;border-top-color:#d3d3d3;border-right-color:#c7c7c7;border-bottom-color:#c2c2c2;border-left-color:#c7c7c7;text-shadow:#fff 0 1px 0;color:#5E6469;background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #F0F0F0);border-color:#d0d0d0;border-top-color:#d9d9d9;border-right-color:#d0d0d0;border-bottom-color:#c5c5c5;border-left-color:#d0d0d0;text-decoration:none;border-radius:0;border-width:1px .5px 1px .5px;margin-right:0;padding:4px 14px 4px}.ui-tabs-nav li a.disabled{opacity:0.5;cursor:default}.ui-tabs-nav li a:not(.disabled):hover{background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #F1F1F1)}.ui-tabs-nav li a:not(.disabled):active{box-shadow:0 1px 2px rgba(0,0,0,0.22) inset,0 1px 0 0px #EEE;border-color:#b9b9b9;border-top-color:#c2c2c2;border-right-color:#b9b9b9;border-bottom-color:#b7b7b7;border-left-color:#b9b9b9;background-color:#F3F3F3;background-image:linear-gradient(180deg, #F3F3F3, #D8D8D8)}.ui-tabs-nav li a:not(.disabled):hover{background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #F6F6F6)}.ui-tabs-nav li.ui-tabs-active a{cursor:default;background-color:#F0F0F0;background-image:linear-gradient(180deg, #F0F0F0, #FDFDFD);box-shadow:0 1px 1px 0 rgba(0,0,0,0.1) inset}.ui-tabs-nav li.ui-tabs-active a a:hover{background-color:#F0F0F0;background-image:linear-gradient(180deg, #F0F0F0, #FDFDFD)}.tab-content{border:1px solid #D3D3D3;padding:15px;padding-top:30px;text-align:left}body.logged_out{background:#e8e9ea}body.logged_out #content_wrapper{width:500px;margin:70px auto}body.logged_out #content_wrapper #active_admin_content{box-shadow:0 1px 2px rgba(0,0,0,0.37);background:#fff;padding:13px 30px}body.logged_out h2{background-color:#efefef;background-image:linear-gradient(180deg, #efefef, #dfe1e2);text-shadow:#fff 0 1px 0;border:solid 1px #cdcdcd;border-color:#d4d4d4;border-top-color:#e6e6e6;border-right-color:#d4d4d4;border-bottom-color:#cdcdcd;border-left-color:#d4d4d4;box-shadow:0 1px 3px rgba(0,0,0,0.12),0 0 1px #FFF inset;font-size:1em;font-weight:bold;line-height:18px;margin-bottom:0.5em;color:#5E6469;padding:5px 10px 3px 10px;background-color:#6a7176;background-image:linear-gradient(180deg, #6a7176, #4d5256);border-bottom:1px solid #44484b;text-shadow:#000 0 1px 0;box-shadow:0 1px 3px rgba(0,0,0,0.3);border:none;color:#fff;margin:-13px -30px 20px -30px}body.logged_out h2 span.icon svg path,body.logged_out h2 span.icon svg polygon,body.logged_out h2 span.icon svg rect,body.logged_out h2 span.icon svg circle{fill:#5E6469}body.logged_out h2 span.icon{width:1em;height:1em}body.logged_out #login form fieldset{box-shadow:none;background:none;padding:0;margin-bottom:0}body.logged_out #login form fieldset li{padding:10px 0}body.logged_out #login form fieldset input[type=text],body.logged_out #login form fieldset input[type=email],body.logged_out #login form fieldset input[type=password]{width:70%}body.logged_out #login form fieldset.buttons{margin-left:20%}body.logged_out #login a{float:right;margin-top:-32px}#footer{padding:30px 30px;font-size:0.8em;clear:both}#footer p{padding-top:10px}#index_footer{padding-top:5px;text-align:right;font-size:0.85em}.index_content{clear:both}#wrapper{width:100%}.index #wrapper{display:table}#active_admin_content{margin:0;padding:30px}#active_admin_content #main_content_wrapper{float:left;width:100%}#active_admin_content #main_content_wrapper #main_content{margin-right:300px}#active_admin_content.without_sidebar #main_content_wrapper #main_content{margin-right:0}#active_admin_content #sidebar{float:left;width:270px;margin-left:-270px}#title_bar{background-color:#efefef;background-image:linear-gradient(180deg, #efefef, #dfe1e2);text-shadow:#fff 0 1px 0;border:solid 1px #cdcdcd;border-color:#d4d4d4;border-top-color:#e6e6e6;border-right-color:#d4d4d4;border-bottom-color:#cdcdcd;border-left-color:#d4d4d4;box-shadow:0 1px 3px rgba(0,0,0,0.12),0 0 1px #FFF inset;font-size:1em;font-weight:bold;line-height:18px;margin-bottom:0.5em;color:#5E6469;padding:5px 10px 3px 10px;box-sizing:border-box;box-shadow:0 1px 2px rgba(0,0,0,0.37);display:table;border-bottom-color:#EEE;width:100%;position:relative;margin:0;padding:10px 30px;z-index:800}#title_bar span.icon svg path,#title_bar span.icon svg polygon,#title_bar span.icon svg rect,#title_bar span.icon svg circle{fill:#5E6469}#title_bar span.icon{width:1em;height:1em}#title_bar::after{clear:both;content:"";display:table}#title_bar #titlebar_left,#title_bar #titlebar_right{height:50px;vertical-align:middle;display:table-cell}#title_bar #titlebar_right{text-align:right}#title_bar h2{margin:0;padding:0;font-size:2.6em;line-height:100%;font-weight:bold}#title_bar .action_items span.action_item>a,#title_bar .action_items span.action_item>.dropdown_menu>a{border-radius:200px;display:inline-block;font-weight:bold;font-size:1.0em;font-family:Helvetica, Arial, sans-serif;line-height:12px;margin-right:3px;padding:7px 16px 6px;text-decoration:none;background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #E7E7E7);box-shadow:0 1px 1px rgba(0,0,0,0.1),0 1px 0 0 rgba(255,255,255,0.8) inset;border:solid 1px #c7c7c7;border-color:#c7c7c7;border-top-color:#d3d3d3;border-right-color:#c7c7c7;border-bottom-color:#c2c2c2;border-left-color:#c7c7c7;text-shadow:#fff 0 1px 0;color:#5E6469;padding:12px 17px 10px;margin:0px}#title_bar .action_items span.action_item>a.disabled,#title_bar .action_items span.action_item>.dropdown_menu>a.disabled{opacity:0.5;cursor:default}#title_bar .action_items span.action_item>a:not(.disabled):hover,#title_bar .action_items span.action_item>.dropdown_menu>a:not(.disabled):hover{background-color:#FFFFFF;background-image:linear-gradient(180deg, #fff, #F1F1F1)}#title_bar .action_items span.action_item>a:not(.disabled):active,#title_bar .action_items span.action_item>.dropdown_menu>a:not(.disabled):active{box-shadow:0 1px 2px rgba(0,0,0,0.22) inset,0 1px 0 0px #EEE;border-color:#b9b9b9;border-top-color:#c2c2c2;border-right-color:#b9b9b9;border-bottom-color:#b7b7b7;border-left-color:#b9b9b9;background-color:#F3F3F3;background-image:linear-gradient(180deg, #F3F3F3, #D8D8D8)}#title_bar .action_items span.action_item>a span.icon,#title_bar .action_items span.action_item>.dropdown_menu>a span.icon{vertical-align:bottom;margin-right:4px}#title_bar .action_items span.action_item>a:hover span.icon svg path,#title_bar .action_items span.action_item>a:hover span.icon svg polygon,#title_bar .action_items span.action_item>a:hover span.icon svg rect,#title_bar .action_items span.action_item>a:hover span.icon svg circle,#title_bar .action_items span.action_item>.dropdown_menu>a:hover span.icon svg path,#title_bar .action_items span.action_item>.dropdown_menu>a:hover span.icon svg polygon,#title_bar .action_items span.action_item>.dropdown_menu>a:hover span.icon svg rect,#title_bar .action_items span.action_item>.dropdown_menu>a:hover span.icon svg circle{fill:#000}body{font-family:Helvetica, Arial, sans-serif;line-height:150%;font-size:72%;background:#FFF;margin:0;padding:0;color:#323537}.wmd-panel{margin-left:25%;margin-right:25%;width:76%;display:inline-block}.wmd-button-bar{width:100%;background-color:Silver}.wmd-input{height:300px;width:100% !important}.wmd-preview{background-color:#c0e0ff}.wmd-button-row{position:relative;margin-left:5px;margin-right:5px;margin-bottom:5px;margin-top:10px;padding:0px;height:20px}.wmd-spacer{width:1px;height:20px;margin-left:14px;position:absolute;background-color:Silver;display:inline-block;list-style:none}.wmd-button{width:20px;height:20px;padding-left:2px;padding-right:3px;position:absolute;display:inline-block;list-style:none;cursor:pointer}.wmd-button>span{background-image:url("/assets/active_admin_pagedown/wmd-buttons-c2040b12f2d6cb568ddc33587a070a29a18fed20099260c3ecbbfdbd62042f7b.png");background-repeat:no-repeat;background-position:0px 0px;width:20px;height:20px;display:inline-block}.wmd-spacer1{left:50px}.wmd-spacer2{left:175px}.wmd-spacer3{left:300px}.wmd-preview>ul,.wmd-preview>ol{margin:0 0 10px 25px !important}.wmd-preview>p{margin:0 0 10px !important}.wmd-preview>ul>li{list-style:disc !important}.wmd-prompt-dialog{border:1px solid #999999;background-color:#F5F5F5}/*! + * Font Awesome 4.6.2 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url("../fonts/font-awesome/fontawesome-webfont.eot?v=4.6.2");src:url("../fonts/font-awesome/fontawesome-webfont.eot?v=4.6.2#iefix") format("embedded-opentype"),url("../fonts/font-awesome/fontawesome-webfont.woff2?v=4.6.2") format("woff2"),url("../fonts/font-awesome/fontawesome-webfont.woff?v=4.6.2") format("woff"),url("../fonts/font-awesome/fontawesome-webfont.ttf?v=4.6.2") format("truetype"),url("../fonts/font-awesome/fontawesome-webfont.svg?v=4.6.2#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:0.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:0.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:"ï€"}.fa-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-remove:before,.fa-close:before,.fa-times:before{content:"ï€"}.fa-search-plus:before{content:""}.fa-search-minus:before{content:"ï€"}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:"ï€"}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before{content:"ï€"}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:"ï€"}.fa-map-marker:before{content:"ï"}.fa-adjust:before{content:"ï‚"}.fa-tint:before{content:"ïƒ"}.fa-edit:before,.fa-pencil-square-o:before{content:"ï„"}.fa-share-square-o:before{content:"ï…"}.fa-check-square-o:before{content:"ï†"}.fa-arrows:before{content:"ï‡"}.fa-step-backward:before{content:"ïˆ"}.fa-fast-backward:before{content:"ï‰"}.fa-backward:before{content:"ïŠ"}.fa-play:before{content:"ï‹"}.fa-pause:before{content:"ïŒ"}.fa-stop:before{content:"ï"}.fa-forward:before{content:"ïŽ"}.fa-fast-forward:before{content:"ï"}.fa-step-forward:before{content:"ï‘"}.fa-eject:before{content:"ï’"}.fa-chevron-left:before{content:"ï“"}.fa-chevron-right:before{content:"ï”"}.fa-plus-circle:before{content:"ï•"}.fa-minus-circle:before{content:"ï–"}.fa-times-circle:before{content:"ï—"}.fa-check-circle:before{content:"ï˜"}.fa-question-circle:before{content:"ï™"}.fa-info-circle:before{content:"ïš"}.fa-crosshairs:before{content:"ï›"}.fa-times-circle-o:before{content:"ïœ"}.fa-check-circle-o:before{content:"ï"}.fa-ban:before{content:"ïž"}.fa-arrow-left:before{content:"ï "}.fa-arrow-right:before{content:"ï¡"}.fa-arrow-up:before{content:"ï¢"}.fa-arrow-down:before{content:"ï£"}.fa-mail-forward:before,.fa-share:before{content:"ï¤"}.fa-expand:before{content:"ï¥"}.fa-compress:before{content:"ï¦"}.fa-plus:before{content:"ï§"}.fa-minus:before{content:"ï¨"}.fa-asterisk:before{content:"ï©"}.fa-exclamation-circle:before{content:"ïª"}.fa-gift:before{content:"ï«"}.fa-leaf:before{content:"ï¬"}.fa-fire:before{content:"ï"}.fa-eye:before{content:"ï®"}.fa-eye-slash:before{content:"ï°"}.fa-warning:before,.fa-exclamation-triangle:before{content:"ï±"}.fa-plane:before{content:"ï²"}.fa-calendar:before{content:"ï³"}.fa-random:before{content:"ï´"}.fa-comment:before{content:"ïµ"}.fa-magnet:before{content:"ï¶"}.fa-chevron-up:before{content:"ï·"}.fa-chevron-down:before{content:"ï¸"}.fa-retweet:before{content:"ï¹"}.fa-shopping-cart:before{content:"ïº"}.fa-folder:before{content:"ï»"}.fa-folder-open:before{content:"ï¼"}.fa-arrows-v:before{content:"ï½"}.fa-arrows-h:before{content:"ï¾"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"ï‚€"}.fa-twitter-square:before{content:"ï‚"}.fa-facebook-square:before{content:"ï‚‚"}.fa-camera-retro:before{content:""}.fa-key:before{content:"ï‚„"}.fa-gears:before,.fa-cogs:before{content:"ï‚…"}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:"ï‚Š"}.fa-sign-out:before{content:"ï‚‹"}.fa-linkedin-square:before{content:"ï‚Œ"}.fa-thumb-tack:before{content:"ï‚"}.fa-external-link:before{content:"ï‚Ž"}.fa-sign-in:before{content:"ï‚"}.fa-trophy:before{content:"ï‚‘"}.fa-github-square:before{content:"ï‚’"}.fa-upload:before{content:"ï‚“"}.fa-lemon-o:before{content:"ï‚”"}.fa-phone:before{content:"ï‚•"}.fa-square-o:before{content:"ï‚–"}.fa-bookmark-o:before{content:"ï‚—"}.fa-phone-square:before{content:""}.fa-twitter:before{content:"ï‚™"}.fa-facebook-f:before,.fa-facebook:before{content:"ï‚š"}.fa-github:before{content:"ï‚›"}.fa-unlock:before{content:"ï‚œ"}.fa-credit-card:before{content:"ï‚"}.fa-feed:before,.fa-rss:before{content:"ï‚ž"}.fa-hdd-o:before{content:"ï‚ "}.fa-bullhorn:before{content:"ï‚¡"}.fa-bell:before{content:""}.fa-certificate:before{content:"ï‚£"}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:"ï‚¥"}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before{content:""}.fa-arrow-circle-right:before{content:"ï‚©"}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:"ï‚«"}.fa-globe:before{content:""}.fa-wrench:before{content:"ï‚"}.fa-tasks:before{content:"ï‚®"}.fa-filter:before{content:"ï‚°"}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before{content:"ïƒ"}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:"ïƒ"}.fa-table:before{content:""}.fa-magic:before{content:"ïƒ"}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:"ïƒ"}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:"ïƒ "}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:"ïƒ"}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:"ï‚¢"}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:"ï„€"}.fa-angle-double-right:before{content:"ï„"}.fa-angle-double-up:before{content:"ï„‚"}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:"ï„„"}.fa-angle-right:before{content:"ï„…"}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:"ï„Š"}.fa-mobile-phone:before,.fa-mobile:before{content:"ï„‹"}.fa-circle-o:before{content:"ï„Œ"}.fa-quote-left:before{content:"ï„"}.fa-quote-right:before{content:"ï„Ž"}.fa-spinner:before{content:"ï„"}.fa-circle:before{content:"ï„‘"}.fa-mail-reply:before,.fa-reply:before{content:"ï„’"}.fa-github-alt:before{content:"ï„“"}.fa-folder-o:before{content:"ï„”"}.fa-folder-open-o:before{content:"ï„•"}.fa-smile-o:before{content:""}.fa-frown-o:before{content:"ï„™"}.fa-meh-o:before{content:"ï„š"}.fa-gamepad:before{content:"ï„›"}.fa-keyboard-o:before{content:"ï„œ"}.fa-flag-o:before{content:"ï„"}.fa-flag-checkered:before{content:"ï„ž"}.fa-terminal:before{content:"ï„ "}.fa-code:before{content:"ï„¡"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"ï„¢"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"ï„£"}.fa-location-arrow:before{content:""}.fa-crop:before{content:"ï„¥"}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:"ï„©"}.fa-exclamation:before{content:""}.fa-superscript:before{content:"ï„«"}.fa-subscript:before{content:""}.fa-eraser:before{content:"ï„"}.fa-puzzle-piece:before{content:"ï„®"}.fa-microphone:before{content:"ï„°"}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:"ï„´"}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:"ï„·"}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:"ï„»"}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:"ï…€"}.fa-ellipsis-h:before{content:"ï…"}.fa-ellipsis-v:before{content:"ï…‚"}.fa-rss-square:before{content:"ï…ƒ"}.fa-play-circle:before{content:"ï…„"}.fa-ticket:before{content:"ï……"}.fa-minus-square:before{content:"ï…†"}.fa-minus-square-o:before{content:"ï…‡"}.fa-level-up:before{content:"ï…ˆ"}.fa-level-down:before{content:"ï…‰"}.fa-check-square:before{content:"ï…Š"}.fa-pencil-square:before{content:"ï…‹"}.fa-external-link-square:before{content:"ï…Œ"}.fa-share-square:before{content:"ï…"}.fa-compass:before{content:"ï…Ž"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"ï…"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"ï…‘"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"ï…’"}.fa-euro:before,.fa-eur:before{content:"ï…“"}.fa-gbp:before{content:"ï…”"}.fa-dollar:before,.fa-usd:before{content:"ï…•"}.fa-rupee:before,.fa-inr:before{content:"ï…–"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"ï…—"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"ï…˜"}.fa-won:before,.fa-krw:before{content:"ï…™"}.fa-bitcoin:before,.fa-btc:before{content:"ï…š"}.fa-file:before{content:"ï…›"}.fa-file-text:before{content:"ï…œ"}.fa-sort-alpha-asc:before{content:"ï…"}.fa-sort-alpha-desc:before{content:"ï…ž"}.fa-sort-amount-asc:before{content:"ï… "}.fa-sort-amount-desc:before{content:"ï…¡"}.fa-sort-numeric-asc:before{content:"ï…¢"}.fa-sort-numeric-desc:before{content:"ï…£"}.fa-thumbs-up:before{content:"ï…¤"}.fa-thumbs-down:before{content:"ï…¥"}.fa-youtube-square:before{content:"ï…¦"}.fa-youtube:before{content:"ï…§"}.fa-xing:before{content:"ï…¨"}.fa-xing-square:before{content:"ï…©"}.fa-youtube-play:before{content:"ï…ª"}.fa-dropbox:before{content:"ï…«"}.fa-stack-overflow:before{content:"ï…¬"}.fa-instagram:before{content:"ï…"}.fa-flickr:before{content:"ï…®"}.fa-adn:before{content:"ï…°"}.fa-bitbucket:before{content:"ï…±"}.fa-bitbucket-square:before{content:"ï…²"}.fa-tumblr:before{content:"ï…³"}.fa-tumblr-square:before{content:"ï…´"}.fa-long-arrow-down:before{content:"ï…µ"}.fa-long-arrow-up:before{content:"ï…¶"}.fa-long-arrow-left:before{content:"ï…·"}.fa-long-arrow-right:before{content:"ï…¸"}.fa-apple:before{content:"ï…¹"}.fa-windows:before{content:"ï…º"}.fa-android:before{content:"ï…»"}.fa-linux:before{content:"ï…¼"}.fa-dribbble:before{content:"ï…½"}.fa-skype:before{content:"ï…¾"}.fa-foursquare:before{content:""}.fa-trello:before{content:"ï†"}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:"ï†"}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:"ï†"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:"ï†"}.fa-yahoo:before{content:""}.fa-google:before{content:"ï† "}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:"ï†"}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:"ï‡"}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"ï‡"}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"ï‡"}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:"ï‡"}.fa-sliders:before{content:""}.fa-share-alt:before{content:"ï‡ "}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:"ï‡"}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:"ïˆ"}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:"ïˆ"}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:"ïˆ"}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:"ïˆ"}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:"ïˆ"}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-hotel:before,.fa-bed:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-yc:before,.fa-y-combinator:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"ï‰"}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:"ï‰"}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:"ï‰"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:"ï‰"}.fa-creative-commons:before{content:""}.fa-gg:before{content:"ï‰ "}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-tv:before,.fa-television:before{content:""}.fa-contao:before{content:"ï‰"}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:"ïŠ"}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:"ïŠ"}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:"ïŠ"}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:"ïŠ"}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:"ïŠ "}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:""}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-signing:before,.fa-sign-language:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:"ïŠ"}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.quantity{text-align:right !important;white-space:nowrap}table{margin:1em auto;border-spacing:2px}table th{padding:0.3em 0.6em}table.list tbody tr:nth-child(odd){background-color:#D1EAFF}table.list tbody tr:nth-child(even){background-color:#C9E2F5}table.list th{font-size:larger}table.list td{padding:0.2em;text-align:left}table.list td.updated_at{text-align:center}dl{margin:1em auto;max-width:40em}dl dt{clear:left;float:left;padding:0.2em 1em;min-width:50%;text-align:right}dl dd{padding:0.2em 1em;text-align:left}dl dd.quantity{padding-right:16em}dl dd h3{display:inline}dl dt+dd+dt+dd{border-top:1px solid #999}ul.counters{text-align:center}ul.counters li{display:inline}ul.counters li a:link,ul.counters li a:visited{color:white;display:inline-block;padding:0.2em 0.8em;background-color:darkblue;-moz-border-radius:1em;-webkit-border-radius:1em;border-radius:1em}.edit_link:link,.delete_link:link{display:none}.wmd-panel{padding:1em;margin-left:0;margin-right:0} diff --git a/public/assets/active_admin-5f05779513d42df8ed807ee625244d8e144534286b6c72cecee9151938308901.css.gz b/public/assets/active_admin-5f05779513d42df8ed807ee625244d8e144534286b6c72cecee9151938308901.css.gz new file mode 100644 index 0000000000000000000000000000000000000000..0210cd2b1952f60bd42e510db9f12beef904bac5 GIT binary patch literal 15301 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 X+M`^y{`{tW@OS?Yylt?*EkywU?3{xL literal 0 HcmV?d00001 diff --git a/public/assets/active_admin-716bc3a1c121d8ebdfc555d143e5f535aff487ef907952790491e39e34688a2f.js b/public/assets/active_admin-716bc3a1c121d8ebdfc555d143e5f535aff487ef907952790491e39e34688a2f.js new file mode 100644 index 000000000..a81342e78 --- /dev/null +++ b/public/assets/active_admin-716bc3a1c121d8ebdfc555d143e5f535aff487ef907952790491e39e34688a2f.js @@ -0,0 +1,24677 @@ +/*! + * jQuery JavaScript Library v1.11.3 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2015-04-28T16:19Z + */ + + +(function( global, factory ) { + + if ( typeof module === "object" && typeof module.exports === "object" ) { + // For CommonJS and CommonJS-like environments where a proper window is present, + // execute the factory and get jQuery + // For environments that do not inherently posses a window with a document + // (such as Node.js), expose a jQuery-making factory as module.exports + // This accentuates the need for the creation of a real window + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Can't do this because several apps including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// Support: Firefox 18+ +// + +var deletedIds = []; + +var slice = deletedIds.slice; + +var concat = deletedIds.concat; + +var push = deletedIds.push; + +var indexOf = deletedIds.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var support = {}; + + + +var + version = "1.11.3", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android<4.1, IE<9 + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num != null ? + + // Return just the one element from the set + ( num < 0 ? this[ num + this.length ] : this[ num ] ) : + + // Return all the elements in a clean array + slice.call( this ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: deletedIds.sort, + splice: deletedIds.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var src, copyIsArray, copy, name, options, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + /* jshint eqeqeq: false */ + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + // parseFloat NaNs numeric-cast false positives (null|true|false|"") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + // adding 1 corrects loss of precision from parseFloat (#15100) + return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0; + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + isPlainObject: function( obj ) { + var key; + + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Support: IE<9 + // Handle iteration over inherited properties before own properties. + if ( support.ownLast ) { + for ( key in obj ) { + return hasOwn.call( obj, key ); + } + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call(obj) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && jQuery.trim( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + // Support: Android<4.1, IE<9 + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArraylike( Object(arr) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( indexOf ) { + return indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + while ( j < len ) { + first[ i++ ] = second[ j++ ]; + } + + // Support: IE<9 + // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists) + if ( len !== len ) { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var args, proxy, tmp; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: function() { + return +( new Date() ); + }, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + + // Support: iOS 8.2 (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = "length" in obj && obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.2.0-pre + * http://sizzlejs.com/ + * + * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-12-16 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // General-purpose constants + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // http://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + characterEncoding + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + nodeType = context.nodeType; + + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + if ( !seed && documentIsHTML ) { + + // Try to shortcut find operations when possible (e.g., not under DocumentFragment) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document (jQuery #6963) + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType !== 1 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, parent, + doc = node ? node.ownerDocument || node : preferredDoc; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + parent = doc.defaultView; + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent !== parent.top ) { + // IE11 does not have attachEvent, so all must suffer + if ( parent.addEventListener ) { + parent.addEventListener( "unload", unloadHandler, false ); + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", unloadHandler ); + } + } + + /* Support tests + ---------------------------------------------------------------------- */ + documentIsHTML = !isXML( doc ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( doc.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [ m ] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" + + "<select id='" + expando + "-\f]' msallowcapture=''>" + + "<option selected=''></option></select>"; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( div.querySelectorAll("[msallowcapture^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+ + if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push("~="); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibing-combinator selector` fails + if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push(".#.+[+~]"); + } + }); + + assert(function( div ) { + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( div.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch (e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + // Don't keep the element (issue #299) + input[0] = null; + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (oldCache = outerCache[ dir ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + outerCache[ dir ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context !== document && context; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is no seed and only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = "<a href='#'></a>"; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = "<input/>"; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + + +var rneedsContext = jQuery.expr.match.needsContext; + +var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not; + }); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); +}; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + ret = [], + self = this, + len = self.length; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + filter: function( selector ) { + return this.pushStack( winnow(this, selector || [], false) ); + }, + not: function( selector ) { + return this.pushStack( winnow(this, selector || [], true) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +}); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + + // A simple way to check for HTML strings + // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + init = jQuery.fn.init = function( selector, context ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return typeof rootjQuery.ready !== "undefined" ? + rootjQuery.ready( selector ) : + // Execute immediately if ready is not present + selector( jQuery ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.extend({ + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +jQuery.fn.extend({ + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments + if ( cur.nodeType < 11 && (pos ? + pos.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector(cur, selectors)) ) { + + matched.push( cur ); + break; + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.unique( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + if ( this.length > 1 ) { + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + ret = jQuery.unique( ret ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + } + + return this.pushStack( ret ); + }; +}); +var rnotwhite = (/\S+/g); + + + +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // First callback to fire (used internally by add and fireWith) + firingStart, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + firingLength = 0; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( list && ( !fired || stack ) ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( values === progressValues ) { + deferred.notifyWith( contexts, values ); + + } else if ( !(--remaining) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); + + +// The deferred used on DOM ready +var readyList; + +jQuery.fn.ready = function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; +}; + +jQuery.extend({ + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.triggerHandler ) { + jQuery( document ).triggerHandler( "ready" ); + jQuery( document ).off( "ready" ); + } + } +}); + +/** + * Clean-up method for dom ready events + */ +function detach() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + + } else { + document.detachEvent( "onreadystatechange", completed ); + window.detachEvent( "onload", completed ); + } +} + +/** + * The ready event handler and self cleanup method + */ +function completed() { + // readyState === "complete" is good enough for us to call the dom ready in oldIE + if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { + detach(); + jQuery.ready(); + } +} + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", completed ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", completed ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // detach all dom ready events + detach(); + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + + +var strundefined = typeof undefined; + + + +// Support: IE<9 +// Iteration over object's inherited properties before its own +var i; +for ( i in jQuery( support ) ) { + break; +} +support.ownLast = i !== "0"; + +// Note: most support tests are defined in their respective modules. +// false until the test is run +support.inlineBlockNeedsLayout = false; + +// Execute ASAP in case we need to set body.style.zoom +jQuery(function() { + // Minified: var a,b,c,d + var val, div, body, container; + + body = document.getElementsByTagName( "body" )[ 0 ]; + if ( !body || !body.style ) { + // Return for frameset docs that don't have a body + return; + } + + // Setup + div = document.createElement( "div" ); + container = document.createElement( "div" ); + container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; + body.appendChild( container ).appendChild( div ); + + if ( typeof div.style.zoom !== strundefined ) { + // Support: IE<8 + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1"; + + support.inlineBlockNeedsLayout = val = div.offsetWidth === 3; + if ( val ) { + // Prevent IE 6 from affecting layout for positioned elements #11048 + // Prevent IE from shrinking the body in IE 7 mode #12869 + // Support: IE<8 + body.style.zoom = 1; + } + } + + body.removeChild( container ); +}); + + + + +(function() { + var div = document.createElement( "div" ); + + // Execute the test only if not already executed in another module. + if (support.deleteExpando == null) { + // Support: IE<9 + support.deleteExpando = true; + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + } + + // Null elements to avoid leaks in IE. + div = null; +})(); + + +/** + * Determines whether an object can have data + */ +jQuery.acceptData = function( elem ) { + var noData = jQuery.noData[ (elem.nodeName + " ").toLowerCase() ], + nodeType = +elem.nodeType || 1; + + // Do not set data on non-element DOM nodes because it will not be cleared (#8335). + return nodeType !== 1 && nodeType !== 9 ? + false : + + // Nodes accept data unless otherwise specified; rejection can be conditional + !noData || noData !== true && elem.getAttribute("classid") === noData; +}; + + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /([A-Z])/g; + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + +function internalData( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var ret, thisCache, + internalKey = jQuery.expando, + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + // Avoid exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + cache[ id ] = isNode ? {} : { toJSON: jQuery.noop }; + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( typeof name === "string" ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; +} + +function internalRemoveData( elem, name, pvt ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } else { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = name.concat( jQuery.map( name, jQuery.camelCase ) ); + } + + i = name.length; + while ( i-- ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + /* jshint eqeqeq: false */ + } else if ( support.deleteExpando || cache != cache.window ) { + /* jshint eqeqeq: true */ + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = null; + } +} + +jQuery.extend({ + cache: {}, + + // The following elements (space-suffixed to avoid Object.prototype collisions) + // throw uncatchable exceptions if you attempt to set expando properties + noData: { + "applet ": true, + "embed ": true, + // ...but Flash objects (which have this classid) *can* handle expandos + "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data ) { + return internalData( elem, name, data ); + }, + + removeData: function( elem, name ) { + return internalRemoveData( elem, name ); + }, + + // For internal use only. + _data: function( elem, name, data ) { + return internalData( elem, name, data, true ); + }, + + _removeData: function( elem, name ) { + return internalRemoveData( elem, name, true ); + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var i, name, data, + elem = this[0], + attrs = elem && elem.attributes; + + // Special expections of .data basically thwart jQuery.access, + // so implement the relevant behavior ourselves + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE11+ + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice(5) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + return arguments.length > 1 ? + + // Sets one value + this.each(function() { + jQuery.data( this, key, value ); + }) : + + // Gets one value + // Try to fetch any internally stored data first + elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined; + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + + +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery._removeData( elem, type + "queue" ); + jQuery._removeData( elem, key ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHidden = function( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); + }; + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + length = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < length; i++ ) { + fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; +}; +var rcheckableType = (/^(?:checkbox|radio)$/i); + + + +(function() { + // Minified: var a,b,c + var input = document.createElement( "input" ), + div = document.createElement( "div" ), + fragment = document.createDocumentFragment(); + + // Setup + div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>"; + + // IE strips leading whitespace when .innerHTML is used + support.leadingWhitespace = div.firstChild.nodeType === 3; + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + support.tbody = !div.getElementsByTagName( "tbody" ).length; + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + support.htmlSerialize = !!div.getElementsByTagName( "link" ).length; + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + support.html5Clone = + document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav></:nav>"; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + input.type = "checkbox"; + input.checked = true; + fragment.appendChild( input ); + support.appendChecked = input.checked; + + // Make sure textarea (and checkbox) defaultValue is properly cloned + // Support: IE6-IE11+ + div.innerHTML = "<textarea>x</textarea>"; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // #11217 - WebKit loses check when the name is after the checked attribute + fragment.appendChild( div ); + div.innerHTML = "<input type='radio' checked='checked' name='t'/>"; + + // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 + // old WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<9 + // Opera does not clone events (and typeof div.attachEvent === undefined). + // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() + support.noCloneEvent = true; + if ( div.attachEvent ) { + div.attachEvent( "onclick", function() { + support.noCloneEvent = false; + }); + + div.cloneNode( true ).click(); + } + + // Execute the test only if not already executed in another module. + if (support.deleteExpando == null) { + // Support: IE<9 + support.deleteExpando = true; + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + } +})(); + + +(function() { + var i, eventName, + div = document.createElement( "div" ); + + // Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event) + for ( i in { submit: true, change: true, focusin: true }) { + eventName = "on" + i; + + if ( !(support[ i + "Bubbles" ] = eventName in window) ) { + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) + div.setAttribute( eventName, "t" ); + support[ i + "Bubbles" ] = div.attributes[ eventName ].expando === false; + } + } + + // Null elements to avoid leaks in IE. + div = null; +})(); + + +var rformElems = /^(?:input|select|textarea)$/i, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + var tmp, events, t, handleObjIn, + special, eventHandle, handleObj, + handlers, type, namespaces, origType, + elemData = jQuery._data( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + var j, handleObj, tmp, + origCount, t, events, + special, handlers, type, + namespaces, origType, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery._removeData( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + var handle, ontype, cur, + bubbleType, special, tmp, i, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && jQuery.acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && + jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + try { + elem[ type ](); + } catch ( e ) { + // IE<9 dies on focus/blur to hidden element (#1486,#12518) + // only reproducible on winXP IE8 native, not IE9 in IE8 mode + } + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, ret, handleObj, matched, j, + handlerQueue = [], + args = slice.call( arguments ), + handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( (event.result = ret) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var sel, handleObj, matches, i, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG <use> instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + /* jshint eqeqeq: false */ + for ( ; cur != this; cur = cur.parentNode || this ) { + /* jshint eqeqeq: true */ + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: IE<9 + // Fix target property (#1925) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Support: Chrome 23+, Safari? + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Support: IE<9 + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) + event.metaKey = !!event.metaKey; + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var body, eventDoc, doc, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + try { + this.focus(); + return false; + } catch ( e ) { + // Support: IE<9 + // If we error on focus to hidden element (#1486, #12518), + // let .trigger() run the handlers + } + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === strundefined ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + // Support: IE < 9, Android < 4.0 + src.returnValue === false ? + returnTrue : + returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + if ( !e ) { + return; + } + + // If preventDefault exists, run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // Support: IE + // Otherwise set the returnValue property of the original event to false + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + if ( !e ) { + return; + } + // If stopPropagation exists, run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + + // Support: IE + // Set the cancelBubble property of the original event to true + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && e.stopImmediatePropagation ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "submitBubbles" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "submitBubbles", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "changeBubbles", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = jQuery._data( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + jQuery._data( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = jQuery._data( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + jQuery._removeData( doc, fix ); + } else { + jQuery._data( doc, fix, attaches ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var type, origFn; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +}); + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /<tbody/i, + rhtml = /<|&#?\w+;/, + rnoInnerhtml = /<(?:script|style|link)/i, + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /^$|\/(?:java|ecma)script/i, + rscriptTypeMasked = /^true\/(.*)/, + rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + option: [ 1, "<select multiple='multiple'>", "</select>" ], + legend: [ 1, "<fieldset>", "</fieldset>" ], + area: [ 1, "<map>", "</map>" ], + param: [ 1, "<object>", "</object>" ], + thead: [ 1, "<table>", "</table>" ], + tr: [ 2, "<table><tbody>", "</tbody></table>" ], + col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ], + td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], + + // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, + // unless wrapped in a div with non-breaking characters in front of it. + _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +function getAll( context, tag ) { + var elems, elem, + i = 0, + found = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || "*" ) : + undefined; + + if ( !found ) { + for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { + if ( !tag || jQuery.nodeName( elem, tag ) ) { + found.push( elem ); + } else { + jQuery.merge( found, getAll( elem, tag ) ); + } + } + } + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], found ) : + found; +} + +// Used in buildFragment, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +// Support: IE<8 +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName("tbody")[0] || + elem.appendChild( elem.ownerDocument.createElement("tbody") ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + if ( match ) { + elem.type = match[1]; + } else { + elem.removeAttribute("type"); + } + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var elem, + i = 0; + for ( ; (elem = elems[i]) != null; i++ ) { + jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) ); + } +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function fixCloneNodeIssues( src, dest ) { + var nodeName, e, data; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + nodeName = dest.nodeName.toLowerCase(); + + // IE6-8 copies events bound via attachEvent when using cloneNode. + if ( !support.noCloneEvent && dest[ jQuery.expando ] ) { + data = jQuery._data( dest ); + + for ( e in data.events ) { + jQuery.removeEvent( dest, e, data.handle ); + } + + // Event data gets referenced instead of copied if the expando gets copied too + dest.removeAttribute( jQuery.expando ); + } + + // IE blanks contents when cloning scripts, and tries to evaluate newly-set text + if ( nodeName === "script" && dest.text !== src.text ) { + disableScript( dest ).text = src.text; + restoreScript( dest ); + + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + } else if ( nodeName === "object" ) { + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.defaultSelected = dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var destElements, node, clone, i, srcElements, + inPage = jQuery.contains( elem.ownerDocument, elem ); + + if ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!support.noCloneEvent || !support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + // Fix all IE cloning issues + for ( i = 0; (node = srcElements[i]) != null; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + fixCloneNodeIssues( node, destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0; (node = srcElements[i]) != null; i++ ) { + cloneCopyEvent( node, destElements[i] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + destElements = srcElements = node = null; + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var j, elem, contains, + tmp, tag, tbody, wrap, + l = elems.length, + + // Ensure a safe fragment + safe = createSafeFragment( context ), + + nodes = [], + i = 0; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || safe.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = (rtagName.exec( elem ) || [ "", "" ])[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + + tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[2]; + + // Descend through wrappers to the right content + j = wrap[0]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Manually add leading whitespace removed by IE + if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); + } + + // Remove IE's autoinserted <tbody> from table fragments + if ( !support.tbody ) { + + // String was a <table>, *may* have spurious <tbody> + elem = tag === "table" && !rtbody.test( elem ) ? + tmp.firstChild : + + // String was a bare <thead> or <tfoot> + wrap[1] === "<table>" && !rtbody.test( elem ) ? + tmp : + 0; + + j = elem && elem.childNodes.length; + while ( j-- ) { + if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) { + elem.removeChild( tbody ); + } + } + } + + jQuery.merge( nodes, tmp.childNodes ); + + // Fix #12392 for WebKit and IE > 9 + tmp.textContent = ""; + + // Fix #12392 for oldIE + while ( tmp.firstChild ) { + tmp.removeChild( tmp.firstChild ); + } + + // Remember the top-level container for proper cleanup + tmp = safe.lastChild; + } + } + } + + // Fix #11356: Clear elements from fragment + if ( tmp ) { + safe.removeChild( tmp ); + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !support.appendChecked ) { + jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); + } + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( safe.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + tmp = null; + + return safe; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var elem, type, id, data, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( typeof elem.removeAttribute !== strundefined ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + deletedIds.push( id ); + } + } + } + } + } +}); + +jQuery.fn.extend({ + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + append: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + remove: function( selector, keepData /* Internal Use Only */ ) { + var elem, + elems = selector ? jQuery.filter( selector, this ) : this, + i = 0; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + + // If this is a select, ensure that it displays empty (#12336) + // Support: IE<9 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) { + elem.options.length = 0; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map(function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1></$2>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var arg = arguments[ 0 ]; + + // Make the changes, replacing each context element with the new content + this.domManip( arguments, function( elem ) { + arg = this.parentNode; + + jQuery.cleanData( getAll( this ) ); + + if ( arg ) { + arg.replaceChild( elem, this ); + } + }); + + // Force removal if there was no new content (e.g., from empty arguments) + return arg && (arg.length || arg.nodeType) ? this : this.remove(); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, callback ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var first, node, hasScripts, + scripts, doc, fragment, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[0], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[0] = value.call( this, index, self.html() ); + } + self.domManip( args, callback ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( this[i], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + } + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + } + } + + return this; + } +}); + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone(true); + jQuery( insert[i] )[ original ]( elems ); + + // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + + +var iframe, + elemdisplay = {}; + +/** + * Retrieve the actual display of a element + * @param {String} name nodeName of the element + * @param {Object} doc Document object + */ +// Called only from within defaultDisplay +function actualDisplay( name, doc ) { + var style, + elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), + + // getDefaultComputedStyle might be reliably used only on attached element + display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? + + // Use of this method is a temporary fix (more like optmization) until something better comes along, + // since it was removed from specification and supported only in FF + style.display : jQuery.css( elem[ 0 ], "display" ); + + // We don't have any data stored on the element, + // so use "detach" method as fast way to get rid of the element + elem.detach(); + + return display; +} + +/** + * Try to determine the default display value of an element + * @param {String} nodeName + */ +function defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + + // Use the already-created iframe if possible + iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement ); + + // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse + doc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document; + + // Support: IE + doc.write(); + doc.close(); + + display = actualDisplay( nodeName, doc ); + iframe.detach(); + } + + // Store the correct default display + elemdisplay[ nodeName ] = display; + } + + return display; +} + + +(function() { + var shrinkWrapBlocksVal; + + support.shrinkWrapBlocks = function() { + if ( shrinkWrapBlocksVal != null ) { + return shrinkWrapBlocksVal; + } + + // Will be changed later if needed. + shrinkWrapBlocksVal = false; + + // Minified: var b,c,d + var div, body, container; + + body = document.getElementsByTagName( "body" )[ 0 ]; + if ( !body || !body.style ) { + // Test fired too early or in an unsupported environment, exit. + return; + } + + // Setup + div = document.createElement( "div" ); + container = document.createElement( "div" ); + container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; + body.appendChild( container ).appendChild( div ); + + // Support: IE6 + // Check if elements with layout shrink-wrap their children + if ( typeof div.style.zoom !== strundefined ) { + // Reset CSS: box-sizing; display; margin; border + div.style.cssText = + // Support: Firefox<29, Android 2.3 + // Vendor-prefix box-sizing + "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" + + "box-sizing:content-box;display:block;margin:0;border:0;" + + "padding:1px;width:1px;zoom:1"; + div.appendChild( document.createElement( "div" ) ).style.width = "5px"; + shrinkWrapBlocksVal = div.offsetWidth !== 3; + } + + body.removeChild( container ); + + return shrinkWrapBlocksVal; + }; + +})(); +var rmargin = (/^margin/); + +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + + + +var getStyles, curCSS, + rposition = /^(top|right|bottom|left)$/; + +if ( window.getComputedStyle ) { + getStyles = function( elem ) { + // Support: IE<=11+, Firefox<=30+ (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + if ( elem.ownerDocument.defaultView.opener ) { + return elem.ownerDocument.defaultView.getComputedStyle( elem, null ); + } + + return window.getComputedStyle( elem, null ); + }; + + curCSS = function( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is only needed for .css('filter') in IE9, see #12537 + ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined; + + if ( computed ) { + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right + // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + // Support: IE + // IE returns zIndex value as an integer. + return ret === undefined ? + ret : + ret + ""; + }; +} else if ( document.documentElement.currentStyle ) { + getStyles = function( elem ) { + return elem.currentStyle; + }; + + curCSS = function( elem, name, computed ) { + var left, rs, rsLeft, ret, + style = elem.style; + + computed = computed || getStyles( elem ); + ret = computed ? computed[ name ] : undefined; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret == null && style && style[ name ] ) { + ret = style[ name ]; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + // but not position css attributes, as those are proportional to the parent element instead + // and we can't measure the parent instead because it might trigger a "stacking dolls" problem + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { + + // Remember the original values + left = style.left; + rs = elem.runtimeStyle; + rsLeft = rs && rs.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + rs.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ret; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + rs.left = rsLeft; + } + } + + // Support: IE + // IE returns zIndex value as an integer. + return ret === undefined ? + ret : + ret + "" || "auto"; + }; +} + + + + +function addGetHookIf( conditionFn, hookFn ) { + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + var condition = conditionFn(); + + if ( condition == null ) { + // The test was not ready at this point; screw the hook this time + // but check again when needed next time. + return; + } + + if ( condition ) { + // Hook not needed (or it's not possible to use it due to missing dependency), + // remove it. + // Since there are no other hooks for marginRight, remove the whole object. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + + return (this.get = hookFn).apply( this, arguments ); + } + }; +} + + +(function() { + // Minified: var b,c,d,e,f,g, h,i + var div, style, a, pixelPositionVal, boxSizingReliableVal, + reliableHiddenOffsetsVal, reliableMarginRightVal; + + // Setup + div = document.createElement( "div" ); + div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>"; + a = div.getElementsByTagName( "a" )[ 0 ]; + style = a && a.style; + + // Finish early in limited (non-browser) environments + if ( !style ) { + return; + } + + style.cssText = "float:left;opacity:.5"; + + // Support: IE<9 + // Make sure that element opacity exists (as opposed to filter) + support.opacity = style.opacity === "0.5"; + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + support.cssFloat = !!style.cssFloat; + + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + // Support: Firefox<29, Android 2.3 + // Vendor-prefix box-sizing + support.boxSizing = style.boxSizing === "" || style.MozBoxSizing === "" || + style.WebkitBoxSizing === ""; + + jQuery.extend(support, { + reliableHiddenOffsets: function() { + if ( reliableHiddenOffsetsVal == null ) { + computeStyleTests(); + } + return reliableHiddenOffsetsVal; + }, + + boxSizingReliable: function() { + if ( boxSizingReliableVal == null ) { + computeStyleTests(); + } + return boxSizingReliableVal; + }, + + pixelPosition: function() { + if ( pixelPositionVal == null ) { + computeStyleTests(); + } + return pixelPositionVal; + }, + + // Support: Android 2.3 + reliableMarginRight: function() { + if ( reliableMarginRightVal == null ) { + computeStyleTests(); + } + return reliableMarginRightVal; + } + }); + + function computeStyleTests() { + // Minified: var b,c,d,j + var div, body, container, contents; + + body = document.getElementsByTagName( "body" )[ 0 ]; + if ( !body || !body.style ) { + // Test fired too early or in an unsupported environment, exit. + return; + } + + // Setup + div = document.createElement( "div" ); + container = document.createElement( "div" ); + container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; + body.appendChild( container ).appendChild( div ); + + div.style.cssText = + // Support: Firefox<29, Android 2.3 + // Vendor-prefix box-sizing + "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" + + "box-sizing:border-box;display:block;margin-top:1%;top:1%;" + + "border:1px;padding:1px;width:4px;position:absolute"; + + // Support: IE<9 + // Assume reasonable values in the absence of getComputedStyle + pixelPositionVal = boxSizingReliableVal = false; + reliableMarginRightVal = true; + + // Check for getComputedStyle so that this code is not run in IE<9. + if ( window.getComputedStyle ) { + pixelPositionVal = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; + boxSizingReliableVal = + ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + + // Support: Android 2.3 + // Div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container (#3333) + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + contents = div.appendChild( document.createElement( "div" ) ); + + // Reset CSS: box-sizing; display; margin; border; padding + contents.style.cssText = div.style.cssText = + // Support: Firefox<29, Android 2.3 + // Vendor-prefix box-sizing + "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" + + "box-sizing:content-box;display:block;margin:0;border:0;padding:0"; + contents.style.marginRight = contents.style.width = "0"; + div.style.width = "1px"; + + reliableMarginRightVal = + !parseFloat( ( window.getComputedStyle( contents, null ) || {} ).marginRight ); + + div.removeChild( contents ); + } + + // Support: IE8 + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>"; + contents = div.getElementsByTagName( "td" ); + contents[ 0 ].style.cssText = "margin:0;border:0;padding:0;display:none"; + reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0; + if ( reliableHiddenOffsetsVal ) { + contents[ 0 ].style.display = ""; + contents[ 1 ].style.display = "none"; + reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0; + } + + body.removeChild( container ); + } + +})(); + + +// A method for quickly swapping in/out CSS properties to get correct calculations. +jQuery.swap = function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var + ralpha = /alpha\([^)]*\)/i, + ropacity = /opacity\s*=\s*([^)]*)/, + + // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ), + rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ), + + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }, + + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; + + +// return a css property mapped to a potentially vendor prefixed property +function vendorPropName( style, name ) { + + // shortcut for names that are not vendor prefixed + if ( name in style ) { + return name; + } + + // check for vendor prefixed names + var capName = name.charAt(0).toUpperCase() + name.slice(1), + origName = name, + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in style ) { + return name; + } + } + + return origName; +} + +function showHide( elements, show ) { + var display, elem, hidden, + values = [], + index = 0, + length = elements.length; + + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + values[ index ] = jQuery._data( elem, "olddisplay" ); + display = elem.style.display; + if ( show ) { + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !values[ index ] && display === "none" ) { + elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( elem.style.display === "" && isHidden( elem ) ) { + values[ index ] = jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) ); + } + } else { + hidden = isHidden( elem ); + + if ( display && display !== "none" || !hidden ) { + jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) ); + } + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( index = 0; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + if ( !show || elem.style.display === "none" || elem.style.display === "" ) { + elem.style.display = show ? values[ index ] || "" : "none"; + } + } + + return elements; +} + +function setPositiveNumber( elem, value, subtract ) { + var matches = rnumsplit.exec( value ); + return matches ? + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { + var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation + 4 : + // Otherwise initialize for horizontal or vertical properties + name === "width" ? 1 : 0, + + val = 0; + + for ( ; i < 4; i += 2 ) { + // both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); + } + + if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // at this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } else { + // at this point, extra isn't content, so add padding + val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // at this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with offset property, which is equivalent to the border-box value + var valueIsBorderBox = true, + val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + styles = getStyles( elem ), + isBorderBox = support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name, styles ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // we need the check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] ); + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + } + + // use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles + ) + ) + "px"; +} + +jQuery.extend({ + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + // normalize float css property + "float": support.cssFloat ? "cssFloat" : "styleFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + style = elem.style; + + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && (ret = rrelNum.exec( value )) ) { + value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set. See: #7116 + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add 'px' to the (except for certain CSS properties) + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + value += "px"; + } + + // Fixes #8908, it can be done more correctly by specifing setters in cssHooks, + // but it would mean to define eight (for every problematic property) identical functions + if ( !support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { + + // Support: IE + // Swallow errors from 'invalid' CSS values (#5509) + try { + style[ name ] = value; + } catch(e) {} + } + + } else { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var num, val, hooks, + origName = jQuery.camelCase( name ); + + // Make sure that we're working with the right name + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + //convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Return, converting to number if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; + } + return val; + } +}); + +jQuery.each([ "height", "width" ], function( i, name ) { + jQuery.cssHooks[ name ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + // certain elements can have dimension info if we invisibly show them + // however, it must have a current display style that would benefit from this + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ? + jQuery.swap( elem, cssShow, function() { + return getWidthOrHeight( elem, name, extra ); + }) : + getWidthOrHeight( elem, name, extra ); + } + }, + + set: function( elem, value, extra ) { + var styles = extra && getStyles( elem ); + return setPositiveNumber( elem, value, extra ? + augmentWidthOrHeight( + elem, + name, + extra, + support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + styles + ) : 0 + ); + } + }; +}); + +if ( !support.opacity ) { + jQuery.cssHooks.opacity = { + get: function( elem, computed ) { + // IE uses filters for opacity + return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? + ( 0.01 * parseFloat( RegExp.$1 ) ) + "" : + computed ? "1" : ""; + }, + + set: function( elem, value ) { + var style = elem.style, + currentStyle = elem.currentStyle, + opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "", + filter = currentStyle && currentStyle.filter || style.filter || ""; + + // IE has trouble with opacity if it does not have layout + // Force it by setting the zoom level + style.zoom = 1; + + // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652 + // if value === "", then remove inline opacity #12685 + if ( ( value >= 1 || value === "" ) && + jQuery.trim( filter.replace( ralpha, "" ) ) === "" && + style.removeAttribute ) { + + // Setting style.filter to null, "" & " " still leave "filter:" in the cssText + // if "filter:" is present at all, clearType is disabled, we want to avoid this + // style.removeAttribute is IE Only, but so apparently is this code path... + style.removeAttribute( "filter" ); + + // if there is no filter style applied in a css rule or unset inline opacity, we are done + if ( value === "" || currentStyle && !currentStyle.filter ) { + return; + } + } + + // otherwise, set new filter values + style.filter = ralpha.test( filter ) ? + filter.replace( ralpha, opacity ) : + filter + " " + opacity; + } + }; +} + +jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight, + function( elem, computed ) { + if ( computed ) { + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + // Work around by temporarily setting element display to inline-block + return jQuery.swap( elem, { "display": "inline-block" }, + curCSS, [ elem, "marginRight" ] ); + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each({ + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // assumes a single number if not a string + parts = typeof value === "string" ? value.split(" ") : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( !rmargin.test( prefix ) ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +}); + +jQuery.fn.extend({ + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( jQuery.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each(function() { + if ( isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || "swing"; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + if ( tween.elem[ tween.prop ] != null && + (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) { + return tween.elem[ tween.prop ]; + } + + // passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails + // so, simple values such as "10px" are parsed to Float. + // complex values such as "rotate(1rad)" are returned as is. + result = jQuery.css( tween.elem, tween.prop, "" ); + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + // use step hook for back compat - use cssHook if its there - use .style if its + // available and use plain properties where available + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 +// Panic based approach to setting things on disconnected nodes + +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + } +}; + +jQuery.fx = Tween.prototype.init; + +// Back Compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, timerId, + rfxtypes = /^(?:toggle|show|hide)$/, + rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ), + rrun = /queueHooks$/, + animationPrefilters = [ defaultPrefilter ], + tweeners = { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ), + target = tween.cur(), + parts = rfxnum.exec( value ), + unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) && + rfxnum.exec( jQuery.css( tween.elem, prop ) ), + scale = 1, + maxIterations = 20; + + if ( start && start[ 3 ] !== unit ) { + // Trust units reported by jQuery.css + unit = unit || start[ 3 ]; + + // Make sure we update the tween properties later on + parts = parts || []; + + // Iteratively approximate from a nonzero starting point + start = +target || 1; + + do { + // If previous iteration zeroed out, double until we get *something* + // Use a string for doubling factor so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + start = start / scale; + jQuery.style( tween.elem, prop, start + unit ); + + // Update scale, tolerating zero or NaN from tween.cur() + // And breaking the loop if scale is unchanged or perfect, or if we've just had enough + } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations ); + } + + // Update tween properties + if ( parts ) { + start = tween.start = +start || +target || 0; + tween.unit = unit; + // If a +=/-= token was provided, we're doing a relative animation + tween.end = parts[ 1 ] ? + start + ( parts[ 1 ] + 1 ) * parts[ 2 ] : + +parts[ 2 ]; + } + + return tween; + } ] + }; + +// Animations created synchronously will run synchronously +function createFxNow() { + setTimeout(function() { + fxNow = undefined; + }); + return ( fxNow = jQuery.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + attrs = { height: type }, + i = 0; + + // if we include width, step value is 1 to do all cssExpand values, + // if we don't include width, step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4 ; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( (tween = collection[ index ].call( animation, prop, value )) ) { + + // we're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + /* jshint validthis: true */ + var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHidden( elem ), + dataShow = jQuery._data( elem, "fxshow" ); + + // handle queue: false promises + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always(function() { + // doing this makes sure that the complete handler will be called + // before this completes + anim.always(function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + }); + }); + } + + // height/width overflow pass + if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { + // Make sure that nothing sneaks out + // Record all 3 overflow attributes because IE does not + // change the overflow attribute when overflowX and + // overflowY are set to the same value + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Set display property to inline-block for height/width + // animations on inline elements that are having width/height animated + display = jQuery.css( elem, "display" ); + + // Test default display if display is currently "none" + checkDisplay = display === "none" ? + jQuery._data( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display; + + if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) { + + // inline-level elements accept inline-block; + // block-level elements need to be inline with layout + if ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === "inline" ) { + style.display = "inline-block"; + } else { + style.zoom = 1; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + if ( !support.shrinkWrapBlocks() ) { + anim.always(function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + }); + } + } + + // show/hide pass + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.exec( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + + // Any non-fx value stops us from restoring the original display value + } else { + display = undefined; + } + } + + if ( !jQuery.isEmptyObject( orig ) ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = jQuery._data( elem, "fxshow", {} ); + } + + // store state if its toggle - enables .stop().toggle() to "reverse" + if ( toggle ) { + dataShow.hidden = !hidden; + } + if ( hidden ) { + jQuery( elem ).show(); + } else { + anim.done(function() { + jQuery( elem ).hide(); + }); + } + anim.done(function() { + var prop; + jQuery._removeData( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + }); + for ( prop in orig ) { + tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = tween.start; + if ( hidden ) { + tween.end = tween.start; + tween.start = prop === "width" || prop === "height" ? 1 : 0; + } + } + } + + // If this is a noop like .hide().hide(), restore an overwritten display value + } else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) { + style.display = display; + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = jQuery.camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( jQuery.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // not quite $.extend, this wont overwrite keys already present. + // also - reusing 'index' from above because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = animationPrefilters.length, + deferred = jQuery.Deferred().always( function() { + // don't match elem in the :animated selector + delete tick.elem; + }), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ]); + + if ( percent < 1 && length ) { + return remaining; + } else { + deferred.resolveWith( elem, [ animation ] ); + return false; + } + }, + animation = deferred.promise({ + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { specialEasing: {} }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + // if we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // resolve when we played the last frame + // otherwise, reject + if ( gotoEnd ) { + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + }), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length ; index++ ) { + result = animationPrefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( jQuery.isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + }) + ); + + // attach callbacks from options + return animation.progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); +} + +jQuery.Animation = jQuery.extend( Animation, { + tweener: function( props, callback ) { + if ( jQuery.isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.split(" "); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length ; index++ ) { + prop = props[ index ]; + tweeners[ prop ] = tweeners[ prop ] || []; + tweeners[ prop ].unshift( callback ); + } + }, + + prefilter: function( callback, prepend ) { + if ( prepend ) { + animationPrefilters.unshift( callback ); + } else { + animationPrefilters.push( callback ); + } + } +}); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + jQuery.isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing + }; + + opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : + opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; + + // normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( jQuery.isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend({ + fadeTo: function( speed, to, easing, callback ) { + + // show any hidden elements after setting opacity to 0 + return this.filter( isHidden ).css( "opacity", 0 ).show() + + // animate to the value specified + .end().animate({ opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || jQuery._data( this, "finish" ) ) { + anim.stop( true ); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each(function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = jQuery._data( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // start the next in the queue if the last step wasn't forced + // timers currently will call their complete callbacks, which will dequeue + // but only if they were gotoEnd + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + }); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each(function() { + var index, + data = jQuery._data( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // enable finishing flag on private data + data.finish = true; + + // empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // turn off finishing flag + delete data.finish; + }); + } +}); + +jQuery.each([ "toggle", "show", "hide" ], function( i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +}); + +// Generate shortcuts for custom animations +jQuery.each({ + slideDown: genFx("show"), + slideUp: genFx("hide"), + slideToggle: genFx("toggle"), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +}); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + timers = jQuery.timers, + i = 0; + + fxNow = jQuery.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + // Checks the timer has not already been removed + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + if ( timer() ) { + jQuery.fx.start(); + } else { + jQuery.timers.pop(); + } +}; + +jQuery.fx.interval = 13; + +jQuery.fx.start = function() { + if ( !timerId ) { + timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); + } +}; + +jQuery.fx.stop = function() { + clearInterval( timerId ); + timerId = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); +}; + + +(function() { + // Minified: var a,b,c,d,e + var input, div, select, a, opt; + + // Setup + div = document.createElement( "div" ); + div.setAttribute( "className", "t" ); + div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>"; + a = div.getElementsByTagName("a")[ 0 ]; + + // First batch of tests. + select = document.createElement("select"); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName("input")[ 0 ]; + + a.style.cssText = "top:1px"; + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + support.getSetAttribute = div.className !== "t"; + + // Get the style information from getAttribute + // (IE uses .cssText instead) + support.style = /top/.test( a.getAttribute("style") ); + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + support.hrefNormalized = a.getAttribute("href") === "/a"; + + // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere) + support.checkOn = !!input.value; + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + support.optSelected = opt.selected; + + // Tests for enctype support on a form (#6743) + support.enctype = !!document.createElement("form").enctype; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Support: IE8 only + // Check if we can trust getAttribute("value") + input = document.createElement( "input" ); + input.setAttribute( "value", "" ); + support.input = input.getAttribute( "value" ) === ""; + + // Check if an input maintains its value after becoming a radio + input.value = "t"; + input.setAttribute( "type", "radio" ); + support.radioValue = input.value === "t"; +})(); + + +var rreturn = /\r/g; + +jQuery.fn.extend({ + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + // Support: IE10-11+ + // option.text throws exceptions (#14686, #14858) + jQuery.trim( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one" || index < 0, + values = one ? null : [], + max = one ? index + 1 : options.length, + i = index < 0 ? + max : + one ? index : 0; + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // oldIE doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + // Don't return options that are disabled or in a disabled optgroup + ( support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && + ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + if ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) >= 0 ) { + + // Support: IE6 + // When new option element is added to select box we need to + // force reflow of newly added node in order to workaround delay + // of initialization properties + try { + option.selected = optionSet = true; + + } catch ( _ ) { + + // Will be executed only in IE6 + option.scrollHeight; + } + + } else { + option.selected = false; + } + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + + return options; + } + } + } +}); + +// Radios and checkboxes getter/setter +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + // Support: Webkit + // "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + }; + } +}); + + + + +var nodeHook, boolHook, + attrHandle = jQuery.expr.attrHandle, + ruseDefault = /^(?:checked|selected)$/i, + getSetAttribute = support.getSetAttribute, + getSetInput = support.input; + +jQuery.fn.extend({ + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + } +}); + +jQuery.extend({ + attr: function( elem, name, value ) { + var hooks, ret, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === strundefined ) { + return jQuery.prop( elem, name, value ); + } + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + + } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, value + "" ); + return value; + } + + } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var name, propName, + i = 0, + attrNames = value && value.match( rnotwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( (name = attrNames[i++]) ) { + propName = jQuery.propFix[ name ] || name; + + // Boolean attributes get special treatment (#10870) + if ( jQuery.expr.match.bool.test( name ) ) { + // Set corresponding property to false + if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { + elem[ propName ] = false; + // Support: IE<9 + // Also clear defaultChecked/defaultSelected (if appropriate) + } else { + elem[ jQuery.camelCase( "default-" + name ) ] = + elem[ propName ] = false; + } + + // See #9699 for explanation of this approach (setting first, then removal) + } else { + jQuery.attr( elem, name, "" ); + } + + elem.removeAttribute( getSetAttribute ? name : propName ); + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to default in case type is set after value during creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + } +}); + +// Hook for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { + // IE<8 needs the *property* name + elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name ); + + // Use defaultChecked and defaultSelected for oldIE + } else { + elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true; + } + + return name; + } +}; + +// Retrieve booleans specially +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { + + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ? + function( elem, name, isXML ) { + var ret, handle; + if ( !isXML ) { + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ name ]; + attrHandle[ name ] = ret; + ret = getter( elem, name, isXML ) != null ? + name.toLowerCase() : + null; + attrHandle[ name ] = handle; + } + return ret; + } : + function( elem, name, isXML ) { + if ( !isXML ) { + return elem[ jQuery.camelCase( "default-" + name ) ] ? + name.toLowerCase() : + null; + } + }; +}); + +// fix oldIE attroperties +if ( !getSetInput || !getSetAttribute ) { + jQuery.attrHooks.value = { + set: function( elem, value, name ) { + if ( jQuery.nodeName( elem, "input" ) ) { + // Does not return so that setAttribute is also used + elem.defaultValue = value; + } else { + // Use nodeHook if defined (#1954); otherwise setAttribute is fine + return nodeHook && nodeHook.set( elem, value, name ); + } + } + }; +} + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = { + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + elem.setAttributeNode( + (ret = elem.ownerDocument.createAttribute( name )) + ); + } + + ret.value = value += ""; + + // Break association with cloned elements by also using setAttribute (#9646) + if ( name === "value" || value === elem.getAttribute( name ) ) { + return value; + } + } + }; + + // Some attributes are constructed with empty-string values when not defined + attrHandle.id = attrHandle.name = attrHandle.coords = + function( elem, name, isXML ) { + var ret; + if ( !isXML ) { + return (ret = elem.getAttributeNode( name )) && ret.value !== "" ? + ret.value : + null; + } + }; + + // Fixing value retrieval on a button requires this module + jQuery.valHooks.button = { + get: function( elem, name ) { + var ret = elem.getAttributeNode( name ); + if ( ret && ret.specified ) { + return ret.value; + } + }, + set: nodeHook.set + }; + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + set: function( elem, value, name ) { + nodeHook.set( elem, value === "" ? false : value, name ); + } + }; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }; + }); +} + +if ( !support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Note: IE uppercases css property names, but if we were to .toLowerCase() + // .cssText, that would destroy case senstitivity in URL's, like in "background" + return elem.style.cssText || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = value + "" ); + } + }; +} + + + + +var rfocusable = /^(?:input|select|textarea|button|object)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend({ + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + } +}); + +jQuery.extend({ + propFix: { + "for": "htmlFor", + "class": "className" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ? + ret : + ( elem[ name ] = value ); + + } else { + return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ? + ret : + elem[ name ]; + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + return tabindex ? + parseInt( tabindex, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + -1; + } + } + } +}); + +// Some attributes require a special call on IE +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !support.hrefNormalized ) { + // href/src property should get the full normalized URL (#10299/#12915) + jQuery.each([ "href", "src" ], function( i, name ) { + jQuery.propHooks[ name ] = { + get: function( elem ) { + return elem.getAttribute( name, 4 ); + } + }; + }); +} + +// Support: Safari, IE9+ +// mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }; +} + +jQuery.each([ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +}); + +// IE6/7 call enctype encoding +if ( !support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + + + + +var rclass = /[\t\r\n\f]/g; + +jQuery.fn.extend({ + addClass: function( value ) { + var classes, elem, cur, clazz, j, finalValue, + i = 0, + len = this.length, + proceed = typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call( this, j, this.className ) ); + }); + } + + if ( proceed ) { + // The disjunction here is for better compressibility (see removeClass) + classes = ( value || "" ).match( rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + " " + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // only assign if different to avoid unneeded rendering. + finalValue = jQuery.trim( cur ); + if ( elem.className !== finalValue ) { + elem.className = finalValue; + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, clazz, j, finalValue, + i = 0, + len = this.length, + proceed = arguments.length === 0 || typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call( this, j, this.className ) ); + }); + } + if ( proceed ) { + classes = ( value || "" ).match( rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + "" + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // only assign if different to avoid unneeded rendering. + finalValue = value ? jQuery.trim( cur ) : ""; + if ( elem.className !== finalValue ) { + elem.className = finalValue; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value; + + if ( typeof stateVal === "boolean" && type === "string" ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + classNames = value.match( rnotwhite ) || []; + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( type === strundefined || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // If the element has a class name or if we're passed "false", + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { + return true; + } + } + + return false; + } +}); + + + + +// Return jQuery for attributes-only inclusion + + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; +}); + +jQuery.fn.extend({ + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); + } +}); + + +var nonce = jQuery.now(); + +var rquery = (/\?/); + + + +var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g; + +jQuery.parseJSON = function( data ) { + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + // Support: Android 2.3 + // Workaround failure to string-cast null input + return window.JSON.parse( data + "" ); + } + + var requireNonComma, + depth = null, + str = jQuery.trim( data + "" ); + + // Guard against invalid (and possibly dangerous) input by ensuring that nothing remains + // after removing valid tokens + return str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) { + + // Force termination if we see a misplaced comma + if ( requireNonComma && comma ) { + depth = 0; + } + + // Perform no more replacements after returning to outermost depth + if ( depth === 0 ) { + return token; + } + + // Commas must not follow "[", "{", or "," + requireNonComma = open || comma; + + // Determine new depth + // array/object open ("[" or "{"): depth += true - false (increment) + // array/object close ("]" or "}"): depth += false - true (decrement) + // other cases ("," or primitive): depth += true - true (numeric cast) + depth += !close - !open; + + // Remove this token + return ""; + }) ) ? + ( Function( "return " + str ) )() : + jQuery.error( "Invalid JSON: " + data ); +}; + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data, "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; +}; + + +var + // Document location + ajaxLocParts, + ajaxLocation, + + rhash = /#.*$/, + rts = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat("*"); + +// #8138, IE may throw an exception when accessing +// a field from window.location if document.domain has been set +try { + ajaxLocation = location.href; +} catch( e ) { + // Use the href attribute of an A element + // since IE will modify it given document.location + ajaxLocation = document.createElement( "a" ); + ajaxLocation.href = ""; + ajaxLocation = ajaxLocation.href; +} + +// Segment location into parts +ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || []; + + if ( jQuery.isFunction( func ) ) { + // For each dataType in the dataTypeExpression + while ( (dataType = dataTypes[i++]) ) { + // Prepend if requested + if ( dataType.charAt( 0 ) === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + (structure[ dataType ] = structure[ dataType ] || []).unshift( func ); + + // Otherwise append + } else { + (structure[ dataType ] = structure[ dataType ] || []).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + }); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var deep, key, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + var firstDataType, ct, finalDataType, type, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader("Content-Type"); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s[ "throws" ] ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend({ + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: ajaxLocation, + type: "GET", + isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /xml/, + html: /html/, + json: /json/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": jQuery.parseJSON, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var // Cross-domain detection vars + parts, + // Loop variable + i, + // URL without anti-cache param + cacheURL, + // Response headers as string + responseHeadersString, + // timeout handle + timeoutTimer, + + // To know if global events are to be dispatched + fireGlobals, + + transport, + // Response headers + responseHeaders, + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + // Callbacks context + callbackContext = s.context || s, + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks("once memory"), + // Status-dependent callbacks + statusCode = s.statusCode || {}, + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + // The jqXHR state + state = 0, + // Default abort message + strAbort = "canceled", + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( state === 2 ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( (match = rheaders.exec( responseHeadersString )) ) { + responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; + } + } + match = responseHeaders[ key.toLowerCase() ]; + } + return match == null ? null : match; + }, + + // Raw string + getAllResponseHeaders: function() { + return state === 2 ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + var lname = name.toLowerCase(); + if ( !state ) { + name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( !state ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( state < 2 ) { + for ( code in map ) { + // Lazy-add the new callback in a way that preserves old ones + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } else { + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ).complete = completeDeferred.add; + jqXHR.success = jqXHR.done; + jqXHR.error = jqXHR.fail; + + // Remove hash character (#7531: and string promotion) + // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ]; + + // A cross-domain request is in order when we have a protocol:host:port mismatch + if ( s.crossDomain == null ) { + parts = rurl.exec( s.url.toLowerCase() ); + s.crossDomain = !!( parts && + ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || + ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !== + ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) ) + ); + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( state === 2 ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger("ajaxStart"); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + cacheURL = s.url; + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // If data is available, append data to url + if ( s.data ) { + cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data ); + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add anti-cache in url if needed + if ( s.cache === false ) { + s.url = rts.test( cacheURL ) ? + + // If there is already a '_' parameter, set its value + cacheURL.replace( rts, "$1_=" + nonce++ ) : + + // Otherwise add one to the end + cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++; + } + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? + s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { + // Abort if not done already and return + return jqXHR.abort(); + } + + // aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + for ( i in { success: 1, error: 1, complete: 1 } ) { + jqXHR[ i ]( s[ i ] ); + } + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = setTimeout(function() { + jqXHR.abort("timeout"); + }, s.timeout ); + } + + try { + state = 1; + transport.send( requestHeaders, done ); + } catch ( e ) { + // Propagate exception as error if not done + if ( state < 2 ) { + done( -1, e ); + // Simply rethrow otherwise + } else { + throw e; + } + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Called once + if ( state === 2 ) { + return; + } + + // State is "done" now + state = 2; + + // Clear timeout if it exists + if ( timeoutTimer ) { + clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader("Last-Modified"); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader("etag"); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + // We extract error from statusText + // then normalize statusText and status for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger("ajaxStop"); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +}); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + // shift arguments if data argument was omitted + if ( jQuery.isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + return jQuery.ajax({ + url: url, + type: method, + dataType: type, + data: data, + success: callback + }); + }; +}); + + +jQuery._evalUrl = function( url ) { + return jQuery.ajax({ + url: url, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); +}; + + +jQuery.fn.extend({ + wrapAll: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); + }); + } + + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + + if ( this[0].parentNode ) { + wrap.insertBefore( this[0] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { + elem = elem.firstChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function(i) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + } +}); + + +jQuery.expr.filters.hidden = function( elem ) { + // Support: Opera <= 12.12 + // Opera reports offsetWidths and offsetHeights less than zero on some elements + return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 || + (!support.reliableHiddenOffsets() && + ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none"); +}; + +jQuery.expr.filters.visible = function( elem ) { + return !jQuery.expr.filters.hidden( elem ); +}; + + + + +var r20 = /%20/g, + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( jQuery.isArray( obj ) ) { + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + // Item is non-scalar (array or object), encode its numeric index. + buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); + } + }); + + } else if ( !traditional && jQuery.type( obj ) === "object" ) { + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, value ) { + // If value is a function, invoke it and return its value + value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); + s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); + }; + + // Set traditional to true for jQuery <= 1.3.2 behavior. + if ( traditional === undefined ) { + traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + }); + + } else { + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ).replace( r20, "+" ); +}; + +jQuery.fn.extend({ + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map(function() { + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + }) + .filter(function() { + var type = this.type; + // Use .is(":disabled") so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + }) + .map(function( i, elem ) { + var val = jQuery( this ).val(); + + return val == null ? + null : + jQuery.isArray( val ) ? + jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }) : + { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }).get(); + } +}); + + +// Create the request object +// (This is still attached to ajaxSettings for backward compatibility) +jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ? + // Support: IE6+ + function() { + + // XHR cannot access local files, always use ActiveX for that case + return !this.isLocal && + + // Support: IE7-8 + // oldIE XHR does not support non-RFC2616 methods (#13240) + // See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx + // and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9 + // Although this check for six methods instead of eight + // since IE also does not support "trace" and "connect" + /^(get|post|head|put|delete|options)$/i.test( this.type ) && + + createStandardXHR() || createActiveXHR(); + } : + // For all other browsers, use the standard XMLHttpRequest object + createStandardXHR; + +var xhrId = 0, + xhrCallbacks = {}, + xhrSupported = jQuery.ajaxSettings.xhr(); + +// Support: IE<10 +// Open requests must be manually aborted on unload (#5280) +// See https://support.microsoft.com/kb/2856746 for more info +if ( window.attachEvent ) { + window.attachEvent( "onunload", function() { + for ( var key in xhrCallbacks ) { + xhrCallbacks[ key ]( undefined, true ); + } + }); +} + +// Determine support properties +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +xhrSupported = support.ajax = !!xhrSupported; + +// Create transport if the browser can provide an xhr +if ( xhrSupported ) { + + jQuery.ajaxTransport(function( options ) { + // Cross domain only allowed if supported through XMLHttpRequest + if ( !options.crossDomain || support.cors ) { + + var callback; + + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(), + id = ++xhrId; + + // Open the socket + xhr.open( options.type, options.url, options.async, options.username, options.password ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers["X-Requested-With"] ) { + headers["X-Requested-With"] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + // Support: IE<9 + // IE's ActiveXObject throws a 'Type Mismatch' exception when setting + // request header to a null-value. + // + // To keep consistent with other XHR implementations, cast the value + // to string and ignore `undefined`. + if ( headers[ i ] !== undefined ) { + xhr.setRequestHeader( i, headers[ i ] + "" ); + } + } + + // Do send the request + // This may raise an exception which is actually + // handled in jQuery.ajax (so no try/catch here) + xhr.send( ( options.hasContent && options.data ) || null ); + + // Listener + callback = function( _, isAbort ) { + var status, statusText, responses; + + // Was never called and is aborted or complete + if ( callback && ( isAbort || xhr.readyState === 4 ) ) { + // Clean up + delete xhrCallbacks[ id ]; + callback = undefined; + xhr.onreadystatechange = jQuery.noop; + + // Abort manually if needed + if ( isAbort ) { + if ( xhr.readyState !== 4 ) { + xhr.abort(); + } + } else { + responses = {}; + status = xhr.status; + + // Support: IE<10 + // Accessing binary-data responseText throws an exception + // (#11426) + if ( typeof xhr.responseText === "string" ) { + responses.text = xhr.responseText; + } + + // Firefox throws an exception when accessing + // statusText for faulty cross-domain requests + try { + statusText = xhr.statusText; + } catch( e ) { + // We normalize with Webkit giving an empty statusText + statusText = ""; + } + + // Filter status for non standard behaviors + + // If the request is local and we have data: assume a success + // (success with no data won't get notified, that's the best we + // can do given current implementations) + if ( !status && options.isLocal && !options.crossDomain ) { + status = responses.text ? 200 : 404; + // IE - #1450: sometimes returns 1223 when it should be 204 + } else if ( status === 1223 ) { + status = 204; + } + } + } + + // Call complete if needed + if ( responses ) { + complete( status, statusText, responses, xhr.getAllResponseHeaders() ); + } + }; + + if ( !options.async ) { + // if we're in sync mode we fire the callback + callback(); + } else if ( xhr.readyState === 4 ) { + // (IE6 & IE7) if it's in cache and has been + // retrieved directly we need to fire the callback + setTimeout( callback ); + } else { + // Add to the list of active xhr callbacks + xhr.onreadystatechange = xhrCallbacks[ id ] = callback; + } + }, + + abort: function() { + if ( callback ) { + callback( undefined, true ); + } + } + }; + } + }); +} + +// Functions to create xhrs +function createStandardXHR() { + try { + return new window.XMLHttpRequest(); + } catch( e ) {} +} + +function createActiveXHR() { + try { + return new window.ActiveXObject( "Microsoft.XMLHTTP" ); + } catch( e ) {} +} + + + + +// Install script dataType +jQuery.ajaxSetup({ + accepts: { + script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /(?:java|ecma)script/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +}); + +// Handle cache's special case and global +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + s.global = false; + } +}); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function(s) { + + // This transport only deals with cross domain requests + if ( s.crossDomain ) { + + var script, + head = document.head || jQuery("head")[0] || document.documentElement; + + return { + + send: function( _, callback ) { + + script = document.createElement("script"); + + script.async = true; + + if ( s.scriptCharset ) { + script.charset = s.scriptCharset; + } + + script.src = s.url; + + // Attach handlers for all browsers + script.onload = script.onreadystatechange = function( _, isAbort ) { + + if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { + + // Handle memory leak in IE + script.onload = script.onreadystatechange = null; + + // Remove the script + if ( script.parentNode ) { + script.parentNode.removeChild( script ); + } + + // Dereference the script + script = null; + + // Callback if not abort + if ( !isAbort ) { + callback( 200, "success" ); + } + } + }; + + // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending + // Use native DOM manipulation to avoid our domManip AJAX trickery + head.insertBefore( script, head.firstChild ); + }, + + abort: function() { + if ( script ) { + script.onload( undefined, true ); + } + } + }; + } +}); + + + + +var oldCallbacks = [], + rjsonp = /(=)\?(?=&|$)|\?\?/; + +// Default jsonp settings +jQuery.ajaxSetup({ + jsonp: "callback", + jsonpCallback: function() { + var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); + this[ callback ] = true; + return callback; + } +}); + +// Detect, normalize options and install callbacks for jsonp requests +jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { + + var callbackName, overwritten, responseContainer, + jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? + "url" : + typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data" + ); + + // Handle iff the expected data type is "jsonp" or we have a parameter to set + if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { + + // Get callback name, remembering preexisting value associated with it + callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? + s.jsonpCallback() : + s.jsonpCallback; + + // Insert callback into url or form data + if ( jsonProp ) { + s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); + } else if ( s.jsonp !== false ) { + s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; + } + + // Use data converter to retrieve json after script execution + s.converters["script json"] = function() { + if ( !responseContainer ) { + jQuery.error( callbackName + " was not called" ); + } + return responseContainer[ 0 ]; + }; + + // force json dataType + s.dataTypes[ 0 ] = "json"; + + // Install callback + overwritten = window[ callbackName ]; + window[ callbackName ] = function() { + responseContainer = arguments; + }; + + // Clean-up function (fires after converters) + jqXHR.always(function() { + // Restore preexisting value + window[ callbackName ] = overwritten; + + // Save back as free + if ( s[ callbackName ] ) { + // make sure that re-using the options doesn't screw things around + s.jsonpCallback = originalSettings.jsonpCallback; + + // save the callback name for future use + oldCallbacks.push( callbackName ); + } + + // Call if it was a function and we have a response + if ( responseContainer && jQuery.isFunction( overwritten ) ) { + overwritten( responseContainer[ 0 ] ); + } + + responseContainer = overwritten = undefined; + }); + + // Delegate to script + return "script"; + } +}); + + + + +// data: string of html +// context (optional): If specified, the fragment will be created in this context, defaults to document +// keepScripts (optional): If true, will include scripts passed in the html string +jQuery.parseHTML = function( data, context, keepScripts ) { + if ( !data || typeof data !== "string" ) { + return null; + } + if ( typeof context === "boolean" ) { + keepScripts = context; + context = false; + } + context = context || document; + + var parsed = rsingleTag.exec( data ), + scripts = !keepScripts && []; + + // Single tag + if ( parsed ) { + return [ context.createElement( parsed[1] ) ]; + } + + parsed = jQuery.buildFragment( [ data ], context, scripts ); + + if ( scripts && scripts.length ) { + jQuery( scripts ).remove(); + } + + return jQuery.merge( [], parsed.childNodes ); +}; + + +// Keep a copy of the old load method +var _load = jQuery.fn.load; + +/** + * Load a url into a page + */ +jQuery.fn.load = function( url, params, callback ) { + if ( typeof url !== "string" && _load ) { + return _load.apply( this, arguments ); + } + + var selector, response, type, + self = this, + off = url.indexOf(" "); + + if ( off >= 0 ) { + selector = jQuery.trim( url.slice( off, url.length ) ); + url = url.slice( 0, off ); + } + + // If it's a function + if ( jQuery.isFunction( params ) ) { + + // We assume that it's the callback + callback = params; + params = undefined; + + // Otherwise, build a param string + } else if ( params && typeof params === "object" ) { + type = "POST"; + } + + // If we have elements to modify, make the request + if ( self.length > 0 ) { + jQuery.ajax({ + url: url, + + // if "type" variable is undefined, then "GET" method will be used + type: type, + dataType: "html", + data: params + }).done(function( responseText ) { + + // Save response for use in complete callback + response = arguments; + + self.html( selector ? + + // If a selector was specified, locate the right elements in a dummy div + // Exclude scripts to avoid IE 'Permission Denied' errors + jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) : + + // Otherwise use the full result + responseText ); + + }).complete( callback && function( jqXHR, status ) { + self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); + }); + } + + return this; +}; + + + + +// Attach a bunch of functions for handling common AJAX events +jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) { + jQuery.fn[ type ] = function( fn ) { + return this.on( type, fn ); + }; +}); + + + + +jQuery.expr.filters.animated = function( elem ) { + return jQuery.grep(jQuery.timers, function( fn ) { + return elem === fn.elem; + }).length; +}; + + + + + +var docElem = window.document.documentElement; + +/** + * Gets a window from an element + */ +function getWindow( elem ) { + return jQuery.isWindow( elem ) ? + elem : + elem.nodeType === 9 ? + elem.defaultView || elem.parentWindow : + false; +} + +jQuery.offset = { + setOffset: function( elem, options, i ) { + var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, + position = jQuery.css( elem, "position" ), + curElem = jQuery( elem ), + props = {}; + + // set position first, in-case top/left are set even on static elem + if ( position === "static" ) { + elem.style.position = "relative"; + } + + curOffset = curElem.offset(); + curCSSTop = jQuery.css( elem, "top" ); + curCSSLeft = jQuery.css( elem, "left" ); + calculatePosition = ( position === "absolute" || position === "fixed" ) && + jQuery.inArray("auto", [ curCSSTop, curCSSLeft ] ) > -1; + + // need to be able to calculate position if either top or left is auto and position is either absolute or fixed + if ( calculatePosition ) { + curPosition = curElem.position(); + curTop = curPosition.top; + curLeft = curPosition.left; + } else { + curTop = parseFloat( curCSSTop ) || 0; + curLeft = parseFloat( curCSSLeft ) || 0; + } + + if ( jQuery.isFunction( options ) ) { + options = options.call( elem, i, curOffset ); + } + + if ( options.top != null ) { + props.top = ( options.top - curOffset.top ) + curTop; + } + if ( options.left != null ) { + props.left = ( options.left - curOffset.left ) + curLeft; + } + + if ( "using" in options ) { + options.using.call( elem, props ); + } else { + curElem.css( props ); + } + } +}; + +jQuery.fn.extend({ + offset: function( options ) { + if ( arguments.length ) { + return options === undefined ? + this : + this.each(function( i ) { + jQuery.offset.setOffset( this, options, i ); + }); + } + + var docElem, win, + box = { top: 0, left: 0 }, + elem = this[ 0 ], + doc = elem && elem.ownerDocument; + + if ( !doc ) { + return; + } + + docElem = doc.documentElement; + + // Make sure it's not a disconnected DOM node + if ( !jQuery.contains( docElem, elem ) ) { + return box; + } + + // If we don't have gBCR, just use 0,0 rather than error + // BlackBerry 5, iOS 3 (original iPhone) + if ( typeof elem.getBoundingClientRect !== strundefined ) { + box = elem.getBoundingClientRect(); + } + win = getWindow( doc ); + return { + top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ), + left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 ) + }; + }, + + position: function() { + if ( !this[ 0 ] ) { + return; + } + + var offsetParent, offset, + parentOffset = { top: 0, left: 0 }, + elem = this[ 0 ]; + + // fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent + if ( jQuery.css( elem, "position" ) === "fixed" ) { + // we assume that getBoundingClientRect is available when computed position is fixed + offset = elem.getBoundingClientRect(); + } else { + // Get *real* offsetParent + offsetParent = this.offsetParent(); + + // Get correct offsets + offset = this.offset(); + if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) { + parentOffset = offsetParent.offset(); + } + + // Add offsetParent borders + parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ); + parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true ); + } + + // Subtract parent offsets and element margins + // note: when an element has margin: auto the offsetLeft and marginLeft + // are the same in Safari causing offset.left to incorrectly be 0 + return { + top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), + left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true) + }; + }, + + offsetParent: function() { + return this.map(function() { + var offsetParent = this.offsetParent || docElem; + + while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) { + offsetParent = offsetParent.offsetParent; + } + return offsetParent || docElem; + }); + } +}); + +// Create scrollLeft and scrollTop methods +jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { + var top = /Y/.test( prop ); + + jQuery.fn[ method ] = function( val ) { + return access( this, function( elem, method, val ) { + var win = getWindow( elem ); + + if ( val === undefined ) { + return win ? (prop in win) ? win[ prop ] : + win.document.documentElement[ method ] : + elem[ method ]; + } + + if ( win ) { + win.scrollTo( + !top ? val : jQuery( win ).scrollLeft(), + top ? val : jQuery( win ).scrollTop() + ); + + } else { + elem[ method ] = val; + } + }, method, val, arguments.length, null ); + }; +}); + +// Add the top/left cssHooks using jQuery.fn.position +// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 +// getComputedStyle returns percent when specified for top/left/bottom/right +// rather than make the css module depend on the offset module, we just check for it here +jQuery.each( [ "top", "left" ], function( i, prop ) { + jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, + function( elem, computed ) { + if ( computed ) { + computed = curCSS( elem, prop ); + // if curCSS returns percentage, fallback to offset + return rnumnonpx.test( computed ) ? + jQuery( elem ).position()[ prop ] + "px" : + computed; + } + } + ); +}); + + +// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods +jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { + jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { + // margin is only for outerHeight, outerWidth + jQuery.fn[ funcName ] = function( margin, value ) { + var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), + extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); + + return access( this, function( elem, type, value ) { + var doc; + + if ( jQuery.isWindow( elem ) ) { + // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there + // isn't a whole lot we can do. See pull request at this URL for discussion: + // https://github.com/jquery/jquery/pull/764 + return elem.document.documentElement[ "client" + name ]; + } + + // Get document width or height + if ( elem.nodeType === 9 ) { + doc = elem.documentElement; + + // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest + // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it. + return Math.max( + elem.body[ "scroll" + name ], doc[ "scroll" + name ], + elem.body[ "offset" + name ], doc[ "offset" + name ], + doc[ "client" + name ] + ); + } + + return value === undefined ? + // Get width or height on the element, requesting but not forcing parseFloat + jQuery.css( elem, type, extra ) : + + // Set width or height on the element + jQuery.style( elem, type, value, extra ); + }, type, chainable ? margin : undefined, chainable, null ); + }; + }); +}); + + +// The number of elements contained in the matched element set +jQuery.fn.size = function() { + return this.length; +}; + +jQuery.fn.andSelf = jQuery.fn.addBack; + + + + +// Register as a named AMD module, since jQuery can be concatenated with other +// files that may use define, but not via a proper concatenation script that +// understands anonymous AMD modules. A named AMD is safest and most robust +// way to register. Lowercase jquery is used because AMD module names are +// derived from file names, and jQuery is normally delivered in a lowercase +// file name. Do this after creating the global so that if an AMD module wants +// to call noConflict to hide this version of jQuery, it will work. + +// Note that for maximum portability, libraries that are not jQuery should +// declare themselves as anonymous modules, and avoid setting a global if an +// AMD loader is present. jQuery is a special case. For more information, see +// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon + +if ( typeof define === "function" && define.amd ) { + define( "jquery", [], function() { + return jQuery; + }); +} + + + + +var + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$; + +jQuery.noConflict = function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; +}; + +// Expose jQuery and $ identifiers, even in +// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557) +// and CommonJS for browser emulators (#13566) +if ( typeof noGlobal === strundefined ) { + window.jQuery = window.$ = jQuery; +} + + + + +return jQuery; + +})); +/*! + * jQuery UI Core 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/category/ui-core/ + */ + +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "jquery" ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +}(function( $ ) { + +// $.ui might exist from components with no dependencies, e.g., $.ui.position +$.ui = $.ui || {}; + +$.extend( $.ui, { + version: "1.11.4", + + keyCode: { + BACKSPACE: 8, + COMMA: 188, + DELETE: 46, + DOWN: 40, + END: 35, + ENTER: 13, + ESCAPE: 27, + HOME: 36, + LEFT: 37, + PAGE_DOWN: 34, + PAGE_UP: 33, + PERIOD: 190, + RIGHT: 39, + SPACE: 32, + TAB: 9, + UP: 38 + } +}); + +// plugins +$.fn.extend({ + scrollParent: function( includeHidden ) { + var position = this.css( "position" ), + excludeStaticParent = position === "absolute", + overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, + scrollParent = this.parents().filter( function() { + var parent = $( this ); + if ( excludeStaticParent && parent.css( "position" ) === "static" ) { + return false; + } + return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) ); + }).eq( 0 ); + + return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent; + }, + + uniqueId: (function() { + var uuid = 0; + + return function() { + return this.each(function() { + if ( !this.id ) { + this.id = "ui-id-" + ( ++uuid ); + } + }); + }; + })(), + + removeUniqueId: function() { + return this.each(function() { + if ( /^ui-id-\d+$/.test( this.id ) ) { + $( this ).removeAttr( "id" ); + } + }); + } +}); + +// selectors +function focusable( element, isTabIndexNotNaN ) { + var map, mapName, img, + nodeName = element.nodeName.toLowerCase(); + if ( "area" === nodeName ) { + map = element.parentNode; + mapName = map.name; + if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { + return false; + } + img = $( "img[usemap='#" + mapName + "']" )[ 0 ]; + return !!img && visible( img ); + } + return ( /^(input|select|textarea|button|object)$/.test( nodeName ) ? + !element.disabled : + "a" === nodeName ? + element.href || isTabIndexNotNaN : + isTabIndexNotNaN) && + // the element and all of its ancestors must be visible + visible( element ); +} + +function visible( element ) { + return $.expr.filters.visible( element ) && + !$( element ).parents().addBack().filter(function() { + return $.css( this, "visibility" ) === "hidden"; + }).length; +} + +$.extend( $.expr[ ":" ], { + data: $.expr.createPseudo ? + $.expr.createPseudo(function( dataName ) { + return function( elem ) { + return !!$.data( elem, dataName ); + }; + }) : + // support: jQuery <1.8 + function( elem, i, match ) { + return !!$.data( elem, match[ 3 ] ); + }, + + focusable: function( element ) { + return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); + }, + + tabbable: function( element ) { + var tabIndex = $.attr( element, "tabindex" ), + isTabIndexNaN = isNaN( tabIndex ); + return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); + } +}); + +// support: jQuery <1.8 +if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { + $.each( [ "Width", "Height" ], function( i, name ) { + var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], + type = name.toLowerCase(), + orig = { + innerWidth: $.fn.innerWidth, + innerHeight: $.fn.innerHeight, + outerWidth: $.fn.outerWidth, + outerHeight: $.fn.outerHeight + }; + + function reduce( elem, size, border, margin ) { + $.each( side, function() { + size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; + if ( border ) { + size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; + } + if ( margin ) { + size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; + } + }); + return size; + } + + $.fn[ "inner" + name ] = function( size ) { + if ( size === undefined ) { + return orig[ "inner" + name ].call( this ); + } + + return this.each(function() { + $( this ).css( type, reduce( this, size ) + "px" ); + }); + }; + + $.fn[ "outer" + name] = function( size, margin ) { + if ( typeof size !== "number" ) { + return orig[ "outer" + name ].call( this, size ); + } + + return this.each(function() { + $( this).css( type, reduce( this, size, true, margin ) + "px" ); + }); + }; + }); +} + +// support: jQuery <1.8 +if ( !$.fn.addBack ) { + $.fn.addBack = function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + }; +} + +// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) +if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { + $.fn.removeData = (function( removeData ) { + return function( key ) { + if ( arguments.length ) { + return removeData.call( this, $.camelCase( key ) ); + } else { + return removeData.call( this ); + } + }; + })( $.fn.removeData ); +} + +// deprecated +$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); + +$.fn.extend({ + focus: (function( orig ) { + return function( delay, fn ) { + return typeof delay === "number" ? + this.each(function() { + var elem = this; + setTimeout(function() { + $( elem ).focus(); + if ( fn ) { + fn.call( elem ); + } + }, delay ); + }) : + orig.apply( this, arguments ); + }; + })( $.fn.focus ), + + disableSelection: (function() { + var eventType = "onselectstart" in document.createElement( "div" ) ? + "selectstart" : + "mousedown"; + + return function() { + return this.bind( eventType + ".ui-disableSelection", function( event ) { + event.preventDefault(); + }); + }; + })(), + + enableSelection: function() { + return this.unbind( ".ui-disableSelection" ); + }, + + zIndex: function( zIndex ) { + if ( zIndex !== undefined ) { + return this.css( "zIndex", zIndex ); + } + + if ( this.length ) { + var elem = $( this[ 0 ] ), position, value; + while ( elem.length && elem[ 0 ] !== document ) { + // Ignore z-index if position is set to a value where z-index is ignored by the browser + // This makes behavior of this function consistent across browsers + // WebKit always returns auto if the element is positioned + position = elem.css( "position" ); + if ( position === "absolute" || position === "relative" || position === "fixed" ) { + // IE returns 0 when zIndex is not specified + // other browsers return a string + // we ignore the case of nested elements with an explicit value of 0 + // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> + value = parseInt( elem.css( "zIndex" ), 10 ); + if ( !isNaN( value ) && value !== 0 ) { + return value; + } + } + elem = elem.parent(); + } + } + + return 0; + } +}); + +// $.ui.plugin is deprecated. Use $.widget() extensions instead. +$.ui.plugin = { + add: function( module, option, set ) { + var i, + proto = $.ui[ module ].prototype; + for ( i in set ) { + proto.plugins[ i ] = proto.plugins[ i ] || []; + proto.plugins[ i ].push( [ option, set[ i ] ] ); + } + }, + call: function( instance, name, args, allowDisconnected ) { + var i, + set = instance.plugins[ name ]; + + if ( !set ) { + return; + } + + if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) { + return; + } + + for ( i = 0; i < set.length; i++ ) { + if ( instance.options[ set[ i ][ 0 ] ] ) { + set[ i ][ 1 ].apply( instance.element, args ); + } + } + } +}; + +})); + + +/*! + * jQuery UI Datepicker 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/datepicker/ + */ + +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define([ + "jquery", + "./core" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +}(function( $ ) { + +$.extend($.ui, { datepicker: { version: "1.11.4" } }); + +var datepicker_instActive; + +function datepicker_getZindex( elem ) { + var position, value; + while ( elem.length && elem[ 0 ] !== document ) { + // Ignore z-index if position is set to a value where z-index is ignored by the browser + // This makes behavior of this function consistent across browsers + // WebKit always returns auto if the element is positioned + position = elem.css( "position" ); + if ( position === "absolute" || position === "relative" || position === "fixed" ) { + // IE returns 0 when zIndex is not specified + // other browsers return a string + // we ignore the case of nested elements with an explicit value of 0 + // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> + value = parseInt( elem.css( "zIndex" ), 10 ); + if ( !isNaN( value ) && value !== 0 ) { + return value; + } + } + elem = elem.parent(); + } + + return 0; +} +/* Date picker manager. + Use the singleton instance of this class, $.datepicker, to interact with the date picker. + Settings for (groups of) date pickers are maintained in an instance object, + allowing multiple different settings on the same page. */ + +function Datepicker() { + this._curInst = null; // The current instance in use + this._keyEvent = false; // If the last event was a key event + this._disabledInputs = []; // List of date picker inputs that have been disabled + this._datepickerShowing = false; // True if the popup picker is showing , false if not + this._inDialog = false; // True if showing within a "dialog", false if not + this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division + this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class + this._appendClass = "ui-datepicker-append"; // The name of the append marker class + this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class + this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class + this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class + this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class + this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class + this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class + this.regional = []; // Available regional settings, indexed by language code + this.regional[""] = { // Default regional settings + closeText: "Done", // Display text for close link + prevText: "Prev", // Display text for previous month link + nextText: "Next", // Display text for next month link + currentText: "Today", // Display text for current month link + monthNames: ["January","February","March","April","May","June", + "July","August","September","October","November","December"], // Names of months for drop-down and formatting + monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting + dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting + dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting + dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday + weekHeader: "Wk", // Column header for week of the year + dateFormat: "mm/dd/yy", // See format options on parseDate + firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... + isRTL: false, // True if right-to-left language, false if left-to-right + showMonthAfterYear: false, // True if the year select precedes month, false for month then year + yearSuffix: "" // Additional text to append to the year in the month headers + }; + this._defaults = { // Global defaults for all the date picker instances + showOn: "focus", // "focus" for popup on focus, + // "button" for trigger button, or "both" for either + showAnim: "fadeIn", // Name of jQuery animation for popup + showOptions: {}, // Options for enhanced animations + defaultDate: null, // Used when field is blank: actual date, + // +/-number for offset from today, null for today + appendText: "", // Display text following the input box, e.g. showing the format + buttonText: "...", // Text for trigger button + buttonImage: "", // URL for trigger button image + buttonImageOnly: false, // True if the image appears alone, false if it appears on a button + hideIfNoPrevNext: false, // True to hide next/previous month links + // if not applicable, false to just disable them + navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links + gotoCurrent: false, // True if today link goes back to current selection instead + changeMonth: false, // True if month can be selected directly, false if only prev/next + changeYear: false, // True if year can be selected directly, false if only prev/next + yearRange: "c-10:c+10", // Range of years to display in drop-down, + // either relative to today's year (-nn:+nn), relative to currently displayed year + // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) + showOtherMonths: false, // True to show dates in other months, false to leave blank + selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable + showWeek: false, // True to show week of the year, false to not show it + calculateWeek: this.iso8601Week, // How to calculate the week of the year, + // takes a Date and returns the number of the week for it + shortYearCutoff: "+10", // Short year values < this are in the current century, + // > this are in the previous century, + // string value starting with "+" for current year + value + minDate: null, // The earliest selectable date, or null for no limit + maxDate: null, // The latest selectable date, or null for no limit + duration: "fast", // Duration of display/closure + beforeShowDay: null, // Function that takes a date and returns an array with + // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", + // [2] = cell title (optional), e.g. $.datepicker.noWeekends + beforeShow: null, // Function that takes an input field and + // returns a set of custom settings for the date picker + onSelect: null, // Define a callback function when a date is selected + onChangeMonthYear: null, // Define a callback function when the month or year is changed + onClose: null, // Define a callback function when the datepicker is closed + numberOfMonths: 1, // Number of months to show at a time + showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) + stepMonths: 1, // Number of months to step back/forward + stepBigMonths: 12, // Number of months to step back/forward for the big links + altField: "", // Selector for an alternate field to store selected dates into + altFormat: "", // The date format to use for the alternate field + constrainInput: true, // The input is constrained by the current date format + showButtonPanel: false, // True to show button panel, false to not show it + autoSize: false, // True to size the input for the date format, false to leave as is + disabled: false // The initial disabled state + }; + $.extend(this._defaults, this.regional[""]); + this.regional.en = $.extend( true, {}, this.regional[ "" ]); + this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); + this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")); +} + +$.extend(Datepicker.prototype, { + /* Class name added to elements to indicate already configured with a date picker. */ + markerClassName: "hasDatepicker", + + //Keep track of the maximum number of rows displayed (see #7043) + maxRows: 4, + + // TODO rename to "widget" when switching to widget factory + _widgetDatepicker: function() { + return this.dpDiv; + }, + + /* Override the default settings for all instances of the date picker. + * @param settings object - the new settings to use as defaults (anonymous object) + * @return the manager object + */ + setDefaults: function(settings) { + datepicker_extendRemove(this._defaults, settings || {}); + return this; + }, + + /* Attach the date picker to a jQuery selection. + * @param target element - the target input field or division or span + * @param settings object - the new settings to use for this date picker instance (anonymous) + */ + _attachDatepicker: function(target, settings) { + var nodeName, inline, inst; + nodeName = target.nodeName.toLowerCase(); + inline = (nodeName === "div" || nodeName === "span"); + if (!target.id) { + this.uuid += 1; + target.id = "dp" + this.uuid; + } + inst = this._newInst($(target), inline); + inst.settings = $.extend({}, settings || {}); + if (nodeName === "input") { + this._connectDatepicker(target, inst); + } else if (inline) { + this._inlineDatepicker(target, inst); + } + }, + + /* Create a new instance object. */ + _newInst: function(target, inline) { + var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars + return {id: id, input: target, // associated target + selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection + drawMonth: 0, drawYear: 0, // month being drawn + inline: inline, // is datepicker inline or not + dpDiv: (!inline ? this.dpDiv : // presentation div + datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; + }, + + /* Attach the date picker to an input field. */ + _connectDatepicker: function(target, inst) { + var input = $(target); + inst.append = $([]); + inst.trigger = $([]); + if (input.hasClass(this.markerClassName)) { + return; + } + this._attachments(input, inst); + input.addClass(this.markerClassName).keydown(this._doKeyDown). + keypress(this._doKeyPress).keyup(this._doKeyUp); + this._autoSize(inst); + $.data(target, "datepicker", inst); + //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) + if( inst.settings.disabled ) { + this._disableDatepicker( target ); + } + }, + + /* Make attachments based on settings. */ + _attachments: function(input, inst) { + var showOn, buttonText, buttonImage, + appendText = this._get(inst, "appendText"), + isRTL = this._get(inst, "isRTL"); + + if (inst.append) { + inst.append.remove(); + } + if (appendText) { + inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>"); + input[isRTL ? "before" : "after"](inst.append); + } + + input.unbind("focus", this._showDatepicker); + + if (inst.trigger) { + inst.trigger.remove(); + } + + showOn = this._get(inst, "showOn"); + if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field + input.focus(this._showDatepicker); + } + if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked + buttonText = this._get(inst, "buttonText"); + buttonImage = this._get(inst, "buttonImage"); + inst.trigger = $(this._get(inst, "buttonImageOnly") ? + $("<img/>").addClass(this._triggerClass). + attr({ src: buttonImage, alt: buttonText, title: buttonText }) : + $("<button type='button'></button>").addClass(this._triggerClass). + html(!buttonImage ? buttonText : $("<img/>").attr( + { src:buttonImage, alt:buttonText, title:buttonText }))); + input[isRTL ? "before" : "after"](inst.trigger); + inst.trigger.click(function() { + if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { + $.datepicker._hideDatepicker(); + } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { + $.datepicker._hideDatepicker(); + $.datepicker._showDatepicker(input[0]); + } else { + $.datepicker._showDatepicker(input[0]); + } + return false; + }); + } + }, + + /* Apply the maximum length for the date format. */ + _autoSize: function(inst) { + if (this._get(inst, "autoSize") && !inst.inline) { + var findMax, max, maxI, i, + date = new Date(2009, 12 - 1, 20), // Ensure double digits + dateFormat = this._get(inst, "dateFormat"); + + if (dateFormat.match(/[DM]/)) { + findMax = function(names) { + max = 0; + maxI = 0; + for (i = 0; i < names.length; i++) { + if (names[i].length > max) { + max = names[i].length; + maxI = i; + } + } + return maxI; + }; + date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? + "monthNames" : "monthNamesShort")))); + date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? + "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); + } + inst.input.attr("size", this._formatDate(inst, date).length); + } + }, + + /* Attach an inline date picker to a div. */ + _inlineDatepicker: function(target, inst) { + var divSpan = $(target); + if (divSpan.hasClass(this.markerClassName)) { + return; + } + divSpan.addClass(this.markerClassName).append(inst.dpDiv); + $.data(target, "datepicker", inst); + this._setDate(inst, this._getDefaultDate(inst), true); + this._updateDatepicker(inst); + this._updateAlternate(inst); + //If disabled option is true, disable the datepicker before showing it (see ticket #5665) + if( inst.settings.disabled ) { + this._disableDatepicker( target ); + } + // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements + // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height + inst.dpDiv.css( "display", "block" ); + }, + + /* Pop-up the date picker in a "dialog" box. + * @param input element - ignored + * @param date string or Date - the initial date to display + * @param onSelect function - the function to call when a date is selected + * @param settings object - update the dialog date picker instance's settings (anonymous object) + * @param pos int[2] - coordinates for the dialog's position within the screen or + * event - with x/y coordinates or + * leave empty for default (screen centre) + * @return the manager object + */ + _dialogDatepicker: function(input, date, onSelect, settings, pos) { + var id, browserWidth, browserHeight, scrollX, scrollY, + inst = this._dialogInst; // internal instance + + if (!inst) { + this.uuid += 1; + id = "dp" + this.uuid; + this._dialogInput = $("<input type='text' id='" + id + + "' style='position: absolute; top: -100px; width: 0px;'/>"); + this._dialogInput.keydown(this._doKeyDown); + $("body").append(this._dialogInput); + inst = this._dialogInst = this._newInst(this._dialogInput, false); + inst.settings = {}; + $.data(this._dialogInput[0], "datepicker", inst); + } + datepicker_extendRemove(inst.settings, settings || {}); + date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); + this._dialogInput.val(date); + + this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); + if (!this._pos) { + browserWidth = document.documentElement.clientWidth; + browserHeight = document.documentElement.clientHeight; + scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; + scrollY = document.documentElement.scrollTop || document.body.scrollTop; + this._pos = // should use actual width/height below + [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; + } + + // move input on screen for focus, but hidden behind dialog + this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); + inst.settings.onSelect = onSelect; + this._inDialog = true; + this.dpDiv.addClass(this._dialogClass); + this._showDatepicker(this._dialogInput[0]); + if ($.blockUI) { + $.blockUI(this.dpDiv); + } + $.data(this._dialogInput[0], "datepicker", inst); + return this; + }, + + /* Detach a datepicker from its control. + * @param target element - the target input field or division or span + */ + _destroyDatepicker: function(target) { + var nodeName, + $target = $(target), + inst = $.data(target, "datepicker"); + + if (!$target.hasClass(this.markerClassName)) { + return; + } + + nodeName = target.nodeName.toLowerCase(); + $.removeData(target, "datepicker"); + if (nodeName === "input") { + inst.append.remove(); + inst.trigger.remove(); + $target.removeClass(this.markerClassName). + unbind("focus", this._showDatepicker). + unbind("keydown", this._doKeyDown). + unbind("keypress", this._doKeyPress). + unbind("keyup", this._doKeyUp); + } else if (nodeName === "div" || nodeName === "span") { + $target.removeClass(this.markerClassName).empty(); + } + + if ( datepicker_instActive === inst ) { + datepicker_instActive = null; + } + }, + + /* Enable the date picker to a jQuery selection. + * @param target element - the target input field or division or span + */ + _enableDatepicker: function(target) { + var nodeName, inline, + $target = $(target), + inst = $.data(target, "datepicker"); + + if (!$target.hasClass(this.markerClassName)) { + return; + } + + nodeName = target.nodeName.toLowerCase(); + if (nodeName === "input") { + target.disabled = false; + inst.trigger.filter("button"). + each(function() { this.disabled = false; }).end(). + filter("img").css({opacity: "1.0", cursor: ""}); + } else if (nodeName === "div" || nodeName === "span") { + inline = $target.children("." + this._inlineClass); + inline.children().removeClass("ui-state-disabled"); + inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). + prop("disabled", false); + } + this._disabledInputs = $.map(this._disabledInputs, + function(value) { return (value === target ? null : value); }); // delete entry + }, + + /* Disable the date picker to a jQuery selection. + * @param target element - the target input field or division or span + */ + _disableDatepicker: function(target) { + var nodeName, inline, + $target = $(target), + inst = $.data(target, "datepicker"); + + if (!$target.hasClass(this.markerClassName)) { + return; + } + + nodeName = target.nodeName.toLowerCase(); + if (nodeName === "input") { + target.disabled = true; + inst.trigger.filter("button"). + each(function() { this.disabled = true; }).end(). + filter("img").css({opacity: "0.5", cursor: "default"}); + } else if (nodeName === "div" || nodeName === "span") { + inline = $target.children("." + this._inlineClass); + inline.children().addClass("ui-state-disabled"); + inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). + prop("disabled", true); + } + this._disabledInputs = $.map(this._disabledInputs, + function(value) { return (value === target ? null : value); }); // delete entry + this._disabledInputs[this._disabledInputs.length] = target; + }, + + /* Is the first field in a jQuery collection disabled as a datepicker? + * @param target element - the target input field or division or span + * @return boolean - true if disabled, false if enabled + */ + _isDisabledDatepicker: function(target) { + if (!target) { + return false; + } + for (var i = 0; i < this._disabledInputs.length; i++) { + if (this._disabledInputs[i] === target) { + return true; + } + } + return false; + }, + + /* Retrieve the instance data for the target control. + * @param target element - the target input field or division or span + * @return object - the associated instance data + * @throws error if a jQuery problem getting data + */ + _getInst: function(target) { + try { + return $.data(target, "datepicker"); + } + catch (err) { + throw "Missing instance data for this datepicker"; + } + }, + + /* Update or retrieve the settings for a date picker attached to an input field or division. + * @param target element - the target input field or division or span + * @param name object - the new settings to update or + * string - the name of the setting to change or retrieve, + * when retrieving also "all" for all instance settings or + * "defaults" for all global defaults + * @param value any - the new value for the setting + * (omit if above is an object or to retrieve a value) + */ + _optionDatepicker: function(target, name, value) { + var settings, date, minDate, maxDate, + inst = this._getInst(target); + + if (arguments.length === 2 && typeof name === "string") { + return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : + (inst ? (name === "all" ? $.extend({}, inst.settings) : + this._get(inst, name)) : null)); + } + + settings = name || {}; + if (typeof name === "string") { + settings = {}; + settings[name] = value; + } + + if (inst) { + if (this._curInst === inst) { + this._hideDatepicker(); + } + + date = this._getDateDatepicker(target, true); + minDate = this._getMinMaxDate(inst, "min"); + maxDate = this._getMinMaxDate(inst, "max"); + datepicker_extendRemove(inst.settings, settings); + // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided + if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { + inst.settings.minDate = this._formatDate(inst, minDate); + } + if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { + inst.settings.maxDate = this._formatDate(inst, maxDate); + } + if ( "disabled" in settings ) { + if ( settings.disabled ) { + this._disableDatepicker(target); + } else { + this._enableDatepicker(target); + } + } + this._attachments($(target), inst); + this._autoSize(inst); + this._setDate(inst, date); + this._updateAlternate(inst); + this._updateDatepicker(inst); + } + }, + + // change method deprecated + _changeDatepicker: function(target, name, value) { + this._optionDatepicker(target, name, value); + }, + + /* Redraw the date picker attached to an input field or division. + * @param target element - the target input field or division or span + */ + _refreshDatepicker: function(target) { + var inst = this._getInst(target); + if (inst) { + this._updateDatepicker(inst); + } + }, + + /* Set the dates for a jQuery selection. + * @param target element - the target input field or division or span + * @param date Date - the new date + */ + _setDateDatepicker: function(target, date) { + var inst = this._getInst(target); + if (inst) { + this._setDate(inst, date); + this._updateDatepicker(inst); + this._updateAlternate(inst); + } + }, + + /* Get the date(s) for the first entry in a jQuery selection. + * @param target element - the target input field or division or span + * @param noDefault boolean - true if no default date is to be used + * @return Date - the current date + */ + _getDateDatepicker: function(target, noDefault) { + var inst = this._getInst(target); + if (inst && !inst.inline) { + this._setDateFromField(inst, noDefault); + } + return (inst ? this._getDate(inst) : null); + }, + + /* Handle keystrokes. */ + _doKeyDown: function(event) { + var onSelect, dateStr, sel, + inst = $.datepicker._getInst(event.target), + handled = true, + isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); + + inst._keyEvent = true; + if ($.datepicker._datepickerShowing) { + switch (event.keyCode) { + case 9: $.datepicker._hideDatepicker(); + handled = false; + break; // hide on tab out + case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + + $.datepicker._currentClass + ")", inst.dpDiv); + if (sel[0]) { + $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); + } + + onSelect = $.datepicker._get(inst, "onSelect"); + if (onSelect) { + dateStr = $.datepicker._formatDate(inst); + + // trigger custom callback + onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); + } else { + $.datepicker._hideDatepicker(); + } + + return false; // don't submit the form + case 27: $.datepicker._hideDatepicker(); + break; // hide on escape + case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? + -$.datepicker._get(inst, "stepBigMonths") : + -$.datepicker._get(inst, "stepMonths")), "M"); + break; // previous month/year on page up/+ ctrl + case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? + +$.datepicker._get(inst, "stepBigMonths") : + +$.datepicker._get(inst, "stepMonths")), "M"); + break; // next month/year on page down/+ ctrl + case 35: if (event.ctrlKey || event.metaKey) { + $.datepicker._clearDate(event.target); + } + handled = event.ctrlKey || event.metaKey; + break; // clear on ctrl or command +end + case 36: if (event.ctrlKey || event.metaKey) { + $.datepicker._gotoToday(event.target); + } + handled = event.ctrlKey || event.metaKey; + break; // current on ctrl or command +home + case 37: if (event.ctrlKey || event.metaKey) { + $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); + } + handled = event.ctrlKey || event.metaKey; + // -1 day on ctrl or command +left + if (event.originalEvent.altKey) { + $.datepicker._adjustDate(event.target, (event.ctrlKey ? + -$.datepicker._get(inst, "stepBigMonths") : + -$.datepicker._get(inst, "stepMonths")), "M"); + } + // next month/year on alt +left on Mac + break; + case 38: if (event.ctrlKey || event.metaKey) { + $.datepicker._adjustDate(event.target, -7, "D"); + } + handled = event.ctrlKey || event.metaKey; + break; // -1 week on ctrl or command +up + case 39: if (event.ctrlKey || event.metaKey) { + $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); + } + handled = event.ctrlKey || event.metaKey; + // +1 day on ctrl or command +right + if (event.originalEvent.altKey) { + $.datepicker._adjustDate(event.target, (event.ctrlKey ? + +$.datepicker._get(inst, "stepBigMonths") : + +$.datepicker._get(inst, "stepMonths")), "M"); + } + // next month/year on alt +right + break; + case 40: if (event.ctrlKey || event.metaKey) { + $.datepicker._adjustDate(event.target, +7, "D"); + } + handled = event.ctrlKey || event.metaKey; + break; // +1 week on ctrl or command +down + default: handled = false; + } + } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home + $.datepicker._showDatepicker(this); + } else { + handled = false; + } + + if (handled) { + event.preventDefault(); + event.stopPropagation(); + } + }, + + /* Filter entered characters - based on date format. */ + _doKeyPress: function(event) { + var chars, chr, + inst = $.datepicker._getInst(event.target); + + if ($.datepicker._get(inst, "constrainInput")) { + chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); + chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); + return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); + } + }, + + /* Synchronise manual entry and field/alternate field. */ + _doKeyUp: function(event) { + var date, + inst = $.datepicker._getInst(event.target); + + if (inst.input.val() !== inst.lastVal) { + try { + date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), + (inst.input ? inst.input.val() : null), + $.datepicker._getFormatConfig(inst)); + + if (date) { // only if valid + $.datepicker._setDateFromField(inst); + $.datepicker._updateAlternate(inst); + $.datepicker._updateDatepicker(inst); + } + } + catch (err) { + } + } + return true; + }, + + /* Pop-up the date picker for a given input field. + * If false returned from beforeShow event handler do not show. + * @param input element - the input field attached to the date picker or + * event - if triggered by focus + */ + _showDatepicker: function(input) { + input = input.target || input; + if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger + input = $("input", input.parentNode)[0]; + } + + if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here + return; + } + + var inst, beforeShow, beforeShowSettings, isFixed, + offset, showAnim, duration; + + inst = $.datepicker._getInst(input); + if ($.datepicker._curInst && $.datepicker._curInst !== inst) { + $.datepicker._curInst.dpDiv.stop(true, true); + if ( inst && $.datepicker._datepickerShowing ) { + $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); + } + } + + beforeShow = $.datepicker._get(inst, "beforeShow"); + beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; + if(beforeShowSettings === false){ + return; + } + datepicker_extendRemove(inst.settings, beforeShowSettings); + + inst.lastVal = null; + $.datepicker._lastInput = input; + $.datepicker._setDateFromField(inst); + + if ($.datepicker._inDialog) { // hide cursor + input.value = ""; + } + if (!$.datepicker._pos) { // position below input + $.datepicker._pos = $.datepicker._findPos(input); + $.datepicker._pos[1] += input.offsetHeight; // add the height + } + + isFixed = false; + $(input).parents().each(function() { + isFixed |= $(this).css("position") === "fixed"; + return !isFixed; + }); + + offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; + $.datepicker._pos = null; + //to avoid flashes on Firefox + inst.dpDiv.empty(); + // determine sizing offscreen + inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); + $.datepicker._updateDatepicker(inst); + // fix width for dynamic number of date pickers + // and adjust position before showing + offset = $.datepicker._checkOffset(inst, offset, isFixed); + inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? + "static" : (isFixed ? "fixed" : "absolute")), display: "none", + left: offset.left + "px", top: offset.top + "px"}); + + if (!inst.inline) { + showAnim = $.datepicker._get(inst, "showAnim"); + duration = $.datepicker._get(inst, "duration"); + inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); + $.datepicker._datepickerShowing = true; + + if ( $.effects && $.effects.effect[ showAnim ] ) { + inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); + } else { + inst.dpDiv[showAnim || "show"](showAnim ? duration : null); + } + + if ( $.datepicker._shouldFocusInput( inst ) ) { + inst.input.focus(); + } + + $.datepicker._curInst = inst; + } + }, + + /* Generate the date picker content. */ + _updateDatepicker: function(inst) { + this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) + datepicker_instActive = inst; // for delegate hover events + inst.dpDiv.empty().append(this._generateHTML(inst)); + this._attachHandlers(inst); + + var origyearshtml, + numMonths = this._getNumberOfMonths(inst), + cols = numMonths[1], + width = 17, + activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ); + + if ( activeCell.length > 0 ) { + datepicker_handleMouseover.apply( activeCell.get( 0 ) ); + } + + inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); + if (cols > 1) { + inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); + } + inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + + "Class"]("ui-datepicker-multi"); + inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + + "Class"]("ui-datepicker-rtl"); + + if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { + inst.input.focus(); + } + + // deffered render of the years select (to avoid flashes on Firefox) + if( inst.yearshtml ){ + origyearshtml = inst.yearshtml; + setTimeout(function(){ + //assure that inst.yearshtml didn't change. + if( origyearshtml === inst.yearshtml && inst.yearshtml ){ + inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); + } + origyearshtml = inst.yearshtml = null; + }, 0); + } + }, + + // #6694 - don't focus the input if it's already focused + // this breaks the change event in IE + // Support: IE and jQuery <1.9 + _shouldFocusInput: function( inst ) { + return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); + }, + + /* Check positioning to remain on screen. */ + _checkOffset: function(inst, offset, isFixed) { + var dpWidth = inst.dpDiv.outerWidth(), + dpHeight = inst.dpDiv.outerHeight(), + inputWidth = inst.input ? inst.input.outerWidth() : 0, + inputHeight = inst.input ? inst.input.outerHeight() : 0, + viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), + viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); + + offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); + offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; + offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; + + // now check if datepicker is showing outside window viewport - move to a better place if so. + offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? + Math.abs(offset.left + dpWidth - viewWidth) : 0); + offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? + Math.abs(dpHeight + inputHeight) : 0); + + return offset; + }, + + /* Find an object's position on the screen. */ + _findPos: function(obj) { + var position, + inst = this._getInst(obj), + isRTL = this._get(inst, "isRTL"); + + while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { + obj = obj[isRTL ? "previousSibling" : "nextSibling"]; + } + + position = $(obj).offset(); + return [position.left, position.top]; + }, + + /* Hide the date picker from view. + * @param input element - the input field attached to the date picker + */ + _hideDatepicker: function(input) { + var showAnim, duration, postProcess, onClose, + inst = this._curInst; + + if (!inst || (input && inst !== $.data(input, "datepicker"))) { + return; + } + + if (this._datepickerShowing) { + showAnim = this._get(inst, "showAnim"); + duration = this._get(inst, "duration"); + postProcess = function() { + $.datepicker._tidyDialog(inst); + }; + + // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed + if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { + inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); + } else { + inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : + (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); + } + + if (!showAnim) { + postProcess(); + } + this._datepickerShowing = false; + + onClose = this._get(inst, "onClose"); + if (onClose) { + onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); + } + + this._lastInput = null; + if (this._inDialog) { + this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); + if ($.blockUI) { + $.unblockUI(); + $("body").append(this.dpDiv); + } + } + this._inDialog = false; + } + }, + + /* Tidy up after a dialog display. */ + _tidyDialog: function(inst) { + inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); + }, + + /* Close date picker if clicked elsewhere. */ + _checkExternalClick: function(event) { + if (!$.datepicker._curInst) { + return; + } + + var $target = $(event.target), + inst = $.datepicker._getInst($target[0]); + + if ( ( ( $target[0].id !== $.datepicker._mainDivId && + $target.parents("#" + $.datepicker._mainDivId).length === 0 && + !$target.hasClass($.datepicker.markerClassName) && + !$target.closest("." + $.datepicker._triggerClass).length && + $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || + ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { + $.datepicker._hideDatepicker(); + } + }, + + /* Adjust one of the date sub-fields. */ + _adjustDate: function(id, offset, period) { + var target = $(id), + inst = this._getInst(target[0]); + + if (this._isDisabledDatepicker(target[0])) { + return; + } + this._adjustInstDate(inst, offset + + (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning + period); + this._updateDatepicker(inst); + }, + + /* Action for current link. */ + _gotoToday: function(id) { + var date, + target = $(id), + inst = this._getInst(target[0]); + + if (this._get(inst, "gotoCurrent") && inst.currentDay) { + inst.selectedDay = inst.currentDay; + inst.drawMonth = inst.selectedMonth = inst.currentMonth; + inst.drawYear = inst.selectedYear = inst.currentYear; + } else { + date = new Date(); + inst.selectedDay = date.getDate(); + inst.drawMonth = inst.selectedMonth = date.getMonth(); + inst.drawYear = inst.selectedYear = date.getFullYear(); + } + this._notifyChange(inst); + this._adjustDate(target); + }, + + /* Action for selecting a new month/year. */ + _selectMonthYear: function(id, select, period) { + var target = $(id), + inst = this._getInst(target[0]); + + inst["selected" + (period === "M" ? "Month" : "Year")] = + inst["draw" + (period === "M" ? "Month" : "Year")] = + parseInt(select.options[select.selectedIndex].value,10); + + this._notifyChange(inst); + this._adjustDate(target); + }, + + /* Action for selecting a day. */ + _selectDay: function(id, month, year, td) { + var inst, + target = $(id); + + if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { + return; + } + + inst = this._getInst(target[0]); + inst.selectedDay = inst.currentDay = $("a", td).html(); + inst.selectedMonth = inst.currentMonth = month; + inst.selectedYear = inst.currentYear = year; + this._selectDate(id, this._formatDate(inst, + inst.currentDay, inst.currentMonth, inst.currentYear)); + }, + + /* Erase the input field and hide the date picker. */ + _clearDate: function(id) { + var target = $(id); + this._selectDate(target, ""); + }, + + /* Update the input field with the selected date. */ + _selectDate: function(id, dateStr) { + var onSelect, + target = $(id), + inst = this._getInst(target[0]); + + dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); + if (inst.input) { + inst.input.val(dateStr); + } + this._updateAlternate(inst); + + onSelect = this._get(inst, "onSelect"); + if (onSelect) { + onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback + } else if (inst.input) { + inst.input.trigger("change"); // fire the change event + } + + if (inst.inline){ + this._updateDatepicker(inst); + } else { + this._hideDatepicker(); + this._lastInput = inst.input[0]; + if (typeof(inst.input[0]) !== "object") { + inst.input.focus(); // restore focus + } + this._lastInput = null; + } + }, + + /* Update any alternate field to synchronise with the main field. */ + _updateAlternate: function(inst) { + var altFormat, date, dateStr, + altField = this._get(inst, "altField"); + + if (altField) { // update alternate field too + altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); + date = this._getDate(inst); + dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); + $(altField).each(function() { $(this).val(dateStr); }); + } + }, + + /* Set as beforeShowDay function to prevent selection of weekends. + * @param date Date - the date to customise + * @return [boolean, string] - is this date selectable?, what is its CSS class? + */ + noWeekends: function(date) { + var day = date.getDay(); + return [(day > 0 && day < 6), ""]; + }, + + /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. + * @param date Date - the date to get the week for + * @return number - the number of the week within the year that contains this date + */ + iso8601Week: function(date) { + var time, + checkDate = new Date(date.getTime()); + + // Find Thursday of this week starting on Monday + checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); + + time = checkDate.getTime(); + checkDate.setMonth(0); // Compare with Jan 1 + checkDate.setDate(1); + return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; + }, + + /* Parse a string value into a date object. + * See formatDate below for the possible formats. + * + * @param format string - the expected format of the date + * @param value string - the date in the above format + * @param settings Object - attributes include: + * shortYearCutoff number - the cutoff year for determining the century (optional) + * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) + * dayNames string[7] - names of the days from Sunday (optional) + * monthNamesShort string[12] - abbreviated names of the months (optional) + * monthNames string[12] - names of the months (optional) + * @return Date - the extracted date value or null if value is blank + */ + parseDate: function (format, value, settings) { + if (format == null || value == null) { + throw "Invalid arguments"; + } + + value = (typeof value === "object" ? value.toString() : value + ""); + if (value === "") { + return null; + } + + var iFormat, dim, extra, + iValue = 0, + shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, + shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : + new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), + dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, + dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, + monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, + monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, + year = -1, + month = -1, + day = -1, + doy = -1, + literal = false, + date, + // Check whether a format character is doubled + lookAhead = function(match) { + var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); + if (matches) { + iFormat++; + } + return matches; + }, + // Extract a number from the string value + getNumber = function(match) { + var isDoubled = lookAhead(match), + size = (match === "@" ? 14 : (match === "!" ? 20 : + (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), + minSize = (match === "y" ? size : 1), + digits = new RegExp("^\\d{" + minSize + "," + size + "}"), + num = value.substring(iValue).match(digits); + if (!num) { + throw "Missing number at position " + iValue; + } + iValue += num[0].length; + return parseInt(num[0], 10); + }, + // Extract a name from the string value and convert to an index + getName = function(match, shortNames, longNames) { + var index = -1, + names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { + return [ [k, v] ]; + }).sort(function (a, b) { + return -(a[1].length - b[1].length); + }); + + $.each(names, function (i, pair) { + var name = pair[1]; + if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { + index = pair[0]; + iValue += name.length; + return false; + } + }); + if (index !== -1) { + return index + 1; + } else { + throw "Unknown name at position " + iValue; + } + }, + // Confirm that a literal character matches the string value + checkLiteral = function() { + if (value.charAt(iValue) !== format.charAt(iFormat)) { + throw "Unexpected literal at position " + iValue; + } + iValue++; + }; + + for (iFormat = 0; iFormat < format.length; iFormat++) { + if (literal) { + if (format.charAt(iFormat) === "'" && !lookAhead("'")) { + literal = false; + } else { + checkLiteral(); + } + } else { + switch (format.charAt(iFormat)) { + case "d": + day = getNumber("d"); + break; + case "D": + getName("D", dayNamesShort, dayNames); + break; + case "o": + doy = getNumber("o"); + break; + case "m": + month = getNumber("m"); + break; + case "M": + month = getName("M", monthNamesShort, monthNames); + break; + case "y": + year = getNumber("y"); + break; + case "@": + date = new Date(getNumber("@")); + year = date.getFullYear(); + month = date.getMonth() + 1; + day = date.getDate(); + break; + case "!": + date = new Date((getNumber("!") - this._ticksTo1970) / 10000); + year = date.getFullYear(); + month = date.getMonth() + 1; + day = date.getDate(); + break; + case "'": + if (lookAhead("'")){ + checkLiteral(); + } else { + literal = true; + } + break; + default: + checkLiteral(); + } + } + } + + if (iValue < value.length){ + extra = value.substr(iValue); + if (!/^\s+/.test(extra)) { + throw "Extra/unparsed characters found in date: " + extra; + } + } + + if (year === -1) { + year = new Date().getFullYear(); + } else if (year < 100) { + year += new Date().getFullYear() - new Date().getFullYear() % 100 + + (year <= shortYearCutoff ? 0 : -100); + } + + if (doy > -1) { + month = 1; + day = doy; + do { + dim = this._getDaysInMonth(year, month - 1); + if (day <= dim) { + break; + } + month++; + day -= dim; + } while (true); + } + + date = this._daylightSavingAdjust(new Date(year, month - 1, day)); + if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { + throw "Invalid date"; // E.g. 31/02/00 + } + return date; + }, + + /* Standard date formats. */ + ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) + COOKIE: "D, dd M yy", + ISO_8601: "yy-mm-dd", + RFC_822: "D, d M y", + RFC_850: "DD, dd-M-y", + RFC_1036: "D, d M y", + RFC_1123: "D, d M yy", + RFC_2822: "D, d M yy", + RSS: "D, d M y", // RFC 822 + TICKS: "!", + TIMESTAMP: "@", + W3C: "yy-mm-dd", // ISO 8601 + + _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + + Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), + + /* Format a date object into a string value. + * The format can be combinations of the following: + * d - day of month (no leading zero) + * dd - day of month (two digit) + * o - day of year (no leading zeros) + * oo - day of year (three digit) + * D - day name short + * DD - day name long + * m - month of year (no leading zero) + * mm - month of year (two digit) + * M - month name short + * MM - month name long + * y - year (two digit) + * yy - year (four digit) + * @ - Unix timestamp (ms since 01/01/1970) + * ! - Windows ticks (100ns since 01/01/0001) + * "..." - literal text + * '' - single quote + * + * @param format string - the desired format of the date + * @param date Date - the date value to format + * @param settings Object - attributes include: + * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) + * dayNames string[7] - names of the days from Sunday (optional) + * monthNamesShort string[12] - abbreviated names of the months (optional) + * monthNames string[12] - names of the months (optional) + * @return string - the date in the above format + */ + formatDate: function (format, date, settings) { + if (!date) { + return ""; + } + + var iFormat, + dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, + dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, + monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, + monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, + // Check whether a format character is doubled + lookAhead = function(match) { + var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); + if (matches) { + iFormat++; + } + return matches; + }, + // Format a number, with leading zero if necessary + formatNumber = function(match, value, len) { + var num = "" + value; + if (lookAhead(match)) { + while (num.length < len) { + num = "0" + num; + } + } + return num; + }, + // Format a name, short or long as requested + formatName = function(match, value, shortNames, longNames) { + return (lookAhead(match) ? longNames[value] : shortNames[value]); + }, + output = "", + literal = false; + + if (date) { + for (iFormat = 0; iFormat < format.length; iFormat++) { + if (literal) { + if (format.charAt(iFormat) === "'" && !lookAhead("'")) { + literal = false; + } else { + output += format.charAt(iFormat); + } + } else { + switch (format.charAt(iFormat)) { + case "d": + output += formatNumber("d", date.getDate(), 2); + break; + case "D": + output += formatName("D", date.getDay(), dayNamesShort, dayNames); + break; + case "o": + output += formatNumber("o", + Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); + break; + case "m": + output += formatNumber("m", date.getMonth() + 1, 2); + break; + case "M": + output += formatName("M", date.getMonth(), monthNamesShort, monthNames); + break; + case "y": + output += (lookAhead("y") ? date.getFullYear() : + (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); + break; + case "@": + output += date.getTime(); + break; + case "!": + output += date.getTime() * 10000 + this._ticksTo1970; + break; + case "'": + if (lookAhead("'")) { + output += "'"; + } else { + literal = true; + } + break; + default: + output += format.charAt(iFormat); + } + } + } + } + return output; + }, + + /* Extract all possible characters from the date format. */ + _possibleChars: function (format) { + var iFormat, + chars = "", + literal = false, + // Check whether a format character is doubled + lookAhead = function(match) { + var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); + if (matches) { + iFormat++; + } + return matches; + }; + + for (iFormat = 0; iFormat < format.length; iFormat++) { + if (literal) { + if (format.charAt(iFormat) === "'" && !lookAhead("'")) { + literal = false; + } else { + chars += format.charAt(iFormat); + } + } else { + switch (format.charAt(iFormat)) { + case "d": case "m": case "y": case "@": + chars += "0123456789"; + break; + case "D": case "M": + return null; // Accept anything + case "'": + if (lookAhead("'")) { + chars += "'"; + } else { + literal = true; + } + break; + default: + chars += format.charAt(iFormat); + } + } + } + return chars; + }, + + /* Get a setting value, defaulting if necessary. */ + _get: function(inst, name) { + return inst.settings[name] !== undefined ? + inst.settings[name] : this._defaults[name]; + }, + + /* Parse existing date and initialise date picker. */ + _setDateFromField: function(inst, noDefault) { + if (inst.input.val() === inst.lastVal) { + return; + } + + var dateFormat = this._get(inst, "dateFormat"), + dates = inst.lastVal = inst.input ? inst.input.val() : null, + defaultDate = this._getDefaultDate(inst), + date = defaultDate, + settings = this._getFormatConfig(inst); + + try { + date = this.parseDate(dateFormat, dates, settings) || defaultDate; + } catch (event) { + dates = (noDefault ? "" : dates); + } + inst.selectedDay = date.getDate(); + inst.drawMonth = inst.selectedMonth = date.getMonth(); + inst.drawYear = inst.selectedYear = date.getFullYear(); + inst.currentDay = (dates ? date.getDate() : 0); + inst.currentMonth = (dates ? date.getMonth() : 0); + inst.currentYear = (dates ? date.getFullYear() : 0); + this._adjustInstDate(inst); + }, + + /* Retrieve the default date shown on opening. */ + _getDefaultDate: function(inst) { + return this._restrictMinMax(inst, + this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); + }, + + /* A date may be specified as an exact value or a relative one. */ + _determineDate: function(inst, date, defaultDate) { + var offsetNumeric = function(offset) { + var date = new Date(); + date.setDate(date.getDate() + offset); + return date; + }, + offsetString = function(offset) { + try { + return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), + offset, $.datepicker._getFormatConfig(inst)); + } + catch (e) { + // Ignore + } + + var date = (offset.toLowerCase().match(/^c/) ? + $.datepicker._getDate(inst) : null) || new Date(), + year = date.getFullYear(), + month = date.getMonth(), + day = date.getDate(), + pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, + matches = pattern.exec(offset); + + while (matches) { + switch (matches[2] || "d") { + case "d" : case "D" : + day += parseInt(matches[1],10); break; + case "w" : case "W" : + day += parseInt(matches[1],10) * 7; break; + case "m" : case "M" : + month += parseInt(matches[1],10); + day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); + break; + case "y": case "Y" : + year += parseInt(matches[1],10); + day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); + break; + } + matches = pattern.exec(offset); + } + return new Date(year, month, day); + }, + newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : + (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); + + newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); + if (newDate) { + newDate.setHours(0); + newDate.setMinutes(0); + newDate.setSeconds(0); + newDate.setMilliseconds(0); + } + return this._daylightSavingAdjust(newDate); + }, + + /* Handle switch to/from daylight saving. + * Hours may be non-zero on daylight saving cut-over: + * > 12 when midnight changeover, but then cannot generate + * midnight datetime, so jump to 1AM, otherwise reset. + * @param date (Date) the date to check + * @return (Date) the corrected date + */ + _daylightSavingAdjust: function(date) { + if (!date) { + return null; + } + date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); + return date; + }, + + /* Set the date(s) directly. */ + _setDate: function(inst, date, noChange) { + var clear = !date, + origMonth = inst.selectedMonth, + origYear = inst.selectedYear, + newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); + + inst.selectedDay = inst.currentDay = newDate.getDate(); + inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); + inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); + if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { + this._notifyChange(inst); + } + this._adjustInstDate(inst); + if (inst.input) { + inst.input.val(clear ? "" : this._formatDate(inst)); + } + }, + + /* Retrieve the date(s) directly. */ + _getDate: function(inst) { + var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : + this._daylightSavingAdjust(new Date( + inst.currentYear, inst.currentMonth, inst.currentDay))); + return startDate; + }, + + /* Attach the onxxx handlers. These are declared statically so + * they work with static code transformers like Caja. + */ + _attachHandlers: function(inst) { + var stepMonths = this._get(inst, "stepMonths"), + id = "#" + inst.id.replace( /\\\\/g, "\\" ); + inst.dpDiv.find("[data-handler]").map(function () { + var handler = { + prev: function () { + $.datepicker._adjustDate(id, -stepMonths, "M"); + }, + next: function () { + $.datepicker._adjustDate(id, +stepMonths, "M"); + }, + hide: function () { + $.datepicker._hideDatepicker(); + }, + today: function () { + $.datepicker._gotoToday(id); + }, + selectDay: function () { + $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); + return false; + }, + selectMonth: function () { + $.datepicker._selectMonthYear(id, this, "M"); + return false; + }, + selectYear: function () { + $.datepicker._selectMonthYear(id, this, "Y"); + return false; + } + }; + $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); + }); + }, + + /* Generate the HTML for the current state of the date picker. */ + _generateHTML: function(inst) { + var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, + controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, + monthNames, monthNamesShort, beforeShowDay, showOtherMonths, + selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, + cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, + printDate, dRow, tbody, daySettings, otherMonth, unselectable, + tempDate = new Date(), + today = this._daylightSavingAdjust( + new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time + isRTL = this._get(inst, "isRTL"), + showButtonPanel = this._get(inst, "showButtonPanel"), + hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), + navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), + numMonths = this._getNumberOfMonths(inst), + showCurrentAtPos = this._get(inst, "showCurrentAtPos"), + stepMonths = this._get(inst, "stepMonths"), + isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), + currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : + new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), + minDate = this._getMinMaxDate(inst, "min"), + maxDate = this._getMinMaxDate(inst, "max"), + drawMonth = inst.drawMonth - showCurrentAtPos, + drawYear = inst.drawYear; + + if (drawMonth < 0) { + drawMonth += 12; + drawYear--; + } + if (maxDate) { + maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), + maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); + maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); + while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { + drawMonth--; + if (drawMonth < 0) { + drawMonth = 11; + drawYear--; + } + } + } + inst.drawMonth = drawMonth; + inst.drawYear = drawYear; + + prevText = this._get(inst, "prevText"); + prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, + this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), + this._getFormatConfig(inst))); + + prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? + "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + + " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : + (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+ prevText +"'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>")); + + nextText = this._get(inst, "nextText"); + nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, + this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), + this._getFormatConfig(inst))); + + next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? + "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + + " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : + (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+ nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>")); + + currentText = this._get(inst, "currentText"); + gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); + currentText = (!navigationAsDateFormat ? currentText : + this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); + + controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" + + this._get(inst, "closeText") + "</button>" : ""); + + buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") + + (this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" + + ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; + + firstDay = parseInt(this._get(inst, "firstDay"),10); + firstDay = (isNaN(firstDay) ? 0 : firstDay); + + showWeek = this._get(inst, "showWeek"); + dayNames = this._get(inst, "dayNames"); + dayNamesMin = this._get(inst, "dayNamesMin"); + monthNames = this._get(inst, "monthNames"); + monthNamesShort = this._get(inst, "monthNamesShort"); + beforeShowDay = this._get(inst, "beforeShowDay"); + showOtherMonths = this._get(inst, "showOtherMonths"); + selectOtherMonths = this._get(inst, "selectOtherMonths"); + defaultDate = this._getDefaultDate(inst); + html = ""; + dow; + for (row = 0; row < numMonths[0]; row++) { + group = ""; + this.maxRows = 4; + for (col = 0; col < numMonths[1]; col++) { + selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); + cornerClass = " ui-corner-all"; + calender = ""; + if (isMultiMonth) { + calender += "<div class='ui-datepicker-group"; + if (numMonths[1] > 1) { + switch (col) { + case 0: calender += " ui-datepicker-group-first"; + cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break; + case numMonths[1]-1: calender += " ui-datepicker-group-last"; + cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break; + default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; + } + } + calender += "'>"; + } + calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + + (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + + (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + + this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, + row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers + "</div><table class='ui-datepicker-calendar'><thead>" + + "<tr>"; + thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : ""); + for (dow = 0; dow < 7; dow++) { // days of the week + day = (dow + firstDay) % 7; + thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + + "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>"; + } + calender += thead + "</tr></thead><tbody>"; + daysInMonth = this._getDaysInMonth(drawYear, drawMonth); + if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { + inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); + } + leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; + curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate + numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) + this.maxRows = numRows; + printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); + for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows + calender += "<tr>"; + tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" + + this._get(inst, "calculateWeek")(printDate) + "</td>"); + for (dow = 0; dow < 7; dow++) { // create date picker days + daySettings = (beforeShowDay ? + beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); + otherMonth = (printDate.getMonth() !== drawMonth); + unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || + (minDate && printDate < minDate) || (maxDate && printDate > maxDate); + tbody += "<td class='" + + ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends + (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months + ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key + (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ? + // or defaultDate is current printedDate and defaultDate is selectedDate + " " + this._dayOverClass : "") + // highlight selected day + (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days + (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates + (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day + (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different) + ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "'") + "'" : "") + // cell title + (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions + (otherMonth && !showOtherMonths ? " " : // display for other months + (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + + (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") + + (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day + (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months + "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date + printDate.setDate(printDate.getDate() + 1); + printDate = this._daylightSavingAdjust(printDate); + } + calender += tbody + "</tr>"; + } + drawMonth++; + if (drawMonth > 11) { + drawMonth = 0; + drawYear++; + } + calender += "</tbody></table>" + (isMultiMonth ? "</div>" + + ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); + group += calender; + } + html += group; + } + html += buttonPanel; + inst._keyEvent = false; + return html; + }, + + /* Generate the month and year header. */ + _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, + secondary, monthNames, monthNamesShort) { + + var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, + changeMonth = this._get(inst, "changeMonth"), + changeYear = this._get(inst, "changeYear"), + showMonthAfterYear = this._get(inst, "showMonthAfterYear"), + html = "<div class='ui-datepicker-title'>", + monthHtml = ""; + + // month selection + if (secondary || !changeMonth) { + monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>"; + } else { + inMinYear = (minDate && minDate.getFullYear() === drawYear); + inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); + monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; + for ( month = 0; month < 12; month++) { + if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { + monthHtml += "<option value='" + month + "'" + + (month === drawMonth ? " selected='selected'" : "") + + ">" + monthNamesShort[month] + "</option>"; + } + } + monthHtml += "</select>"; + } + + if (!showMonthAfterYear) { + html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); + } + + // year selection + if ( !inst.yearshtml ) { + inst.yearshtml = ""; + if (secondary || !changeYear) { + html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; + } else { + // determine range of years to display + years = this._get(inst, "yearRange").split(":"); + thisYear = new Date().getFullYear(); + determineYear = function(value) { + var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : + (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : + parseInt(value, 10))); + return (isNaN(year) ? thisYear : year); + }; + year = determineYear(years[0]); + endYear = Math.max(year, determineYear(years[1] || "")); + year = (minDate ? Math.max(year, minDate.getFullYear()) : year); + endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); + inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; + for (; year <= endYear; year++) { + inst.yearshtml += "<option value='" + year + "'" + + (year === drawYear ? " selected='selected'" : "") + + ">" + year + "</option>"; + } + inst.yearshtml += "</select>"; + + html += inst.yearshtml; + inst.yearshtml = null; + } + } + + html += this._get(inst, "yearSuffix"); + if (showMonthAfterYear) { + html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; + } + html += "</div>"; // Close datepicker_header + return html; + }, + + /* Adjust one of the date sub-fields. */ + _adjustInstDate: function(inst, offset, period) { + var year = inst.drawYear + (period === "Y" ? offset : 0), + month = inst.drawMonth + (period === "M" ? offset : 0), + day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), + date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); + + inst.selectedDay = date.getDate(); + inst.drawMonth = inst.selectedMonth = date.getMonth(); + inst.drawYear = inst.selectedYear = date.getFullYear(); + if (period === "M" || period === "Y") { + this._notifyChange(inst); + } + }, + + /* Ensure a date is within any min/max bounds. */ + _restrictMinMax: function(inst, date) { + var minDate = this._getMinMaxDate(inst, "min"), + maxDate = this._getMinMaxDate(inst, "max"), + newDate = (minDate && date < minDate ? minDate : date); + return (maxDate && newDate > maxDate ? maxDate : newDate); + }, + + /* Notify change of month/year. */ + _notifyChange: function(inst) { + var onChange = this._get(inst, "onChangeMonthYear"); + if (onChange) { + onChange.apply((inst.input ? inst.input[0] : null), + [inst.selectedYear, inst.selectedMonth + 1, inst]); + } + }, + + /* Determine the number of months to show. */ + _getNumberOfMonths: function(inst) { + var numMonths = this._get(inst, "numberOfMonths"); + return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); + }, + + /* Determine the current maximum date - ensure no time components are set. */ + _getMinMaxDate: function(inst, minMax) { + return this._determineDate(inst, this._get(inst, minMax + "Date"), null); + }, + + /* Find the number of days in a given month. */ + _getDaysInMonth: function(year, month) { + return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); + }, + + /* Find the day of the week of the first of a month. */ + _getFirstDayOfMonth: function(year, month) { + return new Date(year, month, 1).getDay(); + }, + + /* Determines if we should allow a "next/prev" month display change. */ + _canAdjustMonth: function(inst, offset, curYear, curMonth) { + var numMonths = this._getNumberOfMonths(inst), + date = this._daylightSavingAdjust(new Date(curYear, + curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); + + if (offset < 0) { + date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); + } + return this._isInRange(inst, date); + }, + + /* Is the given date in the accepted range? */ + _isInRange: function(inst, date) { + var yearSplit, currentYear, + minDate = this._getMinMaxDate(inst, "min"), + maxDate = this._getMinMaxDate(inst, "max"), + minYear = null, + maxYear = null, + years = this._get(inst, "yearRange"); + if (years){ + yearSplit = years.split(":"); + currentYear = new Date().getFullYear(); + minYear = parseInt(yearSplit[0], 10); + maxYear = parseInt(yearSplit[1], 10); + if ( yearSplit[0].match(/[+\-].*/) ) { + minYear += currentYear; + } + if ( yearSplit[1].match(/[+\-].*/) ) { + maxYear += currentYear; + } + } + + return ((!minDate || date.getTime() >= minDate.getTime()) && + (!maxDate || date.getTime() <= maxDate.getTime()) && + (!minYear || date.getFullYear() >= minYear) && + (!maxYear || date.getFullYear() <= maxYear)); + }, + + /* Provide the configuration settings for formatting/parsing. */ + _getFormatConfig: function(inst) { + var shortYearCutoff = this._get(inst, "shortYearCutoff"); + shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : + new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); + return {shortYearCutoff: shortYearCutoff, + dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), + monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; + }, + + /* Format the given date for display. */ + _formatDate: function(inst, day, month, year) { + if (!day) { + inst.currentDay = inst.selectedDay; + inst.currentMonth = inst.selectedMonth; + inst.currentYear = inst.selectedYear; + } + var date = (day ? (typeof day === "object" ? day : + this._daylightSavingAdjust(new Date(year, month, day))) : + this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); + return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); + } +}); + +/* + * Bind hover events for datepicker elements. + * Done via delegate so the binding only occurs once in the lifetime of the parent div. + * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. + */ +function datepicker_bindHover(dpDiv) { + var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; + return dpDiv.delegate(selector, "mouseout", function() { + $(this).removeClass("ui-state-hover"); + if (this.className.indexOf("ui-datepicker-prev") !== -1) { + $(this).removeClass("ui-datepicker-prev-hover"); + } + if (this.className.indexOf("ui-datepicker-next") !== -1) { + $(this).removeClass("ui-datepicker-next-hover"); + } + }) + .delegate( selector, "mouseover", datepicker_handleMouseover ); +} + +function datepicker_handleMouseover() { + if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) { + $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); + $(this).addClass("ui-state-hover"); + if (this.className.indexOf("ui-datepicker-prev") !== -1) { + $(this).addClass("ui-datepicker-prev-hover"); + } + if (this.className.indexOf("ui-datepicker-next") !== -1) { + $(this).addClass("ui-datepicker-next-hover"); + } + } +} + +/* jQuery extend now ignores nulls! */ +function datepicker_extendRemove(target, props) { + $.extend(target, props); + for (var name in props) { + if (props[name] == null) { + target[name] = props[name]; + } + } + return target; +} + +/* Invoke the datepicker functionality. + @param options string - a command, optionally followed by additional parameters or + Object - settings for attaching new datepicker functionality + @return jQuery object */ +$.fn.datepicker = function(options){ + + /* Verify an empty collection wasn't passed - Fixes #6976 */ + if ( !this.length ) { + return this; + } + + /* Initialise the date picker. */ + if (!$.datepicker.initialized) { + $(document).mousedown($.datepicker._checkExternalClick); + $.datepicker.initialized = true; + } + + /* Append datepicker main container to body if not exist. */ + if ($("#"+$.datepicker._mainDivId).length === 0) { + $("body").append($.datepicker.dpDiv); + } + + var otherArgs = Array.prototype.slice.call(arguments, 1); + if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { + return $.datepicker["_" + options + "Datepicker"]. + apply($.datepicker, [this[0]].concat(otherArgs)); + } + if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { + return $.datepicker["_" + options + "Datepicker"]. + apply($.datepicker, [this[0]].concat(otherArgs)); + } + return this.each(function() { + typeof options === "string" ? + $.datepicker["_" + options + "Datepicker"]. + apply($.datepicker, [this].concat(otherArgs)) : + $.datepicker._attachDatepicker(this, options); + }); +}; + +$.datepicker = new Datepicker(); // singleton instance +$.datepicker.initialized = false; +$.datepicker.uuid = new Date().getTime(); +$.datepicker.version = "1.11.4"; + +return $.datepicker; + +})); +/*! + * jQuery UI Widget 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/jQuery.widget/ + */ + +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "jquery" ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +}(function( $ ) { + +var widget_uuid = 0, + widget_slice = Array.prototype.slice; + +$.cleanData = (function( orig ) { + return function( elems ) { + var events, elem, i; + for ( i = 0; (elem = elems[i]) != null; i++ ) { + try { + + // Only trigger remove when necessary to save time + events = $._data( elem, "events" ); + if ( events && events.remove ) { + $( elem ).triggerHandler( "remove" ); + } + + // http://bugs.jquery.com/ticket/8235 + } catch ( e ) {} + } + orig( elems ); + }; +})( $.cleanData ); + +$.widget = function( name, base, prototype ) { + var fullName, existingConstructor, constructor, basePrototype, + // proxiedPrototype allows the provided prototype to remain unmodified + // so that it can be used as a mixin for multiple widgets (#8876) + proxiedPrototype = {}, + namespace = name.split( "." )[ 0 ]; + + name = name.split( "." )[ 1 ]; + fullName = namespace + "-" + name; + + if ( !prototype ) { + prototype = base; + base = $.Widget; + } + + // create selector for plugin + $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { + return !!$.data( elem, fullName ); + }; + + $[ namespace ] = $[ namespace ] || {}; + existingConstructor = $[ namespace ][ name ]; + constructor = $[ namespace ][ name ] = function( options, element ) { + // allow instantiation without "new" keyword + if ( !this._createWidget ) { + return new constructor( options, element ); + } + + // allow instantiation without initializing for simple inheritance + // must use "new" keyword (the code above always passes args) + if ( arguments.length ) { + this._createWidget( options, element ); + } + }; + // extend with the existing constructor to carry over any static properties + $.extend( constructor, existingConstructor, { + version: prototype.version, + // copy the object used to create the prototype in case we need to + // redefine the widget later + _proto: $.extend( {}, prototype ), + // track widgets that inherit from this widget in case this widget is + // redefined after a widget inherits from it + _childConstructors: [] + }); + + basePrototype = new base(); + // we need to make the options hash a property directly on the new instance + // otherwise we'll modify the options hash on the prototype that we're + // inheriting from + basePrototype.options = $.widget.extend( {}, basePrototype.options ); + $.each( prototype, function( prop, value ) { + if ( !$.isFunction( value ) ) { + proxiedPrototype[ prop ] = value; + return; + } + proxiedPrototype[ prop ] = (function() { + var _super = function() { + return base.prototype[ prop ].apply( this, arguments ); + }, + _superApply = function( args ) { + return base.prototype[ prop ].apply( this, args ); + }; + return function() { + var __super = this._super, + __superApply = this._superApply, + returnValue; + + this._super = _super; + this._superApply = _superApply; + + returnValue = value.apply( this, arguments ); + + this._super = __super; + this._superApply = __superApply; + + return returnValue; + }; + })(); + }); + constructor.prototype = $.widget.extend( basePrototype, { + // TODO: remove support for widgetEventPrefix + // always use the name + a colon as the prefix, e.g., draggable:start + // don't prefix for widgets that aren't DOM-based + widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name + }, proxiedPrototype, { + constructor: constructor, + namespace: namespace, + widgetName: name, + widgetFullName: fullName + }); + + // If this widget is being redefined then we need to find all widgets that + // are inheriting from it and redefine all of them so that they inherit from + // the new version of this widget. We're essentially trying to replace one + // level in the prototype chain. + if ( existingConstructor ) { + $.each( existingConstructor._childConstructors, function( i, child ) { + var childPrototype = child.prototype; + + // redefine the child widget using the same prototype that was + // originally used, but inherit from the new version of the base + $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); + }); + // remove the list of existing child constructors from the old constructor + // so the old child constructors can be garbage collected + delete existingConstructor._childConstructors; + } else { + base._childConstructors.push( constructor ); + } + + $.widget.bridge( name, constructor ); + + return constructor; +}; + +$.widget.extend = function( target ) { + var input = widget_slice.call( arguments, 1 ), + inputIndex = 0, + inputLength = input.length, + key, + value; + for ( ; inputIndex < inputLength; inputIndex++ ) { + for ( key in input[ inputIndex ] ) { + value = input[ inputIndex ][ key ]; + if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { + // Clone objects + if ( $.isPlainObject( value ) ) { + target[ key ] = $.isPlainObject( target[ key ] ) ? + $.widget.extend( {}, target[ key ], value ) : + // Don't extend strings, arrays, etc. with objects + $.widget.extend( {}, value ); + // Copy everything else by reference + } else { + target[ key ] = value; + } + } + } + } + return target; +}; + +$.widget.bridge = function( name, object ) { + var fullName = object.prototype.widgetFullName || name; + $.fn[ name ] = function( options ) { + var isMethodCall = typeof options === "string", + args = widget_slice.call( arguments, 1 ), + returnValue = this; + + if ( isMethodCall ) { + this.each(function() { + var methodValue, + instance = $.data( this, fullName ); + if ( options === "instance" ) { + returnValue = instance; + return false; + } + if ( !instance ) { + return $.error( "cannot call methods on " + name + " prior to initialization; " + + "attempted to call method '" + options + "'" ); + } + if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { + return $.error( "no such method '" + options + "' for " + name + " widget instance" ); + } + methodValue = instance[ options ].apply( instance, args ); + if ( methodValue !== instance && methodValue !== undefined ) { + returnValue = methodValue && methodValue.jquery ? + returnValue.pushStack( methodValue.get() ) : + methodValue; + return false; + } + }); + } else { + + // Allow multiple hashes to be passed on init + if ( args.length ) { + options = $.widget.extend.apply( null, [ options ].concat(args) ); + } + + this.each(function() { + var instance = $.data( this, fullName ); + if ( instance ) { + instance.option( options || {} ); + if ( instance._init ) { + instance._init(); + } + } else { + $.data( this, fullName, new object( options, this ) ); + } + }); + } + + return returnValue; + }; +}; + +$.Widget = function( /* options, element */ ) {}; +$.Widget._childConstructors = []; + +$.Widget.prototype = { + widgetName: "widget", + widgetEventPrefix: "", + defaultElement: "<div>", + options: { + disabled: false, + + // callbacks + create: null + }, + _createWidget: function( options, element ) { + element = $( element || this.defaultElement || this )[ 0 ]; + this.element = $( element ); + this.uuid = widget_uuid++; + this.eventNamespace = "." + this.widgetName + this.uuid; + + this.bindings = $(); + this.hoverable = $(); + this.focusable = $(); + + if ( element !== this ) { + $.data( element, this.widgetFullName, this ); + this._on( true, this.element, { + remove: function( event ) { + if ( event.target === element ) { + this.destroy(); + } + } + }); + this.document = $( element.style ? + // element within the document + element.ownerDocument : + // element is window or document + element.document || element ); + this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); + } + + this.options = $.widget.extend( {}, + this.options, + this._getCreateOptions(), + options ); + + this._create(); + this._trigger( "create", null, this._getCreateEventData() ); + this._init(); + }, + _getCreateOptions: $.noop, + _getCreateEventData: $.noop, + _create: $.noop, + _init: $.noop, + + destroy: function() { + this._destroy(); + // we can probably remove the unbind calls in 2.0 + // all event bindings should go through this._on() + this.element + .unbind( this.eventNamespace ) + .removeData( this.widgetFullName ) + // support: jquery <1.6.3 + // http://bugs.jquery.com/ticket/9413 + .removeData( $.camelCase( this.widgetFullName ) ); + this.widget() + .unbind( this.eventNamespace ) + .removeAttr( "aria-disabled" ) + .removeClass( + this.widgetFullName + "-disabled " + + "ui-state-disabled" ); + + // clean up events and states + this.bindings.unbind( this.eventNamespace ); + this.hoverable.removeClass( "ui-state-hover" ); + this.focusable.removeClass( "ui-state-focus" ); + }, + _destroy: $.noop, + + widget: function() { + return this.element; + }, + + option: function( key, value ) { + var options = key, + parts, + curOption, + i; + + if ( arguments.length === 0 ) { + // don't return a reference to the internal hash + return $.widget.extend( {}, this.options ); + } + + if ( typeof key === "string" ) { + // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } + options = {}; + parts = key.split( "." ); + key = parts.shift(); + if ( parts.length ) { + curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); + for ( i = 0; i < parts.length - 1; i++ ) { + curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; + curOption = curOption[ parts[ i ] ]; + } + key = parts.pop(); + if ( arguments.length === 1 ) { + return curOption[ key ] === undefined ? null : curOption[ key ]; + } + curOption[ key ] = value; + } else { + if ( arguments.length === 1 ) { + return this.options[ key ] === undefined ? null : this.options[ key ]; + } + options[ key ] = value; + } + } + + this._setOptions( options ); + + return this; + }, + _setOptions: function( options ) { + var key; + + for ( key in options ) { + this._setOption( key, options[ key ] ); + } + + return this; + }, + _setOption: function( key, value ) { + this.options[ key ] = value; + + if ( key === "disabled" ) { + this.widget() + .toggleClass( this.widgetFullName + "-disabled", !!value ); + + // If the widget is becoming disabled, then nothing is interactive + if ( value ) { + this.hoverable.removeClass( "ui-state-hover" ); + this.focusable.removeClass( "ui-state-focus" ); + } + } + + return this; + }, + + enable: function() { + return this._setOptions({ disabled: false }); + }, + disable: function() { + return this._setOptions({ disabled: true }); + }, + + _on: function( suppressDisabledCheck, element, handlers ) { + var delegateElement, + instance = this; + + // no suppressDisabledCheck flag, shuffle arguments + if ( typeof suppressDisabledCheck !== "boolean" ) { + handlers = element; + element = suppressDisabledCheck; + suppressDisabledCheck = false; + } + + // no element argument, shuffle and use this.element + if ( !handlers ) { + handlers = element; + element = this.element; + delegateElement = this.widget(); + } else { + element = delegateElement = $( element ); + this.bindings = this.bindings.add( element ); + } + + $.each( handlers, function( event, handler ) { + function handlerProxy() { + // allow widgets to customize the disabled handling + // - disabled as an array instead of boolean + // - disabled class as method for disabling individual parts + if ( !suppressDisabledCheck && + ( instance.options.disabled === true || + $( this ).hasClass( "ui-state-disabled" ) ) ) { + return; + } + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + + // copy the guid so direct unbinding works + if ( typeof handler !== "string" ) { + handlerProxy.guid = handler.guid = + handler.guid || handlerProxy.guid || $.guid++; + } + + var match = event.match( /^([\w:-]*)\s*(.*)$/ ), + eventName = match[1] + instance.eventNamespace, + selector = match[2]; + if ( selector ) { + delegateElement.delegate( selector, eventName, handlerProxy ); + } else { + element.bind( eventName, handlerProxy ); + } + }); + }, + + _off: function( element, eventName ) { + eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + + this.eventNamespace; + element.unbind( eventName ).undelegate( eventName ); + + // Clear the stack to avoid memory leaks (#10056) + this.bindings = $( this.bindings.not( element ).get() ); + this.focusable = $( this.focusable.not( element ).get() ); + this.hoverable = $( this.hoverable.not( element ).get() ); + }, + + _delay: function( handler, delay ) { + function handlerProxy() { + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + var instance = this; + return setTimeout( handlerProxy, delay || 0 ); + }, + + _hoverable: function( element ) { + this.hoverable = this.hoverable.add( element ); + this._on( element, { + mouseenter: function( event ) { + $( event.currentTarget ).addClass( "ui-state-hover" ); + }, + mouseleave: function( event ) { + $( event.currentTarget ).removeClass( "ui-state-hover" ); + } + }); + }, + + _focusable: function( element ) { + this.focusable = this.focusable.add( element ); + this._on( element, { + focusin: function( event ) { + $( event.currentTarget ).addClass( "ui-state-focus" ); + }, + focusout: function( event ) { + $( event.currentTarget ).removeClass( "ui-state-focus" ); + } + }); + }, + + _trigger: function( type, event, data ) { + var prop, orig, + callback = this.options[ type ]; + + data = data || {}; + event = $.Event( event ); + event.type = ( type === this.widgetEventPrefix ? + type : + this.widgetEventPrefix + type ).toLowerCase(); + // the original event may come from any element + // so we need to reset the target on the new event + event.target = this.element[ 0 ]; + + // copy original event properties over to the new event + orig = event.originalEvent; + if ( orig ) { + for ( prop in orig ) { + if ( !( prop in event ) ) { + event[ prop ] = orig[ prop ]; + } + } + } + + this.element.trigger( event, data ); + return !( $.isFunction( callback ) && + callback.apply( this.element[0], [ event ].concat( data ) ) === false || + event.isDefaultPrevented() ); + } +}; + +$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { + $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { + if ( typeof options === "string" ) { + options = { effect: options }; + } + var hasOptions, + effectName = !options ? + method : + options === true || typeof options === "number" ? + defaultEffect : + options.effect || defaultEffect; + options = options || {}; + if ( typeof options === "number" ) { + options = { duration: options }; + } + hasOptions = !$.isEmptyObject( options ); + options.complete = callback; + if ( options.delay ) { + element.delay( options.delay ); + } + if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { + element[ method ]( options ); + } else if ( effectName !== method && element[ effectName ] ) { + element[ effectName ]( options.duration, options.easing, callback ); + } else { + element.queue(function( next ) { + $( this )[ method ](); + if ( callback ) { + callback.call( element[ 0 ] ); + } + next(); + }); + } + }; +}); + +return $.widget; + +})); + + + +/*! + * jQuery UI Button 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/button/ + */ + +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define([ + "jquery", + "./core", + "./widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +}(function( $ ) { + +var lastActive, + baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", + typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only", + formResetHandler = function() { + var form = $( this ); + setTimeout(function() { + form.find( ":ui-button" ).button( "refresh" ); + }, 1 ); + }, + radioGroup = function( radio ) { + var name = radio.name, + form = radio.form, + radios = $( [] ); + if ( name ) { + name = name.replace( /'/g, "\\'" ); + if ( form ) { + radios = $( form ).find( "[name='" + name + "'][type=radio]" ); + } else { + radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument ) + .filter(function() { + return !this.form; + }); + } + } + return radios; + }; + +$.widget( "ui.button", { + version: "1.11.4", + defaultElement: "<button>", + options: { + disabled: null, + text: true, + label: null, + icons: { + primary: null, + secondary: null + } + }, + _create: function() { + this.element.closest( "form" ) + .unbind( "reset" + this.eventNamespace ) + .bind( "reset" + this.eventNamespace, formResetHandler ); + + if ( typeof this.options.disabled !== "boolean" ) { + this.options.disabled = !!this.element.prop( "disabled" ); + } else { + this.element.prop( "disabled", this.options.disabled ); + } + + this._determineButtonType(); + this.hasTitle = !!this.buttonElement.attr( "title" ); + + var that = this, + options = this.options, + toggleButton = this.type === "checkbox" || this.type === "radio", + activeClass = !toggleButton ? "ui-state-active" : ""; + + if ( options.label === null ) { + options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); + } + + this._hoverable( this.buttonElement ); + + this.buttonElement + .addClass( baseClasses ) + .attr( "role", "button" ) + .bind( "mouseenter" + this.eventNamespace, function() { + if ( options.disabled ) { + return; + } + if ( this === lastActive ) { + $( this ).addClass( "ui-state-active" ); + } + }) + .bind( "mouseleave" + this.eventNamespace, function() { + if ( options.disabled ) { + return; + } + $( this ).removeClass( activeClass ); + }) + .bind( "click" + this.eventNamespace, function( event ) { + if ( options.disabled ) { + event.preventDefault(); + event.stopImmediatePropagation(); + } + }); + + // Can't use _focusable() because the element that receives focus + // and the element that gets the ui-state-focus class are different + this._on({ + focus: function() { + this.buttonElement.addClass( "ui-state-focus" ); + }, + blur: function() { + this.buttonElement.removeClass( "ui-state-focus" ); + } + }); + + if ( toggleButton ) { + this.element.bind( "change" + this.eventNamespace, function() { + that.refresh(); + }); + } + + if ( this.type === "checkbox" ) { + this.buttonElement.bind( "click" + this.eventNamespace, function() { + if ( options.disabled ) { + return false; + } + }); + } else if ( this.type === "radio" ) { + this.buttonElement.bind( "click" + this.eventNamespace, function() { + if ( options.disabled ) { + return false; + } + $( this ).addClass( "ui-state-active" ); + that.buttonElement.attr( "aria-pressed", "true" ); + + var radio = that.element[ 0 ]; + radioGroup( radio ) + .not( radio ) + .map(function() { + return $( this ).button( "widget" )[ 0 ]; + }) + .removeClass( "ui-state-active" ) + .attr( "aria-pressed", "false" ); + }); + } else { + this.buttonElement + .bind( "mousedown" + this.eventNamespace, function() { + if ( options.disabled ) { + return false; + } + $( this ).addClass( "ui-state-active" ); + lastActive = this; + that.document.one( "mouseup", function() { + lastActive = null; + }); + }) + .bind( "mouseup" + this.eventNamespace, function() { + if ( options.disabled ) { + return false; + } + $( this ).removeClass( "ui-state-active" ); + }) + .bind( "keydown" + this.eventNamespace, function(event) { + if ( options.disabled ) { + return false; + } + if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { + $( this ).addClass( "ui-state-active" ); + } + }) + // see #8559, we bind to blur here in case the button element loses + // focus between keydown and keyup, it would be left in an "active" state + .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() { + $( this ).removeClass( "ui-state-active" ); + }); + + if ( this.buttonElement.is("a") ) { + this.buttonElement.keyup(function(event) { + if ( event.keyCode === $.ui.keyCode.SPACE ) { + // TODO pass through original event correctly (just as 2nd argument doesn't work) + $( this ).click(); + } + }); + } + } + + this._setOption( "disabled", options.disabled ); + this._resetButton(); + }, + + _determineButtonType: function() { + var ancestor, labelSelector, checked; + + if ( this.element.is("[type=checkbox]") ) { + this.type = "checkbox"; + } else if ( this.element.is("[type=radio]") ) { + this.type = "radio"; + } else if ( this.element.is("input") ) { + this.type = "input"; + } else { + this.type = "button"; + } + + if ( this.type === "checkbox" || this.type === "radio" ) { + // we don't search against the document in case the element + // is disconnected from the DOM + ancestor = this.element.parents().last(); + labelSelector = "label[for='" + this.element.attr("id") + "']"; + this.buttonElement = ancestor.find( labelSelector ); + if ( !this.buttonElement.length ) { + ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); + this.buttonElement = ancestor.filter( labelSelector ); + if ( !this.buttonElement.length ) { + this.buttonElement = ancestor.find( labelSelector ); + } + } + this.element.addClass( "ui-helper-hidden-accessible" ); + + checked = this.element.is( ":checked" ); + if ( checked ) { + this.buttonElement.addClass( "ui-state-active" ); + } + this.buttonElement.prop( "aria-pressed", checked ); + } else { + this.buttonElement = this.element; + } + }, + + widget: function() { + return this.buttonElement; + }, + + _destroy: function() { + this.element + .removeClass( "ui-helper-hidden-accessible" ); + this.buttonElement + .removeClass( baseClasses + " ui-state-active " + typeClasses ) + .removeAttr( "role" ) + .removeAttr( "aria-pressed" ) + .html( this.buttonElement.find(".ui-button-text").html() ); + + if ( !this.hasTitle ) { + this.buttonElement.removeAttr( "title" ); + } + }, + + _setOption: function( key, value ) { + this._super( key, value ); + if ( key === "disabled" ) { + this.widget().toggleClass( "ui-state-disabled", !!value ); + this.element.prop( "disabled", !!value ); + if ( value ) { + if ( this.type === "checkbox" || this.type === "radio" ) { + this.buttonElement.removeClass( "ui-state-focus" ); + } else { + this.buttonElement.removeClass( "ui-state-focus ui-state-active" ); + } + } + return; + } + this._resetButton(); + }, + + refresh: function() { + //See #8237 & #8828 + var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); + + if ( isDisabled !== this.options.disabled ) { + this._setOption( "disabled", isDisabled ); + } + if ( this.type === "radio" ) { + radioGroup( this.element[0] ).each(function() { + if ( $( this ).is( ":checked" ) ) { + $( this ).button( "widget" ) + .addClass( "ui-state-active" ) + .attr( "aria-pressed", "true" ); + } else { + $( this ).button( "widget" ) + .removeClass( "ui-state-active" ) + .attr( "aria-pressed", "false" ); + } + }); + } else if ( this.type === "checkbox" ) { + if ( this.element.is( ":checked" ) ) { + this.buttonElement + .addClass( "ui-state-active" ) + .attr( "aria-pressed", "true" ); + } else { + this.buttonElement + .removeClass( "ui-state-active" ) + .attr( "aria-pressed", "false" ); + } + } + }, + + _resetButton: function() { + if ( this.type === "input" ) { + if ( this.options.label ) { + this.element.val( this.options.label ); + } + return; + } + var buttonElement = this.buttonElement.removeClass( typeClasses ), + buttonText = $( "<span></span>", this.document[0] ) + .addClass( "ui-button-text" ) + .html( this.options.label ) + .appendTo( buttonElement.empty() ) + .text(), + icons = this.options.icons, + multipleIcons = icons.primary && icons.secondary, + buttonClasses = []; + + if ( icons.primary || icons.secondary ) { + if ( this.options.text ) { + buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); + } + + if ( icons.primary ) { + buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); + } + + if ( icons.secondary ) { + buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); + } + + if ( !this.options.text ) { + buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); + + if ( !this.hasTitle ) { + buttonElement.attr( "title", $.trim( buttonText ) ); + } + } + } else { + buttonClasses.push( "ui-button-text-only" ); + } + buttonElement.addClass( buttonClasses.join( " " ) ); + } +}); + +$.widget( "ui.buttonset", { + version: "1.11.4", + options: { + items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)" + }, + + _create: function() { + this.element.addClass( "ui-buttonset" ); + }, + + _init: function() { + this.refresh(); + }, + + _setOption: function( key, value ) { + if ( key === "disabled" ) { + this.buttons.button( "option", key, value ); + } + + this._super( key, value ); + }, + + refresh: function() { + var rtl = this.element.css( "direction" ) === "rtl", + allButtons = this.element.find( this.options.items ), + existingButtons = allButtons.filter( ":ui-button" ); + + // Initialize new buttons + allButtons.not( ":ui-button" ).button(); + + // Refresh existing buttons + existingButtons.button( "refresh" ); + + this.buttons = allButtons + .map(function() { + return $( this ).button( "widget" )[ 0 ]; + }) + .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) + .filter( ":first" ) + .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) + .end() + .filter( ":last" ) + .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) + .end() + .end(); + }, + + _destroy: function() { + this.element.removeClass( "ui-buttonset" ); + this.buttons + .map(function() { + return $( this ).button( "widget" )[ 0 ]; + }) + .removeClass( "ui-corner-left ui-corner-right" ) + .end() + .button( "destroy" ); + } +}); + +return $.ui.button; + +})); + + + +/*! + * jQuery UI Mouse 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/mouse/ + */ + +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define([ + "jquery", + "./widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +}(function( $ ) { + +var mouseHandled = false; +$( document ).mouseup( function() { + mouseHandled = false; +}); + +return $.widget("ui.mouse", { + version: "1.11.4", + options: { + cancel: "input,textarea,button,select,option", + distance: 1, + delay: 0 + }, + _mouseInit: function() { + var that = this; + + this.element + .bind("mousedown." + this.widgetName, function(event) { + return that._mouseDown(event); + }) + .bind("click." + this.widgetName, function(event) { + if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { + $.removeData(event.target, that.widgetName + ".preventClickEvent"); + event.stopImmediatePropagation(); + return false; + } + }); + + this.started = false; + }, + + // TODO: make sure destroying one instance of mouse doesn't mess with + // other instances of mouse + _mouseDestroy: function() { + this.element.unbind("." + this.widgetName); + if ( this._mouseMoveDelegate ) { + this.document + .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate) + .unbind("mouseup." + this.widgetName, this._mouseUpDelegate); + } + }, + + _mouseDown: function(event) { + // don't let more than one widget handle mouseStart + if ( mouseHandled ) { + return; + } + + this._mouseMoved = false; + + // we may have missed mouseup (out of window) + (this._mouseStarted && this._mouseUp(event)); + + this._mouseDownEvent = event; + + var that = this, + btnIsLeft = (event.which === 1), + // event.target.nodeName works around a bug in IE 8 with + // disabled inputs (#7620) + elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); + if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { + return true; + } + + this.mouseDelayMet = !this.options.delay; + if (!this.mouseDelayMet) { + this._mouseDelayTimer = setTimeout(function() { + that.mouseDelayMet = true; + }, this.options.delay); + } + + if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { + this._mouseStarted = (this._mouseStart(event) !== false); + if (!this._mouseStarted) { + event.preventDefault(); + return true; + } + } + + // Click event may never have fired (Gecko & Opera) + if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { + $.removeData(event.target, this.widgetName + ".preventClickEvent"); + } + + // these delegates are required to keep context + this._mouseMoveDelegate = function(event) { + return that._mouseMove(event); + }; + this._mouseUpDelegate = function(event) { + return that._mouseUp(event); + }; + + this.document + .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate ) + .bind( "mouseup." + this.widgetName, this._mouseUpDelegate ); + + event.preventDefault(); + + mouseHandled = true; + return true; + }, + + _mouseMove: function(event) { + // Only check for mouseups outside the document if you've moved inside the document + // at least once. This prevents the firing of mouseup in the case of IE<9, which will + // fire a mousemove event if content is placed under the cursor. See #7778 + // Support: IE <9 + if ( this._mouseMoved ) { + // IE mouseup check - mouseup happened when mouse was out of window + if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { + return this._mouseUp(event); + + // Iframe mouseup check - mouseup occurred in another document + } else if ( !event.which ) { + return this._mouseUp( event ); + } + } + + if ( event.which || event.button ) { + this._mouseMoved = true; + } + + if (this._mouseStarted) { + this._mouseDrag(event); + return event.preventDefault(); + } + + if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { + this._mouseStarted = + (this._mouseStart(this._mouseDownEvent, event) !== false); + (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); + } + + return !this._mouseStarted; + }, + + _mouseUp: function(event) { + this.document + .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate ) + .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate ); + + if (this._mouseStarted) { + this._mouseStarted = false; + + if (event.target === this._mouseDownEvent.target) { + $.data(event.target, this.widgetName + ".preventClickEvent", true); + } + + this._mouseStop(event); + } + + mouseHandled = false; + return false; + }, + + _mouseDistanceMet: function(event) { + return (Math.max( + Math.abs(this._mouseDownEvent.pageX - event.pageX), + Math.abs(this._mouseDownEvent.pageY - event.pageY) + ) >= this.options.distance + ); + }, + + _mouseDelayMet: function(/* event */) { + return this.mouseDelayMet; + }, + + // These are placeholder methods, to be overriden by extending plugin + _mouseStart: function(/* event */) {}, + _mouseDrag: function(/* event */) {}, + _mouseStop: function(/* event */) {}, + _mouseCapture: function(/* event */) { return true; } +}); + +})); + + + + +/*! + * jQuery UI Draggable 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/draggable/ + */ + +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define([ + "jquery", + "./core", + "./mouse", + "./widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +}(function( $ ) { + +$.widget("ui.draggable", $.ui.mouse, { + version: "1.11.4", + widgetEventPrefix: "drag", + options: { + addClasses: true, + appendTo: "parent", + axis: false, + connectToSortable: false, + containment: false, + cursor: "auto", + cursorAt: false, + grid: false, + handle: false, + helper: "original", + iframeFix: false, + opacity: false, + refreshPositions: false, + revert: false, + revertDuration: 500, + scope: "default", + scroll: true, + scrollSensitivity: 20, + scrollSpeed: 20, + snap: false, + snapMode: "both", + snapTolerance: 20, + stack: false, + zIndex: false, + + // callbacks + drag: null, + start: null, + stop: null + }, + _create: function() { + + if ( this.options.helper === "original" ) { + this._setPositionRelative(); + } + if (this.options.addClasses){ + this.element.addClass("ui-draggable"); + } + if (this.options.disabled){ + this.element.addClass("ui-draggable-disabled"); + } + this._setHandleClassName(); + + this._mouseInit(); + }, + + _setOption: function( key, value ) { + this._super( key, value ); + if ( key === "handle" ) { + this._removeHandleClassName(); + this._setHandleClassName(); + } + }, + + _destroy: function() { + if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { + this.destroyOnClear = true; + return; + } + this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); + this._removeHandleClassName(); + this._mouseDestroy(); + }, + + _mouseCapture: function(event) { + var o = this.options; + + this._blurActiveElement( event ); + + // among others, prevent a drag on a resizable-handle + if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { + return false; + } + + //Quit if we're not on a valid handle + this.handle = this._getHandle(event); + if (!this.handle) { + return false; + } + + this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); + + return true; + + }, + + _blockFrames: function( selector ) { + this.iframeBlocks = this.document.find( selector ).map(function() { + var iframe = $( this ); + + return $( "<div>" ) + .css( "position", "absolute" ) + .appendTo( iframe.parent() ) + .outerWidth( iframe.outerWidth() ) + .outerHeight( iframe.outerHeight() ) + .offset( iframe.offset() )[ 0 ]; + }); + }, + + _unblockFrames: function() { + if ( this.iframeBlocks ) { + this.iframeBlocks.remove(); + delete this.iframeBlocks; + } + }, + + _blurActiveElement: function( event ) { + var document = this.document[ 0 ]; + + // Only need to blur if the event occurred on the draggable itself, see #10527 + if ( !this.handleElement.is( event.target ) ) { + return; + } + + // support: IE9 + // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> + try { + + // Support: IE9, IE10 + // If the <body> is blurred, IE will switch windows, see #9520 + if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) { + + // Blur any element that currently has focus, see #4261 + $( document.activeElement ).blur(); + } + } catch ( error ) {} + }, + + _mouseStart: function(event) { + + var o = this.options; + + //Create and append the visible helper + this.helper = this._createHelper(event); + + this.helper.addClass("ui-draggable-dragging"); + + //Cache the helper size + this._cacheHelperProportions(); + + //If ddmanager is used for droppables, set the global draggable + if ($.ui.ddmanager) { + $.ui.ddmanager.current = this; + } + + /* + * - Position generation - + * This block generates everything position related - it's the core of draggables. + */ + + //Cache the margins of the original element + this._cacheMargins(); + + //Store the helper's css position + this.cssPosition = this.helper.css( "position" ); + this.scrollParent = this.helper.scrollParent( true ); + this.offsetParent = this.helper.offsetParent(); + this.hasFixedAncestor = this.helper.parents().filter(function() { + return $( this ).css( "position" ) === "fixed"; + }).length > 0; + + //The element's absolute position on the page minus margins + this.positionAbs = this.element.offset(); + this._refreshOffsets( event ); + + //Generate the original position + this.originalPosition = this.position = this._generatePosition( event, false ); + this.originalPageX = event.pageX; + this.originalPageY = event.pageY; + + //Adjust the mouse offset relative to the helper if "cursorAt" is supplied + (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); + + //Set a containment if given in the options + this._setContainment(); + + //Trigger event + callbacks + if (this._trigger("start", event) === false) { + this._clear(); + return false; + } + + //Recache the helper size + this._cacheHelperProportions(); + + //Prepare the droppable offsets + if ($.ui.ddmanager && !o.dropBehaviour) { + $.ui.ddmanager.prepareOffsets(this, event); + } + + // Reset helper's right/bottom css if they're set and set explicit width/height instead + // as this prevents resizing of elements with right/bottom set (see #7772) + this._normalizeRightBottom(); + + this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position + + //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) + if ( $.ui.ddmanager ) { + $.ui.ddmanager.dragStart(this, event); + } + + return true; + }, + + _refreshOffsets: function( event ) { + this.offset = { + top: this.positionAbs.top - this.margins.top, + left: this.positionAbs.left - this.margins.left, + scroll: false, + parent: this._getParentOffset(), + relative: this._getRelativeOffset() + }; + + this.offset.click = { + left: event.pageX - this.offset.left, + top: event.pageY - this.offset.top + }; + }, + + _mouseDrag: function(event, noPropagation) { + // reset any necessary cached properties (see #5009) + if ( this.hasFixedAncestor ) { + this.offset.parent = this._getParentOffset(); + } + + //Compute the helpers position + this.position = this._generatePosition( event, true ); + this.positionAbs = this._convertPositionTo("absolute"); + + //Call plugins and callbacks and use the resulting position if something is returned + if (!noPropagation) { + var ui = this._uiHash(); + if (this._trigger("drag", event, ui) === false) { + this._mouseUp({}); + return false; + } + this.position = ui.position; + } + + this.helper[ 0 ].style.left = this.position.left + "px"; + this.helper[ 0 ].style.top = this.position.top + "px"; + + if ($.ui.ddmanager) { + $.ui.ddmanager.drag(this, event); + } + + return false; + }, + + _mouseStop: function(event) { + + //If we are using droppables, inform the manager about the drop + var that = this, + dropped = false; + if ($.ui.ddmanager && !this.options.dropBehaviour) { + dropped = $.ui.ddmanager.drop(this, event); + } + + //if a drop comes from outside (a sortable) + if (this.dropped) { + dropped = this.dropped; + this.dropped = false; + } + + if ((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) { + $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { + if (that._trigger("stop", event) !== false) { + that._clear(); + } + }); + } else { + if (this._trigger("stop", event) !== false) { + this._clear(); + } + } + + return false; + }, + + _mouseUp: function( event ) { + this._unblockFrames(); + + //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) + if ( $.ui.ddmanager ) { + $.ui.ddmanager.dragStop(this, event); + } + + // Only need to focus if the event occurred on the draggable itself, see #10527 + if ( this.handleElement.is( event.target ) ) { + // The interaction is over; whether or not the click resulted in a drag, focus the element + this.element.focus(); + } + + return $.ui.mouse.prototype._mouseUp.call(this, event); + }, + + cancel: function() { + + if (this.helper.is(".ui-draggable-dragging")) { + this._mouseUp({}); + } else { + this._clear(); + } + + return this; + + }, + + _getHandle: function(event) { + return this.options.handle ? + !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : + true; + }, + + _setHandleClassName: function() { + this.handleElement = this.options.handle ? + this.element.find( this.options.handle ) : this.element; + this.handleElement.addClass( "ui-draggable-handle" ); + }, + + _removeHandleClassName: function() { + this.handleElement.removeClass( "ui-draggable-handle" ); + }, + + _createHelper: function(event) { + + var o = this.options, + helperIsFunction = $.isFunction( o.helper ), + helper = helperIsFunction ? + $( o.helper.apply( this.element[ 0 ], [ event ] ) ) : + ( o.helper === "clone" ? + this.element.clone().removeAttr( "id" ) : + this.element ); + + if (!helper.parents("body").length) { + helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); + } + + // http://bugs.jqueryui.com/ticket/9446 + // a helper function can return the original element + // which wouldn't have been set to relative in _create + if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) { + this._setPositionRelative(); + } + + if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { + helper.css("position", "absolute"); + } + + return helper; + + }, + + _setPositionRelative: function() { + if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) { + this.element[ 0 ].style.position = "relative"; + } + }, + + _adjustOffsetFromHelper: function(obj) { + if (typeof obj === "string") { + obj = obj.split(" "); + } + if ($.isArray(obj)) { + obj = { left: +obj[0], top: +obj[1] || 0 }; + } + if ("left" in obj) { + this.offset.click.left = obj.left + this.margins.left; + } + if ("right" in obj) { + this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; + } + if ("top" in obj) { + this.offset.click.top = obj.top + this.margins.top; + } + if ("bottom" in obj) { + this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; + } + }, + + _isRootNode: function( element ) { + return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ]; + }, + + _getParentOffset: function() { + + //Get the offsetParent and cache its position + var po = this.offsetParent.offset(), + document = this.document[ 0 ]; + + // This is a special case where we need to modify a offset calculated on start, since the following happened: + // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent + // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that + // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag + if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { + po.left += this.scrollParent.scrollLeft(); + po.top += this.scrollParent.scrollTop(); + } + + if ( this._isRootNode( this.offsetParent[ 0 ] ) ) { + po = { top: 0, left: 0 }; + } + + return { + top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0), + left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0) + }; + + }, + + _getRelativeOffset: function() { + if ( this.cssPosition !== "relative" ) { + return { top: 0, left: 0 }; + } + + var p = this.element.position(), + scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); + + return { + top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), + left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) + }; + + }, + + _cacheMargins: function() { + this.margins = { + left: (parseInt(this.element.css("marginLeft"), 10) || 0), + top: (parseInt(this.element.css("marginTop"), 10) || 0), + right: (parseInt(this.element.css("marginRight"), 10) || 0), + bottom: (parseInt(this.element.css("marginBottom"), 10) || 0) + }; + }, + + _cacheHelperProportions: function() { + this.helperProportions = { + width: this.helper.outerWidth(), + height: this.helper.outerHeight() + }; + }, + + _setContainment: function() { + + var isUserScrollable, c, ce, + o = this.options, + document = this.document[ 0 ]; + + this.relativeContainer = null; + + if ( !o.containment ) { + this.containment = null; + return; + } + + if ( o.containment === "window" ) { + this.containment = [ + $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, + $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, + $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left, + $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top + ]; + return; + } + + if ( o.containment === "document") { + this.containment = [ + 0, + 0, + $( document ).width() - this.helperProportions.width - this.margins.left, + ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top + ]; + return; + } + + if ( o.containment.constructor === Array ) { + this.containment = o.containment; + return; + } + + if ( o.containment === "parent" ) { + o.containment = this.helper[ 0 ].parentNode; + } + + c = $( o.containment ); + ce = c[ 0 ]; + + if ( !ce ) { + return; + } + + isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) ); + + this.containment = [ + ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), + ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), + ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - + ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - + ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - + this.helperProportions.width - + this.margins.left - + this.margins.right, + ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - + ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - + ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - + this.helperProportions.height - + this.margins.top - + this.margins.bottom + ]; + this.relativeContainer = c; + }, + + _convertPositionTo: function(d, pos) { + + if (!pos) { + pos = this.position; + } + + var mod = d === "absolute" ? 1 : -1, + scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); + + return { + top: ( + pos.top + // The absolute mouse position + this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) + ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod) + ), + left: ( + pos.left + // The absolute mouse position + this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) + ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod) + ) + }; + + }, + + _generatePosition: function( event, constrainPosition ) { + + var containment, co, top, left, + o = this.options, + scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ), + pageX = event.pageX, + pageY = event.pageY; + + // Cache the scroll + if ( !scrollIsRootNode || !this.offset.scroll ) { + this.offset.scroll = { + top: this.scrollParent.scrollTop(), + left: this.scrollParent.scrollLeft() + }; + } + + /* + * - Position constraining - + * Constrain the position to a mix of grid, containment. + */ + + // If we are not dragging yet, we won't check for options + if ( constrainPosition ) { + if ( this.containment ) { + if ( this.relativeContainer ){ + co = this.relativeContainer.offset(); + containment = [ + this.containment[ 0 ] + co.left, + this.containment[ 1 ] + co.top, + this.containment[ 2 ] + co.left, + this.containment[ 3 ] + co.top + ]; + } else { + containment = this.containment; + } + + if (event.pageX - this.offset.click.left < containment[0]) { + pageX = containment[0] + this.offset.click.left; + } + if (event.pageY - this.offset.click.top < containment[1]) { + pageY = containment[1] + this.offset.click.top; + } + if (event.pageX - this.offset.click.left > containment[2]) { + pageX = containment[2] + this.offset.click.left; + } + if (event.pageY - this.offset.click.top > containment[3]) { + pageY = containment[3] + this.offset.click.top; + } + } + + if (o.grid) { + //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) + top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; + pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; + + left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; + pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; + } + + if ( o.axis === "y" ) { + pageX = this.originalPageX; + } + + if ( o.axis === "x" ) { + pageY = this.originalPageY; + } + } + + return { + top: ( + pageY - // The absolute mouse position + this.offset.click.top - // Click offset (relative to the element) + this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.top + // The offsetParent's offset without borders (offset + border) + ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) + ), + left: ( + pageX - // The absolute mouse position + this.offset.click.left - // Click offset (relative to the element) + this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.left + // The offsetParent's offset without borders (offset + border) + ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) + ) + }; + + }, + + _clear: function() { + this.helper.removeClass("ui-draggable-dragging"); + if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { + this.helper.remove(); + } + this.helper = null; + this.cancelHelperRemoval = false; + if ( this.destroyOnClear ) { + this.destroy(); + } + }, + + _normalizeRightBottom: function() { + if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) { + this.helper.width( this.helper.width() ); + this.helper.css( "right", "auto" ); + } + if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) { + this.helper.height( this.helper.height() ); + this.helper.css( "bottom", "auto" ); + } + }, + + // From now on bulk stuff - mainly helpers + + _trigger: function( type, event, ui ) { + ui = ui || this._uiHash(); + $.ui.plugin.call( this, type, [ event, ui, this ], true ); + + // Absolute position and offset (see #6884 ) have to be recalculated after plugins + if ( /^(drag|start|stop)/.test( type ) ) { + this.positionAbs = this._convertPositionTo( "absolute" ); + ui.offset = this.positionAbs; + } + return $.Widget.prototype._trigger.call( this, type, event, ui ); + }, + + plugins: {}, + + _uiHash: function() { + return { + helper: this.helper, + position: this.position, + originalPosition: this.originalPosition, + offset: this.positionAbs + }; + } + +}); + +$.ui.plugin.add( "draggable", "connectToSortable", { + start: function( event, ui, draggable ) { + var uiSortable = $.extend( {}, ui, { + item: draggable.element + }); + + draggable.sortables = []; + $( draggable.options.connectToSortable ).each(function() { + var sortable = $( this ).sortable( "instance" ); + + if ( sortable && !sortable.options.disabled ) { + draggable.sortables.push( sortable ); + + // refreshPositions is called at drag start to refresh the containerCache + // which is used in drag. This ensures it's initialized and synchronized + // with any changes that might have happened on the page since initialization. + sortable.refreshPositions(); + sortable._trigger("activate", event, uiSortable); + } + }); + }, + stop: function( event, ui, draggable ) { + var uiSortable = $.extend( {}, ui, { + item: draggable.element + }); + + draggable.cancelHelperRemoval = false; + + $.each( draggable.sortables, function() { + var sortable = this; + + if ( sortable.isOver ) { + sortable.isOver = 0; + + // Allow this sortable to handle removing the helper + draggable.cancelHelperRemoval = true; + sortable.cancelHelperRemoval = false; + + // Use _storedCSS To restore properties in the sortable, + // as this also handles revert (#9675) since the draggable + // may have modified them in unexpected ways (#8809) + sortable._storedCSS = { + position: sortable.placeholder.css( "position" ), + top: sortable.placeholder.css( "top" ), + left: sortable.placeholder.css( "left" ) + }; + + sortable._mouseStop(event); + + // Once drag has ended, the sortable should return to using + // its original helper, not the shared helper from draggable + sortable.options.helper = sortable.options._helper; + } else { + // Prevent this Sortable from removing the helper. + // However, don't set the draggable to remove the helper + // either as another connected Sortable may yet handle the removal. + sortable.cancelHelperRemoval = true; + + sortable._trigger( "deactivate", event, uiSortable ); + } + }); + }, + drag: function( event, ui, draggable ) { + $.each( draggable.sortables, function() { + var innermostIntersecting = false, + sortable = this; + + // Copy over variables that sortable's _intersectsWith uses + sortable.positionAbs = draggable.positionAbs; + sortable.helperProportions = draggable.helperProportions; + sortable.offset.click = draggable.offset.click; + + if ( sortable._intersectsWith( sortable.containerCache ) ) { + innermostIntersecting = true; + + $.each( draggable.sortables, function() { + // Copy over variables that sortable's _intersectsWith uses + this.positionAbs = draggable.positionAbs; + this.helperProportions = draggable.helperProportions; + this.offset.click = draggable.offset.click; + + if ( this !== sortable && + this._intersectsWith( this.containerCache ) && + $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) { + innermostIntersecting = false; + } + + return innermostIntersecting; + }); + } + + if ( innermostIntersecting ) { + // If it intersects, we use a little isOver variable and set it once, + // so that the move-in stuff gets fired only once. + if ( !sortable.isOver ) { + sortable.isOver = 1; + + // Store draggable's parent in case we need to reappend to it later. + draggable._parent = ui.helper.parent(); + + sortable.currentItem = ui.helper + .appendTo( sortable.element ) + .data( "ui-sortable-item", true ); + + // Store helper option to later restore it + sortable.options._helper = sortable.options.helper; + + sortable.options.helper = function() { + return ui.helper[ 0 ]; + }; + + // Fire the start events of the sortable with our passed browser event, + // and our own helper (so it doesn't create a new one) + event.target = sortable.currentItem[ 0 ]; + sortable._mouseCapture( event, true ); + sortable._mouseStart( event, true, true ); + + // Because the browser event is way off the new appended portlet, + // modify necessary variables to reflect the changes + sortable.offset.click.top = draggable.offset.click.top; + sortable.offset.click.left = draggable.offset.click.left; + sortable.offset.parent.left -= draggable.offset.parent.left - + sortable.offset.parent.left; + sortable.offset.parent.top -= draggable.offset.parent.top - + sortable.offset.parent.top; + + draggable._trigger( "toSortable", event ); + + // Inform draggable that the helper is in a valid drop zone, + // used solely in the revert option to handle "valid/invalid". + draggable.dropped = sortable.element; + + // Need to refreshPositions of all sortables in the case that + // adding to one sortable changes the location of the other sortables (#9675) + $.each( draggable.sortables, function() { + this.refreshPositions(); + }); + + // hack so receive/update callbacks work (mostly) + draggable.currentItem = draggable.element; + sortable.fromOutside = draggable; + } + + if ( sortable.currentItem ) { + sortable._mouseDrag( event ); + // Copy the sortable's position because the draggable's can potentially reflect + // a relative position, while sortable is always absolute, which the dragged + // element has now become. (#8809) + ui.position = sortable.position; + } + } else { + // If it doesn't intersect with the sortable, and it intersected before, + // we fake the drag stop of the sortable, but make sure it doesn't remove + // the helper by using cancelHelperRemoval. + if ( sortable.isOver ) { + + sortable.isOver = 0; + sortable.cancelHelperRemoval = true; + + // Calling sortable's mouseStop would trigger a revert, + // so revert must be temporarily false until after mouseStop is called. + sortable.options._revert = sortable.options.revert; + sortable.options.revert = false; + + sortable._trigger( "out", event, sortable._uiHash( sortable ) ); + sortable._mouseStop( event, true ); + + // restore sortable behaviors that were modfied + // when the draggable entered the sortable area (#9481) + sortable.options.revert = sortable.options._revert; + sortable.options.helper = sortable.options._helper; + + if ( sortable.placeholder ) { + sortable.placeholder.remove(); + } + + // Restore and recalculate the draggable's offset considering the sortable + // may have modified them in unexpected ways. (#8809, #10669) + ui.helper.appendTo( draggable._parent ); + draggable._refreshOffsets( event ); + ui.position = draggable._generatePosition( event, true ); + + draggable._trigger( "fromSortable", event ); + + // Inform draggable that the helper is no longer in a valid drop zone + draggable.dropped = false; + + // Need to refreshPositions of all sortables just in case removing + // from one sortable changes the location of other sortables (#9675) + $.each( draggable.sortables, function() { + this.refreshPositions(); + }); + } + } + }); + } +}); + +$.ui.plugin.add("draggable", "cursor", { + start: function( event, ui, instance ) { + var t = $( "body" ), + o = instance.options; + + if (t.css("cursor")) { + o._cursor = t.css("cursor"); + } + t.css("cursor", o.cursor); + }, + stop: function( event, ui, instance ) { + var o = instance.options; + if (o._cursor) { + $("body").css("cursor", o._cursor); + } + } +}); + +$.ui.plugin.add("draggable", "opacity", { + start: function( event, ui, instance ) { + var t = $( ui.helper ), + o = instance.options; + if (t.css("opacity")) { + o._opacity = t.css("opacity"); + } + t.css("opacity", o.opacity); + }, + stop: function( event, ui, instance ) { + var o = instance.options; + if (o._opacity) { + $(ui.helper).css("opacity", o._opacity); + } + } +}); + +$.ui.plugin.add("draggable", "scroll", { + start: function( event, ui, i ) { + if ( !i.scrollParentNotHidden ) { + i.scrollParentNotHidden = i.helper.scrollParent( false ); + } + + if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { + i.overflowOffset = i.scrollParentNotHidden.offset(); + } + }, + drag: function( event, ui, i ) { + + var o = i.options, + scrolled = false, + scrollParent = i.scrollParentNotHidden[ 0 ], + document = i.document[ 0 ]; + + if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { + if ( !o.axis || o.axis !== "x" ) { + if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) { + scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; + } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { + scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; + } + } + + if ( !o.axis || o.axis !== "y" ) { + if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) { + scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; + } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { + scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; + } + } + + } else { + + if (!o.axis || o.axis !== "x") { + if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) { + scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); + } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { + scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); + } + } + + if (!o.axis || o.axis !== "y") { + if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { + scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); + } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { + scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); + } + } + + } + + if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { + $.ui.ddmanager.prepareOffsets(i, event); + } + + } +}); + +$.ui.plugin.add("draggable", "snap", { + start: function( event, ui, i ) { + + var o = i.options; + + i.snapElements = []; + + $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { + var $t = $(this), + $o = $t.offset(); + if (this !== i.element[0]) { + i.snapElements.push({ + item: this, + width: $t.outerWidth(), height: $t.outerHeight(), + top: $o.top, left: $o.left + }); + } + }); + + }, + drag: function( event, ui, inst ) { + + var ts, bs, ls, rs, l, r, t, b, i, first, + o = inst.options, + d = o.snapTolerance, + x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, + y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; + + for (i = inst.snapElements.length - 1; i >= 0; i--){ + + l = inst.snapElements[i].left - inst.margins.left; + r = l + inst.snapElements[i].width; + t = inst.snapElements[i].top - inst.margins.top; + b = t + inst.snapElements[i].height; + + if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) { + if (inst.snapElements[i].snapping) { + (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); + } + inst.snapElements[i].snapping = false; + continue; + } + + if (o.snapMode !== "inner") { + ts = Math.abs(t - y2) <= d; + bs = Math.abs(b - y1) <= d; + ls = Math.abs(l - x2) <= d; + rs = Math.abs(r - x1) <= d; + if (ts) { + ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top; + } + if (bs) { + ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top; + } + if (ls) { + ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left; + } + if (rs) { + ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left; + } + } + + first = (ts || bs || ls || rs); + + if (o.snapMode !== "outer") { + ts = Math.abs(t - y1) <= d; + bs = Math.abs(b - y2) <= d; + ls = Math.abs(l - x1) <= d; + rs = Math.abs(r - x2) <= d; + if (ts) { + ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top; + } + if (bs) { + ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top; + } + if (ls) { + ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left; + } + if (rs) { + ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left; + } + } + + if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { + (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); + } + inst.snapElements[i].snapping = (ts || bs || ls || rs || first); + + } + + } +}); + +$.ui.plugin.add("draggable", "stack", { + start: function( event, ui, instance ) { + var min, + o = instance.options, + group = $.makeArray($(o.stack)).sort(function(a, b) { + return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0); + }); + + if (!group.length) { return; } + + min = parseInt($(group[0]).css("zIndex"), 10) || 0; + $(group).each(function(i) { + $(this).css("zIndex", min + i); + }); + this.css("zIndex", (min + group.length)); + } +}); + +$.ui.plugin.add("draggable", "zIndex", { + start: function( event, ui, instance ) { + var t = $( ui.helper ), + o = instance.options; + + if (t.css("zIndex")) { + o._zIndex = t.css("zIndex"); + } + t.css("zIndex", o.zIndex); + }, + stop: function( event, ui, instance ) { + var o = instance.options; + + if (o._zIndex) { + $(ui.helper).css("zIndex", o._zIndex); + } + } +}); + +return $.ui.draggable; + +})); +/*! + * jQuery UI Position 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/position/ + */ + +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "jquery" ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +}(function( $ ) { +(function() { + +$.ui = $.ui || {}; + +var cachedScrollbarWidth, supportsOffsetFractions, + max = Math.max, + abs = Math.abs, + round = Math.round, + rhorizontal = /left|center|right/, + rvertical = /top|center|bottom/, + roffset = /[\+\-]\d+(\.[\d]+)?%?/, + rposition = /^\w+/, + rpercent = /%$/, + _position = $.fn.position; + +function getOffsets( offsets, width, height ) { + return [ + parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), + parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) + ]; +} + +function parseCss( element, property ) { + return parseInt( $.css( element, property ), 10 ) || 0; +} + +function getDimensions( elem ) { + var raw = elem[0]; + if ( raw.nodeType === 9 ) { + return { + width: elem.width(), + height: elem.height(), + offset: { top: 0, left: 0 } + }; + } + if ( $.isWindow( raw ) ) { + return { + width: elem.width(), + height: elem.height(), + offset: { top: elem.scrollTop(), left: elem.scrollLeft() } + }; + } + if ( raw.preventDefault ) { + return { + width: 0, + height: 0, + offset: { top: raw.pageY, left: raw.pageX } + }; + } + return { + width: elem.outerWidth(), + height: elem.outerHeight(), + offset: elem.offset() + }; +} + +$.position = { + scrollbarWidth: function() { + if ( cachedScrollbarWidth !== undefined ) { + return cachedScrollbarWidth; + } + var w1, w2, + div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), + innerDiv = div.children()[0]; + + $( "body" ).append( div ); + w1 = innerDiv.offsetWidth; + div.css( "overflow", "scroll" ); + + w2 = innerDiv.offsetWidth; + + if ( w1 === w2 ) { + w2 = div[0].clientWidth; + } + + div.remove(); + + return (cachedScrollbarWidth = w1 - w2); + }, + getScrollInfo: function( within ) { + var overflowX = within.isWindow || within.isDocument ? "" : + within.element.css( "overflow-x" ), + overflowY = within.isWindow || within.isDocument ? "" : + within.element.css( "overflow-y" ), + hasOverflowX = overflowX === "scroll" || + ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), + hasOverflowY = overflowY === "scroll" || + ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); + return { + width: hasOverflowY ? $.position.scrollbarWidth() : 0, + height: hasOverflowX ? $.position.scrollbarWidth() : 0 + }; + }, + getWithinInfo: function( element ) { + var withinElement = $( element || window ), + isWindow = $.isWindow( withinElement[0] ), + isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9; + return { + element: withinElement, + isWindow: isWindow, + isDocument: isDocument, + offset: withinElement.offset() || { left: 0, top: 0 }, + scrollLeft: withinElement.scrollLeft(), + scrollTop: withinElement.scrollTop(), + + // support: jQuery 1.6.x + // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows + width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(), + height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight() + }; + } +}; + +$.fn.position = function( options ) { + if ( !options || !options.of ) { + return _position.apply( this, arguments ); + } + + // make a copy, we don't want to modify arguments + options = $.extend( {}, options ); + + var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, + target = $( options.of ), + within = $.position.getWithinInfo( options.within ), + scrollInfo = $.position.getScrollInfo( within ), + collision = ( options.collision || "flip" ).split( " " ), + offsets = {}; + + dimensions = getDimensions( target ); + if ( target[0].preventDefault ) { + // force left top to allow flipping + options.at = "left top"; + } + targetWidth = dimensions.width; + targetHeight = dimensions.height; + targetOffset = dimensions.offset; + // clone to reuse original targetOffset later + basePosition = $.extend( {}, targetOffset ); + + // force my and at to have valid horizontal and vertical positions + // if a value is missing or invalid, it will be converted to center + $.each( [ "my", "at" ], function() { + var pos = ( options[ this ] || "" ).split( " " ), + horizontalOffset, + verticalOffset; + + if ( pos.length === 1) { + pos = rhorizontal.test( pos[ 0 ] ) ? + pos.concat( [ "center" ] ) : + rvertical.test( pos[ 0 ] ) ? + [ "center" ].concat( pos ) : + [ "center", "center" ]; + } + pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; + pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; + + // calculate offsets + horizontalOffset = roffset.exec( pos[ 0 ] ); + verticalOffset = roffset.exec( pos[ 1 ] ); + offsets[ this ] = [ + horizontalOffset ? horizontalOffset[ 0 ] : 0, + verticalOffset ? verticalOffset[ 0 ] : 0 + ]; + + // reduce to just the positions without the offsets + options[ this ] = [ + rposition.exec( pos[ 0 ] )[ 0 ], + rposition.exec( pos[ 1 ] )[ 0 ] + ]; + }); + + // normalize collision option + if ( collision.length === 1 ) { + collision[ 1 ] = collision[ 0 ]; + } + + if ( options.at[ 0 ] === "right" ) { + basePosition.left += targetWidth; + } else if ( options.at[ 0 ] === "center" ) { + basePosition.left += targetWidth / 2; + } + + if ( options.at[ 1 ] === "bottom" ) { + basePosition.top += targetHeight; + } else if ( options.at[ 1 ] === "center" ) { + basePosition.top += targetHeight / 2; + } + + atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); + basePosition.left += atOffset[ 0 ]; + basePosition.top += atOffset[ 1 ]; + + return this.each(function() { + var collisionPosition, using, + elem = $( this ), + elemWidth = elem.outerWidth(), + elemHeight = elem.outerHeight(), + marginLeft = parseCss( this, "marginLeft" ), + marginTop = parseCss( this, "marginTop" ), + collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, + collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, + position = $.extend( {}, basePosition ), + myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); + + if ( options.my[ 0 ] === "right" ) { + position.left -= elemWidth; + } else if ( options.my[ 0 ] === "center" ) { + position.left -= elemWidth / 2; + } + + if ( options.my[ 1 ] === "bottom" ) { + position.top -= elemHeight; + } else if ( options.my[ 1 ] === "center" ) { + position.top -= elemHeight / 2; + } + + position.left += myOffset[ 0 ]; + position.top += myOffset[ 1 ]; + + // if the browser doesn't support fractions, then round for consistent results + if ( !supportsOffsetFractions ) { + position.left = round( position.left ); + position.top = round( position.top ); + } + + collisionPosition = { + marginLeft: marginLeft, + marginTop: marginTop + }; + + $.each( [ "left", "top" ], function( i, dir ) { + if ( $.ui.position[ collision[ i ] ] ) { + $.ui.position[ collision[ i ] ][ dir ]( position, { + targetWidth: targetWidth, + targetHeight: targetHeight, + elemWidth: elemWidth, + elemHeight: elemHeight, + collisionPosition: collisionPosition, + collisionWidth: collisionWidth, + collisionHeight: collisionHeight, + offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], + my: options.my, + at: options.at, + within: within, + elem: elem + }); + } + }); + + if ( options.using ) { + // adds feedback as second argument to using callback, if present + using = function( props ) { + var left = targetOffset.left - position.left, + right = left + targetWidth - elemWidth, + top = targetOffset.top - position.top, + bottom = top + targetHeight - elemHeight, + feedback = { + target: { + element: target, + left: targetOffset.left, + top: targetOffset.top, + width: targetWidth, + height: targetHeight + }, + element: { + element: elem, + left: position.left, + top: position.top, + width: elemWidth, + height: elemHeight + }, + horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", + vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" + }; + if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { + feedback.horizontal = "center"; + } + if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { + feedback.vertical = "middle"; + } + if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { + feedback.important = "horizontal"; + } else { + feedback.important = "vertical"; + } + options.using.call( this, props, feedback ); + }; + } + + elem.offset( $.extend( position, { using: using } ) ); + }); +}; + +$.ui.position = { + fit: { + left: function( position, data ) { + var within = data.within, + withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, + outerWidth = within.width, + collisionPosLeft = position.left - data.collisionPosition.marginLeft, + overLeft = withinOffset - collisionPosLeft, + overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, + newOverRight; + + // element is wider than within + if ( data.collisionWidth > outerWidth ) { + // element is initially over the left side of within + if ( overLeft > 0 && overRight <= 0 ) { + newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; + position.left += overLeft - newOverRight; + // element is initially over right side of within + } else if ( overRight > 0 && overLeft <= 0 ) { + position.left = withinOffset; + // element is initially over both left and right sides of within + } else { + if ( overLeft > overRight ) { + position.left = withinOffset + outerWidth - data.collisionWidth; + } else { + position.left = withinOffset; + } + } + // too far left -> align with left edge + } else if ( overLeft > 0 ) { + position.left += overLeft; + // too far right -> align with right edge + } else if ( overRight > 0 ) { + position.left -= overRight; + // adjust based on position and margin + } else { + position.left = max( position.left - collisionPosLeft, position.left ); + } + }, + top: function( position, data ) { + var within = data.within, + withinOffset = within.isWindow ? within.scrollTop : within.offset.top, + outerHeight = data.within.height, + collisionPosTop = position.top - data.collisionPosition.marginTop, + overTop = withinOffset - collisionPosTop, + overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, + newOverBottom; + + // element is taller than within + if ( data.collisionHeight > outerHeight ) { + // element is initially over the top of within + if ( overTop > 0 && overBottom <= 0 ) { + newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; + position.top += overTop - newOverBottom; + // element is initially over bottom of within + } else if ( overBottom > 0 && overTop <= 0 ) { + position.top = withinOffset; + // element is initially over both top and bottom of within + } else { + if ( overTop > overBottom ) { + position.top = withinOffset + outerHeight - data.collisionHeight; + } else { + position.top = withinOffset; + } + } + // too far up -> align with top + } else if ( overTop > 0 ) { + position.top += overTop; + // too far down -> align with bottom edge + } else if ( overBottom > 0 ) { + position.top -= overBottom; + // adjust based on position and margin + } else { + position.top = max( position.top - collisionPosTop, position.top ); + } + } + }, + flip: { + left: function( position, data ) { + var within = data.within, + withinOffset = within.offset.left + within.scrollLeft, + outerWidth = within.width, + offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, + collisionPosLeft = position.left - data.collisionPosition.marginLeft, + overLeft = collisionPosLeft - offsetLeft, + overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, + myOffset = data.my[ 0 ] === "left" ? + -data.elemWidth : + data.my[ 0 ] === "right" ? + data.elemWidth : + 0, + atOffset = data.at[ 0 ] === "left" ? + data.targetWidth : + data.at[ 0 ] === "right" ? + -data.targetWidth : + 0, + offset = -2 * data.offset[ 0 ], + newOverRight, + newOverLeft; + + if ( overLeft < 0 ) { + newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; + if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { + position.left += myOffset + atOffset + offset; + } + } else if ( overRight > 0 ) { + newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; + if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { + position.left += myOffset + atOffset + offset; + } + } + }, + top: function( position, data ) { + var within = data.within, + withinOffset = within.offset.top + within.scrollTop, + outerHeight = within.height, + offsetTop = within.isWindow ? within.scrollTop : within.offset.top, + collisionPosTop = position.top - data.collisionPosition.marginTop, + overTop = collisionPosTop - offsetTop, + overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, + top = data.my[ 1 ] === "top", + myOffset = top ? + -data.elemHeight : + data.my[ 1 ] === "bottom" ? + data.elemHeight : + 0, + atOffset = data.at[ 1 ] === "top" ? + data.targetHeight : + data.at[ 1 ] === "bottom" ? + -data.targetHeight : + 0, + offset = -2 * data.offset[ 1 ], + newOverTop, + newOverBottom; + if ( overTop < 0 ) { + newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; + if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { + position.top += myOffset + atOffset + offset; + } + } else if ( overBottom > 0 ) { + newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; + if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { + position.top += myOffset + atOffset + offset; + } + } + } + }, + flipfit: { + left: function() { + $.ui.position.flip.left.apply( this, arguments ); + $.ui.position.fit.left.apply( this, arguments ); + }, + top: function() { + $.ui.position.flip.top.apply( this, arguments ); + $.ui.position.fit.top.apply( this, arguments ); + } + } +}; + +// fraction support test +(function() { + var testElement, testElementParent, testElementStyle, offsetLeft, i, + body = document.getElementsByTagName( "body" )[ 0 ], + div = document.createElement( "div" ); + + //Create a "fake body" for testing based on method used in jQuery.support + testElement = document.createElement( body ? "div" : "body" ); + testElementStyle = { + visibility: "hidden", + width: 0, + height: 0, + border: 0, + margin: 0, + background: "none" + }; + if ( body ) { + $.extend( testElementStyle, { + position: "absolute", + left: "-1000px", + top: "-1000px" + }); + } + for ( i in testElementStyle ) { + testElement.style[ i ] = testElementStyle[ i ]; + } + testElement.appendChild( div ); + testElementParent = body || document.documentElement; + testElementParent.insertBefore( testElement, testElementParent.firstChild ); + + div.style.cssText = "position: absolute; left: 10.7432222px;"; + + offsetLeft = $( div ).offset().left; + supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11; + + testElement.innerHTML = ""; + testElementParent.removeChild( testElement ); +})(); + +})(); + +return $.ui.position; + +})); + + + + +/*! + * jQuery UI Resizable 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/resizable/ + */ + +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define([ + "jquery", + "./core", + "./mouse", + "./widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +}(function( $ ) { + +$.widget("ui.resizable", $.ui.mouse, { + version: "1.11.4", + widgetEventPrefix: "resize", + options: { + alsoResize: false, + animate: false, + animateDuration: "slow", + animateEasing: "swing", + aspectRatio: false, + autoHide: false, + containment: false, + ghost: false, + grid: false, + handles: "e,s,se", + helper: false, + maxHeight: null, + maxWidth: null, + minHeight: 10, + minWidth: 10, + // See #7960 + zIndex: 90, + + // callbacks + resize: null, + start: null, + stop: null + }, + + _num: function( value ) { + return parseInt( value, 10 ) || 0; + }, + + _isNumber: function( value ) { + return !isNaN( parseInt( value, 10 ) ); + }, + + _hasScroll: function( el, a ) { + + if ( $( el ).css( "overflow" ) === "hidden") { + return false; + } + + var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", + has = false; + + if ( el[ scroll ] > 0 ) { + return true; + } + + // TODO: determine which cases actually cause this to happen + // if the element doesn't have the scroll set, see if it's possible to + // set the scroll + el[ scroll ] = 1; + has = ( el[ scroll ] > 0 ); + el[ scroll ] = 0; + return has; + }, + + _create: function() { + + var n, i, handle, axis, hname, + that = this, + o = this.options; + this.element.addClass("ui-resizable"); + + $.extend(this, { + _aspectRatio: !!(o.aspectRatio), + aspectRatio: o.aspectRatio, + originalElement: this.element, + _proportionallyResizeElements: [], + _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null + }); + + // Wrap the element if it cannot hold child nodes + if (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) { + + this.element.wrap( + $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({ + position: this.element.css("position"), + width: this.element.outerWidth(), + height: this.element.outerHeight(), + top: this.element.css("top"), + left: this.element.css("left") + }) + ); + + this.element = this.element.parent().data( + "ui-resizable", this.element.resizable( "instance" ) + ); + + this.elementIsWrapper = true; + + this.element.css({ + marginLeft: this.originalElement.css("marginLeft"), + marginTop: this.originalElement.css("marginTop"), + marginRight: this.originalElement.css("marginRight"), + marginBottom: this.originalElement.css("marginBottom") + }); + this.originalElement.css({ + marginLeft: 0, + marginTop: 0, + marginRight: 0, + marginBottom: 0 + }); + // support: Safari + // Prevent Safari textarea resize + this.originalResizeStyle = this.originalElement.css("resize"); + this.originalElement.css("resize", "none"); + + this._proportionallyResizeElements.push( this.originalElement.css({ + position: "static", + zoom: 1, + display: "block" + }) ); + + // support: IE9 + // avoid IE jump (hard set the margin) + this.originalElement.css({ margin: this.originalElement.css("margin") }); + + this._proportionallyResize(); + } + + this.handles = o.handles || + ( !$(".ui-resizable-handle", this.element).length ? + "e,s,se" : { + n: ".ui-resizable-n", + e: ".ui-resizable-e", + s: ".ui-resizable-s", + w: ".ui-resizable-w", + se: ".ui-resizable-se", + sw: ".ui-resizable-sw", + ne: ".ui-resizable-ne", + nw: ".ui-resizable-nw" + } ); + + this._handles = $(); + if ( this.handles.constructor === String ) { + + if ( this.handles === "all") { + this.handles = "n,e,s,w,se,sw,ne,nw"; + } + + n = this.handles.split(","); + this.handles = {}; + + for (i = 0; i < n.length; i++) { + + handle = $.trim(n[i]); + hname = "ui-resizable-" + handle; + axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); + + axis.css({ zIndex: o.zIndex }); + + // TODO : What's going on here? + if ("se" === handle) { + axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); + } + + this.handles[handle] = ".ui-resizable-" + handle; + this.element.append(axis); + } + + } + + this._renderAxis = function(target) { + + var i, axis, padPos, padWrapper; + + target = target || this.element; + + for (i in this.handles) { + + if (this.handles[i].constructor === String) { + this.handles[i] = this.element.children( this.handles[ i ] ).first().show(); + } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) { + this.handles[ i ] = $( this.handles[ i ] ); + this._on( this.handles[ i ], { "mousedown": that._mouseDown }); + } + + if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)) { + + axis = $(this.handles[i], this.element); + + padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); + + padPos = [ "padding", + /ne|nw|n/.test(i) ? "Top" : + /se|sw|s/.test(i) ? "Bottom" : + /^e$/.test(i) ? "Right" : "Left" ].join(""); + + target.css(padPos, padWrapper); + + this._proportionallyResize(); + } + + this._handles = this._handles.add( this.handles[ i ] ); + } + }; + + // TODO: make renderAxis a prototype function + this._renderAxis(this.element); + + this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) ); + this._handles.disableSelection(); + + this._handles.mouseover(function() { + if (!that.resizing) { + if (this.className) { + axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); + } + that.axis = axis && axis[1] ? axis[1] : "se"; + } + }); + + if (o.autoHide) { + this._handles.hide(); + $(this.element) + .addClass("ui-resizable-autohide") + .mouseenter(function() { + if (o.disabled) { + return; + } + $(this).removeClass("ui-resizable-autohide"); + that._handles.show(); + }) + .mouseleave(function() { + if (o.disabled) { + return; + } + if (!that.resizing) { + $(this).addClass("ui-resizable-autohide"); + that._handles.hide(); + } + }); + } + + this._mouseInit(); + }, + + _destroy: function() { + + this._mouseDestroy(); + + var wrapper, + _destroy = function(exp) { + $(exp) + .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") + .removeData("resizable") + .removeData("ui-resizable") + .unbind(".resizable") + .find(".ui-resizable-handle") + .remove(); + }; + + // TODO: Unwrap at same DOM position + if (this.elementIsWrapper) { + _destroy(this.element); + wrapper = this.element; + this.originalElement.css({ + position: wrapper.css("position"), + width: wrapper.outerWidth(), + height: wrapper.outerHeight(), + top: wrapper.css("top"), + left: wrapper.css("left") + }).insertAfter( wrapper ); + wrapper.remove(); + } + + this.originalElement.css("resize", this.originalResizeStyle); + _destroy(this.originalElement); + + return this; + }, + + _mouseCapture: function(event) { + var i, handle, + capture = false; + + for (i in this.handles) { + handle = $(this.handles[i])[0]; + if (handle === event.target || $.contains(handle, event.target)) { + capture = true; + } + } + + return !this.options.disabled && capture; + }, + + _mouseStart: function(event) { + + var curleft, curtop, cursor, + o = this.options, + el = this.element; + + this.resizing = true; + + this._renderProxy(); + + curleft = this._num(this.helper.css("left")); + curtop = this._num(this.helper.css("top")); + + if (o.containment) { + curleft += $(o.containment).scrollLeft() || 0; + curtop += $(o.containment).scrollTop() || 0; + } + + this.offset = this.helper.offset(); + this.position = { left: curleft, top: curtop }; + + this.size = this._helper ? { + width: this.helper.width(), + height: this.helper.height() + } : { + width: el.width(), + height: el.height() + }; + + this.originalSize = this._helper ? { + width: el.outerWidth(), + height: el.outerHeight() + } : { + width: el.width(), + height: el.height() + }; + + this.sizeDiff = { + width: el.outerWidth() - el.width(), + height: el.outerHeight() - el.height() + }; + + this.originalPosition = { left: curleft, top: curtop }; + this.originalMousePosition = { left: event.pageX, top: event.pageY }; + + this.aspectRatio = (typeof o.aspectRatio === "number") ? + o.aspectRatio : + ((this.originalSize.width / this.originalSize.height) || 1); + + cursor = $(".ui-resizable-" + this.axis).css("cursor"); + $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); + + el.addClass("ui-resizable-resizing"); + this._propagate("start", event); + return true; + }, + + _mouseDrag: function(event) { + + var data, props, + smp = this.originalMousePosition, + a = this.axis, + dx = (event.pageX - smp.left) || 0, + dy = (event.pageY - smp.top) || 0, + trigger = this._change[a]; + + this._updatePrevProperties(); + + if (!trigger) { + return false; + } + + data = trigger.apply(this, [ event, dx, dy ]); + + this._updateVirtualBoundaries(event.shiftKey); + if (this._aspectRatio || event.shiftKey) { + data = this._updateRatio(data, event); + } + + data = this._respectSize(data, event); + + this._updateCache(data); + + this._propagate("resize", event); + + props = this._applyChanges(); + + if ( !this._helper && this._proportionallyResizeElements.length ) { + this._proportionallyResize(); + } + + if ( !$.isEmptyObject( props ) ) { + this._updatePrevProperties(); + this._trigger( "resize", event, this.ui() ); + this._applyChanges(); + } + + return false; + }, + + _mouseStop: function(event) { + + this.resizing = false; + var pr, ista, soffseth, soffsetw, s, left, top, + o = this.options, that = this; + + if (this._helper) { + + pr = this._proportionallyResizeElements; + ista = pr.length && (/textarea/i).test(pr[0].nodeName); + soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height; + soffsetw = ista ? 0 : that.sizeDiff.width; + + s = { + width: (that.helper.width() - soffsetw), + height: (that.helper.height() - soffseth) + }; + left = (parseInt(that.element.css("left"), 10) + + (that.position.left - that.originalPosition.left)) || null; + top = (parseInt(that.element.css("top"), 10) + + (that.position.top - that.originalPosition.top)) || null; + + if (!o.animate) { + this.element.css($.extend(s, { top: top, left: left })); + } + + that.helper.height(that.size.height); + that.helper.width(that.size.width); + + if (this._helper && !o.animate) { + this._proportionallyResize(); + } + } + + $("body").css("cursor", "auto"); + + this.element.removeClass("ui-resizable-resizing"); + + this._propagate("stop", event); + + if (this._helper) { + this.helper.remove(); + } + + return false; + + }, + + _updatePrevProperties: function() { + this.prevPosition = { + top: this.position.top, + left: this.position.left + }; + this.prevSize = { + width: this.size.width, + height: this.size.height + }; + }, + + _applyChanges: function() { + var props = {}; + + if ( this.position.top !== this.prevPosition.top ) { + props.top = this.position.top + "px"; + } + if ( this.position.left !== this.prevPosition.left ) { + props.left = this.position.left + "px"; + } + if ( this.size.width !== this.prevSize.width ) { + props.width = this.size.width + "px"; + } + if ( this.size.height !== this.prevSize.height ) { + props.height = this.size.height + "px"; + } + + this.helper.css( props ); + + return props; + }, + + _updateVirtualBoundaries: function(forceAspectRatio) { + var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, + o = this.options; + + b = { + minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0, + maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity, + minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0, + maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity + }; + + if (this._aspectRatio || forceAspectRatio) { + pMinWidth = b.minHeight * this.aspectRatio; + pMinHeight = b.minWidth / this.aspectRatio; + pMaxWidth = b.maxHeight * this.aspectRatio; + pMaxHeight = b.maxWidth / this.aspectRatio; + + if (pMinWidth > b.minWidth) { + b.minWidth = pMinWidth; + } + if (pMinHeight > b.minHeight) { + b.minHeight = pMinHeight; + } + if (pMaxWidth < b.maxWidth) { + b.maxWidth = pMaxWidth; + } + if (pMaxHeight < b.maxHeight) { + b.maxHeight = pMaxHeight; + } + } + this._vBoundaries = b; + }, + + _updateCache: function(data) { + this.offset = this.helper.offset(); + if (this._isNumber(data.left)) { + this.position.left = data.left; + } + if (this._isNumber(data.top)) { + this.position.top = data.top; + } + if (this._isNumber(data.height)) { + this.size.height = data.height; + } + if (this._isNumber(data.width)) { + this.size.width = data.width; + } + }, + + _updateRatio: function( data ) { + + var cpos = this.position, + csize = this.size, + a = this.axis; + + if (this._isNumber(data.height)) { + data.width = (data.height * this.aspectRatio); + } else if (this._isNumber(data.width)) { + data.height = (data.width / this.aspectRatio); + } + + if (a === "sw") { + data.left = cpos.left + (csize.width - data.width); + data.top = null; + } + if (a === "nw") { + data.top = cpos.top + (csize.height - data.height); + data.left = cpos.left + (csize.width - data.width); + } + + return data; + }, + + _respectSize: function( data ) { + + var o = this._vBoundaries, + a = this.axis, + ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), + ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), + isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width), + isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height), + dw = this.originalPosition.left + this.originalSize.width, + dh = this.position.top + this.size.height, + cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); + if (isminw) { + data.width = o.minWidth; + } + if (isminh) { + data.height = o.minHeight; + } + if (ismaxw) { + data.width = o.maxWidth; + } + if (ismaxh) { + data.height = o.maxHeight; + } + + if (isminw && cw) { + data.left = dw - o.minWidth; + } + if (ismaxw && cw) { + data.left = dw - o.maxWidth; + } + if (isminh && ch) { + data.top = dh - o.minHeight; + } + if (ismaxh && ch) { + data.top = dh - o.maxHeight; + } + + // Fixing jump error on top/left - bug #2330 + if (!data.width && !data.height && !data.left && data.top) { + data.top = null; + } else if (!data.width && !data.height && !data.top && data.left) { + data.left = null; + } + + return data; + }, + + _getPaddingPlusBorderDimensions: function( element ) { + var i = 0, + widths = [], + borders = [ + element.css( "borderTopWidth" ), + element.css( "borderRightWidth" ), + element.css( "borderBottomWidth" ), + element.css( "borderLeftWidth" ) + ], + paddings = [ + element.css( "paddingTop" ), + element.css( "paddingRight" ), + element.css( "paddingBottom" ), + element.css( "paddingLeft" ) + ]; + + for ( ; i < 4; i++ ) { + widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 ); + widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 ); + } + + return { + height: widths[ 0 ] + widths[ 2 ], + width: widths[ 1 ] + widths[ 3 ] + }; + }, + + _proportionallyResize: function() { + + if (!this._proportionallyResizeElements.length) { + return; + } + + var prel, + i = 0, + element = this.helper || this.element; + + for ( ; i < this._proportionallyResizeElements.length; i++) { + + prel = this._proportionallyResizeElements[i]; + + // TODO: Seems like a bug to cache this.outerDimensions + // considering that we are in a loop. + if (!this.outerDimensions) { + this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); + } + + prel.css({ + height: (element.height() - this.outerDimensions.height) || 0, + width: (element.width() - this.outerDimensions.width) || 0 + }); + + } + + }, + + _renderProxy: function() { + + var el = this.element, o = this.options; + this.elementOffset = el.offset(); + + if (this._helper) { + + this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); + + this.helper.addClass(this._helper).css({ + width: this.element.outerWidth() - 1, + height: this.element.outerHeight() - 1, + position: "absolute", + left: this.elementOffset.left + "px", + top: this.elementOffset.top + "px", + zIndex: ++o.zIndex //TODO: Don't modify option + }); + + this.helper + .appendTo("body") + .disableSelection(); + + } else { + this.helper = this.element; + } + + }, + + _change: { + e: function(event, dx) { + return { width: this.originalSize.width + dx }; + }, + w: function(event, dx) { + var cs = this.originalSize, sp = this.originalPosition; + return { left: sp.left + dx, width: cs.width - dx }; + }, + n: function(event, dx, dy) { + var cs = this.originalSize, sp = this.originalPosition; + return { top: sp.top + dy, height: cs.height - dy }; + }, + s: function(event, dx, dy) { + return { height: this.originalSize.height + dy }; + }, + se: function(event, dx, dy) { + return $.extend(this._change.s.apply(this, arguments), + this._change.e.apply(this, [ event, dx, dy ])); + }, + sw: function(event, dx, dy) { + return $.extend(this._change.s.apply(this, arguments), + this._change.w.apply(this, [ event, dx, dy ])); + }, + ne: function(event, dx, dy) { + return $.extend(this._change.n.apply(this, arguments), + this._change.e.apply(this, [ event, dx, dy ])); + }, + nw: function(event, dx, dy) { + return $.extend(this._change.n.apply(this, arguments), + this._change.w.apply(this, [ event, dx, dy ])); + } + }, + + _propagate: function(n, event) { + $.ui.plugin.call(this, n, [ event, this.ui() ]); + (n !== "resize" && this._trigger(n, event, this.ui())); + }, + + plugins: {}, + + ui: function() { + return { + originalElement: this.originalElement, + element: this.element, + helper: this.helper, + position: this.position, + size: this.size, + originalSize: this.originalSize, + originalPosition: this.originalPosition + }; + } + +}); + +/* + * Resizable Extensions + */ + +$.ui.plugin.add("resizable", "animate", { + + stop: function( event ) { + var that = $(this).resizable( "instance" ), + o = that.options, + pr = that._proportionallyResizeElements, + ista = pr.length && (/textarea/i).test(pr[0].nodeName), + soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height, + soffsetw = ista ? 0 : that.sizeDiff.width, + style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, + left = (parseInt(that.element.css("left"), 10) + + (that.position.left - that.originalPosition.left)) || null, + top = (parseInt(that.element.css("top"), 10) + + (that.position.top - that.originalPosition.top)) || null; + + that.element.animate( + $.extend(style, top && left ? { top: top, left: left } : {}), { + duration: o.animateDuration, + easing: o.animateEasing, + step: function() { + + var data = { + width: parseInt(that.element.css("width"), 10), + height: parseInt(that.element.css("height"), 10), + top: parseInt(that.element.css("top"), 10), + left: parseInt(that.element.css("left"), 10) + }; + + if (pr && pr.length) { + $(pr[0]).css({ width: data.width, height: data.height }); + } + + // propagating resize, and updating values for each animation step + that._updateCache(data); + that._propagate("resize", event); + + } + } + ); + } + +}); + +$.ui.plugin.add( "resizable", "containment", { + + start: function() { + var element, p, co, ch, cw, width, height, + that = $( this ).resizable( "instance" ), + o = that.options, + el = that.element, + oc = o.containment, + ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; + + if ( !ce ) { + return; + } + + that.containerElement = $( ce ); + + if ( /document/.test( oc ) || oc === document ) { + that.containerOffset = { + left: 0, + top: 0 + }; + that.containerPosition = { + left: 0, + top: 0 + }; + + that.parentData = { + element: $( document ), + left: 0, + top: 0, + width: $( document ).width(), + height: $( document ).height() || document.body.parentNode.scrollHeight + }; + } else { + element = $( ce ); + p = []; + $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) { + p[ i ] = that._num( element.css( "padding" + name ) ); + }); + + that.containerOffset = element.offset(); + that.containerPosition = element.position(); + that.containerSize = { + height: ( element.innerHeight() - p[ 3 ] ), + width: ( element.innerWidth() - p[ 1 ] ) + }; + + co = that.containerOffset; + ch = that.containerSize.height; + cw = that.containerSize.width; + width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw ); + height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ; + + that.parentData = { + element: ce, + left: co.left, + top: co.top, + width: width, + height: height + }; + } + }, + + resize: function( event ) { + var woset, hoset, isParent, isOffsetRelative, + that = $( this ).resizable( "instance" ), + o = that.options, + co = that.containerOffset, + cp = that.position, + pRatio = that._aspectRatio || event.shiftKey, + cop = { + top: 0, + left: 0 + }, + ce = that.containerElement, + continueResize = true; + + if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) { + cop = co; + } + + if ( cp.left < ( that._helper ? co.left : 0 ) ) { + that.size.width = that.size.width + + ( that._helper ? + ( that.position.left - co.left ) : + ( that.position.left - cop.left ) ); + + if ( pRatio ) { + that.size.height = that.size.width / that.aspectRatio; + continueResize = false; + } + that.position.left = o.helper ? co.left : 0; + } + + if ( cp.top < ( that._helper ? co.top : 0 ) ) { + that.size.height = that.size.height + + ( that._helper ? + ( that.position.top - co.top ) : + that.position.top ); + + if ( pRatio ) { + that.size.width = that.size.height * that.aspectRatio; + continueResize = false; + } + that.position.top = that._helper ? co.top : 0; + } + + isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 ); + isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) ); + + if ( isParent && isOffsetRelative ) { + that.offset.left = that.parentData.left + that.position.left; + that.offset.top = that.parentData.top + that.position.top; + } else { + that.offset.left = that.element.offset().left; + that.offset.top = that.element.offset().top; + } + + woset = Math.abs( that.sizeDiff.width + + (that._helper ? + that.offset.left - cop.left : + (that.offset.left - co.left)) ); + + hoset = Math.abs( that.sizeDiff.height + + (that._helper ? + that.offset.top - cop.top : + (that.offset.top - co.top)) ); + + if ( woset + that.size.width >= that.parentData.width ) { + that.size.width = that.parentData.width - woset; + if ( pRatio ) { + that.size.height = that.size.width / that.aspectRatio; + continueResize = false; + } + } + + if ( hoset + that.size.height >= that.parentData.height ) { + that.size.height = that.parentData.height - hoset; + if ( pRatio ) { + that.size.width = that.size.height * that.aspectRatio; + continueResize = false; + } + } + + if ( !continueResize ) { + that.position.left = that.prevPosition.left; + that.position.top = that.prevPosition.top; + that.size.width = that.prevSize.width; + that.size.height = that.prevSize.height; + } + }, + + stop: function() { + var that = $( this ).resizable( "instance" ), + o = that.options, + co = that.containerOffset, + cop = that.containerPosition, + ce = that.containerElement, + helper = $( that.helper ), + ho = helper.offset(), + w = helper.outerWidth() - that.sizeDiff.width, + h = helper.outerHeight() - that.sizeDiff.height; + + if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) { + $( this ).css({ + left: ho.left - cop.left - co.left, + width: w, + height: h + }); + } + + if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) { + $( this ).css({ + left: ho.left - cop.left - co.left, + width: w, + height: h + }); + } + } +}); + +$.ui.plugin.add("resizable", "alsoResize", { + + start: function() { + var that = $(this).resizable( "instance" ), + o = that.options; + + $(o.alsoResize).each(function() { + var el = $(this); + el.data("ui-resizable-alsoresize", { + width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), + left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) + }); + }); + }, + + resize: function(event, ui) { + var that = $(this).resizable( "instance" ), + o = that.options, + os = that.originalSize, + op = that.originalPosition, + delta = { + height: (that.size.height - os.height) || 0, + width: (that.size.width - os.width) || 0, + top: (that.position.top - op.top) || 0, + left: (that.position.left - op.left) || 0 + }; + + $(o.alsoResize).each(function() { + var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, + css = el.parents(ui.originalElement[0]).length ? + [ "width", "height" ] : + [ "width", "height", "top", "left" ]; + + $.each(css, function(i, prop) { + var sum = (start[prop] || 0) + (delta[prop] || 0); + if (sum && sum >= 0) { + style[prop] = sum || null; + } + }); + + el.css(style); + }); + }, + + stop: function() { + $(this).removeData("resizable-alsoresize"); + } +}); + +$.ui.plugin.add("resizable", "ghost", { + + start: function() { + + var that = $(this).resizable( "instance" ), o = that.options, cs = that.size; + + that.ghost = that.originalElement.clone(); + that.ghost + .css({ + opacity: 0.25, + display: "block", + position: "relative", + height: cs.height, + width: cs.width, + margin: 0, + left: 0, + top: 0 + }) + .addClass("ui-resizable-ghost") + .addClass(typeof o.ghost === "string" ? o.ghost : ""); + + that.ghost.appendTo(that.helper); + + }, + + resize: function() { + var that = $(this).resizable( "instance" ); + if (that.ghost) { + that.ghost.css({ + position: "relative", + height: that.size.height, + width: that.size.width + }); + } + }, + + stop: function() { + var that = $(this).resizable( "instance" ); + if (that.ghost && that.helper) { + that.helper.get(0).removeChild(that.ghost.get(0)); + } + } + +}); + +$.ui.plugin.add("resizable", "grid", { + + resize: function() { + var outerDimensions, + that = $(this).resizable( "instance" ), + o = that.options, + cs = that.size, + os = that.originalSize, + op = that.originalPosition, + a = that.axis, + grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid, + gridX = (grid[0] || 1), + gridY = (grid[1] || 1), + ox = Math.round((cs.width - os.width) / gridX) * gridX, + oy = Math.round((cs.height - os.height) / gridY) * gridY, + newWidth = os.width + ox, + newHeight = os.height + oy, + isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), + isMaxHeight = o.maxHeight && (o.maxHeight < newHeight), + isMinWidth = o.minWidth && (o.minWidth > newWidth), + isMinHeight = o.minHeight && (o.minHeight > newHeight); + + o.grid = grid; + + if (isMinWidth) { + newWidth += gridX; + } + if (isMinHeight) { + newHeight += gridY; + } + if (isMaxWidth) { + newWidth -= gridX; + } + if (isMaxHeight) { + newHeight -= gridY; + } + + if (/^(se|s|e)$/.test(a)) { + that.size.width = newWidth; + that.size.height = newHeight; + } else if (/^(ne)$/.test(a)) { + that.size.width = newWidth; + that.size.height = newHeight; + that.position.top = op.top - oy; + } else if (/^(sw)$/.test(a)) { + that.size.width = newWidth; + that.size.height = newHeight; + that.position.left = op.left - ox; + } else { + if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) { + outerDimensions = that._getPaddingPlusBorderDimensions( this ); + } + + if ( newHeight - gridY > 0 ) { + that.size.height = newHeight; + that.position.top = op.top - oy; + } else { + newHeight = gridY - outerDimensions.height; + that.size.height = newHeight; + that.position.top = op.top + os.height - newHeight; + } + if ( newWidth - gridX > 0 ) { + that.size.width = newWidth; + that.position.left = op.left - ox; + } else { + newWidth = gridX - outerDimensions.width; + that.size.width = newWidth; + that.position.left = op.left + os.width - newWidth; + } + } + } + +}); + +return $.ui.resizable; + +})); + + + + + + + +/*! + * jQuery UI Dialog 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/dialog/ + */ + +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define([ + "jquery", + "./core", + "./widget", + "./button", + "./draggable", + "./mouse", + "./position", + "./resizable" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +}(function( $ ) { + +return $.widget( "ui.dialog", { + version: "1.11.4", + options: { + appendTo: "body", + autoOpen: true, + buttons: [], + closeOnEscape: true, + closeText: "Close", + dialogClass: "", + draggable: true, + hide: null, + height: "auto", + maxHeight: null, + maxWidth: null, + minHeight: 150, + minWidth: 150, + modal: false, + position: { + my: "center", + at: "center", + of: window, + collision: "fit", + // Ensure the titlebar is always visible + using: function( pos ) { + var topOffset = $( this ).css( pos ).offset().top; + if ( topOffset < 0 ) { + $( this ).css( "top", pos.top - topOffset ); + } + } + }, + resizable: true, + show: null, + title: null, + width: 300, + + // callbacks + beforeClose: null, + close: null, + drag: null, + dragStart: null, + dragStop: null, + focus: null, + open: null, + resize: null, + resizeStart: null, + resizeStop: null + }, + + sizeRelatedOptions: { + buttons: true, + height: true, + maxHeight: true, + maxWidth: true, + minHeight: true, + minWidth: true, + width: true + }, + + resizableRelatedOptions: { + maxHeight: true, + maxWidth: true, + minHeight: true, + minWidth: true + }, + + _create: function() { + this.originalCss = { + display: this.element[ 0 ].style.display, + width: this.element[ 0 ].style.width, + minHeight: this.element[ 0 ].style.minHeight, + maxHeight: this.element[ 0 ].style.maxHeight, + height: this.element[ 0 ].style.height + }; + this.originalPosition = { + parent: this.element.parent(), + index: this.element.parent().children().index( this.element ) + }; + this.originalTitle = this.element.attr( "title" ); + this.options.title = this.options.title || this.originalTitle; + + this._createWrapper(); + + this.element + .show() + .removeAttr( "title" ) + .addClass( "ui-dialog-content ui-widget-content" ) + .appendTo( this.uiDialog ); + + this._createTitlebar(); + this._createButtonPane(); + + if ( this.options.draggable && $.fn.draggable ) { + this._makeDraggable(); + } + if ( this.options.resizable && $.fn.resizable ) { + this._makeResizable(); + } + + this._isOpen = false; + + this._trackFocus(); + }, + + _init: function() { + if ( this.options.autoOpen ) { + this.open(); + } + }, + + _appendTo: function() { + var element = this.options.appendTo; + if ( element && (element.jquery || element.nodeType) ) { + return $( element ); + } + return this.document.find( element || "body" ).eq( 0 ); + }, + + _destroy: function() { + var next, + originalPosition = this.originalPosition; + + this._untrackInstance(); + this._destroyOverlay(); + + this.element + .removeUniqueId() + .removeClass( "ui-dialog-content ui-widget-content" ) + .css( this.originalCss ) + // Without detaching first, the following becomes really slow + .detach(); + + this.uiDialog.stop( true, true ).remove(); + + if ( this.originalTitle ) { + this.element.attr( "title", this.originalTitle ); + } + + next = originalPosition.parent.children().eq( originalPosition.index ); + // Don't try to place the dialog next to itself (#8613) + if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { + next.before( this.element ); + } else { + originalPosition.parent.append( this.element ); + } + }, + + widget: function() { + return this.uiDialog; + }, + + disable: $.noop, + enable: $.noop, + + close: function( event ) { + var activeElement, + that = this; + + if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { + return; + } + + this._isOpen = false; + this._focusedElement = null; + this._destroyOverlay(); + this._untrackInstance(); + + if ( !this.opener.filter( ":focusable" ).focus().length ) { + + // support: IE9 + // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> + try { + activeElement = this.document[ 0 ].activeElement; + + // Support: IE9, IE10 + // If the <body> is blurred, IE will switch windows, see #4520 + if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) { + + // Hiding a focused element doesn't trigger blur in WebKit + // so in case we have nothing to focus on, explicitly blur the active element + // https://bugs.webkit.org/show_bug.cgi?id=47182 + $( activeElement ).blur(); + } + } catch ( error ) {} + } + + this._hide( this.uiDialog, this.options.hide, function() { + that._trigger( "close", event ); + }); + }, + + isOpen: function() { + return this._isOpen; + }, + + moveToTop: function() { + this._moveToTop(); + }, + + _moveToTop: function( event, silent ) { + var moved = false, + zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map(function() { + return +$( this ).css( "z-index" ); + }).get(), + zIndexMax = Math.max.apply( null, zIndices ); + + if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) { + this.uiDialog.css( "z-index", zIndexMax + 1 ); + moved = true; + } + + if ( moved && !silent ) { + this._trigger( "focus", event ); + } + return moved; + }, + + open: function() { + var that = this; + if ( this._isOpen ) { + if ( this._moveToTop() ) { + this._focusTabbable(); + } + return; + } + + this._isOpen = true; + this.opener = $( this.document[ 0 ].activeElement ); + + this._size(); + this._position(); + this._createOverlay(); + this._moveToTop( null, true ); + + // Ensure the overlay is moved to the top with the dialog, but only when + // opening. The overlay shouldn't move after the dialog is open so that + // modeless dialogs opened after the modal dialog stack properly. + if ( this.overlay ) { + this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 ); + } + + this._show( this.uiDialog, this.options.show, function() { + that._focusTabbable(); + that._trigger( "focus" ); + }); + + // Track the dialog immediately upon openening in case a focus event + // somehow occurs outside of the dialog before an element inside the + // dialog is focused (#10152) + this._makeFocusTarget(); + + this._trigger( "open" ); + }, + + _focusTabbable: function() { + // Set focus to the first match: + // 1. An element that was focused previously + // 2. First element inside the dialog matching [autofocus] + // 3. Tabbable element inside the content element + // 4. Tabbable element inside the buttonpane + // 5. The close button + // 6. The dialog itself + var hasFocus = this._focusedElement; + if ( !hasFocus ) { + hasFocus = this.element.find( "[autofocus]" ); + } + if ( !hasFocus.length ) { + hasFocus = this.element.find( ":tabbable" ); + } + if ( !hasFocus.length ) { + hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); + } + if ( !hasFocus.length ) { + hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" ); + } + if ( !hasFocus.length ) { + hasFocus = this.uiDialog; + } + hasFocus.eq( 0 ).focus(); + }, + + _keepFocus: function( event ) { + function checkFocus() { + var activeElement = this.document[0].activeElement, + isActive = this.uiDialog[0] === activeElement || + $.contains( this.uiDialog[0], activeElement ); + if ( !isActive ) { + this._focusTabbable(); + } + } + event.preventDefault(); + checkFocus.call( this ); + // support: IE + // IE <= 8 doesn't prevent moving focus even with event.preventDefault() + // so we check again later + this._delay( checkFocus ); + }, + + _createWrapper: function() { + this.uiDialog = $("<div>") + .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + + this.options.dialogClass ) + .hide() + .attr({ + // Setting tabIndex makes the div focusable + tabIndex: -1, + role: "dialog" + }) + .appendTo( this._appendTo() ); + + this._on( this.uiDialog, { + keydown: function( event ) { + if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && + event.keyCode === $.ui.keyCode.ESCAPE ) { + event.preventDefault(); + this.close( event ); + return; + } + + // prevent tabbing out of dialogs + if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) { + return; + } + var tabbables = this.uiDialog.find( ":tabbable" ), + first = tabbables.filter( ":first" ), + last = tabbables.filter( ":last" ); + + if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { + this._delay(function() { + first.focus(); + }); + event.preventDefault(); + } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { + this._delay(function() { + last.focus(); + }); + event.preventDefault(); + } + }, + mousedown: function( event ) { + if ( this._moveToTop( event ) ) { + this._focusTabbable(); + } + } + }); + + // We assume that any existing aria-describedby attribute means + // that the dialog content is marked up properly + // otherwise we brute force the content as the description + if ( !this.element.find( "[aria-describedby]" ).length ) { + this.uiDialog.attr({ + "aria-describedby": this.element.uniqueId().attr( "id" ) + }); + } + }, + + _createTitlebar: function() { + var uiDialogTitle; + + this.uiDialogTitlebar = $( "<div>" ) + .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" ) + .prependTo( this.uiDialog ); + this._on( this.uiDialogTitlebar, { + mousedown: function( event ) { + // Don't prevent click on close button (#8838) + // Focusing a dialog that is partially scrolled out of view + // causes the browser to scroll it into view, preventing the click event + if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) { + // Dialog isn't getting focus when dragging (#8063) + this.uiDialog.focus(); + } + } + }); + + // support: IE + // Use type="button" to prevent enter keypresses in textboxes from closing the + // dialog in IE (#9312) + this.uiDialogTitlebarClose = $( "<button type='button'></button>" ) + .button({ + label: this.options.closeText, + icons: { + primary: "ui-icon-closethick" + }, + text: false + }) + .addClass( "ui-dialog-titlebar-close" ) + .appendTo( this.uiDialogTitlebar ); + this._on( this.uiDialogTitlebarClose, { + click: function( event ) { + event.preventDefault(); + this.close( event ); + } + }); + + uiDialogTitle = $( "<span>" ) + .uniqueId() + .addClass( "ui-dialog-title" ) + .prependTo( this.uiDialogTitlebar ); + this._title( uiDialogTitle ); + + this.uiDialog.attr({ + "aria-labelledby": uiDialogTitle.attr( "id" ) + }); + }, + + _title: function( title ) { + if ( !this.options.title ) { + title.html( " " ); + } + title.text( this.options.title ); + }, + + _createButtonPane: function() { + this.uiDialogButtonPane = $( "<div>" ) + .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" ); + + this.uiButtonSet = $( "<div>" ) + .addClass( "ui-dialog-buttonset" ) + .appendTo( this.uiDialogButtonPane ); + + this._createButtons(); + }, + + _createButtons: function() { + var that = this, + buttons = this.options.buttons; + + // if we already have a button pane, remove it + this.uiDialogButtonPane.remove(); + this.uiButtonSet.empty(); + + if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { + this.uiDialog.removeClass( "ui-dialog-buttons" ); + return; + } + + $.each( buttons, function( name, props ) { + var click, buttonOptions; + props = $.isFunction( props ) ? + { click: props, text: name } : + props; + // Default to a non-submitting button + props = $.extend( { type: "button" }, props ); + // Change the context for the click callback to be the main element + click = props.click; + props.click = function() { + click.apply( that.element[ 0 ], arguments ); + }; + buttonOptions = { + icons: props.icons, + text: props.showText + }; + delete props.icons; + delete props.showText; + $( "<button></button>", props ) + .button( buttonOptions ) + .appendTo( that.uiButtonSet ); + }); + this.uiDialog.addClass( "ui-dialog-buttons" ); + this.uiDialogButtonPane.appendTo( this.uiDialog ); + }, + + _makeDraggable: function() { + var that = this, + options = this.options; + + function filteredUi( ui ) { + return { + position: ui.position, + offset: ui.offset + }; + } + + this.uiDialog.draggable({ + cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", + handle: ".ui-dialog-titlebar", + containment: "document", + start: function( event, ui ) { + $( this ).addClass( "ui-dialog-dragging" ); + that._blockFrames(); + that._trigger( "dragStart", event, filteredUi( ui ) ); + }, + drag: function( event, ui ) { + that._trigger( "drag", event, filteredUi( ui ) ); + }, + stop: function( event, ui ) { + var left = ui.offset.left - that.document.scrollLeft(), + top = ui.offset.top - that.document.scrollTop(); + + options.position = { + my: "left top", + at: "left" + (left >= 0 ? "+" : "") + left + " " + + "top" + (top >= 0 ? "+" : "") + top, + of: that.window + }; + $( this ).removeClass( "ui-dialog-dragging" ); + that._unblockFrames(); + that._trigger( "dragStop", event, filteredUi( ui ) ); + } + }); + }, + + _makeResizable: function() { + var that = this, + options = this.options, + handles = options.resizable, + // .ui-resizable has position: relative defined in the stylesheet + // but dialogs have to use absolute or fixed positioning + position = this.uiDialog.css("position"), + resizeHandles = typeof handles === "string" ? + handles : + "n,e,s,w,se,sw,ne,nw"; + + function filteredUi( ui ) { + return { + originalPosition: ui.originalPosition, + originalSize: ui.originalSize, + position: ui.position, + size: ui.size + }; + } + + this.uiDialog.resizable({ + cancel: ".ui-dialog-content", + containment: "document", + alsoResize: this.element, + maxWidth: options.maxWidth, + maxHeight: options.maxHeight, + minWidth: options.minWidth, + minHeight: this._minHeight(), + handles: resizeHandles, + start: function( event, ui ) { + $( this ).addClass( "ui-dialog-resizing" ); + that._blockFrames(); + that._trigger( "resizeStart", event, filteredUi( ui ) ); + }, + resize: function( event, ui ) { + that._trigger( "resize", event, filteredUi( ui ) ); + }, + stop: function( event, ui ) { + var offset = that.uiDialog.offset(), + left = offset.left - that.document.scrollLeft(), + top = offset.top - that.document.scrollTop(); + + options.height = that.uiDialog.height(); + options.width = that.uiDialog.width(); + options.position = { + my: "left top", + at: "left" + (left >= 0 ? "+" : "") + left + " " + + "top" + (top >= 0 ? "+" : "") + top, + of: that.window + }; + $( this ).removeClass( "ui-dialog-resizing" ); + that._unblockFrames(); + that._trigger( "resizeStop", event, filteredUi( ui ) ); + } + }) + .css( "position", position ); + }, + + _trackFocus: function() { + this._on( this.widget(), { + focusin: function( event ) { + this._makeFocusTarget(); + this._focusedElement = $( event.target ); + } + }); + }, + + _makeFocusTarget: function() { + this._untrackInstance(); + this._trackingInstances().unshift( this ); + }, + + _untrackInstance: function() { + var instances = this._trackingInstances(), + exists = $.inArray( this, instances ); + if ( exists !== -1 ) { + instances.splice( exists, 1 ); + } + }, + + _trackingInstances: function() { + var instances = this.document.data( "ui-dialog-instances" ); + if ( !instances ) { + instances = []; + this.document.data( "ui-dialog-instances", instances ); + } + return instances; + }, + + _minHeight: function() { + var options = this.options; + + return options.height === "auto" ? + options.minHeight : + Math.min( options.minHeight, options.height ); + }, + + _position: function() { + // Need to show the dialog to get the actual offset in the position plugin + var isVisible = this.uiDialog.is( ":visible" ); + if ( !isVisible ) { + this.uiDialog.show(); + } + this.uiDialog.position( this.options.position ); + if ( !isVisible ) { + this.uiDialog.hide(); + } + }, + + _setOptions: function( options ) { + var that = this, + resize = false, + resizableOptions = {}; + + $.each( options, function( key, value ) { + that._setOption( key, value ); + + if ( key in that.sizeRelatedOptions ) { + resize = true; + } + if ( key in that.resizableRelatedOptions ) { + resizableOptions[ key ] = value; + } + }); + + if ( resize ) { + this._size(); + this._position(); + } + if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { + this.uiDialog.resizable( "option", resizableOptions ); + } + }, + + _setOption: function( key, value ) { + var isDraggable, isResizable, + uiDialog = this.uiDialog; + + if ( key === "dialogClass" ) { + uiDialog + .removeClass( this.options.dialogClass ) + .addClass( value ); + } + + if ( key === "disabled" ) { + return; + } + + this._super( key, value ); + + if ( key === "appendTo" ) { + this.uiDialog.appendTo( this._appendTo() ); + } + + if ( key === "buttons" ) { + this._createButtons(); + } + + if ( key === "closeText" ) { + this.uiDialogTitlebarClose.button({ + // Ensure that we always pass a string + label: "" + value + }); + } + + if ( key === "draggable" ) { + isDraggable = uiDialog.is( ":data(ui-draggable)" ); + if ( isDraggable && !value ) { + uiDialog.draggable( "destroy" ); + } + + if ( !isDraggable && value ) { + this._makeDraggable(); + } + } + + if ( key === "position" ) { + this._position(); + } + + if ( key === "resizable" ) { + // currently resizable, becoming non-resizable + isResizable = uiDialog.is( ":data(ui-resizable)" ); + if ( isResizable && !value ) { + uiDialog.resizable( "destroy" ); + } + + // currently resizable, changing handles + if ( isResizable && typeof value === "string" ) { + uiDialog.resizable( "option", "handles", value ); + } + + // currently non-resizable, becoming resizable + if ( !isResizable && value !== false ) { + this._makeResizable(); + } + } + + if ( key === "title" ) { + this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) ); + } + }, + + _size: function() { + // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content + // divs will both have width and height set, so we need to reset them + var nonContentHeight, minContentHeight, maxContentHeight, + options = this.options; + + // Reset content sizing + this.element.show().css({ + width: "auto", + minHeight: 0, + maxHeight: "none", + height: 0 + }); + + if ( options.minWidth > options.width ) { + options.width = options.minWidth; + } + + // reset wrapper sizing + // determine the height of all the non-content elements + nonContentHeight = this.uiDialog.css({ + height: "auto", + width: options.width + }) + .outerHeight(); + minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); + maxContentHeight = typeof options.maxHeight === "number" ? + Math.max( 0, options.maxHeight - nonContentHeight ) : + "none"; + + if ( options.height === "auto" ) { + this.element.css({ + minHeight: minContentHeight, + maxHeight: maxContentHeight, + height: "auto" + }); + } else { + this.element.height( Math.max( 0, options.height - nonContentHeight ) ); + } + + if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { + this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); + } + }, + + _blockFrames: function() { + this.iframeBlocks = this.document.find( "iframe" ).map(function() { + var iframe = $( this ); + + return $( "<div>" ) + .css({ + position: "absolute", + width: iframe.outerWidth(), + height: iframe.outerHeight() + }) + .appendTo( iframe.parent() ) + .offset( iframe.offset() )[0]; + }); + }, + + _unblockFrames: function() { + if ( this.iframeBlocks ) { + this.iframeBlocks.remove(); + delete this.iframeBlocks; + } + }, + + _allowInteraction: function( event ) { + if ( $( event.target ).closest( ".ui-dialog" ).length ) { + return true; + } + + // TODO: Remove hack when datepicker implements + // the .ui-front logic (#8989) + return !!$( event.target ).closest( ".ui-datepicker" ).length; + }, + + _createOverlay: function() { + if ( !this.options.modal ) { + return; + } + + // We use a delay in case the overlay is created from an + // event that we're going to be cancelling (#2804) + var isOpening = true; + this._delay(function() { + isOpening = false; + }); + + if ( !this.document.data( "ui-dialog-overlays" ) ) { + + // Prevent use of anchors and inputs + // Using _on() for an event handler shared across many instances is + // safe because the dialogs stack and must be closed in reverse order + this._on( this.document, { + focusin: function( event ) { + if ( isOpening ) { + return; + } + + if ( !this._allowInteraction( event ) ) { + event.preventDefault(); + this._trackingInstances()[ 0 ]._focusTabbable(); + } + } + }); + } + + this.overlay = $( "<div>" ) + .addClass( "ui-widget-overlay ui-front" ) + .appendTo( this._appendTo() ); + this._on( this.overlay, { + mousedown: "_keepFocus" + }); + this.document.data( "ui-dialog-overlays", + (this.document.data( "ui-dialog-overlays" ) || 0) + 1 ); + }, + + _destroyOverlay: function() { + if ( !this.options.modal ) { + return; + } + + if ( this.overlay ) { + var overlays = this.document.data( "ui-dialog-overlays" ) - 1; + + if ( !overlays ) { + this.document + .unbind( "focusin" ) + .removeData( "ui-dialog-overlays" ); + } else { + this.document.data( "ui-dialog-overlays", overlays ); + } + + this.overlay.remove(); + this.overlay = null; + } + } +}); + +})); + + + + +/*! + * jQuery UI Sortable 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/sortable/ + */ + +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define([ + "jquery", + "./core", + "./mouse", + "./widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +}(function( $ ) { + +return $.widget("ui.sortable", $.ui.mouse, { + version: "1.11.4", + widgetEventPrefix: "sort", + ready: false, + options: { + appendTo: "parent", + axis: false, + connectWith: false, + containment: false, + cursor: "auto", + cursorAt: false, + dropOnEmpty: true, + forcePlaceholderSize: false, + forceHelperSize: false, + grid: false, + handle: false, + helper: "original", + items: "> *", + opacity: false, + placeholder: false, + revert: false, + scroll: true, + scrollSensitivity: 20, + scrollSpeed: 20, + scope: "default", + tolerance: "intersect", + zIndex: 1000, + + // callbacks + activate: null, + beforeStop: null, + change: null, + deactivate: null, + out: null, + over: null, + receive: null, + remove: null, + sort: null, + start: null, + stop: null, + update: null + }, + + _isOverAxis: function( x, reference, size ) { + return ( x >= reference ) && ( x < ( reference + size ) ); + }, + + _isFloating: function( item ) { + return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display")); + }, + + _create: function() { + this.containerCache = {}; + this.element.addClass("ui-sortable"); + + //Get the items + this.refresh(); + + //Let's determine the parent's offset + this.offset = this.element.offset(); + + //Initialize mouse events for interaction + this._mouseInit(); + + this._setHandleClassName(); + + //We're ready to go + this.ready = true; + + }, + + _setOption: function( key, value ) { + this._super( key, value ); + + if ( key === "handle" ) { + this._setHandleClassName(); + } + }, + + _setHandleClassName: function() { + this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" ); + $.each( this.items, function() { + ( this.instance.options.handle ? + this.item.find( this.instance.options.handle ) : this.item ) + .addClass( "ui-sortable-handle" ); + }); + }, + + _destroy: function() { + this.element + .removeClass( "ui-sortable ui-sortable-disabled" ) + .find( ".ui-sortable-handle" ) + .removeClass( "ui-sortable-handle" ); + this._mouseDestroy(); + + for ( var i = this.items.length - 1; i >= 0; i-- ) { + this.items[i].item.removeData(this.widgetName + "-item"); + } + + return this; + }, + + _mouseCapture: function(event, overrideHandle) { + var currentItem = null, + validHandle = false, + that = this; + + if (this.reverting) { + return false; + } + + if(this.options.disabled || this.options.type === "static") { + return false; + } + + //We have to refresh the items data once first + this._refreshItems(event); + + //Find out if the clicked node (or one of its parents) is a actual item in this.items + $(event.target).parents().each(function() { + if($.data(this, that.widgetName + "-item") === that) { + currentItem = $(this); + return false; + } + }); + if($.data(event.target, that.widgetName + "-item") === that) { + currentItem = $(event.target); + } + + if(!currentItem) { + return false; + } + if(this.options.handle && !overrideHandle) { + $(this.options.handle, currentItem).find("*").addBack().each(function() { + if(this === event.target) { + validHandle = true; + } + }); + if(!validHandle) { + return false; + } + } + + this.currentItem = currentItem; + this._removeCurrentsFromItems(); + return true; + + }, + + _mouseStart: function(event, overrideHandle, noActivation) { + + var i, body, + o = this.options; + + this.currentContainer = this; + + //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture + this.refreshPositions(); + + //Create and append the visible helper + this.helper = this._createHelper(event); + + //Cache the helper size + this._cacheHelperProportions(); + + /* + * - Position generation - + * This block generates everything position related - it's the core of draggables. + */ + + //Cache the margins of the original element + this._cacheMargins(); + + //Get the next scrolling parent + this.scrollParent = this.helper.scrollParent(); + + //The element's absolute position on the page minus margins + this.offset = this.currentItem.offset(); + this.offset = { + top: this.offset.top - this.margins.top, + left: this.offset.left - this.margins.left + }; + + $.extend(this.offset, { + click: { //Where the click happened, relative to the element + left: event.pageX - this.offset.left, + top: event.pageY - this.offset.top + }, + parent: this._getParentOffset(), + relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper + }); + + // Only after we got the offset, we can change the helper's position to absolute + // TODO: Still need to figure out a way to make relative sorting possible + this.helper.css("position", "absolute"); + this.cssPosition = this.helper.css("position"); + + //Generate the original position + this.originalPosition = this._generatePosition(event); + this.originalPageX = event.pageX; + this.originalPageY = event.pageY; + + //Adjust the mouse offset relative to the helper if "cursorAt" is supplied + (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); + + //Cache the former DOM position + this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; + + //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way + if(this.helper[0] !== this.currentItem[0]) { + this.currentItem.hide(); + } + + //Create the placeholder + this._createPlaceholder(); + + //Set a containment if given in the options + if(o.containment) { + this._setContainment(); + } + + if( o.cursor && o.cursor !== "auto" ) { // cursor option + body = this.document.find( "body" ); + + // support: IE + this.storedCursor = body.css( "cursor" ); + body.css( "cursor", o.cursor ); + + this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body ); + } + + if(o.opacity) { // opacity option + if (this.helper.css("opacity")) { + this._storedOpacity = this.helper.css("opacity"); + } + this.helper.css("opacity", o.opacity); + } + + if(o.zIndex) { // zIndex option + if (this.helper.css("zIndex")) { + this._storedZIndex = this.helper.css("zIndex"); + } + this.helper.css("zIndex", o.zIndex); + } + + //Prepare scrolling + if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") { + this.overflowOffset = this.scrollParent.offset(); + } + + //Call callbacks + this._trigger("start", event, this._uiHash()); + + //Recache the helper size + if(!this._preserveHelperProportions) { + this._cacheHelperProportions(); + } + + + //Post "activate" events to possible containers + if( !noActivation ) { + for ( i = this.containers.length - 1; i >= 0; i-- ) { + this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); + } + } + + //Prepare possible droppables + if($.ui.ddmanager) { + $.ui.ddmanager.current = this; + } + + if ($.ui.ddmanager && !o.dropBehaviour) { + $.ui.ddmanager.prepareOffsets(this, event); + } + + this.dragging = true; + + this.helper.addClass("ui-sortable-helper"); + this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position + return true; + + }, + + _mouseDrag: function(event) { + var i, item, itemElement, intersection, + o = this.options, + scrolled = false; + + //Compute the helpers position + this.position = this._generatePosition(event); + this.positionAbs = this._convertPositionTo("absolute"); + + if (!this.lastPositionAbs) { + this.lastPositionAbs = this.positionAbs; + } + + //Do scrolling + if(this.options.scroll) { + if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") { + + if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { + this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; + } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { + this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; + } + + if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { + this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; + } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { + this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; + } + + } else { + + if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) { + scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed); + } else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) { + scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed); + } + + if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) { + scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed); + } else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) { + scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed); + } + + } + + if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { + $.ui.ddmanager.prepareOffsets(this, event); + } + } + + //Regenerate the absolute position used for position checks + this.positionAbs = this._convertPositionTo("absolute"); + + //Set the helper position + if(!this.options.axis || this.options.axis !== "y") { + this.helper[0].style.left = this.position.left+"px"; + } + if(!this.options.axis || this.options.axis !== "x") { + this.helper[0].style.top = this.position.top+"px"; + } + + //Rearrange + for (i = this.items.length - 1; i >= 0; i--) { + + //Cache variables and intersection, continue if no intersection + item = this.items[i]; + itemElement = item.item[0]; + intersection = this._intersectsWithPointer(item); + if (!intersection) { + continue; + } + + // Only put the placeholder inside the current Container, skip all + // items from other containers. This works because when moving + // an item from one container to another the + // currentContainer is switched before the placeholder is moved. + // + // Without this, moving items in "sub-sortables" can cause + // the placeholder to jitter between the outer and inner container. + if (item.instance !== this.currentContainer) { + continue; + } + + // cannot intersect with itself + // no useless actions that have been done before + // no action if the item moved is the parent of the item checked + if (itemElement !== this.currentItem[0] && + this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && + !$.contains(this.placeholder[0], itemElement) && + (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) + ) { + + this.direction = intersection === 1 ? "down" : "up"; + + if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { + this._rearrange(event, item); + } else { + break; + } + + this._trigger("change", event, this._uiHash()); + break; + } + } + + //Post events to containers + this._contactContainers(event); + + //Interconnect with droppables + if($.ui.ddmanager) { + $.ui.ddmanager.drag(this, event); + } + + //Call callbacks + this._trigger("sort", event, this._uiHash()); + + this.lastPositionAbs = this.positionAbs; + return false; + + }, + + _mouseStop: function(event, noPropagation) { + + if(!event) { + return; + } + + //If we are using droppables, inform the manager about the drop + if ($.ui.ddmanager && !this.options.dropBehaviour) { + $.ui.ddmanager.drop(this, event); + } + + if(this.options.revert) { + var that = this, + cur = this.placeholder.offset(), + axis = this.options.axis, + animation = {}; + + if ( !axis || axis === "x" ) { + animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft); + } + if ( !axis || axis === "y" ) { + animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop); + } + this.reverting = true; + $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() { + that._clear(event); + }); + } else { + this._clear(event, noPropagation); + } + + return false; + + }, + + cancel: function() { + + if(this.dragging) { + + this._mouseUp({ target: null }); + + if(this.options.helper === "original") { + this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); + } else { + this.currentItem.show(); + } + + //Post deactivating events to containers + for (var i = this.containers.length - 1; i >= 0; i--){ + this.containers[i]._trigger("deactivate", null, this._uiHash(this)); + if(this.containers[i].containerCache.over) { + this.containers[i]._trigger("out", null, this._uiHash(this)); + this.containers[i].containerCache.over = 0; + } + } + + } + + if (this.placeholder) { + //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! + if(this.placeholder[0].parentNode) { + this.placeholder[0].parentNode.removeChild(this.placeholder[0]); + } + if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { + this.helper.remove(); + } + + $.extend(this, { + helper: null, + dragging: false, + reverting: false, + _noFinalSort: null + }); + + if(this.domPosition.prev) { + $(this.domPosition.prev).after(this.currentItem); + } else { + $(this.domPosition.parent).prepend(this.currentItem); + } + } + + return this; + + }, + + serialize: function(o) { + + var items = this._getItemsAsjQuery(o && o.connected), + str = []; + o = o || {}; + + $(items).each(function() { + var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); + if (res) { + str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); + } + }); + + if(!str.length && o.key) { + str.push(o.key + "="); + } + + return str.join("&"); + + }, + + toArray: function(o) { + + var items = this._getItemsAsjQuery(o && o.connected), + ret = []; + + o = o || {}; + + items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); + return ret; + + }, + + /* Be careful with the following core functions */ + _intersectsWith: function(item) { + + var x1 = this.positionAbs.left, + x2 = x1 + this.helperProportions.width, + y1 = this.positionAbs.top, + y2 = y1 + this.helperProportions.height, + l = item.left, + r = l + item.width, + t = item.top, + b = t + item.height, + dyClick = this.offset.click.top, + dxClick = this.offset.click.left, + isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ), + isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ), + isOverElement = isOverElementHeight && isOverElementWidth; + + if ( this.options.tolerance === "pointer" || + this.options.forcePointerForContainers || + (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) + ) { + return isOverElement; + } else { + + return (l < x1 + (this.helperProportions.width / 2) && // Right Half + x2 - (this.helperProportions.width / 2) < r && // Left Half + t < y1 + (this.helperProportions.height / 2) && // Bottom Half + y2 - (this.helperProportions.height / 2) < b ); // Top Half + + } + }, + + _intersectsWithPointer: function(item) { + + var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), + isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), + isOverElement = isOverElementHeight && isOverElementWidth, + verticalDirection = this._getDragVerticalDirection(), + horizontalDirection = this._getDragHorizontalDirection(); + + if (!isOverElement) { + return false; + } + + return this.floating ? + ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) + : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); + + }, + + _intersectsWithSides: function(item) { + + var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), + isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), + verticalDirection = this._getDragVerticalDirection(), + horizontalDirection = this._getDragHorizontalDirection(); + + if (this.floating && horizontalDirection) { + return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); + } else { + return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); + } + + }, + + _getDragVerticalDirection: function() { + var delta = this.positionAbs.top - this.lastPositionAbs.top; + return delta !== 0 && (delta > 0 ? "down" : "up"); + }, + + _getDragHorizontalDirection: function() { + var delta = this.positionAbs.left - this.lastPositionAbs.left; + return delta !== 0 && (delta > 0 ? "right" : "left"); + }, + + refresh: function(event) { + this._refreshItems(event); + this._setHandleClassName(); + this.refreshPositions(); + return this; + }, + + _connectWith: function() { + var options = this.options; + return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; + }, + + _getItemsAsjQuery: function(connected) { + + var i, j, cur, inst, + items = [], + queries = [], + connectWith = this._connectWith(); + + if(connectWith && connected) { + for (i = connectWith.length - 1; i >= 0; i--){ + cur = $(connectWith[i], this.document[0]); + for ( j = cur.length - 1; j >= 0; j--){ + inst = $.data(cur[j], this.widgetFullName); + if(inst && inst !== this && !inst.options.disabled) { + queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]); + } + } + } + } + + queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]); + + function addItems() { + items.push( this ); + } + for (i = queries.length - 1; i >= 0; i--){ + queries[i][0].each( addItems ); + } + + return $(items); + + }, + + _removeCurrentsFromItems: function() { + + var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); + + this.items = $.grep(this.items, function (item) { + for (var j=0; j < list.length; j++) { + if(list[j] === item.item[0]) { + return false; + } + } + return true; + }); + + }, + + _refreshItems: function(event) { + + this.items = []; + this.containers = [this]; + + var i, j, cur, inst, targetData, _queries, item, queriesLength, + items = this.items, + queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], + connectWith = this._connectWith(); + + if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down + for (i = connectWith.length - 1; i >= 0; i--){ + cur = $(connectWith[i], this.document[0]); + for (j = cur.length - 1; j >= 0; j--){ + inst = $.data(cur[j], this.widgetFullName); + if(inst && inst !== this && !inst.options.disabled) { + queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); + this.containers.push(inst); + } + } + } + } + + for (i = queries.length - 1; i >= 0; i--) { + targetData = queries[i][1]; + _queries = queries[i][0]; + + for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { + item = $(_queries[j]); + + item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) + + items.push({ + item: item, + instance: targetData, + width: 0, height: 0, + left: 0, top: 0 + }); + } + } + + }, + + refreshPositions: function(fast) { + + // Determine whether items are being displayed horizontally + this.floating = this.items.length ? + this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) : + false; + + //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change + if(this.offsetParent && this.helper) { + this.offset.parent = this._getParentOffset(); + } + + var i, item, t, p; + + for (i = this.items.length - 1; i >= 0; i--){ + item = this.items[i]; + + //We ignore calculating positions of all connected containers when we're not over them + if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { + continue; + } + + t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; + + if (!fast) { + item.width = t.outerWidth(); + item.height = t.outerHeight(); + } + + p = t.offset(); + item.left = p.left; + item.top = p.top; + } + + if(this.options.custom && this.options.custom.refreshContainers) { + this.options.custom.refreshContainers.call(this); + } else { + for (i = this.containers.length - 1; i >= 0; i--){ + p = this.containers[i].element.offset(); + this.containers[i].containerCache.left = p.left; + this.containers[i].containerCache.top = p.top; + this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); + this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); + } + } + + return this; + }, + + _createPlaceholder: function(that) { + that = that || this; + var className, + o = that.options; + + if(!o.placeholder || o.placeholder.constructor === String) { + className = o.placeholder; + o.placeholder = { + element: function() { + + var nodeName = that.currentItem[0].nodeName.toLowerCase(), + element = $( "<" + nodeName + ">", that.document[0] ) + .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") + .removeClass("ui-sortable-helper"); + + if ( nodeName === "tbody" ) { + that._createTrPlaceholder( + that.currentItem.find( "tr" ).eq( 0 ), + $( "<tr>", that.document[ 0 ] ).appendTo( element ) + ); + } else if ( nodeName === "tr" ) { + that._createTrPlaceholder( that.currentItem, element ); + } else if ( nodeName === "img" ) { + element.attr( "src", that.currentItem.attr( "src" ) ); + } + + if ( !className ) { + element.css( "visibility", "hidden" ); + } + + return element; + }, + update: function(container, p) { + + // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that + // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified + if(className && !o.forcePlaceholderSize) { + return; + } + + //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item + if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } + if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } + } + }; + } + + //Create the placeholder + that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); + + //Append it after the actual current item + that.currentItem.after(that.placeholder); + + //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) + o.placeholder.update(that, that.placeholder); + + }, + + _createTrPlaceholder: function( sourceTr, targetTr ) { + var that = this; + + sourceTr.children().each(function() { + $( "<td> </td>", that.document[ 0 ] ) + .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) + .appendTo( targetTr ); + }); + }, + + _contactContainers: function(event) { + var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis, + innermostContainer = null, + innermostIndex = null; + + // get innermost container that intersects with item + for (i = this.containers.length - 1; i >= 0; i--) { + + // never consider a container that's located within the item itself + if($.contains(this.currentItem[0], this.containers[i].element[0])) { + continue; + } + + if(this._intersectsWith(this.containers[i].containerCache)) { + + // if we've already found a container and it's more "inner" than this, then continue + if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { + continue; + } + + innermostContainer = this.containers[i]; + innermostIndex = i; + + } else { + // container doesn't intersect. trigger "out" event if necessary + if(this.containers[i].containerCache.over) { + this.containers[i]._trigger("out", event, this._uiHash(this)); + this.containers[i].containerCache.over = 0; + } + } + + } + + // if no intersecting containers found, return + if(!innermostContainer) { + return; + } + + // move the item into the container if it's not there already + if(this.containers.length === 1) { + if (!this.containers[innermostIndex].containerCache.over) { + this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); + this.containers[innermostIndex].containerCache.over = 1; + } + } else { + + //When entering a new container, we will find the item with the least distance and append our item near it + dist = 10000; + itemWithLeastDistance = null; + floating = innermostContainer.floating || this._isFloating(this.currentItem); + posProperty = floating ? "left" : "top"; + sizeProperty = floating ? "width" : "height"; + axis = floating ? "clientX" : "clientY"; + + for (j = this.items.length - 1; j >= 0; j--) { + if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { + continue; + } + if(this.items[j].item[0] === this.currentItem[0]) { + continue; + } + + cur = this.items[j].item.offset()[posProperty]; + nearBottom = false; + if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) { + nearBottom = true; + } + + if ( Math.abs( event[ axis ] - cur ) < dist ) { + dist = Math.abs( event[ axis ] - cur ); + itemWithLeastDistance = this.items[ j ]; + this.direction = nearBottom ? "up": "down"; + } + } + + //Check if dropOnEmpty is enabled + if(!itemWithLeastDistance && !this.options.dropOnEmpty) { + return; + } + + if(this.currentContainer === this.containers[innermostIndex]) { + if ( !this.currentContainer.containerCache.over ) { + this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() ); + this.currentContainer.containerCache.over = 1; + } + return; + } + + itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); + this._trigger("change", event, this._uiHash()); + this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); + this.currentContainer = this.containers[innermostIndex]; + + //Update the placeholder + this.options.placeholder.update(this.currentContainer, this.placeholder); + + this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); + this.containers[innermostIndex].containerCache.over = 1; + } + + + }, + + _createHelper: function(event) { + + var o = this.options, + helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); + + //Add the helper to the DOM if that didn't happen already + if(!helper.parents("body").length) { + $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); + } + + if(helper[0] === this.currentItem[0]) { + this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") }; + } + + if(!helper[0].style.width || o.forceHelperSize) { + helper.width(this.currentItem.width()); + } + if(!helper[0].style.height || o.forceHelperSize) { + helper.height(this.currentItem.height()); + } + + return helper; + + }, + + _adjustOffsetFromHelper: function(obj) { + if (typeof obj === "string") { + obj = obj.split(" "); + } + if ($.isArray(obj)) { + obj = {left: +obj[0], top: +obj[1] || 0}; + } + if ("left" in obj) { + this.offset.click.left = obj.left + this.margins.left; + } + if ("right" in obj) { + this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; + } + if ("top" in obj) { + this.offset.click.top = obj.top + this.margins.top; + } + if ("bottom" in obj) { + this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; + } + }, + + _getParentOffset: function() { + + + //Get the offsetParent and cache its position + this.offsetParent = this.helper.offsetParent(); + var po = this.offsetParent.offset(); + + // This is a special case where we need to modify a offset calculated on start, since the following happened: + // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent + // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that + // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag + if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) { + po.left += this.scrollParent.scrollLeft(); + po.top += this.scrollParent.scrollTop(); + } + + // This needs to be actually done for all browsers, since pageX/pageY includes this information + // with an ugly IE fix + if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { + po = { top: 0, left: 0 }; + } + + return { + top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), + left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) + }; + + }, + + _getRelativeOffset: function() { + + if(this.cssPosition === "relative") { + var p = this.currentItem.position(); + return { + top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), + left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() + }; + } else { + return { top: 0, left: 0 }; + } + + }, + + _cacheMargins: function() { + this.margins = { + left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), + top: (parseInt(this.currentItem.css("marginTop"),10) || 0) + }; + }, + + _cacheHelperProportions: function() { + this.helperProportions = { + width: this.helper.outerWidth(), + height: this.helper.outerHeight() + }; + }, + + _setContainment: function() { + + var ce, co, over, + o = this.options; + if(o.containment === "parent") { + o.containment = this.helper[0].parentNode; + } + if(o.containment === "document" || o.containment === "window") { + this.containment = [ + 0 - this.offset.relative.left - this.offset.parent.left, + 0 - this.offset.relative.top - this.offset.parent.top, + o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left, + (o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top + ]; + } + + if(!(/^(document|window|parent)$/).test(o.containment)) { + ce = $(o.containment)[0]; + co = $(o.containment).offset(); + over = ($(ce).css("overflow") !== "hidden"); + + this.containment = [ + co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, + co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, + co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left, + co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top + ]; + } + + }, + + _convertPositionTo: function(d, pos) { + + if(!pos) { + pos = this.position; + } + var mod = d === "absolute" ? 1 : -1, + scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, + scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); + + return { + top: ( + pos.top + // The absolute mouse position + this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) + ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) + ), + left: ( + pos.left + // The absolute mouse position + this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) + ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) + ) + }; + + }, + + _generatePosition: function(event) { + + var top, left, + o = this.options, + pageX = event.pageX, + pageY = event.pageY, + scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); + + // This is another very weird special case that only happens for relative elements: + // 1. If the css position is relative + // 2. and the scroll parent is the document or similar to the offset parent + // we have to refresh the relative offset during the scroll so there are no jumps + if(this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) { + this.offset.relative = this._getRelativeOffset(); + } + + /* + * - Position constraining - + * Constrain the position to a mix of grid, containment. + */ + + if(this.originalPosition) { //If we are not dragging yet, we won't check for options + + if(this.containment) { + if(event.pageX - this.offset.click.left < this.containment[0]) { + pageX = this.containment[0] + this.offset.click.left; + } + if(event.pageY - this.offset.click.top < this.containment[1]) { + pageY = this.containment[1] + this.offset.click.top; + } + if(event.pageX - this.offset.click.left > this.containment[2]) { + pageX = this.containment[2] + this.offset.click.left; + } + if(event.pageY - this.offset.click.top > this.containment[3]) { + pageY = this.containment[3] + this.offset.click.top; + } + } + + if(o.grid) { + top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; + pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; + + left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; + pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; + } + + } + + return { + top: ( + pageY - // The absolute mouse position + this.offset.click.top - // Click offset (relative to the element) + this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.top + // The offsetParent's offset without borders (offset + border) + ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) + ), + left: ( + pageX - // The absolute mouse position + this.offset.click.left - // Click offset (relative to the element) + this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.left + // The offsetParent's offset without borders (offset + border) + ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) + ) + }; + + }, + + _rearrange: function(event, i, a, hardRefresh) { + + a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling)); + + //Various things done here to improve the performance: + // 1. we create a setTimeout, that calls refreshPositions + // 2. on the instance, we have a counter variable, that get's higher after every append + // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same + // 4. this lets only the last addition to the timeout stack through + this.counter = this.counter ? ++this.counter : 1; + var counter = this.counter; + + this._delay(function() { + if(counter === this.counter) { + this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove + } + }); + + }, + + _clear: function(event, noPropagation) { + + this.reverting = false; + // We delay all events that have to be triggered to after the point where the placeholder has been removed and + // everything else normalized again + var i, + delayedTriggers = []; + + // We first have to update the dom position of the actual currentItem + // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) + if(!this._noFinalSort && this.currentItem.parent().length) { + this.placeholder.before(this.currentItem); + } + this._noFinalSort = null; + + if(this.helper[0] === this.currentItem[0]) { + for(i in this._storedCSS) { + if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { + this._storedCSS[i] = ""; + } + } + this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); + } else { + this.currentItem.show(); + } + + if(this.fromOutside && !noPropagation) { + delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); + } + if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { + delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed + } + + // Check if the items Container has Changed and trigger appropriate + // events. + if (this !== this.currentContainer) { + if(!noPropagation) { + delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); + delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); + delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); + } + } + + + //Post events to containers + function delayEvent( type, instance, container ) { + return function( event ) { + container._trigger( type, event, instance._uiHash( instance ) ); + }; + } + for (i = this.containers.length - 1; i >= 0; i--){ + if (!noPropagation) { + delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); + } + if(this.containers[i].containerCache.over) { + delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); + this.containers[i].containerCache.over = 0; + } + } + + //Do what was originally in plugins + if ( this.storedCursor ) { + this.document.find( "body" ).css( "cursor", this.storedCursor ); + this.storedStylesheet.remove(); + } + if(this._storedOpacity) { + this.helper.css("opacity", this._storedOpacity); + } + if(this._storedZIndex) { + this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); + } + + this.dragging = false; + + if(!noPropagation) { + this._trigger("beforeStop", event, this._uiHash()); + } + + //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! + this.placeholder[0].parentNode.removeChild(this.placeholder[0]); + + if ( !this.cancelHelperRemoval ) { + if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { + this.helper.remove(); + } + this.helper = null; + } + + if(!noPropagation) { + for (i=0; i < delayedTriggers.length; i++) { + delayedTriggers[i].call(this, event); + } //Trigger all delayed events + this._trigger("stop", event, this._uiHash()); + } + + this.fromOutside = false; + return !this.cancelHelperRemoval; + + }, + + _trigger: function() { + if ($.Widget.prototype._trigger.apply(this, arguments) === false) { + this.cancel(); + } + }, + + _uiHash: function(_inst) { + var inst = _inst || this; + return { + helper: inst.helper, + placeholder: inst.placeholder || $([]), + position: inst.position, + originalPosition: inst.originalPosition, + offset: inst.positionAbs, + item: inst.currentItem, + sender: _inst ? _inst.element : null + }; + } + +}); + +})); + + + +/*! + * jQuery UI Tabs 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/tabs/ + */ + +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define([ + "jquery", + "./core", + "./widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +}(function( $ ) { + +return $.widget( "ui.tabs", { + version: "1.11.4", + delay: 300, + options: { + active: null, + collapsible: false, + event: "click", + heightStyle: "content", + hide: null, + show: null, + + // callbacks + activate: null, + beforeActivate: null, + beforeLoad: null, + load: null + }, + + _isLocal: (function() { + var rhash = /#.*$/; + + return function( anchor ) { + var anchorUrl, locationUrl; + + // support: IE7 + // IE7 doesn't normalize the href property when set via script (#9317) + anchor = anchor.cloneNode( false ); + + anchorUrl = anchor.href.replace( rhash, "" ); + locationUrl = location.href.replace( rhash, "" ); + + // decoding may throw an error if the URL isn't UTF-8 (#9518) + try { + anchorUrl = decodeURIComponent( anchorUrl ); + } catch ( error ) {} + try { + locationUrl = decodeURIComponent( locationUrl ); + } catch ( error ) {} + + return anchor.hash.length > 1 && anchorUrl === locationUrl; + }; + })(), + + _create: function() { + var that = this, + options = this.options; + + this.running = false; + + this.element + .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) + .toggleClass( "ui-tabs-collapsible", options.collapsible ); + + this._processTabs(); + options.active = this._initialActive(); + + // Take disabling tabs via class attribute from HTML + // into account and update option properly. + if ( $.isArray( options.disabled ) ) { + options.disabled = $.unique( options.disabled.concat( + $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { + return that.tabs.index( li ); + }) + ) ).sort(); + } + + // check for length avoids error when initializing empty list + if ( this.options.active !== false && this.anchors.length ) { + this.active = this._findActive( options.active ); + } else { + this.active = $(); + } + + this._refresh(); + + if ( this.active.length ) { + this.load( options.active ); + } + }, + + _initialActive: function() { + var active = this.options.active, + collapsible = this.options.collapsible, + locationHash = location.hash.substring( 1 ); + + if ( active === null ) { + // check the fragment identifier in the URL + if ( locationHash ) { + this.tabs.each(function( i, tab ) { + if ( $( tab ).attr( "aria-controls" ) === locationHash ) { + active = i; + return false; + } + }); + } + + // check for a tab marked active via a class + if ( active === null ) { + active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); + } + + // no active tab, set to false + if ( active === null || active === -1 ) { + active = this.tabs.length ? 0 : false; + } + } + + // handle numbers: negative, out of range + if ( active !== false ) { + active = this.tabs.index( this.tabs.eq( active ) ); + if ( active === -1 ) { + active = collapsible ? false : 0; + } + } + + // don't allow collapsible: false and active: false + if ( !collapsible && active === false && this.anchors.length ) { + active = 0; + } + + return active; + }, + + _getCreateEventData: function() { + return { + tab: this.active, + panel: !this.active.length ? $() : this._getPanelForTab( this.active ) + }; + }, + + _tabKeydown: function( event ) { + var focusedTab = $( this.document[0].activeElement ).closest( "li" ), + selectedIndex = this.tabs.index( focusedTab ), + goingForward = true; + + if ( this._handlePageNav( event ) ) { + return; + } + + switch ( event.keyCode ) { + case $.ui.keyCode.RIGHT: + case $.ui.keyCode.DOWN: + selectedIndex++; + break; + case $.ui.keyCode.UP: + case $.ui.keyCode.LEFT: + goingForward = false; + selectedIndex--; + break; + case $.ui.keyCode.END: + selectedIndex = this.anchors.length - 1; + break; + case $.ui.keyCode.HOME: + selectedIndex = 0; + break; + case $.ui.keyCode.SPACE: + // Activate only, no collapsing + event.preventDefault(); + clearTimeout( this.activating ); + this._activate( selectedIndex ); + return; + case $.ui.keyCode.ENTER: + // Toggle (cancel delayed activation, allow collapsing) + event.preventDefault(); + clearTimeout( this.activating ); + // Determine if we should collapse or activate + this._activate( selectedIndex === this.options.active ? false : selectedIndex ); + return; + default: + return; + } + + // Focus the appropriate tab, based on which key was pressed + event.preventDefault(); + clearTimeout( this.activating ); + selectedIndex = this._focusNextTab( selectedIndex, goingForward ); + + // Navigating with control/command key will prevent automatic activation + if ( !event.ctrlKey && !event.metaKey ) { + + // Update aria-selected immediately so that AT think the tab is already selected. + // Otherwise AT may confuse the user by stating that they need to activate the tab, + // but the tab will already be activated by the time the announcement finishes. + focusedTab.attr( "aria-selected", "false" ); + this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); + + this.activating = this._delay(function() { + this.option( "active", selectedIndex ); + }, this.delay ); + } + }, + + _panelKeydown: function( event ) { + if ( this._handlePageNav( event ) ) { + return; + } + + // Ctrl+up moves focus to the current tab + if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { + event.preventDefault(); + this.active.focus(); + } + }, + + // Alt+page up/down moves focus to the previous/next tab (and activates) + _handlePageNav: function( event ) { + if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { + this._activate( this._focusNextTab( this.options.active - 1, false ) ); + return true; + } + if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { + this._activate( this._focusNextTab( this.options.active + 1, true ) ); + return true; + } + }, + + _findNextTab: function( index, goingForward ) { + var lastTabIndex = this.tabs.length - 1; + + function constrain() { + if ( index > lastTabIndex ) { + index = 0; + } + if ( index < 0 ) { + index = lastTabIndex; + } + return index; + } + + while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { + index = goingForward ? index + 1 : index - 1; + } + + return index; + }, + + _focusNextTab: function( index, goingForward ) { + index = this._findNextTab( index, goingForward ); + this.tabs.eq( index ).focus(); + return index; + }, + + _setOption: function( key, value ) { + if ( key === "active" ) { + // _activate() will handle invalid values and update this.options + this._activate( value ); + return; + } + + if ( key === "disabled" ) { + // don't use the widget factory's disabled handling + this._setupDisabled( value ); + return; + } + + this._super( key, value); + + if ( key === "collapsible" ) { + this.element.toggleClass( "ui-tabs-collapsible", value ); + // Setting collapsible: false while collapsed; open first panel + if ( !value && this.options.active === false ) { + this._activate( 0 ); + } + } + + if ( key === "event" ) { + this._setupEvents( value ); + } + + if ( key === "heightStyle" ) { + this._setupHeightStyle( value ); + } + }, + + _sanitizeSelector: function( hash ) { + return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; + }, + + refresh: function() { + var options = this.options, + lis = this.tablist.children( ":has(a[href])" ); + + // get disabled tabs from class attribute from HTML + // this will get converted to a boolean if needed in _refresh() + options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { + return lis.index( tab ); + }); + + this._processTabs(); + + // was collapsed or no tabs + if ( options.active === false || !this.anchors.length ) { + options.active = false; + this.active = $(); + // was active, but active tab is gone + } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { + // all remaining tabs are disabled + if ( this.tabs.length === options.disabled.length ) { + options.active = false; + this.active = $(); + // activate previous tab + } else { + this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); + } + // was active, active tab still exists + } else { + // make sure active index is correct + options.active = this.tabs.index( this.active ); + } + + this._refresh(); + }, + + _refresh: function() { + this._setupDisabled( this.options.disabled ); + this._setupEvents( this.options.event ); + this._setupHeightStyle( this.options.heightStyle ); + + this.tabs.not( this.active ).attr({ + "aria-selected": "false", + "aria-expanded": "false", + tabIndex: -1 + }); + this.panels.not( this._getPanelForTab( this.active ) ) + .hide() + .attr({ + "aria-hidden": "true" + }); + + // Make sure one tab is in the tab order + if ( !this.active.length ) { + this.tabs.eq( 0 ).attr( "tabIndex", 0 ); + } else { + this.active + .addClass( "ui-tabs-active ui-state-active" ) + .attr({ + "aria-selected": "true", + "aria-expanded": "true", + tabIndex: 0 + }); + this._getPanelForTab( this.active ) + .show() + .attr({ + "aria-hidden": "false" + }); + } + }, + + _processTabs: function() { + var that = this, + prevTabs = this.tabs, + prevAnchors = this.anchors, + prevPanels = this.panels; + + this.tablist = this._getList() + .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) + .attr( "role", "tablist" ) + + // Prevent users from focusing disabled tabs via click + .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) { + if ( $( this ).is( ".ui-state-disabled" ) ) { + event.preventDefault(); + } + }) + + // support: IE <9 + // Preventing the default action in mousedown doesn't prevent IE + // from focusing the element, so if the anchor gets focused, blur. + // We don't have to worry about focusing the previously focused + // element since clicking on a non-focusable element should focus + // the body anyway. + .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { + if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { + this.blur(); + } + }); + + this.tabs = this.tablist.find( "> li:has(a[href])" ) + .addClass( "ui-state-default ui-corner-top" ) + .attr({ + role: "tab", + tabIndex: -1 + }); + + this.anchors = this.tabs.map(function() { + return $( "a", this )[ 0 ]; + }) + .addClass( "ui-tabs-anchor" ) + .attr({ + role: "presentation", + tabIndex: -1 + }); + + this.panels = $(); + + this.anchors.each(function( i, anchor ) { + var selector, panel, panelId, + anchorId = $( anchor ).uniqueId().attr( "id" ), + tab = $( anchor ).closest( "li" ), + originalAriaControls = tab.attr( "aria-controls" ); + + // inline tab + if ( that._isLocal( anchor ) ) { + selector = anchor.hash; + panelId = selector.substring( 1 ); + panel = that.element.find( that._sanitizeSelector( selector ) ); + // remote tab + } else { + // If the tab doesn't already have aria-controls, + // generate an id by using a throw-away element + panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id; + selector = "#" + panelId; + panel = that.element.find( selector ); + if ( !panel.length ) { + panel = that._createPanel( panelId ); + panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); + } + panel.attr( "aria-live", "polite" ); + } + + if ( panel.length) { + that.panels = that.panels.add( panel ); + } + if ( originalAriaControls ) { + tab.data( "ui-tabs-aria-controls", originalAriaControls ); + } + tab.attr({ + "aria-controls": panelId, + "aria-labelledby": anchorId + }); + panel.attr( "aria-labelledby", anchorId ); + }); + + this.panels + .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) + .attr( "role", "tabpanel" ); + + // Avoid memory leaks (#10056) + if ( prevTabs ) { + this._off( prevTabs.not( this.tabs ) ); + this._off( prevAnchors.not( this.anchors ) ); + this._off( prevPanels.not( this.panels ) ); + } + }, + + // allow overriding how to find the list for rare usage scenarios (#7715) + _getList: function() { + return this.tablist || this.element.find( "ol,ul" ).eq( 0 ); + }, + + _createPanel: function( id ) { + return $( "<div>" ) + .attr( "id", id ) + .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) + .data( "ui-tabs-destroy", true ); + }, + + _setupDisabled: function( disabled ) { + if ( $.isArray( disabled ) ) { + if ( !disabled.length ) { + disabled = false; + } else if ( disabled.length === this.anchors.length ) { + disabled = true; + } + } + + // disable tabs + for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { + if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { + $( li ) + .addClass( "ui-state-disabled" ) + .attr( "aria-disabled", "true" ); + } else { + $( li ) + .removeClass( "ui-state-disabled" ) + .removeAttr( "aria-disabled" ); + } + } + + this.options.disabled = disabled; + }, + + _setupEvents: function( event ) { + var events = {}; + if ( event ) { + $.each( event.split(" "), function( index, eventName ) { + events[ eventName ] = "_eventHandler"; + }); + } + + this._off( this.anchors.add( this.tabs ).add( this.panels ) ); + // Always prevent the default action, even when disabled + this._on( true, this.anchors, { + click: function( event ) { + event.preventDefault(); + } + }); + this._on( this.anchors, events ); + this._on( this.tabs, { keydown: "_tabKeydown" } ); + this._on( this.panels, { keydown: "_panelKeydown" } ); + + this._focusable( this.tabs ); + this._hoverable( this.tabs ); + }, + + _setupHeightStyle: function( heightStyle ) { + var maxHeight, + parent = this.element.parent(); + + if ( heightStyle === "fill" ) { + maxHeight = parent.height(); + maxHeight -= this.element.outerHeight() - this.element.height(); + + this.element.siblings( ":visible" ).each(function() { + var elem = $( this ), + position = elem.css( "position" ); + + if ( position === "absolute" || position === "fixed" ) { + return; + } + maxHeight -= elem.outerHeight( true ); + }); + + this.element.children().not( this.panels ).each(function() { + maxHeight -= $( this ).outerHeight( true ); + }); + + this.panels.each(function() { + $( this ).height( Math.max( 0, maxHeight - + $( this ).innerHeight() + $( this ).height() ) ); + }) + .css( "overflow", "auto" ); + } else if ( heightStyle === "auto" ) { + maxHeight = 0; + this.panels.each(function() { + maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); + }).height( maxHeight ); + } + }, + + _eventHandler: function( event ) { + var options = this.options, + active = this.active, + anchor = $( event.currentTarget ), + tab = anchor.closest( "li" ), + clickedIsActive = tab[ 0 ] === active[ 0 ], + collapsing = clickedIsActive && options.collapsible, + toShow = collapsing ? $() : this._getPanelForTab( tab ), + toHide = !active.length ? $() : this._getPanelForTab( active ), + eventData = { + oldTab: active, + oldPanel: toHide, + newTab: collapsing ? $() : tab, + newPanel: toShow + }; + + event.preventDefault(); + + if ( tab.hasClass( "ui-state-disabled" ) || + // tab is already loading + tab.hasClass( "ui-tabs-loading" ) || + // can't switch durning an animation + this.running || + // click on active header, but not collapsible + ( clickedIsActive && !options.collapsible ) || + // allow canceling activation + ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { + return; + } + + options.active = collapsing ? false : this.tabs.index( tab ); + + this.active = clickedIsActive ? $() : tab; + if ( this.xhr ) { + this.xhr.abort(); + } + + if ( !toHide.length && !toShow.length ) { + $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); + } + + if ( toShow.length ) { + this.load( this.tabs.index( tab ), event ); + } + this._toggle( event, eventData ); + }, + + // handles show/hide for selecting tabs + _toggle: function( event, eventData ) { + var that = this, + toShow = eventData.newPanel, + toHide = eventData.oldPanel; + + this.running = true; + + function complete() { + that.running = false; + that._trigger( "activate", event, eventData ); + } + + function show() { + eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); + + if ( toShow.length && that.options.show ) { + that._show( toShow, that.options.show, complete ); + } else { + toShow.show(); + complete(); + } + } + + // start out by hiding, then showing, then completing + if ( toHide.length && this.options.hide ) { + this._hide( toHide, this.options.hide, function() { + eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); + show(); + }); + } else { + eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); + toHide.hide(); + show(); + } + + toHide.attr( "aria-hidden", "true" ); + eventData.oldTab.attr({ + "aria-selected": "false", + "aria-expanded": "false" + }); + // If we're switching tabs, remove the old tab from the tab order. + // If we're opening from collapsed state, remove the previous tab from the tab order. + // If we're collapsing, then keep the collapsing tab in the tab order. + if ( toShow.length && toHide.length ) { + eventData.oldTab.attr( "tabIndex", -1 ); + } else if ( toShow.length ) { + this.tabs.filter(function() { + return $( this ).attr( "tabIndex" ) === 0; + }) + .attr( "tabIndex", -1 ); + } + + toShow.attr( "aria-hidden", "false" ); + eventData.newTab.attr({ + "aria-selected": "true", + "aria-expanded": "true", + tabIndex: 0 + }); + }, + + _activate: function( index ) { + var anchor, + active = this._findActive( index ); + + // trying to activate the already active panel + if ( active[ 0 ] === this.active[ 0 ] ) { + return; + } + + // trying to collapse, simulate a click on the current active header + if ( !active.length ) { + active = this.active; + } + + anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; + this._eventHandler({ + target: anchor, + currentTarget: anchor, + preventDefault: $.noop + }); + }, + + _findActive: function( index ) { + return index === false ? $() : this.tabs.eq( index ); + }, + + _getIndex: function( index ) { + // meta-function to give users option to provide a href string instead of a numerical index. + if ( typeof index === "string" ) { + index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); + } + + return index; + }, + + _destroy: function() { + if ( this.xhr ) { + this.xhr.abort(); + } + + this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); + + this.tablist + .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) + .removeAttr( "role" ); + + this.anchors + .removeClass( "ui-tabs-anchor" ) + .removeAttr( "role" ) + .removeAttr( "tabIndex" ) + .removeUniqueId(); + + this.tablist.unbind( this.eventNamespace ); + + this.tabs.add( this.panels ).each(function() { + if ( $.data( this, "ui-tabs-destroy" ) ) { + $( this ).remove(); + } else { + $( this ) + .removeClass( "ui-state-default ui-state-active ui-state-disabled " + + "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) + .removeAttr( "tabIndex" ) + .removeAttr( "aria-live" ) + .removeAttr( "aria-busy" ) + .removeAttr( "aria-selected" ) + .removeAttr( "aria-labelledby" ) + .removeAttr( "aria-hidden" ) + .removeAttr( "aria-expanded" ) + .removeAttr( "role" ); + } + }); + + this.tabs.each(function() { + var li = $( this ), + prev = li.data( "ui-tabs-aria-controls" ); + if ( prev ) { + li + .attr( "aria-controls", prev ) + .removeData( "ui-tabs-aria-controls" ); + } else { + li.removeAttr( "aria-controls" ); + } + }); + + this.panels.show(); + + if ( this.options.heightStyle !== "content" ) { + this.panels.css( "height", "" ); + } + }, + + enable: function( index ) { + var disabled = this.options.disabled; + if ( disabled === false ) { + return; + } + + if ( index === undefined ) { + disabled = false; + } else { + index = this._getIndex( index ); + if ( $.isArray( disabled ) ) { + disabled = $.map( disabled, function( num ) { + return num !== index ? num : null; + }); + } else { + disabled = $.map( this.tabs, function( li, num ) { + return num !== index ? num : null; + }); + } + } + this._setupDisabled( disabled ); + }, + + disable: function( index ) { + var disabled = this.options.disabled; + if ( disabled === true ) { + return; + } + + if ( index === undefined ) { + disabled = true; + } else { + index = this._getIndex( index ); + if ( $.inArray( index, disabled ) !== -1 ) { + return; + } + if ( $.isArray( disabled ) ) { + disabled = $.merge( [ index ], disabled ).sort(); + } else { + disabled = [ index ]; + } + } + this._setupDisabled( disabled ); + }, + + load: function( index, event ) { + index = this._getIndex( index ); + var that = this, + tab = this.tabs.eq( index ), + anchor = tab.find( ".ui-tabs-anchor" ), + panel = this._getPanelForTab( tab ), + eventData = { + tab: tab, + panel: panel + }, + complete = function( jqXHR, status ) { + if ( status === "abort" ) { + that.panels.stop( false, true ); + } + + tab.removeClass( "ui-tabs-loading" ); + panel.removeAttr( "aria-busy" ); + + if ( jqXHR === that.xhr ) { + delete that.xhr; + } + }; + + // not remote + if ( this._isLocal( anchor[ 0 ] ) ) { + return; + } + + this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); + + // support: jQuery <1.8 + // jQuery <1.8 returns false if the request is canceled in beforeSend, + // but as of 1.8, $.ajax() always returns a jqXHR object. + if ( this.xhr && this.xhr.statusText !== "canceled" ) { + tab.addClass( "ui-tabs-loading" ); + panel.attr( "aria-busy", "true" ); + + this.xhr + .done(function( response, status, jqXHR ) { + // support: jQuery <1.8 + // http://bugs.jquery.com/ticket/11778 + setTimeout(function() { + panel.html( response ); + that._trigger( "load", event, eventData ); + + complete( jqXHR, status ); + }, 1 ); + }) + .fail(function( jqXHR, status ) { + // support: jQuery <1.8 + // http://bugs.jquery.com/ticket/11778 + setTimeout(function() { + complete( jqXHR, status ); + }, 1 ); + }); + } + }, + + _ajaxSettings: function( anchor, event, eventData ) { + var that = this; + return { + url: anchor.attr( "href" ), + beforeSend: function( jqXHR, settings ) { + return that._trigger( "beforeLoad", event, + $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) ); + } + }; + }, + + _getPanelForTab: function( tab ) { + var id = $( tab ).attr( "aria-controls" ); + return this.element.find( this._sanitizeSelector( "#" + id ) ); + } +}); + +})); +(function($, undefined) { + +/** + * Unobtrusive scripting adapter for jQuery + * https://github.com/rails/jquery-ujs + * + * Requires jQuery 1.8.0 or later. + * + * Released under the MIT license + * + */ + + // Cut down on the number of issues from people inadvertently including jquery_ujs twice + // by detecting and raising an error when it happens. + 'use strict'; + + if ( $.rails !== undefined ) { + $.error('jquery-ujs has already been loaded!'); + } + + // Shorthand to make it a little easier to call public rails functions from within rails.js + var rails; + var $document = $(document); + + $.rails = rails = { + // Link elements bound by jquery-ujs + linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote], a[data-disable-with], a[data-disable]', + + // Button elements bound by jquery-ujs + buttonClickSelector: 'button[data-remote]:not(form button), button[data-confirm]:not(form button)', + + // Select elements bound by jquery-ujs + inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]', + + // Form elements bound by jquery-ujs + formSubmitSelector: 'form', + + // Form input elements bound by jquery-ujs + formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])', + + // Form input elements disabled during form submission + disableSelector: 'input[data-disable-with]:enabled, button[data-disable-with]:enabled, textarea[data-disable-with]:enabled, input[data-disable]:enabled, button[data-disable]:enabled, textarea[data-disable]:enabled', + + // Form input elements re-enabled after form submission + enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled', + + // Form required input elements + requiredInputSelector: 'input[name][required]:not([disabled]),textarea[name][required]:not([disabled])', + + // Form file input elements + fileInputSelector: 'input[type=file]:not([disabled])', + + // Link onClick disable selector with possible reenable after remote submission + linkDisableSelector: 'a[data-disable-with], a[data-disable]', + + // Button onClick disable selector with possible reenable after remote submission + buttonDisableSelector: 'button[data-remote][data-disable-with], button[data-remote][data-disable]', + + // Up-to-date Cross-Site Request Forgery token + csrfToken: function() { + return $('meta[name=csrf-token]').attr('content'); + }, + + // URL param that must contain the CSRF token + csrfParam: function() { + return $('meta[name=csrf-param]').attr('content'); + }, + + // Make sure that every Ajax request sends the CSRF token + CSRFProtection: function(xhr) { + var token = rails.csrfToken(); + if (token) xhr.setRequestHeader('X-CSRF-Token', token); + }, + + // making sure that all forms have actual up-to-date token(cached forms contain old one) + refreshCSRFTokens: function(){ + $('form input[name="' + rails.csrfParam() + '"]').val(rails.csrfToken()); + }, + + // Triggers an event on an element and returns false if the event result is false + fire: function(obj, name, data) { + var event = $.Event(name); + obj.trigger(event, data); + return event.result !== false; + }, + + // Default confirm dialog, may be overridden with custom confirm dialog in $.rails.confirm + confirm: function(message) { + return confirm(message); + }, + + // Default ajax function, may be overridden with custom function in $.rails.ajax + ajax: function(options) { + return $.ajax(options); + }, + + // Default way to get an element's href. May be overridden at $.rails.href. + href: function(element) { + return element[0].href; + }, + + // Checks "data-remote" if true to handle the request through a XHR request. + isRemote: function(element) { + return element.data('remote') !== undefined && element.data('remote') !== false; + }, + + // Submits "remote" forms and links with ajax + handleRemote: function(element) { + var method, url, data, withCredentials, dataType, options; + + if (rails.fire(element, 'ajax:before')) { + withCredentials = element.data('with-credentials') || null; + dataType = element.data('type') || ($.ajaxSettings && $.ajaxSettings.dataType); + + if (element.is('form')) { + method = element.attr('method'); + url = element.attr('action'); + data = element.serializeArray(); + // memoized value from clicked submit button + var button = element.data('ujs:submit-button'); + if (button) { + data.push(button); + element.data('ujs:submit-button', null); + } + } else if (element.is(rails.inputChangeSelector)) { + method = element.data('method'); + url = element.data('url'); + data = element.serialize(); + if (element.data('params')) data = data + '&' + element.data('params'); + } else if (element.is(rails.buttonClickSelector)) { + method = element.data('method') || 'get'; + url = element.data('url'); + data = element.serialize(); + if (element.data('params')) data = data + '&' + element.data('params'); + } else { + method = element.data('method'); + url = rails.href(element); + data = element.data('params') || null; + } + + options = { + type: method || 'GET', data: data, dataType: dataType, + // stopping the "ajax:beforeSend" event will cancel the ajax request + beforeSend: function(xhr, settings) { + if (settings.dataType === undefined) { + xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script); + } + if (rails.fire(element, 'ajax:beforeSend', [xhr, settings])) { + element.trigger('ajax:send', xhr); + } else { + return false; + } + }, + success: function(data, status, xhr) { + element.trigger('ajax:success', [data, status, xhr]); + }, + complete: function(xhr, status) { + element.trigger('ajax:complete', [xhr, status]); + }, + error: function(xhr, status, error) { + element.trigger('ajax:error', [xhr, status, error]); + }, + crossDomain: rails.isCrossDomain(url) + }; + + // There is no withCredentials for IE6-8 when + // "Enable native XMLHTTP support" is disabled + if (withCredentials) { + options.xhrFields = { + withCredentials: withCredentials + }; + } + + // Only pass url to `ajax` options if not blank + if (url) { options.url = url; } + + return rails.ajax(options); + } else { + return false; + } + }, + + // Determines if the request is a cross domain request. + isCrossDomain: function(url) { + var originAnchor = document.createElement('a'); + originAnchor.href = location.href; + var urlAnchor = document.createElement('a'); + + try { + urlAnchor.href = url; + // This is a workaround to a IE bug. + urlAnchor.href = urlAnchor.href; + + // If URL protocol is false or is a string containing a single colon + // *and* host are false, assume it is not a cross-domain request + // (should only be the case for IE7 and IE compatibility mode). + // Otherwise, evaluate protocol and host of the URL against the origin + // protocol and host. + return !(((!urlAnchor.protocol || urlAnchor.protocol === ':') && !urlAnchor.host) || + (originAnchor.protocol + '//' + originAnchor.host === + urlAnchor.protocol + '//' + urlAnchor.host)); + } catch (e) { + // If there is an error parsing the URL, assume it is crossDomain. + return true; + } + }, + + // Handles "data-method" on links such as: + // <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a> + handleMethod: function(link) { + var href = rails.href(link), + method = link.data('method'), + target = link.attr('target'), + csrfToken = rails.csrfToken(), + csrfParam = rails.csrfParam(), + form = $('<form method="post" action="' + href + '"></form>'), + metadataInput = '<input name="_method" value="' + method + '" type="hidden" />'; + + if (csrfParam !== undefined && csrfToken !== undefined && !rails.isCrossDomain(href)) { + metadataInput += '<input name="' + csrfParam + '" value="' + csrfToken + '" type="hidden" />'; + } + + if (target) { form.attr('target', target); } + + form.hide().append(metadataInput).appendTo('body'); + form.submit(); + }, + + // Helper function that returns form elements that match the specified CSS selector + // If form is actually a "form" element this will return associated elements outside the from that have + // the html form attribute set + formElements: function(form, selector) { + return form.is('form') ? $(form[0].elements).filter(selector) : form.find(selector); + }, + + /* Disables form elements: + - Caches element value in 'ujs:enable-with' data store + - Replaces element text with value of 'data-disable-with' attribute + - Sets disabled property to true + */ + disableFormElements: function(form) { + rails.formElements(form, rails.disableSelector).each(function() { + rails.disableFormElement($(this)); + }); + }, + + disableFormElement: function(element) { + var method, replacement; + + method = element.is('button') ? 'html' : 'val'; + replacement = element.data('disable-with'); + + element.data('ujs:enable-with', element[method]()); + if (replacement !== undefined) { + element[method](replacement); + } + + element.prop('disabled', true); + }, + + /* Re-enables disabled form elements: + - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`) + - Sets disabled property to false + */ + enableFormElements: function(form) { + rails.formElements(form, rails.enableSelector).each(function() { + rails.enableFormElement($(this)); + }); + }, + + enableFormElement: function(element) { + var method = element.is('button') ? 'html' : 'val'; + if (typeof element.data('ujs:enable-with') !== 'undefined') element[method](element.data('ujs:enable-with')); + element.prop('disabled', false); + }, + + /* For 'data-confirm' attribute: + - Fires `confirm` event + - Shows the confirmation dialog + - Fires the `confirm:complete` event + + Returns `true` if no function stops the chain and user chose yes; `false` otherwise. + Attaching a handler to the element's `confirm` event that returns a `falsy` value cancels the confirmation dialog. + Attaching a handler to the element's `confirm:complete` event that returns a `falsy` value makes this function + return false. The `confirm:complete` event is fired whether or not the user answered true or false to the dialog. + */ + allowAction: function(element) { + var message = element.data('confirm'), + answer = false, callback; + if (!message) { return true; } + + if (rails.fire(element, 'confirm')) { + try { + answer = rails.confirm(message); + } catch (e) { + (console.error || console.log).call(console, e.stack || e); + } + callback = rails.fire(element, 'confirm:complete', [answer]); + } + return answer && callback; + }, + + // Helper function which checks for blank inputs in a form that match the specified CSS selector + blankInputs: function(form, specifiedSelector, nonBlank) { + var inputs = $(), input, valueToCheck, + selector = specifiedSelector || 'input,textarea', + allInputs = form.find(selector); + + allInputs.each(function() { + input = $(this); + valueToCheck = input.is('input[type=checkbox],input[type=radio]') ? input.is(':checked') : !!input.val(); + if (valueToCheck === nonBlank) { + + // Don't count unchecked required radio if other radio with same name is checked + if (input.is('input[type=radio]') && allInputs.filter('input[type=radio]:checked[name="' + input.attr('name') + '"]').length) { + return true; // Skip to next input + } + + inputs = inputs.add(input); + } + }); + return inputs.length ? inputs : false; + }, + + // Helper function which checks for non-blank inputs in a form that match the specified CSS selector + nonBlankInputs: function(form, specifiedSelector) { + return rails.blankInputs(form, specifiedSelector, true); // true specifies nonBlank + }, + + // Helper function, needed to provide consistent behavior in IE + stopEverything: function(e) { + $(e.target).trigger('ujs:everythingStopped'); + e.stopImmediatePropagation(); + return false; + }, + + // replace element's html with the 'data-disable-with' after storing original html + // and prevent clicking on it + disableElement: function(element) { + var replacement = element.data('disable-with'); + + element.data('ujs:enable-with', element.html()); // store enabled state + if (replacement !== undefined) { + element.html(replacement); + } + + element.bind('click.railsDisable', function(e) { // prevent further clicking + return rails.stopEverything(e); + }); + }, + + // restore element to its original state which was disabled by 'disableElement' above + enableElement: function(element) { + if (element.data('ujs:enable-with') !== undefined) { + element.html(element.data('ujs:enable-with')); // set to old enabled state + element.removeData('ujs:enable-with'); // clean up cache + } + element.unbind('click.railsDisable'); // enable element + } + }; + + if (rails.fire($document, 'rails:attachBindings')) { + + $.ajaxPrefilter(function(options, originalOptions, xhr){ if ( !options.crossDomain ) { rails.CSRFProtection(xhr); }}); + + // This event works the same as the load event, except that it fires every + // time the page is loaded. + // + // See https://github.com/rails/jquery-ujs/issues/357 + // See https://developer.mozilla.org/en-US/docs/Using_Firefox_1.5_caching + $(window).on('pageshow.rails', function () { + $($.rails.enableSelector).each(function () { + var element = $(this); + + if (element.data('ujs:enable-with')) { + $.rails.enableFormElement(element); + } + }); + + $($.rails.linkDisableSelector).each(function () { + var element = $(this); + + if (element.data('ujs:enable-with')) { + $.rails.enableElement(element); + } + }); + }); + + $document.delegate(rails.linkDisableSelector, 'ajax:complete', function() { + rails.enableElement($(this)); + }); + + $document.delegate(rails.buttonDisableSelector, 'ajax:complete', function() { + rails.enableFormElement($(this)); + }); + + $document.delegate(rails.linkClickSelector, 'click.rails', function(e) { + var link = $(this), method = link.data('method'), data = link.data('params'), metaClick = e.metaKey || e.ctrlKey; + if (!rails.allowAction(link)) return rails.stopEverything(e); + + if (!metaClick && link.is(rails.linkDisableSelector)) rails.disableElement(link); + + if (rails.isRemote(link)) { + if (metaClick && (!method || method === 'GET') && !data) { return true; } + + var handleRemote = rails.handleRemote(link); + // response from rails.handleRemote() will either be false or a deferred object promise. + if (handleRemote === false) { + rails.enableElement(link); + } else { + handleRemote.fail( function() { rails.enableElement(link); } ); + } + return false; + + } else if (method) { + rails.handleMethod(link); + return false; + } + }); + + $document.delegate(rails.buttonClickSelector, 'click.rails', function(e) { + var button = $(this); + + if (!rails.allowAction(button) || !rails.isRemote(button)) return rails.stopEverything(e); + + if (button.is(rails.buttonDisableSelector)) rails.disableFormElement(button); + + var handleRemote = rails.handleRemote(button); + // response from rails.handleRemote() will either be false or a deferred object promise. + if (handleRemote === false) { + rails.enableFormElement(button); + } else { + handleRemote.fail( function() { rails.enableFormElement(button); } ); + } + return false; + }); + + $document.delegate(rails.inputChangeSelector, 'change.rails', function(e) { + var link = $(this); + if (!rails.allowAction(link) || !rails.isRemote(link)) return rails.stopEverything(e); + + rails.handleRemote(link); + return false; + }); + + $document.delegate(rails.formSubmitSelector, 'submit.rails', function(e) { + var form = $(this), + remote = rails.isRemote(form), + blankRequiredInputs, + nonBlankFileInputs; + + if (!rails.allowAction(form)) return rails.stopEverything(e); + + // skip other logic when required values are missing or file upload is present + if (form.attr('novalidate') === undefined) { + blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector, false); + if (blankRequiredInputs && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) { + return rails.stopEverything(e); + } + } + + if (remote) { + nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector); + if (nonBlankFileInputs) { + // slight timeout so that the submit button gets properly serialized + // (make it easy for event handler to serialize form without disabled values) + setTimeout(function(){ rails.disableFormElements(form); }, 13); + var aborted = rails.fire(form, 'ajax:aborted:file', [nonBlankFileInputs]); + + // re-enable form elements if event bindings return false (canceling normal form submission) + if (!aborted) { setTimeout(function(){ rails.enableFormElements(form); }, 13); } + + return aborted; + } + + rails.handleRemote(form); + return false; + + } else { + // slight timeout so that the submit button gets properly serialized + setTimeout(function(){ rails.disableFormElements(form); }, 13); + } + }); + + $document.delegate(rails.formInputClickSelector, 'click.rails', function(event) { + var button = $(this); + + if (!rails.allowAction(button)) return rails.stopEverything(event); + + // register the pressed submit button + var name = button.attr('name'), + data = name ? {name:name, value:button.val()} : null; + + button.closest('form').data('ujs:submit-button', data); + }); + + $document.delegate(rails.formSubmitSelector, 'ajax:send.rails', function(event) { + if (this === event.target) rails.disableFormElements($(this)); + }); + + $document.delegate(rails.formSubmitSelector, 'ajax:complete.rails', function(event) { + if (this === event.target) rails.enableFormElements($(this)); + }); + + $(function(){ + rails.refreshCSRFTokens(); + }); + } + +})( jQuery ); +(function() { + window.ActiveAdmin = {}; + +}).call(this); +(function() { + $(document).on('ready page:load', function() { + $('.batch_actions_selector li a').click(function(e) { + var message; + e.stopPropagation(); + e.preventDefault(); + if (message = $(this).data('confirm')) { + return ActiveAdmin.modal_dialog(message, $(this).data('inputs'), (function(_this) { + return function(inputs) { + return $(_this).trigger('confirm:complete', inputs); + }; + })(this)); + } else { + return $(this).trigger('confirm:complete'); + } + }); + $('.batch_actions_selector li a').on('confirm:complete', function(e, inputs) { + var val; + if (val = JSON.stringify(inputs)) { + $('#batch_action_inputs').val(val); + } else { + $('#batch_action_inputs').attr('disabled', 'disabled'); + } + $('#batch_action').val($(this).data('action')); + return $('#collection_selection').submit(); + }); + if ($(".batch_actions_selector").length && $(":checkbox.toggle_all").length) { + if ($(".paginated_collection table.index_table").length) { + $(".paginated_collection table.index_table").tableCheckboxToggler(); + } else { + $(".paginated_collection").checkboxToggler(); + } + return $(document).on('change', '.paginated_collection :checkbox', function() { + if ($(".paginated_collection :checkbox:checked").length) { + return $(".batch_actions_selector").each(function() { + return $(this).aaDropdownMenu("enable"); + }); + } else { + return $(".batch_actions_selector").each(function() { + return $(this).aaDropdownMenu("disable"); + }); + } + }); + } + }); + +}).call(this); +(function() { + ActiveAdmin.CheckboxToggler = (function() { + function CheckboxToggler(options, container) { + var defaults; + this.options = options; + this.container = container; + defaults = {}; + this.options = $.extend(defaults, this.options); + this._init(); + this._bind(); + } + + CheckboxToggler.prototype._init = function() { + if (!this.container) { + throw new Error('Container element not found'); + } else { + this.$container = $(this.container); + } + if (!this.$container.find('.toggle_all').length) { + throw new Error('"toggle all" checkbox not found'); + } else { + this.toggle_all_checkbox = this.$container.find('.toggle_all'); + } + return this.checkboxes = this.$container.find(':checkbox').not(this.toggle_all_checkbox); + }; + + CheckboxToggler.prototype._bind = function() { + this.checkboxes.change((function(_this) { + return function(e) { + return _this._didChangeCheckbox(e.target); + }; + })(this)); + return this.toggle_all_checkbox.change((function(_this) { + return function() { + return _this._didChangeToggleAllCheckbox(); + }; + })(this)); + }; + + CheckboxToggler.prototype._didChangeCheckbox = function(checkbox) { + switch (this.checkboxes.filter(':checked').length) { + case this.checkboxes.length - 1: + return this.toggle_all_checkbox.prop({ + checked: null + }); + case this.checkboxes.length: + return this.toggle_all_checkbox.prop({ + checked: true + }); + } + }; + + CheckboxToggler.prototype._didChangeToggleAllCheckbox = function() { + var setting; + setting = this.toggle_all_checkbox.prop('checked') ? true : null; + return this.checkboxes.each((function(_this) { + return function(index, el) { + $(el).prop({ + checked: setting + }); + return _this._didChangeCheckbox(el); + }; + })(this)); + }; + + return CheckboxToggler; + + })(); + + $.widget.bridge('checkboxToggler', ActiveAdmin.CheckboxToggler); + +}).call(this); +(function() { + ActiveAdmin.DropdownMenu = (function() { + function DropdownMenu(options, element) { + var defaults; + this.options = options; + this.element = element; + this.$element = $(this.element); + defaults = { + fadeInDuration: 20, + fadeOutDuration: 100, + onClickActionItemCallback: null + }; + this.options = $.extend(defaults, this.options); + this.isOpen = false; + this.$menuButton = this.$element.find('.dropdown_menu_button'); + this.$menuList = this.$element.find('.dropdown_menu_list_wrapper'); + this._buildMenuList(); + this._bind(); + } + + DropdownMenu.prototype.open = function() { + this.isOpen = true; + this.$menuList.fadeIn(this.options.fadeInDuration); + this._position(); + return this; + }; + + DropdownMenu.prototype.close = function() { + this.isOpen = false; + this.$menuList.fadeOut(this.options.fadeOutDuration); + return this; + }; + + DropdownMenu.prototype.destroy = function() { + this.$element.unbind(); + this.$element = null; + return this; + }; + + DropdownMenu.prototype.isDisabled = function() { + return this.$menuButton.hasClass('disabled'); + }; + + DropdownMenu.prototype.disable = function() { + return this.$menuButton.addClass('disabled'); + }; + + DropdownMenu.prototype.enable = function() { + return this.$menuButton.removeClass('disabled'); + }; + + DropdownMenu.prototype.option = function(key, value) { + if ($.isPlainObject(key)) { + return this.options = $.extend(true, this.options, key); + } else if (key != null) { + return this.options[key]; + } else { + return this.options[key] = value; + } + }; + + DropdownMenu.prototype._buildMenuList = function() { + this.$nipple = $('<div class="dropdown_menu_nipple"></div>'); + this.$menuList.prepend(this.$nipple); + return this.$menuList.hide(); + }; + + DropdownMenu.prototype._bind = function() { + $('body').click((function(_this) { + return function() { + if (_this.isOpen) { + return _this.close(); + } + }; + })(this)); + return this.$menuButton.click((function(_this) { + return function() { + if (!_this.isDisabled()) { + if (_this.isOpen) { + _this.close(); + } else { + _this.open(); + } + } + return false; + }; + })(this)); + }; + + DropdownMenu.prototype._position = function() { + var button_center, button_left, button_right, centered_menu_left, centered_menu_right, menu_center, nipple_center, window_right; + this.$menuList.css('top', this.$menuButton.position().top + this.$menuButton.outerHeight() + 10); + button_left = this.$menuButton.position().left; + button_center = this.$menuButton.outerWidth() / 2; + button_right = button_left + button_center * 2; + menu_center = this.$menuList.outerWidth() / 2; + nipple_center = this.$nipple.outerWidth() / 2; + window_right = $(window).width(); + centered_menu_left = button_left + button_center - menu_center; + centered_menu_right = button_left + button_center + menu_center; + if (centered_menu_left < 0) { + this.$menuList.css('left', button_left); + return this.$nipple.css('left', button_center - nipple_center); + } else if (centered_menu_right > window_right) { + this.$menuList.css('right', window_right - button_right); + return this.$nipple.css('right', button_center - nipple_center); + } else { + this.$menuList.css('left', centered_menu_left); + return this.$nipple.css('left', menu_center - nipple_center); + } + }; + + return DropdownMenu; + + })(); + + $.widget.bridge('aaDropdownMenu', ActiveAdmin.DropdownMenu); + + $(document).on('ready page:load', function() { + return $('.dropdown_menu').aaDropdownMenu(); + }); + +}).call(this); +(function() { + var Flash; + + ActiveAdmin.flash = Flash = (function() { + Flash.error = function(message, close_after) { + return new this(message, "error", close_after); + }; + + Flash.notice = function(message, close_after) { + return new this(message, "notice", close_after); + }; + + Flash.prototype.reference = function() { + return this.reference; + }; + + function Flash(message1, type1, close_after) { + this.message = message1; + this.type = type1 != null ? type1 : "notice"; + this.reference = jQuery("<div>").addClass("flash flash_" + type).text(message); + jQuery(".flashes").append(this.reference); + if (close_after != null) { + this.close_after(close_after); + } + } + + Flash.prototype.close_after = function(close_after) { + return setTimeout((function(_this) { + return function() { + return _this.close(); + }; + })(this), close_after * 1000); + }; + + Flash.prototype.close = function() { + return this.reference.remove(); + }; + + return Flash; + + })(); + +}).call(this); +(function() { + var init_sortable, recompute_positions; + + $(function() { + $(document).on('click', 'a.button.has_many_remove', function(e) { + var parent, to_remove; + e.preventDefault(); + parent = $(this).closest('.has_many_container'); + to_remove = $(this).closest('fieldset'); + recompute_positions(parent); + parent.trigger('has_many_remove:before', [to_remove, parent]); + to_remove.remove(); + return parent.trigger('has_many_remove:after', [to_remove, parent]); + }); + $(document).on('click', 'a.button.has_many_add', function(e) { + var before_add, fieldset, html, index, parent, regex; + e.preventDefault(); + parent = $(this).closest('.has_many_container'); + parent.trigger(before_add = $.Event('has_many_add:before'), [parent]); + if (!before_add.isDefaultPrevented()) { + index = parent.data('has_many_index') || parent.children('fieldset').length - 1; + parent.data({ + has_many_index: ++index + }); + regex = new RegExp($(this).data('placeholder'), 'g'); + html = $(this).data('html').replace(regex, index); + fieldset = $(html).insertBefore(this); + recompute_positions(parent); + return parent.trigger('has_many_add:after', [fieldset, parent]); + } + }); + $(document).on('change', '.has_many_container[data-sortable] :input[name$="[_destroy]"]', function() { + return recompute_positions($(this).closest('.has_many')); + }); + init_sortable(); + return $(document).on('has_many_add:after', '.has_many_container', init_sortable); + }); + + init_sortable = function() { + var elems; + elems = $('.has_many_container[data-sortable]:not(.ui-sortable)'); + elems.sortable({ + items: '> fieldset', + handle: '> ol > .handle', + stop: recompute_positions + }); + return elems.each(recompute_positions); + }; + + recompute_positions = function(parent) { + var input_name, position; + parent = parent instanceof jQuery ? parent : $(this); + input_name = parent.data('sortable'); + position = parseInt(parent.data('sortable-start') || 0, 10); + return parent.children('fieldset').each(function() { + var destroy_input, sortable_input; + destroy_input = $(this).find("> ol > .input > :input[name$='[_destroy]']"); + sortable_input = $(this).find("> ol > .input > :input[name$='[" + input_name + "]']"); + if (sortable_input.length) { + return sortable_input.val(destroy_input.is(':checked') ? '' : position++); + } + }); + }; + +}).call(this); +(function() { + ActiveAdmin.modal_dialog = function(message, inputs, callback) { + var elem, html, klass, name, opts, ref, ref1, type, v, wrapper; + html = "<form id=\"dialog_confirm\" title=\"" + message + "\"><ul>"; + for (name in inputs) { + type = inputs[name]; + if (/^(datepicker|checkbox|text)$/.test(type)) { + wrapper = 'input'; + } else if (type === 'textarea') { + wrapper = 'textarea'; + } else if ($.isArray(type)) { + ref = ['select', 'option', type, ''], wrapper = ref[0], elem = ref[1], opts = ref[2], type = ref[3]; + } else { + throw new Error("Unsupported input type: {" + name + ": " + type + "}"); + } + klass = type === 'datepicker' ? type : ''; + html += ("<li>\n<label>" + (name.charAt(0).toUpperCase() + name.slice(1)) + "</label>\n<" + wrapper + " name=\"" + name + "\" class=\"" + klass + "\" type=\"" + type + "\">") + (opts ? ((function() { + var i, len, results; + results = []; + for (i = 0, len = opts.length; i < len; i++) { + v = opts[i]; + if ($.isArray(v)) { + results.push("<" + elem + " value=" + v[1] + ">" + v[0] + "</" + elem + ">"); + } else { + results.push("<" + elem + ">" + v + "</" + elem + ">"); + } + } + return results; + })()).join('') : '') + ("</" + wrapper + ">") + "</li>"; + ref1 = [], wrapper = ref1[0], elem = ref1[1], opts = ref1[2], type = ref1[3], klass = ref1[4]; + } + html += "</ul></form>"; + return $(html).appendTo('body').dialog({ + modal: true, + dialogClass: 'active_admin_dialog', + buttons: { + OK: function() { + callback($(this).serializeObject()); + return $(this).dialog('close'); + }, + Cancel: function() { + return $(this).dialog('close').remove(); + } + } + }); + }; + +}).call(this); +(function() { + ActiveAdmin.PerPage = (function() { + function PerPage(options, element) { + this.options = options; + this.element = element; + this.$element = $(this.element); + this._init(); + this._bind(); + } + + PerPage.prototype._init = function() { + return this.$params = this._queryParams(); + }; + + PerPage.prototype._bind = function() { + return this.$element.change((function(_this) { + return function() { + _this.$params['per_page'] = _this.$element.val(); + delete _this.$params['page']; + return location.search = $.param(_this.$params); + }; + })(this)); + }; + + PerPage.prototype._queryParams = function() { + var m, params, query, re; + query = window.location.search.substring(1); + params = {}; + re = /([^&=]+)=([^&]*)/g; + while (m = re.exec(query)) { + params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]); + } + return params; + }; + + return PerPage; + + })(); + + $.widget.bridge('perPage', ActiveAdmin.PerPage); + + $(function() { + return $('.pagination_per_page select').perPage(); + }); + +}).call(this); +(function() { + ActiveAdmin.Popover = (function() { + function Popover(options1, element) { + var defaults; + this.options = options1; + this.element = element; + this.$element = $(this.element); + defaults = { + fadeInDuration: 20, + fadeOutDuration: 100, + autoOpen: true, + pageWrapperElement: "#wrapper", + onClickActionItemCallback: null + }; + this.options = $.extend(defaults, options); + this.isOpen = false; + if (!(this.$popover = $(this.$element.attr('href'))).length) { + this.$popover = this.$element.next('.popover'); + } + this._buildPopover(); + this._bind(); + } + + Popover.prototype.open = function() { + this.isOpen = true; + this.$popover.fadeIn(this.options.fadeInDuration); + this._positionPopover(); + this._positionNipple(); + return this; + }; + + Popover.prototype.close = function() { + this.isOpen = false; + this.$popover.fadeOut(this.options.fadeOutDuration); + return this; + }; + + Popover.prototype.destroy = function() { + this.$element.removeData('popover'); + this.$element.unbind(); + this.$element = null; + return this; + }; + + Popover.prototype._buildPopover = function() { + this.$nipple = $('<div class="popover_nipple"></div>'); + this.$popover.prepend(this.$nipple); + this.$popover.hide(); + return this.$popover.addClass('popover'); + }; + + Popover.prototype._bind = function() { + $(this.options.pageWrapperElement).click((function(_this) { + return function() { + if (_this.isOpen) { + return _this.close(); + } + }; + })(this)); + if (this.options.autoOpen) { + return this.$element.click((function(_this) { + return function(e) { + e.stopPropagation(); + if (_this.isOpen) { + return _this.close(); + } else { + return _this.open(); + } + }; + })(this)); + } + }; + + Popover.prototype._positionPopover = function() { + var button_center, popover_center; + button_center = this.$element.offset().left + this.$element.outerWidth() / 2; + popover_center = this.$popover.outerWidth() / 2; + return this.$popover.css('left', button_center - popover_center); + }; + + Popover.prototype._positionNipple = function() { + this.$popover.css('top', this.$element.offset().top + this.$element.outerHeight() + 10); + return this.$nipple.css('left', this.$popover.outerWidth() / 2 - this.$nipple.outerWidth() / 2); + }; + + return Popover; + + })(); + + $.widget.bridge('popover', ActiveAdmin.Popover); + +}).call(this); +(function() { + var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + ActiveAdmin.TableCheckboxToggler = (function(superClass) { + extend(TableCheckboxToggler, superClass); + + function TableCheckboxToggler() { + return TableCheckboxToggler.__super__.constructor.apply(this, arguments); + } + + TableCheckboxToggler.prototype._init = function() { + return TableCheckboxToggler.__super__._init.apply(this, arguments); + }; + + TableCheckboxToggler.prototype._bind = function() { + TableCheckboxToggler.__super__._bind.apply(this, arguments); + return this.$container.find('tbody td').click((function(_this) { + return function(e) { + if (e.target.type !== 'checkbox') { + return _this._didClickCell(e.target); + } + }; + })(this)); + }; + + TableCheckboxToggler.prototype._didChangeCheckbox = function(checkbox) { + var $row; + TableCheckboxToggler.__super__._didChangeCheckbox.apply(this, arguments); + $row = $(checkbox).parents('tr'); + if (checkbox.checked) { + return $row.addClass('selected'); + } else { + return $row.removeClass('selected'); + } + }; + + TableCheckboxToggler.prototype._didClickCell = function(cell) { + return $(cell).parent('tr').find(':checkbox').click(); + }; + + return TableCheckboxToggler; + + })(ActiveAdmin.CheckboxToggler); + + $.widget.bridge('tableCheckboxToggler', ActiveAdmin.TableCheckboxToggler); + +}).call(this); +(function() { + $.ui.dialog.prototype._focusTabbable = function() { + return this.uiDialog.focus(); + }; + +}).call(this); +(function() { + $.fn.serializeObject = function() { + var i, len, o, obj, ref; + obj = {}; + ref = this.serializeArray(); + for (i = 0, len = ref.length; i < len; i++) { + o = ref[i]; + obj[o.name] = o.value; + } + return obj; + }; + +}).call(this); +(function() { + $(document).on('ready page:load', function() { + var batch_actions_selector; + $(document).on('focus', '.datepicker:not(.hasDatepicker)', function() { + var defaults, options; + defaults = { + dateFormat: 'yy-mm-dd' + }; + options = $(this).data('datepicker-options'); + return $(this).datepicker($.extend(defaults, options)); + }); + $('.clear_filters_btn').click(function() { + var param, params, regex; + params = window.location.search.split('&'); + regex = /^(q\[|q%5B|q%5b|page|commit)/; + return window.location.search = ((function() { + var i, len, results; + results = []; + for (i = 0, len = params.length; i < len; i++) { + param = params[i]; + if (!param.match(regex)) { + results.push(param); + } + } + return results; + })()).join('&'); + }); + $('.filter_form').submit(function() { + return $(this).find(':input').filter(function() { + return this.value === ''; + }).prop('disabled', true); + }); + $('.filter_form_field.select_and_search select').change(function() { + return $(this).siblings('input').prop({ + name: "q[" + this.value + "]" + }); + }); + $('#active_admin_content .tabs').tabs(); + if ((batch_actions_selector = $('.table_tools .batch_actions_selector')).length) { + return batch_actions_selector.next().css({ + width: "calc(100% - 10px - " + (batch_actions_selector.outerWidth()) + "px)", + 'float': 'right' + }); + } + }); + +}).call(this); +var Markdown; + +if (typeof exports === "object" && typeof require === "function") // we're in a CommonJS (e.g. Node.js) module + Markdown = exports; +else + Markdown = {}; + +// The following text is included for historical reasons, but should +// be taken with a pinch of salt; it's not all true anymore. + +// +// Wherever possible, Showdown is a straight, line-by-line port +// of the Perl version of Markdown. +// +// This is not a normal parser design; it's basically just a +// series of string substitutions. It's hard to read and +// maintain this way, but keeping Showdown close to the original +// design makes it easier to port new features. +// +// More importantly, Showdown behaves like markdown.pl in most +// edge cases. So web applications can do client-side preview +// in Javascript, and then build identical HTML on the server. +// +// This port needs the new RegExp functionality of ECMA 262, +// 3rd Edition (i.e. Javascript 1.5). Most modern web browsers +// should do fine. Even with the new regular expression features, +// We do a lot of work to emulate Perl's regex functionality. +// The tricky changes in this file mostly have the "attacklab:" +// label. Major or self-explanatory changes don't. +// +// Smart diff tools like Araxis Merge will be able to match up +// this file with markdown.pl in a useful way. A little tweaking +// helps: in a copy of markdown.pl, replace "#" with "//" and +// replace "$text" with "text". Be sure to ignore whitespace +// and line endings. +// + + +// +// Usage: +// +// var text = "Markdown *rocks*."; +// +// var converter = new Markdown.Converter(); +// var html = converter.makeHtml(text); +// +// alert(html); +// +// Note: move the sample code to the bottom of this +// file before uncommenting it. +// + +(function () { + + function identity(x) { return x; } + function returnFalse(x) { return false; } + + function HookCollection() { } + + HookCollection.prototype = { + + chain: function (hookname, func) { + var original = this[hookname]; + if (!original) + throw new Error("unknown hook " + hookname); + + if (original === identity) + this[hookname] = func; + else + this[hookname] = function (x) { return func(original(x)); } + }, + set: function (hookname, func) { + if (!this[hookname]) + throw new Error("unknown hook " + hookname); + this[hookname] = func; + }, + addNoop: function (hookname) { + this[hookname] = identity; + }, + addFalse: function (hookname) { + this[hookname] = returnFalse; + } + }; + + Markdown.HookCollection = HookCollection; + + // g_urls and g_titles allow arbitrary user-entered strings as keys. This + // caused an exception (and hence stopped the rendering) when the user entered + // e.g. [push] or [__proto__]. Adding a prefix to the actual key prevents this + // (since no builtin property starts with "s_"). See + // http://meta.stackoverflow.com/questions/64655/strange-wmd-bug + // (granted, switching from Array() to Object() alone would have left only __proto__ + // to be a problem) + function SaveHash() { } + SaveHash.prototype = { + set: function (key, value) { + this["s_" + key] = value; + }, + get: function (key) { + return this["s_" + key]; + } + }; + + Markdown.Converter = function () { + var pluginHooks = this.hooks = new HookCollection(); + pluginHooks.addNoop("plainLinkText"); // given a URL that was encountered by itself (without markup), should return the link text that's to be given to this link + pluginHooks.addNoop("preConversion"); // called with the orignal text as given to makeHtml. The result of this plugin hook is the actual markdown source that will be cooked + pluginHooks.addNoop("postConversion"); // called with the final cooked HTML code. The result of this plugin hook is the actual output of makeHtml + + // + // Private state of the converter instance: + // + + // Global hashes, used by various utility routines + var g_urls; + var g_titles; + var g_html_blocks; + + // Used to track when we're inside an ordered or unordered list + // (see _ProcessListItems() for details): + var g_list_level; + + this.makeHtml = function (text) { + + // + // Main function. The order in which other subs are called here is + // essential. Link and image substitutions need to happen before + // _EscapeSpecialCharsWithinTagAttributes(), so that any *'s or _'s in the <a> + // and <img> tags get encoded. + // + + // This will only happen if makeHtml on the same converter instance is called from a plugin hook. + // Don't do that. + if (g_urls) + throw new Error("Recursive call to converter.makeHtml"); + + // Create the private state objects. + g_urls = new SaveHash(); + g_titles = new SaveHash(); + g_html_blocks = []; + g_list_level = 0; + + text = pluginHooks.preConversion(text); + + // attacklab: Replace ~ with ~T + // This lets us use tilde as an escape char to avoid md5 hashes + // The choice of character is arbitray; anything that isn't + // magic in Markdown will work. + text = text.replace(/~/g, "~T"); + + // attacklab: Replace $ with ~D + // RegExp interprets $ as a special character + // when it's in a replacement string + text = text.replace(/\$/g, "~D"); + + // Standardize line endings + text = text.replace(/\r\n/g, "\n"); // DOS to Unix + text = text.replace(/\r/g, "\n"); // Mac to Unix + + // Make sure text begins and ends with a couple of newlines: + text = "\n\n" + text + "\n\n"; + + // Convert all tabs to spaces. + text = _Detab(text); + + // Strip any lines consisting only of spaces and tabs. + // This makes subsequent regexen easier to write, because we can + // match consecutive blank lines with /\n+/ instead of something + // contorted like /[ \t]*\n+/ . + text = text.replace(/^[ \t]+$/mg, ""); + + // Turn block-level HTML blocks into hash entries + text = _HashHTMLBlocks(text); + + // Strip link definitions, store in hashes. + text = _StripLinkDefinitions(text); + + text = _RunBlockGamut(text); + + text = _UnescapeSpecialChars(text); + + // attacklab: Restore dollar signs + text = text.replace(/~D/g, "$$"); + + // attacklab: Restore tildes + text = text.replace(/~T/g, "~"); + + text = pluginHooks.postConversion(text); + + g_html_blocks = g_titles = g_urls = null; + + return text; + }; + + function _StripLinkDefinitions(text) { + // + // Strips link definitions from text, stores the URLs and titles in + // hash references. + // + + // Link defs are in the form: ^[id]: url "optional title" + + /* + text = text.replace(/ + ^[ ]{0,3}\[(.+)\]: // id = $1 attacklab: g_tab_width - 1 + [ \t]* + \n? // maybe *one* newline + [ \t]* + <?(\S+?)>? // url = $2 + (?=\s|$) // lookahead for whitespace instead of the lookbehind removed below + [ \t]* + \n? // maybe one newline + [ \t]* + ( // (potential) title = $3 + (\n*) // any lines skipped = $4 attacklab: lookbehind removed + [ \t]+ + ["(] + (.+?) // title = $5 + [")] + [ \t]* + )? // title is optional + (?:\n+|$) + /gm, function(){...}); + */ + + text = text.replace(/^[ ]{0,3}\[(.+)\]:[ \t]*\n?[ \t]*<?(\S+?)>?(?=\s|$)[ \t]*\n?[ \t]*((\n*)["(](.+?)[")][ \t]*)?(?:\n+)/gm, + function (wholeMatch, m1, m2, m3, m4, m5) { + m1 = m1.toLowerCase(); + g_urls.set(m1, _EncodeAmpsAndAngles(m2)); // Link IDs are case-insensitive + if (m4) { + // Oops, found blank lines, so it's not a title. + // Put back the parenthetical statement we stole. + return m3; + } else if (m5) { + g_titles.set(m1, m5.replace(/"/g, """)); + } + + // Completely remove the definition from the text + return ""; + } + ); + + return text; + } + + function _HashHTMLBlocks(text) { + + // Hashify HTML blocks: + // We only want to do this for block-level HTML tags, such as headers, + // lists, and tables. That's because we still want to wrap <p>s around + // "paragraphs" that are wrapped in non-block-level tags, such as anchors, + // phrase emphasis, and spans. The list of tags we're looking for is + // hard-coded: + var block_tags_a = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del" + var block_tags_b = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math" + + // First, look for nested blocks, e.g.: + // <div> + // <div> + // tags for inner block must be indented. + // </div> + // </div> + // + // The outermost tags must start at the left margin for this to match, and + // the inner nested divs must be indented. + // We need to do this before the next, more liberal match, because the next + // match will start at the first `<div>` and stop at the first `</div>`. + + // attacklab: This regex can be expensive when it fails. + + /* + text = text.replace(/ + ( // save in $1 + ^ // start of line (with /m) + <($block_tags_a) // start tag = $2 + \b // word break + // attacklab: hack around khtml/pcre bug... + [^\r]*?\n // any number of lines, minimally matching + </\2> // the matching end tag + [ \t]* // trailing spaces/tabs + (?=\n+) // followed by a newline + ) // attacklab: there are sentinel newlines at end of document + /gm,function(){...}}; + */ + text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\b[^\r]*?\n<\/\2>[ \t]*(?=\n+))/gm, hashElement); + + // + // Now match more liberally, simply from `\n<tag>` to `</tag>\n` + // + + /* + text = text.replace(/ + ( // save in $1 + ^ // start of line (with /m) + <($block_tags_b) // start tag = $2 + \b // word break + // attacklab: hack around khtml/pcre bug... + [^\r]*? // any number of lines, minimally matching + .*</\2> // the matching end tag + [ \t]* // trailing spaces/tabs + (?=\n+) // followed by a newline + ) // attacklab: there are sentinel newlines at end of document + /gm,function(){...}}; + */ + text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math)\b[^\r]*?.*<\/\2>[ \t]*(?=\n+)\n)/gm, hashElement); + + // Special case just for <hr />. It was easier to make a special case than + // to make the other regex more complicated. + + /* + text = text.replace(/ + \n // Starting after a blank line + [ ]{0,3} + ( // save in $1 + (<(hr) // start tag = $2 + \b // word break + ([^<>])*? + \/?>) // the matching end tag + [ \t]* + (?=\n{2,}) // followed by a blank line + ) + /g,hashElement); + */ + text = text.replace(/\n[ ]{0,3}((<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g, hashElement); + + // Special case for standalone HTML comments: + + /* + text = text.replace(/ + \n\n // Starting after a blank line + [ ]{0,3} // attacklab: g_tab_width - 1 + ( // save in $1 + <! + (--(?:|(?:[^>-]|-[^>])(?:[^-]|-[^-])*)--) // see http://www.w3.org/TR/html-markup/syntax.html#comments and http://meta.stackoverflow.com/q/95256 + > + [ \t]* + (?=\n{2,}) // followed by a blank line + ) + /g,hashElement); + */ + text = text.replace(/\n\n[ ]{0,3}(<!(--(?:|(?:[^>-]|-[^>])(?:[^-]|-[^-])*)--)>[ \t]*(?=\n{2,}))/g, hashElement); + + // PHP and ASP-style processor instructions (<?...?> and <%...%>) + + /* + text = text.replace(/ + (?: + \n\n // Starting after a blank line + ) + ( // save in $1 + [ ]{0,3} // attacklab: g_tab_width - 1 + (?: + <([?%]) // $2 + [^\r]*? + \2> + ) + [ \t]* + (?=\n{2,}) // followed by a blank line + ) + /g,hashElement); + */ + text = text.replace(/(?:\n\n)([ ]{0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g, hashElement); + + return text; + } + + function hashElement(wholeMatch, m1) { + var blockText = m1; + + // Undo double lines + blockText = blockText.replace(/^\n+/, ""); + + // strip trailing blank lines + blockText = blockText.replace(/\n+$/g, ""); + + // Replace the element text with a marker ("~KxK" where x is its key) + blockText = "\n\n~K" + (g_html_blocks.push(blockText) - 1) + "K\n\n"; + + return blockText; + } + + function _RunBlockGamut(text, doNotUnhash) { + // + // These are all the transformations that form block-level + // tags like paragraphs, headers, and list items. + // + text = _DoHeaders(text); + + // Do Horizontal Rules: + var replacement = "<hr />\n"; + text = text.replace(/^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$/gm, replacement); + text = text.replace(/^[ ]{0,2}([ ]?-[ ]?){3,}[ \t]*$/gm, replacement); + text = text.replace(/^[ ]{0,2}([ ]?_[ ]?){3,}[ \t]*$/gm, replacement); + + text = _DoLists(text); + text = _DoCodeBlocks(text); + text = _DoBlockQuotes(text); + + // We already ran _HashHTMLBlocks() before, in Markdown(), but that + // was to escape raw HTML in the original Markdown source. This time, + // we're escaping the markup we've just created, so that we don't wrap + // <p> tags around block-level tags. + text = _HashHTMLBlocks(text); + text = _FormParagraphs(text, doNotUnhash); + + return text; + } + + function _RunSpanGamut(text) { + // + // These are all the transformations that occur *within* block-level + // tags like paragraphs, headers, and list items. + // + + text = _DoCodeSpans(text); + text = _EscapeSpecialCharsWithinTagAttributes(text); + text = _EncodeBackslashEscapes(text); + + // Process anchor and image tags. Images must come first, + // because ![foo][f] looks like an anchor. + text = _DoImages(text); + text = _DoAnchors(text); + + // Make links out of things like `<http://example.com/>` + // Must come after _DoAnchors(), because you can use < and > + // delimiters in inline links like [this](<url>). + text = _DoAutoLinks(text); + + text = text.replace(/~P/g, "://"); // put in place to prevent autolinking; reset now + + text = _EncodeAmpsAndAngles(text); + text = _DoItalicsAndBold(text); + + // Do hard breaks: + text = text.replace(/ +\n/g, " <br>\n"); + + return text; + } + + function _EscapeSpecialCharsWithinTagAttributes(text) { + // + // Within tags -- meaning between < and > -- encode [\ ` * _] so they + // don't conflict with their use in Markdown for code, italics and strong. + // + + // Build a regex to find HTML tags and comments. See Friedl's + // "Mastering Regular Expressions", 2nd Ed., pp. 200-201. + + // SE: changed the comment part of the regex + + var regex = /(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|<!(--(?:|(?:[^>-]|-[^>])(?:[^-]|-[^-])*)--)>)/gi; + + text = text.replace(regex, function (wholeMatch) { + var tag = wholeMatch.replace(/(.)<\/?code>(?=.)/g, "$1`"); + tag = escapeCharacters(tag, wholeMatch.charAt(1) == "!" ? "\\`*_/" : "\\`*_"); // also escape slashes in comments to prevent autolinking there -- http://meta.stackoverflow.com/questions/95987 + return tag; + }); + + return text; + } + + function _DoAnchors(text) { + // + // Turn Markdown link shortcuts into XHTML <a> tags. + // + // + // First, handle reference-style links: [link text] [id] + // + + /* + text = text.replace(/ + ( // wrap whole match in $1 + \[ + ( + (?: + \[[^\]]*\] // allow brackets nested one level + | + [^\[] // or anything else + )* + ) + \] + + [ ]? // one optional space + (?:\n[ ]*)? // one optional newline followed by spaces + + \[ + (.*?) // id = $3 + \] + ) + ()()()() // pad remaining backreferences + /g, writeAnchorTag); + */ + text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g, writeAnchorTag); + + // + // Next, inline-style links: [link text](url "optional title") + // + + /* + text = text.replace(/ + ( // wrap whole match in $1 + \[ + ( + (?: + \[[^\]]*\] // allow brackets nested one level + | + [^\[\]] // or anything else + )* + ) + \] + \( // literal paren + [ \t]* + () // no id, so leave $3 empty + <?( // href = $4 + (?: + \([^)]*\) // allow one level of (correctly nested) parens (think MSDN) + | + [^()\s] + )*? + )>? + [ \t]* + ( // $5 + (['"]) // quote char = $6 + (.*?) // Title = $7 + \6 // matching quote + [ \t]* // ignore any spaces/tabs between closing quote and ) + )? // title is optional + \) + ) + /g, writeAnchorTag); + */ + + text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()<?((?:\([^)]*\)|[^()\s])*?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g, writeAnchorTag); + + // + // Last, handle reference-style shortcuts: [link text] + // These must come last in case you've also got [link test][1] + // or [link test](/foo) + // + + /* + text = text.replace(/ + ( // wrap whole match in $1 + \[ + ([^\[\]]+) // link text = $2; can't contain '[' or ']' + \] + ) + ()()()()() // pad rest of backreferences + /g, writeAnchorTag); + */ + text = text.replace(/(\[([^\[\]]+)\])()()()()()/g, writeAnchorTag); + + return text; + } + + function writeAnchorTag(wholeMatch, m1, m2, m3, m4, m5, m6, m7) { + if (m7 == undefined) m7 = ""; + var whole_match = m1; + var link_text = m2.replace(/:\/\//g, "~P"); // to prevent auto-linking withing the link. will be converted back after the auto-linker runs + var link_id = m3.toLowerCase(); + var url = m4; + var title = m7; + + if (url == "") { + if (link_id == "") { + // lower-case and turn embedded newlines into spaces + link_id = link_text.toLowerCase().replace(/ ?\n/g, " "); + } + url = "#" + link_id; + + if (g_urls.get(link_id) != undefined) { + url = g_urls.get(link_id); + if (g_titles.get(link_id) != undefined) { + title = g_titles.get(link_id); + } + } + else { + if (whole_match.search(/\(\s*\)$/m) > -1) { + // Special case for explicit empty url + url = ""; + } else { + return whole_match; + } + } + } + url = encodeProblemUrlChars(url); + url = escapeCharacters(url, "*_"); + var result = "<a href=\"" + url + "\""; + + if (title != "") { + title = attributeEncode(title); + title = escapeCharacters(title, "*_"); + result += " title=\"" + title + "\""; + } + + result += ">" + link_text + "</a>"; + + return result; + } + + function _DoImages(text) { + // + // Turn Markdown image shortcuts into <img> tags. + // + + // + // First, handle reference-style labeled images: ![alt text][id] + // + + /* + text = text.replace(/ + ( // wrap whole match in $1 + !\[ + (.*?) // alt text = $2 + \] + + [ ]? // one optional space + (?:\n[ ]*)? // one optional newline followed by spaces + + \[ + (.*?) // id = $3 + \] + ) + ()()()() // pad rest of backreferences + /g, writeImageTag); + */ + text = text.replace(/(!\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g, writeImageTag); + + // + // Next, handle inline images:  + // Don't forget: encode * and _ + + /* + text = text.replace(/ + ( // wrap whole match in $1 + !\[ + (.*?) // alt text = $2 + \] + \s? // One optional whitespace character + \( // literal paren + [ \t]* + () // no id, so leave $3 empty + <?(\S+?)>? // src url = $4 + [ \t]* + ( // $5 + (['"]) // quote char = $6 + (.*?) // title = $7 + \6 // matching quote + [ \t]* + )? // title is optional + \) + ) + /g, writeImageTag); + */ + text = text.replace(/(!\[(.*?)\]\s?\([ \t]*()<?(\S+?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g, writeImageTag); + + return text; + } + + function attributeEncode(text) { + // unconditionally replace angle brackets here -- what ends up in an attribute (e.g. alt or title) + // never makes sense to have verbatim HTML in it (and the sanitizer would totally break it) + return text.replace(/>/g, ">").replace(/</g, "<").replace(/"/g, """); + } + + function writeImageTag(wholeMatch, m1, m2, m3, m4, m5, m6, m7) { + var whole_match = m1; + var alt_text = m2; + var link_id = m3.toLowerCase(); + var url = m4; + var title = m7; + + if (!title) title = ""; + + if (url == "") { + if (link_id == "") { + // lower-case and turn embedded newlines into spaces + link_id = alt_text.toLowerCase().replace(/ ?\n/g, " "); + } + url = "#" + link_id; + + if (g_urls.get(link_id) != undefined) { + url = g_urls.get(link_id); + if (g_titles.get(link_id) != undefined) { + title = g_titles.get(link_id); + } + } + else { + return whole_match; + } + } + + alt_text = escapeCharacters(attributeEncode(alt_text), "*_[]()"); + url = escapeCharacters(url, "*_"); + var result = "<img src=\"" + url + "\" alt=\"" + alt_text + "\""; + + // attacklab: Markdown.pl adds empty title attributes to images. + // Replicate this bug. + + //if (title != "") { + title = attributeEncode(title); + title = escapeCharacters(title, "*_"); + result += " title=\"" + title + "\""; + //} + + result += " />"; + + return result; + } + + function _DoHeaders(text) { + + // Setext-style headers: + // Header 1 + // ======== + // + // Header 2 + // -------- + // + text = text.replace(/^(.+)[ \t]*\n=+[ \t]*\n+/gm, + function (wholeMatch, m1) { return "<h1>" + _RunSpanGamut(m1) + "</h1>\n\n"; } + ); + + text = text.replace(/^(.+)[ \t]*\n-+[ \t]*\n+/gm, + function (matchFound, m1) { return "<h2>" + _RunSpanGamut(m1) + "</h2>\n\n"; } + ); + + // atx-style headers: + // # Header 1 + // ## Header 2 + // ## Header 2 with closing hashes ## + // ... + // ###### Header 6 + // + + /* + text = text.replace(/ + ^(\#{1,6}) // $1 = string of #'s + [ \t]* + (.+?) // $2 = Header text + [ \t]* + \#* // optional closing #'s (not counted) + \n+ + /gm, function() {...}); + */ + + text = text.replace(/^(\#{1,6})[ \t]*(.+?)[ \t]*\#*\n+/gm, + function (wholeMatch, m1, m2) { + var h_level = m1.length; + return "<h" + h_level + ">" + _RunSpanGamut(m2) + "</h" + h_level + ">\n\n"; + } + ); + + return text; + } + + function _DoLists(text) { + // + // Form HTML ordered (numbered) and unordered (bulleted) lists. + // + + // attacklab: add sentinel to hack around khtml/safari bug: + // http://bugs.webkit.org/show_bug.cgi?id=11231 + text += "~0"; + + // Re-usable pattern to match any entirel ul or ol list: + + /* + var whole_list = / + ( // $1 = whole list + ( // $2 + [ ]{0,3} // attacklab: g_tab_width - 1 + ([*+-]|\d+[.]) // $3 = first list item marker + [ \t]+ + ) + [^\r]+? + ( // $4 + ~0 // sentinel for workaround; should be $ + | + \n{2,} + (?=\S) + (?! // Negative lookahead for another list item marker + [ \t]* + (?:[*+-]|\d+[.])[ \t]+ + ) + ) + ) + /g + */ + var whole_list = /^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm; + + if (g_list_level) { + text = text.replace(whole_list, function (wholeMatch, m1, m2) { + var list = m1; + var list_type = (m2.search(/[*+-]/g) > -1) ? "ul" : "ol"; + + var result = _ProcessListItems(list, list_type); + + // Trim any trailing whitespace, to put the closing `</$list_type>` + // up on the preceding line, to get it past the current stupid + // HTML block parser. This is a hack to work around the terrible + // hack that is the HTML block parser. + result = result.replace(/\s+$/, ""); + result = "<" + list_type + ">" + result + "</" + list_type + ">\n"; + return result; + }); + } else { + whole_list = /(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/g; + text = text.replace(whole_list, function (wholeMatch, m1, m2, m3) { + var runup = m1; + var list = m2; + + var list_type = (m3.search(/[*+-]/g) > -1) ? "ul" : "ol"; + var result = _ProcessListItems(list, list_type); + result = runup + "<" + list_type + ">\n" + result + "</" + list_type + ">\n"; + return result; + }); + } + + // attacklab: strip sentinel + text = text.replace(/~0/, ""); + + return text; + } + + var _listItemMarkers = { ol: "\\d+[.]", ul: "[*+-]" }; + + function _ProcessListItems(list_str, list_type) { + // + // Process the contents of a single ordered or unordered list, splitting it + // into individual list items. + // + // list_type is either "ul" or "ol". + + // The $g_list_level global keeps track of when we're inside a list. + // Each time we enter a list, we increment it; when we leave a list, + // we decrement. If it's zero, we're not in a list anymore. + // + // We do this because when we're not inside a list, we want to treat + // something like this: + // + // I recommend upgrading to version + // 8. Oops, now this line is treated + // as a sub-list. + // + // As a single paragraph, despite the fact that the second line starts + // with a digit-period-space sequence. + // + // Whereas when we're inside a list (or sub-list), that line will be + // treated as the start of a sub-list. What a kludge, huh? This is + // an aspect of Markdown's syntax that's hard to parse perfectly + // without resorting to mind-reading. Perhaps the solution is to + // change the syntax rules such that sub-lists must start with a + // starting cardinal number; e.g. "1." or "a.". + + g_list_level++; + + // trim trailing blank lines: + list_str = list_str.replace(/\n{2,}$/, "\n"); + + // attacklab: add sentinel to emulate \z + list_str += "~0"; + + // In the original attacklab showdown, list_type was not given to this function, and anything + // that matched /[*+-]|\d+[.]/ would just create the next <li>, causing this mismatch: + // + // Markdown rendered by WMD rendered by MarkdownSharp + // ------------------------------------------------------------------ + // 1. first 1. first 1. first + // 2. second 2. second 2. second + // - third 3. third * third + // + // We changed this to behave identical to MarkdownSharp. This is the constructed RegEx, + // with {MARKER} being one of \d+[.] or [*+-], depending on list_type: + + /* + list_str = list_str.replace(/ + (^[ \t]*) // leading whitespace = $1 + ({MARKER}) [ \t]+ // list marker = $2 + ([^\r]+? // list item text = $3 + (\n+) + ) + (?= + (~0 | \2 ({MARKER}) [ \t]+) + ) + /gm, function(){...}); + */ + + var marker = _listItemMarkers[list_type]; + var re = new RegExp("(^[ \\t]*)(" + marker + ")[ \\t]+([^\\r]+?(\\n+))(?=(~0|\\1(" + marker + ")[ \\t]+))", "gm"); + var last_item_had_a_double_newline = false; + list_str = list_str.replace(re, + function (wholeMatch, m1, m2, m3) { + var item = m3; + var leading_space = m1; + var ends_with_double_newline = /\n\n$/.test(item); + var contains_double_newline = ends_with_double_newline || item.search(/\n{2,}/) > -1; + + if (contains_double_newline || last_item_had_a_double_newline) { + item = _RunBlockGamut(_Outdent(item), /* doNotUnhash = */true); + } + else { + // Recursion for sub-lists: + item = _DoLists(_Outdent(item)); + item = item.replace(/\n$/, ""); // chomp(item) + item = _RunSpanGamut(item); + } + last_item_had_a_double_newline = ends_with_double_newline; + return "<li>" + item + "</li>\n"; + } + ); + + // attacklab: strip sentinel + list_str = list_str.replace(/~0/g, ""); + + g_list_level--; + return list_str; + } + + function _DoCodeBlocks(text) { + // + // Process Markdown `<pre><code>` blocks. + // + + /* + text = text.replace(/ + (?:\n\n|^) + ( // $1 = the code block -- one or more lines, starting with a space/tab + (?: + (?:[ ]{4}|\t) // Lines must start with a tab or a tab-width of spaces - attacklab: g_tab_width + .*\n+ + )+ + ) + (\n*[ ]{0,3}[^ \t\n]|(?=~0)) // attacklab: g_tab_width + /g ,function(){...}); + */ + + // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug + text += "~0"; + + text = text.replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=~0))/g, + function (wholeMatch, m1, m2) { + var codeblock = m1; + var nextChar = m2; + + codeblock = _EncodeCode(_Outdent(codeblock)); + codeblock = _Detab(codeblock); + codeblock = codeblock.replace(/^\n+/g, ""); // trim leading newlines + codeblock = codeblock.replace(/\n+$/g, ""); // trim trailing whitespace + + codeblock = "<pre><code>" + codeblock + "\n</code></pre>"; + + return "\n\n" + codeblock + "\n\n" + nextChar; + } + ); + + // attacklab: strip sentinel + text = text.replace(/~0/, ""); + + return text; + } + + function hashBlock(text) { + text = text.replace(/(^\n+|\n+$)/g, ""); + return "\n\n~K" + (g_html_blocks.push(text) - 1) + "K\n\n"; + } + + function _DoCodeSpans(text) { + // + // * Backtick quotes are used for <code></code> spans. + // + // * You can use multiple backticks as the delimiters if you want to + // include literal backticks in the code span. So, this input: + // + // Just type ``foo `bar` baz`` at the prompt. + // + // Will translate to: + // + // <p>Just type <code>foo `bar` baz</code> at the prompt.</p> + // + // There's no arbitrary limit to the number of backticks you + // can use as delimters. If you need three consecutive backticks + // in your code, use four for delimiters, etc. + // + // * You can use spaces to get literal backticks at the edges: + // + // ... type `` `bar` `` ... + // + // Turns to: + // + // ... type <code>`bar`</code> ... + // + + /* + text = text.replace(/ + (^|[^\\]) // Character before opening ` can't be a backslash + (`+) // $2 = Opening run of ` + ( // $3 = The code block + [^\r]*? + [^`] // attacklab: work around lack of lookbehind + ) + \2 // Matching closer + (?!`) + /gm, function(){...}); + */ + + text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm, + function (wholeMatch, m1, m2, m3, m4) { + var c = m3; + c = c.replace(/^([ \t]*)/g, ""); // leading whitespace + c = c.replace(/[ \t]*$/g, ""); // trailing whitespace + c = _EncodeCode(c); + c = c.replace(/:\/\//g, "~P"); // to prevent auto-linking. Not necessary in code *blocks*, but in code spans. Will be converted back after the auto-linker runs. + return m1 + "<code>" + c + "</code>"; + } + ); + + return text; + } + + function _EncodeCode(text) { + // + // Encode/escape certain characters inside Markdown code runs. + // The point is that in code, these characters are literals, + // and lose their special Markdown meanings. + // + // Encode all ampersands; HTML entities are not + // entities within a Markdown code span. + text = text.replace(/&/g, "&"); + + // Do the angle bracket song and dance: + text = text.replace(/</g, "<"); + text = text.replace(/>/g, ">"); + + // Now, escape characters that are magic in Markdown: + text = escapeCharacters(text, "\*_{}[]\\", false); + + // jj the line above breaks this: + //--- + + //* Item + + // 1. Subitem + + // special char: * + //--- + + return text; + } + + function _DoItalicsAndBold(text) { + + // <strong> must go first: + text = text.replace(/([\W_]|^)(\*\*|__)(?=\S)([^\r]*?\S[\*_]*)\2([\W_]|$)/g, + "$1<strong>$3</strong>$4"); + + text = text.replace(/([\W_]|^)(\*|_)(?=\S)([^\r\*_]*?\S)\2([\W_]|$)/g, + "$1<em>$3</em>$4"); + + return text; + } + + function _DoBlockQuotes(text) { + + /* + text = text.replace(/ + ( // Wrap whole match in $1 + ( + ^[ \t]*>[ \t]? // '>' at the start of a line + .+\n // rest of the first line + (.+\n)* // subsequent consecutive lines + \n* // blanks + )+ + ) + /gm, function(){...}); + */ + + text = text.replace(/((^[ \t]*>[ \t]?.+\n(.+\n)*\n*)+)/gm, + function (wholeMatch, m1) { + var bq = m1; + + // attacklab: hack around Konqueror 3.5.4 bug: + // "----------bug".replace(/^-/g,"") == "bug" + + bq = bq.replace(/^[ \t]*>[ \t]?/gm, "~0"); // trim one level of quoting + + // attacklab: clean up hack + bq = bq.replace(/~0/g, ""); + + bq = bq.replace(/^[ \t]+$/gm, ""); // trim whitespace-only lines + bq = _RunBlockGamut(bq); // recurse + + bq = bq.replace(/(^|\n)/g, "$1 "); + // These leading spaces screw with <pre> content, so we need to fix that: + bq = bq.replace( + /(\s*<pre>[^\r]+?<\/pre>)/gm, + function (wholeMatch, m1) { + var pre = m1; + // attacklab: hack around Konqueror 3.5.4 bug: + pre = pre.replace(/^ /mg, "~0"); + pre = pre.replace(/~0/g, ""); + return pre; + }); + + return hashBlock("<blockquote>\n" + bq + "\n</blockquote>"); + } + ); + return text; + } + + function _FormParagraphs(text, doNotUnhash) { + // + // Params: + // $text - string to process with html <p> tags + // + + // Strip leading and trailing lines: + text = text.replace(/^\n+/g, ""); + text = text.replace(/\n+$/g, ""); + + var grafs = text.split(/\n{2,}/g); + var grafsOut = []; + + var markerRe = /~K(\d+)K/; + + // + // Wrap <p> tags. + // + var end = grafs.length; + for (var i = 0; i < end; i++) { + var str = grafs[i]; + + // if this is an HTML marker, copy it + if (markerRe.test(str)) { + grafsOut.push(str); + } + else if (/\S/.test(str)) { + str = _RunSpanGamut(str); + str = str.replace(/^([ \t]*)/g, "<p>"); + str += "</p>" + grafsOut.push(str); + } + + } + // + // Unhashify HTML blocks + // + if (!doNotUnhash) { + end = grafsOut.length; + for (var i = 0; i < end; i++) { + var foundAny = true; + while (foundAny) { // we may need several runs, since the data may be nested + foundAny = false; + grafsOut[i] = grafsOut[i].replace(/~K(\d+)K/g, function (wholeMatch, id) { + foundAny = true; + return g_html_blocks[id]; + }); + } + } + } + return grafsOut.join("\n\n"); + } + + function _EncodeAmpsAndAngles(text) { + // Smart processing for ampersands and angle brackets that need to be encoded. + + // Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin: + // http://bumppo.net/projects/amputator/ + text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g, "&"); + + // Encode naked <'s + text = text.replace(/<(?![a-z\/?!]|~D)/gi, "<"); + + return text; + } + + function _EncodeBackslashEscapes(text) { + // + // Parameter: String. + // Returns: The string, with after processing the following backslash + // escape sequences. + // + + // attacklab: The polite way to do this is with the new + // escapeCharacters() function: + // + // text = escapeCharacters(text,"\\",true); + // text = escapeCharacters(text,"`*_{}[]()>#+-.!",true); + // + // ...but we're sidestepping its use of the (slow) RegExp constructor + // as an optimization for Firefox. This function gets called a LOT. + + text = text.replace(/\\(\\)/g, escapeCharacters_callback); + text = text.replace(/\\([`*_{}\[\]()>#+-.!])/g, escapeCharacters_callback); + return text; + } + + function _DoAutoLinks(text) { + + // note that at this point, all other URL in the text are already hyperlinked as <a href=""></a> + // *except* for the <http://www.foo.com> case + + // automatically add < and > around unadorned raw hyperlinks + // must be preceded by space/BOF and followed by non-word/EOF character + text = text.replace(/(^|\s)(https?|ftp)(:\/\/[-A-Z0-9+&@#\/%?=~_|\[\]\(\)!:,\.;]*[-A-Z0-9+&@#\/%=~_|\[\]])($|\W)/gi, "$1<$2$3>$4"); + + // autolink anything like <http://example.com> + + var replacer = function (wholematch, m1) { return "<a href=\"" + m1 + "\">" + pluginHooks.plainLinkText(m1) + "</a>"; } + text = text.replace(/<((https?|ftp):[^'">\s]+)>/gi, replacer); + + // Email addresses: <address@domain.foo> + /* + text = text.replace(/ + < + (?:mailto:)? + ( + [-.\w]+ + \@ + [-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+ + ) + > + /gi, _DoAutoLinks_callback()); + */ + + /* disabling email autolinking, since we don't do that on the server, either + text = text.replace(/<(?:mailto:)?([-.\w]+\@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi, + function(wholeMatch,m1) { + return _EncodeEmailAddress( _UnescapeSpecialChars(m1) ); + } + ); + */ + return text; + } + + function _UnescapeSpecialChars(text) { + // + // Swap back in all the special characters we've hidden. + // + text = text.replace(/~E(\d+)E/g, + function (wholeMatch, m1) { + var charCodeToReplace = parseInt(m1); + return String.fromCharCode(charCodeToReplace); + } + ); + return text; + } + + function _Outdent(text) { + // + // Remove one level of line-leading tabs or spaces + // + + // attacklab: hack around Konqueror 3.5.4 bug: + // "----------bug".replace(/^-/g,"") == "bug" + + text = text.replace(/^(\t|[ ]{1,4})/gm, "~0"); // attacklab: g_tab_width + + // attacklab: clean up hack + text = text.replace(/~0/g, "") + + return text; + } + + function _Detab(text) { + if (!/\t/.test(text)) + return text; + + var spaces = [" ", " ", " ", " "], + skew = 0, + v; + + return text.replace(/[\n\t]/g, function (match, offset) { + if (match === "\n") { + skew = offset + 1; + return match; + } + v = (offset - skew) % 4; + skew = offset + 1; + return spaces[v]; + }); + } + + // + // attacklab: Utility functions + // + + var _problemUrlChars = /(?:["'*()[\]:]|~D)/g; + + // hex-encodes some unusual "problem" chars in URLs to avoid URL detection problems + function encodeProblemUrlChars(url) { + if (!url) + return ""; + + var len = url.length; + + return url.replace(_problemUrlChars, function (match, offset) { + if (match == "~D") // escape for dollar + return "%24"; + if (match == ":") { + if (offset == len - 1 || /[0-9\/]/.test(url.charAt(offset + 1))) + return ":" + } + return "%" + match.charCodeAt(0).toString(16); + }); + } + + + function escapeCharacters(text, charsToEscape, afterBackslash) { + // First we have to escape the escape characters so that + // we can build a character class out of them + var regexString = "([" + charsToEscape.replace(/([\[\]\\])/g, "\\$1") + "])"; + + if (afterBackslash) { + regexString = "\\\\" + regexString; + } + + var regex = new RegExp(regexString, "g"); + text = text.replace(regex, escapeCharacters_callback); + + return text; + } + + + function escapeCharacters_callback(wholeMatch, m1) { + var charCodeToEscape = m1.charCodeAt(0); + return "~E" + charCodeToEscape + "E"; + } + + }; // end of the Markdown.Converter constructor + +})(); +// needs Markdown.Converter.js at the moment + +(function () { + + var util = {}, + position = {}, + ui = {}, + doc = window.document, + re = window.RegExp, + nav = window.navigator, + SETTINGS = { lineLength: 72 }, + + // Used to work around some browser bugs where we can't use feature testing. + uaSniffed = { + isIE: /msie/.test(nav.userAgent.toLowerCase()), + isIE_5or6: /msie 6/.test(nav.userAgent.toLowerCase()) || /msie 5/.test(nav.userAgent.toLowerCase()), + isOpera: /opera/.test(nav.userAgent.toLowerCase()) + }; + + var defaultsStrings = { + bold: "Strong <strong> Ctrl+B", + boldexample: "strong text", + + italic: "Emphasis <em> Ctrl+I", + italicexample: "emphasized text", + + link: "Hyperlink <a> Ctrl+L", + linkdescription: "enter link description here", + linkdialog: "<p><b>Insert Hyperlink</b></p><p>http://example.com/ \"optional title\"</p>", + + quote: "Blockquote <blockquote> Ctrl+Q", + quoteexample: "Blockquote", + + code: "Code Sample <pre><code> Ctrl+K", + codeexample: "enter code here", + + image: "Image <img> Ctrl+G", + imagedescription: "enter image description here", + imagedialog: "<p><b>Insert Image</b></p><p>http://example.com/images/diagram.jpg \"optional title\"<br><br>Need <a href='http://www.google.com/search?q=free+image+hosting' target='_blank'>free image hosting?</a></p>", + + olist: "Numbered List <ol> Ctrl+O", + ulist: "Bulleted List <ul> Ctrl+U", + litem: "List item", + + heading: "Heading <h1>/<h2> Ctrl+H", + headingexample: "Heading", + + hr: "Horizontal Rule <hr> Ctrl+R", + + undo: "Undo - Ctrl+Z", + redo: "Redo - Ctrl+Y", + redomac: "Redo - Ctrl+Shift+Z", + + help: "Markdown Editing Help" + }; + + + // ------------------------------------------------------------------- + // YOUR CHANGES GO HERE + // + // I've tried to localize the things you are likely to change to + // this area. + // ------------------------------------------------------------------- + + // The default text that appears in the dialog input box when entering + // links. + var imageDefaultText = "http://"; + var linkDefaultText = "http://"; + + // ------------------------------------------------------------------- + // END OF YOUR CHANGES + // ------------------------------------------------------------------- + + // options, if given, can have the following properties: + // options.helpButton = { handler: yourEventHandler } + // options.strings = { italicexample: "slanted text" } + // `yourEventHandler` is the click handler for the help button. + // If `options.helpButton` isn't given, not help button is created. + // `options.strings` can have any or all of the same properties as + // `defaultStrings` above, so you can just override some string displayed + // to the user on a case-by-case basis, or translate all strings to + // a different language. + // + // For backwards compatibility reasons, the `options` argument can also + // be just the `helpButton` object, and `strings.help` can also be set via + // `helpButton.title`. This should be considered legacy. + // + // The constructed editor object has the methods: + // - getConverter() returns the markdown converter object that was passed to the constructor + // - run() actually starts the editor; should be called after all necessary plugins are registered. Calling this more than once is a no-op. + // - refreshPreview() forces the preview to be updated. This method is only available after run() was called. + Markdown.Editor = function (markdownConverter, idPostfix, options) { + + options = options || {}; + + if (typeof options.handler === "function") { //backwards compatible behavior + options = { helpButton: options }; + } + options.strings = options.strings || {}; + if (options.helpButton) { + options.strings.help = options.strings.help || options.helpButton.title; + } + var getString = function (identifier) { return options.strings[identifier] || defaultsStrings[identifier]; } + + idPostfix = idPostfix || ""; + + var hooks = this.hooks = new Markdown.HookCollection(); + hooks.addNoop("onPreviewRefresh"); // called with no arguments after the preview has been refreshed + hooks.addNoop("postBlockquoteCreation"); // called with the user's selection *after* the blockquote was created; should return the actual to-be-inserted text + hooks.addFalse("insertImageDialog"); /* called with one parameter: a callback to be called with the URL of the image. If the application creates + * its own image insertion dialog, this hook should return true, and the callback should be called with the chosen + * image url (or null if the user cancelled). If this hook returns false, the default dialog will be used. + */ + + this.getConverter = function () { return markdownConverter; } + + var that = this, + panels; + + this.run = function () { + if (panels) + return; // already initialized + + panels = new PanelCollection(idPostfix); + var commandManager = new CommandManager(hooks, getString); + var previewManager = new PreviewManager(markdownConverter, panels, function () { hooks.onPreviewRefresh(); }); + var undoManager, uiManager; + + if (!/\?noundo/.test(doc.location.href)) { + undoManager = new UndoManager(function () { + previewManager.refresh(); + if (uiManager) // not available on the first call + uiManager.setUndoRedoButtonStates(); + }, panels); + this.textOperation = function (f) { + undoManager.setCommandMode(); + f(); + that.refreshPreview(); + } + } + + uiManager = new UIManager(idPostfix, panels, undoManager, previewManager, commandManager, options.helpButton, getString); + uiManager.setUndoRedoButtonStates(); + + var forceRefresh = that.refreshPreview = function () { previewManager.refresh(true); }; + + forceRefresh(); + }; + + } + + // before: contains all the text in the input box BEFORE the selection. + // after: contains all the text in the input box AFTER the selection. + function Chunks() { } + + // startRegex: a regular expression to find the start tag + // endRegex: a regular expresssion to find the end tag + Chunks.prototype.findTags = function (startRegex, endRegex) { + + var chunkObj = this; + var regex; + + if (startRegex) { + + regex = util.extendRegExp(startRegex, "", "$"); + + this.before = this.before.replace(regex, + function (match) { + chunkObj.startTag = chunkObj.startTag + match; + return ""; + }); + + regex = util.extendRegExp(startRegex, "^", ""); + + this.selection = this.selection.replace(regex, + function (match) { + chunkObj.startTag = chunkObj.startTag + match; + return ""; + }); + } + + if (endRegex) { + + regex = util.extendRegExp(endRegex, "", "$"); + + this.selection = this.selection.replace(regex, + function (match) { + chunkObj.endTag = match + chunkObj.endTag; + return ""; + }); + + regex = util.extendRegExp(endRegex, "^", ""); + + this.after = this.after.replace(regex, + function (match) { + chunkObj.endTag = match + chunkObj.endTag; + return ""; + }); + } + }; + + // If remove is false, the whitespace is transferred + // to the before/after regions. + // + // If remove is true, the whitespace disappears. + Chunks.prototype.trimWhitespace = function (remove) { + var beforeReplacer, afterReplacer, that = this; + if (remove) { + beforeReplacer = afterReplacer = ""; + } else { + beforeReplacer = function (s) { that.before += s; return ""; } + afterReplacer = function (s) { that.after = s + that.after; return ""; } + } + + this.selection = this.selection.replace(/^(\s*)/, beforeReplacer).replace(/(\s*)$/, afterReplacer); + }; + + + Chunks.prototype.skipLines = function (nLinesBefore, nLinesAfter, findExtraNewlines) { + + if (nLinesBefore === undefined) { + nLinesBefore = 1; + } + + if (nLinesAfter === undefined) { + nLinesAfter = 1; + } + + nLinesBefore++; + nLinesAfter++; + + var regexText; + var replacementText; + + // chrome bug ... documented at: http://meta.stackoverflow.com/questions/63307/blockquote-glitch-in-editor-in-chrome-6-and-7/65985#65985 + if (navigator.userAgent.match(/Chrome/)) { + "X".match(/()./); + } + + this.selection = this.selection.replace(/(^\n*)/, ""); + + this.startTag = this.startTag + re.$1; + + this.selection = this.selection.replace(/(\n*$)/, ""); + this.endTag = this.endTag + re.$1; + this.startTag = this.startTag.replace(/(^\n*)/, ""); + this.before = this.before + re.$1; + this.endTag = this.endTag.replace(/(\n*$)/, ""); + this.after = this.after + re.$1; + + if (this.before) { + + regexText = replacementText = ""; + + while (nLinesBefore--) { + regexText += "\\n?"; + replacementText += "\n"; + } + + if (findExtraNewlines) { + regexText = "\\n*"; + } + this.before = this.before.replace(new re(regexText + "$", ""), replacementText); + } + + if (this.after) { + + regexText = replacementText = ""; + + while (nLinesAfter--) { + regexText += "\\n?"; + replacementText += "\n"; + } + if (findExtraNewlines) { + regexText = "\\n*"; + } + + this.after = this.after.replace(new re(regexText, ""), replacementText); + } + }; + + // end of Chunks + + // A collection of the important regions on the page. + // Cached so we don't have to keep traversing the DOM. + // Also holds ieCachedRange and ieCachedScrollTop, where necessary; working around + // this issue: + // Internet explorer has problems with CSS sprite buttons that use HTML + // lists. When you click on the background image "button", IE will + // select the non-existent link text and discard the selection in the + // textarea. The solution to this is to cache the textarea selection + // on the button's mousedown event and set a flag. In the part of the + // code where we need to grab the selection, we check for the flag + // and, if it's set, use the cached area instead of querying the + // textarea. + // + // This ONLY affects Internet Explorer (tested on versions 6, 7 + // and 8) and ONLY on button clicks. Keyboard shortcuts work + // normally since the focus never leaves the textarea. + function PanelCollection(postfix) { + this.buttonBar = doc.getElementById("wmd-button-bar" + postfix); + this.preview = doc.getElementById("wmd-preview" + postfix); + this.input = doc.getElementById("wmd-input" + postfix); + }; + + // Returns true if the DOM element is visible, false if it's hidden. + // Checks if display is anything other than none. + util.isVisible = function (elem) { + + if (window.getComputedStyle) { + // Most browsers + return window.getComputedStyle(elem, null).getPropertyValue("display") !== "none"; + } + else if (elem.currentStyle) { + // IE + return elem.currentStyle["display"] !== "none"; + } + }; + + + // Adds a listener callback to a DOM element which is fired on a specified + // event. + util.addEvent = function (elem, event, listener) { + if (elem.attachEvent) { + // IE only. The "on" is mandatory. + elem.attachEvent("on" + event, listener); + } + else { + // Other browsers. + elem.addEventListener(event, listener, false); + } + }; + + + // Removes a listener callback from a DOM element which is fired on a specified + // event. + util.removeEvent = function (elem, event, listener) { + if (elem.detachEvent) { + // IE only. The "on" is mandatory. + elem.detachEvent("on" + event, listener); + } + else { + // Other browsers. + elem.removeEventListener(event, listener, false); + } + }; + + // Converts \r\n and \r to \n. + util.fixEolChars = function (text) { + text = text.replace(/\r\n/g, "\n"); + text = text.replace(/\r/g, "\n"); + return text; + }; + + // Extends a regular expression. Returns a new RegExp + // using pre + regex + post as the expression. + // Used in a few functions where we have a base + // expression and we want to pre- or append some + // conditions to it (e.g. adding "$" to the end). + // The flags are unchanged. + // + // regex is a RegExp, pre and post are strings. + util.extendRegExp = function (regex, pre, post) { + + if (pre === null || pre === undefined) { + pre = ""; + } + if (post === null || post === undefined) { + post = ""; + } + + var pattern = regex.toString(); + var flags; + + // Replace the flags with empty space and store them. + pattern = pattern.replace(/\/([gim]*)$/, function (wholeMatch, flagsPart) { + flags = flagsPart; + return ""; + }); + + // Remove the slash delimiters on the regular expression. + pattern = pattern.replace(/(^\/|\/$)/g, ""); + pattern = pre + pattern + post; + + return new re(pattern, flags); + } + + // UNFINISHED + // The assignment in the while loop makes jslint cranky. + // I'll change it to a better loop later. + position.getTop = function (elem, isInner) { + var result = elem.offsetTop; + if (!isInner) { + while (elem = elem.offsetParent) { + result += elem.offsetTop; + } + } + return result; + }; + + position.getHeight = function (elem) { + return elem.offsetHeight || elem.scrollHeight; + }; + + position.getWidth = function (elem) { + return elem.offsetWidth || elem.scrollWidth; + }; + + position.getPageSize = function () { + + var scrollWidth, scrollHeight; + var innerWidth, innerHeight; + + // It's not very clear which blocks work with which browsers. + if (self.innerHeight && self.scrollMaxY) { + scrollWidth = doc.body.scrollWidth; + scrollHeight = self.innerHeight + self.scrollMaxY; + } + else if (doc.body.scrollHeight > doc.body.offsetHeight) { + scrollWidth = doc.body.scrollWidth; + scrollHeight = doc.body.scrollHeight; + } + else { + scrollWidth = doc.body.offsetWidth; + scrollHeight = doc.body.offsetHeight; + } + + if (self.innerHeight) { + // Non-IE browser + innerWidth = self.innerWidth; + innerHeight = self.innerHeight; + } + else if (doc.documentElement && doc.documentElement.clientHeight) { + // Some versions of IE (IE 6 w/ a DOCTYPE declaration) + innerWidth = doc.documentElement.clientWidth; + innerHeight = doc.documentElement.clientHeight; + } + else if (doc.body) { + // Other versions of IE + innerWidth = doc.body.clientWidth; + innerHeight = doc.body.clientHeight; + } + + var maxWidth = Math.max(scrollWidth, innerWidth); + var maxHeight = Math.max(scrollHeight, innerHeight); + return [maxWidth, maxHeight, innerWidth, innerHeight]; + }; + + // Handles pushing and popping TextareaStates for undo/redo commands. + // I should rename the stack variables to list. + function UndoManager(callback, panels) { + + var undoObj = this; + var undoStack = []; // A stack of undo states + var stackPtr = 0; // The index of the current state + var mode = "none"; + var lastState; // The last state + var timer; // The setTimeout handle for cancelling the timer + var inputStateObj; + + // Set the mode for later logic steps. + var setMode = function (newMode, noSave) { + if (mode != newMode) { + mode = newMode; + if (!noSave) { + saveState(); + } + } + + if (!uaSniffed.isIE || mode != "moving") { + timer = setTimeout(refreshState, 1); + } + else { + inputStateObj = null; + } + }; + + var refreshState = function (isInitialState) { + inputStateObj = new TextareaState(panels, isInitialState); + timer = undefined; + }; + + this.setCommandMode = function () { + mode = "command"; + saveState(); + timer = setTimeout(refreshState, 0); + }; + + this.canUndo = function () { + return stackPtr > 1; + }; + + this.canRedo = function () { + if (undoStack[stackPtr + 1]) { + return true; + } + return false; + }; + + // Removes the last state and restores it. + this.undo = function () { + + if (undoObj.canUndo()) { + if (lastState) { + // What about setting state -1 to null or checking for undefined? + lastState.restore(); + lastState = null; + } + else { + undoStack[stackPtr] = new TextareaState(panels); + undoStack[--stackPtr].restore(); + + if (callback) { + callback(); + } + } + } + + mode = "none"; + panels.input.focus(); + refreshState(); + }; + + // Redo an action. + this.redo = function () { + + if (undoObj.canRedo()) { + + undoStack[++stackPtr].restore(); + + if (callback) { + callback(); + } + } + + mode = "none"; + panels.input.focus(); + refreshState(); + }; + + // Push the input area state to the stack. + var saveState = function () { + var currState = inputStateObj || new TextareaState(panels); + + if (!currState) { + return false; + } + if (mode == "moving") { + if (!lastState) { + lastState = currState; + } + return; + } + if (lastState) { + if (undoStack[stackPtr - 1].text != lastState.text) { + undoStack[stackPtr++] = lastState; + } + lastState = null; + } + undoStack[stackPtr++] = currState; + undoStack[stackPtr + 1] = null; + if (callback) { + callback(); + } + }; + + var handleCtrlYZ = function (event) { + + var handled = false; + + if (event.ctrlKey || event.metaKey) { + + // IE and Opera do not support charCode. + var keyCode = event.charCode || event.keyCode; + var keyCodeChar = String.fromCharCode(keyCode); + + switch (keyCodeChar.toLowerCase()) { + + case "y": + undoObj.redo(); + handled = true; + break; + + case "z": + if (!event.shiftKey) { + undoObj.undo(); + } + else { + undoObj.redo(); + } + handled = true; + break; + } + } + + if (handled) { + if (event.preventDefault) { + event.preventDefault(); + } + if (window.event) { + window.event.returnValue = false; + } + return; + } + }; + + // Set the mode depending on what is going on in the input area. + var handleModeChange = function (event) { + + if (!event.ctrlKey && !event.metaKey) { + + var keyCode = event.keyCode; + + if ((keyCode >= 33 && keyCode <= 40) || (keyCode >= 63232 && keyCode <= 63235)) { + // 33 - 40: page up/dn and arrow keys + // 63232 - 63235: page up/dn and arrow keys on safari + setMode("moving"); + } + else if (keyCode == 8 || keyCode == 46 || keyCode == 127) { + // 8: backspace + // 46: delete + // 127: delete + setMode("deleting"); + } + else if (keyCode == 13) { + // 13: Enter + setMode("newlines"); + } + else if (keyCode == 27) { + // 27: escape + setMode("escape"); + } + else if ((keyCode < 16 || keyCode > 20) && keyCode != 91) { + // 16-20 are shift, etc. + // 91: left window key + // I think this might be a little messed up since there are + // a lot of nonprinting keys above 20. + setMode("typing"); + } + } + }; + + var setEventHandlers = function () { + util.addEvent(panels.input, "keypress", function (event) { + // keyCode 89: y + // keyCode 90: z + if ((event.ctrlKey || event.metaKey) && (event.keyCode == 89 || event.keyCode == 90)) { + event.preventDefault(); + } + }); + + var handlePaste = function () { + if (uaSniffed.isIE || (inputStateObj && inputStateObj.text != panels.input.value)) { + if (timer == undefined) { + mode = "paste"; + saveState(); + refreshState(); + } + } + }; + + util.addEvent(panels.input, "keydown", handleCtrlYZ); + util.addEvent(panels.input, "keydown", handleModeChange); + util.addEvent(panels.input, "mousedown", function () { + setMode("moving"); + }); + + panels.input.onpaste = handlePaste; + panels.input.ondrop = handlePaste; + }; + + var init = function () { + setEventHandlers(); + refreshState(true); + saveState(); + }; + + init(); + } + + // end of UndoManager + + // The input textarea state/contents. + // This is used to implement undo/redo by the undo manager. + function TextareaState(panels, isInitialState) { + + // Aliases + var stateObj = this; + var inputArea = panels.input; + this.init = function () { + if (!util.isVisible(inputArea)) { + return; + } + if (!isInitialState && doc.activeElement && doc.activeElement !== inputArea) { // this happens when tabbing out of the input box + return; + } + + this.setInputAreaSelectionStartEnd(); + this.scrollTop = inputArea.scrollTop; + if (!this.text && inputArea.selectionStart || inputArea.selectionStart === 0) { + this.text = inputArea.value; + } + + } + + // Sets the selected text in the input box after we've performed an + // operation. + this.setInputAreaSelection = function () { + + if (!util.isVisible(inputArea)) { + return; + } + + if (inputArea.selectionStart !== undefined && !uaSniffed.isOpera) { + + inputArea.focus(); + inputArea.selectionStart = stateObj.start; + inputArea.selectionEnd = stateObj.end; + inputArea.scrollTop = stateObj.scrollTop; + } + else if (doc.selection) { + + if (doc.activeElement && doc.activeElement !== inputArea) { + return; + } + + inputArea.focus(); + var range = inputArea.createTextRange(); + range.moveStart("character", -inputArea.value.length); + range.moveEnd("character", -inputArea.value.length); + range.moveEnd("character", stateObj.end); + range.moveStart("character", stateObj.start); + range.select(); + } + }; + + this.setInputAreaSelectionStartEnd = function () { + + if (!panels.ieCachedRange && (inputArea.selectionStart || inputArea.selectionStart === 0)) { + + stateObj.start = inputArea.selectionStart; + stateObj.end = inputArea.selectionEnd; + } + else if (doc.selection) { + + stateObj.text = util.fixEolChars(inputArea.value); + + // IE loses the selection in the textarea when buttons are + // clicked. On IE we cache the selection. Here, if something is cached, + // we take it. + var range = panels.ieCachedRange || doc.selection.createRange(); + + var fixedRange = util.fixEolChars(range.text); + var marker = "\x07"; + var markedRange = marker + fixedRange + marker; + range.text = markedRange; + var inputText = util.fixEolChars(inputArea.value); + + range.moveStart("character", -markedRange.length); + range.text = fixedRange; + + stateObj.start = inputText.indexOf(marker); + stateObj.end = inputText.lastIndexOf(marker) - marker.length; + + var len = stateObj.text.length - util.fixEolChars(inputArea.value).length; + + if (len) { + range.moveStart("character", -fixedRange.length); + while (len--) { + fixedRange += "\n"; + stateObj.end += 1; + } + range.text = fixedRange; + } + + if (panels.ieCachedRange) + stateObj.scrollTop = panels.ieCachedScrollTop; // this is set alongside with ieCachedRange + + panels.ieCachedRange = null; + + this.setInputAreaSelection(); + } + }; + + // Restore this state into the input area. + this.restore = function () { + + if (stateObj.text != undefined && stateObj.text != inputArea.value) { + inputArea.value = stateObj.text; + } + this.setInputAreaSelection(); + inputArea.scrollTop = stateObj.scrollTop; + }; + + // Gets a collection of HTML chunks from the inptut textarea. + this.getChunks = function () { + + var chunk = new Chunks(); + chunk.before = util.fixEolChars(stateObj.text.substring(0, stateObj.start)); + chunk.startTag = ""; + chunk.selection = util.fixEolChars(stateObj.text.substring(stateObj.start, stateObj.end)); + chunk.endTag = ""; + chunk.after = util.fixEolChars(stateObj.text.substring(stateObj.end)); + chunk.scrollTop = stateObj.scrollTop; + + return chunk; + }; + + // Sets the TextareaState properties given a chunk of markdown. + this.setChunks = function (chunk) { + + chunk.before = chunk.before + chunk.startTag; + chunk.after = chunk.endTag + chunk.after; + + this.start = chunk.before.length; + this.end = chunk.before.length + chunk.selection.length; + this.text = chunk.before + chunk.selection + chunk.after; + this.scrollTop = chunk.scrollTop; + }; + this.init(); + }; + + function PreviewManager(converter, panels, previewRefreshCallback) { + + var managerObj = this; + var timeout; + var elapsedTime; + var oldInputText; + var maxDelay = 3000; + var startType = "delayed"; // The other legal value is "manual" + + // Adds event listeners to elements + var setupEvents = function (inputElem, listener) { + + util.addEvent(inputElem, "input", listener); + inputElem.onpaste = listener; + inputElem.ondrop = listener; + + util.addEvent(inputElem, "keypress", listener); + util.addEvent(inputElem, "keydown", listener); + }; + + var getDocScrollTop = function () { + + var result = 0; + + if (window.innerHeight) { + result = window.pageYOffset; + } + else + if (doc.documentElement && doc.documentElement.scrollTop) { + result = doc.documentElement.scrollTop; + } + else + if (doc.body) { + result = doc.body.scrollTop; + } + + return result; + }; + + var makePreviewHtml = function () { + + // If there is no registered preview panel + // there is nothing to do. + if (!panels.preview) + return; + + + var text = panels.input.value; + if (text && text == oldInputText) { + return; // Input text hasn't changed. + } + else { + oldInputText = text; + } + + var prevTime = new Date().getTime(); + + text = converter.makeHtml(text); + + // Calculate the processing time of the HTML creation. + // It's used as the delay time in the event listener. + var currTime = new Date().getTime(); + elapsedTime = currTime - prevTime; + + pushPreviewHtml(text); + }; + + // setTimeout is already used. Used as an event listener. + var applyTimeout = function () { + + if (timeout) { + clearTimeout(timeout); + timeout = undefined; + } + + if (startType !== "manual") { + + var delay = 0; + + if (startType === "delayed") { + delay = elapsedTime; + } + + if (delay > maxDelay) { + delay = maxDelay; + } + timeout = setTimeout(makePreviewHtml, delay); + } + }; + + var getScaleFactor = function (panel) { + if (panel.scrollHeight <= panel.clientHeight) { + return 1; + } + return panel.scrollTop / (panel.scrollHeight - panel.clientHeight); + }; + + var setPanelScrollTops = function () { + if (panels.preview) { + panels.preview.scrollTop = (panels.preview.scrollHeight - panels.preview.clientHeight) * getScaleFactor(panels.preview); + } + }; + + this.refresh = function (requiresRefresh) { + + if (requiresRefresh) { + oldInputText = ""; + makePreviewHtml(); + } + else { + applyTimeout(); + } + }; + + this.processingTime = function () { + return elapsedTime; + }; + + var isFirstTimeFilled = true; + + // IE doesn't let you use innerHTML if the element is contained somewhere in a table + // (which is the case for inline editing) -- in that case, detach the element, set the + // value, and reattach. Yes, that *is* ridiculous. + var ieSafePreviewSet = function (text) { + var preview = panels.preview; + var parent = preview.parentNode; + var sibling = preview.nextSibling; + parent.removeChild(preview); + preview.innerHTML = text; + if (!sibling) + parent.appendChild(preview); + else + parent.insertBefore(preview, sibling); + } + + var nonSuckyBrowserPreviewSet = function (text) { + panels.preview.innerHTML = text; + } + + var previewSetter; + + var previewSet = function (text) { + if (previewSetter) + return previewSetter(text); + + try { + nonSuckyBrowserPreviewSet(text); + previewSetter = nonSuckyBrowserPreviewSet; + } catch (e) { + previewSetter = ieSafePreviewSet; + previewSetter(text); + } + }; + + var pushPreviewHtml = function (text) { + + var emptyTop = position.getTop(panels.input) - getDocScrollTop(); + + if (panels.preview) { + previewSet(text); + previewRefreshCallback(); + } + + setPanelScrollTops(); + + if (isFirstTimeFilled) { + isFirstTimeFilled = false; + return; + } + + var fullTop = position.getTop(panels.input) - getDocScrollTop(); + + if (uaSniffed.isIE) { + setTimeout(function () { + window.scrollBy(0, fullTop - emptyTop); + }, 0); + } + else { + window.scrollBy(0, fullTop - emptyTop); + } + }; + + var init = function () { + + setupEvents(panels.input, applyTimeout); + makePreviewHtml(); + + if (panels.preview) { + panels.preview.scrollTop = 0; + } + }; + + init(); + }; + + // Creates the background behind the hyperlink text entry box. + // And download dialog + // Most of this has been moved to CSS but the div creation and + // browser-specific hacks remain here. + ui.createBackground = function () { + + var background = doc.createElement("div"), + style = background.style; + + background.className = "wmd-prompt-background"; + + style.position = "absolute"; + style.top = "0"; + + style.zIndex = "1000"; + + if (uaSniffed.isIE) { + style.filter = "alpha(opacity=50)"; + } + else { + style.opacity = "0.5"; + } + + var pageSize = position.getPageSize(); + style.height = pageSize[1] + "px"; + + if (uaSniffed.isIE) { + style.left = doc.documentElement.scrollLeft; + style.width = doc.documentElement.clientWidth; + } + else { + style.left = "0"; + style.width = "100%"; + } + + doc.body.appendChild(background); + return background; + }; + + // This simulates a modal dialog box and asks for the URL when you + // click the hyperlink or image buttons. + // + // text: The html for the input box. + // defaultInputText: The default value that appears in the input box. + // callback: The function which is executed when the prompt is dismissed, either via OK or Cancel. + // It receives a single argument; either the entered text (if OK was chosen) or null (if Cancel + // was chosen). + ui.prompt = function (text, defaultInputText, callback) { + + // These variables need to be declared at this level since they are used + // in multiple functions. + var dialog; // The dialog box. + var input; // The text box where you enter the hyperlink. + + + if (defaultInputText === undefined) { + defaultInputText = ""; + } + + // Used as a keydown event handler. Esc dismisses the prompt. + // Key code 27 is ESC. + var checkEscape = function (key) { + var code = (key.charCode || key.keyCode); + if (code === 27) { + close(true); + } + }; + + // Dismisses the hyperlink input box. + // isCancel is true if we don't care about the input text. + // isCancel is false if we are going to keep the text. + var close = function (isCancel) { + util.removeEvent(doc.body, "keydown", checkEscape); + var text = input.value; + + if (isCancel) { + text = null; + } + else { + // Fixes common pasting errors. + text = text.replace(/^http:\/\/(https?|ftp):\/\//, '$1://'); + if (!/^(?:https?|ftp):\/\//.test(text)) + text = 'http://' + text; + } + + dialog.parentNode.removeChild(dialog); + + callback(text); + return false; + }; + + + + // Create the text input box form/window. + var createDialog = function () { + + // The main dialog box. + dialog = doc.createElement("div"); + dialog.className = "wmd-prompt-dialog"; + dialog.style.padding = "10px;"; + dialog.style.position = "fixed"; + dialog.style.width = "400px"; + dialog.style.zIndex = "1001"; + + // The dialog text. + var question = doc.createElement("div"); + question.innerHTML = text; + question.style.padding = "5px"; + dialog.appendChild(question); + + // The web form container for the text box and buttons. + var form = doc.createElement("form"), + style = form.style; + form.onsubmit = function () { return close(false); }; + style.padding = "0"; + style.margin = "0"; + style.cssFloat = "left"; + style.width = "100%"; + style.textAlign = "center"; + style.position = "relative"; + dialog.appendChild(form); + + // The input text box + input = doc.createElement("input"); + input.type = "text"; + input.value = defaultInputText; + style = input.style; + style.display = "block"; + style.width = "80%"; + style.marginLeft = style.marginRight = "auto"; + form.appendChild(input); + + // The ok button + var okButton = doc.createElement("input"); + okButton.type = "button"; + okButton.onclick = function () { return close(false); }; + okButton.value = "OK"; + style = okButton.style; + style.margin = "10px"; + style.display = "inline"; + style.width = "7em"; + + + // The cancel button + var cancelButton = doc.createElement("input"); + cancelButton.type = "button"; + cancelButton.onclick = function () { return close(true); }; + cancelButton.value = "Cancel"; + style = cancelButton.style; + style.margin = "10px"; + style.display = "inline"; + style.width = "7em"; + + form.appendChild(okButton); + form.appendChild(cancelButton); + + util.addEvent(doc.body, "keydown", checkEscape); + dialog.style.top = "50%"; + dialog.style.left = "50%"; + dialog.style.display = "block"; + if (uaSniffed.isIE_5or6) { + dialog.style.position = "absolute"; + dialog.style.top = doc.documentElement.scrollTop + 200 + "px"; + dialog.style.left = "50%"; + } + doc.body.appendChild(dialog); + + // This has to be done AFTER adding the dialog to the form if you + // want it to be centered. + dialog.style.marginTop = -(position.getHeight(dialog) / 2) + "px"; + dialog.style.marginLeft = -(position.getWidth(dialog) / 2) + "px"; + + }; + + // Why is this in a zero-length timeout? + // Is it working around a browser bug? + setTimeout(function () { + + createDialog(); + + var defTextLen = defaultInputText.length; + if (input.selectionStart !== undefined) { + input.selectionStart = 0; + input.selectionEnd = defTextLen; + } + else if (input.createTextRange) { + var range = input.createTextRange(); + range.collapse(false); + range.moveStart("character", -defTextLen); + range.moveEnd("character", defTextLen); + range.select(); + } + + input.focus(); + }, 0); + }; + + function UIManager(postfix, panels, undoManager, previewManager, commandManager, helpOptions, getString) { + + var inputBox = panels.input, + buttons = {}; // buttons.undo, buttons.link, etc. The actual DOM elements. + + makeSpritedButtonRow(); + + var keyEvent = "keydown"; + if (uaSniffed.isOpera) { + keyEvent = "keypress"; + } + + util.addEvent(inputBox, keyEvent, function (key) { + + // Check to see if we have a button key and, if so execute the callback. + if ((key.ctrlKey || key.metaKey) && !key.altKey && !key.shiftKey) { + + var keyCode = key.charCode || key.keyCode; + var keyCodeStr = String.fromCharCode(keyCode).toLowerCase(); + + switch (keyCodeStr) { + case "b": + doClick(buttons.bold); + break; + case "i": + doClick(buttons.italic); + break; + case "l": + doClick(buttons.link); + break; + case "q": + doClick(buttons.quote); + break; + case "k": + doClick(buttons.code); + break; + case "g": + doClick(buttons.image); + break; + case "o": + doClick(buttons.olist); + break; + case "u": + doClick(buttons.ulist); + break; + case "h": + doClick(buttons.heading); + break; + case "r": + doClick(buttons.hr); + break; + case "y": + doClick(buttons.redo); + break; + case "z": + if (key.shiftKey) { + doClick(buttons.redo); + } + else { + doClick(buttons.undo); + } + break; + default: + return; + } + + + if (key.preventDefault) { + key.preventDefault(); + } + + if (window.event) { + window.event.returnValue = false; + } + } + }); + + // Auto-indent on shift-enter + util.addEvent(inputBox, "keyup", function (key) { + if (key.shiftKey && !key.ctrlKey && !key.metaKey) { + var keyCode = key.charCode || key.keyCode; + // Character 13 is Enter + if (keyCode === 13) { + var fakeButton = {}; + fakeButton.textOp = bindCommand("doAutoindent"); + doClick(fakeButton); + } + } + }); + + // special handler because IE clears the context of the textbox on ESC + if (uaSniffed.isIE) { + util.addEvent(inputBox, "keydown", function (key) { + var code = key.keyCode; + if (code === 27) { + return false; + } + }); + } + + + // Perform the button's action. + function doClick(button) { + + inputBox.focus(); + + if (button.textOp) { + + if (undoManager) { + undoManager.setCommandMode(); + } + + var state = new TextareaState(panels); + + if (!state) { + return; + } + + var chunks = state.getChunks(); + + // Some commands launch a "modal" prompt dialog. Javascript + // can't really make a modal dialog box and the WMD code + // will continue to execute while the dialog is displayed. + // This prevents the dialog pattern I'm used to and means + // I can't do something like this: + // + // var link = CreateLinkDialog(); + // makeMarkdownLink(link); + // + // Instead of this straightforward method of handling a + // dialog I have to pass any code which would execute + // after the dialog is dismissed (e.g. link creation) + // in a function parameter. + // + // Yes this is awkward and I think it sucks, but there's + // no real workaround. Only the image and link code + // create dialogs and require the function pointers. + var fixupInputArea = function () { + + inputBox.focus(); + + if (chunks) { + state.setChunks(chunks); + } + + state.restore(); + previewManager.refresh(); + }; + + var noCleanup = button.textOp(chunks, fixupInputArea); + + if (!noCleanup) { + fixupInputArea(); + } + + } + + if (button.execute) { + button.execute(undoManager); + } + }; + + function setupButton(button, isEnabled) { + + var normalYShift = "0px"; + var disabledYShift = "-20px"; + var highlightYShift = "-40px"; + var image = button.getElementsByTagName("span")[0]; + if (isEnabled) { + image.style.backgroundPosition = button.XShift + " " + normalYShift; + button.onmouseover = function () { + image.style.backgroundPosition = this.XShift + " " + highlightYShift; + }; + + button.onmouseout = function () { + image.style.backgroundPosition = this.XShift + " " + normalYShift; + }; + + // IE tries to select the background image "button" text (it's + // implemented in a list item) so we have to cache the selection + // on mousedown. + if (uaSniffed.isIE) { + button.onmousedown = function () { + if (doc.activeElement && doc.activeElement !== panels.input) { // we're not even in the input box, so there's no selection + return; + } + panels.ieCachedRange = document.selection.createRange(); + panels.ieCachedScrollTop = panels.input.scrollTop; + }; + } + + if (!button.isHelp) { + button.onclick = function () { + if (this.onmouseout) { + this.onmouseout(); + } + doClick(this); + return false; + } + } + } + else { + image.style.backgroundPosition = button.XShift + " " + disabledYShift; + button.onmouseover = button.onmouseout = button.onclick = function () { }; + } + } + + function bindCommand(method) { + if (typeof method === "string") + method = commandManager[method]; + return function () { method.apply(commandManager, arguments); } + } + + function makeSpritedButtonRow() { + + var buttonBar = panels.buttonBar; + + var normalYShift = "0px"; + var disabledYShift = "-20px"; + var highlightYShift = "-40px"; + + var buttonRow = document.createElement("ul"); + buttonRow.id = "wmd-button-row" + postfix; + buttonRow.className = 'wmd-button-row'; + buttonRow = buttonBar.appendChild(buttonRow); + var xPosition = 0; + var makeButton = function (id, title, XShift, textOp) { + var button = document.createElement("li"); + button.className = "wmd-button"; + button.style.left = xPosition + "px"; + xPosition += 25; + var buttonImage = document.createElement("span"); + button.id = id + postfix; + button.appendChild(buttonImage); + button.title = title; + button.XShift = XShift; + if (textOp) + button.textOp = textOp; + setupButton(button, true); + buttonRow.appendChild(button); + return button; + }; + var makeSpacer = function (num) { + var spacer = document.createElement("li"); + spacer.className = "wmd-spacer wmd-spacer" + num; + spacer.id = "wmd-spacer" + num + postfix; + buttonRow.appendChild(spacer); + xPosition += 25; + } + + buttons.bold = makeButton("wmd-bold-button", getString("bold"), "0px", bindCommand("doBold")); + buttons.italic = makeButton("wmd-italic-button", getString("italic"), "-20px", bindCommand("doItalic")); + makeSpacer(1); + buttons.link = makeButton("wmd-link-button", getString("link"), "-40px", bindCommand(function (chunk, postProcessing) { + return this.doLinkOrImage(chunk, postProcessing, false); + })); + buttons.quote = makeButton("wmd-quote-button", getString("quote"), "-60px", bindCommand("doBlockquote")); + buttons.code = makeButton("wmd-code-button", getString("code"), "-80px", bindCommand("doCode")); + buttons.image = makeButton("wmd-image-button", getString("image"), "-100px", bindCommand(function (chunk, postProcessing) { + return this.doLinkOrImage(chunk, postProcessing, true); + })); + makeSpacer(2); + buttons.olist = makeButton("wmd-olist-button", getString("olist"), "-120px", bindCommand(function (chunk, postProcessing) { + this.doList(chunk, postProcessing, true); + })); + buttons.ulist = makeButton("wmd-ulist-button", getString("ulist"), "-140px", bindCommand(function (chunk, postProcessing) { + this.doList(chunk, postProcessing, false); + })); + buttons.heading = makeButton("wmd-heading-button", getString("heading"), "-160px", bindCommand("doHeading")); + buttons.hr = makeButton("wmd-hr-button", getString("hr"), "-180px", bindCommand("doHorizontalRule")); + makeSpacer(3); + buttons.undo = makeButton("wmd-undo-button", getString("undo"), "-200px", null); + buttons.undo.execute = function (manager) { if (manager) manager.undo(); }; + + var redoTitle = /win/.test(nav.platform.toLowerCase()) ? + getString("redo") : + getString("redomac"); // mac and other non-Windows platforms + + buttons.redo = makeButton("wmd-redo-button", redoTitle, "-220px", null); + buttons.redo.execute = function (manager) { if (manager) manager.redo(); }; + + if (helpOptions) { + var helpButton = document.createElement("li"); + var helpButtonImage = document.createElement("span"); + helpButton.appendChild(helpButtonImage); + helpButton.className = "wmd-button wmd-help-button"; + helpButton.id = "wmd-help-button" + postfix; + helpButton.XShift = "-240px"; + helpButton.isHelp = true; + helpButton.style.right = "0px"; + helpButton.title = getString("help"); + helpButton.onclick = helpOptions.handler; + + setupButton(helpButton, true); + buttonRow.appendChild(helpButton); + buttons.help = helpButton; + } + + setUndoRedoButtonStates(); + } + + function setUndoRedoButtonStates() { + if (undoManager) { + setupButton(buttons.undo, undoManager.canUndo()); + setupButton(buttons.redo, undoManager.canRedo()); + } + }; + + this.setUndoRedoButtonStates = setUndoRedoButtonStates; + + } + + function CommandManager(pluginHooks, getString) { + this.hooks = pluginHooks; + this.getString = getString; + } + + var commandProto = CommandManager.prototype; + + // The markdown symbols - 4 spaces = code, > = blockquote, etc. + commandProto.prefixes = "(?:\\s{4,}|\\s*>|\\s*-\\s+|\\s*\\d+\\.|=|\\+|-|_|\\*|#|\\s*\\[[^\n]]+\\]:)"; + + // Remove markdown symbols from the chunk selection. + commandProto.unwrap = function (chunk) { + var txt = new re("([^\\n])\\n(?!(\\n|" + this.prefixes + "))", "g"); + chunk.selection = chunk.selection.replace(txt, "$1 $2"); + }; + + commandProto.wrap = function (chunk, len) { + this.unwrap(chunk); + var regex = new re("(.{1," + len + "})( +|$\\n?)", "gm"), + that = this; + + chunk.selection = chunk.selection.replace(regex, function (line, marked) { + if (new re("^" + that.prefixes, "").test(line)) { + return line; + } + return marked + "\n"; + }); + + chunk.selection = chunk.selection.replace(/\s+$/, ""); + }; + + commandProto.doBold = function (chunk, postProcessing) { + return this.doBorI(chunk, postProcessing, 2, this.getString("boldexample")); + }; + + commandProto.doItalic = function (chunk, postProcessing) { + return this.doBorI(chunk, postProcessing, 1, this.getString("italicexample")); + }; + + // chunk: The selected region that will be enclosed with */** + // nStars: 1 for italics, 2 for bold + // insertText: If you just click the button without highlighting text, this gets inserted + commandProto.doBorI = function (chunk, postProcessing, nStars, insertText) { + + // Get rid of whitespace and fixup newlines. + chunk.trimWhitespace(); + chunk.selection = chunk.selection.replace(/\n{2,}/g, "\n"); + + // Look for stars before and after. Is the chunk already marked up? + // note that these regex matches cannot fail + var starsBefore = /(\**$)/.exec(chunk.before)[0]; + var starsAfter = /(^\**)/.exec(chunk.after)[0]; + + var prevStars = Math.min(starsBefore.length, starsAfter.length); + + // Remove stars if we have to since the button acts as a toggle. + if ((prevStars >= nStars) && (prevStars != 2 || nStars != 1)) { + chunk.before = chunk.before.replace(re("[*]{" + nStars + "}$", ""), ""); + chunk.after = chunk.after.replace(re("^[*]{" + nStars + "}", ""), ""); + } + else if (!chunk.selection && starsAfter) { + // It's not really clear why this code is necessary. It just moves + // some arbitrary stuff around. + chunk.after = chunk.after.replace(/^([*_]*)/, ""); + chunk.before = chunk.before.replace(/(\s?)$/, ""); + var whitespace = re.$1; + chunk.before = chunk.before + starsAfter + whitespace; + } + else { + + // In most cases, if you don't have any selected text and click the button + // you'll get a selected, marked up region with the default text inserted. + if (!chunk.selection && !starsAfter) { + chunk.selection = insertText; + } + + // Add the true markup. + var markup = nStars <= 1 ? "*" : "**"; // shouldn't the test be = ? + chunk.before = chunk.before + markup; + chunk.after = markup + chunk.after; + } + + return; + }; + + commandProto.stripLinkDefs = function (text, defsToAdd) { + + text = text.replace(/^[ ]{0,3}\[(\d+)\]:[ \t]*\n?[ \t]*<?(\S+?)>?[ \t]*\n?[ \t]*(?:(\n*)["(](.+?)[")][ \t]*)?(?:\n+|$)/gm, + function (totalMatch, id, link, newlines, title) { + defsToAdd[id] = totalMatch.replace(/\s*$/, ""); + if (newlines) { + // Strip the title and return that separately. + defsToAdd[id] = totalMatch.replace(/["(](.+?)[")]$/, ""); + return newlines + title; + } + return ""; + }); + + return text; + }; + + commandProto.addLinkDef = function (chunk, linkDef) { + + var refNumber = 0; // The current reference number + var defsToAdd = {}; // + // Start with a clean slate by removing all previous link definitions. + chunk.before = this.stripLinkDefs(chunk.before, defsToAdd); + chunk.selection = this.stripLinkDefs(chunk.selection, defsToAdd); + chunk.after = this.stripLinkDefs(chunk.after, defsToAdd); + + var defs = ""; + var regex = /(\[)((?:\[[^\]]*\]|[^\[\]])*)(\][ ]?(?:\n[ ]*)?\[)(\d+)(\])/g; + + var addDefNumber = function (def) { + refNumber++; + def = def.replace(/^[ ]{0,3}\[(\d+)\]:/, " [" + refNumber + "]:"); + defs += "\n" + def; + }; + + // note that + // a) the recursive call to getLink cannot go infinite, because by definition + // of regex, inner is always a proper substring of wholeMatch, and + // b) more than one level of nesting is neither supported by the regex + // nor making a lot of sense (the only use case for nesting is a linked image) + var getLink = function (wholeMatch, before, inner, afterInner, id, end) { + inner = inner.replace(regex, getLink); + if (defsToAdd[id]) { + addDefNumber(defsToAdd[id]); + return before + inner + afterInner + refNumber + end; + } + return wholeMatch; + }; + + chunk.before = chunk.before.replace(regex, getLink); + + if (linkDef) { + addDefNumber(linkDef); + } + else { + chunk.selection = chunk.selection.replace(regex, getLink); + } + + var refOut = refNumber; + + chunk.after = chunk.after.replace(regex, getLink); + + if (chunk.after) { + chunk.after = chunk.after.replace(/\n*$/, ""); + } + if (!chunk.after) { + chunk.selection = chunk.selection.replace(/\n*$/, ""); + } + + chunk.after += "\n\n" + defs; + + return refOut; + }; + + // takes the line as entered into the add link/as image dialog and makes + // sure the URL and the optinal title are "nice". + function properlyEncoded(linkdef) { + return linkdef.replace(/^\s*(.*?)(?:\s+"(.+)")?\s*$/, function (wholematch, link, title) { + link = link.replace(/\?.*$/, function (querypart) { + return querypart.replace(/\+/g, " "); // in the query string, a plus and a space are identical + }); + link = decodeURIComponent(link); // unencode first, to prevent double encoding + link = encodeURI(link).replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29'); + link = link.replace(/\?.*$/, function (querypart) { + return querypart.replace(/\+/g, "%2b"); // since we replaced plus with spaces in the query part, all pluses that now appear where originally encoded + }); + if (title) { + title = title.trim ? title.trim() : title.replace(/^\s*/, "").replace(/\s*$/, ""); + title = title.replace(/"/g, "quot;").replace(/\(/g, "(").replace(/\)/g, ")").replace(/</g, "<").replace(/>/g, ">"); + } + return title ? link + ' "' + title + '"' : link; + }); + } + + commandProto.doLinkOrImage = function (chunk, postProcessing, isImage) { + + chunk.trimWhitespace(); + chunk.findTags(/\s*!?\[/, /\][ ]?(?:\n[ ]*)?(\[.*?\])?/); + var background; + + if (chunk.endTag.length > 1 && chunk.startTag.length > 0) { + + chunk.startTag = chunk.startTag.replace(/!?\[/, ""); + chunk.endTag = ""; + this.addLinkDef(chunk, null); + + } + else { + + // We're moving start and end tag back into the selection, since (as we're in the else block) we're not + // *removing* a link, but *adding* one, so whatever findTags() found is now back to being part of the + // link text. linkEnteredCallback takes care of escaping any brackets. + chunk.selection = chunk.startTag + chunk.selection + chunk.endTag; + chunk.startTag = chunk.endTag = ""; + + if (/\n\n/.test(chunk.selection)) { + this.addLinkDef(chunk, null); + return; + } + var that = this; + // The function to be executed when you enter a link and press OK or Cancel. + // Marks up the link and adds the ref. + var linkEnteredCallback = function (link) { + + background.parentNode.removeChild(background); + + if (link !== null) { + // ( $1 + // [^\\] anything that's not a backslash + // (?:\\\\)* an even number (this includes zero) of backslashes + // ) + // (?= followed by + // [[\]] an opening or closing bracket + // ) + // + // In other words, a non-escaped bracket. These have to be escaped now to make sure they + // don't count as the end of the link or similar. + // Note that the actual bracket has to be a lookahead, because (in case of to subsequent brackets), + // the bracket in one match may be the "not a backslash" character in the next match, so it + // should not be consumed by the first match. + // The "prepend a space and finally remove it" steps makes sure there is a "not a backslash" at the + // start of the string, so this also works if the selection begins with a bracket. We cannot solve + // this by anchoring with ^, because in the case that the selection starts with two brackets, this + // would mean a zero-width match at the start. Since zero-width matches advance the string position, + // the first bracket could then not act as the "not a backslash" for the second. + chunk.selection = (" " + chunk.selection).replace(/([^\\](?:\\\\)*)(?=[[\]])/g, "$1\\").substr(1); + + var linkDef = " [999]: " + properlyEncoded(link); + + var num = that.addLinkDef(chunk, linkDef); + chunk.startTag = isImage ? "![" : "["; + chunk.endTag = "][" + num + "]"; + + if (!chunk.selection) { + if (isImage) { + chunk.selection = that.getString("imagedescription"); + } + else { + chunk.selection = that.getString("linkdescription"); + } + } + } + postProcessing(); + }; + + background = ui.createBackground(); + + if (isImage) { + if (!this.hooks.insertImageDialog(linkEnteredCallback)) + ui.prompt(this.getString("imagedialog"), imageDefaultText, linkEnteredCallback); + } + else { + ui.prompt(this.getString("linkdialog"), linkDefaultText, linkEnteredCallback); + } + return true; + } + }; + + // When making a list, hitting shift-enter will put your cursor on the next line + // at the current indent level. + commandProto.doAutoindent = function (chunk, postProcessing) { + + var commandMgr = this, + fakeSelection = false; + + chunk.before = chunk.before.replace(/(\n|^)[ ]{0,3}([*+-]|\d+[.])[ \t]*\n$/, "\n\n"); + chunk.before = chunk.before.replace(/(\n|^)[ ]{0,3}>[ \t]*\n$/, "\n\n"); + chunk.before = chunk.before.replace(/(\n|^)[ \t]+\n$/, "\n\n"); + + // There's no selection, end the cursor wasn't at the end of the line: + // The user wants to split the current list item / code line / blockquote line + // (for the latter it doesn't really matter) in two. Temporarily select the + // (rest of the) line to achieve this. + if (!chunk.selection && !/^[ \t]*(?:\n|$)/.test(chunk.after)) { + chunk.after = chunk.after.replace(/^[^\n]*/, function (wholeMatch) { + chunk.selection = wholeMatch; + return ""; + }); + fakeSelection = true; + } + + if (/(\n|^)[ ]{0,3}([*+-]|\d+[.])[ \t]+.*\n$/.test(chunk.before)) { + if (commandMgr.doList) { + commandMgr.doList(chunk); + } + } + if (/(\n|^)[ ]{0,3}>[ \t]+.*\n$/.test(chunk.before)) { + if (commandMgr.doBlockquote) { + commandMgr.doBlockquote(chunk); + } + } + if (/(\n|^)(\t|[ ]{4,}).*\n$/.test(chunk.before)) { + if (commandMgr.doCode) { + commandMgr.doCode(chunk); + } + } + + if (fakeSelection) { + chunk.after = chunk.selection + chunk.after; + chunk.selection = ""; + } + }; + + commandProto.doBlockquote = function (chunk, postProcessing) { + + chunk.selection = chunk.selection.replace(/^(\n*)([^\r]+?)(\n*)$/, + function (totalMatch, newlinesBefore, text, newlinesAfter) { + chunk.before += newlinesBefore; + chunk.after = newlinesAfter + chunk.after; + return text; + }); + + chunk.before = chunk.before.replace(/(>[ \t]*)$/, + function (totalMatch, blankLine) { + chunk.selection = blankLine + chunk.selection; + return ""; + }); + + chunk.selection = chunk.selection.replace(/^(\s|>)+$/, ""); + chunk.selection = chunk.selection || this.getString("quoteexample"); + + // The original code uses a regular expression to find out how much of the + // text *directly before* the selection already was a blockquote: + + /* + if (chunk.before) { + chunk.before = chunk.before.replace(/\n?$/, "\n"); + } + chunk.before = chunk.before.replace(/(((\n|^)(\n[ \t]*)*>(.+\n)*.*)+(\n[ \t]*)*$)/, + function (totalMatch) { + chunk.startTag = totalMatch; + return ""; + }); + */ + + // This comes down to: + // Go backwards as many lines a possible, such that each line + // a) starts with ">", or + // b) is almost empty, except for whitespace, or + // c) is preceeded by an unbroken chain of non-empty lines + // leading up to a line that starts with ">" and at least one more character + // and in addition + // d) at least one line fulfills a) + // + // Since this is essentially a backwards-moving regex, it's susceptible to + // catstrophic backtracking and can cause the browser to hang; + // see e.g. http://meta.stackoverflow.com/questions/9807. + // + // Hence we replaced this by a simple state machine that just goes through the + // lines and checks for a), b), and c). + + var match = "", + leftOver = "", + line; + if (chunk.before) { + var lines = chunk.before.replace(/\n$/, "").split("\n"); + var inChain = false; + for (var i = 0; i < lines.length; i++) { + var good = false; + line = lines[i]; + inChain = inChain && line.length > 0; // c) any non-empty line continues the chain + if (/^>/.test(line)) { // a) + good = true; + if (!inChain && line.length > 1) // c) any line that starts with ">" and has at least one more character starts the chain + inChain = true; + } else if (/^[ \t]*$/.test(line)) { // b) + good = true; + } else { + good = inChain; // c) the line is not empty and does not start with ">", so it matches if and only if we're in the chain + } + if (good) { + match += line + "\n"; + } else { + leftOver += match + line; + match = "\n"; + } + } + if (!/(^|\n)>/.test(match)) { // d) + leftOver += match; + match = ""; + } + } + + chunk.startTag = match; + chunk.before = leftOver; + + // end of change + + if (chunk.after) { + chunk.after = chunk.after.replace(/^\n?/, "\n"); + } + + chunk.after = chunk.after.replace(/^(((\n|^)(\n[ \t]*)*>(.+\n)*.*)+(\n[ \t]*)*)/, + function (totalMatch) { + chunk.endTag = totalMatch; + return ""; + } + ); + + var replaceBlanksInTags = function (useBracket) { + + var replacement = useBracket ? "> " : ""; + + if (chunk.startTag) { + chunk.startTag = chunk.startTag.replace(/\n((>|\s)*)\n$/, + function (totalMatch, markdown) { + return "\n" + markdown.replace(/^[ ]{0,3}>?[ \t]*$/gm, replacement) + "\n"; + }); + } + if (chunk.endTag) { + chunk.endTag = chunk.endTag.replace(/^\n((>|\s)*)\n/, + function (totalMatch, markdown) { + return "\n" + markdown.replace(/^[ ]{0,3}>?[ \t]*$/gm, replacement) + "\n"; + }); + } + }; + + if (/^(?![ ]{0,3}>)/m.test(chunk.selection)) { + this.wrap(chunk, SETTINGS.lineLength - 2); + chunk.selection = chunk.selection.replace(/^/gm, "> "); + replaceBlanksInTags(true); + chunk.skipLines(); + } else { + chunk.selection = chunk.selection.replace(/^[ ]{0,3}> ?/gm, ""); + this.unwrap(chunk); + replaceBlanksInTags(false); + + if (!/^(\n|^)[ ]{0,3}>/.test(chunk.selection) && chunk.startTag) { + chunk.startTag = chunk.startTag.replace(/\n{0,2}$/, "\n\n"); + } + + if (!/(\n|^)[ ]{0,3}>.*$/.test(chunk.selection) && chunk.endTag) { + chunk.endTag = chunk.endTag.replace(/^\n{0,2}/, "\n\n"); + } + } + + chunk.selection = this.hooks.postBlockquoteCreation(chunk.selection); + + if (!/\n/.test(chunk.selection)) { + chunk.selection = chunk.selection.replace(/^(> *)/, + function (wholeMatch, blanks) { + chunk.startTag += blanks; + return ""; + }); + } + }; + + commandProto.doCode = function (chunk, postProcessing) { + + var hasTextBefore = /\S[ ]*$/.test(chunk.before); + var hasTextAfter = /^[ ]*\S/.test(chunk.after); + + // Use 'four space' markdown if the selection is on its own + // line or is multiline. + if ((!hasTextAfter && !hasTextBefore) || /\n/.test(chunk.selection)) { + + chunk.before = chunk.before.replace(/[ ]{4}$/, + function (totalMatch) { + chunk.selection = totalMatch + chunk.selection; + return ""; + }); + + var nLinesBack = 1; + var nLinesForward = 1; + + if (/(\n|^)(\t|[ ]{4,}).*\n$/.test(chunk.before)) { + nLinesBack = 0; + } + if (/^\n(\t|[ ]{4,})/.test(chunk.after)) { + nLinesForward = 0; + } + + chunk.skipLines(nLinesBack, nLinesForward); + + if (!chunk.selection) { + chunk.startTag = " "; + chunk.selection = this.getString("codeexample"); + } + else { + if (/^[ ]{0,3}\S/m.test(chunk.selection)) { + if (/\n/.test(chunk.selection)) + chunk.selection = chunk.selection.replace(/^/gm, " "); + else // if it's not multiline, do not select the four added spaces; this is more consistent with the doList behavior + chunk.before += " "; + } + else { + chunk.selection = chunk.selection.replace(/^(?:[ ]{4}|[ ]{0,3}\t)/gm, ""); + } + } + } + else { + // Use backticks (`) to delimit the code block. + + chunk.trimWhitespace(); + chunk.findTags(/`/, /`/); + + if (!chunk.startTag && !chunk.endTag) { + chunk.startTag = chunk.endTag = "`"; + if (!chunk.selection) { + chunk.selection = this.getString("codeexample"); + } + } + else if (chunk.endTag && !chunk.startTag) { + chunk.before += chunk.endTag; + chunk.endTag = ""; + } + else { + chunk.startTag = chunk.endTag = ""; + } + } + }; + + commandProto.doList = function (chunk, postProcessing, isNumberedList) { + + // These are identical except at the very beginning and end. + // Should probably use the regex extension function to make this clearer. + var previousItemsRegex = /(\n|^)(([ ]{0,3}([*+-]|\d+[.])[ \t]+.*)(\n.+|\n{2,}([*+-].*|\d+[.])[ \t]+.*|\n{2,}[ \t]+\S.*)*)\n*$/; + var nextItemsRegex = /^\n*(([ ]{0,3}([*+-]|\d+[.])[ \t]+.*)(\n.+|\n{2,}([*+-].*|\d+[.])[ \t]+.*|\n{2,}[ \t]+\S.*)*)\n*/; + + // The default bullet is a dash but others are possible. + // This has nothing to do with the particular HTML bullet, + // it's just a markdown bullet. + var bullet = "-"; + + // The number in a numbered list. + var num = 1; + + // Get the item prefix - e.g. " 1. " for a numbered list, " - " for a bulleted list. + var getItemPrefix = function () { + var prefix; + if (isNumberedList) { + prefix = " " + num + ". "; + num++; + } + else { + prefix = " " + bullet + " "; + } + return prefix; + }; + + // Fixes the prefixes of the other list items. + var getPrefixedItem = function (itemText) { + + // The numbering flag is unset when called by autoindent. + if (isNumberedList === undefined) { + isNumberedList = /^\s*\d/.test(itemText); + } + + // Renumber/bullet the list element. + itemText = itemText.replace(/^[ ]{0,3}([*+-]|\d+[.])\s/gm, + function (_) { + return getItemPrefix(); + }); + + return itemText; + }; + + chunk.findTags(/(\n|^)*[ ]{0,3}([*+-]|\d+[.])\s+/, null); + + if (chunk.before && !/\n$/.test(chunk.before) && !/^\n/.test(chunk.startTag)) { + chunk.before += chunk.startTag; + chunk.startTag = ""; + } + + if (chunk.startTag) { + + var hasDigits = /\d+[.]/.test(chunk.startTag); + chunk.startTag = ""; + chunk.selection = chunk.selection.replace(/\n[ ]{4}/g, "\n"); + this.unwrap(chunk); + chunk.skipLines(); + + if (hasDigits) { + // Have to renumber the bullet points if this is a numbered list. + chunk.after = chunk.after.replace(nextItemsRegex, getPrefixedItem); + } + if (isNumberedList == hasDigits) { + return; + } + } + + var nLinesUp = 1; + + chunk.before = chunk.before.replace(previousItemsRegex, + function (itemText) { + if (/^\s*([*+-])/.test(itemText)) { + bullet = re.$1; + } + nLinesUp = /[^\n]\n\n[^\n]/.test(itemText) ? 1 : 0; + return getPrefixedItem(itemText); + }); + + if (!chunk.selection) { + chunk.selection = this.getString("litem"); + } + + var prefix = getItemPrefix(); + + var nLinesDown = 1; + + chunk.after = chunk.after.replace(nextItemsRegex, + function (itemText) { + nLinesDown = /[^\n]\n\n[^\n]/.test(itemText) ? 1 : 0; + return getPrefixedItem(itemText); + }); + + chunk.trimWhitespace(true); + chunk.skipLines(nLinesUp, nLinesDown, true); + chunk.startTag = prefix; + var spaces = prefix.replace(/./g, " "); + this.wrap(chunk, SETTINGS.lineLength - spaces.length); + chunk.selection = chunk.selection.replace(/\n/g, "\n" + spaces); + + }; + + commandProto.doHeading = function (chunk, postProcessing) { + + // Remove leading/trailing whitespace and reduce internal spaces to single spaces. + chunk.selection = chunk.selection.replace(/\s+/g, " "); + chunk.selection = chunk.selection.replace(/(^\s+|\s+$)/g, ""); + + // If we clicked the button with no selected text, we just + // make a level 2 hash header around some default text. + if (!chunk.selection) { + chunk.startTag = "## "; + chunk.selection = this.getString("headingexample"); + chunk.endTag = " ##"; + return; + } + + var headerLevel = 0; // The existing header level of the selected text. + + // Remove any existing hash heading markdown and save the header level. + chunk.findTags(/#+[ ]*/, /[ ]*#+/); + if (/#+/.test(chunk.startTag)) { + headerLevel = re.lastMatch.length; + } + chunk.startTag = chunk.endTag = ""; + + // Try to get the current header level by looking for - and = in the line + // below the selection. + chunk.findTags(null, /\s?(-+|=+)/); + if (/=+/.test(chunk.endTag)) { + headerLevel = 1; + } + if (/-+/.test(chunk.endTag)) { + headerLevel = 2; + } + + // Skip to the next line so we can create the header markdown. + chunk.startTag = chunk.endTag = ""; + chunk.skipLines(1, 1); + + // We make a level 2 header if there is no current header. + // If there is a header level, we substract one from the header level. + // If it's already a level 1 header, it's removed. + var headerLevelToCreate = headerLevel == 0 ? 2 : headerLevel - 1; + + if (headerLevelToCreate > 0) { + + // The button only creates level 1 and 2 underline headers. + // Why not have it iterate over hash header levels? Wouldn't that be easier and cleaner? + var headerChar = headerLevelToCreate >= 2 ? "-" : "="; + var len = chunk.selection.length; + if (len > SETTINGS.lineLength) { + len = SETTINGS.lineLength; + } + chunk.endTag = "\n"; + while (len--) { + chunk.endTag += headerChar; + } + } + }; + + commandProto.doHorizontalRule = function (chunk, postProcessing) { + chunk.startTag = "----------\n"; + chunk.selection = ""; + chunk.skipLines(2, 1, true); + } + + +})(); +(function () { + var output, Converter; + if (typeof exports === "object" && typeof require === "function") { // we're in a CommonJS (e.g. Node.js) module + output = exports; + Converter = require("./Markdown.Converter").Converter; + } else { + output = window.Markdown; + Converter = output.Converter; + } + + output.getSanitizingConverter = function () { + var converter = new Converter(); + converter.hooks.chain("postConversion", sanitizeHtml); + converter.hooks.chain("postConversion", balanceTags); + return converter; + } + + function sanitizeHtml(html) { + return html.replace(/<[^>]*>?/gi, sanitizeTag); + } + + // (tags that can be opened/closed) | (tags that stand alone) + var basic_tag_whitelist = /^(<\/?(b|blockquote|code|del|dd|dl|dt|em|h1|h2|h3|i|kbd|li|ol|p|pre|s|sup|sub|strong|strike|ul)>|<(br|hr)\s?\/?>)$/i; + // <a href="url..." optional title>|</a> + var a_white = /^(<a\shref="((https?|ftp):\/\/|\/)[-A-Za-z0-9+&@#\/%?=~_|!:,.;\(\)]+"(\stitle="[^"<>]+")?\s?>|<\/a>)$/i; + + // <img src="url..." optional width optional height optional alt optional title + var img_white = /^(<img\ssrc="(https?:\/\/|\/)[-A-Za-z0-9+&@#\/%?=~_|!:,.;\(\)]+"(\swidth="\d{1,3}")?(\sheight="\d{1,3}")?(\salt="[^"<>]*")?(\stitle="[^"<>]*")?\s?\/?>)$/i; + + function sanitizeTag(tag) { + if (tag.match(basic_tag_whitelist) || tag.match(a_white) || tag.match(img_white)) + return tag; + else + return ""; + } + + /// <summary> + /// attempt to balance HTML tags in the html string + /// by removing any unmatched opening or closing tags + /// IMPORTANT: we *assume* HTML has *already* been + /// sanitized and is safe/sane before balancing! + /// + /// adapted from CODESNIPPET: A8591DBA-D1D3-11DE-947C-BA5556D89593 + /// </summary> + function balanceTags(html) { + + if (html == "") + return ""; + + var re = /<\/?\w+[^>]*(\s|$|>)/g; + // convert everything to lower case; this makes + // our case insensitive comparisons easier + var tags = html.toLowerCase().match(re); + + // no HTML tags present? nothing to do; exit now + var tagcount = (tags || []).length; + if (tagcount == 0) + return html; + + var tagname, tag; + var ignoredtags = "<p><img><br><li><hr>"; + var match; + var tagpaired = []; + var tagremove = []; + var needsRemoval = false; + + // loop through matched tags in forward order + for (var ctag = 0; ctag < tagcount; ctag++) { + tagname = tags[ctag].replace(/<\/?(\w+).*/, "$1"); + // skip any already paired tags + // and skip tags in our ignore list; assume they're self-closed + if (tagpaired[ctag] || ignoredtags.search("<" + tagname + ">") > -1) + continue; + + tag = tags[ctag]; + match = -1; + + if (!/^<\//.test(tag)) { + // this is an opening tag + // search forwards (next tags), look for closing tags + for (var ntag = ctag + 1; ntag < tagcount; ntag++) { + if (!tagpaired[ntag] && tags[ntag] == "</" + tagname + ">") { + match = ntag; + break; + } + } + } + + if (match == -1) + needsRemoval = tagremove[ctag] = true; // mark for removal + else + tagpaired[match] = true; // mark paired + } + + if (!needsRemoval) + return html; + + // delete all orphaned tags from the string + + var ctag = 0; + html = html.replace(re, function (match) { + var res = tagremove[ctag] ? "" : match; + ctag++; + return res; + }); + return html; + } +})(); + + + +$(document).ready(function() { + $wmd_input = $('.wmd-input'); + if ( $wmd_input.length > 0 ) { + + $wmd_input.each(function( index ) { + $this = $(this); + $this.attr('id', 'wmd-input-' + index); + $this.closest('.pagedown_text').find('.wmd-preview').attr('id', 'wmd-preview-' + index); + $this.closest('.wmd-panel').find('.wmd-button-bar').attr('id', 'wmd-button-bar-' + index); + converter = Markdown.getSanitizingConverter(); + options = {}; + editor = new Markdown.Editor(converter, "-" + index, options ); + editor.run(); + }); + } +}); +/* +Turbolinks 5.0.0 +Copyright © 2016 Basecamp, LLC + */ + +(function(){(function(){(function(){this.Turbolinks={supported:function(){return null!=window.history.pushState&&null!=window.requestAnimationFrame}(),visit:function(e,r){return t.controller.visit(e,r)},clearCache:function(){return t.controller.clearCache()}}}).call(this)}).call(this);var t=this.Turbolinks;(function(){(function(){var e,r;t.copyObject=function(t){var e,r,n;r={};for(e in t)n=t[e],r[e]=n;return r},t.closest=function(t,r){return e.call(t,r)},e=function(){var t,e;return t=document.documentElement,null!=(e=t.closest)?e:function(t){var e;for(e=this;e;){if(e.nodeType===Node.ELEMENT_NODE&&r.call(e,t))return e;e=e.parentNode}}}(),t.defer=function(t){return setTimeout(t,1)},t.dispatch=function(t,e){var r,n,o,i,s;return i=null!=e?e:{},s=i.target,r=i.cancelable,n=i.data,o=document.createEvent("Events"),o.initEvent(t,!0,r===!0),o.data=null!=n?n:{},(null!=s?s:document).dispatchEvent(o),o},t.match=function(t,e){return r.call(t,e)},r=function(){var t,e,r,n;return t=document.documentElement,null!=(e=null!=(r=null!=(n=t.matchesSelector)?n:t.webkitMatchesSelector)?r:t.msMatchesSelector)?e:t.mozMatchesSelector}(),t.uuid=function(){var t,e,r;for(r="",t=e=1;36>=e;t=++e)r+=9===t||14===t||19===t||24===t?"-":15===t?"4":20===t?(Math.floor(4*Math.random())+8).toString(16):Math.floor(15*Math.random()).toString(16);return r}}).call(this),function(){t.Location=function(){function t(t){var e,r;null==t&&(t=""),r=document.createElement("a"),r.href=t.toString(),this.absoluteURL=r.href,e=r.hash.length,2>e?this.requestURL=this.absoluteURL:(this.requestURL=this.absoluteURL.slice(0,-e),this.anchor=r.hash.slice(1))}var e,r,n,o;return t.wrap=function(t){return t instanceof this?t:new this(t)},t.prototype.getOrigin=function(){return this.absoluteURL.split("/",3).join("/")},t.prototype.getPath=function(){var t,e;return null!=(t=null!=(e=this.absoluteURL.match(/\/\/[^\/]*(\/[^?;]*)/))?e[1]:void 0)?t:"/"},t.prototype.getPathComponents=function(){return this.getPath().split("/").slice(1)},t.prototype.getLastPathComponent=function(){return this.getPathComponents().slice(-1)[0]},t.prototype.getExtension=function(){var t,e;return null!=(t=null!=(e=this.getLastPathComponent().match(/\.[^.]*$/))?e[0]:void 0)?t:""},t.prototype.isHTML=function(){return this.getExtension().match(/^(?:|\.(?:htm|html|xhtml))$/)},t.prototype.isPrefixedBy=function(t){var e;return e=r(t),this.isEqualTo(t)||o(this.absoluteURL,e)},t.prototype.isEqualTo=function(t){return this.absoluteURL===(null!=t?t.absoluteURL:void 0)},t.prototype.toCacheKey=function(){return this.requestURL},t.prototype.toJSON=function(){return this.absoluteURL},t.prototype.toString=function(){return this.absoluteURL},t.prototype.valueOf=function(){return this.absoluteURL},r=function(t){return e(t.getOrigin()+t.getPath())},e=function(t){return n(t,"/")?t:t+"/"},o=function(t,e){return t.slice(0,e.length)===e},n=function(t,e){return t.slice(-e.length)===e},t}()}.call(this),function(){var e=function(t,e){return function(){return t.apply(e,arguments)}};t.HttpRequest=function(){function r(r,n,o){this.delegate=r,this.requestCanceled=e(this.requestCanceled,this),this.requestTimedOut=e(this.requestTimedOut,this),this.requestFailed=e(this.requestFailed,this),this.requestLoaded=e(this.requestLoaded,this),this.requestProgressed=e(this.requestProgressed,this),this.url=t.Location.wrap(n).requestURL,this.referrer=t.Location.wrap(o).absoluteURL,this.createXHR()}return r.NETWORK_FAILURE=0,r.TIMEOUT_FAILURE=-1,r.timeout=60,r.prototype.send=function(){var t;return this.xhr&&!this.sent?(this.notifyApplicationBeforeRequestStart(),this.setProgress(0),this.xhr.send(),this.sent=!0,"function"==typeof(t=this.delegate).requestStarted?t.requestStarted():void 0):void 0},r.prototype.cancel=function(){return this.xhr&&this.sent?this.xhr.abort():void 0},r.prototype.requestProgressed=function(t){return t.lengthComputable?this.setProgress(t.loaded/t.total):void 0},r.prototype.requestLoaded=function(){return this.endRequest(function(t){return function(){var e;return 200<=(e=t.xhr.status)&&300>e?t.delegate.requestCompletedWithResponse(t.xhr.responseText,t.xhr.getResponseHeader("Turbolinks-Location")):(t.failed=!0,t.delegate.requestFailedWithStatusCode(t.xhr.status,t.xhr.responseText))}}(this))},r.prototype.requestFailed=function(){return this.endRequest(function(t){return function(){return t.failed=!0,t.delegate.requestFailedWithStatusCode(t.constructor.NETWORK_FAILURE)}}(this))},r.prototype.requestTimedOut=function(){return this.endRequest(function(t){return function(){return t.failed=!0,t.delegate.requestFailedWithStatusCode(t.constructor.TIMEOUT_FAILURE)}}(this))},r.prototype.requestCanceled=function(){return this.endRequest()},r.prototype.notifyApplicationBeforeRequestStart=function(){return t.dispatch("turbolinks:request-start",{data:{url:this.url,xhr:this.xhr}})},r.prototype.notifyApplicationAfterRequestEnd=function(){return t.dispatch("turbolinks:request-end",{data:{url:this.url,xhr:this.xhr}})},r.prototype.createXHR=function(){return this.xhr=new XMLHttpRequest,this.xhr.open("GET",this.url,!0),this.xhr.timeout=1e3*this.constructor.timeout,this.xhr.setRequestHeader("Accept","text/html, application/xhtml+xml"),this.xhr.setRequestHeader("Turbolinks-Referrer",this.referrer),this.xhr.onprogress=this.requestProgressed,this.xhr.onload=this.requestLoaded,this.xhr.onerror=this.requestFailed,this.xhr.ontimeout=this.requestTimedOut,this.xhr.onabort=this.requestCanceled},r.prototype.endRequest=function(t){return this.xhr?(this.notifyApplicationAfterRequestEnd(),null!=t&&t.call(this),this.destroy()):void 0},r.prototype.setProgress=function(t){var e;return this.progress=t,"function"==typeof(e=this.delegate).requestProgressed?e.requestProgressed(this.progress):void 0},r.prototype.destroy=function(){var t;return this.setProgress(1),"function"==typeof(t=this.delegate).requestFinished&&t.requestFinished(),this.delegate=null,this.xhr=null},r}()}.call(this),function(){var e=function(t,e){return function(){return t.apply(e,arguments)}};t.ProgressBar=function(){function t(){this.trickle=e(this.trickle,this),this.stylesheetElement=this.createStylesheetElement(),this.progressElement=this.createProgressElement()}var r;return r=300,t.defaultCSS=".turbolinks-progress-bar {\n position: fixed;\n display: block;\n top: 0;\n left: 0;\n height: 3px;\n background: #0076ff;\n z-index: 9999;\n transition: width "+r+"ms ease-out, opacity "+r/2+"ms "+r/2+"ms ease-in;\n transform: translate3d(0, 0, 0);\n}",t.prototype.show=function(){return this.visible?void 0:(this.visible=!0,this.installStylesheetElement(),this.installProgressElement(),this.startTrickling())},t.prototype.hide=function(){return this.visible&&!this.hiding?(this.hiding=!0,this.fadeProgressElement(function(t){return function(){return t.uninstallProgressElement(),t.stopTrickling(),t.visible=!1,t.hiding=!1}}(this))):void 0},t.prototype.setValue=function(t){return this.value=t,this.refresh()},t.prototype.installStylesheetElement=function(){return document.head.insertBefore(this.stylesheetElement,document.head.firstChild)},t.prototype.installProgressElement=function(){return this.progressElement.style.width=0,this.progressElement.style.opacity=1,document.documentElement.insertBefore(this.progressElement,document.body),this.refresh()},t.prototype.fadeProgressElement=function(t){return this.progressElement.style.opacity=0,setTimeout(t,1.5*r)},t.prototype.uninstallProgressElement=function(){return this.progressElement.parentNode?document.documentElement.removeChild(this.progressElement):void 0},t.prototype.startTrickling=function(){return null!=this.trickleInterval?this.trickleInterval:this.trickleInterval=setInterval(this.trickle,r)},t.prototype.stopTrickling=function(){return clearInterval(this.trickleInterval),this.trickleInterval=null},t.prototype.trickle=function(){return this.setValue(this.value+Math.random()/100)},t.prototype.refresh=function(){return requestAnimationFrame(function(t){return function(){return t.progressElement.style.width=10+90*t.value+"%"}}(this))},t.prototype.createStylesheetElement=function(){var t;return t=document.createElement("style"),t.type="text/css",t.textContent=this.constructor.defaultCSS,t},t.prototype.createProgressElement=function(){var t;return t=document.createElement("div"),t.className="turbolinks-progress-bar",t},t}()}.call(this),function(){var e=function(t,e){return function(){return t.apply(e,arguments)}};t.BrowserAdapter=function(){function r(r){this.controller=r,this.showProgressBar=e(this.showProgressBar,this),this.progressBar=new t.ProgressBar}var n,o,i,s;return s=t.HttpRequest,n=s.NETWORK_FAILURE,i=s.TIMEOUT_FAILURE,o=500,r.prototype.visitProposedToLocationWithAction=function(t,e){return this.controller.startVisitToLocationWithAction(t,e)},r.prototype.visitStarted=function(t){return t.issueRequest(),t.changeHistory(),t.loadCachedSnapshot()},r.prototype.visitRequestStarted=function(t){return this.progressBar.setValue(0),t.hasCachedSnapshot()||"restore"!==t.action?this.showProgressBarAfterDelay():this.showProgressBar()},r.prototype.visitRequestProgressed=function(t){return this.progressBar.setValue(t.progress)},r.prototype.visitRequestCompleted=function(t){return t.loadResponse()},r.prototype.visitRequestFailedWithStatusCode=function(t,e){switch(e){case n:case i:return this.reload();default:return t.loadResponse()}},r.prototype.visitRequestFinished=function(t){return this.hideProgressBar()},r.prototype.visitCompleted=function(t){return t.followRedirect()},r.prototype.pageInvalidated=function(){return this.reload()},r.prototype.showProgressBarAfterDelay=function(){return this.progressBarTimeout=setTimeout(this.showProgressBar,o)},r.prototype.showProgressBar=function(){return this.progressBar.show()},r.prototype.hideProgressBar=function(){return this.progressBar.hide(),clearTimeout(this.progressBarTimeout)},r.prototype.reload=function(){return window.location.reload()},r}()}.call(this),function(){var e,r=function(t,e){return function(){return t.apply(e,arguments)}};e=!1,addEventListener("load",function(){return t.defer(function(){return e=!0})},!1),t.History=function(){function n(t){this.delegate=t,this.onPopState=r(this.onPopState,this)}return n.prototype.start=function(){return this.started?void 0:(addEventListener("popstate",this.onPopState,!1),this.started=!0)},n.prototype.stop=function(){return this.started?(removeEventListener("popstate",this.onPopState,!1),this.started=!1):void 0},n.prototype.push=function(e,r){return e=t.Location.wrap(e),this.update("push",e,r)},n.prototype.replace=function(e,r){return e=t.Location.wrap(e),this.update("replace",e,r)},n.prototype.onPopState=function(e){var r,n,o,i;return this.shouldHandlePopState()&&(i=null!=(n=e.state)?n.turbolinks:void 0)?(r=t.Location.wrap(window.location),o=i.restorationIdentifier,this.delegate.historyPoppedToLocationWithRestorationIdentifier(r,o)):void 0},n.prototype.shouldHandlePopState=function(){return e===!0},n.prototype.update=function(t,e,r){var n;return n={turbolinks:{restorationIdentifier:r}},history[t+"State"](n,null,e)},n}()}.call(this),function(){t.Snapshot=function(){function e(t){var e,r;r=t.head,e=t.body,this.head=null!=r?r:document.createElement("head"),this.body=null!=e?e:document.createElement("body")}return e.wrap=function(t){return t instanceof this?t:this.fromHTML(t)},e.fromHTML=function(t){var e;return e=document.createElement("html"),e.innerHTML=t,this.fromElement(e)},e.fromElement=function(t){return new this({head:t.querySelector("head"),body:t.querySelector("body")})},e.prototype.clone=function(){return new e({head:this.head.cloneNode(!0),body:this.body.cloneNode(!0)})},e.prototype.getRootLocation=function(){var e,r;return r=null!=(e=this.getSetting("root"))?e:"/",new t.Location(r)},e.prototype.getCacheControlValue=function(){return this.getSetting("cache-control")},e.prototype.hasAnchor=function(t){try{return null!=this.body.querySelector("[id='"+t+"']")}catch(e){}},e.prototype.isPreviewable=function(){return"no-preview"!==this.getCacheControlValue()},e.prototype.isCacheable=function(){return"no-cache"!==this.getCacheControlValue()},e.prototype.getSetting=function(t){var e,r;return r=this.head.querySelectorAll("meta[name='turbolinks-"+t+"']"),e=r[r.length-1],null!=e?e.getAttribute("content"):void 0},e}()}.call(this),function(){var e=[].slice;t.Renderer=function(){function t(){}var r;return t.render=function(){var t,r,n,o;return n=arguments[0],r=arguments[1],t=3<=arguments.length?e.call(arguments,2):[],o=function(t,e,r){r.prototype=t.prototype;var n=new r,o=t.apply(n,e);return Object(o)===o?o:n}(this,t,function(){}),o.delegate=n,o.render(r),o},t.prototype.renderView=function(t){return this.delegate.viewWillRender(this.newBody),t(),this.delegate.viewRendered(this.newBody)},t.prototype.invalidateView=function(){return this.delegate.viewInvalidated()},t.prototype.createScriptElement=function(t){var e;return"false"===t.getAttribute("data-turbolinks-eval")?t:(e=document.createElement("script"),e.textContent=t.textContent,r(e,t),e)},r=function(t,e){var r,n,o,i,s,a,u;for(i=e.attributes,a=[],r=0,n=i.length;n>r;r++)s=i[r],o=s.name,u=s.value,a.push(t.setAttribute(o,u));return a},t}()}.call(this),function(){t.HeadDetails=function(){function t(t){var e,r,i,s,a,u,c;for(this.element=t,this.elements={},c=this.element.childNodes,s=0,u=c.length;u>s;s++)i=c[s],i.nodeType===Node.ELEMENT_NODE&&(a=i.outerHTML,r=null!=(e=this.elements)[a]?e[a]:e[a]={type:o(i),tracked:n(i),elements:[]},r.elements.push(i))}var e,r,n,o;return t.prototype.hasElementWithKey=function(t){return t in this.elements},t.prototype.getTrackedElementSignature=function(){var t,e;return function(){var r,n;r=this.elements,n=[];for(t in r)e=r[t].tracked,e&&n.push(t);return n}.call(this).join("")},t.prototype.getScriptElementsNotInDetails=function(t){return this.getElementsMatchingTypeNotInDetails("script",t)},t.prototype.getStylesheetElementsNotInDetails=function(t){return this.getElementsMatchingTypeNotInDetails("stylesheet",t)},t.prototype.getElementsMatchingTypeNotInDetails=function(t,e){var r,n,o,i,s,a;o=this.elements,s=[];for(n in o)i=o[n],a=i.type,r=i.elements,a!==t||e.hasElementWithKey(n)||s.push(r[0]);return s},t.prototype.getProvisionalElements=function(){var t,e,r,n,o,i,s;r=[],n=this.elements;for(e in n)o=n[e],s=o.type,i=o.tracked,t=o.elements,null!=s||i?t.length>1&&r.push.apply(r,t.slice(1)):r.push.apply(r,t);return r},o=function(t){return e(t)?"script":r(t)?"stylesheet":void 0},n=function(t){return"reload"===t.getAttribute("data-turbolinks-track")},e=function(t){var e;return e=t.tagName.toLowerCase(),"script"===e},r=function(t){var e;return e=t.tagName.toLowerCase(),"style"===e||"link"===e&&"stylesheet"===t.getAttribute("rel")},t}()}.call(this),function(){var e=function(t,e){function n(){this.constructor=t}for(var o in e)r.call(e,o)&&(t[o]=e[o]);return n.prototype=e.prototype,t.prototype=new n,t.__super__=e.prototype,t},r={}.hasOwnProperty;t.SnapshotRenderer=function(r){function n(e,r){this.currentSnapshot=e,this.newSnapshot=r,this.currentHeadDetails=new t.HeadDetails(this.currentSnapshot.head),this.newHeadDetails=new t.HeadDetails(this.newSnapshot.head),this.newBody=this.newSnapshot.body}return e(n,r),n.prototype.render=function(t){return this.trackedElementsAreIdentical()?(this.mergeHead(),this.renderView(function(e){return function(){return e.replaceBody(),e.focusFirstAutofocusableElement(),t()}}(this))):this.invalidateView()},n.prototype.mergeHead=function(){return this.copyNewHeadStylesheetElements(),this.copyNewHeadScriptElements(),this.removeCurrentHeadProvisionalElements(),this.copyNewHeadProvisionalElements()},n.prototype.replaceBody=function(){return this.activateBodyScriptElements(),this.importBodyPermanentElements(),this.assignNewBody()},n.prototype.trackedElementsAreIdentical=function(){return this.currentHeadDetails.getTrackedElementSignature()===this.newHeadDetails.getTrackedElementSignature()},n.prototype.copyNewHeadStylesheetElements=function(){var t,e,r,n,o;for(n=this.getNewHeadStylesheetElements(),o=[],e=0,r=n.length;r>e;e++)t=n[e],o.push(document.head.appendChild(t));return o},n.prototype.copyNewHeadScriptElements=function(){var t,e,r,n,o;for(n=this.getNewHeadScriptElements(),o=[],e=0,r=n.length;r>e;e++)t=n[e],o.push(document.head.appendChild(this.createScriptElement(t)));return o},n.prototype.removeCurrentHeadProvisionalElements=function(){var t,e,r,n,o;for(n=this.getCurrentHeadProvisionalElements(),o=[],e=0,r=n.length;r>e;e++)t=n[e],o.push(document.head.removeChild(t));return o},n.prototype.copyNewHeadProvisionalElements=function(){var t,e,r,n,o;for(n=this.getNewHeadProvisionalElements(),o=[],e=0,r=n.length;r>e;e++)t=n[e],o.push(document.head.appendChild(t));return o},n.prototype.importBodyPermanentElements=function(){var t,e,r,n,o,i;for(n=this.getNewBodyPermanentElements(),i=[],e=0,r=n.length;r>e;e++)o=n[e],(t=this.findCurrentBodyPermanentElement(o))?i.push(o.parentNode.replaceChild(t,o)):i.push(void 0);return i},n.prototype.activateBodyScriptElements=function(){var t,e,r,n,o,i;for(n=this.getNewBodyScriptElements(),i=[],e=0,r=n.length;r>e;e++)o=n[e],t=this.createScriptElement(o),i.push(o.parentNode.replaceChild(t,o));return i},n.prototype.assignNewBody=function(){return document.body=this.newBody},n.prototype.focusFirstAutofocusableElement=function(){var t;return null!=(t=this.findFirstAutofocusableElement())?t.focus():void 0},n.prototype.getNewHeadStylesheetElements=function(){return this.newHeadDetails.getStylesheetElementsNotInDetails(this.currentHeadDetails)},n.prototype.getNewHeadScriptElements=function(){return this.newHeadDetails.getScriptElementsNotInDetails(this.currentHeadDetails)},n.prototype.getCurrentHeadProvisionalElements=function(){return this.currentHeadDetails.getProvisionalElements()},n.prototype.getNewHeadProvisionalElements=function(){return this.newHeadDetails.getProvisionalElements()},n.prototype.getNewBodyPermanentElements=function(){return this.newBody.querySelectorAll("[id][data-turbolinks-permanent]")},n.prototype.findCurrentBodyPermanentElement=function(t){return document.body.querySelector("#"+t.id+"[data-turbolinks-permanent]")},n.prototype.getNewBodyScriptElements=function(){return this.newBody.querySelectorAll("script")},n.prototype.findFirstAutofocusableElement=function(){return document.body.querySelector("[autofocus]")},n}(t.Renderer)}.call(this),function(){var e=function(t,e){function n(){this.constructor=t}for(var o in e)r.call(e,o)&&(t[o]=e[o]);return n.prototype=e.prototype,t.prototype=new n,t.__super__=e.prototype,t},r={}.hasOwnProperty;t.ErrorRenderer=function(t){function r(t){this.html=t}return e(r,t),r.prototype.render=function(t){return this.renderView(function(e){return function(){return e.replaceDocumentHTML(),e.activateBodyScriptElements(),t()}}(this))},r.prototype.replaceDocumentHTML=function(){return document.documentElement.innerHTML=this.html},r.prototype.activateBodyScriptElements=function(){var t,e,r,n,o,i;for(n=this.getScriptElements(),i=[],e=0,r=n.length;r>e;e++)o=n[e],t=this.createScriptElement(o),i.push(o.parentNode.replaceChild(t,o));return i},r.prototype.getScriptElements=function(){return document.documentElement.querySelectorAll("script")},r}(t.Renderer)}.call(this),function(){t.View=function(){function e(t){this.delegate=t,this.element=document.documentElement}return e.prototype.getRootLocation=function(){return this.getSnapshot().getRootLocation()},e.prototype.getSnapshot=function(){return t.Snapshot.fromElement(this.element)},e.prototype.render=function(t,e){var r,n,o;return o=t.snapshot,r=t.error,n=t.isPreview,this.markAsPreview(n),null!=o?this.renderSnapshot(o,e):this.renderError(r,e)},e.prototype.markAsPreview=function(t){return t?this.element.setAttribute("data-turbolinks-preview",""):this.element.removeAttribute("data-turbolinks-preview")},e.prototype.renderSnapshot=function(e,r){return t.SnapshotRenderer.render(this.delegate,r,this.getSnapshot(),t.Snapshot.wrap(e))},e.prototype.renderError=function(e,r){return t.ErrorRenderer.render(this.delegate,r,e)},e}()}.call(this),function(){var e=function(t,e){return function(){return t.apply(e,arguments)}};t.ScrollManager=function(){function t(t){this.delegate=t,this.onScroll=e(this.onScroll,this)}return t.prototype.start=function(){return this.started?void 0:(addEventListener("scroll",this.onScroll,!1),this.onScroll(),this.started=!0)},t.prototype.stop=function(){return this.started?(removeEventListener("scroll",this.onScroll,!1),this.started=!1):void 0},t.prototype.scrollToElement=function(t){return t.scrollIntoView()},t.prototype.scrollToPosition=function(t){var e,r;return e=t.x,r=t.y,window.scrollTo(e,r)},t.prototype.onScroll=function(t){return this.updatePosition({x:window.pageXOffset,y:window.pageYOffset})},t.prototype.updatePosition=function(t){var e;return this.position=t,null!=(e=this.delegate)?e.scrollPositionChanged(this.position):void 0},t}()}.call(this),function(){t.SnapshotCache=function(){function e(t){this.size=t,this.keys=[],this.snapshots={}}var r;return e.prototype.has=function(t){var e;return e=r(t),e in this.snapshots},e.prototype.get=function(t){var e;if(this.has(t))return e=this.read(t),this.touch(t),e},e.prototype.put=function(t,e){return this.write(t,e),this.touch(t),e},e.prototype.read=function(t){var e;return e=r(t),this.snapshots[e]},e.prototype.write=function(t,e){var n;return n=r(t),this.snapshots[n]=e},e.prototype.touch=function(t){var e,n;return n=r(t),e=this.keys.indexOf(n),e>-1&&this.keys.splice(e,1),this.keys.unshift(n),this.trim()},e.prototype.trim=function(){var t,e,r,n,o;for(n=this.keys.splice(this.size),o=[],t=0,r=n.length;r>t;t++)e=n[t],o.push(delete this.snapshots[e]);return o},r=function(e){return t.Location.wrap(e).toCacheKey()},e}()}.call(this),function(){var e=function(t,e){return function(){return t.apply(e,arguments)}};t.Visit=function(){function r(r,n,o){this.controller=r,this.action=o,this.performScroll=e(this.performScroll,this),this.identifier=t.uuid(),this.location=t.Location.wrap(n),this.adapter=this.controller.adapter,this.state="initialized",this.timingMetrics={}}var n;return r.prototype.start=function(){return"initialized"===this.state?(this.recordTimingMetric("visitStart"),this.state="started",this.adapter.visitStarted(this)):void 0},r.prototype.cancel=function(){var t;return"started"===this.state?(null!=(t=this.request)&&t.cancel(),this.cancelRender(),this.state="canceled"):void 0},r.prototype.complete=function(){var t;return"started"===this.state?(this.recordTimingMetric("visitEnd"),this.state="completed","function"==typeof(t=this.adapter).visitCompleted&&t.visitCompleted(this),this.controller.visitCompleted(this)):void 0},r.prototype.fail=function(){var t;return"started"===this.state?(this.state="failed","function"==typeof(t=this.adapter).visitFailed?t.visitFailed(this):void 0):void 0},r.prototype.changeHistory=function(){var t,e;return this.historyChanged?void 0:(t=this.location.isEqualTo(this.referrer)?"replace":this.action,e=n(t),this.controller[e](this.location,this.restorationIdentifier),this.historyChanged=!0)},r.prototype.issueRequest=function(){return this.shouldIssueRequest()&&null==this.request?(this.progress=0,this.request=new t.HttpRequest(this,this.location,this.referrer),this.request.send()):void 0},r.prototype.getCachedSnapshot=function(){var t;return!(t=this.controller.getCachedSnapshotForLocation(this.location))||null!=this.location.anchor&&!t.hasAnchor(this.location.anchor)||"restore"!==this.action&&!t.isPreviewable()?void 0:t},r.prototype.hasCachedSnapshot=function(){return null!=this.getCachedSnapshot()},r.prototype.loadCachedSnapshot=function(){var t,e;return(e=this.getCachedSnapshot())?(t=this.shouldIssueRequest(),this.render(function(){var r;return this.cacheSnapshot(),this.controller.render({snapshot:e,isPreview:t},this.performScroll),"function"==typeof(r=this.adapter).visitRendered&&r.visitRendered(this),t?void 0:this.complete()})):void 0},r.prototype.loadResponse=function(){return null!=this.response?this.render(function(){var t,e;return this.cacheSnapshot(),this.request.failed?(this.controller.render({error:this.response},this.performScroll),"function"==typeof(t=this.adapter).visitRendered&&t.visitRendered(this),this.fail()):(this.controller.render({snapshot:this.response},this.performScroll),"function"==typeof(e=this.adapter).visitRendered&&e.visitRendered(this),this.complete())}):void 0},r.prototype.followRedirect=function(){return this.redirectedToLocation&&!this.followedRedirect?(this.location=this.redirectedToLocation,this.controller.replaceHistoryWithLocationAndRestorationIdentifier(this.redirectedToLocation,this.restorationIdentifier),this.followedRedirect=!0):void 0},r.prototype.requestStarted=function(){var t;return this.recordTimingMetric("requestStart"),"function"==typeof(t=this.adapter).visitRequestStarted?t.visitRequestStarted(this):void 0},r.prototype.requestProgressed=function(t){var e;return this.progress=t,"function"==typeof(e=this.adapter).visitRequestProgressed?e.visitRequestProgressed(this):void 0},r.prototype.requestCompletedWithResponse=function(e,r){return this.response=e,null!=r&&(this.redirectedToLocation=t.Location.wrap(r)),this.adapter.visitRequestCompleted(this)},r.prototype.requestFailedWithStatusCode=function(t,e){return this.response=e,this.adapter.visitRequestFailedWithStatusCode(this,t)},r.prototype.requestFinished=function(){var t;return this.recordTimingMetric("requestEnd"),"function"==typeof(t=this.adapter).visitRequestFinished?t.visitRequestFinished(this):void 0},r.prototype.performScroll=function(){return this.scrolled?void 0:("restore"===this.action?this.scrollToRestoredPosition()||this.scrollToTop():this.scrollToAnchor()||this.scrollToTop(),this.scrolled=!0)},r.prototype.scrollToRestoredPosition=function(){var t,e;return t=null!=(e=this.restorationData)?e.scrollPosition:void 0,null!=t?(this.controller.scrollToPosition(t),!0):void 0},r.prototype.scrollToAnchor=function(){return null!=this.location.anchor?(this.controller.scrollToAnchor(this.location.anchor),!0):void 0},r.prototype.scrollToTop=function(){return this.controller.scrollToPosition({x:0,y:0})},r.prototype.recordTimingMetric=function(t){var e;return null!=(e=this.timingMetrics)[t]?e[t]:e[t]=(new Date).getTime()},r.prototype.getTimingMetrics=function(){return t.copyObject(this.timingMetrics)},n=function(t){switch(t){case"replace":return"replaceHistoryWithLocationAndRestorationIdentifier";case"advance":case"restore":return"pushHistoryWithLocationAndRestorationIdentifier"}},r.prototype.shouldIssueRequest=function(){return"restore"===this.action?!this.hasCachedSnapshot():!0},r.prototype.cacheSnapshot=function(){return this.snapshotCached?void 0:(this.controller.cacheSnapshot(),this.snapshotCached=!0)},r.prototype.render=function(t){return this.cancelRender(),this.frame=requestAnimationFrame(function(e){return function(){return e.frame=null,t.call(e)}}(this))},r.prototype.cancelRender=function(){return this.frame?cancelAnimationFrame(this.frame):void 0},r}()}.call(this),function(){var e=function(t,e){return function(){return t.apply(e,arguments)}};t.Controller=function(){function r(){this.clickBubbled=e(this.clickBubbled,this),this.clickCaptured=e(this.clickCaptured,this),this.pageLoaded=e(this.pageLoaded,this),this.history=new t.History(this),this.view=new t.View(this),this.scrollManager=new t.ScrollManager(this),this.restorationData={},this.clearCache()}return r.prototype.start=function(){return t.supported&&!this.started?(addEventListener("click",this.clickCaptured,!0),addEventListener("DOMContentLoaded",this.pageLoaded,!1),this.scrollManager.start(),this.startHistory(),this.started=!0,this.enabled=!0):void 0},r.prototype.disable=function(){return this.enabled=!1},r.prototype.stop=function(){return this.started?(removeEventListener("click",this.clickCaptured,!0),removeEventListener("DOMContentLoaded",this.pageLoaded,!1),this.scrollManager.stop(),this.stopHistory(),this.started=!1):void 0},r.prototype.clearCache=function(){return this.cache=new t.SnapshotCache(10)},r.prototype.visit=function(e,r){var n,o;return null==r&&(r={}),e=t.Location.wrap(e),this.applicationAllowsVisitingLocation(e)?this.locationIsVisitable(e)?(n=null!=(o=r.action)?o:"advance",this.adapter.visitProposedToLocationWithAction(e,n)):window.location=e:void 0},r.prototype.startVisitToLocationWithAction=function(e,r,n){var o;return t.supported?(o=this.getRestorationDataForIdentifier(n),this.startVisit(e,r,{restorationData:o})):window.location=e},r.prototype.startHistory=function(){return this.location=t.Location.wrap(window.location),this.restorationIdentifier=t.uuid(),this.history.start(),this.history.replace(this.location,this.restorationIdentifier)},r.prototype.stopHistory=function(){return this.history.stop()},r.prototype.pushHistoryWithLocationAndRestorationIdentifier=function(e,r){return this.restorationIdentifier=r,this.location=t.Location.wrap(e),this.history.push(this.location,this.restorationIdentifier)},r.prototype.replaceHistoryWithLocationAndRestorationIdentifier=function(e,r){return this.restorationIdentifier=r,this.location=t.Location.wrap(e),this.history.replace(this.location,this.restorationIdentifier)},r.prototype.historyPoppedToLocationWithRestorationIdentifier=function(e,r){var n;return this.restorationIdentifier=r,this.enabled?(n=this.getRestorationDataForIdentifier(this.restorationIdentifier),this.startVisit(e,"restore",{restorationIdentifier:this.restorationIdentifier,restorationData:n,historyChanged:!0}),this.location=t.Location.wrap(e)):this.adapter.pageInvalidated()},r.prototype.getCachedSnapshotForLocation=function(t){var e;return e=this.cache.get(t),e?e.clone():void 0},r.prototype.shouldCacheSnapshot=function(){return this.view.getSnapshot().isCacheable()},r.prototype.cacheSnapshot=function(){var t;return this.shouldCacheSnapshot()?(this.notifyApplicationBeforeCachingSnapshot(),t=this.view.getSnapshot(),this.cache.put(this.lastRenderedLocation,t.clone())):void 0},r.prototype.scrollToAnchor=function(t){var e;return(e=document.getElementById(t))?this.scrollToElement(e):this.scrollToPosition({x:0,y:0})},r.prototype.scrollToElement=function(t){return this.scrollManager.scrollToElement(t)},r.prototype.scrollToPosition=function(t){return this.scrollManager.scrollToPosition(t)},r.prototype.scrollPositionChanged=function(t){var e;return e=this.getCurrentRestorationData(),e.scrollPosition=t},r.prototype.render=function(t,e){return this.view.render(t,e)},r.prototype.viewInvalidated=function(){return this.adapter.pageInvalidated()},r.prototype.viewWillRender=function(t){return this.notifyApplicationBeforeRender(t)},r.prototype.viewRendered=function(){return this.lastRenderedLocation=this.currentVisit.location,this.notifyApplicationAfterRender()},r.prototype.pageLoaded=function(){return this.lastRenderedLocation=this.location,this.notifyApplicationAfterPageLoad()},r.prototype.clickCaptured=function(){return removeEventListener("click",this.clickBubbled,!1),addEventListener("click",this.clickBubbled,!1)},r.prototype.clickBubbled=function(t){var e,r,n;return this.enabled&&this.clickEventIsSignificant(t)&&(r=this.getVisitableLinkForNode(t.target))&&(n=this.getVisitableLocationForLink(r))&&this.applicationAllowsFollowingLinkToLocation(r,n)?(t.preventDefault(),e=this.getActionForLink(r),this.visit(n,{action:e})):void 0},r.prototype.applicationAllowsFollowingLinkToLocation=function(t,e){var r;return r=this.notifyApplicationAfterClickingLinkToLocation(t,e),!r.defaultPrevented},r.prototype.applicationAllowsVisitingLocation=function(t){var e;return e=this.notifyApplicationBeforeVisitingLocation(t),!e.defaultPrevented},r.prototype.notifyApplicationAfterClickingLinkToLocation=function(e,r){return t.dispatch("turbolinks:click",{target:e,data:{url:r.absoluteURL},cancelable:!0})},r.prototype.notifyApplicationBeforeVisitingLocation=function(e){return t.dispatch("turbolinks:before-visit",{data:{url:e.absoluteURL},cancelable:!0})},r.prototype.notifyApplicationAfterVisitingLocation=function(e){return t.dispatch("turbolinks:visit",{data:{url:e.absoluteURL}})},r.prototype.notifyApplicationBeforeCachingSnapshot=function(){return t.dispatch("turbolinks:before-cache")},r.prototype.notifyApplicationBeforeRender=function(e){return t.dispatch("turbolinks:before-render",{data:{newBody:e}})},r.prototype.notifyApplicationAfterRender=function(){return t.dispatch("turbolinks:render")},r.prototype.notifyApplicationAfterPageLoad=function(e){return null==e&&(e={}),t.dispatch("turbolinks:load",{data:{url:this.location.absoluteURL,timing:e}})},r.prototype.startVisit=function(t,e,r){var n;return null!=(n=this.currentVisit)&&n.cancel(),this.currentVisit=this.createVisit(t,e,r),this.currentVisit.start(),this.notifyApplicationAfterVisitingLocation(t)},r.prototype.createVisit=function(e,r,n){ +var o,i,s,a,u;return i=null!=n?n:{},a=i.restorationIdentifier,s=i.restorationData,o=i.historyChanged,u=new t.Visit(this,e,r),u.restorationIdentifier=null!=a?a:t.uuid(),u.restorationData=t.copyObject(s),u.historyChanged=o,u.referrer=this.location,u},r.prototype.visitCompleted=function(t){return this.notifyApplicationAfterPageLoad(t.getTimingMetrics())},r.prototype.clickEventIsSignificant=function(t){return!(t.defaultPrevented||t.target.isContentEditable||t.which>1||t.altKey||t.ctrlKey||t.metaKey||t.shiftKey)},r.prototype.getVisitableLinkForNode=function(e){return this.nodeIsVisitable(e)?t.closest(e,"a[href]:not([target])"):void 0},r.prototype.getVisitableLocationForLink=function(e){var r;return r=new t.Location(e.getAttribute("href")),this.locationIsVisitable(r)?r:void 0},r.prototype.getActionForLink=function(t){var e;return null!=(e=t.getAttribute("data-turbolinks-action"))?e:"advance"},r.prototype.nodeIsVisitable=function(e){var r;return(r=t.closest(e,"[data-turbolinks]"))?"false"!==r.getAttribute("data-turbolinks"):!0},r.prototype.locationIsVisitable=function(t){return t.isPrefixedBy(this.view.getRootLocation())&&t.isHTML()},r.prototype.getCurrentRestorationData=function(){return this.getRestorationDataForIdentifier(this.restorationIdentifier)},r.prototype.getRestorationDataForIdentifier=function(t){var e;return null!=(e=this.restorationData)[t]?e[t]:e[t]={}},r}()}.call(this),function(){var e,r,n;t.start=function(){return r()?(null==t.controller&&(t.controller=e()),t.controller.start()):void 0},r=function(){return null==window.Turbolinks&&(window.Turbolinks=t),n()},e=function(){var e;return e=new t.Controller,e.adapter=new t.BrowserAdapter(e),e},n=function(){return window.Turbolinks===t},n()&&t.start()}.call(this)}).call(this),"object"==typeof module&&module.exports?module.exports=t:"function"==typeof define&&define.amd&&define(t)}).call(this); +(function() { + $(document).on('turbolinks:load', function() {}); + +}).call(this); +(function() { + + +}).call(this); diff --git a/public/assets/active_admin-716bc3a1c121d8ebdfc555d143e5f535aff487ef907952790491e39e34688a2f.js.gz b/public/assets/active_admin-716bc3a1c121d8ebdfc555d143e5f535aff487ef907952790491e39e34688a2f.js.gz new file mode 100644 index 0000000000000000000000000000000000000000..e3422f2dc5587858eb8a0ee0b5e5ec9cca4ea99f GIT binary patch literal 203169 zcmV(tK<vLCiwFRXeAQP11I)c^W7|fuDEL|Y6%d^>1}&0$*iLN9vevPk8PCSCCw3-h zS5hVr2}!U?fB{I$nn?58x1QbA04T{bIcM+Ob7Kl<^rO1Ey56;UZ@m-Ui$45qnU)vP zUz1PCyK$M#7t#0GahbrQPus)o?csfFbhcQ`N1K};e#5rIaWUJ3r}*MkKAtWoX%)T8 z{`t>oI{Z+X<`q5rP}vWj7xRlUJ3U)OJ6l^1`|#iG2ReuEie)}Y7Fm(^vEyNs<ddja zoTX(nF7id09WNI}NhAE2PSd1HClP!Buc1x!`qlernvK)EN}E$I%F|8%65qc_7U>9w ze>m8BFxYwYe*5du_T&E-UTt<do%m##k8vh(bUH1LlW9LXNyaexMbwLa?{wC(lPHcB z7xT0@iDt!QIZdOzy}hVg9Dhj1i*EF%KZS3H>F0S-E~>B<_O-UQxd}@z0W`B&k^l7_ zEnEK>OtX(^l;)qZvdCv?4n3R$K+-6Q=4CO5wV!ACq&SbV3Lc~twCHn}>F0F3T%-gW zojdk?nl1$3e(0e8#aXh5CPkDNizv%+uzWGSh~`CA!A2)K;CZ$<gTE%lc!}R}XK}S0 z!_zAIp_m{x^!gDlyu$hNpo3ZRG0RW=l&TtpxTE)Hu%KiNJGNNDPF1vwJcS)UDR{rf zWlFdb0gRIf{+P<lWckC>Ve}~}6}k4H$#2W7Oye%&M7I}n``#{p@h$~mW#f+kpF7(R z9zJ+XL(K{Rc9x$M(5SwZf*V7HL9`Ez)?{TKa~9<?g{>aZONUqIvioa{OY7&p8-201 zI4c3td3qkbEX$&dqpqw**0Op#0JnCjk1P6bnJ$)P9=WNV%j+xn?^TpeVS{kU+SIAh zRi^{Md7D(Y2e2tHTaR*xBa`$b%VA?K(naSg7Oa;h>xk`mMyW|R+SeB&>I_bmhX=jr zLzjP+!SSHM(9e_nE+Hfhf1Hk!B}}(UKcywKO6GHz6OkcAt7q@t4u5$09$=n~Q~VlH zrCKE8kI|<riIVb^zymZXnNHJ^|4Hd!d<OtMDLzM&EX7sg#}~yCdb)@f1$P+XhAdCd zU`;p$AW3+Nv5#ncmSlM~jN&`n_wV0-*u&4?E$4_SBiHrzqYZf8=^$QCfP^j5$*Tz> z(!tR#Kdq2T!2|zxNRQ+-(7`dB&fq;ilLqr;br!zHC-M>?oPK_D626y*I=~b*dIvWV zTK#?{PZz~ISSx^c&omh7Q)zUTRBz7nun9kVOO$GHp=)HY=m7Mvvj*E);c*6p;ftr+ z2RaK-d_l+qxIHZZ(g1?_1)h1OVeWi;RH|Tgh{%1qH`31wPiWr*I>;AHgd?IeKxC#s z<322_1z}8<XAArows?s>MR(KuEXl{|<SzH~1Ck<YmFZNlCqk!56jMj=8!$b^lZzO1 z%;*Ckf=`&Z(&ahnb=(2Pqt3kzPx2x5-?|z+mI57zW6$zQS!9zZ4~E-teZGA1m|nk5 z;QFYRK*P>q_%fSC-@bWG=>EgE@7{LSN_w^zZT@m_SRF3Ed->gWho7Hq9c^6J{{Cw7 zR7QNAEXHSWL?%gf25YStGmut}lUX{={t16V$Fu4!Abs|kIv>oc!6sZxC4Tg5IzLPB z@gP1poFs#P9`!a)GwJ;&yw#5{6bjVk^8_ythVC&QWq@Xx&Zlr9V*uWXZ)C9m8uueW z^95Xzy#E4Zeg^3K(;Uzezl#Z?fQt_H(3AXzYj#oSf#@g>jh7|fi;-fjLrB<W1P9QE z3E(E(G$U<=OEgF|l23Fe7YQ5+rsH{(&gP2?xA&bj{WXfZdN6PvKv|RJbOCG1PvJwl z3mf>o)mh{Bqi74iT@=sCGJ$zHU<L3Yf<u%sW}0j9?awKnkRM<)m=fJrSx%2;gcuX| zxPqo{ehj`kKP#r~4HLY}#=zC(K%`-Eoi$)o%nYM^ISaQDAFS`eKR|u=J9wMHKtJ+3 zcaRI996HQNS<Lu8NReGx<3686TW~GmIuGdY4f;J4fF8+B#qW;j8V`p;;*XumD0msw zSF*NtElA(v8P(Rfg{~_+r$o_#&cN9({B1@b#taF>H)fB{+dvB^1p9c0pILxnlS<fG z?CslSHl4uKJq>E>4ca0NhmrjenWg1v$_pDB{Em_P<3V<1jAxSxZwrhh_!+J%iU|>b zav<M1PK7qYDNH}T;Scs`pj~;PG;z-jkALcTvPS})>BRuZ)U2@}K`8jg?8-~wpA%1Z zkj5d~aj^>Xp}QgP%>M(N!x;9o!g~UnIL^bJaJSv?3OFGUZiK<AsEZ<p3kk^x3<BgT z#|vr*;7F74ncYU6U7z|1kBICKei94ARd22<o+b0PUc>$f#15HaxBtmJuCsFpp?;Jp zFDo5rw{jGu5u*vSq*pyRB|0>#h*W(le8PYmoL=ZsJ;-~0ohMmYEw1e}{VfKP;64Cm z=H~W;ZT~^~n+2po01pk&6va~}FDR<5eSl{h8PFYU%+v@Qj${%mVIMu+gC-zoet@s= zi~Z<;Y1M}#qFV<?W>Wd&dPw^7b$Qu5$w*`^$wHw~(GroAu$58&+w?5?1ndC`u7Kur z)!YRsFI}7!lRj}i{LWDsdNX7)H6nrsfT@V9v3xK*z~^&D3;Tv1b<710Bmh?IDHJeM z?okK@Vo1wzpZLmG70s6afT;ps(T|Ebw#K6~h1&$T3@++ZqJIv<4z`XEZogmQ>kQs( z;}5w*OgpphlQf;<Y!VQ@b{VRF0eU}0z|cElbgK;IUl>1BIp_>fygDulylhmPApLR+ zrGwSSY))iI8q>{!e{-|;H32%xst^scjSZFt%}mG0bDf_7?#buKOe;qSC{h);xA;el z>VxcfimbI?Uaxgk>orBnx@=-reWzQ;Eqk(LH+Pz;Oi}h*dGiG@P$$TF6J15NKo?4? z6OdStVWZh(1XtO-+6a2}WP^bWg_lAc?b6xhZ{YXFh8H>B;D8g>Pe6xxkq_`VZ91_y z`jkwUDJni__*f9Gu@^nZ?g&w(TZ&dmTZ@~)U?WWf%?nW&L9TtOY5`E*A;|%^I%0(Z zq1~Q-;NQ_p)C2&fK&a(-6AoZ-+}>$X%)KtdU?=tF^ci?NXZbQ!)r9u>BV4s5%pP?M z>0J<3kfXqUfyc+m)1oTGD7rK&KNO)7;0TQa|GGOVtKQ<bOw(dQHpJ!F9CJ?|GJe3# z5UbpbX%PF3d$ShyB<EOOA*Fza2xTPD;VAI52gDj*j#%=ikBlDXx<2f(f}Z%8dbqNf z3Y!$oicf$UWd<MxEEH%8Jww!)iMA=g1`i!RNepYHg0it5EnXC;r8%aP4_nrP+-`*q zrgYMMORx5-PXrqqbr$~T${lpW<IRdmc9NwNcMSB36Jpr7A!3&3e#$eD)R?~mUa6*I z0BS+K&y&*>Zqm<lAb!P2b#Yy~xm6C_K=Jr&SYneI+%UbN3aZiO;R}$VL41pPa*IBz zDmdOoeNd*!<budVv1Iv$pRnQ)$W!$r{yid<B3<jKT(IoMtU6VaRo5NTE4{;WIItl@ z;1mj|22HC4(5Gy%IW9`n;}U2l=_1Ld6)B-o7CSsi=F9(G2Cp12wukro(Tg{)<%VZ@ zM#oeRVVaf;`ZfWEA5ciNL+NCQ0xqgLMRhqPHY0lVGK%l)JpTGoZ-@ZV@huQw_gnd3 zyk=r}+2e~-Kj<n@<baNtXVLSDWaEqbCOTz0{+YC!?UUTR7k#MUmRv;XZ}|U4ve<i@ zeiUr2)E}q;{t3gtKSS1=`jLJBlq$3FilH_Ei-FR9H!YGy^h5GPg>o&nAHZF{kb&W@ z&K4Omam4stBDP)9tIKY;$K4EvLzGx%Sw(yx@Q*;CfwjQv0PeThG0+`m1c1`On2T(@ zoF*k)g=gt!*!l%(Z()G$)@SHSd##qosAwg<KA_wfHL>{#>cLPc3xXm{nOi0kx_Gt$ z8_SYzhbeFvcxYiN<Baf+1b(yL_|Epj?X4}NZ(FaCW&ssmB=~D!zSege(RPnmZx8a9 zsH<U;+zxhRGLe`e4XfSDuFaZ7^j)TKj((MNXUcHq23S4Z$Miy(zt^Y?IVNVDzZ#0b zFRFBa*{hd*R1m_@MTG1-f*K@RRJ9@DBg4{|T9WC-C`RX^+m$}OzLCsGc=+=I4TN~~ zMfb1Q`Gl^FIa?M;uii&B(0MwYDlfE-i-PmlIAj5j2o3Ng;6U$DQRhF<gQw7032G#m zK!cU7`T>L#)YP`EG@1!K-#A{2=899W?f>*Ay0O+-2hI{Nw1FGIwCeU&wX=PBB_w<e z2%vwxIq7;{rM@V>CV@v^z>Nm7w&5CIy?oSv9Q~Y;>I$!k^z%3s4iU}`Q1=D$U1tR> zRCnvn<42FbSqVI=iDu=q5fkXJv#k!<5i%;mvx$Nf&-QV8f|fP}x_>%UJdjIa2(Q0K zIwectvjnJKJ4!l73(|;Sk8OJ%Ix_V)!Kio>MJdt61ZPPqgDJ>^a5&&xRCCnnEazfp zh54b1fJ6$o!eNGeJS40btaS=6hn@Cm(^O>I_+~F)jR2!puZ740qC-11P~^l5!%7e4 zX4wF)q)u{JB;)VGvsQoQ?oqaXdh^eLGaNar?y*Sex+9~g@6hVskZ~l_FG!T^nLwIV zF-?l1kDC5mlpm84y$33if+mQ>064rMDl{hiHJe2*%B&g}NLt_v@eVjokEg|HHT;l# zN``s5*u+0KC(?2=DaU7U4Q}piZ9U$^|9iBV!mI|^oToJ4*$mul_-~xM-Hb`HNbGLV z-=3*Q8;on@PwCGosaDXCFRmHL{*cxMq^p;o=TkT_W!RWR`y#)X70b#^fDjkSu_{Zm z%G=8EW5Dw>a-&Fc$BpJ{wPaN}w;!6x1Z<I6;o2IvJ&3vpt!{KANUIiJZp()->c!^o zE5H5EiyUahLaj`AAE}jRm(`-MuXGtze7R6B%qX)0^>sEbi>f$TASZDO1ReS~Th2%i zl9j-u!fcSLlaVUE^Z4O6JHQ#ZQSAPSMkBP6Fk(CQ-Wj}rM9->0*RuZJ?A4EqwaReg zlk^98JZdOViBAZ|#pgr)0FfwoFkBSh7w2l#qVt(I9-C7}O5lw7d!x_;Nrx0AO?5L- zo>rYRavdb>kyaCxU|aOdX~FPPGkVX=$<Fc%<pCjF#JbQ?F$0KprY4AAuYXy?dBL1e zh*aIPD2ZVpQmc4PxDol~qdgJqjo5z-BH2eLX?vN}O7A?UtbQx~Z%svwEqGOpGj?98 z7JXLNssGFjFZVII8AZYc;$C;crTjr4cej=-GwZuQ{{I2||Kx;}vG5n{E$#Jq57@J2 zTo?3KCR3L)dctU3xkIJ(2I&_J<-tB#>0l-S{QPpdxc=bJfRnGAiBbL5cVGKs&(=VF z4i|%Hwd4esb;YH{Dn9k1(1NyB{TA96VU)foh?rr(o{0ltS}gp>+S&oVK@$l4OON!n zF{pxO20;Vtm_Dg-hE2O*mN!7cbeaHDv-N}^2$n96I5l=v9?Pt#OJ_#gbtij`%}DTC zsOhfK+br65CL~fr&63YCP+_tTZP4^a@ZS;2uASyN4i7QnDq0QD39qU|tyhse+|a_( zfx|_@bp-$LF~Xf;yPlpHUFPoU!!p=*21(p>3ut1)feBB6i<va6Y8(8#ZdluLml1vL zAO=s*&oYorVrM>6nF8A#5GYXf$lV@9AMo!R#2wFvBB@=F5#%INR|3{vAP+}At>>8n zlJsCIX2s~Z*eCzV@3U%A^%RG2itB8b(5dPQWR4$>Rwz_&T9V%d3nWCSU9&axPIu=N zC``kdz%m9Ivu}Qz^wleTQ8AM+6IUX1fLp~iP|tQ-wIg7F*&Se=$5M62p9|-v$A)*Z z=#kl{N<OKx1jwH=@iisZSkw?H()$c}NjMt1y3UO^UTtkSCw(NK(Q8HyGONIAU*YD} z7N<KXfFk>^?QsRglI9_wcLTM*emn8|Te5kL4O_wJiEBt-WKs2kyk-v<Ws+CZgbo(z z=|vw!dl|7C32^qP^A1gFH3sG;{-w?>)b>!IAzXrC5^A@cc&^Zvaf9A&lS?y8W#1AM z>&4>0M4?~f$qbX@eR%#C=k4eI9c;z|RUP>SK)pg`iMtxq<Ac0YmC=P`PRxR3MxLoi z|L31xy@2*h#81Lhp@~3kmf2*4Hg)zefO|4ZymSj2pQvc7=6Z7HB(*dBqTvy3V5WK= z#3J8Wo0rAs;7UKq>z<>C^z5cXjR6&BbAP=HJK|iCEK4FVh4y#{<p-`6Q(o`Bbdu8p zay_KpJ(&Nt%*G#8A6uXuCM{>^6PukF!#nPJay(7@>Xn4tzf!o2b*$&8O+g(g*@W2X z=sX3<9Cn|4=49909pW@_Ek<~lazmx+J`AqPY_^<|D(x7y4xW*evlloTx((?^JB)7x z>4v|Czm9T6DutmquCNd#Zqaf3AT)1QIVj0_CoYPJYe-m@Y!f^q6=oT!lNt)$sH;+I zs=O!VAo>g^IjV-s6m6~(UB!?(#XYY7@~Ue56J0F)(V<Vhir{>e1J6cGBo8B6;$CpH zq-%A!7KeRtDvO?@!WA)qV{BkJW<lUgBXK2SO5GSO=7LtqYsGL3dXjzyP6aTfQkF=5 zbgq!tpwB=tCj?-HjdwAJTc=}v)Vkk_d&&=NKoYNW#W=Rh(L$pi(^I%3MQ&gdXO|p- z7I8P~_KYi9##$5tnbl2p55xlzEx4p-0paPWODs~G&V&}@h)z>yL5`G`G0fh)iyjSk zq8Nb={8Cv=mSgpSsrXD3Wsg4kHOqgM6HeO$P@RjT#a~~&7bo)g^lY%R{oo;gBL4PS zg;o^$hysHqOS0auu$rf*30d+)>^n_LGMgcLIfYGAFP9AMsvTvg`5y1`udWKyY<4sk zyEsK#+l<%VIKo)h5#MB-shJn9w6DOzgMDt}i~=v6nzgLcvC3>~m&HlwI``0v?((wZ zq)PLm%ZALZ8R;qe+{OC$0OrvX5CM)*fCC4^MSGo1j<J)!pTBztREFKSqnG(9Qt(eZ z!=2&Q0QUMz0_Pt6pAb0rV6eS2*#4R#=HhxB4<82#I_W#Y0KeeOmVNT=evh{`nlu0V z_4j@BN&lGU**}r1gjLT$u<5JQJNzh?c;yw<;<;S&>>v0lpD*z@9EBH4bOMCA3F-Tu zf<;_N70jf<{uVFf34ApPe!fIW+dq6&{pCGPtUO+xo?iUz-81)F0wDSwWy@*KIhxEW z8U0mWEihbUKpMD{Y)tBD=RAU^i#Hi*&o)5S6YxGVB<TKJrW2SfG!@mmoo-f^OY#ug zqA8Q35dI|k_8dqlv4I#Nm(pL<ErEE|O96Vh>OF${O^G-Y#8?0eVGSDz9UFZV><h9r zd@!w<X)6dV$k8caFkhAwGDrr{Bu57D^|Sx}#}6<6{OtX!zrRH9%IL|H=>B#M*y?6N z_`sn^@$Xl?S`ZSfh4e-&a?Xpn=u+TUpIuP@krU0-=j@IufmP;-hHBv>`rX$67V&|c z&(q0ZLIFRb?@21SH}6)Yj#YaL4`!`W9{_2}6FU5`o^n867bk;H6}qo)K14N?26FkW zKyu!<3Ku$jRy>2>*vM#&u2TT9(gE5ZWG%X!K$UY9?y1+|h_@*sYL_mzbaKgO8h#|z zMLxbvfHa)|W>@rUK20tziDnhk>T-g|;Bt~x$kt9S&$7uR%`dYG*oI5=IJ|@_bdk-c z=_PD!eu=(PD9v6<bR>*5h8Gi!mjRXmT~IJ0wM3N`pclXR`3xk;YK{SZ<Ff?)Pe2}b zHp27s;rV?cgztac99Px-fyUxgn|IFLr=2zb8`pbqc=&l|>+o=Kcvv1D=7)zTN8Ns4 zd~E6X0;tI6%{zV;a4_}v%Y0l+I0&yB?~e}Qf5S@{<$Q2-dGHI2wzV~Y|0Y{Uy^XG; zf^d+g<Up2A*)EE=PzG>Zpr>3J*`ZJvLl*wGWwB7ty{I}XmeUFOkJP`t6@-ABqzfqZ z4?FBfO5w}A<WYNHFy7AgCNx3nIXqj;rgvyk1Hg=dp9mZXKdHT_0Wq%*@1A%2@Si)z z2T!NxVy&tbleuY4?jfQ3;o$+&c7qeZUEYiFS#w9>RS&kb{((3r%+U`4PwF_CFVM9H z?UZZK*}=VEzPeoh*U|o7ul>`mUmYt%obO7wlT~z}eLp-R$8Gl9@{jLF6yL{xJUHs| z1olUFV~>iz;J<f|diQ#FFAux*7l&PZbJ)Ek7?=&i#rH1TR?xk7cz8spJg?H_q#(eK zu7}~_VT=tV+7sghf$3(!L%h;}#dEtxG7PB%h5b<387Rbe*>r(|9pA=Yb{uiv+rvoC ziQAX^yB<UqUJq%%;xC6)@6s)0XNV%h9QD20?bqCG?c2BqG~wt7zl;n@B6#kZ{_Z1} zc)`y3q*|(B*YF-U?e-22ad(uUu!kRUnCQu#R`40hD`k>R@rB>QzN{agVjuvuKW`<q z=&~pK0I(;e5*+F>AgIV8vCtRSPSpmU=~Ft=E}qr4?*7s|i5r&)w_gNiM?D21z^JA1 zSAGN-0*$80EylRlZ+Rxugg%b5JRuysMNjd;(~W=eo`!FFtA>Cv-0uGk@w73{Uh6mj zkE6SQfA{v=x~B7JK*8s-*0UZ~T4+F-o9hhez*o{Q@zp3QaLnym_tlH;sP^@pYv=$2 zd9C~W`)BXoHNJ#xzQwoipZ&S<W&3B1>jifp=<C`0_dhl|s~u2o`S#t*pI*FaZEL{_ zOZ&^K@0&mw#l!%Sspb;h(k}DG8UFtP{?Qx6<Fjl!xddhsg<YYSEtD6DJ8B;;i^&8| z%E1Qk7`^!LaB{DgU$!9z^dzlT^akH<03B&ZDk3mZH&b{a-`E5`UyzQcL;!zfKa;pL zbY=i5KBY7^l*<9hCX#O4;$c?B;%qD~Q=}Y4PWbJccWgNkW9P4YP5g>8B3+jVpRK!7 zTN9txkq2V>+vO>232%tsAHM}+&<lVHFM*|-^!5qzt3Vg;?;ZRCp#RDNQP^)Fy&xY~ z6oC(2(O<%UU*bX%;FvD~`xZss`)U&f_3{kpI~~={U(OCE^bnppfoSuWgI|6>+Bp3E zu)246Ade5vH`Qk^sj}(CfQ-b*vu}b#09)`0e@Cxg;GGD^3jd*#85!=W{0)`da^`8e zcj5!&Z2@cI!*lpAoLYGRlci~4Kp8W{n+E`HN-)3|5<Y^9_0T0PKz@f`Rkvm}<!&2T z78%5DH$s2}boIi`J4ps7N560PzrJd2*ZyVPLcuSGyl--YotP24boY<GOn>5j7^%ez zd}rAy>F%~Z<4Aft52CHl+gtEINp*vE=ouX%ypw^7rSl@w96t4|B~Nx9G|bzmkIYl_ zF_iFu$VCCTq&yoq2`?4W%+SP1KQ1p@mO<_tI%o1~p|<4EpgsxTzJ43o39qe*hbcPy zKZl)q4liRKWJ8y&*>`k#Ob(K1^mdx$sqYW-7s1L-QC%@lGStmpJHXSY(e_q!3B$a2 zw6)dehkt@U?|=6lKYqTo6=>usy#-lePs(H_dRYv)F{-J!C*ta?aOP^KcRnu@%vuqV z>pog@x^K}KMB;4p0(e-EcRBu%RK}v%UFOpwnfyg;84a6CFu0_`AjxBq&5$X^36sB! zSX}<$9Tb4rh~vCz0A0qcWU<y4tJWIQMf3xO2K0z}uXx)b-<@{HsV&J5vp_9AP##WH zbt0UopATt#4pxotQaw2J@@}W$HZSU*-`SElGTt|wdxBVF%t&;aN)DgwB+{7Ij?MeT z20PT$IK!<`I=KjTX=UICAE?cWlTfrfp}g_VC4eaC7@J{y3_{`hSx~Yp7Zhp@_-y6h z6=z}2$FwL>l2j~^*48OSVssBaY-}8nS3q@;!OtE$ySpeq?`(qMHrwh2jH+~RY+(g@ zODY`ajMnE&3ofLa?s0XWLO)vBTHzD^_U@Uegx9iubP7am4qX&ej8D(-Kk2z@n(?=4 z?VVx68y)xc7se)}r5+<BaN1-PU|z(*E45@__5_A`emG~07>SLkQ#;tDOOG7y8ZLNi z-eBUU>5)7PzE;?BXpNe$p`&&8hO8v6%XPKE1Wz6}o@{Sxk`d=mN0YS1opsth_%c+# zo9ra-ISp5J2IxLsF37z<D&`VcQgIZz3o;ikDzbKxp+kZD9h^}7*SS^Ir;4^6LLP*s z<4MTx-Q!=>vwr&TFd$^GoR1VwyLUid={Y58i~=e3d9Z!d3)8*@7OltL1A~;Ue$(Kf zyyQ#k+lyC|IGU+T1|3K;8_qF)a)Aeuo#k-}1e9+<Hu-oA=ywr47=A4l{>pvL;aTJZ zg&`_=5lxHyl)`lA=5dG`i?!*_*N?xx-!mSvG*@**H`DN*vOW}u48W2#07k>OGtzJM zNu%&{di*hSP6+CvB|RKpXw+P_04|ln)?UbKH;*A&*8!Bq>u^oahw+|r;A=rj<Ih`< z$!=|X)oHfm00xb<Kr{?8CHlbfHqwD8Slj=gK^r!>FtRmgii$mv6xF@%Q45T&1JQM> z?yNimC_nc)wWx1C1v^J>WXn}JQr^V+>f4L=$tean*h8pOtWR*|oQA9rXiUqT(ECRO zCk;3YrtloCYd`pij4zqK`<AwA)y!-DRd`L!6S`M}Fu30;3LlEsopF)~wfk#`0o<+R zDktv~Ouw`ji7}E!^%tJUI(^}6)_YNt_*dp?q&fcvlQ{=Tp+Y5c0+fW(ZA1czL0OQ_ z6s^k{rv+e1935xyvq&TiPWE`gAq*$tyM;+T%7i3ICQjI!^g#ip&;ey%o4aIRKxE?g zXG#8%JXMf)L`&;(UgQfG3IY7%8F~BkTzq8o2+nItt`#(^LbFh~<XoLr628sJDEw91 z5|p#vOaZ&L#ykkJU!sY&+h<+&V%|K1WKPK+ce6>iXR=qg-8KOMEMN6eV*Tn*K22yq zzO?hob{=8x#2<yZMR}0!K{naDORhBVH^{YjkD{*58&jpy`mD#g;}o;Oz)zXmk<C$h zS`><aapd2IQ?S^pYJtWfprpL1^C9r$H@LGr<F>1Pn*$)r_yE#k-0gR*TRtO$X{~E= zfyM3gLa3}?!;oArw3}xrItAVG2TGpXsI!PKG0+L}jMAB0A=^X_kv6@_I%1T~Yr?Z& zAGR8DtqOP1WE?PC_B^Sa^9^r+--u>#%2(T{`dG=+lPs`#kKJI%EdhOG2W*}kC*(nn zemfwmB5A4M@L<#bOE{hAcjvLlTy0;x#(GzhJA@s-#g&ZW2$Pcq<u52Wp9w`?N(v#& z&H>%8xo~h|O0a{Nv>1bGd2*6{PA5GL8$`+!XA(M3?iE1VrYQZ03jlGL^yYgy9zE=z z@>{9+4?6^i8v&M<7vyl`M5Dk@L!}=8kIO2%=9^L@eA!pOUQG&tP75(Q9>c+nx;=8K z{RBdGgmJK(Oo5XZvBuBm#5AsfG3-|Ks;Z#hJKGPxaU3>IM)(Rh0*w5$v24RqQ_iH1 znA^vNs-cM}XAsE6!5P4KSqD5!b(Wnh01ihrH<Q>mk_jMvAt11j<rCCFJBx6y6TFkW z{sr$039BRRF<ep1T@cCvB}rx;;jYj{_Ptf#0AOd(W4MR-q~=u%fIw$q^%pww-ZReq z)y`7%07Tw6{it4;d|R!Y+*?X~<r8YBs4w_LD4S9U0;-raX&9f&aPIhhx$v{5)W*<* zmvD#Nu`mE}7v6U1MpL?|xj5EOFpwC&r7cknOxo@i7*I0RmZf~{!$}o!2)9R4q`KJa z>{E-75<V5$_Z)RZeoBN;<VHz8bkPhNailb=*w%Q}=txf(<u~WqWKwzOVRa}*M8XsS z62l;lV(38+6t}V)#`?!Aei6OR=IC~S?{K%sixXqvoF%D!uXR|&M)s3pnU7q*k4afH zh0$x9I}x2>%!Bt`H*T+4%|~z5{r0lk(=>Se+y`AXuY4i`*o+6F&^^505#wdB8aPSZ zt-M@XkXIUl@w|xS?hk+<m<IrCeR>>T7VLWLuZC$#fkA-&TPQ3fVywoL6{tBv)GmYf zCk5txuBcxFOPLwX-a5`vY}68gcue7Qlp8QRLFX=fjE`FUUXPp4I12P%$HS^vmgDpl z`iLPn6Zp>cqJgwau5Y*N^wr1>+orh4Pf13x26!(X7nIeGbhUEAPEJCPTzuj)^Rd1H znjSk?CGsh*n7?#tM1~FgcbEfn@Q$I_3%t~*iS;`SJkbIcMP4M)KEP~54LoM)mWQz= zVoy}_D~C|cF+UeTzxANvi?&;u+*RLFKjIrr^HtIoL|@f12T5Gj3X#I33FXEpVbCPI zPUv?&&<j%jiHh}0SI*YLFIx4t^vVD5vg5|O0i*pho_4qQ2SbAsWnr{Ywd#g#gUDO= znL<TxPZz&u7y=u8eQI^a?$5nwLx1nuAi&m6kf-izgkYfi@B2_gI_cyxf_E}TZQ*BX z6EG9;_5u5y4YPGA<9%A|6O!<gMeX9t_~XtB(U3JDFpYyK{!kkbZj4^!wMuK$>;v8* z>#;1A|CASvfHq<|LP>+KnS@9i?KVY*W{V5XRW45bn)#)9vs|)3v3C`;araEv>QW+K zuIPeh`a%OEwH;$}CJyZ~p~J)rT`&_HVp*Gz8{n5d^HplDQ@J&&cz6{D0}RuUlE=0N z8lh>0D*|8^mpsGdVI5!gL5c;{>OctG*_>BJ|NZ)Vxm8wz_KHcyGsosqhET6)4dCqo zjOAGHilUD*-r{^f_68l4;7Oqge!BW+8^Hn)=%_C>HF$-25E-+%I0D*hS?!%IoObCV zU2yzVC#au;=2{Xx*-Xq#W;BTIJa}{;mG8u6*GAlPns`zlHw{wwv^T7M=0%EnfBW?( zKJ5%)1VXGEjg%)hd-yJ0cm{0%{Bpwn#ASw9j5)@}sn683F!dCIy<4&A2hixKw(Fi7 zWGP<gHCl`$uCE;{v`?!DXqn4q#~A1g1_uvKtpX=mNMV%c#SEp3zKA8n<56q}wcMwF zn)^jBL+hciWv{S;h+j12KWgHiW7GO#Qc(sChqg9IHYW~ihCEa$<KueIA#3N&kXM>O z6n0@*8hgjY!)Ss_&~O|6y9FUdc$3#Gzx_Q+&v$DPcCTJOeWdW<lj7He>#wTpH0Nl# zuCI)wct~K&+?TLTAPA)>=HlstTe2g%;B%iSuRHhN78CZi5KjxTwfSTjE#uK8sxe!4 zw(mc_|Fw+p_27|K+)|>r@WnlF<v#mhRj6#MqMM`4vc2*e=z#pf?c|@pKh3??=he&Y zZ6ZW8GUa{b*w2?3ct|0wD4~+iIBK;h*_at(2=XB{MHc`J-f<2M?XP3JMG&^#eiV45 z^fkB6ZYMO%Xh(il^&$Kl=)K6>`}f(!5P?E<3Gf?(KjeRuueD~s#^e-uZSa|6q3WKG zIru}zt{;sjd^G-!m(T?Z`_@=MCDW#wU$?TZsO;RmFv>l?oFq#mVE3z+kDMcB&&Br* zgAfSO44E8ps7K)(_1UN4*csE1XYU%ubsb-ab`96KtBe`}(sL_u)%*71-X9K5C#trZ zBD?oMqEPrzf)Q^VYBeA#Lv<r?*mXzsPw1}1YTjbTI<#&ts12bIYoDSwx?J^|6cqi2 zZm@RlMdAS}CKa5}D#K{Y0NY!uV2S2y2S6tth@s!rI65xTBv$`Sb4p7VS<H~IoFmGf z0yT%(qR-UD0B?WntYTtbF<X#CWMoW^G0k?c5?TbVG5`t<c>SjFjaJ(@d`;GNYio6T zR)->ut(R`&P3)AxZ5#UP1$)F$hHVO5>4YX@U4_xQ;RgrkT7MKUFX;aiX1{35a#3?a zXp<3Ie0kPH*1XQQ#oHJEBj1)Uacv=&7OOZSE;?{#!Qv`2DXZd@O1mDG2=i8GS{WM& zB%xAfO|t6oOGyjF`IkX(osJ~T2-&m)6N|?Kx>}F*f{)=z{d)5oepcICabW?zNcbjF zjUc+IJ66Y8V``X1Du6Z!{V#!t6iK*$dy2meXwmkzpl@qKYXwz}8-6cNZ$qCguod!J z@awc=k083rkaFU>J7d4*zj^wFr}P?mzJ^cNyWhab>X1NXA40!6Ide>uiK9Gy`R)53 z>JB&7k!8i`O(VFB>@r)E6YTXM!R=2uu-_%&kyK+Qbrt!QU%+(d^9$%9%f}d&gb{2> z6!Y!V<8_cvEh;zA*}8q{i=yZlkE&Kew;G-tbQs~i<eVADeCvCU6a0kKn)m$PIeoc! zj>+)e=eFjsSGON{`#(Ub%?->te7U?DoTrH2H60PI<Z>eRAi#L`!&-^+o}YkoWr~vN z<N7|URNHdhT!+)fCu?ju7<EA=9`kSSo^6T>@tv#2_y@C@=)i?HcWoS(M~52KUdAJ= zlkh1;4wUN=vkb-Mm{7+Rzk2z2le{aV?d>53p$7RYoPz*4Z6)!D!tk%@?m0-n0HB?1 zj!*bGl?tapU0$j{3B$0)>e1$7zJE3ORL;^eb%0${eVSjLshF1}JM?QLHJ~d|6eYRH z>daymQnLW(z>}x6Ii{Wf16B$&F0xtb9UJfoi1vOq7=$5_K`{MlXo{V4Rp`y_`}e<j zWD<fn0J2|}rD<&(bDf}huRK?L5j!o@)AY02wBaYY(Jj)`izt~CbIM1LHtrW$dRjzp zLAc8^v<0kYO?h!ssRc^vutLj=N~NwmlAIgT{5{tpq@-8qck=4xUHAh<5Z1AA{aWBh zr`b5;&;sJF(*;R~-eZ7{9V)2w4()4GDilM8dMz&D6Ah#}Zl1KfVNZ7MKYUCE{A(ES zJWopz$GcCGNFCLbpGIf3r%yJMrxJy?)_qb5yqYZshbKpOqgh30Cn3{&ckh~SIRRay zc`oqflTCgIKlt&}uJ=;){MRFKhKA!h*xng#f9<PLP)wqSkao_;({5%ZHr42tJ=BYS zMgP6G=Qft58^0kgBfv8Mm~*ZYnFMAA>sHB0+9mz<&sqNC`*2TY)g&LzG|f6~OPUXs z)h5SYUTkLR=GobUuOHrj^k|q=^UpqU!au51b8C9HjK-DUJqQ8)3jp)T3ACPbaDK0R zZ*?&-!qHxPnCe{&xId)WT;se~+X#82>BwrjkuGt0T@fl4d@|CBmZIVFz^-*GmZkf5 zo5ifiB(XoDSzI<^VplJW3HXzp$9)q-wX@NW-X$kVnLYVtxCMV?Z{EqTw`WPdC}w|s z_hftcc=*l64a*`Q(0}dK56n?Fx@nPJ_^LK(4h4|wYY>ejeT<%gz_$=@2R?MxId@g2 zm7T5a?ad!wJ|BdcN(T6R>+#NGOus^7`C=)0eX*vOOgLQ62B<hGZBxoxfQ}%nQM`Wp zbul+?zG=B)OL^y_N4#(FuUUDeWb>S0N$Usjo&N(K4#%h2K9INV`(HnLxUDPA2Uz1w z1D}iXPKNH3$5_(ICoFJ|oWD}2U3DW?BzI~kv2pJfC^5V<+`y>bu3`C^Prm7{Q`m5J zxhi@T{lIRE&*t;W5<=vDN!N*dpFQIxYDbZt5^ha6hlROE*s!3%9F%B@EVg?_SLgiQ z*dIai{^IYtTQ$xDBY-)-ksjZM8jy$R)xXBc<JT{`MvQ2oWiN9os6}>2!1|m@e4#ZP zZ}R{EH_>Ely>~0pMRRKjj(2%$8no)W@1py|hj`%AoU%S`jx_%hZ56}F>k8xg1Khi6 zfd^AM=>5+fV;SKVfN)J=quhcTi<irPYhcYXY<DUsxNR}u+#^{|z6k1zqUh3`;=TUp zv!Gu6eD#O-MqMenY(w!JA6pkj>O5`ivv(`=rB5hOP#-e&d0p!*XfiAQdF}h+`md|n z>z=aKHxrBJnp79}9&Le`p3O<#m~6L*8q(hy*XKr81FRGTWP#`eDS|-giXIcrDI9H^ z*AiK%`MfzW8m0tzfqt>(2on!3w;j@1S2x_%>XL?kh7}YZUsBHOt6FuI;v{Cy<XjJi zKB(4_vjSX+EV8@~vW|Dx_W*re7LovStW4w)O-=>s#!RXN|DK~LF2$Hp7f!=DT-TSj z3Hl@9{kg=#{h>BKZ_jU&^9Uu!{9aW=>hR^vBWg<5SUoJ-gq}T|8I5JJlO>wx+`hUj zCa{^~>9WELZIV`FxFF~rqI#n6u5aAF{ns*(1Tpx0mE>jXmUDTzay`<#SJOk91dyz~ zrF@5bb)VJ8(LOw?I}(i8+jVX2csW=9*JGn}xB6YlEC~(KLb4vyPi()Ox46f~)GbZM z&t0m6gipC6%@47btlT<s#9i@HJNZ+@GF#7u>92wnk=o;?_U;(rU_ek;-5s-TIf&e} zNpD+%bD9PF<Z!$L>I96<AFj=M5qf4<I*d&rYLITf(*`4#VE&YA&$=|C<eHyMzbxaZ zO*iV(lA{X%hF`EdJb7V}Cc;(;XRZr<Lssm)mbY*eVSP0Y4WjkqRWEltE-09Lsw*(* zsh$7xWIE=w+Ukc&PSpkFbEd>U$0-`Tg52dM3fWH?z}WOYLL@`j0@5{K9t$N{yY5WT zu~Oc~IWC^35o#K6N*Bbg*$Wa|Z)-~S7xmk<s>28l9P<Ke@w(o(h-NQRbPM5>0>`Uo zs7sUvj%i@d0CQ(@@)b<i<Y+4CGpSfJyR`vy(cQ^;X$67a21n5Y1i@MZCcX;tLx^`J z5hwcs2z&1u2X{*!WT@kRf2iZeP}?D|`Wil>8^zZZ$D?g9)+J~b!t2T&#r{>FwqVfu z=9p4~GhO!QHarf101x158K5seWu3+LtrVA>R5RE`szEH#cv6}cJu)c|-S|JJD-zC8 zD~^)T1(z7YPLJi@t3OW2Oa)V5OVu&|c^tX&C~v7fMW*;Aq#0%WR_v?DEiyb>EX^cx ziSnKGd*hNt>|vPl<!m16Gwi}Pp+EJnKX~KCSFOHd8tFqu0E`}=U>T6#e5s6@D;aHp zun^&@+ahx;oefAACW4EQHKWL@O2W4?;C$fbs3@N!J3b?RW)<BJ9Kw?9wuiN}T=vO) zxXd}0kwaoM`b+|aZr{^!dry+kE17<bh+!l9NQvTaQBVZ^342ll`jqJ$mUdxAOy-&r z`j~zxOM}%b!c&?t1`tnxNwFng+gLq;{Eo8oq1Gc*SdthO?hcOFcLTRvFWeszCgX!j z=*4uL;j1eM$f3vR<5dmh{gx!jGG4Ik04<KeUNkm-37GocD=Mr%zUDXLCKy7f|Mkt= z`Zuz9y&xTS<$Tl8B{xWgkHAMvc0QwG6mE4HzeUC(XDJpBhguo%q?u%y&M+s?rL_1Z zJ4xB-@LK*-kW=^Wezkq~sB0=rtWs7q-H#|hF4iO&ubrl%_Cy390bj578A`bLzqV`} z?h|1mT-d*_kQmC|cB7owkLrWFRl^b-iu34v+{PO*OmHli;A;H?b4+U@GGe{;eoKE$ zWs{6Joa2<MFNaBNpo0_je&7g&$3A_L6Zf1mjWhGM<%bG#87!Iw%u~)AW`g*_Q{&1b z$jLciq&)JP=BIc~n?qz|VB=#@%b9cg19W2^urE#gWqlV~6Z!<J!PC-02YdnH|8+Wm zcu(c58Zo}j@;c1w&_#isLs-)41dUo$=9z;uhV5Agyg&V;ElN57!Xd@2A=(8+(`(b{ zw@pK&nv(#2eR9bRolEE%Fx9TyZsG7@8OD8?6n@g;DJ>qKwtG&5*>LOA&E$fwyv}wn zH7a;S(T>n+=tJ!GwN9KksxgzrG3y4GSV3-)X;w-7KUPPh4vsR5#8LMhW$;(M<1#PP zadC<nY$m4C!icIYQ7=KH&<lG(YqE?|GhaHXKL`S&!b{(0AJZ#!Hlhd}nLF3*ddGof zegQ$zTI&|($8f%3u5hU2J>*E}ocL{E0q>#sde5<)oPN@G(?|2rl5>J&rSos-)MW@K zuyPOX6}nD&7TUDKhwms35I0scc2S1NIN~&;?qPvB8N9;9UzoupYN6KGxsLfvZ^#vC z6Rtt2)q2qq;8r18<18pqX{xUJ$WAxuIWNWcaS(mL%7xou{02IdrOxIisagbm7KKaC z;Hn22=N>ePo`RgTB&C29Ig)xyn{zk@n>#xXL-6zA=rr8h3=;pe$fjsX3zCFL>SN8| zLUf%E9lA*6TqqHLzj*Vy8R$qje(7=)Am9nfrEroDLGusVJYd!RwcpVio87KM?7q$B zxEFc_I(%7oEqvGz1)sT$n(Y4t|HlbKQsozPjTXbi6&HsJ(Tha{cBV+U9ICiIdgcZf zu(21(iZ#kkF~f*@HGQx|(ivrR{fT2iB;x^Y)^l-P!o4(Z1<-=*zyx%zpen`wG~l&j zH6j~Uflh+-65LbU+Yj&eYNaDNCf$tMRzuRddz-eqwep~pEK^{J4px-u76e0II#kX% zbwn}|S(ta}!EW%@q+GB}TCfeqOZ4i7y|~|i{DUx>(Ba_U@uV;p<WYkR9}|xm1r;sy z<*5N)OFn>%Go65;!~-k&#a;NO3L|@3yze>JZ%igw4U@SKJiW^bRa+)k(I|Sjg(;mS zpr4Flqafto)iD@FuABir^9;xc7+QRSF0uNXl#1CWe1~c0pLXE~X7Gjk(@Xc=K8vy= zcFeq@ocU3EQ+c~#-<Cj@ie)7m+uGZ|u4x}#Nj_^=Bt>Q`WeyD2K&-nUj%GkL$xv^0 z@K<dk=JuiLoB*3#=;)$wIUCUrj<jD=k_F2E<SJe2(D#o>)$RTOT;$&m%<qTvyNeDg zx0+m-){>4bx<Cbmn|b6evq1WQ(oh+lsx95@F7-Yh5IW!pZ(sFc1&BBAxx^0SB<c|F zK)yVpNo}+13)hOkdIZDakh99|03bnLua$|QSNDC^2Vd3TaB>g-e@?X@u)@Q>@9RPI z8FS0e=0z?}qo4DQ3)2gJvyWe2@&^wi^s3>8{zH28b@aLQ`8V#9i`tt<(M8K+G~c#k zVlA;qZEK-{-;(=cHR$G89aDE2<Bb+)gL{!wAFJF-efElVxBJe1XE|;iZOf!LbbU*n z{m;Z9Q*C45@u_+a5_J<|Go-E7@8EJusq7IcVn}_kN#`6Z)FU^8cQzcVDWzB5+T1p1 z`v4)d5&KiJ?+?j__<tOHO$TNhq>^X{7#MTD2u6r1U4OjvF(6OZr$KeS(s0_vH%IQg zJUZgcjBTAbBEc0eDJu`&3uoDJw(w<}+EdY*t+;k4nrGCUN>{XH#jzxD<1^k<Z0>dy z*7g)50EifHCS;_Je!&SAZIhp0U3(%K$c(M#86^-=+UScQC)FUUYM5>S;;Gs-bke(= zVZ}pPrmgKngvhOU<#xChDB7@-iLBJUaXF63>1Cl~ai&+T-xY)SxhyNfXeKMMw6m#I zwa-4^c|F^8GWkT+B*kiqEKoF_7Q|!l#R~M5;b!{Q9*54N(d|(fx;%E}V&w}oe$-xi z^CQ)7;C7s!M9TQGxx{SFmfxH$OQLj;-TFqlAy>3@IKv4s*bXk<*OjP>lqr(pPfT^x ziXJ<!O5N(-HMiS+&%ZM#q}+tBz!YZHz!05!f>jlABv!fJ?52CXnN!L}_5}lK&=spu zY!Qvfx?x0DqF7lGl-S^QHPq>vTvs%<zLLwqG6quVswG&;f@w~r)letrE5#m|rji?T z*HSzEMzqGU?;|LH6aTWRJXz3vO9dP(Tx5=*pIH#`bptGARzfqZSY;9oSfNV6?O$X4 z_!Tjtw~7yyGzHzBa*(o3mVs-q$gE#1q{d@kY-6=j_p4)DSsmd;8k8<V)vwJRt*u$B z(SV`Of&sO@*R?s8B~`FCsekMJk6ef#jkU4oE{XPGfLY%66WbF2h&xteM!xO(^=*Hl zw%ovJ%RF&bFmw6u)*kNNu7{`I3|{NttJV&L_zmc}cO1T9>Hng>Vi6*wD^J*L)kRLP zD`|GWWWJZ}TY*l2!PK_|OLg)a6h7)dz@U$=4&l7cLUPrRV-}=JLg~Y&mlMIXA7Q05 zOU9%UCdYKwIP-Po%$e5$=J-4*C$+YN2ig+5mZrstXu?PaVh)ofpl(1A*&WE2piktl zEiMJb+>onN0?-|iU=ZiM+gu9k>$N%>n$nwX-D`CNkFyDVo|zL(ZYW4Y`w`Vnf6l*2 z7f9(i`8TD{>qpfhq3Z1PKM?vcE|)=!Fj5fi16;j62s3{*RSD9EOW;&ni%WLSSG7R= z`kPO`SyrhQCtt_4!dL6ufsmIV`;lX%Xgfx+DT#<YO`{Z|EhHjqHx)!wfr+p&kJpSo z(-jnHXgl$r1NziPV!P1<2$BTsy4xRtHuB9{qqo;u96r~AnkK<7;`CTo$aSJreLX@b zfi#PW%g<Bt&(L&rRByg2dae^fA5{Jm=D5_FUF?Fc%5`o5zXA+$bGxb)V=>OGdY$-D z4h%v{7AUX8#B^!=47Zve9qk%Sz*K*TJ#;1s1!B}#P_B32a5+Ca<$wo3{K|d(YLP<+ zhs8LIG~j1r!^h}X#ED;7IH8=ubWQ-IV|GmRoIFw<cSIx2)Mayj0|kzoPcdzxFJm*7 zuYFesyc0*R7?ej@PUO2MsnfSuoQB;42Du`qKzhFIKhlK6*S6mY2NBHYv0O4TQ+Vyb zy!U(5I6fO2K{qzthMX#7O)W-$mrSR}iHqwXhbFrp<P3}0<UWdJffhJh#K%#);k=l~ zy`Cj1>_COlx0KDaubKTNajHQc5{8b;H2K&G&VAcChIMUh&|Gw-_&mHPLWFU<j0Z!u zB%tlo+mRsyG?m>ZEx0nL1dSj~oK0N-LOl<(o>eQ*>)}9me8o;OG1gJL{)`a2rwi+O z1gjyQfk=R#+rfcvJM4NVBaLWz9&@$a{efH#vD0ZbDndDnk@{Cpi(*a*a*j!5%?Nls z_WgSZ|DT|)xO)6CH;>2J07c1|g1f%ZV}bhEG{Ho``54X&V6exj+MU=&S#hllgAje{ z&qDMG&qd=fTy<(AUvuc{C#UT~z3Ma%(<@kRIWI7a0~hl+IjOMr;sU7$v&_jUI`}N2 z@x^$Was?BE*n>S{GHdm?c;AsfBYqS?!O#B7aHw1435QQN<>}Ks@f9$kBG>COS<ln2 zr=P~9@v8yJy_{!_yv8WT6c!{=rs;Lz*v<&IdB^tVYD2v(v!aAv{z<hqsCJx<Ud?iT zHeSLFK6Bw|IE!S0$|?$*TVl;rYBx<6T*+6fMi}il><Zhn(0}wSEzx>PN7lqya?OKN z(d2sfCTVh@S~0>+dgFW5mvz@Ccbr2NbQe&TT|ZI{^<+018N$X2vWYU9B^Q+7&YC5W z2*LSdj}Kg@7R>T`;4)R!9;R305<49DK&m}O1^Ez7qe$W;12)E(IVEyfw4|n)J_&M| zhx*2EK~|b+Oo1jrMMe~h6QPkOAr+(<$h-A<{ug(KPQ2o*{@d*u{5=Ztchxp&$Ub9l zCEse?zGpp+Ci{{s>l!OQ`K&UHL}N}Q(K>%s&#rD0tUG0~5`)$vTJXUH?*Z>!Z>BRb z<+C(ZI?gHLbm=;2|E%pZt&ive=T=FzcJEnW-J%s%o(44yEGN0u3d_+NsfWhf0^J@m z%3g}ry(wHR{)Be(0xPty+?P;yOwJOST*~@xE=6$)>OPw){qo6!@Q5H+IZZiDH?nw( zk_!)Oh8xtzpp7N+sS~Ptx&X~Z=97i#69zhY_VWNQK+wM&ZY-ds^uVgx)6yQt{myMM z_ByqK&!>i#ERVo4p!URGxbSr!*5pw+lO+5>iGa2u0lsS>`@c%(B8jylJ##hUzT!To z(g5aU5WZ(&X@KlVg!l%2cLFTGo$iG;mrXN9G2p<Hag>XJkMm9RHC@>a)>Xh#&O6Sy zzShp;$Gyg2&hY1TNv^CXGJ)1=(Bs=4Xx;74%B_-7HcK^gtH24nJ`MG7UOg9^)KBXC zNs+ogD2Zm=^uZFh=b`uaf+sb%C#zwVIX-n!d1i^QrQM&!N5#ZvQy3w8h>EvS5{;%w zehODi<?{`o(^(}6^Q&SiB{dCV+{J=&`RNkf(YPQ4m&{F(IHkWWlc}0BIneDSgLym` zmuoERlAgjUu`#hr^@dS4o28Qs*aEDtPWh#Hw%tK@*l{cfp*STJJArSMr@d~PxGcD4 z;hvvi{-he)IK42P2lEM&mW#h37wGUKkb8Hxb1T*pKN|2Qf(VI!){)U55WY4y2>r?H z(QH~e89!^EO{DY>*<3~6lg+5N!W$uA1+h6Zf;<l&0!n}H(c^#L>UoW|2_Jk9oiinY zJH>{k$NJXPezX4U>e5b=9N8zK5e-Np9RaqZwKU+Dfk<nH)}Jj43@xwReviSWL(!M+ zMAI8KXNak&R`a>;I$cwD_X5?nm6`(%v~DADB;$2fjngU2A}yB0+bpnZ<RXyH>?TRI z3Cu8ZPRWmk(_)-x`hwacWOUE$#?zM^G~sOYYT1#x(MC|j(z`1sV!*7?qc7zul+P(& z<ClEjk|2_6AiH-k@9!uJB$u-YAI2OGvA!Pr`cH~pXJvYVfBcJICC8*kF=ktn3eM)l zU+ZdGpIfYB=<*nm%<hsgFgRRJpfB!8b>-5LCJbBE59uSK=kMO#@2^U#Mi~V36>_#N z%i15FUajW3aYL;yU+l|$5*9iW+nEf|bLt`Amh;5f#=1CbrPpWILGhU@^+Epcu0F>s z`IuG?WP{_2fiFNww=K<pB2*=L8x@%5?@j8!8Yyvfxc1!5pK!J*N(F0dK^U!6&%4^C zRFc;%`=*POI`B6s8Q(ZRC1w#vKPKiJ97nrNYFAAZ%8`dLvQney{%$lzQ_LuOu#1IX zQQrecbre19X&%vt(o`ZR0DW@d;V2gW@KN+=cZGxaDEbC^T#SdB9n8_^C(+kZzFaff znozBHr>AvVI1x07cYm;deM^dFoK)RTY^-~YR4+A}z}RvVX;}~SSb_;h*1z9jjL_dr zTL%%P36O@<@}_Z0Zl+PQfe(~DgnX=T>Wnj;+}N2E0KD$v%)f{R-CSo;$84=cXr_j^ ze(l5%0e3qq+{Rk8^?pX4VE9?laQM!-Dug9tB;{;+9wF=Y(8O*NhYN=w9i9&R5fI6w z9G?M~CP#rJhql2a2}CRrsx2HH`B?ON&M^toq`=#@wej>rbku|{AUh1OV6{sv+ojV7 zz+F*y(R%P103SqKQbAheQ*siyxtE|MVLu9!0=mAPC+K!KNc!8qJ4918?*?-(o}hb* z|8qm9F{-IW-E7cr`#)SVX}Tiinwd84!jmV`4u5a#MLVI#vDT1m#t#OnEoo-wjQ-$% z(3H3Tm!>>j{BfJEbN_-p4^}xCWMm!M{i7Cl`hU>kHa6@g{>KZXlGGAV=I=~&J3Fdd zgz#XaMH+d=$wVsXnyb_4u6e2%a)!T0WirVM4#^UCyW`@s{(X{R^cep}Wi>D?6a71z zC8w#za`8e#164*!{g#TvwDPNP8rAZ6mMyezR8%c)+jm&^S30L+p-FWSJ$w6#1143K zj?Tp13S;VKyJs<FfH0OCpAcZr2EbIc9oX&EOg!ScY<q_NaUlfGnbtgMYDKA*W0k%^ z2YDB3D>`S<qxU)D0I-_88!`O9_%122Y<RJp!($gfN9IKFvXD3h@$PU+SmT<_DbToe z5I*T=w2xk`(k2WMN9lm3L5g_p93JzOq@;n5?DMeHC$@|`_v6#`J*VunT!RX2&E+!h z1ffqbVU)>ck_NS;bhbk{R%6#$7;zrN(Rjr;hS^exz1UnRBs3vw3+de?50$JE|5YHk zU<pU}(Nh9j_*2iY5PA^v9uj1FCV!H#+%YHaKwykLtQfP))t4(4T{EW)Idv0LB%TOQ zOLcO<k&PVIxuRL<kt(@C6Us8`h9!>_v`le996-yF2T8-OgdW5l=fZvsKz)EqkYGv= zvyx#tt66RjYp~l6Qa<cS+&JpsBF&G-Qse8!+@^NaY~par1N~a4w}8DB?gC6b=|0o0 zv@@{)UjRu7scxJiP4A^1DLyxX1n!{LT{_|vWiDwn$NNxQ^6k7^rfkwj>OuBPn@_7R z38=MlOXQLf332PR5Fe#<x|ESVU`=qS+csvVQK#-Wq+`f7NLYxc!9uor0gc0p*;H<K z6?3FFPp(}W1emANT}?Gi<l5)g!XSn^KL|fIHe4DUrPJEaL3YGhR)S<cp5$JcNhXtt zCmf0i7!Bec_R0L?r_R2%{{0Xh&?SPb!Vg8RRgN%S9DYb{K;r0cBgrX`cCHFI{E2DY zOzt5!0F(6nj>((t+?J+AMO8&4Z`&puyKzdEaqr)C8{=u4KE2^Oy|RWC=31&RzpgfM zX4tk#)T_d?&wXRLSW#&8Qmb386?d_iPM$Zs^f@O_dae$^)_+a6>S)&&%D^-<cgcGR zSl{Dpfu&cR3$rVuPUU<l=PDOxJ5KZTBwMh96G9l71#w>>2wR)>t@h>L+!%Awui6)D zzi)LBZ{$6;UYh@-lMh_CZ|&W>8@Mbe7S!CgWrm{0!Lg(r=_l$w*#70VzEotfzMquy zje_QZ6L3gY70w9(9j6DVjZRL<4XkjEz=8VTn$ESG1CWbxfqp9Rw|A*%dd~isqJkAZ zAO8olXn>5_dwQ}PtXppW8I{W6iw|M6i`6VK!@j<7R%P<Ppv{+q;rFb*=4<gc4Et!o zVB<I1mcsigye$L*uXRWnJIpDm53QTr{uhuY?{en)*zK(Fy|KJWi5K5Z$M{Qh*u)jM zzPFA-Sj+%jviUT9&LdTpIgrt-elz=5?dI2(excV~^-UKS{hV@>T5q1Kmb_7B^6=dR zI0XtwH=^UbFP@ieyJKCj011CG9$4%<R$H3u+3+<pRM|4SJCD|Vj;m`HeY0~FBY|-B zK>7IB4VYk8&{B0$t_GT|Lmv3MrmHb0CCCtIdk-NGm!&&CPDbdPEp;pymR-@;{2TU6 zeut6h9De4Sla0~;+4PGwP4~hH`4@sjrfVGCbd7(m>N=mS=(=qM0k&T2BPgicN;(ib z7wHTzIO}^)L4fe<#MEBJk;4aNO6m7Aa^X;~HAUEt&-sw$8G3$tH$h@wa9+-e_<5n( z6D#pGq^uPy=>&P+-0QmK`1>DgK5I%&to-cO%MOjsK|K|uhZ_SESE}o#IQo%$SNVwx zBjSNOp&DB0WT2Fyy2!^MWaZgE6LqteK3?Tkh9#-jt!Ui{PV8Xg$qB8VhJKCI#9(-B z&qmHfRPlmj;5SR3uU4csN&TkRV-nyJ%z}Y{-UNgtMM<%CG+Tqvl(Wlkw&D^EV6c{= z8R*-6v;I-=Ewr&GMWb(Vp2OiV!vGWUS_`beXoki=fJ^4~u$!ac)50Z_M)pK^iQ^-u z7kY#7(~<SoeU<Mz%|{N)F0&c(;-U!Xgsg6;^6}UBtK3naH;6w?5k=K2&*pQGwml4V zfB-7uGD)S6J%ZQ)^fWRp^&iJ_lHrUtCLy^0Q$Apx>O}N#?pz+jvJ1_AIEyqK&#h7O z<KqywVlVXW!4E>8UcZ(DT?=~jS{Gj!u<_3L`(8CQErfgaW($$i<76;N)5uLvC>O_5 zV4(za#4w_T_ry7p1b7R76t+`kG(_W+N<nL3BMr+2ori$}w{V#@aIE=E6RS=UvVH@l zge!e31>!L{II)Y=?`e}oo$5EldtFEEe%FQ|#Nsa<2lVOSsMi-H4dizvSClqR`J<LA zW8no3<@O0%JwawSrRyNu3fSx5>g2gt_Rs9^em!JEd;vy6%Bcg&;9z7r@@U7t7~?fJ zt3I)Q?SWh&L}X$>;{nolHI&WtU|Es@rIvFt*cC@*I%~C8K69)OpK(Cd^sk1*_nScX zrJDRJD!H`Vx#kcy5y>snQbLbJfv}30i?tZ17jfHnwd9w*nt;OXz5}FtPkO<o8j>W; z=SpE6=lS6p&7=gL{3z)n)k>r3BM(#uxpl<e7%UmgxL~vSs@{(Vt+|f6QP)Wo^~O{V zA=*+m4D`~bVCaM`z3!reiBS3|3bG3-HI^6;N*RqMi`RTGO+TemC3JDsQ{hkGgC^im zS$aDUQVU~t9*OGU&}3kJ9r9Uz@$ZcqCS7@6ODV4b0=Jn0Ti_0&+e+=6<QL?y`d$(1 zh>cA`dQ9#?+LIX^kLNB+J^M|v9mOud%gH^%Bb&o0?N-du9$OFDRr2Akx>-`d)mf6C za;0*tUA`h1rZ!g>4ii=txMJPujiRm(z-m8PnVzhg?M^l<M3>bX8+YD&;(ybms-bne zIRPb2OxXNe7k#)}OX^1X;Ng5O=OhWIESk)ni-u0AQ&Y~ig?1{h>r&+@pnRGqOd*ow z7d;Yu*v}O=bfUp>lsJ52Biq%4J+v_&bYniajnV0}Z^#FQhv8go#J0KnyfMaYiE>a+ zISa!z8&+#+>`Nx(n@w)sHb8TX&e25OZkg?)dum#u4aHFfgxWx{{nvY%hD0s{pY|vt zXR;m^v=}Fg`1eTclL8oezY`r9zq|-DJz*xh5hg0Tl323dipavio>@8oJb^vZtd(sS zoX#+Vs|=5{d?*{c;!|&K4?FolTGVD2ZRR~{WW0Es8k1R2Cx7iW6h^DJedVS8XS6`d z2UT3_0j(|$$IOj?eDRJ5wRvd*<ZzY87aHWSSMRgdvRcA{dhJL>U0Y)bt6_T_-4BwK z5-I-Rc@S$Ie~vjDTtzct2)bKc&1mYiki=QT&S)g7TjRupx5})(1+kE7pw+J-=gaW3 z#8f5I^W;M6L`kJH8pyE|Xqt9wGK!#vCdfk;CMkq9pBzxS$)lK6K?XW*CO=Uf-9>tu zmd@^ii4`>cJ*9SV-x(6RCar&>$`p7#>*pKpMpZzF11xh^0JgJXi3E2R)1|yM+?M$; zTS!X_B566JRDEyP8n^sjzy#PzJ!8)!nGCX4NI;J>BkMctRt1TXBINV`8zrk>vtO|W z7^Pp7;$N7g0do%&zVoWkU|&YKU%5Q@aSF(`)uoD-=glJLPagLrnnHuRi)l&;H_*!c zeTLo*re@5mmq7OzY~5Y?a1=esmzWFUY0n2TT6G3{6?wh^0VhPrS{5sk(Nw8!*b1%C zXwff>mH!a=2s3B2^h`hv-UlCS0fm3Vjw+$S4W)ZM(@7|kufQ;e<&m>WGQQVtUp-Cl zOVkK?y5XgB(vB`fomg4GA<eXEmG@}PCiEb(aEf`!RBA;Vy{qG`WV}T<SF4rohJ}&E z!@<BU#Es9T08)0g;d&laE#eavdXNRVtP89VU6?6Y6_cf*ZCg?o+`anGzzPpu6QZ3u z2?wf^d1;x!3ae*~4qDpEE?c3x!{DX4#OgTdu+iAJ{C%*>{i3r1M8v@o38tg1oRRXm zBpPHh<fl^MN2Mx<D?wa4CbG<@=r-i`VO2&AGH=D!^hK_NZZ&nK*;??5^gMH^L{$&? zZ?XUSOaNIm#(Z;}LW$V3vto+M4T;APs{>_fPR5I+<KG3{gZtNOfX(BE-VDjTfvO?q z?YfY#ua3`yH=&wIRq8jXT8_sl^TcYB;b&EKvYdK`tAbZt+}LhjjrdS%L18!i91MTt zlx?*g-)Q5!dM=erkd4O|lxl2Tcpl%txyRUU7%Jz<Bdb`PM5oi@IGNHVlBZNw#1f<x z1oc{Sy81q6Mxq%9xb$|=wV-q*pa1<%Eip(Gu$4V6UgjPVKP;(9yvMYE(B?4Brh?6T z(JRz(qo9dA6}b%F+cdU$cD?hAg|dxxhC`n_$7vb9yvcWZJ#d~T1%1x!LgI@!!N$2< z^6sf9vBq2`W~pgn$UTg6n>l|s;}j8S2!cfPm9@VTJ~>sh(K5G?B)8@k8HycxUAi9Q zF5V`=+mpaIk3y%Z39U;aZS8{!<?6>NJ2SDlq}sPFZW`ggT+HgJ9qt`61`f!SriWpl z1d|vVPfz0%Z)z|m;zQu8em#qT6%}<Qe?z%bo!=?q2}hDrWE`K6yOje4_Ti`I5X@Eq zdq>Rjr5?&F-~5^XNtJr%WjeUN<LGz^T!Nj8o>n`et2m|-RJ|tIRdgUk@Tlz_QsX0< z9aVg>h6P4`@u8$*W<1AwJ*E}J!?6nH*3l!(RKrJG;J*@df#xXk&~_NOr&->sAg#ZS z+2zYbhVA%6>uwr<dSin&+W*k{73golNT23Oe@SlE4zt80IspR%Ow2!3fyTk&DlU<w zjaQDyOqV{gz2pboF}#glYCb=(DCw~>Z-Np3oS&NG`xkOZ`7)8p%$VW90|^UJ<k2fE zEaOx(*A<~)a==B-tn~se*&ULZSS7aSEfqbZpnCPf#jk4lLtt{gy?8Y-GU~8a)@?=6 z-?g=Nh2eIfFzk4(1ZmKXW&kF0B&$%RstuQDOR&=Go3gL8$x)Ad*BmG5U)O5iil3PG zE^(Oam?M&TfJ1`+0?(11T!=ezc|l&jz+%j!<s7z|s8hYvitA5@9@m+OdiHVVBwA>s z?zZacIBtU7-rFNWQX&G3!6dq1JVADPwiql5Af_h^Cw$wxkSpLIKVJ#Q;|k$eFBl4X z3b1X(?ODUU%)3)RJI2I=lJpu?utrDQS)qWAB?gT#gwlzd`_;?RS3b}M5zFiK0m-78 zF@YIqjIi#@oy}oRyi*7@%{}L;s)uRjWFP|c9#KKjPp`z|6`6uW=UU1*T45u!FH%Gf zzHw%qCMxksu&TKri4UvIX}(xYl5$3n%&dCdGQ|XueJ#AID%+$~pB%-)xzjtlOgka+ zdKqDb26@+ritF_}Xse|lFH1Ggb0F6l{Yu?+kz>e+i$>avaZgKTOi9Scopx6`%nymb zxL?f6;!{SYoQZDGAEHeA)#omRc^M8!Fnv}`xIl1_2a$3Zch(HWp#7_*Bka2%y<Xg5 zZv?(?og%kZ-k6J#I=`<PVi{<EF-ma>+?G16Ae`mtV3EyIEY6#q=BydP7gQ;@S|rC* z!?n{=Y<EwYX2PsR-0k+71$KuYiY&)hoGyt!;GvzK^7$DsvT3yaU~vE82E_xjQd{Z; zn@Yrd17oo~%DV3pQYtT<lv!oC&CaS?!pOI*+nT>TrC01miCl(F(<Yf}e3f@w+`Cs> z&Clua$87QB;r(xh_jjU!X0!QvxHY`LDNEgXh@|c_<-6DA?|jq4eqN*t=Kne63+y5J z4gey!9COh<5~;`??_RJo?&CcKUJ85RS;k5BY1>yk4>B8V_bFWr|5Zf~U~)7N4BG4X zyvm=phYaIX7q8*#u}>_;LC(T2$6fe}vbX&SQwLntVMVDm_%{E9Dl3;%W7Fjg>XPHv zykNCKx8rl|%&G~{>ug*WRdKSQ!o_JmSXP_U>=<KxpuxlYUq9G+{9ikd{{C+G=;43u zJRT<1{BwutR~v*FK=6aJ8xpewY}b<{!em%`ckkSN`eZYC+TFEaG0ALd2|Vy4LH+KX zZiEov5t7M-i=D<1W%;<omX~KK-uRd2*#zsfwAQTe16BKPs<iG*^6U0VkPM|+CB3z{ zJ0}pqTq9y&+3_|&7o8qh6*^+~k%RGf&RLkV8je&u0T_ty>GlNfD{8%e$##$n@g{9U z4gOWIWEr`yWv6bjXZnp6v+TBSns)qUdvuFhW}2m@Ex(z8_U-n^u8i&lAeAS?Y94dm zwhAl6=0Uq?ib>pVIwA&=;a<CpZ7yw1D*$!;+dvS-Sb+ELjR=3h35AYaJ}=DS-vqOG z+{DmlTizW6R4i4(=(2@&L-GwFR$$-7Ix{~n-KkrR-;^NpD-gb`UM#r=N$Tx%xb*c< zcwTKMPt*32%)$GE?uhbgm`6UjgFIZSb+w_kbxjs+mDAl@0yYqQ--4dF_nM^EYCHJ} zEt0&itb|gVFH7aN!LEFS#?)#0KEcq3c=MMh@!|PK@36XexVir{-XA?V+&tWVdfEGG zv*!oOs&`rgYx9@k!7rmbhX;ql{?Wa!HsyxLw`3mi$y~>P2a1IWSFCq_`^0RbeabPH zu!VVX?o@4n!I(#u(w6p#-}FH*4uW2N?Aki3qo9ejJq4-5_FX?6nW<^~0pv<p$l&L# z?MD%p@O8zq+&E%dk*}Sz-8z*`WX~_s!Ca{l*ne3oasMR~tsTzTI~-a7te%9ZqI~0) z!tY$VPj_6{<R*M;^VaYyvuS=2w0%x4H>2O;YnMgj-++??lVVIxibLHtyC|+xVL&I; zCYWHLE5u{g*U%S-pz7D+%=4VwtE1&UR0AV)s5^p3RHTv~Pz}r7hL2Dcs@GOzc|{6p zXrId5UfkqW(?C6nHlm4Qs1e1aw0^DYY=HeH+-#X4Bcx<Z(6Mr$SBo^CV6qD?O}{cF zxU<%*vEQk9_dqMGNP~_s^fx=J;8W|XV)5VgyWT{97Z3{Fk--7PvhhbnAv-6<+Im{I zHBD(m$*o#EK2_AOQF`k8gt8j-+0CcdENo!Hc&(A%ri!_7c(ct`t~R41d;>+=4^oO( zl2m@xqAG{pk5PFDeCJoOe^?ua+~s)t>JY|#qp;y9xMO3U4PdF875uO!6za(Ry<hu# zL#kN12P1293Eg$C`o1dgN;F)7Aaa2b8V1pR7|=wa$Gk~61|0f7cmTu;-+xx!-2M8x zbVwRXIy@cYPMS$EXz!=H>3nU?-jgYktJ=V|IY()Ql=(CUD_ylhMFDuxosT$4Vh^rw z{EKoO_M&r25@B$hc!dPzU&#@FUPRqFrGH;*HK>?Ey8&O+qPJxylg4=#j<W{Yj#d@z zpvS6H^IoykUDs|1>PE%!2k3;~Ka0k2N0q=0fiRkusj2o&HV>JJiuyffx!?`I=(Cni z%YKcE68+x16J0WfN216ePzf{aa@EBZFk8pPXE=H8BbTvTpU5cBv>N4ka^X$QxECZO zGLWlIty0pRY!Vfp;C_6vNKT)6<==n5dl!Amk|@Xl9>sSaKit{wb+n8-EQUHq)5B>_ z$Odh;w|5?Ijo2HLYcbN|o}lLBw`Df|_>ynX&0m0N1@<+5a&UNl`18@m)84@^Pmk_h z-ihJC;OJftSXo>h#_}4DBOl6xYpj3f-jNJzTw#N0;$NQq@Z$TIBgE=%uMhvAtU^Cr z<!1Ve&wgi>e%G9KOL1AEtAV}!7HeVR)SpT0CgZcDe71<UL>7J$SRM7Pe_(Qk$`?<= zFVwcSM>TMr1>qTM7P-0=&sqOSN;dw%O)neyl$<eXePk8<n9YTBoTi@{@w`7U1vzlU zf!`(aT@_nO;5XnhpgBa*gkFLFgZHK3VlZcm*%WO6m{U8#7$UR=I4flpd0`a~#2xm~ zG<oCD%*ckxZF1I9qnj~11Zacf^`gO3_(|@3y-w&bhTS*@pkXzm1k-4U15^;Iv#;;a zNILSqwa(&EjmvDlVE<tyvXuLT6p#yV8KLypMD>BHOvPZ!8M%(x>+zhF`ILo=_Rv`c zsJe)FnDSYhrR6DF?dal?XYRw;dOyO7wQ`THvd#YL);WY}q@}7&ZLrZO@{~>D7|NxT zxpTFPTK1z)p1W1guxVammb=7k4$RI;qi?6c#l0cIZ}=a>!ZBmUxRT{j-6X3PSm!tl z8>?-&%-s}?B1r}J?c%JMkltRMP6NNe76BQ7e;{KYg|4}4!8<o~(>lm&GaL@d7r;fW zQzod&BrbPehP4ztG?3Jc7kb(@*7ZJ$0l93RDL9qAPIGV($(%a<G+l@;9gY0Dr8`Ff zW^fuVWB$Plk>*L-y>F**a)9rFgZE(gwW|3$zVz=zgAm2*d|KqEl&FENABweizJC1m z{aRKiC*!rG<hR!YaRiuf?VS8IUcDq*`UYJ&l$**HAguWh(JK&ja7aDUWP(UWUKU|e zD!9CzdoF>ckrB%?C=CvOx1}nj$?$iMgX1X)YE3zJehNazHz6x!Fi3@ANt>(~TrYv8 z!_zmOd@9^`&D(Z=thMItZ0-z?b1Wf$MRi+yb@vD7dEtrE@WXGkvPMlP)6|2vMTFX2 zH3z+L<aK<0mLaXFIOAdp*WssRN?N)CKXUPvGyrzdYuu$)7{NTKRMP;p39BW%T^sQ2 zr}*N{YdLehP6#8%SJYHv^{w;U9PCmXQq;*rFcW3@dg8UG-bqNH-LWj;bX?RX+Co?j zJ6B`qm`gL~gnDG1gX0jpB97FXwFoAd%UI0wwm?>P!c%R#fh(u`QC!-srJYd68mkd; zlMA+?)gPy^4SuscduhU;I}L>=GFzgR^PC-PKTynK_41!l>g24Vm_yJzJvu7klQWaE zO0pnAiwqLTW@NL*PlFuJP7-JssT=ZI#~jB!rwVeYLXsd!ZA`8!%pRw*i9EW*XYl7w zFrn$?GmsQ|AeP{!>TQ0yOiGxpWQu^9PL^X7DaF))*DT#T#7vW823LFc?>lS04;TLR zJEiI5q9Kx5Tm2<qTK-8+MNsrFoGt&wo8W8<s;dKfJ!+`YF)Jv{2Ub`YooqPXcv*&d z5$S}g-xR(@rf+G;!MZx!#oYN`fTc)T>#Zq~;=1k>_DLECom`kkEcn{HFq)tobv<5| zHeWk01pa#f%Q#Y(>L4TDWLL_Hira~WS>CsbQ^Fs~uhQ|6Upf3AhL^V$Z(*HsOI7!r zU=S7_lqKYK$7#LKy;7r1H4BovojO+rYv^V9ab?a3KhYCy^s~~`s%Y(1vqHCevud?n zv&yoEj7h%gjqHG4v+8}Mdb)d(a<)yYR<)@M04MsIbBH5Yr>dy*SvA%gCj+>76kD&+ zUsddbR8s*|p(eXs!(}FlJy>e3SIky`dIaA9y8MRGo-X6;XxAKAnuU`4$eoThCf2(n zk>Kx0=}DQK`h1(s)A=OYCJc`eRQoP(4;Rskp{XRSF)6k<hx?prh8Ow3I*GGoRRruN z5pcP4t~0CPR(lu+K8CA^$10D!)w<tVJ=Um2P41I*kNj^%V0M8@%UPE5O{#ib6aY+# zP}I$2IkjJ$`D{it2Yb|}0lZtw2#LX<a0<wNWb>4eKMUc5(}=ZNHkH>yuRQ)4qS3z6 ziLyc;V7#y3QjJ~Z*O8_@kqNoMO`%h(O>>si751RI2~j51ca%;mwAw+xFUA@jXyMJy zZ&g<MxXI3{fxJ#WL!NY;0xMM270rFg_k}65O|e%D7}D&7Ds=4g#Y+kzzO+5Fg@}?& zT1{|uBG-<m#=0a}*=g4Up#UED`VFg^9fo8P{EwX*2Ati}bONnot0a|JcgLzC%CNcy z-MGUidjGhH3Y`YukUp^|U&wU0iTx4RDy~)P`2*#1OcBpje9pE8Z*U~gvb1(+^iag> zn2*AWGG2HAaf4=!(A}VXhs1^Rui7+_!bp>mX177xlJK*mYfbJlU0AiUhBghnvr|c5 z#1l8U$t>h0Z`HN?L@jN^)m}GMw}sM~;j_#{i5>ouZZv^(qbuwmDAgCkZ{@uHozAYE z-G90rcBb|Hz=8kc?XFF}K89???NHS1TeAixa7n*kk$yvc8v8y>9tZMb)t3xZE7a(F zb0XO-dQ(?N2b2srry2QI?mLn%JzD*^eg1Q30%RUAq}6CzmLjJx)gMTuDRj{Kf3S1m zNzPMs@`HCAG;L|G`fa`)>=xkk0&`{CPja)vdTo;fqQnCY9*XNumr%=H-9}|W-?uA2 zh{d>tNiCS3dMx>iEA*LQ*1{;Jo_e8@5(~^QS)}*D_mNt45#9mOs0;l(0w0OcsP!Xe zhN#l0ppXH|hQ;Le9w~|O6b;}__KA%8eg;;FA<_qXZPsRhUKk~h5x2{fbuLyXdBr~K z?88_r;6_|fqMFUacN?3h>~|=}VM=Bd$u+ITY_Whlg+&8zO1;PnEo<<*sEt5``h-cY zxT67oh5_-uDz59?zRi)tLYpMzAk8Em*CbLWXZ$zZN$h%a4q(ibVV)r~uLIZaNT#@E zFLiy(@<nU_({oNF?hO3{{+K4J2jJlj_z`w4qU@FN&E_`j)lBik&uI-9aF$G`lrMLR zd25!E8a9nwtU^RVw<tVRBlr^jZ%yVpLdk)DCsY0&4-po88dNEMW`WHi${0mB#sqt5 zbXJ^WXULAFwP_rum}8~lXyX~~!U9Xw$w=IzS_WuJ(YF^ao}|7e8Z&_nnPwP`nnxTJ z5jMj8<~V!o4NG~Va@Hk{z+j$gC}X|VOfL!t1xr3oN0`$C2jn!AQFCoL3PsW$6U$Br zHwKQ7X9r^1Nm|0wo^(0`Qc+&GZaHl%rLzH8yD}A$og*RhI)a$1#$5QZfgPq`ZIVBe z6UrctRhw{1X9*S{PIH+LMMy>o`hc+W4YornwTQYj9n4hQ)xNY)>x%g^g{p(a?2&~B zO;X^I7oI+<(F|v+9mDCIzsbKt?~2hHg|n2)Id3a@9+0xsjH7Wl?9D@cY${*<TpCru zRb>yhgvv2NafAppunp?cMpJ;Y=Hx@yVZ%%+t~E+rSa<_5L%Viy<L*IS!xOJ0FQ^b* zMWTAv(^K?&K#lso3Er_t#V~#rDGKH)&Wm$g0wD`Xiy)QY6@j5sS;@h({G%^&FP4Nu zTw=V$z$ebn4*!DW$ANCx87EvN43|$^honq~Q#NxDit>OQ`iFLre4=vov?%7h^|h&e z@APh@>_=??8rW+q@#qq}D8*x}15Wp~+r^&imU_~;lK}2|z^D*}K}?A|GRZ=Mh<<^H zu9XYZpW%%84&R}AUpjoo33dYdf$4Y=CaN@~i&Dq|4Tr5cu~nJQ0Si2^F<z3I?nUc* z-OyQc`SW-Yo?=x3=-^mTu_w(jLVM@0x}iM4;CN`pMNx^U_)_o|auh7=mQ7jbOcQ>% z7d-o34Sl#In;Tm;(2gUDOoA88$d3CYvfb_4cXe$tetr;q?2@438p*}GFF&`5QNy!J zWQIy531ketGAXMReq5X;qGWPJ)=3+>EGhROZz<o+fH|vmh#m;O*o|95xGKhk&?A|i z4Z|A6vVr<ig6`|7!i<qrmgGKn*t*-|m_csZ65JFw^5cicz!Pcb6Cl3dznjE?hT;?V z;7fGVd3Sw?mw_Cqn%=9i|3O+XI_KobP$goR6gnbB5H*&m6wkLNvI6<G<@jRMmfAvJ z0c(iwYV038vQ8OP2qiFU;$Ja0+YOw9eAWw}gT#6Ru@s_6E5=1B0CIvJoYHIX5pA;Q zxx+D?A5VZI*anUU{9{AoRrgevyu4c)y5KE*q9hH)=l!b>?L3GauJ&T5mG)uxWFo-L z%*FJIwAr$4iYu<UZnhk@W8~QP%`uYa!2!CCa&hWW<h0}}^rbS<qA%TH?myQWagT$I ziPQ5OTW9U2^H`&;grU2^N!Kq{r!sc_FmyzXL~BkT=U6vKj4#pKow7RqFB@?_jYB|Y zNF>j@wbXjCDF62wN_^;`PXqU*NiQ-54=ifCEDv<un@kVZ8%s7S<I>&1scWEwJm+Db z>;<<`c(m*rmlx6=tk#}h$$A<c(Tmo8>K=EN9IxJZ_L9S-+tDc;$=o9Vl^1asF!Yv; z+#83m5q;*YM8LbzoyQ3*y?o+NBXHE5Mhkna8KzYSWvagA-c;r`9#u+$aBMD&*4Jal zCz$i8N|idAPp4)=4NRwWA}xqsy9#S$L2_QMg!EtZvY~D!1;U5&#)6!OGIEFV_|a9m zdTeC?9pmBrC~g@2RfQHPjYHlygSB0p8f1c_hW&hBAZx6v$k0L22^2WH1+8OR1a=;m zJx*p{o3tdqs}Z`Dyv0q6#KC2W{PUUx(u`^+f@JRiL!1~bM?~FvK>~2ZO<85U2rNpw zRAd2*;Atk+T3BZ$8<T(uU+2I;pY8G2k^sy;KL`h4ohlp|{|Cl)^XEsq*WGf=AUY<% z->@}DV7_F+7Pq1_3fJ&*uEDke&o(qd%uraXnz_LltenVuFP?@|;ZkKHsFFfOowkuP zM4=ePEhiIQgI2tsyQU<kt?7KiF_aCjtj?NhUjmv4zih$0<$Ox1S`O3`BcX<UVtf## zFg<18{gMlk3oW?=x^@tC%d{${pC}OoRyOTA?|#Rr$6b;y`D9|0jD9oeM&jyE{UAG! z-C$v_TXut=gxvr+%uX)4WFaa}VW6tDEA1sZ!Ve{e6qkkZxbu{f!gQrhU@=1v_dQR2 z7H#O{c4k2-Z`K^HtZ^RswofLqQA31Wz?KdX2yKjN(-)ZsLB`PT_vSsg-(EnsXgc{W zL2JuN{#HQZa-S;8bdn2o;L*ad1bT{9CS^sQp3~D+G7DpwW!NxfB0j9kEho9*%#3I4 z2^W))Fbn<5vRw+p11hW=U2<JrESDy0J>rxDMR}f3h@4=0CDn*&0otGMjAn`P9Y@XB z-ZfwOh65b;aQ-wu)d{SiCO)1-KefRle%bnZsMuGNwCeBUo`1I{*raP4%4v&&HjH1U z4OuIKCJI5*j89h}+12Aa*0iz0kSa%SL|r7aU5qUuUlSBQb#eQC0Jk1-$LKTbcHjYa z#P?7WuAYVU!3XXaBe<*2gRlHp!9kMRd5N1HVh>GOk;7D`ERH`Q^Qvjk`ci_0KTKFq z#Ryu`Xp6GJ#4<=rdv3AEI!VE2>#j^gO>GM=`;kYJk^Z)76k3^1Uu|Q)Ou{^yw}pX8 zM?-q;c58@~X4h15!<%6sVR2)1WbS-1CBOqE?5W_*j*@jEsbUCpZ||Fe^fI+;NPx)O zqBnEx{V6vsd}IYnbnd!S^_ZKCWvj{6s7Wd?;7;xpL}I@8U~YPM@de~BAJe@LZ90(V z{~!QeYCrtvk+QeDZo&Ux;iZu1$twXh5zk*xJxRdT@BG^xeS@FYP05}%DnZdzzz-n| zN1YZTx^)y<|6RKAX1i80;ShJ<;rZy+?AmVUrjc~#l@;_UQ#dO0W2%YjcovQ_*drpO z#J6%C5W~t`De+)jnM%C_3|mHJ(j}#gcGC|!G!+z~PsH_gZ)ewrfwQN4dzMb;c*&jD zn1pJ1Okv}QdcZLBF|My~pZ?%Eg`kA_nxMen+3W{si!y>t-fW8cdb4aBd{i&B%yI3Q zDZe-Y(GIE5G{pmArc;RqDamrC1=6*1_79iTez%$y!S%WyIj_;JU{*8W*@4GVXbzF^ zhwI0fC^39<O@xTUMcp@j4!&Ae92h;U(POhD&f*d*W7Ocld?o0g<`Zn<)W}4|3s{7n zQTFl>I>=U9{B%j*Ay5LVPG&3Ei%qw#N^y<ZtXB_C7JhBdu&81k))x*xLQm!uC<M#@ zq*>XN2FuKZhoH6nJ)ErJt(i2jkk?$ChI$6!dhuZ3wxrkAr$Bdgr&gd<xlwK&Gu^(M z{&Uxdbgd7Rj99UZSXXzr?fKY^7HIS3z+BAo>8>0lI89Ha8U*){8H+?k7U;j~bG@c% zZ4uYBtQAEhGh8E-BRFl0MyvSddc!sjdUY$uM+*<_j|rWP+OqmJGSGAUv#{3&Ujp{p zu-3H^n)uK_@Lrn<%^+-BL;?D~TWi93k}bHnC0<6PKy-^SG|zeGdjcguY(EJ%!KWVn z=X$ZMxXG&W-rl=pK!*vxc=KA~GFb+LU*D60(ZnpV@@20@CoD{>RoOTnEc(jNMR4FG z51g@?thI*2vF;GNc5}p&Dpfo7BdmIYLI7r6AYDcVCv}WwtRbfB`4K-DvC-D0VxcP$ z-E<0Z_&F=ivD(W8$8_U!+)O6?=?Q6o<=)~6h!Gi>n`(&laiTk4fAeS?mjiEqhEGS) zwv6_dVmgUp@)<xyRobg}(^<nhKsrwcTYP8}$C<wa(Bfzt8}*W-VZ<vJqt$GWIx%L% z&$aLsf;X!)I=8IPhXCTkP+Wd>U;a%rJTy~sFyo`4T00H<rPWYxChO&3P+yb3p=A@p zuo26+y>@9ujthh;R-HyZR#bz1_64dail3tB5}^8v1-hAiO3Qzy$rK&E;zc(82*`Bj z;e!YFdqa0jU1|gBJd9nb(#891mKMu}3ytH&28`v8Dd%xwN4+Mj*J=w@M~jY1#0k)s za+XZ#yB}*9Nc`-$lqzN9r-tAYj~aBlvoK#*m;<eE0lF!n)r9jayW75!&hh`p-kY|! zaU^S^pT%EMf_z4R2m&Ov6QVe>mTsN)HkP{GeQDZLB#LBNAPPnSB4tzm{l=b=Sp|x6 z`#g7++cU=^YRSqaGBVaT5bwE9WxF_wns||LkeHVlbO>l)l4o-er24n>^5lddEI)9g zew!FbPhdz3ex3<=9&ZkxM4UX>MI$G)+Yzqc@<MfdoILf>c&L<(d5&<f8_Ss}=aS-n z7Izr~;Y^Gi6WDb(z-=03fgJJ@U-(K5!#otb&;H%$5$GNe!*h-||EkKz#kkYYOu!dl zH14|~Qnj}-fp=HDx#n4lb%uvQ&A{u`lm<*1Hb<ZO#-i`1FQ#AC_;;J)w+X*Jm4)V7 zCzIps2-m=tAf9b&wyQ@JHT8x~0vHRSPjtvtT2+XlL^TI-DVH^al893ztSs;n;BT*A zesT>lCjc+FYA7^fyx~@MRiA_egl0x-2~W4VYCC4*SW7j2snj7mQ<-_Vu-nv$g2IjH zEXYJ_K}7i?;HqhtD1cGiG8P7VIIqs@Vs1+q;tlDPp0l@^125?OhRw=$Jyh)6{4lUO z+L_<O^k5$t1-`_<Kn?`NI^s14Ba=~ZT5!|jvOYpq&mo7;PZ5NbTG&x+_QT~#Es1;t z%+6=QaBF+}(e^F4faBcRy01Lw+Uw^IS}a0Rf0!Pf&MP3Zn(M3PgpaT2QPgRI#a>Pk z))yWa7n3}koj0yJa4ckTI?m_gdgCz1Ns;--iha~_ma>fmiQ`jD$wTJhhWwBOeUl)& zs*US&EsZ<FD;D%AjD%T7-^IO4RbedCwRXc8PRrM?<aTn#ft0{QI;&vzUAm_iuqZZ` zWDbp0A~`YBzMbVC4mq})h_ud+Q4*>vVlJFgRL4`b_&m1yr%ce|(;PVjmk0(DsycZ_ zBanNjtC!OyMc{Jq^@3_!sT<c0RwweX!?c=(fJ#aq1%ZH-FTN%Hq>ou0Z86%rDp8hc zCC^B~JA#zzg2es%$52!m8>VV8GkELG(Y%^WOo<JVgL;c%aJq3U=gk(m)S%ElM3`f` zQ4oyr9rB(RWpPqv-(mfi(mf|!=$HI`&b(kSJwL22h!wql8SR&$zUD{J?O@5JPVmvV zu_y3So`XcA>}U5k+aad-5TXEqhJ>Rw96hGOTT#^;kmyuB4i)ku=Vmz8oRy~+<v+PP zenGx8D>0pO;=bnq(Rn~Jv7mn!-?G+Thv4->%C#}_CVQ4{W5gAl7$xosSAtr0Jx1D8 z=TrJ_Ia*UNjdB|Du!Z}I#Y94kKUy^uc$;GTccp%BXS2hpR^L?U8K;t>+6Lx})Fg!K z@HiT*L?x5_V~FYl+-o_()Ea1nnH;D35j_^1ZU8f6Jt(IWXzNS#QXnXC{Z;+}h{Wwr z2b1*d&9m=Jt8xLJh-QFl(x6^^m=uHGs_IMxl*EgJS{rNu%mP4DB*=9A!~Ri!yr#ty zFz5SypBiKHX%3y6BYlw?)`~b+fBE5Ue!|I{9efN<VSx#kolEax$ZhCkC?5K~*kaMK zP5ikaFj&d28WY$B$DvTS)|`qY1)tu)?-`Z&@EwdR%w$wzhBlfF>+_zL$vvv;w+sl? zQ3!;c{1B8aSfJ4%<tFZIj;J;Z{L7_U;16IM@LyyXI~$MTf3pk3MW^}5XQ;wc?rb;A zIjBR?4JxTIN`UXNu0~jMqTp!%*(ArMbmBP2DdkII8V3@gl;kv25z8}ULftqNR~)op z&oGQru~<l0FYE}A{bm!!+`Y|j-X_*`QoiRT7B=jh!C8&;jxx86#Z9p^v%^h{&hq(5 zIfaR|iJpP9fiOf{vkRGY{0nDeXRAYe@sk^k>wDnmLH~qN{D94nTzS`OiQqFq5YswD za5O&<)T-lS-2X6q9uKFd3Vrzc?6<bIHt#)ZwnMGdAR<rSX~H7y8rbb{_aO;I@bdPf z2ao0DbV+X{96+Jtq%a!YWnHvMYEp9v{+BQeWDD2aS8E>7&A1);kdVkwd=U*qjwj-u z`IPMY!Zrs?-k}^9%0n-u=B`K}tu+1EEp+mhrO%j@zz@)hV;|Xw$0v7YPM}q-SsqF# zIQI?8MIMHS(V{_1epmAX4wO4-p_?w7g<0V?Ae-8Pg>%gYrEEfCf0&QsQ~dIyqhhvr zfw@b&tr_;XcGF58ur&J@l-ARY>I*TZd@regLlFxBK`2{~OCSJ0-;z~-L7}^J3{fr> z9O4d{h|Fh<9;$fzrO3zl7Rc*pP(UrQd+X8NyZ6xuDDp-EB!Wm_F@ze%wDKvtV?aIl zA)XxW&2ma*)E&U9;vSF0=}(3Wu1Sp*-X$#;OYh12U0&);dP82bcvk0Vf(7!%Qp}6r zal+C3aE_I)6y^JOhWNho<HyS%_x0}s!uP&0r&Qe+2rv$hclV!d{67c1;fV)p!O=Y< z^jXGCcvpPryJR+vP3M?uOgW?yaV~KWVfH_SVo&7DN5K=Duo!RzHNH>RHtqyaT(!dx zbw%iPE2?>jxK2cgB!|o$+r&}^&~aBr(+1wpIvZbXb+UvoiL3L6SJf}`zzTX)YERQ- zoS-~No8d`ZXe@R{3ohlL!d;>}ysZS7+{e9+w@Gc<u@D+6*nT95x5zBu0WwpU1c@}R ziW)^8$tkCbk_$=vg#WEm`|DV#jN(b~*Ivd~<r_?7f^;C{uovM}|L2=;zp-1c-;n~x ztk6M<tF`~Uu#(5r1ZdZ2_;$S>Ghn6jh~R@QWJ;^#^?O-@C>;J{R6mCM$;He_>#ZqA z=g6Yb=;+0S1!Smo*ezxK60;a^M=Geb+31ui;d87+2&Aw*VSYynid!B|$|GTQ{7o&n zs!?+YLP3>9xy&%#^GF{|A=pAEa{p2nUHA6!VTbM~I)7p1?yW)6UKSNDZ3^|39$67U z;77+$lry|=tHn?#*wcPCd%wWgn%D9e>Dffi8d(!5>fwM2U}6sWMdWu0K4sW0%KXM- zM|<+O;zLvj3=iSHti}%oAB?bv*hK9P8Wc7E^Np-d4M+VkA)hWNE1%Dx*DoJzJmi*u z_XF+z<+-k=;iT50bYdI~7LYWL=ms=SzLI=S>sk}Q&Th>4w4*ddp>M3UVSN9jI)qsi zj||c9DD;}?tE?qvLUM!xu5=WFiJK7mPtXHs-_7#nqB_f|Xc;9H9to6)^wjtPUl-^! z-(T8*oQ#vbenFecO(^lITJ~L#>q^p)(YRW#xkxC68n>e9f^=IW+0Js1wb43l6U6xs zSgC+ON?>xwzTXV9>ghv~-_onFuiOO@Ri2S(Hm)Sih_N`(K8Nb&)GO8Op`Cva$d(f) z+~f=>C{s^*Dq7eP-~pdNg!IWoc0>1OIp*RCglbTZ3C^H<6ZaDIFkB`c$(01#PgOa{ z0{e&$vS?RH0Ys+(wh>`Yp)8UTD~n7uV^wmiOL7gcMu+kz>wVL4jRn#r8BWO9mWz`2 zYLAXdE7-O~7!XM&&)4I6Fso)=!iLe>T+4FYbg?rv_;oeDCivux9#M`BV#t;q7)V7q z=d$I_ibbw#I>TxQp2W>VZ$Zv@0su!Z<_xPmmIQWWxdUE{^4Rv8^uST>?;n9sf6tgl z?*xgwnq?n@G2>Yz`5zXpda*l8J=}ecC+d(R*k*Y-A91)Ty4<P7`jp)rN7W2nJZxT5 zP<q<4j1xi2=S8MKY22fZLuw88(yVK00jXP$tY|iph;MhZZ<1TQ;O>#ZI8tU>8X53G z<yzv2wZjGR3&Z2W6oec|Na^vZUCl*5%@p{@j{0ehmB9mLkdabOMBXHHq#T{H1VLz3 zrWC?bQ3iimvlG8qoMT#5)Bv4ca74{FWcQm?K2RbL^UJ?&d;<?=kz5s&CN?tr8Hu0s zEM%-YPij-LSN6k6a#l=8LRWaL0}-YJaX+{6OBC2CQgAWeSX3MIzPLK38+MDkV0E6S z?7`6hjrb<&IHugKqGiuDJ<Q2lQH8L~YF=-Yb!b;uUnuh?BWEBpi=#k$2LZ!?z<(Jg zENw=UX3V9co(zh`2%X@#E}7KOOn`2?)*9$02s<iyIWEsgb>rG(LQWKJN`^*>e^B-d zVjp8}UoA>u(3fX}INfIqYR1?^h>U+-X{TMZh=om(F5*kVG%PHq48C=hS~3LO{}9q` z9I7q9Fs-PK*>VmiQlZszK(Z%AZ`DE8JmO`Qe@}NbuF9V0bXYzqVUwc>*N@+Hq$uXK zj7m9STp8h@WdR3`Hxlnij>Ewf0S4#5|4gxwcv%O$rwJisf-o(YWkKYU;^QG9EuWUN z<wRH4t3Bm3={@Idv4tV*&?w3@WV6gB<s$4e@~ez9L;ys}Km5Q$uGNCX{j&62xye#* z^xajv(Z_vX(fju9r|D_(5aUMTK)PtdYpJE_Ut_xMObJ>O33saNdrT`g7!35eA5i`g z9faysl<a9H^Y6G%h48u^cnK3!LHg+QKwLbT=0Ku_rJrG&Z0cj%n(%ar@sY`~557@h zQ@4l~?OPP^{?Dh?`Omrpx#Xes1;|R9pi_k<Ied;W@Z>vWWkM7B!$%MF`M0<^se5Fn zo)uFrn1Rd7^J2ITsHkvP{lvqNj`9!`LLi^a7gHLrXlHSXYYPrGMe#k#jg2fM7Llzw zIdl;5{~%6j^6W?z5p*}HlzzlK_8dzgQo$VMI2ulXlckl>B6|ubdKmRZ3J@G|^Xfwp zD#bCQx!E+XSdTI5;byCW!#xrwX2j0twd*tfR5+5^Yvp`~q%VVF%MAlW^Y~@kbDb71 zpLvboG#_(jJcmA^Vovr}o%?d(>d`kWP%)2h2?5pdzi^%OqI#rgDa~Pg9-qBh6S;4} z$X0w)=7xQD%<H8Rpqz6QO#DCTWB*f&@#I>KbA|@Xnh|%gy5;8PqfIP<Y30U?U-AD* z2so7;k18a!dRGwVk7oX+Na+Lln&@$j#%WMg(!9CSGE`z?IXP%B0X8ouHCI}UWTIF} zQFL$*RBn;+^ym&k4DtuwM%bd}2I>lI=<@iuybv5F(f|aIJyh-q>OfE8-RBi*<z$8> zu)E>{r71>uJ<dK<OEd?eO;MfyDy)PM39QMBB(Oun>tHH3Jl6>YaXJ_qJ@!|)79NI8 zy_%rgK^0-Cy2Z9OWSHXQ=w)|6MZKfOH>DbETQ~<a-Z`4UqdPCQA3lHa<%5?S&t5)w zv9YyvbiDES!IzIV?%lh0|Nh<k_cq~w9SM>@&1>#?D{QnYM(ztJdI67#em|Dl4xF7R z74b&Cim;ZeYum0KEqjfO)lJy%U@(n=uCF$(hF0e$Xt%fB-fFve9@Wcug&}at$It?b z+zO7gpa0Bp1V+Q({rS%vj&FQ*X`ggB<Zti^eq7(jcX}<9RMa{cgrT=s%xfVw^J|5= zkQV!iDksb-&{HA7`5;d5Idz!VY=eb{&k>-^DM)oK+YSI%K&ZbxC>Z-kf(GZQOp5n- zOcQQ!2@6*(=Wq%mto54a^^>JF<UtZ&MX6`Et>jq)zq=PZy&8TROD7CP6q|LK^j!bh z`*%9zV;ZANuI~6;HI#X1N@J|JRO|_{Y|g{KwY46uBg^HrF?K7)GSa8vIJ)=f@x7j} z0!fc6{DuYRi6|Ft4#W#|BNo)T9M89yoghw2cJOXSP!?B8{{lU9zvpotQV(t*$$*l+ zx`3#U<6FG~ZqtNZI_Diy$KOX&v0*w5CpsoCF{UV$nO(41`kAp38hP>&nQ`7bHYSpB zBdM-Ez1B2T>?xuoP$#Vp%IAF97=v^`>MZF7iyC+48FiO?5L~etvUG|TC1Wak?VkE} z*C<08M;_2Cjs<=ptrXKb0~YWZIBT*1AAQPVL+<%?SuBet4@Z)SjtS(h^lY#%_<~4+ z>M6LLAn|pMFOY!Nvktx0p_QON!(NK0n_dhd(!hPu6h8xjmfr%s{X}BXFcOPuW^)h{ zNiSMG6wA0*?=W!ihO>1>xw<#G!QhfmI|jLG!ruQ>Z~M*SkkUe1{wuX6uwy0~M4-5` z*4DfI1D|9l^U%IjYQE)F@M|zy^NSZoLqFpt6k=+=FswiBw5tV2C`f!&Aa?2UDa?88 zriz~UD_(5*#FV1|SMKGarEdzA;dAG*;|m!TLEq4y<Gx1c3l_G(-7vZURvd-hH!*CB zDKorsYEWDTb<r5;D48AxrwnB@B!4%;_-%ZdYi4qMU^D~@%sDJ1A_Nt8@9MSTt+n9e zUIYYM?(lNTT}}oTTNWrf3pW_U=GP192;x86+PJtnT4F+n=B)Us03pZ`N636k21$95 zo1UaVx{!ys$J{CfQV_gJH%+WX^%U9hbS!GDglQn4#qx|RENlR0m|~ncl^hGSX9n78 zZm{|u1({Ns9Ialtw{Q>93CS0gvC)g2QKRzB&&>lMFr1$ofiu55JkC$R%C*DzXv_14 zh#hrT$>56T{mGpiA8m4ZgDbTj9T-MTq1oGw5U!PY$|A$!{gFFkn5%L67POge!-jD2 zL_gkIDNlHf)yWI&CV~NIy6&w)8;4q5A)~D3zEbbgO;|uwvI-QuU(D%1uSQGgnQdq> zmh@wG0lSc1LYSeOD;QvtAIEKnvr8*OwVY6H|6Es+S@}8p4sovkam`O@W9~@o!^vvp ztQufyhJZyTG<v;efBaD~$H;1Gi(bT}5eiAeAXnhzC9@a$)}a-8>8-V)sPUo)EH!eP zoz1xNFo6v1BI<zxS+u2-ntn^F66?5D&NVIKs?Zs`D{!rEcC(EQ{;(5)#vY!Jv(EK{ zeX&B)#}8tPxc(l;321KdG*ED*VAEn-he>Re*|49a4EEa?xb&a<e8x#_XEQ#SY&vLq zICh1;Bj*-jx*LR{w{q*O^Qq<`MH-n_!eXf?;&gdNb*A>$HxBkNqIi7g$H8Uq$MHJ+ z*e_ll&<*%`*&Fr-b+w!yp;%58ee0UduH<Oyysc*F$N3)9Rq&55s|83E_}5pM;zs6F zvYXU@EyrW3c$^-A#U#Yr*kfk|<bGIahB8SnJm<H#=9slJ(!!=3QH9R9zN_QPKBT(9 z2yNrt-XN&u;F?G5QEk$tW|XJ~-<cxNt1GVUiY$}SqdEtH;e`Px1Ph>MvVD!JvW_92 zC@_J9jB(QZLgAE{Jy-<?1%{!!L$+dQ{V6UW6mlgn;_fzzEhchN0vFkl0v+4$cy*-e zT+n#?7^+)N88eTl^Dh{LInU2SM65xi8R{7|<(S3ca)Rj9Y!48#`C2d{poXjl1P>y? zwH#R1X|W?%&s_3`%k2v~?~Q2C(MU@g?0zYpkH#4F+-@-=cs~VO2igK)nw?y0IK5vr z@WoWJfG&iw1(Ag2Gvpb4i9gYzpR-kQzMN+H2@)sk1gI*^DH=NzyVC_sCGR>mb+Fo^ zE2hSOb~NyT#+2t%M;+!`q_GMW98X=#DRXETVS{{yuS-Yc+QUhYKgKoryef4K@U3Ir z2}Bdr9h|E@`Gz2~`3a*3OC+b{O<KoZ>ZH^Hw?-Fx!klW$P5BFj<nes%HFTp|gYjj% z?YS>++Lw2Xk}0o*!lx+?9=|D>I$cUHp{s}0#U)mnt9oAyOV07SR!*pJfa#1<<W?qs z(E}Y;*RPc)h7W2@^ybsbXJ5$^-QFlo@f?&>V91!1f)aj~J(-l#cf+Sos4UdeCqwxc zq~UpSynB0?-+r1u8Rk!)@K})b?B3R?xjlT^(QuxZ6oE3UF>i|im8e=F2ffgSa9=iX z0`+6cJ3oY1IHNF>MUAcJcjc=gtAas_7)i-;FG2ady+{;%*!>hlp}nS)kuP#aB^7~W zd4wjT4&7Wx7Vk~$+lma{g{1JBk-n{?IO(CEc+k19*rRGLG3tldU755s3%Hnr;Eotx z=uMtulIuJa`NnLy(BIR=+2oBjjQzf<<JhOxe%IXbqe-O!?bz;p`zWT|kokZU13=(9 z#7(E}V}zH0BRH(Qo&-{AoKrk7hP;k@e*gIdkCj~y<CE@+X^y*MfPE{_ldq^@gYZd` zhM(-flR)0|kJ79wRYF)RFx7;^tK`kJ0gNfvvJ`kjNQe0zirn}?Mvmc(<ACps@#5Xr zFCPpaf^I?^XrQ{aegidZz9Wr?gH88&oXE`k5ZR~BmEP9Zqvo3QS6nP$W8_(v!h56} zJyoIzpD!z2<_66zkJ&kt9&CtHslij8=og+|06WpYJFdgiidHuCnCY^)h-fY2-S2xR zL%OxKwY~K)+sJ+>4*y0~IuPcEkvuH;oWsOwhwP)%>{9XCCt5PbTL$P^Asr64wN+t_ z#rQUTdH43hu}GV}H~DcsFSGlDEjS>*eZzk|n~vug-*9hm5q@kB?sBTcWURxq1UK3o zIvU1|4x9rBR!8M_6+JDxDr=wes}><9sU&|Gb0kpIa_oRU#E2VAZ7%KJfw;u>9!y^) z&ir^|Ym?ikwGoC_!^k=JI^!w9(tZ%M1Hnz>NJAJ<iC8EN>XT3FW@8sd(lLpGimwvp z47J+nH+1|J9|<XBl76{j?y0LG-uwTybZ|}VZpoqtL6V37536fSOKp^zbtecrR4)(D z%EeI9L=TsTaAtwTjMXlWf%9+QU6%)s;S+T!MS^>4UX%J=T9Fta$==jo@}fjpeU$JU z9Ro5FO!`<y<P}qWbgj^SvYvImq;A!WOdei^Pjg^b&nr8{Ihx5}dp&>i9a>2cy@&Ol zE&}z`JHz1^u_=(P56-IJ;B3nW)%;{wOowl<f?m1!Fobt|T*~SFppNo_!|a2Mqh_2d zx+}XzVm<a<_YW*`$m(MLNq_((&0{>{OVS4<Pn_8GC0Ay@)B_3Sc}x=rtw1;F@Fz?J zqTKNc1etId+Mp|!vx*$nmjd$){af}fY1h(gwBlb^^VzAsCNx0*T+)9*E;*bm=aQt3 z43PrBXO`E#|I^^$P7jSygYICxcL`7Wq;*!4-U3PS-dLH8$~UOIX!NAaw|^92zMc{M zj&2}&L3g;C(+u;=KZ?wXcRM<&=VbiPK8CvDe<i$mhr3CUr};ELp>RLu>l+)y(PkLn zQ$<O_G~dUVk4=TPK_(HzYmh=;j<JkOeLGXcG!Ux~=eZ;fko80wE5}7n)w&J+p^(Kz zHzFtCX-HyR_|v&|>b^obYN!^IR5ed5%Q7l>OW*kR@R!$9_WE+HlRU#1d+sUr@$y&9 zVPOPPql2wH;e-w`NyqpUKQ{u9EKHYAFr9HMc*BSc=<Wbo9tvEb<TrNlOy#^cjt7@$ z#-6b%`}j)WRrIS-vDzsm;qm#TQPEUuxdz2dV&tc=c*Rl|Os2q4g!$*-G{#JIlM7QI zH%D#??J7Mp@K4y<#gFLacA#EE!qxT(7&2sl_8FO4GLVK^C3<1`{5*9!9L&&+$0FBu zTXHznBR`dt3*nEqMK~hhqN4?QvOq>cjP5|LE_P#~wZ+4kBP7A*NnBFi9krb<s~&I} zadBgU9qC@+uEZ^_dMY-5nFR_d8MHLm@|-@xmTVq8*@gYqR`6WlWYDI*&n4jHEN|d` z=0K(=1+D3lKn10~kFr=6UM1PFffa>i_ip-Nm#81`0KQR>{@2U);;N?fBwE&yk80g0 zH%9~JLQyFMZXqsw$R<7siXbLH^l2G%(e6Uyp9_-6wFD#{vn)Hmeo4863~=S3^U|Kl z5_&R~wY4}nA()W;bV#K!kgJK;skW#lDofZwwf>By$T=JiWKCk<{yyHMke!9Ns(eJG zda4$wrz$>d2Pihn_x2YD((-|Kjw!FjkDSf+xA<n@#@u1JvwdJa=1iijGoT+J8g)aY z)myTK+&KfbcL#kFx$^f)n6ssWQRq9#`g#_GlrZOhjqxm^Toyq$C4sai+Xa7XDbS9! z#@u>{Vs(BOhC{+0SUa{{?l6(8T;69#AI*Z)lag*2mo<~mSizc-F66UPU9|=@#HDhy z4;J}mjqYh1q*j~&UD0yw*yTgu!f$!LB=vffR7=rLFzPG<FBRt#M6M->mVamTcB+su z#gfn|l_Hw-=p<`oXA7<<d|`*@hkh$*?!*Ft#BN(mww@|Gb`;Q6JXP!xoiTkagGm#+ zV^hr65$r(AP=tF9cm?G7Id9g1e^xMbf|%5|1TZ4;9VglhegWCK3;U+WB~tvU>;YZv z_=~W$B|1&(TKGdw4<@5=(WGi!x8Q|e`G~90tIrt8J(n1Q%@9#SSP{6>QYhb{H!cVo zPP7eb8<B=lk+|-n2b8pHwCGcPSAQW26$`oiDn0sRw->apsF?kinmaAH6!AnW>;VfO zE+3O)`&WQ3i>%rLZOmIf5{4r%<rw8z69^ImO=v%{(x7_X_(EHeS%<W%^NCe<tUheG z7R_+jwowewO}jp56ZPD7A0%R*|JevQ*Lo#YBLC^ya9viV%bIO~)ii8^L|<{ltmVwx zse66BpKT_iO`VwbCI{X&p4Aahl|e3F0@4VlMj7d|lriUoKoq6>oKVLy-fU5xmA_dQ zbHt08Slxb&oWo*Mz_N5CuQ;*C2|cyCPc$Y%^VqD08UqTe{8&-69S%bVz)+Ucusa$R z?pLUj#%@7wpUnz7vudYR{^C_ci(W$3PwPXPrYN0}l9_0dvH0>yWl|E!EdD(3`=*+i z=!6&#@@c)IsWN_x@s|dpgPk4(^N2)*VPz{^<+Ge3JgT#DLGHZ&OQguZPY(%VV`4`} zx8e}I!0Jik(@La0lj<DTZjmL~ut}HH+*vnb6nVEXT_<s`JPFwX1HW1*yOBlHCcJ*0 zr1j?sg;yT_Zb^v*WU&xUvpCPbFHT-w%wVy)KVAO#<DiFUPD8AL8{NH~!JQv5ysSgn z8eRPRi(bbGH=MPX5xoZMShUq~X2Lm9x23=T;?m!}T&eHuLkkD~xavk+2Syu6cGp=) z26h=)0aHaVX5f4AVHUkB=bw8I=Mv}tY$jr2csOkNUi^+NGRi$>z==Mz@{!J+I~0%G z@@OwTncay9{B|n{BhDI?w4icG`w7ai(;@3Dk~G9j6xxVytd=<1rI<iS6s%t!B_bS2 z$&$4(&gu#S?%1!7&_Rp}V4H!^Ii%Gtnc+d1sSwv6w<&RIe6q%<1gu_0xT;G+BB3w9 zLvTK}Ynwe|M1j09DKa7MB&SFxXHn$yadkfRGO%8YGbX$MoLHJ#h2SXDON2?EjMQjE znVLtOh<V5;Ey4GFNSaY+h(;*F8ceDwIxwYxhY$TrATEtd_aa|h(nDh~AqRo0dI$h$ zg!sv*9~k*vr`=N+PRY3yBw`1p#-CriGV7tkeeT4S-NZ~5iAwC;Wi5u^MU%*1l{ABR zbSjzyoF}wEK!_yLuvd>HoXlh*ve1`(vtxaiQ)s3jJ-8}IQgT{O7!ZcO4TQyA>)^c( z!Na<mNjq}8am=?iVNdvWf_x#!G@uqkyZg+x5ucJyAx*8`ZS*}s=%|!XP*T98Fj`}8 z@LyY*sC-xBg5%4NRts_D=Nh7y3z^C6l)Me%2^&_+#Yj^wLJ>--Mnmyea|(H$R_BKG z75r*)REWf}!qB=(zO*=bOGl=8ed_X%QBlyjA8R1NNI-kC95&Di><1hV9n!+kRAyp2 z<ierR%F{=~QhLe7i3&db&0iMzj~NKlxVC8n*@1yPfpGx;bb9aT3QvsA9xKwC!1ZlN z<l-#PsUM>uDXaU8{%yhh+OzG&hH4a){P$Gx7n^!vVIUUDjBo+0;-_`?4$H+^UccMP z{u`Xkgcry5X+1VZaATWph^f9SiHazJ_O$cBNwvY<n6K=?+dEvlAlZ%aa+$%Z<w@Xs zIy>(5J)MewUuKkP)%asvV??ddG(&N4NU0Nom*$*DpkO&wRFbcklSP^dBHA49t9*{} ziQaLe*P3R3jxFNMZs0HYK|^E&jT@t@LjU@_ue4r+)ybQmkSSv=MHFXr0-8h#CqPUR zciM#XU^z9yV@5^KxO7=;bi;~e7|jgK$-pVG+6A)3&s9ly?jni;S~dwqXs&t5+&*Tz zYm-iz+}5fe$XL<Ylb>)YAVLSm%|3pgPf;yISNsompPM@dx{!5mJ$`(DtG6a0^LS(u z8C9<C<$~hrv{Kh7J16dkdn{KwVU*}WfzZ(K!|i*$m2+aE+_aL<I!Fu!M~d(d<3k;5 z&9|v~UaOPpfsGTywX&`mZRS*=^A-L(U^pv`(J}$f0_EX8{ipG$wPWIi*u?PRp5-+0 zd$Dnh4994A6x=2j)laI0UyZC=3{D1pj+jv2d`3PN!MJ|$?bp31$qLD++f2vt5<_og zw^2jW@XHdImndyKU_r2gYYH{h5Op!6Dku~JUM;i=Us>Zcx=n9&>GHf<Pxj08^#d|M z-BjlNT_E!}iwf1(ZlDog!7?ia_2NcMJUfwP*Ng(GpGeM-5Rh=goYdXK9EM`26K|O% zU@a%tor9(ojbGzdqx3k_QM@j%Y=Yi$@CHUh-$bWj)M1ewpa<~wzWzLDe9^RI{+R2s z$0a3lj;SUbCs%h?WX<T6rXI%k#Zdc#DX`mX)HF|)+si#vzk_1-r4>Pr7jnkpOh7+< z6p+hE<ZSXPr90`zciNt#I>9SflKNS{;uKW97Ww#juOWJOlkc1P<7!}7^*o`Vhp^;K z0~mfT>2$K~<lqh%oEVQcwg2RG*qnpVCh8F6&cY;)kd@VwU~6(~yRrbohl~>^;WEH) ztu50>;uRpazzl@TKi<}Qt#Y`)aZ*w)23mZ(w;pUg-0THH3Utl*WMQX$@-%V1nim@j zE9DGrzWVlCVN(<~a?UxJ<V%NJFnX!qdm}J({(RV1&e($w#NMj#U~o0~8iuaGRp=U_ zvK)uC6G4iB=FdYd0cLb#D&Kmj2%k4rC`>LdI4%b1r!y2e4B>umL=>|9<Z(8}`hwNe zD}h*Gg0opQV}uZ<9`tW*ZQtK|)C(<8$ODLp^J=_2Dp4X}y7=dJ(D)-EYd-m2zkJN@ znnzUIs}0ksIZR(h@!CrRx7$o@F>Zn9WrlAj0X+?)hQrRL*fPxHDJj<|R?4h~kdMF# z=$Wd7MZ-NVFS?QDB*D{EBg8q8NPk5KTNHEnKLkBtUjW?ZC#b#>^p@ByTnth_F`K97 zA>#^s@<1f>djC4s|Ma!r4W~vcmcr;aV5Os3oaYo0PxUGAnJ(@SimvHJ6T8OaMW_Z5 zJ%VCq@}(+1I5w|c3;a#-Le`wXB+T)`_I1&D6(|<A<{_|26!OMJ4MLLH`t-E$?Ky?P zU6w`RnO55RETzFkp(HdAt%2EO8y^f_#-L<<znnThG(}>JI70)Sb_$?N061P<IV`3H zYAnmTRVWma4XzC8={}{YUROFau|l9}Y(b^*0c*6RRB8u854<}?UvO@fW<Oq^ofYE} zX5mV4)mb+RjcCLuv8*VGbhmo!8=qF*#aGSs-EF<EH@kHYqwAK3<e#2r#jneJ!hr(< zm(B$emli<T<$?lQEYE+bH*nVX7CVPkjQ3YR;nUH>*AtibQo-LN|AZI<LURT~Y-s+l zJndYg#epT<qo)>p^If@+j7-m^8!D`M5}{zsI&lnPN7{1TgQqQ#lHr9`55(27uieHC z<Or+l${?>iuOfa`)r(IutOir^FKKp9%e^+%G`hyAsr#wL6>!=#{ny2$<yfoL!ry+Z zrJ-BxK08K;35uv#y+)?i!sgKzJR3zT3T6&%oK`?uZ~pO@><I|QPsvY`6GZ#GzzF+W zTX(kz^f?sR!Dw3qzTTjm5*Ff6;)4yViAmjCcOO02GNVd76xQs5p`K%ssq=@+#iE*q z%^HAWIF&8z%BwJ_Bl8EsOw&2oZU#Y38lw^{etRYSbgUh)QsD|<@?33iilk@{!qGus z9W($EIzi&fN$hoRK6t#f)z5A{+In!mk2#}vA8pgW4<FofDnvAGhR=$2h=Da~wJSd{ ziM02G5MAV;Wsc#oLO2W2;>B<at6cYGP%GSwRnuemzUXxgfNWRzn<w(FvNqT~S*!D$ z3Yyx7Xoh4!`?%#$E?&XsZluroGr+}$Y6!fE>s{W<Ofu})P#XhzXm*n42bf~vUSd>o zwE5yo2QHC4hJS4vOtbqd!q^({vA(s`Umdd_Zt-^_%^kLg1Xici^07C%l66!39|0U= zf(NpOt`@Z0pyRyfIZ+FTc#^H~uCMMYPj2XI2$A3jiTDG(tO-Nw+g3IYl6t#d<c&iu zo~0OD&ct*(+tgEM8r4xXv&09lKuNsA{EWd7Fb*QZe^<o`ul1=F?+y<8-$L=qX+C-B z{bG#cSzaLUl>&vyPZt<qCMSK;6`yK6j;S%)Am^rpR7LL_MOQL4K(`sAkvEVfJhna# zH~qsQyN71cK90;~R_jaj!%BI?kD%K+JVc{awYBLJjAu~-3-MrqkGI6;IV>`4T^<x3 zsY22|Eg;QY)VyAgpqrBvXgcLD)M#c|G{8h3Z{P2Ij-M?0^q`&}N%myyvv29i^V2yJ z=Jwt7zQ6|Ti8qv+u1~AwWUPgtbN2328OZLf`<wUhq`SLy?`|*JR?@H3&%eUO=ii7O zB3I2D)fWNU8zStECPZSvz`qqAc6V8#(1@3Cj(~J?_rW7Rr?(#kXRW+QP!Z9Ukz+GT zd4h|!ms~J0G9fb!*l>})uct?oC8j|VR|tN!8jAtWIeY1EnmCMn<ZIi7gh4n1HrdH1 z3+ysm;s~4UsF*NITFj|{W2}R+E%+22wmRH-fr*1-TkG<env}I!lxM}8MSeER-lJcJ zVyQc>mXWYoL0skRR^8xS*Fw8`bc%>}@So>MIk;l*fB1LY9C9<9$rjOE=QKs;<p6J# zd;%S;#SQ>|#20f58jjqv<_Ffvo9Yg3xwjLp$v8$0*miev@UjO^8PAOf&ioGvoABa4 z<==mijZQanb$kp8_dn&|e^EN&Kk2{!%IYJK`ltVtfByx_xV-hprdZHU(YGPm)r;x~ z9T`V`adc6y-OTY7zUw>f9&wk={{_n85ta@scr?R*;jTR^>smtwWkTRa{yr~>z>@{$ zY0w1*u{x}nOy<qD#fJf<>}RF-lBK3`cmp09=*^I+juXQOPWBM~7C|@aZL^c>C``c@ zu)r+52n$(FCW!8c9ie974*r|m!r-Ef_+4(Y_1*Z^rple6Z~toc?O*MEdkg2=ioWTs zm3?b{H@>x*dLD7VM;wd7(5D3|X<X+yIxu7A2H)^hnYtDIqr1_Qcy>icmg5Mv$$%w9 z#GQ6KuqjgHc0m2Zc2O4}W!v=kSvkf~N;oI+7X_)Q$F*7%JHjBe(31(4<35H;GB6DX zOs4a|-^MxS7TPUHF+c3;!x#g#2miO@FKxr6yYZ!a64taCf$v?#55=a#%n-AocPvCs z-BQ7|Ql0^24)Ccc7sd=27CJ)DQ0S7xe6SS&ze~&yy++|f6gm(&KQOPM0_KCqD9kJR zmxlBbXmY<UvF13Xbu$hUiP4R~(kPsm)J@9eZo$AnY+91S=>w+Lc@J5*AFOX_+4!q` zW~t~DiVU6?2&aLiYs8th+K-lrBds4AKnH`%fk)&^7h_d7mCVR6#;K(piP`Mv>fmh4 z;#_B1cRw+$<QxpMs+VjcoAdaIu2##1^;Pz<Q4(%#!8+@sM<Sss4Td%-Ed|WAjsA%d zTRG}+!FYP&{ZfQS8+8B(HwZYp$7a8HN&+a<)pOzpI)^Q?aX7EeYmE8?v4!$2k3RH; z5&7}!2awJX0+47!;}lk@=qW;Q7`A7{F#NpZBZ8=xT$q#*7G#0E-FT(9G~O=;)U>&- z_w<q?q~#ODbd)q(?k}U;9hU{@Ov0%_QX8y@Nx7MpkmtLp{t$($#G0P}>TYW8PQqB2 z>y~FEZ8Z_h1teM#&nRBbz`MQ!+Wc@xNtGDd3#)8tljvxZMhWNe__)xT3<J^C&<7n4 z$}pFxrQ1}|+q)VVbB(7~YH-On#-=XGL7<Ty3kjkaS0Q>qqEhH112MT2jTHFS0ODSV z;HSUZ^W@9=jrJ=P>PyTus2b@q^hN<n*v)WjL;(<s+8hnlI?9P{NB8ilDWS-^P~YkR zqbq$v44xM1M!3`!50d6CTZZ-?=!mT)iK6JUkQ>m}hW2m8{chBvOYoM;+B?_k0@B7b z0#36?uh2UVfqWUU4TOq(bpIY&{~vDNzt>mNM7bo&{w48`F^PnBDZu2x#v^IQw~n@K zU!1(MQ@M}U0qQAP9rJ~5+C>#WHH!-_Tuoc;FVCZDGZ+w0K`2tfY&V6PF_|!WD#Q@6 zV3$saR@U`dOCK4CJ&Kp`=sWfNsGq4NkHL;PfSR3Ii;^Ap=y#|XgfY7fTlF?-`{&hM zi^$*XGW?Kuzzju)zZlmxZ?OydUN~^XC>n-+lyg#J;Gcmn)`Z7sYN3T^MtV<dy84=W z_+AR=qzbVTTW@i=7|TH3a!OY}%jX0uT8CIeZibL<EJwdOhyPOE8pY$y3s5QG*h0Sx zBd@UNDsbA`!zNph{*KejmzNyZ+IDX@InUObLTL6RdmP|LpJew2o7P@*n3>ahFDMa+ zO2?LC2R=9QtHlmw$0U>a53Bp#lFG7zY*HegsU|afXI3>;D1;^@IGVi?pC%%hHOR?4 z2WVES$*hL<NljzmZ>VTN%T85|cmQUJ+l^?@E(cVoX?1R>++PF9P=p@F$Xp=3P<5Q9 z(?j75aIacSvTRq(>`?HU7vFw;SIIW#@O}a&M;gS5dinh8XK#+?<!q6Cl}}HW2zP~e zADGmGkTr|NY-cz;KR+Lw-z8|sx8D!9H#hGNe|WJ0ZEt*q_>miTH~149cx&_S-K}A9 zbe3<_)bPe3w?_!h5o2*4NyOc|(WL1e4_esACz@e1&1bHNu}L0A+pIr48?wC0A5D%y zJYn@#4D|2PXI6(_y*|$3o^YNmkR>W=<w6A`Gx=$Nnn(%B%X<E{$Oa7qz2Gbu#!_7@ z8uD?97Z!JeviSs+#)~^eBJD=Np0HAh2>Aymzq!btGyR5375C*cr$2q$=D#%{=i{nH zcw^P#(K8?^FrS`#v6o;#rhCs2Pjsr=w#6Tu^DA~(GWj+~q%93r^&_6KwkO=wQ777F z_M`GcVclfG#~nEzf<R}8b=i_^)pQp`(>bP~lI5CiZy=MFL}&vC#j07qi%WnS+{rrj zey1;Y=p%Lqw0yWB2(kK-{M6Uvr@p9n(QNV2VM)`Xqm|-<C#pTJ4IiSj;rF%F90G5W zy+)E+<bs8GuGH!YKeu3o>c+yyy7oosXB97~vfkR;K%7XT`$pbIL6hdz>PUmq987_J z4vsjVnJ3NwwZ4A2lYLVqt};>j=_6#t9n!ZX{X;DyY?5?oV)8vWt-Ja+1^t+bx>@8% zEgkxNFHMQD{P8pjakLhK7n^`k5_8DHiVM0PHJgUT9i_ER=fxt(_XIjFH982eT4Od4 zNl8!@1fQGl3y`y@P;KNV4+`}W_E^(0rWtLhE3rxNn9|gkRH@43nf54g4X!e$;VZr< zcEcWKX8o`7-#%>QR2)=3p_Iiapcr(01Og!jBU49EoHu9-t{%lNvLqi*1C=6^K9K=! z@UwgcG@lvP_tOg=BtAwnr6@Vl-Z<n<;5G8>A76j9q4ab#&+AiGL@}ZA(dNUR)jHJV ze>JyRnAusdp*YJN!!MXY(#xdDGwe1HL;_SJsm-{mvaS@}YSuEx%g|CpPf<1V=5$7{ zv`=3O`bICylRqCOC*cjNiQTC4-P*ghO5eSaL1z%51@*~NZrG$sG;Z1Q6ES_5(eu+5 zPBZ+|gr1}LuGFXEJ211k+5Up!BYG+7l8NUvnHj5D?;uK&XGXCN-^X+MxOPpQZ(mKd z1$K3YJN>jZvt+guSJydHG?)Ly7>hu+gs%nQ0fbGN61)n1bxC{#gp*mF@Ss`{Uy)`s zJ*yRAOL}L!!JBP9DpQvt27#$(zO>7bN|fL!k??wc?HasZ+Gn)%R%RdSry2Ub#+Tu` z>ukIE<({iPO%4h93|X+L^V0JraO4TO`bJjUgN1bByxN?BIEw_$%?+}bg4vA?Y{)l& zpT>iebJr3T--gOW$5d;nn#!xWB2Saxc&vUU=__{vKQ%~pQk&mLLZsb2YNc}(mlTRf zM)@=UdnLDYj3M??Xj@#D!n#<DJ3ca&dipb>g8Z!Tz!9sp$k>GCt~@ZW+vS!IU&)JB zbk+M~EgIMin&!*yJ6DD*x#H~I+S<Cmxv9a^t5}{5D@u~`e9orm<0@7o(cQ*k*gKz1 zf=nY_Q<(;X--A3uXMBC7(869gD&+uQXkU!X7gkP$4G$pK*z^V$B%8h|9*Ce3v7k?g z2hl5^Nj)o$F>?-milDBw)}K1wR_>6i=47Q%^6|O~oi1FO!$KyAbFT3qzTlYNDTE_F zMfyI+ID~%?Zj&8kabSf)Q#I$@UDPQ@&5MX9WL5}Al;m!oa-nRracC!c=k;`|>&P8f zAJIY#niM9Tx%sIhF+I@5n$c0eLr20t@Jy$W36W^x!(3uD{Aqq8GG}BGTVqij{fy%| zLhM9#g%LvX54ea(j?(W5MzZF!1*82rMie<oI9MCwXb~9*Q$K6N0@DviFmCg>{6n;* zS8PMHZX|&RD|4cw{lxjh?dBC6xLQ|MDY(>ajyhxuS{k1iOeZ%);Hw+OS}<mlr#Zrq zw&z2Q@am`qL7SJ!09TtZtL<Ow!#C^`5(&7@P?r{Cvw9=^$pg<evaM?jzSXyU#rRuM z2>o>5NKvd;PFCnps;ZzNvPXMY^OB|kyMOIQWOP;F=YWdKI8|72d3fjbH*a5l|IM?n z?hL7%vMVaYbrE2oucn5EMqsU&uuF0OXZb9X^6&L9O#yPX;p?`7(FE?vw>K03F79I1 zOFh(<D%MtPzOBK~Oa$xYU|L5}5rPzx%%d+U;NHUFWUHUo0%p=lR(xVgr0Me%H|%Dd z*Y5!XBk(bdQk|x;>S3^bDyY1sMVzC7$)Hya&%@j|KhZk#yI0S=p8@R__luLK-AW`A z?RSK4Pl@%)wmxGuKe{s1jVx$tJ@O;RlXNrGu3ouzROphDIps;-L!sDqT5CHxZ5aDT zk#D#na9tSMij-IpOEA|Nn;ut==XQI8>iD?pv!AWA+>=j;Bx-y@cnb=cA{b?iRSbZR zf*#CH4sKOSV@pi|`4as?`6{}QRGJF$NN!G9fVf&1a;k;xgl3sEt$<1A3oOpHSYsR= z5^eGotdvhN`o{6`mEW+|gZ#k|`(mHBeMcZr3=*F>U+ucf6?J?;Nh;F-umqkYt^Sg< zHCl5CvV1SWB4HYfeJ>t!vJL-WouK8{Tj3dYT3$$8JA=49OheGdt4zU-o%sh&BuUrY z59@XyJob}k0dBtZFo=$UD^Gy5YDQpD0ut9?#!6`|!@&L@PY+g|4l9p^&t{Qrd-pT+ z7`J=d_iZayGf(n3lmq;{E?7imXh$=_BbFi0{Z*?PUC{xj`BG5L=E2BE3MNO#r+XuD zi6&i2y;`g~YIQUjCiqQ$T)dLn%iW*|StVQa4PdmMD1fz9d${Z{rcx~pH0#@{gl)}} z%D_}AFU6H`Wtf^Vi=R&NzT4kpenO8EFrDpa8n(`wzDv?C#b@f6Fi0~$Je*(V^F?_y zDK2yL-d^TQ(B&@=$K@rQT<`Px66cowgP*#@V8wD$Umlkys93_3;-AZTad})-Sa%h8 z7WAQWTI6H+b$T+dma|I?yt_O@K%>iP{{9m5Ni6p|n^!03hP$i_TAa&zc?M5@xJ0w< zCB~9f=#dBE34vY(<#9LD;Hn?T>${!q-VO?3m++(48J^(d)2co#&yG+RkQ8RY^6fl< zrwPZ`<^Z^CZ~w<1>*3Rb4m#c_zYm@N7$5ZmRw4;yUw^FEsUYkHhE2VtwI4!@H?dUh z<snv_om>`YhsF5vbbeW$om_HJTMXF8vFDdqSMRLX?e710zH_kN+yCk5!JXcZ!>7X& zDs#KYPo(NFG%L?=1zJgn8$O}GxF{}mg05Zuw_AHZp0AIFJoeXE2HkGLfH~&tvR-_E zHO9{Lr~zPmS`a;$lGRd<-qd+0c0ZIqf2{97gZn@29$fCi-&$;Zz%9=CO9J~k{OOC! zABXVxFZuiY5~I(0d_R5m>%5k){DfN<-WlBCag(b?V&QlJ?mW4PRd@HFzj*fc*^m2| z8yme#ym0X20sj3Ip7;WZfQI)&!7+e~3QLqT`WXH<KcPGwvC3rsq?+-Jx`Bq{^Lak| zI-iMIp_*|}&VIH9^znrGt<_B2y{&)Uev0(-WXKOZ?JzPuNCBW^+S`=W0OF}U8-DWB zNJ#c9Xp8a~{l!lZ1=%Bf>dI64gCAVr{<8-OWkH^kzvZzxKC>O3VG7en>F?wfpz`*2 z?0I;CcD=M>Khtkh|L!*1S<LnO^QWzykPtD9`bP2kHYSM7OU8&m0`F%`UGOgwJt3td z-Zk!u`&sv!>djGw6+V#?`rO!ZN(C}-?PpS^9jjwAS_|Ub9KzbXL-8FmnDe6r`Ukam z7i#q-1-pct9JTr3H{V$A_F%-DFg6??mf+SE`sWk)n2ehK%CZ9q6LTjOq9<H=e8Ka_ za`^?7-u7>!9s|Vq9L||>cU4t(D#}jDhikGA2CxHY{h&E_2{y&Z9#IBmzws<^zm)|1 zB|bd-OGvV=%~OAG?CWcTNc{{GG^E6L9~Uy5-6#b}8IitX)N$S-LaFVlR46YGpfMSI z{pE+Z!h#!>WB0CnzDqs8%20O<_dWT{uXtj;5ory2f7K__XWN>OU@}G7rUA0dz;d?^ zdH;atqbB?f{>Ty1!8cS$8d{dCBR1^|OlrMf9`rQvJHkGa(p2256%i`DD4}u{bVU$* zLMl#d$54p)0+c4{eBTy3YSf!2(3GH}EFQ{H06l5}a511Ghh8Ssv$vLZU|%0WQ<P5b zj#84k0{&hzzc^gNeCl2!i)2xIAmit9nyMo=kTX2`B6`M)zwErDgEkjfZ12E}V9_O; zB>Eh$q@L6qkxBjbS*?%ODAIje&d^#<$-s={J1>4+l50KBXpe_ZpV`yZl(k%4BAPT6 zYgeWqvLB5;)6oJ_?MpOuASk$LwzhPuP|mnMLkO0{+_2p_1xBsuq_l3@4h;$9zs&<l z$>0K&o=r9Z*;9rojR<KlG$qgQ_r+`ivf~iuZ&69bQ(CWl0qV=)azWWgd{hNAG~Bt! zwiy}P&2pG~K|5o~$P-H-iCsflL<lY{x;YP%E){WZiUE_#Rt!-tw)aQ2aylUUxQwRx zapb*RaRn6KRJ@ZSe2!*EYYv#p6R`B3u5&3q$0S_-+B2QSE{}-AjnjUwX$}YXh;lAK zDkNkK#bL(OpaPS5(B&CM3X<7h2-^B3-0SMOGB1vml;Sg|?*LI1f$v(}wAI6WVqXTS z;HLj*;JEUJy9u9&-xX#_n?C5kSOMgDHT&Rmx8NYqd_2J<tJ94~B_q?qlbA~rXNO6? zPVkD9{cM7>Q%%Nk^-384HPPp)Nv#iHUqFhJ*XdC!Tq#$jZl#@uQEfyCrjzEa;+B1I zV66#U@l|ye9Yi3Et5J$jL9hrtFg`U~%&|N&SO3=9A&ji%NeASNB~&;m0oM^ul;z>1 zJYvI&;-)dAnt@YmEYX@FDblc=Ehf5@X7?g6QSwrQsNfW%$}%WYysqnIQKy7;!<!%a znV4-xrmT%ChUF-@3OD=&p`GjAQ3)ZC!j;aipwSjeG(Y}scmsbA7S&gn>-Rjb3rqMC zwW69~`kJgfqwu~j^UN1ErWj?m=^yFH2P%xI{6DQ|R`?BsZ-EZ1gv=YSB7X5ZGwBgc zjvd*?=DMgR9@Cdh^&n0wbs3aQJa9_lkx$9zM<mr))i|1uvBvCczv%_JwWuoEY4xJP zpVQ&GjK0?|v%^U~eOK!_Uh}l#gyO^s*Jea+Xs;mEU70mkg5RM0C?Hjt`>@>Pe4`dR zI`;z-=t%g+>_7Y=a~~h7JnQ^Gcy>gj6&-+Kd4zbjHnZ}~l8A{iV00)>z_j9A${w{7 zUr8vh>vBAhcA%BTDds?A-&9{$<MOyXA}N3(;fnD~f*nDm6^dsfpae>DzqPf!b$5HP z7Wv`g8HvsKVIwum<Iv>_mT*os5}pV9?Wu@jF{zXhiceUVa5<$|c>+^Ix_$lf@gV!b zuWddJIQh_o0;W(L{o_9KE&Dd8O0eK3A2@``fFYL0FfpZ+!r<6!LN0(41x_evYbx*O zQ!Oh}gMiBsxER@r&4>+vSf;!^2yd2}!b-DY*9S1wn|HVGnG3=x{P(%W7NXN8jkzd0 zpysn~+-A>LiS##Q>g~5q{pv-Q6ax5OtMcH|uMMDrIiHjTsjv<eVv_Jl6XC7^4d;6J zXoMFx0qe{$ww#>+3tr7@;6B(iR~*5XPs;bv0TyZ=V~DVQj46rWn1$~ox((%D11T_& zNL``Cwx&#|p$E~`VAI4IFs&#|z(Ztegw~5S*f<9b{%<+M#;pz-f7#80P*5DsEyzv? z)M3793I*_-6@e0>ZOCmahvHwJDBer%rrlLyXfC07cnWb8VG1(aU5uvLL#nr_6+zeW zdzIg+uVgDT?^g3`@J7Eai%^H(E(czp8nq5Zb6~Z~6-|N+BFe|7ezSR7`_8o`$is)0 zI@}qIFH>J*2Z78RU&nI*EwybU{fAo{e@UgKSgeA#iF%sF=kYjxHsvrf4C*L~*$aQk zIneO)Di-yrt9_<PlDh+pDTjKM)9>;V2j3Es<eHjpzfnBCg~tVLq^$q>^;hsN={%IW zbkn<Hgz<Eqn4)RZ3hL)m7g$WaH^YTWR$X)K>1KVh`^Z>$79Y4)XRQzC(7P!@Iq31C zrBuD;$r()}p38IM&%5YRmUF~XpuP4F1e=7DxwHgTn}CRumfR2qW<{pD%{s4J?d4y$ zwt8`WrD%N|^a{w{MGdocp1mo5`wh-(D(i%YHcTl-#u5((lCOaU>?j1mFE!o;3OXAC z%giT}jra9NO$`jUm0OwCx*M#vlMvSB$kRRH$WHNnG4m9&Xk<&5q+qP2fbCsE)!p?} zA1mGK>!lAJddW3zxdv7u98gn=6i6?>B9q>&$M+vS3}KLdknpV#4B4g+@$PKAGFnjs zLgf)3>mB8rEB~7i%teTWOZkL$wVjKk%iw<jVWq2bqq(%vPxp!~_1cZkUaAObKebp~ zV<Np_IelFWm6JHWQ0M(SknoE+h$w2BV{HS80;F7!{XeW-P2ByUbp)^~|APAWpN6W& ziLoi>>NkaL!)}hv;o&=u!6aRa7gwg;SEc<vNC_g4p&Vs#7j#YIN+K(FdT!PIU{p87 zjSu?(D1c|yFMVe##^Z-WnX&5kB0uS~t+`L$AG$M96Piq%A?e8m&e>wBtXE?uR`|=* zs^8;g=s*aCN5q7;7RqQe4LOljFVuSokt@QFi4AW?;CP5+%3su?01bRXlvK>H+7@_~ zIx48WesTirX}NUtGJ1~6tY!Khf%nj+La_p*<Tz+@A9gK?_xPN1J@`Z*>VQ^IRsRyr z{9E{wPj7vv*@@5rG<oa!oJM_f^}YoI_2BBphWhxkE$&P!$58}lagL(ybezw}RMD<L zv;(%a^Cv0BqpN`#&W6pY+56_m?d`)Me306cs1YRM;K|%4ZxhuvQs1WfjJ1zgxYY|G z_}u>1fl5tt_9}EUi$g)L@fTZ9pA5g)CNXNAU)es0M}5SFo#)l^<WwBp^IDG(F6b^c z7@;x!_NEp`(GaCy0;s=Vn873$X{T8w@#}obnYNf2C*d`iccSq%EJ{%pH9@bKk5Q$e zW=IaIwvDSR2=rPM+R~a|adZ>)LV92rn<N{*etEmj^5voeeg<R>gOPv+Ik?#pB3!6$ z8zZ~XL**^X{$hm@bItQi0wwy{owNMI9gc3PXUln6Eo=RnE0KuHA|6row4pr6@kH@V zS)~_TM<=%KXjdA2IRqUDzKKrzr>OToA*a87{)SR5eOv=jKK*&3rcg#^)9Ty&BK+2p z%!2<qDI(KOr7JSayBfNXw7LJwK@VMJ<lK|&NbYyzyZ$5IKP8Mw7S+mveN1cAT*1+C zF`S>?voREkZ*6VgeY{PA`VYn7-%5te0WtY$_Bikor1j_GE`_z|tZt;5jCJ$rBqrn# z?fPV#$&;=71jFOFdfB3yZA=iVOl1JLP8tX4ah#>UoO#wyJU?MEADe}&FQ_oZ{RcbQ zb7*7k9ILnsorsXu6{YsmA;q@x?+Y|TB$lOPi7q0WPaUQ87gB31KP2SEit>Qy)M6J0 zP6VEL3>|_+dAqkBZ9doxbxV{r=vl{~j1B%La3pk1Fci`;43T~_zQ8M^jS7y!IH(z` z+vssR?`=MMm~Eh?mGuxBvDchz#&dCc*W~YE3oJrR*3uLMZz>|ExPP46$7HG?Lxw<( za{6pO&p)Un?8Qv9oo#G|TJaSEi7q`vgk^+$z9EE!I9d$?S#u&Mlc}ylQ$*oLV&x#9 zwSQXW5Z|44-ITXjb1<R}Xc*5a0~Fmh#nF-@JHph8TijffR#CG-640_0&@@KC@hQRG z-v~~@u%#$#{Dyq884T23Qj4e66c!iPtV)SNdbB7c!#f!Pc%iy{2X>;>=1yYJ)d^dU zC7RrH0kNBL8(iQf_GfVsLJ2oka>Abmf(`<yxW0DHh8A7FMrqwhCHagfEjQv|tGlX1 zc{#Q!*?!aqQ3hE_>G(9tef)9YQ$w9w*<VWBm5uC>_GhBXmLVs^ow==<5@Ailu^Bv7 zB}y>$DXhcM(jjTLv;;C8BEzAWV<&i|m#lESdYWqZUat}af<Vb6MfJ9+3KI!l$Ragx z#R<(VJ$JM3*2#;P8Wz!5MGyTVUql1~u5X~oL_*OH?3GSfK7T?ph;mNtlmf|`XNiB< zHZ8%UYA`FcGYajT7hG>w<`E5o48K_82x`$8T|vFD=^U|W=iA78En40b>N)jlHv>3* zY1p<frRaOT^n1~}N#Ek)^F}H%n(^zgGShOrnw4rUOiK#%4U`c*^YmUPVYtXL>RMBf z+8@<t-y8n03vcxiF!;T$mLA;+*<j=(>-OZ_><UH&YF<))0sdTFVJPc0bUN*wz;TF^ zoUXcDPLt&IMB(o@a_W7?)VMmMh)Gv&y`LOEab~b0O2lUSmdh)yKaQYY7NID1GZ0fy zZQRK!c#JLbNHBle=w~2M{vSDf*37>oSe+12Ot%`UOFShE#q;OSNHgZ*MsmHq)0TIa z^pmiy{+H_JU<#Y@P08@=ZCz$I>A6ox1brti3l!sCs~Crw)&wmF@?0Xssd2XUS^RsM zg~D=;L6>MM94KI6G|j))khMZcymeU36bZ>Ek$@(-b`v*CB*KT<2`%eDH~nWnL!k*r zR-!~)?PbuzCFxSEJg3}cZ7ogTrPU{n-;Q~#3%Ytq=tNj0{RTlQa{ZDXD*542ZHaiM z|IoTw-HcQNla7#?z{&!frCSv(hVg7#Tbf3t#*^{qC<@BNT%vYZa_8(sc-gX^P4W-5 z1g3P+4s`cHZ*4`*t1vSX3euWWq4YwZ^je>PQ%_q}G_N9$MtsCIBO_uj=x*W_-L=A$ zyk0x;{Si6Q(uQ|iJ{B5^Kd{q$c9e{8aF)*+8P{>T1Pxw~vri8^&HzW}z@H(~rAgY^ zCc7_w|0v~qOh+a+9SuzlvPL*<0$~aW*0SrwEKIjT;9c;5_{88on;FD*oC29BSr;VO zpA(=v9R2SKuLmM$KtMt+0;u0hv0cJg4A_Ot+Aj50j37FX8o99|DR4!kjK1C0K+_vS zjjVEqm=vrn-86Sp>fO>uKk44`s-%XbaY2+%dZ<M8aW(pgvA2fI|1m!993Xr|FvX4{ zl+7#H{AY9eCYkDVjM~+F>E32=hXT{)NZ`<fL;z#--~}3NsH)eJGnugi6DlWmRxD1d z@tUh)*e!ZiFe`RUN77rWZOPg@sJ-jzOS0rYl#A2WvmD-p!P@)8L^S;1YfEP!Y(7e{ z!Pcmv3nJO6zh0N0a&qwnOzjUY%g>c=xlf50%geEP?L}bhIo^it=(NJ$O8)MoZk5-q z2Df@YL9*pA*Lfk99zQ^kc?KtgKHFIM$hHyo97~^5vSSxJB8vo+kH3`CwT`?NeHVk7 zEhR_JwTa^`upw$~a}u?pZ*XI>9KJc|3<ioQ^#<U=SD?i$5cYkFsL?fgP;)f#*OVH6 zBFU>j;EKqEX{~gFrxOW{WFifNJk9Gj5{9xC?9P3GjMG%j*wCAtVSS0s@g)|@Z#Xg! zu1ydXufOJ4Aogc}Q$k7VS8CbX4N;P>(sNd6;fF%9*)8TVxQkhA6PaEkr2A+!WzU~F zjNB)s%2XFR`4m{2U?8nJz?dsJ+-dlNMX@UsMB_MVf_o)MGSI_uaS^HRKr6?jo-GE& zul9fgHFsk$ek{{!XAD>9W5I=5AP>+novhtNO`#hRV~FT)<nUT8KGRU$jzjLftY8!Z zrOlaWlqy<uOhgQTNYn+2Iyv5P6}#K?H^)bn>mW6h>W%z4a~6ra$3}xvsBt&j6Hevp z$LXdzwPA1JT8c-<%YBN876mL?XYs(tJLt~^Z3MWo3yG)Gjk<kU9OYb*nFKbD#Mjmj z3pyfz7gB1{RKmc~Tn<~LnA29N%LO~qYVxf<-0TfpFk-vNAu)2=S+&$MagyEFSU?<M z;`~1>x-%c5qLw~<SqAVokl{nVRV_dz6o4mFi@ikr)VZYHy5J=4j$4MN>>|Mg#`nC7 zxJ|2X2r0Tr+;*c3Q*NLP+idO14lxL+bYnlE7UZDmwi$U}NHL|z8F?#?mO$dQ;YEpA zQLw~I%@+$EP@7^(T|`<lD>7TMY@(yERV0@%#8gz(m{uKWsa~^{eo}lR_LC|r24)=R z0m`by$-Qm%9y;EpY$I~so{$_j;GEsyz`|M$BwfN5efFQv{t4P81u0NDVyq&2PW3ae z@|I2;R*k2ydkUJfmVA`W&*;Ve`+O38>PB+Y_sAq^^Np?awVgO)mCho{h?1=l1-<CC zAXm#=J59ww4T&Oog`>{Vd<Z#twE1`^dq!@=i9p4$R?^C)<5HmQ_K(P2qxG&>R)1UV zWF7vKYF4qqp03K@c-fm|cN9)O+<3;e;ttu2322L_19${nbs~LI`HD-F8c+8y*2hy< z>vW|A8Bkhc*^BEeX&f%~(KxDagax&nW|079K$*WEbG#%C-QA@#rV+l2$5u&4DK!+! z#LT^sVfP|%NB$Uvn(v1RIFMii7tirE&>O6z6tQ9qU=mtoG$6@MBwmFO30ThMy+%=3 zlm(5}JA|%aY&Z1qspN|Vz$7A??z@N{FN@(TZ$O-XM{lrLE~Taj3$6sRJi{;rY)TA* zngl<*b7w8PgTdkRvXFee{0Qr%sOgaN-!yp-p8f9xPnG@7ae^P25-iI{4)&Jk8GiU9 zfmNGdPf|m(J3|6oM=;efJHtr@LM0Gm1~{<k1@|aqqjOK?vXU&eZ;9v(4Yg*PxUMmR zSjR!cJPw%Sfo?v2iUa!;jtbU6qpYg4*%GvuH~59@j3R5XN_{aY;pF*{Eo&VKc2sN3 zge1tY5M2Chu&Qa!FQq>}^=wyM-kW5$5oi<@(JC<)vmt@4#vqb`B9H^AA`W-=3;|3g zB^Du{EzZi{ND%2s*%w5P=REzxVzHod_K2;Q!!A1M%Xb)$SArNcaDi4*Dxe;PsyL#A z=q$l9zj{S_7>;D1)3akIUtPQ50sEFGI+m9GgI0jz00hu4DMW?Dg|WinYakk@KvraD z>9983(W${Iu*fdX;rk29f6wOSI3;ag)|qhyWK&AV7?*_i*W39A4yu58J1eI}l$EJN z4e6%SEBBjhHQF=*EhgF`F3Zuj0?TJA|MVjgbev&7ym}B&r}R<FqL&xb9cZ`@v<pXT zalUqWHk%YQt(5VJ!dx!&0ZbRG3c}EtU0FhnehL-YDKKox)r|VH7ONo=H?zUpdo1ly z7JXIMB}j#=HO(0-qAPz{*c4_j$~F4$VKoOfzk7T0HtfFf;*|b6EpWr*pF^~Drc6U; z*}y+TP~qep-7)9$l1dz-?T0hp-(i#o;?Y#7?7x#R-&ZAQ4%LMa_R(qej><C4izQWk z6`{K;gJj)QY)L;5tH5!!+<Xy&DaMgF-YAbsc>mO0Np>LCiAal5)%G)}!RFm<8&{Uq z@RKyvH`yV=##;y#30rrahYIssaV_z~(D85zd+OZ}^L+N@q&j+6|AQm&tOjFp+lxC6 zSD~d9^;IUelh*Hr8TbLKTpg;7bSz3C3gJ}a9(CHbZ&^hpF}0Rcsx`fn;Sdk|NByy8 z5tr{l`k<^Ui^rz7Bs|{W0^8y5Iua)@hF$fB)62LiDRQ1qs^Fb{i^v&Rxr@L<vLeUy zT|~9OQvi;Za10dF_vO5ritGA<u@+luHow6VAjE~<H-UNWIH#l_Cb|%N{&|n{Sn%X| z%K#xA;2<R-h31EKHGy+?#N1(Lb40uW{$<Vpe=MpQ{1;1}?rc1U|IIEsBbn-EQWJNt zm!LPo0NW}@Kak8(s#RGYhfr*?nFGCJ96A%q1|=rJo+{^tPLe=>!&hXWzg579R|ULT zVEpqpZ+3u)E-(ui4y2K7vg|CMgRDHtcutr#yiX^wQR-e;+>>or?tXi4SD*U_%ttlf z0EGudl<-};-`O}PUbzvj?+Ay(OQVgm>bF(*7{VCZSaDy5wR4F3Y{X-O1+@jY_h<PS z{c$^6vkRdD{0k>@XR9;PX}At9r&1vh0?!&XhlF=usAt9g#}8D;$FMv<&>OgjcWuuQ z$;D~xf#jla>sI!JdcwyZ@@lF|%rk+f&hRJxdx(wDz3K7{&gj`ijL4jIe(E9~zzl8^ z7ISy+=Io-kpKtv39|!ASFeEeegqs2GL*i^ra8y8VsI}_WBaGlKY_3bnX1hGB7K`fa z68Bl}iy^c@v>oK+SePbaw)W$a6TxegghuRcZLRl>PIvEau45p@{msXZ5Q*m={MA#m z0(Iv31PK#FrXYdLmNQ8gdG!k9&3wvXA>lQaJnUsn<?ATWL|HV4)me)|HzFWI|6VmK zrlFjgcge4QC;gT>yZCfV719;+-gt=s*m!Xpi_jNE?nqj2_5|7webBb1KgeJCh5V(} zvQ<-}VbKqwaBFNgw97f{ObQVm0V{gn35MrC1b~M16h4Z{W=lHBZH_m)-7`p|x+pN; z>i*q_YijMVPwv^DgY*lgff7(FKV){6sN(OMC5gBR3WY!MizqF3+UsOrBT$SxEpOJ* z0$QQ85N`1-(_m>ycIxEk1!{|+h`|AM_#t}%be_E&pXc*&-O+RvAZ&Q#Nw)QnB;7ap zaXv4z`-4r?$?B|Qqa(ej6QSvlaxK?!C72Iw5JylcR@>VeJj}ZJ0_}D6q9<rMHG*Co zVIuGeV_@WPZqBjr9UgJ&J`-CFb75H4vs%)-Ov|5@7sVuGI!QFv3C=WwO#p#^`*k*+ z=f?}ufelz=T)ZEg-yKx*lOd4NIsLaf8{V43)J;Hb-rydDWmVoPHf1vPklT(2ucqcu z+;y!jBhTzvq4^tn%D6L!&7!)`?4Dkb+p_t>ZMhJ9L*Fe4>P!9j{83e^^DJKDj4RNo z384A)^n2QIsj;5!HXTZs2+BkcQ3zu{3vrWf78<>YXQ9!zFbhfAVysy4d7<R^+iUWW z@;u}e4T8x5K#_wrUrW9%-X1US=pXBp{7Du-m*QXoN1~YyfCpn##OIuj{@n1d|8cgC zhc|F=GzipR@!x+IH@|`duVk*s)5yfHU|`q;0up*~FO1;eXF+4P;^V5ZVzSY4QLRNh z*(#USYS^PctRLZARtnc!Uj2Ec05Ml_S$<SlO))Ru4T`)NOpC=ZpMxIozNm-Wo0|`Z z@c*|T4!0f+?%x}1-5=h9xk0kn*xKCQe!LaTH|NFedBK^RMNUE9q-$W7&&d)vCo@7A zATk<$3pr;lS2(cYlv2viK^GyoHE4yZm?{+Lksw8sG=0Wdr77}5sSF6bGT<vCZX^my zSo{H#Q88Dknv0`LjwAt44CsS&mPp<%oId9ol>s7|1kl<`dhj?mHJf|21a^)g7O)67 zE#qo3sXN$*L-^L(r<nImlWW`g_chozZXV-^_=D>`)w*luXudrwbc^DxulSWYh4;>D zd28+8VA<mMq=rq3;D#;j-m!|%&yT_6D-TZ%gY6h(mN(^ZaK`Utovq@m13Oh&z1t)M zA{F{HFh5e1)~><uqmNpDt{w>A`2UWvlTQ;Fi?VoBnVdglJpN0u_-j?Ydwonw-k3=1 z)wG|T!o^n-YC}jN$7+VgJGc*T18<@TAT^b<3lrVJl$dxME&7D+Vb&<=J<bvkN3%F7 z@^<S52X<+Xx<0thJrkSFIF%FnS=1phlG7py%nRX2s}c)x*Pvyc+j#gElD&nIEEh65 zlFk_SP-J<`U7?2uE>t;<unB#1eZ#3XIAdt3i-s+nDdARRZpOVMd}GXThG%6>F`&T# z&)!aKQmP1w^^2&BoGKhLm=hNkutOYa?d0F@kt_AJ1)PiX(+a-NPPW0CON}JQ;fWKQ z;t|`>Xjmg?lIar1P*(v;O{?qB`Us2~M_*uAA5QeZS77eyXMq-&AbVHVU9@7%sqMDi z%Goda$9*h8+b`FGy;G{g<b6I;z7u{6Iv3hPFW!*l=X)0D3%p9(l7IfS9K-T_OO}<I z-q1T=hZz^6aj;BY*DyIwfCxKT_5>^244-PP9I1!%B+pLg#qsX#VSf8*{$!XxeZu&b zXu{jQtw0p$i-2ZxF$k?N;^xkRtKt=<6y-s{qJW2KS)Yo%7B<YJJS%ZkyId!ST;4rz zv#kvj+gX4kgzknp^>|X{iyh*<)hs_M7aw*8_d7b7adL{r5Qp>@J<R1*G#S@GIbC2A z6}(!rRKe<bFBtXpaXmfkHy$~g;rsspvFZ4O$ZFJ6{sKmE(F0xJ@}#QLBd_QQ52jt$ zbj^KQFTuBO-n7}EOZd@XEyZvwtfey@KcAEcjL>nG$&Qdt12l8x%lL-%0r65OtnG~~ z{_4-}Ha@&|J=5)#c3bU<Z9ZEHcZCfY2m(fTzOH`zvUzh&PjU8`rB7gYV=PwrbYEz* zWs^4#F%jU~8A9X067h)U7F{28w^`V7RbwM7eBa<pE4tOjzy45{+8PSoi5TaKuB6QM z4|OALBy_=(UF;=j;mDs@#F%&gTT7T81AJzYY!eD`G}}`vbK4>I%N5Q#tGiSG|8Beg z4cvAs++Wx9etp9E)#m%+VYRxx+%553b=vQ?`Mox9R<{0QB>#j4Xcp1k)pUa0!>j4U zcUs(;lzNIbm%4^E76f97-WA<bv{7gS&t5!RQ~yHBqu49f&K=cR-pV=n2|P}<qwHlx zA-myB3X*V%l`R62FzHNF8rnej+m#-v*6w##dsB!v2-BjRH!NaN&B*W9+4>K56}Asw z(nYS_G+RP<vJR|gC&Leki4;F|&uiN&_%o@ST4b@fm`%!~Qf=yJdI5FDo9}&yzq~C4 zNW|_CJ$#sRn4PpIrTBPTc5mH<|Md+1ny~Y}T%KfGckkZ2n{6}~RCV@q;AbbIvbVVx ztcnQ>PoL-7b=HZ`ai@<m*<!u}4OaJmvcp|j%qEj}G6zlt*7}Fxruoq~gF`;Kvt^{b ziY;(X?JS?yEbMo$+M(Kk#y0i+v;eC2P4~Rlf*UOJQ4#^d$qq-wWP;iVMiEgAqzefc z{*?|mwtE0K{XnJ!hJZ%bRi$*dgF$v$NJT6T+$0+v-j`z3aGyk>K-!_JpdF5|TXofM z>q9Q4WSwZ*V`w4aq7K-OMoLnqtdEE!BQn);J0<Da0G2teR^IkQ>6T=g;4u(jwAf>~ zXO!fSHw?sTL8p(5(7I3Wf}VI%ot#W0GZ|gIhrm&8-MhcV=$aHlTTTg2pQ2|6A_qi@ zzSY8=!~cy@&mYqt3;s)L;xe47$~KPStdR2-V<!q(25wUvx?*dM{M2<uSC~TFCX<vn zx+P0Ykl3TOPiaqD3!<gJA*!$w?|05pZ#-lj{&#zPosb!Ph(lti^x!j%97YQGby*(0 z1A45_;auQM?;!?cp-;@gsEI*cLmiLu$&mmY)dNij!6sV#Xo9d2(i=5FR>K-8abU_p z|5%UDO5Qcx36rsTx{;nG9YbyZSky|(9FkccHo5|X@X|p8E*B(t>Ad5rc@+!#aWn2Y z3ERX~(u6dz4f3dIhzMA4U=iQWz8^+%b%)zK6GjookCM0Hqa;$`X2>VAQ?#!Q>5m_~ z`#<##?))f~(Sv1aD1ZJ~-@y{<{1}!y=dg363}Srcu?0Aj=r~0W55kqtHJXnZDgy&3 zzO$B8-9YZ!p~BaCf$J@I_%ns8@eu`?OL>o)!w`xI66F9+Zs3qPMI;o{jlaJcf+$lD zfoz8se>+z^879o(PiPG+F6raly_*|H`$c}x8%Ra_>GBMoE*GDQ1{>VzSr8b$2OIdC z<yrHs{q>E5-fsMIcyH|nu(&s;)j3kTxe77!Np+7tA714I4UJicd3&dC#|3E0D0+aD z+o#69K_)(VJI|*z@^h&bKcVc0H#5R6*g=tk>rPJ>Kd=r7V)5o?N1<)%`a6=OxcWfW zVN(@$`&<0a*VS+M&sp7}aQij#0C18&c{#O^Fi3+`vz!3@XBBd>lAJN`NnFcVTx+d7 z%uisf5uX!c5T9yx027PCqfimX{H%~<bUmw+&u9@o*<($UFWm|i0FO+IO8ZOSVzvd; zD+L_!;s9%~KU;J+QMLIy;@Ar$$vWSzL6IoBTjV)Gx2Stni?q7QcUj8{#8et|IJ+GE z<6M_>UAtr_S=)e<5hvBEwQHlOjwVd^Ih;=tSH*%NUUTUhOq5zfgNe1jCKv>vlm%zj zOLCoIE){VN60%2Wwj90iB(n;p_}kLv91I#Cl>E4}8wC#Pk8g!u{<vmcw09fDE(Jge z*sf3FNfT1yGkz4J?RA=*7KKLu;{^G<HB!t~q=TJ<rf>0P27GExFc)d^@B_k(9_8rF zn=et!qnf0_$9*#$8&;fb=BPx7SSth?hgan4L;`glowE2&VlLv+&bf1RAQ-cnaycMu z0OfBc$@;Y5Se0|wym&fBnMUHa5$d%Wpkma^qf?)F6yfJ21F+!2vSt~pQHtU7380^5 zFh#|~qGIqaSy)zWx6u>lT-I*8g}NCh6G<xx`r8#<l^6E1)mds$f?8{V-#1$8F3{^) zRWFh>vsxCnK>u?#sjAtU=xYpS%;_>ytZ;$~)$yb{*R5`x;lF;*8<71eXB@4f8k_Ug zWaYAV8ykn3-^)_!;zaKqrvt<+SO=D{;9|k{w)e$16r`jJCpbv;@^CTFj}}SYb7H+F z+QfKTp`f}xy2ondUzS*XM&m+5lt)KD0z}2gKT>YEpe)3aBAw6^k6ZQYd~u3#hFvU4 zEgv9dDBGZ_ebQZ+jZNB$>sogmAKR9BLL(mIrwMMApOSn@>FcDde>-QzC=T8O4RW6M zVY_`vs^gc{g*e!q_JJoaJx5F0^$%kp4=bItUZRe5q&A3#ni=#palufyMq;zr)4=2} zJyyhwdo(fxIzU^+c}WOw<w79Xa9e<wQ~rjk+$1Am1e7sQH=JT-;sBB(S%)zEXbZZ# z*_X3T5xqRR$UXdLeHZ50oI8gVu<Jt@^cirmNsU7MWH~OxuGdHNG1ke!vxr80j$1f@ z{DdhKg}oEN`X>0PCd=Vh){$r!6`RBug(lH;iZO8f>V#7@_yf=$i`}l({zx6SC>7s# zS6C<=fm>-iA+n9OF=#qX=UU?khiDWJq*K9FV|g%yQSRnmh7gjKT%T{Y%=#5wR+3J8 zj2a4Urp}7K$EVrVqmU^yx^d><l?3rQlX>kP&_sG-z}~E$M(cu~$Mrvb9wUzb9(}Q% zvz-*5<Z3||dV~5mOIvIrGNr07;u(sSzb;Goj7XNqq}-k%-pbsN{(S8=8M~MI#!6ba z4X0?he6AgTiAT`a;0Gy87zaL+W)OX}8Fk@MWui5Z`yGR|G6qk*48zoT5Q;*!B6B9V z$XbNcj;arZQ4#F~#Srb}LwlGTet!aIo0=*PmnUqY@RkY`34Vq<gQJsjuN?0_xc7Mb z(R~RQTAY6U)#o;F@A1}y2anba(G;;oHu30u-v|}JC@HK^KnP<Lz$`AR1s&p3`;Ce` zW$_{sYffM>y!IR_9}}Y|?a+x;eUOIQEpMU5sB~mGEiF!u1FQ#_c0FS|5n2Fw(FQ95 zm*Hc*W)%ScDU0XUdg82Iu);B=8V*=iOcW8`P3m@APR%1=VY;H8G<~lnZau^a$<YI$ zOF+VcHWDU9#hrK``VGP;8|fZV&uO<8X1{H+L*5wMj8NJ@SXB(w?JI^Ux)^9M#BPiR zyhG`IF0P`@U^-DGP>}6PI<M4u#&QLz0^{+}<i8T_XT^IwkeQT>D{}kjgliS_RP3fu zR5hdAVBQE_x}G2xU=rP2hg1$+(%#yQo<(Z6mCKd_nr3D(8(0W<6|Gn+wTte!#`-*n zjU}-fBpXWLU|)^=owQ0eI+C$>*rY9yh)m^iT(cE4jZ#?J((x2=>xTlhmgNLQRYrc` zD0)eYAhIR=3;8O)CpP>BgXqXp9mB0k;>SB2D(?g3<KiG<fqp^BDoCB^r8=^jjies% zHUg@X0Ok)H$Tnc@>PSpR11XJyX9{Rw0=(jRwFElYu`{l744n2`>9)T-DK7p3Tp+#n zhEkBDt7cjCSJBk-*T&VV`5`9K=)&wYpVs~o9K67f{1uMckFHeJnfwm(C}ir~I_H#z z!Uoh2)e@wL`jo>^FEWPa65BizBeS-J(y_=5WQeS0LXccuN4N?HqI%0P&m3HZ-ZcVE zfg1F0+NdE^wG&41mtvtigrmCSU5APx6|nn;O2*RNofXMlqB{qH>P8?pY+epG%rHP_ zB$d(Qlp_Pm4;F{^g6DVJFFztvPSa4)3`9%9h&i?CyqdqWw5FhPP8o{EoN8R^iTDsP zHD`FXnqX(ege=u!VZSPmZ5qES%f4?$V^-R`S3a=2%D`{W^rE!pnlmI6o6`*Oz)@?~ zqUp@VT2Ned3ZGg|Tb^Tf?7L5F)DFc^i7ea-9ghR7O3g6~Y+5#h$Ckg@hAmIPin|f+ zt!XowQwB$3PRFM(UQXhxvo0tiFcBNOJ=~<pQy?7OdU*HV{RkVrfeGJbPAy)m*dUZx zL@B5X9_K>8i0*oaes1GWF9$T`@~JIk03?KsM8OA-x9@VTdYOq1cR#T*CuC1DB<{a& z@^3WI4r3sAqYe;6e+P!Ywe_HZ@6YeDKqQM26%%O9CwYAwjy=rendNm&pa^|Bd2Y`x zZmR&-6?Z3+s3N?^-t%6|lE|Q=q<1}{q74%-$@;EHBEGXcxwjrY-h9+oSlUC%@hmvP zBcRa21`%vCAljOIgOTA*q0uk_3FF>K7C_(!1_Yz58je8dl5F@MfdeId5YJ}g!@aB= zqt_43Rmyxrdic#%@%=Cz4hov4humjmJpJ~#+X+Gcot`UYZmG@APu?k~peU4!PRr5~ zQ=x^OSMQ;xW5uusT9Z?uGNT;TU$Enbr%#jf!jPE1AY1Qt;9-OSVAe|_a#yz$T^iKI zA~E2~A=GQ(8jYAZsfdf0&bbU8$d}bzs@>f#r_g3OzD;B(o27f}{{79zy|l<dI%lpt zKs#=KVgYKOOcEO@ECbZ+Bn9(W5`yPp>Uid0sXHfr-W<E)NjnLXCc6F=lNQUHF$sJd zFRk`A?w|-3g8ArBv6_0TInP%K8e)j{wr4t}feR1;eC8oN`s1>}f6W;l1cm=?4)RY> z?p0KKCDBHPjt1SbJy6Kji+M(peU9*RXpSx2;pDNvv%K-8wW7`S3^>vm6+=2K$af-Z zQ7Y%CtBju%el15z8j=!srg6W`81y}Dy1t4=q<U0(GD9DZu~@}8BTSTEm%#RbHP7QE zMX>=tIidA|SK&}NYVljJtIz2IH>MQV(=d6AJRXs~Pg!k&_DVd=@k?F&B>If#U-EbD z1Upn>nQ8%8-p@Lm?tzgvVst(5*vF-dj=8aFQ|z|nJty{oSP@!bB|s@vgq#2w1>ylY zzs4n8z+Fl)rQ&RX(};p_Kd?g-sQFA=g5M}XkkBH9RH+!NB;T8}nK?1@IFd*Xiz(3e zLboNy1{k|{VPAq%@CkpnRmSsHY!)u|B5-$X(x#2$xB89jt<aNe+3~eDs?~|Q{#zd{ z;jC_3*cSCRzzo;s_k_W>LXp^k_X*cCx55*((p2Y+b<SKT20QutzryI>cXAF>36@se z#J_yfc2A+$Zl;O1ZM({4<$iKkIX9(d;Bu0$m<EF-P03d-3F&sNAtllX1ZS@Wu7cZF zH%#rW^$gN~PcmyZ2b)`<*LfbtF^q#Rw!|-w(F#7*aBNmP4h{Mg1vW@8vMlfdMPq7# z;NYjiv^SZoehT_V(XL&2co!XXeDhAWwYkZ0nACZ0RAy^8i~4|-#9QXnQhdYjPRJ>O z1;&8?1?VSe(Py8W^qJ$hta>$ZItIT~Esn}A!853%IV&6CTuw0XHQ<2IwOs+0r<kha zV5E}|!ZEqk*PJEJhET#I@gdtlP#Q!DVq*gNmt|OnR+HU&@ZkP-_=s1|`s_JU=Q_u; z>DO;<Z9jMvY!SLXPo>6gq~wJH6IzOSUY>QOFRma0t*e$o2pXc>;f;dWk@_SP6fGbL z6If3So60)y|2Xvm^imj9ho9Q%XjY%(C1{f{Hup%ar6<rWonxb<-jdM|Zc5FXao<7^ zTwIhKVQ6e^9SFP+)P*Hx8RZQf*)vW9nNT=(Nb8$n<jr8PwsKaw+UZdDj>p0|G~{tp zO5hEPq3vAIMgn~?+7N}V<rMYec<pI?=sg-s%wJk>ktMBkyWMQtZ+4_QBh8JEkup~W z$r<~CQP}cwik@RToheBetbJ+Ev4bYnh4Wy?vyFA4nRUG#;ee#4Mx68&!{6w!(~{2B z582r(4wqI@?N81k#O6S=goQ=p3n^#<$6rnY!_x3omE3^BnK(8mSiM<K)Js&q2dQia ztvBI44sz#n0uffTeU$~=oOal=DbW>3*^I|i7owUWO;WHLbUvS!XE}pF78JVSy+uiV z6Ujj06GM}a_?P4)X~0KZl!SFxjLkbnhf2GAE}4t#`jm?5+^e0dN}#$jr~Gumxifv+ z(>Wz6Q^j5A^Q3T!6COgjSeEJW8KrUTUQv-vVi^Y%OV|avM^S2Do@B+k5oP9T5osUY zm>YpJVG?-TQ>XYQunhaPp%H>|MW6zNDVS=;-wS(EF<)X3O6iSSzdyY~11`STkc%7o z+ws)-i4*gX^FUp%0&c@`)fDOb7&6-zw9A>$!i}h0byN+hte;_#mk7r#NXu=JI?RA4 z6va%2*{Hl)RKN@q5u;L6XIR^HO4$Cmo(I|P3eSOrd?liNRM*P_S7*(2Z*#uv`B>=& zMr@eSov5OA>d+WT0aEWgY!o2H!iG|8@&;<W4R{ZOuhygrUTI&Y5<|s{>%C~NEGW}6 zDw4U#7ll6}WNY(v(UdBzGSx|u|LF-XKs3Pbb+sV<0DIPLFYObTS@dRv5b&<WN~7p? zy)2*NCG}OdlE*?HtaPdFybwh9_Pi*XNr=ehvF<opJ92_GqpoOD3<wYO-T<CkR5)J) z49UGtGkD|+;ZPGm-t;eYDru5AJjKD!msmb(ho7V>SY?YEwfeJt4wB;O<V6VK@gu#4 zuc09e{;_M)?Op9ZYBKdX@_Bnia}h27(e6;rpH?NEQW6^%sano?UHB7IJdfbNc7-~- z%Y9DF%<B50z8;_&M@kw+fD45~>#dc1)gWxsJQL0x27lmz<IQwy=2_+s&RQ#EO6(wM zcJQ;r@AxOBhx4Te98%O~Ut$aqAo}*P>vWoTu3L}6c*#W<&819lR5dRq2>~X-;M(qI ze#H;i9wUA0uW0&CW)E!kQITwYESOQ;Zf)s~w529bM>aAvB$bWK(H1(J`R#RgdBud( zi((c{hQHwoMGivcWBj}?ff_>06Y8i7gVuDeJNKd+`ASMj-)SqX*W?q#dLp)wJm6p9 zPcm!K@9wmjrxwJVoa_KPD?IC@1A1b>)vFfPK5WXH1`5p9qnqJL31fjxonA}Y5Qls( zb<(Z+XzaN|KRk!X#rVdA)q8i2apqW&Ks0;gE7>`!^HK1a#g4P}BX`y>vX@vDb4p*8 zFR*&dk8(jMts++SwN{k)S~)wd&N^G0$i4{W7hj`%So+Ms0zUA)i^hwvz;FO}x90h{ z#|`i-Nuo_HpjEhTi4+y4vG1mljV2@c>Pt6swboM)vJy@K!?x0w#q+|w-*j+UAV+f# zV9~WNC{ysOd*tU(+9E4q!$=sBq6Cl9UN%=DEd$O{j`k|NFLF8C(`qqU@GYT1zN3r$ z9+ryYYjIfk6zG>}5FCXQ>w~F~e0)J{Bq8G@{jT*P8=x0xk{vdvL)pCM&S`jIqdtTU z+2-<0x|?)ZWZ+fg!ha)+UYEaF&S;8eE1AV^Xe7>i_{f^Mi)P54>^{az-+@+sBq&Mw z4B7#K5~(hjLn#cZqEcBvm($`1>5^mdQdT&qkLJ~6@|HxO_IrXX4FkD?Fw+III6kai z9xk&j?i(&~%O}w_XT~NaI<&c8XadRSkxUV5i!;?U&dDgT^102yeb^<Gly_9sc>50j z`tCJ6ILx+3NiU8sn&%B2NW6Mq;>LW=8}rH5;88}3F8Tf_7iTTr7>enk*c8VX-_ZG6 zo)z=gC=kt$FYpUB<23B;ur_mv3c)3c`@JuQ{M57!YhiCk;1(`>30eb}?MWdUmQ<MM z*JZIRh#shMHVMH9D6O6?<p_cxhpAo7Fq55Dke{G<;yWEQg?QT!Zli{tz7WlTrDek0 z5<Mk)fwlGp*7#T$xsY((k8CwOA8`~PKOvGfKM0g6hLXF@_>QXt?_f!yEThsaglueN zQL)72nO~QLzKA^A@E%ysKPzj=>lE7ps}5Im0Xj%;azfSxMHQ^eWCUM9H1<_TAhp=j zNvYxZM=@$kZ6p`3VLfxza<;vRg!@TV58w};IkqX3iwN+0zN94Cl5&UyW%BTY>ycj% z)qFyu!2lnkdCrS$IUAFC65+&&X54|rh4!QtxRL_@ONcX}Ng3Yz0wd;;p<b}nll<m6 zhG+d&%q#8<E-r6fzf3ys(6D%$Zj39JG4T2r?PKrDY6)_QPG*L!VpPU*fz=er8OCK< zVPx3a9V^dz$6ES3<=Tj}MIbQvBK^pz#<H(mkslpVd?DomAao2bZH{R<3Z8#hP<pvv zc>WhvT|rKkZ$BGTAQ*}WgyN$vC7uKRcgSy#;(&nWG0Gd6-&xP}*whvIJFhD>1^lm? z(3HU-X(3>g7~slb4Pn#k%g@m8K9@?~NE(=7Prg4ISLsKO8?l%l!wE@{I~=k6ULxL3 zb3{VLQe6`2rzj)b5Yl;9=gjpZL&!8F2a1>o&u-z*jg5FeB^j?W@RXPXA}`Tzut17| zfj(};$bZ24IkMawIXT2_GmAZ@NU!zX;RZBUy+dS*DDIP^=EfC=aa&Neod#aYA%ljn zQcPvv^Mtalqu_fQGA)<TU@ZY2>)}$<dbwbm5iZIB8?9;Kr8A*ETm1o+dS1aI*02Rg z$-!eSx*UvQ{MIWxb=hzN0?%7Gd|`*C7CSncvt3_hhAnKCm!(h09+*;_J+2^(`59BB zfg-441RusdpdAj|i~t5~hF#+8^wmXI@)jhOo1<|oU!Rijkbk3(nvP#7Z@a_M)gKj3 zXH)V$H42H-*`+2M$t3T!RN59rH&^Jh4K4|V8gq>>@42$6ZIV~tl`~5E%1FY*#=d7i zS~RBJc!-j>KT1;dGt1TAXql25oRqkmxKc(sLHi*yd|eV4Q2^C@F5^1fWYYqXC0lQs zU#0h57!3bbcuLoRIyLZqoa7uyKVnR0-f4spR(&D%(Ho&iJsXci4D+%BLat#2xugG= zx;O7{+sM*|{}w+5413z7%|()z*i;l<$4lZKJNDR4C;iImT!@4u#3aEXNXbg9?|$p7 zb*cbLO1k^beS3ZrQ$V5iI(63PfHR9P;8-*egw~@F`Kr~baZMN^a&Zve&ex-$AFPAY zfptT6FUX)H^k|lg3vUsGPt^$pa_+5Kc5P)?MU4!VRH#j6LOZyV{93tN7=7Mh?TU(G z#voZY&b#R*+*ZJovv4Rb%K%3Q$lG0y0fmvYjEsXP)eW0@UV*<-+f=hdkRs*OB(4}b z2Q!0b%Z#Da8qsi$K7$zHQ?I)la_kyK_J2rbCK#w=RC7%W0h83n61>Kd*YPi2crfjx zCJ>smg{v7B9LIss@ms#ecrw*>7?oUoc(mic@(=4No`YxvU%wjRxPf-Zx>ATvGW_W7 zU1VEe_4*VJS~KnddTGg$d6i5Z16vt?ba7n994<8J3%aQwYqUEN5IE1MR!5XgyQuUF zWDPEBJnC+*w`0c7%Y?7O1rj@*PDwne;oOkIw&Nq5>9!d#gtH^^fMSG-$(8}33ZnhC zNWUX~yb^?o?7F!0>a&iIM2v%=N@SUnYUWtLij!HPkMyX7`_xVBJ>MgraZGc8y?m|? zX!Ip9iv&qo`;O3k<oVBVjnP-~=<kBcE1^&oSV_e}98Zwe3W79eFyTkt=<lE72Y>g@ z`hY$qE+rc28TpnFV2)WF$(N?A6Z$2ir;<rn%cy}6g^fWIfc$&H$iL(xG7hlbE_EfA z{$f6YC?9+TpUK`%j&~y<D7f1U-Sj!)Efy8>n^&XL!M=(B%8~$~3`|=--Mo4b1?}(d ziVse@#t)a`c*PaZL&+)58!isIF8Ub<_lEg0SUJ&4;~#N($+vf?E`}y=cs-zu%3wn1 zAKaJKE6Oi^jR^?`9C$)lFucGksjdx;-7`bH7wl?yE~ue!<3l?P_vt~+WPowj>$a+P zFQt{W7J_bg51Odp&-Id9%_aX{FRAiPXD7gtgWGrjN<F5U#AG1@XQ<%sEgy$EC+)Yl z2oc-|>kLEvmrMue4y%32juOC-(2vj^l^&)$t-9Z0+e7KW`s5U&POL@XY5LN*QYv$T zN%>GHVC_q_ED<CXX9DyaP>Rz#0!cb9IoiebeFUcfH-3dN2WJY@Fn8=A$fa~dsDq78 zm()?f6_g&C-^xEX2hw?ljFL@k#QQ!#*fS^&$n0t5yO+1^tr&ra4(aeT*XisW!wQci zOCd~Sm8>}Uap5R$xe)z`CZG%eg(Iu2KiyX34bJQhb(lii*&B=rY-9Dh;RwD_#%H}> z<S@hTjtlsil{bAxac{!hx+bUFMeu$bMg^0Svs;f?&S>}dk{r{QRA4?U=WW2Rg%@p% zF;5o|pi}vr?fg|I>`z}ual`jsffhr=O7Z0({@u9z*nuJ~0~x4J$)fMAFOVA7*MBZT z&5pfE$v^tp8ks>I+k`^#vj4u;r;MbgVCzTTN|)5AVx*OiJ%(p|XaMQY$jt$m=ndb3 z*>}?OT2+C%%`npu;%J}@t9`K%s_e-1$l!&6)22QXhS;k<LI{|aQd7=V?vB3uc2YRL zm{*?v>GH`3#T`=FvqiC7V#bBw<XbCjyNScPKI7ELGQ<pn#{&*!beMw|ES<Alj*;cr z<hgN6LoZ)YA!zg$dwsD)j-m@owHhTH*92Dz`#6j7+}^vSqKGcu*}4E^DveuM?UX@t zHi$F2zGI-)*b6nfz_osS?ir8fT79`q6G6)QD<}asn~#&+*x=6_Lf=Eq!SoudydwN~ zryd|oliwI4Y#;%sltpKadouF@%mlNug!B#W{VjGgW{0M;a<<enkSCw=^GZQVIYLDo zP_ju?x+`FjV?Gjq4se6L%^b=hB2KdGc$RyBQ%M7nLXT2UAayH+02@M!YCBCS%DSaA za}Nw>xX*lP+9@&hFxN@r4h=r6DbZBrZizbCEV^Nq2Jb^f3N7U7)~gvC%*?EkKwVaT zlrI+6hwm9baior!`=n6~gZaS0&`LKW2P_Rmh;?#0XeG;q*;mVA^r<hNq8F%3gGUWo zB{qo?!y0*RX@)YId&I^k;T9|mP#M|_AmqndA-Y`0G^4~hyGZ~UtkXnS308I2JXKG{ zUeKCPO$@2yvtr~L&8icGo;f4aAp&NsDoL!fg@DB1AHi6}?VDTM_aA@7SQ+^goELmI z2Tgr|FT2*Q5~M$HXmnq*2fp14O}n9w_huD1)HiFNlUV({u@Tqe70-*6^+Pr0CfR82 zYFidZ=RY~wLU#Iopr{r%P(K9+mdB8~za}kLq+C-34*s?-F>62E5h^FA`I?R>3)Q^q zE=13qv1vf7WyNk=ak?oiwyRfwqM>uB1}LVjwVieph_<zogy!&jcmWQ9`MxkTLQy?H z5_zi?4=qKpMc&YdLv{OZiHQ+*`0%phBpXt{)h*gp*3wl>xfnJKhdHddt^j-Iv4_0p zigj_<WH-9~V4AF(I>*C@1^N*=_Tpbu&b!t(ZSwwnRh@)Bb~W1wZ44yJc8JI2vV0y5 zFgl^$>KDl32zEaUV>rR?3d&b?)~K`w4<ZB-JD3H@oZ}Xg$|xa_F72%&37$c2B*u|L zu~1{Vj{?#C+H~bA!m<^G<zPM-JjSFvK0|lQb4FO5WRRtGk@-CLCU$d?3(gLWFJ7YS z5{j;VsT3pBRG508#XnF@t7)1q^y(z8#*%b=0<^M$+rR8ckPvsxRZ=(L2FBtN17u(l z3_D|tSX_A+9b}w(Nk_soVG5y~T%(~afk9V;@Ra#~p{FvQ5)K4li*v(E9#uqyB;}d$ z%|$=Mwh!)80$xBmvZkv6Y8#sQf@f?njCz7kaTByQ#KM>@m*Bc8slh5iO=T1`F^b!b za=gH(zo>F~kpMSB8jZLJJgjXeHM`+=;I3Z#4j$5LVJo8o3<2A*vCL1*6&uav6Ti29 zSO3WPUNLFltlF$$Gek0ie#LU%j^5vtsOnD2BAPkt@*4j&QL85N4_mlfH4aVbGJR~g zvg;C06Lb|yksCFqh21rN42`Axt66nY94*^sCM^uvTu#58d!Ks`pq>5QPApvTsL2m@ zZJUwGF8+*e=z2ecC|O7P@P0CZi}1uNJC2Mah})T@aUehxiD;xMKpjJPZJ@|$VC$$H z=x}~-5uOPgk|DGJz<ur?09lcMIHMx8J5wqF7dY%_%Q9a2C}(aks#Ja%;741z1|{k@ z9J%ZU?&XbL6P!>U9dWP)PexeMf=%v)?}lWh^$&`f4SIlqRDK@y(SBIVfzKzTMKtn> z>7hpihEK_@qK6EL$Iu_3dqnRWG}C)q8J9LVp7tTbZgF}?{{k!VHv9jAr#P2ThH^~8 zFWCVy!Adr367V`QCG{zx;s++`EDkX9-3&D1{c+CT3KS1)irENuNz^vyT#rqm=118$ z|4<I=CkpW0<x~Z9n5_h4fjSqBuQ%ErAr?p-VP-Q50TzcNank`$EV$Mb>$(dfHY@!# ziHFBx@Gy*uvk8Sj*$ny*D%k!#QP^|$jhySIp>cEse^{4t)_&+CHZfSrAPxl<AhJz~ zga|@_mc**t>sug!t+Y34&DH_HfOGPuL|p4pImgsn*lbmT@ZD2?2qqn*<v0ZA;A*MT z4f|jjtrqRFHL|bkUcv)1&dU@y<~=IVv)CQpqC&qEX3VRkm`?L?;d;%U)Z`X}AA1`g zTdt@ZDb<o%r63w{&?e<$;{%r^J9~Yq03?6^&<6c#^E50&LC67YPlHD>jNMivfx!5d z�}X8y1#`oJi&*r&dG+`Y-w_6mbZ~p`8C0Q!xK!q%@{t9!hq})+|=)MNer0wJ9Ve zCXAM@4D_76VX;2AHTiDWbe!@V>!04=Qz4yWJ1V=E_)qxe#wKa{ZS<~?K_~$pQjU~& zIg##lQ3o(5WiFS2z~Xx*k6V{;R{HyHl6tQ`Mh8R5!KnM`@2(oqYL-}`_#XR!EGAYL z4kg2!jP?Ppoj(S;C*tpd^I%2XNEwga)atI?0rwOFr5GedM&U6Iuj&`e%Lc3|O!P-H z*$+Hwd%c}-rl^qb8KE2Ok~1lK)iI>DatHAjhEs4Q%>d$phTH_F1y7djB(HUp3Q(>X ziDj&7RU$V0frME~RsDG>+Igy$LyJ*8g5Kn38D_8|Y*Vg)H==hNLr2OH>z#^)_q0^0 zQ}RDyNgjj2_bz9Xb8g$!mZO#n$L*6*^0<LFj`cCkObf0?jLZQ5R!E&=au{QiG|&T& zmM^5BA%K284WLE2>a<b;S!3GG0Yyj?(wM68ub~W44JmjT-B8(*THK?512rEn6S-!X zEB0uT9Vci$E>3|ffPRQ0hQ9(y(<gP{#pie1QL!MtAas%S>(|w!<!cZTEP3*e49DBG z7q%XOi3D{6hspVYEH8nf_cR0niT!s_jLQkcwdjLoNB$TY2<O1NrZPPMNrL)w<z!r$ zCza;|s|#p-_(XP%j=S-7O`M4bMnZ`bMZ>*n_!6^4cOuZ92=16&@Ve}?))jBN^{B^a zbF8WtRx+L$i+t_bW$K1V2oOjlRx$XCrlxvOFeT(Au|ItbCzMm6SWy8-DN>C@Kar;g z?XfFF8%D0RQCE^0o#16hE4O2(W~as2cGbj9?X&W1Hst1M&VeN2s~_k30vADFd|<dK ze#vVFuR;2J>FP658ap3e@Y^@5W%!!bS6)liwglIoT!avNG*`xR<zKMU;i7owoGX_h zAoZB?e5Yk~&<&P#w5&mSvc0dnGc=y9DfBK*?i!Oxr3m;!>8QquNmiSR3|LqQU~CZ~ zkljWwxi`7VjnyTYwCbIJs3O7(H=&n!L?L@UrH_G=Wzg{ujSpc2z&jC%MpKMp0A0|R zp&EX}_b8ZNu_DszotC*p+MR|@I5v)Y;W_T8KJ8}MrDC?s7X*F3buV}$zH;H#Fmv*9 zY*+B*n7{{La)lPDgbW%DjW+d&#mKN(l+t|F+P?eVw+=Kgo^sX~5}d{aaPJ;&ZsLiq z+-cv&-;iC4qav`lg(|wgxrsFrx&%Ogz;(j;#pjdNae)c%pH3iN?fZOk1ZRVMqUZTy zT2uf&(TA@ggC-=<bS1}CaXfPjC1~~rc%}8{C-Z^p&Evu5SA$>w8+zY!H&k{$Fsd|s zP}@FT!yzmS>mYaZxlvDwg$_h20S&GD2PU$Kt8E4J$H>3|y>r4tH&6%&1%W6B+!hkn z%Vn`;JZpw~tE-v_saQUh3PoLjw>2(K#AQQ}lDpDDPX|d29ADEt?2fwQZZ6J?bHo5B zPP^=Y<Zi((X)h(O{A%9Xa0O6xGs63kkujc=`mqfWHmBr@>wW;3mW47NIk~9<-%MZ> zmcCdqb2sAmA6~x#ZE%u&?RLYb!8czofusKB>jD3pB`1sgX!rIYyZue}^&tD^YwR*k z{O)axh&e1j-yVDeaz};^ou>f&#(k^4J^zqlW|4N9r5$!YY*AJw$7d&p=#d4x*oo1A z+eEXley}MOKr0m+JMaN;68UWW^rV=K+iO226JtuLw`e4nbs0;TZfA@Z&oI{s#zV}9 zTXW5xi;+!s1wa~6|Ih>%qYo~-m_2HNLMSI$g}^dORfWC*6gcSmH3+I}7x}{hIA2M? z3t*7i0yG|7by8a`rGMWASpgvp#e(&6Xo5X9HDUR-fb#2@A?dxl^GpvUMs?ukV!-;4 ztZ%DoQ>wzWqcNsY=-!X-UTMOzspBo?s|iJxaTnA;QZWKNlSR`D*r%GW6^L-$1t`Et zvC=^%6G92=Oxn>zHuYeUjf;}i?d>#$l_bRIog{Ue2roDU$1=UZkKdrD{|($deNACk zA9coiHy`&7fyz?*v`3M}$TVA#6x8s(KFtk7So62&v_}d8UM4(R=!WHHaaopK3U9cL zB2|WV5=a*|H$!lb-b-s_29n0j9w+uWceD<OG=EA;cuZx}zWMO0`}a((QWPd;-RXoc z(~cBvo--5!=OPtW5E~@G@jOXpBP~7=BAk>6<_umVPdBwiIzoc_TCKVUnHhTKU*14- zAO9_6+k<yKLPb(5N{)z0VU`O{uVr>AZkM!UsM9*4PsGVnvY7BwO$u%2BLJyh`sTRl z8_gaNoDs;oG^5WFa94yRHx-7;&=Dac*kSHi3C0S6^CO)TXKo}#%^ikChyLPsVW;uY z-?)mPLZNOK9pv;|=xxlLf+I;E7lY$9RzO$5I{0u!P3=;mP;b%fiZ2WY?C)<H6w(_t zuw&~UOaVDoFXR~{*EoC0V>kt#6dUjry_ax{{<3^kp5+USJ?JP{(x1&5r^~-CVO*Rs z&cICz7=g*ysSF!w0yM3$;-#w_AR`V;OLrU~gKRkypd&~zUTNE!c7RtHHn-*l^7Y_H zj9aM4BR(U2g8Ave<gXR0;)3D5!jyPX)>*$BtljfPypwh=x5PME&?sUty_H88B?MLu zktYbDwdpt+L0bD{GGa=kK%jdpL;zB}Xpm$&P2h#5icnYi0ceq#(t@Ek9m&uvt(<lh z0bdkG-=swg@E*9SG_7MnD&BtRtYJUA+xTTe{7lk`8nmu?m}qcKK7j~5J=!jud{jEY zF>E|tYmYjv@+C)IcftCjPT^kwF(7#=bU6?pev$}KD{)Zbqj24{oDrliCu0n+i8`6U zjtjx(RBkmS@>-&J8Mq{FCx4-JdD{cu<X|mbU&ei4rfXy^@PUSJ#KO5Jnc63Yn3y|! zYqPhtb=P|>&&lN%*x}{LqCA6?K@hf&TuJ-p*8PW%9(EJ=@1qBgIt{6N<PTSYj;0ej z>k|`l{qbW;*129$GJ%!QW$P^O?Ysml!|dHlZw%T1c%5By84=;ef;|ibbelu;>*5j4 zD7}tnoaLC#&&{kl(<7XqzN1g?VpyZN;`<;U&d8wk%lcpyyg(baBDD#@>b!ywNLZHD z@rnAKEB~xcrcpiyS9O$+f%$MncV~s5-vyH~1BL*z$$*5~4sk=s3qwfR(rt_F2M@M7 z#>(85jievJq~cVIIa$CQP2zR$;DpPo2p!6<0-7E0;r;>h_)?Y6rehh|J!E7tY)2l+ z+C+ksyk}vG$++)oTWj*5uf9?sHL9K^+NKlX%L8NwcblAE6hB}i5M#*;YGe}gcmaWn z3n7wAkJpv2y&Y5QPXb{^^0=EsxHu>e-AvY&xe@kNo0%ITyd&8BB`gvF);Jlh=)Gq# zMctgK9ot<|yV_t!?=jGd+o~j%13g-<%rqySqVD~BU~jKaH}r_>z4<8*qf^cK4G%U? zv>+)Kz1}sCT5y-oxV7lA?E8)C7q~09;T_1Uwi#_9L*5^nEdZ()K+ok$Bw-T-SC7X8 zwZbZ@!}7E0ZkDC50^Jha;v$fU<6K;A056JP!;Ytb_Ax=QgM7~^qfn{pt8rffoNxj9 zj7(#qJt}0Fs9NUG(~@1k!hy-#r>=I>`iq?u96!TP0b~ef%OWp`nVBVR2{EE6hh@Ck z!;q4OzF9|+izq~fGW{LGy~_OKVUDr2kP@V*mh9hwD^<>V7}V*Zcil?46JP>s{WR!) zt6zJrOTDe86gnoghk@v3tKvHlODi-+i`K|(w`0s3KcMvSvGJCKTSwmHgV1hk4KN`m zsF|;>KHt}g9`|sSluQzOW5a5rlh%e(Ofr3IbgY885ew0cSR)pgisGU53COvb#j%I= zr~L3!Aqm&gl)#l4`roL$P(O!>qGeM6Sr2?>#qSYD->8D|m)joIHw+|PR{V2X9a22N z@rH4A6R>sTuNGoKeoum_2@07n`u+u`MyYbK{V>KiugMqLsGVDb!j-HmeAlRgwd_k) z`2;GUHChqq)St-1#Z|%Ae;@%A*mNZIV%%th(Yeu$iCgv+NtaAcs>{TVc);uOh($Uf z%zsS?b|Ipj0Pzqf!TNiPHs>h$5=~E_>A-B5v#~*yBeZ@YUU&{1%QRE4ynErFkHSB< z!&o$nar45Y?LZ%9q@bo_z(s;lo41L#WU~lfJ1W>BBx#Bzz%Yj)G}bt;ws%h;3rW}) zNOiveT@ID_Zjl|j%M^B9<}SVy&T;`P7~n`z52VX8qd74gXHot9`qi^?<fSgoWKMV< zvznm2(;&g)xec<1Q!LCzJ2>8WFZF>CuuX(_^_~(3M^S`g#6b{EN!sM9j*zPYHA=&2 z2s5<BN)oRotS(g(R$fiW2b*eKrz*6X!kS)*?_aC^wHxEEPsdVcsd0{)M{sRLr|r6( zzNpi-&s5Vo6@#5!w^e^|YzZb2rewFet0j#ZW|RTmQR999Y+>g2u<41{H8D`W%=A#^ z$40j`)6+VSfVY)82mK%k$9>97=rug9L;(o%Ny<dr*zIKDXochEmoji%4F8#=<BpI% zd8S1SX!FU_@AjPxe&D$j>7Ac@iWUBB&K~~q^8dHwW@hIdxC@RTcARjYEs^fFZ*FZq z`f9V&ilvN8k8j7I`vX&nU@z6YoQ*L<fI;6x9@oe)_A=(A@|KtanKE3!npQU`VT#Vn zLBvdllFiqTJ%&F(*`OPPSPP#Le=*=c)#%p-#tE_^%oh-((rIMrsT*|wq?Bvx0cJLL zUelFc+4~EVjXF<mK7RQ4F&P>^&nMZ8#GsP#t~3KqTLQ1pb=Rid&L*9P2zNuq!)wV? z9qtEi;97R*c;WVFoI^jXkR^t5sdolx^x#Hi-QG3C^^l=9wlF!8q@H8DnFk|P{R-<r z*_|QY!kS7QHGOEqCDXSX-4gypRhADuLw#0d9*}t0^Ly<bYP{$rK*uv*Tg=cjL+y~9 z#+6gi@rrCda6(mo<Mq2C_uYJrh!HVVoT$|yJVrGgwaB6kikyo^0q}cG#8o3YExqNN zGAK3Nq~6!xuW8`yj}wc@<m;^wGsjrNN_ej12Ev>4UjR`+uD?K_z##Gb>qn>+p)GPp zNa7tV+G<|68*yWP7q21s!KKUjQ9{CojCD-hP?-ms+vtA(gY+z+^6En?;2}2rimoM} z(d%9A2ABKgtK?3aoCjKhb=Oc;t`;M`eg_}V?hcMY%hl}kO%7(Hi{J~EgiSk<F+a1@ zvhu1K-#@c8fN^P-uaF%Nb1j1V9yaa~W^V+=@Gd(oi!pg4fXDojGrdGf*Kyk``nn>Q zQTCXVoactj@gkqs2hZR-O_QQ#aAFRrzUC1|mZrL(A$ARN9bMa`nVXAN%^-h)wOnJa zo95LhM6Q1ju0Ng&(wGS4giPUNL4k3qVv{;%cN+#*Mcd74$@FGbYJRzrEFiZ5+vm*@ z!F_4CFEqjsK)mqsRY@k8z)26d6JWR8i5PoEf+z5A{?ZYV#<C|&%2Y4}Sajz29mD$g z!TrvTflZ2=g@Sf9wHkM5<@Z`yE>h%Cz8ZJ4559uzFGe+hTiu<kfpA`suPV5W!0kBp zT?`gCT+EgXn~tgk0Qr&4s2}8ihGo!GGMk{!2!QaOb5Dz^f-pWE_#fL3%+w={6$o$` z&%f~5dB8Lf>S_$>5+23sNWhrYw)0DqurTWA+I5KE(D7-TYRj`(zIYb8gGCaw6Ke6h zPUyX286A+X#kY&(CCHeSWK~tVy9g;HuHI-;!k$x%14mqWPm@2Q^+|P%`u&F;9UaMZ zz>>1%J%A9eYg}U?r$OfT01vQ2(Qe~3tduTXfWR@Xug7jgYzShT!P0AsJdy1e<ADD6 zjbzGCMrFAG7ydtVpY2>hZ`;?{I2c3X*AZQM)ql!AUqf=)-TJe)kt~Q4aSSnX`^@Ka zmcoj&m6YQZWP6P*ZCrS_DR;7EE`v$9{>gyCJXlrNHz<|*(dN+Xxt7S89fN}U4D>Pi zxIo`_?<!lWv{->k;QsdGPAd?N$}pKSyL>>7<;4O>RYj}_CJ7QC<=X8OH~+`z(puWh zo|;YwrNIpAB>f_s2g=L>yfNqTfHcl4%od{dlTDZuJLq=u?dmwW`Dp9GX43Ign2EJa zpAK8BT?A^~^+?w1V-z>mYFBsvn4la?OKkG1s~kBWvxth9Nq!RO(P~9GC(r@DnJE$H z_%){`knON#ui)dLR}`5+{ce^+^^5@80xtUVIjPDki1YMXC>UbZ#c+0VJH|M6Nc|l! zYh0c9_;-n=Il}}BW5>!b%5&;QmAgGsEQ?dXw{iXZ@!hN2u6_g@cYmf}UpPi{b{gB* z!pI5CVQNt@y4SL7hDOUc7$epmD;pzz!AI`$toZbyi48eCHn4pGtBku!vM)s9z7SLv zTiq6;Niq6lzs<ftVR*g9lm@Ht=S^t@!1ISqX>S`EZ3Hb}t4F<t%?$#Y7v}@=A|R2Z z3cPOJmORWRpQ@xSIonkj%lz&{R%13U&u{~JZw7R%_NPDCC?1^I6k;xVM3OO%_eys| z9zSW}AoL)GK-=YX^1}Uu-AIvB@YIJ;DTZ7)$(Pv-Nu(vip<_KhPbYuWc4)wM|3_?x z)N3%0UC*fItpWU{-!*Q+Y00?XpuWYqF-Ewn_h)R7)4b(&KU{4~^Yr9jZ3Np>t-z2C zgOR$(x`;<srm#PM-lP@x!S*1;L*&V0&2)B%4l&p8JO%I!bP(lF)EAPGF_nyXM0^@I zvf%}!*{ukR3$WBaL-=#C#C*j|sh>ktk0z^P>^chcxL+=g2ZxjL7@|}k4K}w1n~w)9 zkM>v|?YZsM6N=Mw{Ua<4k^*`l9`t_APP1yXDCWz76}#!InIomFGQgg1ezo24h|gT@ zWuC`UCRLa)nH2e$nfQ6OsPdN(*CTJb$<}6~Y7~EUv2HC+yWx(9zoOQZ5tAH5!l_T~ zrh3%&wwk@1VsVS*1PEVan;OFGlpv#<_~L0bp7p22Xi-+>5n=}p@>y?H4JO6mB6HWr zw0dywq2spyWBbwH-uE9p_>b+!{j8dQj<~BRuutM@;qjnajQn-N8J~_>em{a!F!LWe zUIk5l+m9a)+*&@~deEuys~95)z#5Cub$Hbp;SpZ-vSYK>@rW;w`&JR-Sx#%%d!HR; zivnW$9^Zu*)1vB8a`h?*WvoRF0w0-)QyXSZM%F_NK;(aWyGlaeIQ^QGF2yohAsaDh zxnP|h>-l#DBaE1{*bTWHy;HD-)u$qACdNNQm%gUV@yOQ}OVVUu{4FU9#Mc;*EWq&i z;H%9oFHvyqz9S|xNBk=8LzwQ%H~<6;YOoDk8>x^~U_?@Yn0ParoZ}zU?DH#R{_w9+ zKAF4+5Rloi{{5D77UQSonR`8>cjZKXud4iYHpia`IQ}g<q;fHoQ=hY(nzq)tC+Y=F zaV%kY3WvveeJ?5JkWfe{sQb5so<_S#UN^L5qDWKuIt@5{WYvH}-~YJ$xcE5xcyzEf z0MO0TQz(8}6d=|IA`}ty(P{x0h1qYvIX=A$+SY7>`rOESVnWH_U}8*IgCwfkH9<|9 zevX6U#H8z)sPz$M5f{@GWcF(k=LO@KFByEhAwuj|N|a-Q$Td7Aa#NBKc@FQx35Fv4 zD%KXs^M^)KGDZOs8-R8fhs6Zs$Tl1~l3uV&9RggyiN`F~G+aP}fc&&|_Y*;bZbdO2 zZtBCB4jZ^B@Gh>Y)uNV4*`%c<|5%+0zBk)Rnt&xFdV3cicQjCucVw3y%T??C5H+o* zGSCgBE5B;WW8*7>8xOH2ac=g14P0e>HGO0t-W*9E={xQk2Gp3C1!(r}t}Wx8xdWeW z@JR<}aMyNmJfn22M@Ko*VNfBVO>Q*<%dguJ?y;jNZcF#+YkyP>fDZ;k;kd1#KAKVl zz4Kp3CVXGcmTH1ntYc$_lJox*EvQNLu=h3%gx3Ecl`u2&=LkhJo%p|axJ6S5#`GL9 zaDW;iRl15K35o3dPf>|~3z6_%BzN3O-a)NzHXCVBiBxnY9nqK?Lr8Y<GaXj#Gali; zpTf|t+H0URkd!w4A0;=0)z(aIx|D?UZ|bXrlBUN)5^_+3DAvzHs6D~%-E9Cb77Mm~ zxyR6MA!mRyhA-;GAog1Rr-)FojtH6g3W$(~vxhXuPhrQ-X3W1_spRyqt4))KI#5dX z>P|^<T8vj92qXK6T6fhG_>TF|I0>0`!oraWO|)>U8~UBP;9fx;0~(;a)K{~Q<nkc& z|HB}YB*%0t`qgo93VCTNCs}~b-$^%^B5zVKVmhZ-a-Hv=WEHPWa0z%AWGEEu98+$m z(X|vm@w>30yz$Wl`cBJmc2Z7qvjR;(0`-UmzGkCi6GEoOSDc?cN~!AK6-TPQ+Gxaa z|K%4g{L3$C{rZg4MNz734MQYQAU{S7_65Vv?FD5EcOy#C5SVJBKkp7p*(uFDVHNE{ z(s7?<pkdC@gO<}<R@o_7qL!V$0`9Bt$st-pF{I?o$<^S5fmOJh^t32f6{zy?b95-4 zoi8Cu&nF-Rcml0JQioYPtNY4rbPVl-YH_Z|eUC6;cX{+6a5!K9dxC1X#;VY%5<m$9 z)7;vS-5%tQ;KY$Jr^r2{J5USJH5hS-A%D2jia4Es&(STpUmP@XBGjG~h<Faqau|-I z<L`O9%Y*w}sO2K?$Y|Bl4f=REZ_%VFC$ApWBKA12bTnB3Q`QP~AZ{3klNH3zk05h7 z{I{6Vzks_pDKohLD~Oz+FjU7D;6qe_CgZ~i{cuwOI+GF{vC6Yqg1=UC`WH_G{=&5L z^b5d^;0KuM`I#dLt{_!4I>~0o5(=JFtHWurgbcD+yZaZpNciCzA@2axr+kKpgO!_U zpJi#i-zNAKlRu(6Qtr@$J{WDjmxH&$j`qob)V5f+8E%?n4&E+FK`EvZkHG8J?D!Zw z8`Y;Ef^-ekDkm_T_JADC-nb`F>zmcGA*|2Ox0D4zKxe+qAG$LsZ{;|`%*3GSRd>xy z=y<tQJYa@mU(MFk+Fak!QB<L?s)eS?<0!F;P=f9s>#hH+p~u&1M_T|4G~!Y4e(xkm zYohYWK74V28PL{kB_cX|W+r?k>76^NXC3V{DJcXZ>q_~tFzuj7S|^g!fqYTNhoGb& zI}SeX4T##{bM(JimY;G&FBr7DoiFW=`(J){|6F`I=zK}rd&B*Iq#r+mV({S0$B+B) zdvJI(TP)$v)&9qE);oIAdvWml{fo|>^ka2rxc3EU-WQ~AUtop5^!D0&H#R?xJ0Hh) zU5y|6?%yvRs5^gtuz$CAu!j$<+7Ycge|`VvhuVQvbH<Y;xGtldgQeNe4l^QThy{<| z<GY1`)Z<-1CiFhOb{By8liKyGuJ(f`v+)9CsqOwfdh?TqA%MJhD{>N{d$>1(#0zLs zM0W|lA!<$WnA8K~q9y5{(PH#NIeS`8rx_)3o+HLT9vaLGy@(Y<L0yDixylyfBs&J= zxutqswZWJ?FF|^DSIQU&v>Qs*VXV5t^Th3l6}xT$Y!x#Vly$eFjD#45qD~4_G3}+6 z7nBw@Eg5yvJv3sx*@Bk7;}bI4Bf2a8F)6FuB$p!8gC#)qa-b7=?4TwBEIio8m@4u4 zCxeNF?%{j6w`G<$ZK&<re1W($v(nvf3sAjc)i#wCjhLO^+@0up1%9?zT}!iH%vD(x zNp~<@+ah+ZN~QpJ2=13hB_^3p_dy}>dy09I(r$`7D;&@+&K73#g}=o?;#p1;m7_zh zbPKauFS7FidG64sZPyCc|9jdQa;NWdUbG(bhHb}(EN}uk4b{*}wbKKt=OU<wDxhR- zNqd}!^`N6Rd&acg2%&<x+c)4sl{a*UYMD7QyMWZ(?%;LwthiD)s4G1Hwa8~O8SjL* zFDjaPe?pOoz36ZdMmzCxc`7A<Ib8zt+F_@C;lqG?aphj}DT7l!#NtG^b`*{J>B618 z9^-W+;P3&&05}#){(eTJ;U?+_6aw60lI3)+@Dcdh>p=0(h73%hLCtZc;zeXh<Fhxf z-xA$)A0<EtmyTpOQi2=~CNPI>q{TSwo19+Udm6xtMLB)X&X9Bmr@+_^T(LAv_n4r) z%U1!FKf#0^KTBe?^tBqs!FlG*Ytf3iFZx+^J{w_@K9uD2IdHhHbX!+|EQo>MQ%f4P zUQ-t`tMCducc3-_7G*?Hcn*&nk&u&=E*{(zpt)=Up^tZr>uR`RpdY+ot|i_;ZuJTH zoV(+g`w@r#Wxr;hUzH=bC`$k!;y*dztgGrI!*ni#oBcbt2H>N&q>F!l?=J_PUv~HZ z@t1=;`1~Z##*{i>@Q-%?&R%D@pL|>%+-dLs19^cvosWyXTZ8FwmzFL;#uMFoKf2?4 zk}a~)65T?Q=WkwNcW-|6@WH(<c*Jf$z<(ZW53%bLP<AiNQ3*MPmidT=vcOkw<&C%y z9y;3kC7aLT|9c?dX2<!L{@osO(;ydpIVvXk7bjGFIV;9)X*xq1>8yN8c3P?GyXPOi zeE<B(vktwV+m=2KJ`V8dYQatKe>`)o9NZlO-vY0ZHTpQ%yLoWue>rA`eh=NmxEI5= zV`w^G-2V+=+6Q+MpTe}Yk=#kPI$-uYM?ZYWwI8h}3Az(67v*^6E;Y`w0o&jM@|L7t zcgs2WwJK-x{;v}Ak>sB<NYm88dbhFOic*Y&$}b-e@rC<eFZuTQi#P9{Cs~C6$@sma zpV_Pe9>*7Z^5VnucR-P{sk=)T22ZJ7^>JrHw2sj^U{+!9ig?B^fhbdl?sY)4!)GVC zjt5`e@36D3JBncBuFj{2Zu%kdE<pVr<{S*<iazKtyb{G)Kw->qfSw3C0<9i><vx7> z{09^zix~vUg0$(T7-|PC2`a>)?t#f~i@63ac*Q<QwUvmIx^(MCw0->%xp^V3{*R96 zxLh}krSGr~LjwQU`4Lh(PRe6EpRRo;7J$qEE<T%&A9Z$!-2hm4@La~U2+(eR>S%#C z_#mB`OlV&^l6z;6f~&q8b=!4|ofq8kzV`?rw5QoQ`Tx^qWza{4QW0Mo_#|^YdOjIb zv?1R^LfO!=A#pt861Y&*?4ctZ=nwf4vjoreO+H7DC`Uabx~~ybIr>H!A2xFOc_Law zEb96>LO)$xu4y?gj?Td|235blcQs-xommS@ozYEZi<83{W3)!~)XJ%|Q+^y=2S86y zHd<CKdoe&9rlV_pI8yDfy3i-Z>&iKUMv`jK5L{|NLBxIE)uJ>Gca3?WN2#SDrP+A= zq4Y%Y&B7lyln`7CAX2G%M-IaCz$i&xS?&Tcamy8-54|`;1}dzCL=KTDtaYfN!KQSU z`1x)_=^aU;7F7ZVCJpk1OQA@`>1lsc_2EigZsu5LXyTz8Ut_?H0K0~g9S*3dw;v#q zXmQ`u7?lKsC{7Aq9H9`FS4$4{)C7|7VIOGI6L%~&1ylX5iAiZ_sb5hNpe<HH-w{(~ zTes1^9}p-2o1f!+b$niOnjP;F=e78hH=_Y2<IlB7xRuge4LLzhH=aKye9!sP@X^^Q zA?XzcN5NkO{>1U8SDrZmx5Qk$#W7fH-^hbs|NH0f-<eo>u9LhJIUpqm=0a;mhXsG0 zDZjSfQ<P~c>Y?8YHjk|)Q~)SmZZ(=^QMCtZ@k^%O>KlIP`Z;{Fc##2tJGUN|^0ApU z*JS;h_SMt36WB@(tqJOmoL6qtW)>bcOogrFKu?Y!i|YCG8@=g6-iWmoX($t!GeQeu zt<#Zp<VHI&j;`xlQJa!#mi&IW@QIGJzqR3FLK>nFcG7^4!W4%3B|K60;V0^^P0D)W znca=1pvY(~gd`i;Cr7E%qe-?*6=}E)ni~Y;beB^;=Sm=B1_gGwFK#}5^yn*dExNj& zbLMQv4<17#40vp-)DQJ^fdPfX2CcnO@L6-=avWyWw<X-rf4}gl-H?f$`P$h+y%_D| ztApn7k9K0Jl#+Yg*JOxFE;mxwRvUi+T|h8mDZ6W$(0py89?R#Ed@NIe`B-E^s9d=6 z^p4i;4jY5O?;c>LK$Qf}Ff_e#`3zf*4ex<V3d61}Ftk&NM4K~?1CzNt13r`ee0xh_ z$n(!k{p6z#)hWpG8pokvSJI&taO}aVQ<vXKhuumrz37@z=r%xY_A_A|5=erDzBT^Q zk~s?QG;9!!s6}jI%U_s-!g^!YkYSW-AcP$IxL}$HW)WBdY$;a|9X+IHcjPMfWQd3m z9&K{hS~f%EV}`4$KP{$Yz6B^2m>$r+$gF*jN{e>Nf_@JQrZy{Jm{A5i0LFQSCUum% zvgFeY<U~8ZmUfFeLWf62uCr@R&GL}b`5ustIef<PCRnY|#0J`IvLA080_s2*Z({Q? zm8kb74LD-|X1Z|{<-4|FTOsqsYgNqRJ+~3;u7J;@Okb80!fY4klGUPs08lMno58pt zqs%lta;uHI7b?WGkdi1_wPjRz^T6DBai2A*d^DBZWN@ZTCHASQgcku>Lnj7-<h-gl z88Y~UG)!9fH&|zF<vY5fFL4o%(72SDwIaZECpra8xp;zruaQ*>fJi+X*J8@*w1~zZ zcFtT0;S0DGYPag|t>*0;)fpw))}`N%3LcPY6G{2glZ?)pTlxy`F_O2DViP4NmKQ+m znc=czmQef@eofx|{PWMGZlDNJ_lB4=@$IY==%=*%kT6RvN}`ME{R(v%CVQ|ezulGe z>RtRB752z!o-%Fb4Xyk$TNZ^LjmkMjAbDafh;SZ9-KZjt$a{jPYCVx>nMsU<PYJ8V zbZ45)sSAoIJBBN}s?&=t-2im1p%UaP%yCs3ZVoW~ZU})1PdQe0U<f$RrX@iB2BEQV zE**fN08y5-TmTAh4wCWM)u1Tlfcmn!FK~bCYbo97xaj+rmL#w%dK-ZDLiT1ozAs2! z;@WlB=V>uEsc>PBAY-aK%l$!1$X}@ik%|0n@Vad_sb6{Heu@q3N|)jB6_cy()ON}^ zfMt>2uE-M^Lc|cku!LbrX|GVI5P=@}iq=L{rDYMsft))8omKc9Sz;YI&Yv4iQ!Atz zLZ|48REu0|EUI7)H@FLKuJ!MD#EiB12@{53jIM53>NRZI-Nf!=tV?byze&(W>r16~ z!uLDYr*Q_T&3GkXz#X(c&x(aXyTo=?Q{qqKcA^AS52N>NcU4oNa<!a8l5aCTYU{%i z?1>fnqmvjrof9G0ZJI7^2WNp5;nE)@V4wz`FA=|kyd^fSGmqHnCZ07$lirAE3{R*p zD7{ub?bN#C^WGZgu&2PPews~CLGJ6+qP_xBX#{@n&7G%d)+8N~R;deD4-&2u;ETXm zPx6N$TN@kJ`B%FTHGrG8p+|a{WIlHM%O=)S7PaHcUFa{*LD}aQ&FLwK=xJBcyA^YR z&+IfCRAHRGU>NE@{Nro_#1Ji~gkzO~X9R7e!_}eVHoKgxBjkRjt!UwZp1M6k*hHz} z8v~jOMLjKD=YSpL6}kFrlTV~68_w_Kgg*>z$Xy!rkb1wD0CG|KLuoF2qHnO}^`L+* z+|ZPZo#vGag^F4?D!PJFa-|#k0fn)+;?T$!@oL5iosyGsGFIO#%tnV67BuiD;GBjT zTIlZ~=)bXsS6Q{}y$0q65Ut1}?dENCLIMqBqZSshwJ~vprR<QHseG9o57`oCwIT%6 zuv$!pNoXJ!l;QNd=O57HxTxTzD;FB0C1bC#sqj&OkB%qhA$)^Mix$VNk!{pJM27|c zCyR$4sQGLT$PU=4!ROxD*;x;~k9w}h7{Z&6chG|8nA+VRKfLHY!oCjfa5{HK$cJP@ zpv4k@F*)P@iIZ0r;MM4#fJ3~y!N>jy&bR-QPRo$gefR)?kI4#Sp0fJ@FT{r9rD4oS z=6U)z+%-E)#Eys-5AY2cvWv)k;@E!j`UZp<c?`el>1TWx%oIArh<^zd0$X`h3LbGW z4``9LBo~y(>D)<d1?n4^u3#?)rU9&Upml^?p{*%Z@#FQY)Q(x611wX}b$J24M822c z`~jx+;9_zQ|I@MP8hw%w`fbt%p+HR1V4-De89+6XosisDS>yn7>?Eg1mOw@sdX7&x zFbPpW5!7{^))jxc#U<CDuCj@k{I5)4_L4SI_FeF(LwkT`)y7)@7aI$vaz?n4=Mba- zgToRS+W|9Wf))Mu@FLat1@$P^y3ln=D{>3uKmCj?N6uJw`oUBdB$Oj44FYEgwY@|7 z;=EiT^8@0$`|UmlO%wTfNKF*_eZ(GhZk5nVj$e|9225bBIYvOTZF+wZ(k6F8Z87gj zB!NPLHrVZ+o*1|r6%b*v5hCPhl8=uudo&T$gx&to-b|WU{0w*0VF}yHkY5~_eo8`k zU-TZVNCw;Pv{)`7Dd*XuSfbzyoT623D^*_w&{C>5mnH(gH+{ONXr8NrZl^3B5N35S z8u=#ee1p~<5T;GzL*2XhDYj%v$Bi^pD5`JoCLfsFhnHK^jcu^QK4JR$ichVnt}DsK zois7cmnY?z>atVsHk6tVjiatxSMZ}M&^?T%*3D2c#gz5Xzus2=K>`u18CdEfOFX(@ zfm}vksx{cB-E$>&ct6MBXBUC5u%1}7$!KR<wz4udm!LLBoi^F|L><)<_ZHW1&OUcO zqo#XP03Zkoy7C4vb>Lh;*i1HC7CmBU(Ax@6A^hnIbrs`~SuOF%!?-R%G+YFl?@A~x zhp`bez;JVT+t8B_?w^IH%O$G4L7pJig@R~^xn}EC;jROBgOI`g$Vt85VabXr(QUG> z(+ypfqO5yD_#xEY$^82xST}C1=563C{8rQ2IAc>KK}0mA^zbP?@|F-nRrFoqXTV&B zGf`AYT#1{lf|4A97c8YIRCgHH`eY)GjKUE<hq{{jfYI<#{XR|&lmyYcUn!oW!!h#` z3mbP)!s3NJhxTQx&+;QDP2}T>eBS8~KhN^I-QlYNTnv}_vsyu&@OFyvC)0ddF3wY3 zkoQi4Sh-V!t{)(QNGGx33g143xq}HYf8yzrN_fjSra^orD@5|c1XxKavLnj^->d5? z*APCJ_+VfC2i5+fydxdU)fI>43-O_{LoiBDA*0qYms~tKBxith1e#+=^D1Ax02rmu zCks^?3fk2MAQYXyC-G{t>of7dT~z5=2X|e<zBPJ%0?P_*UX}=hX;o!Ppk3%3WaIaF zbQZwSz-$M{G?Y%mSG!0cH$o7EHns-ZPaXujnKe=>fZwx9im1>&b$x&9pg~hiuaa$} z$B5Jr8`_n)S~o@Y?BEUAOt=C~YRCzi&4ga~wR@MH8OjW6^kgy#m&r!K#%a>+qU^1i zu3_Sn9hjD%!kt0(4Vv^81%<m!Vs`%Jz^c4gCYR@R)66>9S-*7rRl`Z!=PD1bdTr4v zYlk)lf^1wZMvMsO2Erc~#n?Clgyw5AVI>!R%{JyZqS24Hc@m6u+8P_L)62`rq@k0x zPhg}87H@=zZ@z~?0eken4i3KRiYe1>_!Y4;*>C4Pu{%O+hIEheW}l&pZw9!ld6h39 z4xpSsBHY|7O#Kk{sU=v;{iOc53mwoh4Tn3_yb)uKsdp&|->2b<CQ)c`pTIWT)DAtO zZdhgK#kJS&DN=oFkfdZJhsa->@KS8!1KrGK)sXFBJZ4h{I1|2G?3ylXu2hEq>SLpA zQ)LJMu`zaQ(smb4Ly7tjQ7b4RQ%?wbc5L_t`3>Ix(*j}{*}<(Z`~qq~L)HOcD$q%f z=ACU@ySxt2KmV4(!Q~x<Sw;a|7|!B@P1-lVdT?)RNCGBNOz2uEdIcE9c<iH1SPd<< zH~0O6M-LwYJUA!CAPH8=_fYffgp7(S<Ct^MdYzMmL#E_dE+z;2dqba&d34Switd=G z+{3kkiJw!UU~Nz_iU&E{3bRu;6D(L%eG+=y#ft^eQG$O2e&ZdE3pJsaFnitjp$xX$ zpx$&f3<jxBAoXNYK#U>^gOdImGyv!;R3!ilyDUbZoZt#bu$%X>zYNVI9(w$>>#jUm zGS_S0(Nk&HiOR6z#wyM@E5^hfhsGKkD0vAZOwKiYs9}N*bi~QXN`c~lP*greIjU^D z501>|@T9DkLp-?dtYBN-;*6C(qdKDmoAbKIJ}z+Vs*h(jswuf~qfP$*PR3wZ<+)!@ zFtF4Y*^QaYY&VwKHug5H?jC&@RF5({BHKc)h4j%TfQh8{@86^RK(1ycU$G`#E30?z ziaJpY=!9{!q^YE^B{n-vko(pUCch3?3hnGRpotNo05Yn-E~=8Zo<Z1#6DxIs3En8m zqddN79h;i~v5hNywSCzxc%zgx|6*0U$OZ*87`z)O>9?bHxHY*N0DUUw1ZmS+FC$2f zVraz<;HMlFo1hkmH3${hd04rSRiDsG$NFmoY{zdz$UaJ}qzZ>B$m{?CIj^7fRv>vL z)hM53i=qVD`e1A85h^&nUc%%J$GUJ$sc$knKOt{VL2$s*0B(G#Ggf);Cts=0ut%n< zyLZE2Zrh|nfTXCifZ(n)SoR+!0fi=#wB(U~xI>P`gaeO5xqT=FMnf@Ui}e8Rj>bFQ z@X?QKyW)nl&i5H(9f5wz`xxCu70|hQNJ5F1M{1Poy@!}6RaXz(WV*LMxJ$hEnlc@b z(GK){iv*P+qTj+XqT-G|e+_Z<st1RQRbmunMW_d}(hQUNa64Gzm-3Q>pg~C^S7w)^ zH|P!I5ME5w5rxmNFjl6kOmrclyv=YL;=w6}AWe1p7o<mfDPFfyox&>KeEjgy_E3<e z@TDX}D*!_ph!aEz@@~g{v_f~b<>K6Ca-f<`#wzA)j6%^>fgFj|8^~>g1!~DMm6vcd zreSd21piXduP|ww(9+w#-1ck=D!|>KDoO5R=hJW-OTbgQwe`y`rpN<L4#GAKePbr< zW;`bQ2LoSm2##N-yMJJ9(xAx@pvh!3tL^p6ws{wof)J~yM(ZiyTl@RPylKd$XHD4q zzVqHOfqCXgu7~*XxSMJB>PjR3S0P@@?D!8i?x(^xT(4;DEK9BfGmUa^4|B?$=8wC* zrOmm=zl|B4P$_YL8{X0uu+Dr<;|jdUyHV`{DVK3PAp^HiJ@L9mkr-fzP`bzbc(W*Y zcwH~hB1zSfQn41&g5ze(`o8t?Bwy$~KH2L_+)dg^tyb}a+amzdyK1P1qqCFz_wHtY za|_RtM_)CKU|3B{fLPT>9bG|KdB}kJqI@XGXY?f0I<8xrqU*~da&5#>Ayx|8R=L;! zbTee=#?Xyy0kElu82Bz5>o9kn$=}2EfI4~mgi(AW9lJUJR~)UVJ1*p(e2gV2i<uJz zao3Yjbytd+Ef(v8G2$bPzlVDxnUsLx10KVujhIL}Xse#aPg3O$!P9v%@k$cdl~%kr z3-f!zg8DGoQa7Znt_t_=kK`iqj&-ZjPMTKdJ2)*Kb--&cTpzDse7!yLD#lm*3eYMA z;u!dX_JZ}kQB$RmcBJP927XoAaD-LjH>OwOyRL7ke=2Su%Lprtwalc@)w*%WqsI~N z=&Ez4aNlpWfOvxegUov7iYGi2qzz&P{KjAtT00;xV)>G*XxG)#b_b^XVJd;DUDJTg zpy~bLDnC7;s;WY3cc|v=(uwHU>{Nk|9EK5>^9-Qd446R14uSSuwJy_n`jyTNfA+qZ z&M^xz;T34k*oIJFDpAjL-U`f+Nbyi1fcaL*SH>M!?w`gNP<KfA*Jbpw_o@ms5n$aU zqL3JcD=y+)Ii`F@ZJ@%Gd4R4_D6`TrZqGYfBY+4R*jks_j(qkj&yLcuaAQqja486Z z*08qi8=2$)*vy-V%&M43w(?=JcDpKf4&TYPjf#X_dFFUk#KZ=)Fg^1}80-$Wz;U)X z1er24+5+Yu;C*EXcYfkl8)&Qv6=CHbqCqgUM<=j`hrS3cW2^DDi1h|?Hu>!8iZjBh z$+_$4&l;M<YHb9tOzykudUMB5iV-4t+Z?S(7SfOdUxQn*%}pdI^x*5{-sYy<bM9}< zm9}|btN$)H{`tUMm~^F4z?b!xy?!KQxWuC7@e2m{x?nJdtc=-tQ``^v4rAUeM*usm zdQYw!^0Q+kPCu2BmYwvWBZy;S+aS(E7&7Do3;wl&$0ef2#)i-YRk1h3QU*@AX<!AM z)+*e%O6b_tk3ze|b$S8<#dSMS6F$~7?0wYn<}j)SL+*HcZ*SiBs%X+g0(_J~rwFKO zIxD%hbSG?OseNh1?)>3tT3_>0YDj}15m7sn&e3sZw=3}xg&b7%Yb>Z&wm4eD#E|GM zH2PX~4;vd|q0x8vK-S36ksId4MN<a%pWr?xwLVpfzU;n#0XDbhD6<ALvijisp?f$4 z039L*hV5x(uDN)X0UV&oN*B&PdE>|a6i5?ob_ZEX%{LMF+8Zj4;;hJuN9-|T+@Asq zr3_#ve#5<M*KTu9q<K(xgKLCVXz&~cwT3or7#AT3c`GNU`A^02q(K_m_Z&!N_!qh` zm2I_4Zz_fXudP>@UsEeB=|OxKTy9IZbM_STX&bL2wxU?Cr053!Q*6AS&OK)7Ii3Op zX!QN001w(HeyrW#OF4<dbpwCO(pZznRv-F&{mG@u|2eruy3;JX82c&gdlr|T{PoGt zj$&cthzV_Tta>ldyxW8cmucP0dD_`opJPN!8EDOSR}LX|M*gfsOx5Ed@FwQAF{@}p zVJAqU6S{ZYbtT_p$U&`{Yc`<!F=&Ou7?Otcy@-OdPkB*Y$$42dBo${%t4ScYFV8~A z^u|FN=NQ0AgZMEIeXZI&c|u7O$h-RzbShTG^D>)+F4iM*$NG12;Hn~THTnXF^9sA9 z?S0{4bkf?8Cm;ah8Y->^2iM?KwER6e)UIh31O|SW1^ES1qyC7B_F!6Rq-(lodl$th z`L4+>F!4nikRw4!`at5|#NGcw;Axux>dzM0{K;fu_bf(n7?gm9733mU=CLWFEH+T2 z)8{s+njn46y3~4@!C~_tO0CBbe(3ZKb&|P_{OJk6TjXeb>r=}>yIrZYU!KkKg(9wY z`uTsiH#_~&1SEHayENodzG+B*32pQ#((_x?Et+l{YL3OG*}SfgfsUHIT~Qtz%(#T8 z5>MTevF5M!kKzOvN=CWTsCbZF#pGe-1?ZDCP4e*UT#~~HhV*ha3;huPuk0dh^?Lj0 z$`nV8MYb*lkwx2qoILV(+inke7(xR3kHf7m7jeKfQNkaddnr}Ry#n>DnQhV=$t-(w zd41-0E}xeouzhO=DjkApWUpxnhNk<z=c`%N_j;xWI$Z6}C8?-xXf6aw=&adm4$JX* zYIulR4nMR{61zlsa^Nh$L9T*{?!)}sL<|}UJ74r!gWW$V#$!xq*p$B4<`{T0&lg$p zwL6vD{jF_$M~@^?ad~u9<&H%jFHgvdK@Yyq0lBJ5&^>K=lFgFe@<j>i{0j0=3ju5e zd6Z3E(B!6)3R@?=L2sY7W}98)6AWwl9>?_ti@OcZE=KJ()>19c9YK;h@vr_E5&6&2 zt%@gV1nH_c^Ebav!6_W2Yk)jR`C4k4*wdmyaG~az6@<C<OCqKD;^Ukc+nWIR{2$w! z0|=y996FKo6DE)!eBA$dKv>aF-@ST)PZoP0XH<?7+ql}r`wTIr>FJll)pA+Rz7$gc zs|Fw0C8AV!ZVd|aZAOE^4-pCB3!&V70p{B6_Uy~2{QNkdbq0m&uPToZA!gt$Sl-1o z=yMmu$8KU=j=E?*S8y8gv~ER2_X%M5x8Yko8z`d^1awXq|4FfQD;mQrVtWBgc^al) zGTu*+c%7$}4fWLPB!CP30D(b-;o{q+h|kKAkZeKfEjKJb>eEJI3Az#ZmQg|I>!eM! zmLh6*x|CiyN4Et@D1dpMsHKK^23dMPMH8x|8Vp0#_L4%3q^{_JW57?FmL;Iwtw1Am z!_J&{K!WCEr5b|cf@PEFOkOv#>!Ck=G2<$5qAnZYj1ywP5Zou?kH2m(7p)i(%y)<9 zU%C@4AofPlpMt$N<89z38FO(cUxyxC<h=!-xHB?9rxOVoO(<H5ef_L^UO+jrU@ZQq zaMxNChqiyvr9KDW0v=-+O+orNdQ?#0EENWvkJIu~jycsmKt<pxa~dZ7ZAuQgN53Ee zg=U2HaVnU%&E%WhK*K+?8z9ipPXF=UOAyi>nFSnbiW_okjGi$~C2R&uhFf}1#$25? zaL$3qZVwHO7h3;be>*wMPqNdZgo9h72~C)P!TZKQTjP*t1B1<n0jQepA<Vf)x&I2c zBJP(v?wabJ;#8Y=TYnAB%*b2V{gCK9llP{m-U6I~WU?T!w&9>I3E5(5uI!M?X5Cu+ z5FQ`oQ7EPdf7*qz6y<ldj|az==^iwnmXmRc7Lzt+K6F25@qkWFC{hN3%?nI%*!4D2 zsRR!e1lx>Oi>f%yC+D8#FipXjk@Ymkt;fC;y@bHXy1w)HcJ5|fO_t;^WYQM+bVU7M z%K|dF{3Y~x-`?yJ%yhtO1QM`Rn6KkWL$_aC1^tHhNJrC;g)c7Ua+_p8iaEi#fLNFB z%aRPuscajBePJkeppN5lZCj}v$<m5+-_@sFvagPah+!Y`E6o)=%|7uM{Yyz?Mtjix zhncTNiAuCPm^x1arx=~zot}0&bj%^JN8_}kE|X-&%a{A|?f}8Zs#r|Ko64U?<?>y< ziK#dd4mRM&m_eb6Sd74u$&HBRlaizhQ-6CFAM(*BN}YORfqy{Vh+ZCi)$y|xEIja2 zp0lMnJ2g~M$K)Q0sL4}+#pGhZK2Z>(jSN;Qc8V9@UZ7Wnj=+m<n0PrrOJcYn!jhqc z-#)+)Zz6NrfO&Si3)0BIq)Q0tg=X>oXDV_s8R$x_Ocn;2i@!A6SHQ}T+0F|Ht1mF3 z7y_Lbn9N=_nEc#vt!I!?4fN}dxKQ%*POIq_0xQn0B(eyS8AZ^_d!ZQk^7+HN9u>Xq zVHCiIGRkHc!a$|~%ANzFggdWn%Z9KaZjG%<*%IBkJ!QFpo07qeV5_PzNW1V=?-4(A zRR863Y<pbh<fF`zAac|1UOe4?xb={gr4{(&-`l>w*--;mo?yJjU@)!5v;I_*IJp@d z<g?zY8cYf&4J^(FMefQxxcBhk{YUN7-P5Z7=s~BSRrAkW7qClQ*V)-w|Lk7BTpSMs zl&Kmljz-WG`L|c)qsM*FF5HA);(s>*?1keKIx!>lORU^&BVzy%&^!b2Izcg*Kh*>v z7@k#|jTEexd5YbHJQ*|K$MMsDwB4Tk0-E<PV6guJq8)j1e_<CkkOVEM@l*sA+_-%u z1(#cjHZmLZnAaK}A`I`aCHOSp-AC!vIMbNhBob6sab=Kl>U%e*@4{nIZ<13<x=sCZ z%z^Rlx5r!HfO_|gcacR2h|fivv&5JU_x09hixeI+@9~fMXb$san$1?OrE`s8abhp0 zuWjFau>EMW(=vOlavMaH72$sSbU4_4^x)xF_aEY#V=lj9c2u@(?lU3)XxJhmSAXs< zj&epFNNX$^@j5VB46z=}6O&E*jM32B*0w{ycf#o?Aiek6kzEHjHlQr$RZGS^Dls_! z#*JVx(4#el7z#%X#{`M$u6F95FXozx)=;WN@btLaoq)co=MyE!mVJleK^$cXtTiAa z;EabYBcW?b8)Gg)3ogU>A!P*)br|u62&94sh<;5{IaoX3)Q8($T|w19+=S18-Q3Qo zxanY|wc4M|RV%95Fc<ELxHf7~Y!Llhu+?{it_$f19uj#~z%tyui)U}gghtF62e~Ri zm(r4I`jG0d9mG?ruWa8!^pKmVdB=Eg{)ynhX(AK@=Sc3=>`WCx*oxN2jE2C_4A)@X zi!Un%10pBl-Fi8EQH$926T|`i3HW|9;&_0g5%yA}_uWy!X^ijyOs|?=H&o=KueDD< z_ufhJn;s~bEdYTK?xq-1OaqL;5ESS|G7)EiLvd+>8ry7<YhBr=0t0fh<k#Z3%FdGc z>bKt@1`3j-lCSFwbI?<;4ukzvs|CA`p$}xSB-k?IE)H{2wSWlc=uS`Asl%))P!$7a zc+SMDU_G5+bd}p-^}(HCJRm0v=Ku-_8f52q*<5`Kz|eGRfisuLfHa=$)Pj6oR%$m% zLrRg>R}xeo#(gu`(I++Zl<2m5Y!G;#->$-Bmy|CJv_`ja8@=X$;oEWkG!8WPb!jvp zO(3p4@cTVvp!-_Te*x%EfE=fx>70X(7zczz2eJi1UB=$_nB5rYj*0C;*DT3@j4V)b zJcH}?f9s|8zxx)5B8c8-Of@3stTFr}_*}Cmub~6a005pb;w?l2nTU%DbJQ&|3^EII z)D@!>R0oZg$baZp<k^XVdgj7P+Kw;8$b<92i2XAcjBCq70ehV%6k+_5O<F_hBnkvK zr1uprk&p}H_z+|=a`N0^h!BBhOLi}>njFh_3?%eVj=~UKpbV0<oIZdULFT=yk(xE7 zH^^y7A0S8S$s%w|c8h&K34njt4crlqxjf=X$B<8Q7oi6PF{2OMJUoG(VXNrP$b`kD zM=$3)7N44WtBhuJPpDs9JhA*D8sZHeqJdwA5+;l%!c&exO*XuzbAYnsy$W$Vu`8g3 zYKd5C^X7>pTZDX;PTuO_KC{T9N_Wg5ur)Z@ZtMQ`!%jGMwtUbOn96n=qU58&^%)B- z{?^Wr?ZAt|-E-yVrhdi=CCyjHtqn*t0(qS`U$XjH0O%ZffcmMA`WmMd_FecXH$JOK zUw_IEKT+~XBA5x}vOkX<UK`v`)Af^s3ct_=)(d)~eXoL#D3;d(S&&Wv!AFfZ@lcfH znfM_F8$)~(B}5yy7G3G!XXC_V3O+$?#BGAAIz(WC+|~n(#<=7RAA(sO-9ORpV~1T! zKfPk3nMLT-SJt>N^QPRxfQMmnAA%a}ggsAs$<3|%4>pHrUWdSwN;5ufZExSBomdD) zE3i!4h<#E=Z#VAV_+@j?wrv+K>R@M{azDj@K9MtG8n!0<!g!0eFTW(Zxb+)>%@l&f zT);w@LS~IZ(*njwvoS#oD7=N}1x$eh@DP+zSDorC>2F7H>`k<IH=@O`U0*(bnEVB_ zTpbEHy3Ki2AT$THOq^QQGFFa|xjS*pIUgX?h0nmUuAe5b&iHpWL&$RozfI=jG15Ue zjM1#tUUBt16L6TU$D}%=Gm2G=RTToAMV_g_0yOI^B5(Ja8bj=v=#<CM#;(^UTV<2V z>vx~4UXs}7XQH(U*>%>1S$d2n<*0t6JG;F0OLNhG|KY=1cD=2)ND62Pwj~cuANXB^ zHH93;7AC!7XW=wLEJqv*4{E;Vc|MvpKL6bFZ&I>Jg}~?1EMz%{%D+JQ4m};{2L>2i zfU~*I06NdaQiwY<`;KQ5d2J0$OTJYvREO_<#qo@~<0^R>5vL^6c-vM}I^wqXjJ0rV z)TbIIMl6TuJ56zU(Q3kNlG1F;LjT+ye8Rr%wgMT|w*>^P(56^s$BytoDmM*|Zd8Uf zji%B>$tcfwMI36xAjuuy%_FNW^IXrG@ksJj+CnWBnr$v?{9FCG+9~{<cEFw0Jv14+ z=?CY$wl0OFQ;U^mzeN7<q*<eRTAN8*=0yZ1`jamlNe^pd;;6t=N~K`Jeds$*u|UYQ zwq)QF%Y`A0rbV=|n0X{DE?8Fs(W0!5w-uD6&fZP*?*_`gR?2JDWfTl%qPom&=$;Os zp?v&BF8zT(0@Vt4qFh0I1_|RgaRM9SKfZh}x7{BY3E`Ofsu|D^wVC)?09r{EHMmpz zR{hI9;p?FLvV3cq6W?eM7#z2(yDjdj26qdb7=sFUR;NKs^cSXME4x0U${N7Q3%`k; z77MrA(Ha44%i-#nkMbdqKDD>EZ*G6J`4~yz&HMMhdelh{5mbyJN2E5es8fU(!d5$Z zx0tUcnLzhtr={Z;AUlC05wGDTh2%KqXY?s&5F$9^kq^6EGWg2)pR;Ehu^H>Q470|y zLr9xxEt}z^dW^xBELG)XY^_u1xV3<29PsfUw0Aon_u6~AfBAB&^X22-$GyQ08(0YE znF<P!W8*!IMTUU-OszoN1wNBzYeTh`15jt19`@(uyv;5|-ec9RW{F@$<YVXol5qGK zIN&R^DX^Ki8m7<RInNNfzH0<hF{+@Rrv?jxu3R`BdS9%$Wib;677cG&p9<S&G>B7) zOM5?%{lT#okoUo{BwqdiRhhe)0J@&?qW}~HQeEnvNBltz6fL&mol%Gl`ZlEQcS_y{ zA+TR9>2^DU{lOS~@ErlS&^Jfzt5fx)=qwWTg*ANcMG8Mtfy(hTwm3SfXKZB?Mny9{ zPeBuBkR}x)6m!8Y#Zyft3S*a>vhs3e-q8Sp_jOy5LCDe69P&01rfQA=4e*;h&9bU0 zM*z7yCennl#&$*hDn0f4zrnpRF2oBKJ#MqBNc7ks+d#mx!6+u2H<&K;gJL{_aC!vC zao<0}gp~Gg<9vcGBX}9+*Ro@^Xfe!b#2ZvWBb!0xbhp+J<)|WY(zMM6*n$kYU~;ax zDG(W!GUjAQs4XJ0n<IiULk8ItoXk^EE}bA0FbK4$9nmPXg5tv4;XFZpGVsKNOO!Ot zsRg!)vcziDn!8T1iH|V32ad`>YSlM8M`Nx-Kxz>LIMW^V-PsR&jZHVdX_%h+#O(Ue z$Y2nt0Pn5lT1C<ZwL--U<=3Rsih!&e`~%;)Z3Nbr+EK;evUQy|qxS*gKwR(`WspBJ zH%KtG8jSZoxCEjlk^GMqd5>&@n5LJn8}Oh34WZj&PSQqjoXUjcZPY17e2p}mf7190 znq@%6Nc+12sAcejA<XyS4qjC!?S`{#LabrG5Jn9`s`|yU3e(KwR*uweejj+>WlI3< z2J|Kp^R&I@Km<K)+I8X94g+HiwCE&9Y$dotgd66ADB@MXX@M^=s)yO~=k8MQxPs@B z-lR?IolQDJ1V{nNU6jFYO%~ZPMFlgC4#{+5!qP4@kqf}*A!}Aqc3F}D$>BerQ%rRg zw}rW_sODlenykjc;~V#HN}B*NXtfA|D*yh&>sNu?#i7sAC)>7HCt&t+xNn)eSO*#` zdM3*0AZi8vNTv_3=)<xE@*p4DW_P9JPD^umg~|&5&}6-l8Qfw13x^9*+kz6neaMa( zZkm{tu4;wQx5)Ou?d1Ifi3gzUam(zON5l071KyX8L;^e)-roXJa=@<p+A&@i^ca7^ zy9OfLv400<QKXw4jc}@bPx)sUdnsPD`X$Sd>_-}hWl!_PvEu=pNWndh;sY<(?essv zu<nz1BkglS5sJs0LJOw;7nYa3-#I)0X8q0`$YA~oUS|w2k0$*&B%gr{<>4pwNPY6g zkHH1v>{>S>wwF2-EEzt6h||fr_=o!lf0-o?j&%%ch&?7T^Bg#fpTlK)bVSL!JUgAF ze$n9dHy&MCDvp8O;d@GF4qtTfZ(Up@ikueAmvaI*RNe`KL(mG~33_X7Kr%--bPU7% zQy#^Tu!+lX7Dn!)3U)BvCRP=pjD%@{alZ?DuZZPA=4z_N!<0+4^|&xmPQHEf{zDoJ zU+yj&E>DT&yL6cc&J%R1APAYK+M^3zf~?R|b59B#Ni{=Sfc4!aj2~2>3J8S-S@Qr5 z0Tu&eAovWSbT83dkY_l;?D-QCSgQ?gG_pJj1qMt5c+FxGZMLjgGmpg#^Nd|fg0!JO zZ9NqNqs;M0{yA_H=4J#VtT?QrTbC{i2G5LF)9HCKE>2sT0VTZMRF(7cd2;(LxQt?M zOn1M}T>ZB>eX@;xPQP~5eUti#{`eZK%~z-ImTPRrrnt=kY_oVAW9CST&<RlABnb&E zk+(!zcM`v50aA^MQ83XIA>~0ybX_osgMj1tHoI!;4A6-#B9c!rEEme{uueB~=W^!$ zh4?TvW+A?<K$p9bOx=v5`iv0nYmh7+8NQo%z?yCiKF4ANg#bcb0})ySb@8w)dQI%p z!w}QuXqMCik0j|)7hhW(ljdOTY*tJ&au~iO8e8l?PL6I16$i-1s(VR)2$=$8=UJbz zC)`dU!lO%rH>qQ4o)e4(+wCr~K=9@IT@HB)xIBT5Wg6pzcdWAb#}F?M#nun3sG<^} zzQCVD{t@DDJSP1HzF_|LZ-o<v+@8f}q}8T6N$0_QozJ>W@%ofl&i$Zx{9&{R1}nEP z2oR&y;%!+K6qoA$c$FV5@yFBm??04t{3-uZ#qyR*W|I*n@zh!{WeNY`Z)zLnFK<)E z%y9Mbnh6(1Q%6-T%DK2eF}jc&t2Tg|W{9ZmQ6hzMKA7YPK16P+=!{BEFw0_u6^q`- zcaoSND4=di2DHEoCSBwcRGp`)YteZD=9&h=3qr05I+e|H0mnTt1z}d3OTw_EXgui% z`xcHTJFLpd$`KDt=Mua+Dn8q2H`%x|3IR(2Cm9jD!d)Pp1J3-Lq_-u@As!HrP8BY4 zu;)wve8U9<(x5{r<QZ{P5?2Xa3RiGbInmh{t)!@o0o8WU>6Z6Lh$euS&1`409#S<s zi_n&)_fopQ1aClk$!lQWLT_UPXsre>$QO=11|JVyZdB!OMs?PU;tOBaV;ME61~l}c zmH=11oDid&woGA8Z4x0RX=p$RO35(a5S%!Cu^Sca`TFp0P)O1&u(3X@8<)7T@(ImG zRMb{Kp=r4*G%4(TimIg4L=HqV(#Hb9Y!D&oG^`@-5j<+P4C*-6!~&N!5*u~{JE^>2 zg!04pg|1y33AjOa9gc-;0Nham?hh|@sISytBs5F&*<R*1g1Ik2MM9+eu!Inw-{F`- zUQ#@#?ngqoQVs4D>YRwpE=LRiT|lD08|5KnELPTzuG<YL8cc(B#$Vj-SEIWCrk)m^ zqGn6UAT=?^+PV3YOuVfK0BA&dFt^4!V!oflRdK_&YIG8d#^}a~!qM@!PaX65D@3IM zTf5oaOcoi@HGtj88AKBtJ0^|^{nkA=Pae4WfAc=Mm$XHFnG|nNoG8+X5?$lmIVR&< z(15xP{B%;d(Z7>`Q78J<eB^1p)_*8D15oMfN*Wdh7h|UtMla#IyGrqZqs`HM*9UdO z-<gt->Ie^w6E@1pgs7c6zB;-65w;I6kh1YzPJ0O|$K!1)|9M^IOdso&;|r=>tiK>% z3azi1UKvY8cJ7*Oh<0P_%3EZ-y8Ks{GqJfxdfi|5kf@OYt}rjh0gJ+{8#0~DfVSgS zpb_83Mc3W5qYULyN;?MtDB$D6b<yY1EwYCFiueJs9h`;AjOGn#b1IR;D@blDIE3~p zmwS6dxzsE7s-ezoioCPPv&o%cVSJVJw}1!OXYEdaMlMNas7Mub%6!XQ!W#TATR)LN z);JhteYAr1ldz2-byF~!Lrf)D#k-DAWyl~lb&0-r2N3bS(!ggTsE|(Lbt{BJSFcgC z;H(Y_znNN)iKcWbwC$6ryA~ZCX5O)c%pv5ruOb)v-cqq4v4^NO#k%m&Lv{2X{^VpR z?0#D@sL}iEC|eW>927E2_`$jgiy7|)cWfNry4gen<r|#wUQ%0yUenp4Zhb%*p6168 zKHG_?LVmWkMi?kp8BjaBQhyjlB&KyuN5~LlI!l5x85BZqi_6c7IVRrjRoiV%<jG5B zY77fI-Eh9>kD4WU?Z{N?BQ7!=&us3XjQlkDzGI+(P@(g?DL-^0@%LKV_22RvzD`qj zY1oX;ggA?ws7Ih8W_<AXfug0s+nrXR*J(uS^*9|o1r#46{9&vkkme1%2jZf}tb@Sj zDWN=FgW#m?LKS=Na)X{1_$N3wxPSI(GzWtH0UW_PrHvWn&|{YRr-rCXJio_Xb@j>` zwCUp;Ft3QCl?+w)fZrJALxZrdD*OTbx3Fjv1YOus%3|(8--4O%)<lP{#sR7lPJ#ta zjMBp$Cx8N~IQrI0E^?+?XsN)kqr=tlP_YugrLcd7FA!0qIw{Y7aS!{W<6^HE?`}Wd zd~_c^c3a>n-}3Jf-%-L|Ad@B9a4{%V)Yt?+!rdDjmdj;19iTcJDzl8U8W`Ld!0NDa zbrXKOq)Owfn%-dmGjib`zoS@Uuw_lh${JPDpTrtcf6hEf!a3A!xeMq?j(vcqFOS-a z2rzey&BSWG;<KdekoA*^A8zP_T~-KKdDS4LyRYeeJmrp*bivk3s&aR^(L~v^x0tP_ zvvM~7ELjnKCjz7&IoC#EqSJ8KQLWFZ96PDOB=mz_AH(ewfV)dTqFwp}nFsI^rDtdK zXX)zVa)fFMe-kq48bV8j!P<jA+yZ0qA>dm8dlFJr21bju;ZoV$t*|>V?qlqupdEGv zr<d(aNt(JM*f#}444Ps6EheX?=L{CbNELLK16Pa;J8W7r@~#=Sx1s@M*P24wPSr)Q zgQ(PnOf!rnTGK+{U2S`6+!VNjH$sO4qJNm11H|*_Q|Skif8=@GLxCgYCws!jpeq}( zl9EOIdKVKdKrm9#Us#X+bxL^EmjKzsl*A7Pj|SVDTifJfg4V@zK$P&jA)BhmsPno! z1ipvZN-)VTHCZyBPjqC;907FGmP|?rY~*OhKH}2M$@)c6mf4cph14`qJ?Jo2XrLSV z2y-UR$Hnqwb%^LS1S}~3K#ha19&%uzh4x*4f2Jfn>;661iL&5;pd??>@k}shqo5$s zJU7`fOlmdJ2Q}((*j`C0Ub;H>anldz92_9hAQG|qbLxKhyh~yF7_aW;^cZQ63GiRd z+!QZYGxv0I-esR6kf1BL1(Tci9^HFHVGIukkML-k1%?_q4i&&M%H+6&Yr2|(9~gim zV({N*cl-2%b$IPAH^+5<W>$j?3V=Gjk8V_M(0&ad>D{R5dBe9QbB*!0wdedTy^U9$ zUUr(W-Tl#xwUV+uqFo^uG>dOt+2j~!zQWL7^v^`cVby;J>PsW=&_O3+6Qlute`U)- zm1w(ZpdMN`$0hJPPcrv}o(+Rc8}i<;VkCyyYY(ywxV!ccP#2H9riYb}-q{SXJiIOl zeYHKeR)I%;>_}>bIcxazpSg?ky~U-+XXEj=<QGXDe3u^se#C-MlwmK7A*H%<RRnOx zu&qG7z#Xrgfh)qyJ9i^8NDDPule{7&5ddg_Qi^7*t1Ew6WQa}!7*(b!&<;t|oBO<l z#}qUk5bp^ZgK~C0EmxK4UDZ#Xm@WfcUv`AV6!Zb5`>`kw9ZLvx@xfg1aQn%t@{Dt> zGdOEeQKD^8rulZT4OGveZ)3hFAm|rWbTD3e-NjaUq7YUZLMbrPZsN)>IE8mIk#=Re z@bf+Zk{}&o*Ipo5;vCDtf|?ini1Xe{_s%l#Bp|dEFmNQ8+5Kozj8M06QXr74tJ`%0 zT|V4aq>gscYZb0KfXVFRj`*QmvYHR^(6Z0PbTv(Y!_5fVu$vG%Um+_EsuoyT9z4ak z(^QQntcRIa`Q#KP(Jmz~BTXGSr*L?Un<ySNjuwR*H((4?Lz+GZ$aHs~nHkT52+%$P z3n`qNTMRO3S2@mn(_OkaTrEE31E5yLBLB4-oE4vn!H@GXE=5ngrh7X4n^2$!<7u_5 z)}FRJ>r(m9q8A;#=x0-A_vvp4lfgX*M%IJwrD(D{8Z%A)4K1>Q%+Z%uCu2rIu&yiO z;_LX5U-+$hLhv4Fg>}G=yS1*0TmI`?p4OQC7C6R&ucP-al<#m}xGyw9|0en67W>-Z zCs>1<x1hsozt{2o;^!)M)Fc{-?om#rQOX7z&<z?f@SL0q&L`+7Q0Ufc-~4K8bNeQ^ z@PGiYwb{KUKlb3kR|rK2O*};hpufH+;7~@w%co$u1~@qY%6#zfVJFy3v+_F*7H%~7 z#A7#esUybC5>11<quf3k+_?cBFZ}h7FI^Aaf!XSBZT0WN3&z%@@vI6Mqk9Z*o|f}- z@<Zc~Ux4;LQ^$7#i-L=8Q8>~Mu4V44ckY7AfXX6m$G!IY<%a}(Fd<c7tw~fq@LO(} z-)HlpZ@UHPO8If=W_?xk9K)Uu&{L;ntfWU7_@tfJ9bT_{UOAQc>u3G&-kjBF8nAwH zxcBvVqq0Fdv11^(*+9q}f+!#6+or;8-R`84G-J9&9dlpb>aU7qN}hp0spx_l2~@iQ zV&N=!qXI~8-aqbl@nf$P!m4(uMkl+Wr_C*~cH`qNDkAARaRMA|m=s9Kr~Dk!<PiYC zw@;q_=li!$o<1KYkAVMt`sVfPC&Ogx5&re;`K#w2+^hQ!@vk>O{Q%f1@ca1>&xXmp z2lVs9^LOr(d-%uur%&FxFSfsezrKI-+Wo$VU%z_(;)DB*&)+`z?)fiN-M#zz;K#S_ zPpswb^LH=bxCXW!V`J}Le)m0m`xyS<-rn1WKR!J9c9`H}{P>a82hS%fG+W$?K*5n? zuj$_<)_@YE7<Vh<OGL2H!1&f2qH^-(e2<E6RdcWL@4+vCXdgLV!|l`jGiFh@?e8Un zHW*UAP<Ovj@{`UW8HO)914?9O1|=OOYem)W2#9ymn3rlUAKkJEp+snG7?wMA^i6## z8vU~Lew6424VV@cznuwDm)jPk0L9ZazUrM{_VRO@_`Fe&1q@8k7SN#4+lqtnbz(&w zvnNx9hPEiln2FLrICWcrPn1+Ra`SRLOxg{>#;X-Vhi=;b)g#odNO@&!=l#N<^T`7@ zN=Jo@agTzO@7~2$g8*$KFM&cGu4xFb_)$B5iS25AdZ)oZsNIj_ySD}wJsEo`{k&z; zIzgjPmP?3LE`ngg$o?ZP%?6O>$gKn-#kakvTT~yi!<P`d;P~htvLC$3W}3~xZGKMC z%*7N^1Z^mO{H|1?*0TPxL>c9&yD!l?OpZ>F^e4rQWU%L9SX0bYC$)I&gB^Out+-$P z8Ha|_BFYyhi~I;Tr4)9*v2<g9NG0grr;)#m9z*p0njX{9Pu;J5Csnx*c5mN=T_LU9 zP14&3t`ZI56hQJD@Uf!?oYJWcQ^psdl!5hbH>XA7^h%t^NB4r6Gf-jZ;05v@)!Au0 z!RnA}=c%^RLrRn$K4qUu%2KT2J<2-(#eIa{8kv)^E93wL-I@mtXI6$U-xBw)o3Q@g zC<kseX2-H+v3ECanMa1Qv$DX`_%(#$7Ewgb5rM6sq^LBT?w6F&_*GjGauv{3$14qy zO#<NvgEe>v6czTi%2(qO*Q4QiJB-OQXQM{wg479q%iY5GU{MnJN_ISE6~&nYK@e0$ z$!W9If7D>~flR81`x*8mZVSuoC-*ew07#+|nAmq)*I5VFK#Fb@mD_+Yvl-GieUXAB z4_lN>=$c{AJwCj=H8ef*{zeAzlA62Gad0QZu_4qYt;2eowUe+kSRtew2Yo@@NApPS zhY{g!S|=iXK$yPHz5(<GZ)s^m229D=gTub%O^4#@l9HymZa$p(O^2ax1!j!Kr+5;m z0(Z%~%Gie^eaBU~``kSxUy<}%w2h{$x8)$MS&a@8v*!dc^7e-*SF0Kv9><&-Gn+3U z<}zP`ZBFD*p|imy`~y=UsKY#IDO!zEsYO0sja2&z`phnSG<8M0%I8BS8)mMa+Gqn+ zp}o*=`c~-8Mz%Y+W9X8%j@NYOQOgEc=E_RNLdA97)rAaezwm8@qq<HTVi0TWw_%zz zb&;!4ovm)6T`)9PM%F>>fn}CRt$dk}25hW)t?Wf@*!hdr_1H$wc+rJ{ns(V6bbW9y z*}5ELW8E<W4UDe!amKsKO8eLXvM;2WPuGk(wCmbYOE3S-*smCRmjl$b`^^(!fD<pH zZ${%Uq|7`CCe26e#oRWg6Z4_AHgOP1f{Xl=LCS|o^hAY2Uq1ocpxa7g|F`-N`&(W7 zXFF-Lwg>%DSS19?o+V&UEeDV9Z{1^UnW5!$ucle=5QE`T<@2BU7hy4x4RCsVS%^rm zv7!1rynAiVzhJ|ybNKf-CQ@Utxg1$=J8psmp6lf0xBf$y)nUaL60wqaXu5yKxmzw! zo{drO(=T$&=rNd9?$`duv;M)|0f+t1veV)iRF#+(;>j_v!=Y5rK}}Jh5y1=F%A$C_ z)=l9!pJeA<AMd9-Q8ab#HK&5*!@IXGDk8|K5#+~?fmrLGY}``U7wo@B=*ERT3J`<c zaD7}!9lfo~z1DaO_L+fcxGa1=TsrJVf|4=|EAR10p#rW+(8mDN4;<VL5w1|W!q8IC z?ymt%gq*vlsiI;9UtzaX&~oPE@{B=quAxFW#F${;A4k&MM(f4H2mr!zpKAwXuTzw1 z7x*vZv9;?YkrWB}ESjB5GzqI2b*{NXo;CgrnM=zU|Hcfg4<+Cyjfo3vo1{IW(r(PZ z8BRD%Tpv*lvyH8W$n6PLFtJH{rxoXa_pUzVcDTtI7K}2<C&r~L4Zrn}lgBhJ#(f`L z?htT-+yc(fB|^(qoa12(P=hAjPb*BV@CiIE7<`;yFd#5Mfp~r1iHyKW19VJsS^Q5( zmP!do#QzOl!#T~6$Sq(h<lZyrwb8id8s}xzjD}IXb_At{fnE|^=^c(<KG!~Pl7l2~ zf`ZeBiMynJ5$5cY46&JFKWu262Itrys0lLQ%`lIN_dY;F00QL$P@S7cT1r=PQ)`0I z{{&qoc2i#6Vba^$+)2M_e1$ItfEPgj70OFlYmw=F3FO60IiCR7zgwG1HU%yd<wSAs z0yPl+ggv`i&ok(EeSk78fj1^@x@~SoL%ucxk&&z+sNjbs@i$~2VbpH*&x$do6io1% zt1xVjGsN{<_G=W%90O%3hqzWyC|)=5K(jvi(;PC`u?c2h?ED9Pd@R{8O>P;3Rf|Qq z`AV`RH9Q0e1oHK&zhu;_ecMI)>cGcB0^YN`^+F>Dcx#OEE_+M5`wWv1PRg@qHYP6~ zEk(u1*S;&_kfypyGtMYXi{96pqCf<#Iv2M$P^}yASkUKPQ6}_m+uDjF1+^=(E}&$0 z|9qWLJO}E$k^-?hJ&UNVa$x4Z&NUHfkD%tCZ@GRk-w=12=G?M>619rv-d5e<>zKiO zj!3Tm|1|rKwg3OG7<~7UO%jg|{G&eri!@+*{@X0Ts!3(@Y~m+o=>DqNYLklu$sPL4 zYSCX{LlLt5j!`n30*>zee@OGK4%J#RJrD9{IFNrI|M4&3KK?1*<64}@zlrboqg=<e zc#eM+$MG-XH~uiU@ke-#8mGb3bsdjkJdZX()E?YHQkyWXoo2J_IA1u@mmp7pp^6BU zw}gGpWL<aXXp&W^8Sp2uOL2>iBtd{B&M;Im_KjfWL9XKV@uFPK!QH)M3sUGYK>T~J z)Xeq*bva$A4sTd+(3?V9^*IFP6h{b{zEo&z@xsN>ONeaiBVpDP=C2&iu>rEqFQe50 z&{qXrJz?)zP5C38DQ1M!Nnd@+&nYddz#Aq$gV6+%(vcuZ$ef@{!N28eG5fs)8zMo1 zV+F4`)ry&;q@XhB@raTCkPRl08ni|o+xrumDBH0Q5c|MXVqVTybFI7rw@EDDWjtVl zl9zgm*|Q>>l+D%2r?3go$<zt)P&jR_3l{oWar#p1^uEtM5dL-QUp^CvLd^c)ivi47 zQ6VCp^lswz%~RN<^*ZULuNJvFu9)6|wiBwwT`qMJ=-8S%>1A`B^scc^N4bvOsasPi zziqCSUp7`tv%RKPUW&#_>D`(-abvBmlvC8Nsg|wTBk)nd)7sF&igiMlG-Hc2H)TsC zqkJ-HY>E%@npXI&dvxC1h|mC6pn0ycbI9wuZm!%t-Gi?6U^dpwn5+2&-CrB(2d8lW zkoEN8iQ*jSyGmi~@rEJ}WRlH}SB?NCBSatxYTHi{Jp1>=q!_5x2G~xMlF;cK@Ak}b z67EpL7ezG(rQ%Xj*kLipQO^K@5Hw}{$y@hx%_mT*AQpD!ZV&!;=3eu+Ke&I^d<&(* z?|6~;(+?%A=9;eZat5E{A7E{-hRJ^VS4g@D>~s1eKV0z7*V$rp;{JUyUlbGk8=n4k zHDjMQ_j3YIo~({nmFsx=KA$fUqTc;}<M?R$^@Ceye)udO(a!_yDK-yV0y{%j=6F%g zd!X(_@rE49Il-#$vZM82!N7il&B1jV{&5|Ke_Vg*FPISMFa0yYcPpUM&{O!wbrSw@ zJ%oQ;@3><x7^YsEc9W}f^&SK;ton5+zdo$;ihur;k7xSFhm+Mpe!o~0{Of(@_!Rhk zMQb|D_cVsrsI-N~xFK$WYv-!3s`WL%IzXMUq^0}M2l(|<4!>ZzU%*Pe&$ybWjuoC# zHeF?F;Djfrq{h&JWkOQ|p5b}^iPF)zJ^9n8G_E4YJ|$30NWpmyUiIL8lE1+2x-X|r z&KwWUc|$|+9*smXn;chzTqm$LAhiJq-Lvc*v0#|o;4>sN+z>R{g|338pqso#!C<SK z^!p%87S+2CuZDDgckN}5(syrJ_AtU*D2%!3;W@ltuq__AgV(TCpFn8I-`((<s+FO$ zr4ES0C<pLj+~ra|hJ@g;ML<@bEBNRA>c~kPL&$|ek>~}XZqu;`iH)vhM(@C;B=`v{ z)V#@{%V)YS@ZL-&*%4kJOY)?M?^Ry0;?chWxfcy6w1E7Zh#<0I;?37(aU>=GF)AWg zKRtuYCEySM)_-_Q&~)6=lUXr^w%kx&&Qc{RKH?@JP)u?k<kqE^w3nQ;et{qI-_*$L z1O_zrpI4-CfQf)jH$<)(zxxpsEhyg|QT(ctVBI$PG~}GcI8`#xyMrFbryXgKC3%i7 zfr4{z8%6EYk)m~EGT%tyMMNM5&vDIw@I;>G%Bmv#E1n@&B~2_>>9#-Bs@Yk?`PcF< zr*7YCA0%)#ESwZjDE#EjY;wNt1YmL8su@T{lX7NH7Kr`)3bUPShakl2<<So%T(&>p zFrw-u3=6K!LBqXUc^qWKFrySQ7+pxMy9yB9fLS{Xse;RzEV6DtJgJ@;id7#So)1rd zsR;sVg#HY0c?Wo{ONWljW%-ou>c;tkFR*ZOT!Ko4;RfV-uf&cfs&QZvFxeMUqoyip zLO9HjzBlPL%}QXnJobA=d2y-Yb;J#+&7Y|jK70o?LsF;S*5+_@cWaY296pAFeU2Lf zG7#`F09i@6203R8U@7_<B!e)2w=3#gyEmH+@6KkOZcxSt8gu2Y-%NBdYv~9+8_{<P zj@h2M{|(_k9VAu&H$R00&r1&eLn-MHlB-eC-mD`u2zrUjQ#I{jD1ti)L8nPUM7)yO zr;{9|V<0(-(SAj}s8ui<hDGnStsnrmkvzEfKe-!qZMWk)-t-u?Ur<Jp6cLsvRY&gQ zRr%=Q=GISmWkX6PS2(~ml?y#+fmdmX8pn+EKfpzb8g3ax2Wu6CT|#48EMZSST`e7H zc6(5FAF^V!bx<W$C0}#=DCNwxViSOZtRT>jy7Nt~pc160Bq#77b(r#3sA@{@rU5UH zJ-Mq1Wv0a}x|M(ha%CLNsf08jA;ZfEcBx)8Gq;6`DNevN``l2?1f%({UCDU0$jA}E z-OH5-H2e^^8Xc_xh)^p;a5%&qcA&vQCQe%y<W<rF$-0i?bp`tXK<DCA@mxawO9sCH zjg9s_RMB)3$aDe7FV)iB!GP|9k|+wRkkS))k5txYe;dn!)V(a0pljD$Cw$#ng<*eI z!v1xacNGlrs`1VE5+`mVn~8o{M~ganNKZnYuB^r}V$C4M!;Bm(Ota6(9Fuu~chwaV z6dYB7+J7S6SkF^`nGoT>c7>knbX_D?v`Xj-;i^HJ{(}`7{TOO&OG->Y2mH;EP`@qW z3ia5ttSMv);;9n=Kxdl97x0ti+p@Cagtv*zSQnd1RoRm8FSJfe3~1PGD=lpz^>>}W zMi*TvyyypRanG{Fn7{nCIM$E1um81fk;CFx*^X?od;wccS-bb*JBa+g+YaDTI75C0 zw<OkFF6`CLm&dZ?`b3aRb^Z)L1Qo3Q4}0(0-o%kD3V*hLMY+QXQY=e0BoJ(jhXJy~ z+2fEC$Yk<59v)e0+dar?ZMB5)fdBhj>sGa@x>}NfWM-aoX749hUH7V0tJZz-tAbBs z*gxgavAD2bj8Ra$%Ql+a6WtC<OGLH2`pHYKW{Td0L-{k(jz9Lt`Ka;9Vj6Y=l^UNb z&^)~?{+TCx0W(!kh6fjtW>b5&`*z=uw_q6}ck35xp$>Qm5iw#8S7O?n3Nqy0D8Nb} z_iFD&!muu8pz_`zw86j#g>8YothctG^YPZtFEccDSlSB==K2^;o)&K*ijh}wf=Sr- zAPj8Xq8u2e81CN|!)z@-2j?Y1(EGOop`)?C$VkNhwZ*}s;LCYFnt<ff?)emg#gNbP z7$n=H(QVdgW$kw8B;yq)-Vy{|WqMzkC+?Ym@MJ{T>%=W~O$8<p>5nk?E<o#PaW<by z43B=GIs%Q&8p%SjXW(KXxK_XNlgKD^0H!p8FrRO{x`2X4c-jV(h>C=5Re5f{xWE1N z-8PK!?k8KkYrf`C1g~B^ePLf0T#KD~M%$NhC^<XX!8x*!rQt1RCHeZ=Yx?k1slFE& z|KZV#g`eF*kReYgSVk^FhVV7RRBs|&@Umm2aa%KAnLklp9^aG|Xl9EjzWmY`G3x18 zUaHaZwgv3IM!mYJ=b}C2awzU$rU#ZIS8CZZ5-ndrIl&YqS+3n!H$Qa$)?PYnK`VR4 zxldvV3~J~l9*B_j;qKT6$R3rr)$!iY$AI7{y}Akht}HhE*j*<42NqokVUgPRHt*=` zKCUhaPBc@$Q{JXY+y*<W-Rj^Fd!e@{HE(wITw~4HzGcx|D^TmBd9FQ`@GI;}=IjSH zxc6en+H10P1s~kaeY1n=YgYvnCc}xtZcxj)Z<0QifWvMm=w~fXq^50IA5XW!X!Eq+ z3JC-DO+XV&Gh70md8Q})n$5VBzF2l0hKqBm@@#Ym^l4#x56T>(u#cb<>Andc${r-Z zKo5?FZ9{j+mh!jT?DE9+T1S6>y!HR}xBj`k_2BhyTgUC*S;u6*+5g?zv1bS`ZC(xf z6BnH1B8RlCkZ4|oB`)mCTnsyORd$Wc0|Jfs%)9iJ^C2N=BtmKV&7v6fg-B^4G;5+9 zjP5_}U;1Y7OE)3<@+1cg4Q1Gbc4yaJ2n>%G5X=Pa$hhHr5jXEzQ09^Yg|Z<^K~Ew8 z5f{gKuNFSy{7(CKTx+c%@$B#Ng14_%!<GS;#o$(h|0Lj9NcLcdeSm>DUs88BS^N$~ zN5}rNh)eZ%yi2y9u6^xscUl}VI-myH3F}9>cZ4^Q_MooRjiatDjk2KY?wkAyq-XLj zmH(YzJ+;5v7*fv`!r@oC^hfxB?dB8x{pX3xi*BdIq;ktmhMjO_Gqa&0Zv2#cz2~Q% z;w2s%0GQ}YC6d)3U81oH1usWa5!#g8sX*wgkQ5?!CiBHN_wIc|DImzS(_vKapdR2i z{;Ck1yr401!$cYCSS%X`YJzg?kaJf*d00n5n?6ME+={A|j`8Aq`5WczD5db)0{4)B z<ur5zzFDp`6Mx~KUi~Fi6ALI4Bm<~}X)&kuUv#QYmxacURd0acpFM<Ew2mgUAqo)u zkDy4c%YJ*<gQkx%HY<b8I-;c<n2aPX80Zv(yJg40?7ayyUJUj~aq23XLxrL!Ipt^@ z_zvr3@uz4boH{JE!&Ksl2&sv-grqNnbn)sd>cHBhnwyjpNK~z{8j|ZSzM;L~L&s0^ zTFJGlVTJzWf-zYy_YqTJZhA0+Z#WANxTy{CrF^amwwvo?u>*t%!!BwAYN<@(F9S3d z7iT@pz8Ij&z=o;KAx6;+|GlZEgWcc;f+%A*xSuE|)Sry=M}skWkASh<zfC{jEu+6y zoD8P7+|ZkKpvT)a!Qx=%)Q;v~n|^)v!Q|UFx^r?>YRA(>ut*2G352K#3%@VF4CSn^ z!SL`oy~O+bgy$_0=)6|K%Agn27Ln{F=;_)|7=GhphmR_Sm$T)%4Cea&BU-K}12|pB zuh(Pnb_hfZY)+n#XvsU~#bW*ulh+Hjwf-1!iwtdm(PyL^@D%XoL4MQ2{yT8crvE(e zuoDXspJ2Uexd&Kr>(2J}gO1s`V;Rz&j=8hlM!NUe7}He^%Q-48inD?e&nSbF6ms#U znaZ-@zjiTzNUL}B^zgVRq}dwJR(pD5uu=yL7g)$K2H@9o^%E_Il^+W>)t)Tg4-45j zC_XBVeg0qDpK_C>v7%agsuad9V(-}?#urp#$k}t721F9_BQ0KT?PwGGba>cvvF<Z( z$b}dqvg-mOz8wyS=X-<Eo<3EhiQN;96_{4RNS2(qvu!~JheBD_Rjcj&dDa*#k%k7` znSqSg(Ft?~aC$Tu=td&$)NU2$tsM*dRg>UY9)_<|%t<fhL~PTSKu*QH2tX|reGGdc zO_#6_oUj=83R%V*5c^Dy<a!s~5kK`7H-t_&1&?nyhj6iZfbxQlsr<317+RmkWY9b3 ztZItiou81v+bql7JsFjQH$df~a03HcxlQlFwCqbt%BV}snFn!(4KnP?Nl)a|>n_ZF z81jK#y*TK@{cpYjocdV1u8|Y_kj!$1IWt<o^#l9$&wN_?i1liM<Ql?j0dqxMj`I7q zx8z46C+jw5%FZ5B*acEaV(z?fliiYnI?&x3>)0)-Me~3yW(`@(f~Ez|vLt9NdQ{_8 zkz1TqTa>sQ4!Ti?x>$-zkgDy}Q)1KGm2cZ5x#lq@CF<lrYrSO#WjP&!O-im5#W>7u z?=~eK4d_i`&lpnoPNB~=7Zt#Eh3boUy{n*4RgV-~`Nd>LDK<p3-{LO8>S3C%C}n43 z|0E`4E}5+n_<TCbG~BLBiwHa7UByXI_?Kk=px};wlRtj#2>y2j0?h?Pk|;JrZy-!2 z$%i9s;)ch~DOqr%5O^&dMr2Ete8<0uO#rLE+fGFW{o+HH-Dan)+dc!Mm?-U0qQtG8 z?d{3CJ&NMLYvAwOJ>jBjLpKVAu)3WUBt-Dp>TB&i(Vy7AnwY!RoHeD2bx`8&_e77# z3lq1s6mR2ubG<+<6AY7-qchQoGzU7c0@*-{=sCyh*(c0$u#iNsv<Uv|A1b}`Z~LPb z7rSz}&30h;=K%ll0ZifBt~r8lnDPt(pHhY%!$@FOp_CQUog^?-cfxoF(KvMoXZ^%# zd#W904O-fe>h1aXwtrjHM&*4|F<3DNhbmLO{kpt2NE_GC8D~%qwi*nwFtk2t49S)k zuTGD%U!3Hl@)9rKQ7hQRp1A`VQ|)!LH`Jk(R=8tQ=^J0^*JGW{5kQh3HcHk2$nzBK zGQe~iGdxhFM{uvT)G;IUBuK&2ODVWI!i(8uf|V2yz!LY0qGfT$E?;X$(ofZOPhIye z?mHChfm*rI0bS(^h#ZK78_KOqQ-&c&o4V@`wr_Qjp!oT@3vS21TYglB1U?3Nq?NKy zb0X|DrHD4&1?L{IXZu-|vG^|L7Uz^#3s{7NiWE16$5EVue(4ra?OqPL!JXWkr?{b7 z_LdGM)-b1~+RY|Wb+hbNHi<tj;(hS`uOvkdtMcpWDo08eT@SS{VMW%z#5L!Wuo|ml zlyqx#?KWSbl{W$jzE%`hDH-a3#dMVmF49noJd;Bv`q?<(%l<e62)J_;>gr}!PL#0! zaaV7d$pE!?jP1S>C<gb6LlTNAfq}LbJB}63ad!qnyj$qzX3|-4amJ6;`*PAB6tgP~ zwE@=JgZZ>7!T&6~{#4+1Mj^82gY#lEoaW<J)=lcQ1+BmbU%4IJ9&ndMD?aa495g${ z%S=Gr4P9&5H!N8OX0@`pknO3Jx$ZS7eZ9Wc<cxm{lN6^45lG!(q0u><m;@45$p#6& z56Cclm+aHqaEQn-4eiA3ody2yN<E*EtmTir(={2)|GU)s77E$+dG0j!c9Sc;-Tg*i zX%;2?8{KS2!~QF-wUdSZ8{O*UJdRQynSniaaH~k_=j5$JPQ2__IrivaV3{TMU2@RX zuL27E;PYBP@~&`FR_H(+{dj!kSVCmNP%unUF@_s1MKa2oa6y^}R1~2|%PWf(Y_QfH zc}-k&K*g~->L>`0!vPY5Cz_NT+E2N~5BXa$foF?8Kz~l;$XmXEDKh4h4=J=vRrYzo zoT$m{9BrjdKAnOa*r|sxd)rPR*3cQJ$dfj3r1o3VFp)OS-h(J#!*C({a*bYakhGv> zr{Uy=c48(wEGo<;p4!g9rZ0;K<)2BMT!Is%I+oDBI(Toj!Bpghq;~vspBZ-qddjuM z7R9n45j3+XpKGh=B9hb)1oG$PHtKhwBh67v&tK6qXH=CY>qGw6*!En7T5_YyTU7b# zXQ97*us*`3#%}DDS|5Ft%fX|_2(9v>p!AdIJ6fP`7;h0ei2IY}@NCYIn$%ef)rS-^ zQn0?5m^s-e3Dw!J5H;^l#f?1>>GDnRI!7`8ieqsDcDVy0Q^~XE-(@_<EJS!MU+y>h zAhdIiEH${A*w>)A6=bEpCp_G!lR%m!ZDSqtn5Zunr7H6-FOnW}4j&RtBc5Hn(7HHV zz8p!AeHZ=gS{tC%P`L}`#cZ{pZz@e%oKO^fmS%f(Yp6;UP;q32_?hZ9hsF4ifJ1C2 zY$Yar7;2VO@3UO-reb+&gr1S&SY|I#X^{<2vnS)T%Pza+v(*QohKiB{;cbkYQA%<9 z4!pHnIFvn?J=l=Y{1&FYp4ayu2By}P+%D=G&H^fsuErZ)(<X2QZLt7z<Q06v9OdX% zm}7Lx^*K_7XpY8HvK&*Fu0xRXtWkm9tU_1T53#KjHHoD-Q42T8x@~pfi@_q{MqB5k zWrI`tEHh77YTn?U`kp*;7y0bG9O?uEYp<#3W)A_496uq+`T_9=?gup{{$D{<zzb+` z!ZfeWS7PfIKWH_?yYk6=g{B*_BSLbmBGLGCdJ2sll!*i2w;{TY(*9I2wogC?X(~Ty zmsWxP)E+Lo9%_&OOYJeZ><cwTyd!d@0q^)bZ~VBF=yG*l5wpQkp;(95YjKieCiH-X zQ75N;nic=C^z__BZhnLf2ARQ;em5;I&~IEwBsbh%$R!FL7El=sDPA`%r}@2ojz>9! z4h8krn_T=PoO(p96b(}R>bwOAY}L!z6h$gES)3ynWdkVNg%;hN<0M326?jT0Yo?-V zWs$UIIva^p59;Y~slr6BU}7u;BD&rho*yUrmFEvb|326?D_Iw-1*x>Hpu*4lZ%~GV z(UQQ1sefY1`OFWob9WbZk?c@rLlln1(^t_TH%+!XE@v&MC#I&cjdBp3(l%(bhE?fj z<^8uKYg6i)wKJYKm~84ZbTqwkxr@I2iUDc3cW(mAe<+o94Pu09l{#54U-_zL%&=JN zE25Iv%9ztZh!X>c_>d?VQbUH}u=Fi&q-yV({{h;4zF{46<SqqNP^%6oq!rE8{ayv4 zAe088-C;F90p?Z0j(K>xbAMHstpg{yY5KnI-i`a}4<Tw7ZfXb-{Btmyjw~J#+u*ge zt;Pcm!fa&17%puh_1h4yF-t5aj7HYOXebzT!cuVaNpI7@9Mu}X{^T`o-h7RlpSDIH ztu$O8D7@<{{AL$L_~Gm=Crux~8`pkl!~y6LTHB2{E0n^3i^r)i1_yv8KofZK2j#^D zFpZlz#pdB<-20?uK=3yV;`+NSgUN{0Le9$zeXZ_)(n^})Q{06%cMKRK0{A@5K6#0D zZCg7O=rgf2FnLl4ntFg#V8ysU!ne8GAI&~)Jq`EmW01<nVU=sY1&J$X*G21xABX)x z021oBzx{oVd+Yw^IbRRL_LwQ=TjHECtf#E#!S4*fTL8eDpAmpJn*mtD%Ko7c{1H#a z$GsUVK(O9`7<Rwj{(Vk*^RvV5<^tG-XOaA!h=bZSDSG`n)OZJ60gCDF-otb+dSdLN zE0Ho|;S5j4;s1rcgqTfLsomeNrx^<;tL8G^{RKG%smM~glOLz0B^3H(KM?Wx-=UoV zF!VVDQGx&+{Q=}zw|uhmuCF^LdULsE&JlxsbnHLV8*+<I-O&j9VJNdqOgM1F+8C3v z!i@1xptQM9?VLzEXlHIadx`pmE|{J|4*(c)Gx(=ZCu>6Z*)?IsAoKBJSceZSn7~7m z88o}tpw-#G@Q*G==znnvmD=VJy!^44>}qVw%5hPl7YG<yliUVlz=M#X7X^vahx_xS z`DBNY(&{E>s$BoTAivG-z4jw`{Qk8+60wM=dqtlT4C3OHuXdi~+q%}o((z1$t4p~6 z+m5NTCm3;zxJzL##fy~@0|wx=-)yhNFzHX6685B>mYYS{>6%HgpAx^<G~$u<0Si=? z_>Gaw^{jZChY?>;+V=dEjW(!Dh?oFo+dft&r?VkUW}(Rk15CM}MZ&`%jAs;#B*4OT z7b^(&Od<e^ZHRWoPIMdK<=7vJ4N2H}h=7L0n3#3X{tlzgq>aTWW4AL717HCQCf*=4 z`|45jZl0)%3P7SFYRU1ER9e6G(e`ohN`#=1vXzl_+37F!`{$`j&^^djmav!;S!hQc zwf_61PcBk@2YJ2lqEWQ=j*-Cg9V4M`oy4yZ!xYXVs=j7X-_`;PNWn&^*G*Ou7f}0% zw#bFmYi(WT!}<{Q@CGh_`XV7sdZJ$H6lMKX7ixh>&DSErt9~A~wd(3X{a{HLdjuY- z_&MkSB}(~Ls?U8UUfL-K=+#ux^=_3Em|qKJ&)x{e{(i28hSPV5oo@Ipp!AF^D19gx z$=#M^I`Yd#jT~_?Uf4ktU7l!`bx<U~sYuLek;ac@r7l3d5&9PiuA*DU-eP!{heJe} z&Y_r42VG1}c;4bc7~52>b~;13H2okUV%Y1+Wd>~PjDDIB+Tf<RXSDsC!eQUM2Tpsp zPSBw{5xQTd)_q++YuZHtm0k}Nr*F%`qFxIq=Q-v=_^tq(hj*cOwQ|5ft4#Y4Ux1No zRs0iOp6yK0hpg_C{ocEb`s{}t=X5T9+Psbo{7APa@7M}=)wdmAkay%kM}EOq<Nif4 zP+?1Tjy!6C#u><^X&BT_`1%YYtaP3a-n_svMlpiH`53)7TXHKJt`#9sb}W;;?GP7l z01+ly0$m3#C8XX|;D7zLj!Vg<M8HGy>!Qqt9PW6_xxoI-->;SJcwJE^FVrGzD|N*7 zMgp`iXd-oVxFzk_&)FigPD29ITP>!EAeHZ?*)b`6kjm&sq@H`qZgun1(|j<i=qUIH z|9j-#XO+x14wB%X@P+%sDPgj<f9m;V(@GQH`H>si(kj?PcI?Ko5aBji`Q)-Hg%=j_ z-}BM%J0Sh=d1#5xRIn-?+DmtsCMEV=aMVD9KF+5u_JE>HIsPIuTk+LShWcT@1q?B4 zNBbI3_)mGoI(mpn6GbWJ(3R;}#f_d}h4|o8fPqnd2GgdLa!5p1N!%DZtDo_@zkhZ3 z7sn=rc0Z(!o>uC?MOCw<c`*+O1mD67Y*$4hF0EhxA&5oK5loP`DMy6lxsiPd@cSh@ zVej0hXnwfdCy;O;&^)6rfzh4{u@ctwF{*~R;rWhyw4m*T_Z=}hhvmG=VJju=wQ3GG z1e@wWdTwH|pObcSfS~zXcTDQ*-Q?G=vvwCZq?LI$Pu#gjW=FerM&889fnlqlEx+~H zFStU}j(<gEuygr^H_BEwyXDVnn=&cypofV%LH=qHznu!AecBF7PoOS5!|7R!keXl? zJw`{ZrkIR3A3#|ph=B(XI4g1?D?~tBhN;qsO8nf1IcBtld>)vtT%~l8=qaYPfC>sC z?zmfNh@1~@s@x*?LCkJn6&HDF=j};F!mz!b-OxE^Tkg-|0fxm8RNZ7^*Jbfa%S0pY z$790wC8rud^8$AvXt#^jO<7yQ9RE_-YZCSv#C%)44T|2hkAm5b4Gh1yckjX15F`tA z`*?&(!hxB(ZdZ=!#&WP{0z(FHQa~v<wO~_4l5-Se^ZXfBdpVy>FxTPpXGrp~sn)}t z?gJ8d1mL9}9_>cVM7olk$xajK6+olxg6S5dS2aP{IbZILQX498a87Ns^aLnPN1(Fn zfxVlM#@B^zkRZdJDvch{I(_QJm=g)lp+Lj}EC-xu(W^3?xL_P{H7aO{XQEwA&|yN* zsCzdMZQ8XA2We_5Bf7S4i~RB?K}IYxR>br+2C|guZ50Hh)o#1~Zx)PXl@VT*lU7@^ zdPJRX?VCjix+Mp;W&CF2R^Zi&dy+|5c+*7=cWBPI)y6^?rD;E495oDZ4e3#!1O{oP zMj>WHop?JvChiaoN%(wRUK)gQF}SZM-L?=?fmp)+7~0x!ba4Oec45#H^!z=^XQ1z) zKxdG{sqEIb?yx^Q2P65G`fgwKkdczZcw{^bLfU!v<B?S1sDaq4<=Gng+44<mXUdx$ z&&z)H)1sYqx0R;FKX_iQNNUA1bFIT8;^}y7NJH*vH5#zg;z*=}f0a7$7h@|H-zZFF z+j+bsZJYgqp!({erZ3M6OsjSB57-F!w+mi0B#)t3H>hEP0+3t3f<i}(fnU!=oRh0A z)yEl#+6_A1ht@uHt=MC|w66kq=Kxs+s%ZJ`rPXeuKyC!Ry1Sx6!yHL121WPN9{RDi zb9ISNw6X$(>u~&^PrD#WgHV8*RvJi<@ld#pYnc5wEeCm3L7X*A)>S`oCLlw(1S$uE z#~6=`JtA358#qKZIJqmw)h2UUFZ4(T+fEBR>XBbVA%|MK4(pnhlFy3a6$y!yO6!^= z7m(HL*^fUxd-C|zv!}ZT!z7zOKS2g|r~7U9otI<;A`FW)LFY8ibLE2+ia=V6g&=e@ z5?!}b@(}=(PmqrU(6U%q;w2;G9XA3Hg^)OKE%DdSlS~XuqRO1{7o}|W&lmF<UR;>G z1)<~CBB@JiicSWzAq{0~RNa>HU}}IxFONoaLw6+wW?Ync4Gn*harx(sOnjGWjkByB z*#FYHX>wW(;kW^R?UYtweQm8N#Mpb27A2E>GusYi$dh-Oxn?#c6}}6u*L*A?yqqpM z8F^6Kj>j%sDhiqQqZd^C%HCQtpYWCJyXc!FlH!NZU+r{+>$D7{9@xw!9Eg~@L4Rb| z(kG8_$5$Zq1Ytl=C7?cDs!LFCYR2N(I|@np1S+M?A`*%oM%`)53$KEXaZ-1eSg85D z<+Ac9c@+HLEuF5%zY4AcpZ4v`FA3Ljs18x@WM9;s5nQ9T_B-B|F6wbsg646&m0B~* zGHDl;CHx@5*!(=YOntdTWn&d}LmP4ShY!%H+riZrvqZnF9)#s4`Z};RDQL=Z9^`1N z<|kW7pSWBn&fHGlp`qt{C;7A}72B(zt{AqLIiCk0#y3A@PT*@VN~wc$h2E9_8Y`Mm z*w&)S(sOi}X$L3$MCyE^8Ik80mws*;A1yIJT7#CqLU3!h^8=UKUhKOettaodvnda@ zJ7FC4$@{Dpt+JR?WPe1BJiDj;D=iXKS+Yc&;43N}lVre>N`Y%n)DpjiZNb|oZmPd= zOZXJqH^xZ@f^f8Y@;-iiSZnFrr6GmXZ?8OaY4@Fds^L>B3It?{#^Usfa`whS(Usk+ z_cKVq6uU}7a13&gch<RG@gju^DkX4mtt)oN`&`%Bemlx!8vp^<?_h>=L0a%vjGT0A z_FYrh(Hk{eL*u>Y<5`OZvE&q89q~_@%X83g9+Oc;XJ=c7?fu-xFmx1&bAF3<ouf%n z&h^<a^!`j-cW*_~vbCcKWUqDFcY4}@pZHkpy1v3muYw!M#;l*=0=t+2r{1y=JJ@d* zf+bc#3ii_#;|6ho9dVvG-0^hS19y@Av^({=bZVouH55FXf|+}b-yaXjtS8Qg%9NnE zL^a_3`1}*ga<Pg6dh}->qFzr21Hw}P8<h|`0@K=~&;E!B|J_e`lDxNNOa9z&CeQL^ zH+^F5zz4dk1S4w^D<xA8F>Zqa?0Vo(nqUOABWc2k^s_j78ne)=G)U{&yms!Om5~~U zvuB<b)4ZnKiG$XNfy!zT6x0j6Ac#$!Zw<D?Gq4zlrxg^kfh$Qtvjr9v1_R7c!gDsm z4VcRm+guOB1!133dDNBRySqiGHqut^5nv@5P`E%Y^SXp@5-31h0#5Uu%nQh6N=q!C z*Z`1&Z`GGjO5csClw4t^o{q*;OAS$plswH}ajc;(ac%vsi=;t3$`af<>$ZZ<Ixx8M z<~kMR1CvgQ4JbTNIx7e}z4*uzz$Sq=kmdNRZY^ww(a|3yB?;YG3nxLCh$D_MVQDS& z{eVm#5LCh?UG|UnLC0L861&2%<WF9{q|}QCEFm73zwnF{e1#D}h7qNE6-vHaQ2q#+ zZLIpx+yif~OpCpFuPo{r%ty8(7!xzDIBP{%G<iySGXU@317DuMd||%5x4mO9Dp64n z<<Yo_XKaRq{hyNEy^k8mhDjVR#aSu21}ZrUP6}-Tz(mU4SGDK7pG8%|Bw>M#8#*gE zCOgV*o<_WeY%~}rhz`<TMO5ItI-gG~bQwIQk#UBVeGQRL1c%RZJcJZBzHgUF%YShU zi=~P|!5<gd6NWo`pGSxJ+8G9wXm)$?K*Y{$6aIWsUVzYsP~89SkIhbUUOO6`P}6lf zD$8jL|D2YVWp1@_3R`{(ZPT;B@bxzQ5B|Q7mWA3c1W0&GICHc>GJGz^ly3_I3R1>t zgoT&6c#q*>khQY}lo9VNu0c0906Y#u76c~D-%W@n;zA`MNdyQCno^7yf;fr+NPVO; z3B8cuiIAtPIGIDlp<+B3&4>A}b1<nO?-@{;Pv*1o^fUtc0ewX1Cc`?qm1xlb<ra(0 zr&pFlK|ZKIYP*hu#A+Ox@#sF_qyEVWsMs(7CuXDbTX0p8%IoDEV0BTqYeAPc?j}kx z$J>0gb7$cMFUX*8VSjF7)YtO%9^WVgmA{*zGb2&X3=5E*8wgkO&zfVnpp#L5{Dv`% z^DOiD#k5ZO0VH13$I5e}Uj{>Q1hltX0{s&47(^d^K1R<l<DxlcN-Rts1QO=ZhYJ>> z%95w}u{$ftGZ9q~RBzKLn?BVviUR2gD&b+>0}sk6+&1D3{>sxKTayUPU*#7Qn5w%g z2R^V|d?T2K_N0o$m5ghq22%Txn!<*P0ts_SR3UYjmp6qX9`nCAsf-s))cfezI&2dY z+{&gM2rD(OKd2XUzpUpKI>r9tYueClT&=nHsAe?C^8Q!q8hgDWIl<PBAH)A7!byIV z>c^<C7#4klP&3sL0=L5|W3nu}JkKqb0NvE7i(N_1&wvvsw<+p|?Q{9&@p;}KYF#xZ z#S{()E)jm9<@0?)Yy5}eIPG*7@&Sf>JkyoQMTUCz3Ow%EsqeVK=4K-OEZ1e5LtgGP z!h;}gq<0DNI*Jz5^9_}qb@jrP7S&VQ99zrn4Oe65S;*%JJAoew3H=E!=g!yQ&7r<- zz}Gw5P9d#|t}+yKyTJ}j+_;3sckRbJklmDrwlC|;`si1P8sPh`-Dj>!iEEiU{3$<s z_HNS3{{Gu<!}lQ2l#VP`?ZEGfe_T6%V!NFZPqtglPiQw=gf-ioHkHOu$GKr!sc@S? zJZe6lzVge#baa1}khOB$jF~sl+8vaAIuR|yg2QH11rb;yU_dzCBv_zW%+lj;bBhxs z+~hESC*VRU5<+0<5E7<)Y(Zpv_JdB?OJY;ohrh9QFBx}GWc?Vd?BTg?><Q}b{VV;p zW8V0v6v9B6qc`^9J~qd!>Ar4vE8Du|+x0u<q}Fb$)j!&CX@IxPiT~AhJ+c4yEn;)W z@q~(wJ%nQF`o?S*v|;ew_Q*ZC_nN_oVTi(l%BYbmF@W{B=3%U|8S@U~NZZFQpqhsq z-}hcB?wHP9tPKjNV|aD9cHD5zOc=^GIVEE)P%Hxb&*L}a@^VZ&u@uxDu%et{dO-|g z-w2NPNLvta3b7$)^B4atq%x$_0SH#6ON`4*;_G(1wk*e#$lO-F$BfF!ril_(JIN1Z zBH$m<Q{oDOJOn(pURZkmgcolklHKt4&3^GqiyqR{q3WG&1*RgpnnYb(vXvNqCL3lF z|AwA;_bRorVH_Auw|nZ^F=A@jPaw6@6qftBprg`Hpo}I^E}FoFYbT_NYI(7!<zccV zF5xg^?UP=F|FEFbE7vL0QEE0<i)QmDbpWCCMD_3|36tXcPis&0sv^Ct#}snb35{=Z ziW`kn)N|a(+Q<t6jR}dDt5@aDgZn7b*g@IGzit7y-2(8|hWF1!R!ZHjdUQ#DO<htE z6<$e?EwPZ+*Opw~K+`}^#zUrb_&K8ZLqI`9G?3s<rzzOz{r$IUv)7%0kq@?LdwVy; zok)oE=3^vTf+$3%AfN(q%@A2~z@pg0UTv0ig!)zDLv3RFqGU%{`ys%EZob*v9t0Ch zI7&*HKt1oroGE)pfX!Z*-w%+^Bfks*y`4SJ_1G%(tCS!)p^5I({#EsSOh8IHYwBgo z?5LL<<;nZN^*ao#fQ8@(+X=4$4YsfW+n};(xk{O|9;q5^lMxuvzwARk5Hf0NxqXY~ zhS=F_4C~hs-(%cQ$T?fTi&#$GsR}HOg|eZum5GEgP&Y%l>a*@y*WBIdZQto_Z->!w zppurm&-!3pIMe~M*evVus~3kBT(7RSE-to)kXFj}{L^<&%-y?pADEU%+uQ4FPhPzE z@8{2K-KTc-Lvv`ZuE2ZU)&NjIufKQ=HG)po*K8NBzrAyZt3z$~^_y+@ioI+dZn^I} z+Ym&vR()sZ&RzA{eZLd-PTya?40@2Y*sAMmubw~oZz$e?ny;Q8K70A<@!^lV@QT<E zzubLN+Xh+uI$D4_tZaF^Rtx?>C^cW1yZ64aXR1WjSlBaP!_}*Q#+wUQF44jkL63L7 zw*R@eE&stc0G<Ky;vhOJ5Mhf{TT_%I)_!%KJIO&G0w_T2xf96T4%RFpt~@PABQ!@u zak1S&@c1JY1Hox)T$+)^{LuS9^Jz))ObZEdz1d}Hkej3$rRoW9MBGuu^~$)Oh5S6% zT|JeqkR(SmMc<$5@4$fJ=L>@_MKGzRv8msSi+aUq6^FjBXz;_su*4021x=EjU0t~n z`)*8i(VuL|&*S19YKN*>|6*cV7nSAdAraBGz3e+Zqztg~hOPVyI#F3}0sz#sEU1jb z>K1NxsCw4zb~D>Vo?*x(j|I1H+poabTO9d6^OAHEOLZH=yeg*4RT~JSu{w@eb_=kd ztkd{^s)rk^9#&Q}+4sTg!%}(%Qnc6A3>#k4DNj<CB}MuFPfq<u%BlbFlPSBWl0=pr z(n9Me08?}1;NjE943-S?4f18DTeC~jJ3u1V4Cwy1UU(9+Otd(+7N$vUOWB`?x>pg~ zX4}xI{W}zN>6J@iV%3<g2OlfYD8kzW78uj~f9Cdep(Ez?rUj&;Nn9i+l~f;#grP^+ z(QzOX<!@TpTh3=>OqFFR4T&>QQuyT)<WMO=)F(=!(xRxC6Xs=ZHp%S5qYm1xD50u} zsA^++QB@~mKsx4*W8nj?ye7Y@cdDdW%8X>Wa4R)VxqR|v)^Q=IwV_DOjK;HOotPhs zm*4h=Et+*s^|TG)GL)5$Hb?20y9-x$v3zwGStrFjE<2yYW#@C4B{pFd*<EV1tJG*( zP;`Ys5fVJIj~?zeHxNsJkOR!~w=;5H1h@G_y@j*;Q)+g@n)Oms^Nr=rg+FuAm=vqH zsB14+OG(ze&`b?%OI(k!Y^_1K=A>)k6e9WB4G~fz9xrvEZP!I-HyU}{DJ?J)C0;#f zcMu4>PIfAv21P_lOzrf;@qZch^Pj1pfdgCufuF9iF%J70hrdjWE8JYN?VUS!zy9Xl z{cj&+3l%yhM!njG34}?H2ZMYv15<FYBRyML#BP*~T_)wxz-N@Oue|%=#m9zwVM4yX zOTx_LBM*kDtQEE0b@}XS!H_WLZY{7=lp{AxV0y3~Cnx1<yAfAJpKDg4`MaW$T;F6) zfcC}xQBkG*Y~rZA^(BNU_>w{8_tQb;6HeGFZ|nYIGkRx6RGF~z1wos1V0mg!Q;!q) zKJ}kfKtmR!t2Uh|$MFJNe6lT;DEe9^?}O+2<q_ec^8lj&-H%M#5(yvg9pBxKw0w@n z17O&8smCzv-!k{kkM{2Tc<0W#6I_dybP($gBq&kJ^{v)M=*m<ho=>ffrs23*qu+Fx zC06C44{~9GvoyvaDknJ@9DB^5ATH_pBKZJtd~ns776Z;R?LG12{<E8ba_X+%BtIU6 z%kY}Bz%%bLP5Z*0!-<{!Bp(!~g~dUAOw*pf1IowQ@%AmhJ?dlZ(sC@GalvG2xPv`- z{9Kfy9J--f79qDQ)pQ9JXu>4zzl=A*ncWX#PXO*FFwtUtlH<~`3Yqmb&%kHKkZwLh zY77^Lf3>t1{`C`#;2u;^@SKfHN)aF_4b`sscwNeDiH+rYe;@SPk};_^lX{9%3>NB6 zftS*#%NGN|G!_w?zyxOEqDdcOr$Kz9Uh8P{x2@xYqwTE+$D8fns;^qZ4^KZ_e)#3X z#fQTWS08?DAN0;-JV(ZI2i^Q#K4>|3SXV-;m@*YAjK3e<!N5ac22&GA7@?J(W}X9t z)okv2Q$Xow=NLVzO@e>A^gaEua!;07yPxds!uNKldZRN~Ff%=@3j8(%ci#kHB(>e` zW&AZy>{m50QTqQ2=5@UqxYVVT31vDd(iLj4m6+ye(LMB@3PZ_ApMj06CQx>r-Mz2l z4ed3yV!<J8W4#dxiJ?)esD9}Gz}4f?0u)Sj@TxcXZnfEgO07-)v@8?<sr@8yE~4<q zm#8)cZskl6<TqV6=@W7(l=ErTVu(=R?Gp(KwM5Cwd{B;u={6%EhIR3E`~)}IQOIng zRL_h!W@Qfr0@B)4*qjvDxCD7?$K`kn#rBx*E2s?~Oj{7SnpD`2%+4KP^(}8)498fH ze3YR|2h!L89Wn-`IK)_!c;KWFmKJc7=%{C^()?q7F#)CJ&f~+5DM5sASz!JkcqbB0 zh%Gvjz>^aM5TQCw)f$wR?sA?$61^|ArAe>C2GyH#Om=TSfrS7n{c6*ec{)!%Z<;%f z&}*<TiPEqS3s}eKD&&<K$eeLW5i(Rtwh_IJ8_pX7LKrvG+OA3yRUP4$W@^zilZrgq zfFN8oUWHtuk6<EFRJ`i$hP*|ByjPt?9ESy`mfv`n04<y$1mu*RuT{a27AP1B4|!pH zl<Q^u#7bcr2!@!&TM+W$x`{tYgYsG4%!^<MP4L1MG`~^XZi<N65Tn}51TvJF<IA_J z0}d{-QHw*4P@3~4F-IUKQ#;7_=N6#Z9Skvw+ft6-y?ZA)(W<Ti^CEDuodQQU81=y- zgc73kN24o?H4)j_mRIJooRS|kSFq>~qL@tk;|fj&q{5@(O>Um_|IzOX@(VLDEZBC* zGMbD4s&bH$#~?^_DTEyD|4?G7w@mLh`#(z+o9wsWDAIR5G&_XY=x^~Z9A|BG2JwPw zhDey0WRKgIh?3L%t(Ix4Xon5SNg-UymS2HRp-ME<8bqwUd7qmL`-GSqEA*Mp-_Cu^ z!ti5_o%r<E9FfNLkO*_s*o&)6t3x2LFz{H6hgumP8q%G>+Bep?!XQxe6bK1i_c#e= zh}*dG99_sP7eFY;i@Rj3FxJ+`4E5`xp;&={@i8a@28OI`+AI{Y!EQ02A2n6v@~lk? z|LgW%Lk=29$l~1YC9oY}j4;4pAdJ<?TpDr2MgQGX`#N?oB*!azXXvjECLgBXWBe}< zN}m8Yok$Y`K1|C|)!{6NKlaD@sADi61BQ44K^8=P@G5Tqm!&fz+n$8hH3%d^{k;H6 zlP~JJ0|Wgv5WN~qOJjzR)o=>`Ih&UANe7agbc`od+=`}S4iwoj6o(Y3;~8imaO(IU zVGlcKIs^P7?h@qr>45nO{(&*mEDOWa82$u<&mdeY_Tlp?mTu}DqeG05tS-Np#KABK zX(KvWY_J{rPfJ&^+FpNm`fvSF2s|_cCPD(3fK?)yi(~lZpFMyy1*KM1xFMj^=chlE zKU%o_0a9WoTE=y_>DcZAB~N}_Jzc0QNY|8ZZj{O>4szMF(l8JvHND}BT^)i3$;q)- z&B((kmxS6`X7L}AY(Tspcrbim|JO0_|LxdS|04-6!Ux4T*0T^xqL`1&R^pwwpn@gU z`|m^(6f+q9!<LE9#<kGwg8cT@SFVSLM!Zn`w@th2clLBgTU$EMB+p;GMhGdd=!d~= zQ}R+(Bsz_)2u!{T;Dc>xR68Z;*Ar{W0a<EYzCJYa@xcAHE2Y$d_?)b;EZHcFCuJKu z7Ic9jmoCMBM#^bVo6jRW_#N^73XddG>DCxh_jiiD48TI3)YM&;GNL+E&DKT((mHTY zwD4|<b#t%xs*F)$cLDSj^}EA2aZ$*ywp*uh>0bu@F%3o#N9*0%>6pZjtS`tO_9^t% z{_QXZIQDEm(Sy8Yxu@Gk6HfcLp$30Ls%!r?MgzZ{aRM;=M$Ja~KK%Ckw`sE5j~-T& z{#XrLSUSe=zgvT1YM;0*ORe?60|1kywTw%Vk)!q1C7NH^uHw!g_Mq=a4}1MbES_%F z9x-OZZ?JUug(TmWWMsPSR;S1R<JRV6xI`)@-&HOnI9D|nz`3hchjT}jehQp#ek7ca zdFBh?eDmYr9D7~}=TKu+ICuN^$#9PPq%7C4pgaE@a9&^fVmSYoERF#{@jxk9SH%SG z!X}yhj|dBHr>H43dlyR43x)GoaFcXJFEdm3Db3ZH<#$1tJ}=RuaHg=a4~Y*npi0`m zO+Rj@Pao3<r~_yF2m8S?P35$hUBMq0{pr=>>j7Ywx*m`Ce$>wj2Bwpu!=`CIVzXLY z<4M4+v?A^V(@s7d7H`ulqsA73aCw)-&<?)E>0=4lS^|k~FWI6OFOme5em?%mNrL?m zwQsu5EHYTQ)1<{(y4MJYi*OOHPJ>=zgZ26mLC7ZXaoBz3s${px!UUtVyR|cwN|wlH zb+2m1%1imuW)E)n8;21|MH9;gWpuTb169KCjLO2AmLFME`LN&wOM#bDt-3FbYm4L6 zf+kpn+J&)M6Rm;@)FzU<G;NZq!tG+&OtNKMiFa>Bn>(n>i95-wZdhLKiNP;8i=(kG z{PECe{s+G~8()+Pxi0Fdo1JgXpd3+;@W;b|g~D&%okk0nR%GasoKLJ$6GH?gtAdG# zSC?&KMTF&7M%p4JK2S!%To;ULo6#HYRHi~81yTl|j#$~j*lp34yI{Vty=#K;Ok$8N zO6=;)E*7jfz^d64b{KI8<XXyNiy4}Mp7z$xD$@bO(T|u7&H*zN<FsnC5!>SxW^hpq zEhf$Y(1NkEsL$)bHYMoSzCfWN*h+^E@=sgIzi0l#c|Mxpdv4+Ow0K9!rTy%L!s1AA zJqw#3U`IHxh^mUD5MEeJQ*_|Ba7-)#Fe7dKR7!uiu{Y@uS*%^`H|j9VhVJwQ-{W#c z_3iJbzpyO!a1s<YBZJ`~4)li)h%g?3lhgu<H@tz61{#DaWNk$oT~TlRJU&GEaKn4g z$+Iklj8bdA_u0eQR1SZ}ZX7N5?g3R{hfDSe0hKLmkBEAyA#f<B4HA-ScJ9fkHNl)i z!No(w#rN?KM3=Z^@E=zprnOxkHr@0uw)tPSwVW3$1c4Vcse=*-BA6=P!Kk7A^By)f zkM_+su;c~nwYzxRlPsCvN4t^8dnmq3p7JC6$FXNB)C=!Q9CHDC)N~VhRk)Q?tP3ak z5VZ%=O6eh*V#uWU(NIqItAyXFTSq|TaxeT!T03}GoVwMAGqQ`z0u4%F87In=fNA=U z&yL0I$u*fReZ=<_e6UtV<}=8PQLE*~*$k$F5wp=d#f4;#!k<quv_z?lqew--Lj=#N zB*79Q;*n^G;(}dQ;Qqo{JU=xT(A#7rAq+ZZ&IwS?EyByE@yuFPo|`Z3Z-0Ha?b8x^ zB8Dfr$BOr26$QW&nJk3Q;LU6YSN$h<*MAbi3&+Oa?#>VFn>7oQ`oTg{<cLRIYj_Kg z`_#ybL=Cgy3K)#9ah)^Nk@&NA%k7b1HH%C|RlEX5ORNsS&Bq;k={-VPAyt0hEKT+2 z8)ZFllRt(R?g$*9Fad$HV)bfA7~fUb8UqZy6k(3FHLasW%W&Tjm^RhOd9?T5Q0s+> zQr<oa9_#f99x9zi0b7fvBdqgC-dZ;`0u2Hf2MPYf*H(BC(l3F32<*Ya?ITM|NnGLj zS9?+K3=7%fBHf=4qJnk#-uu}Hr^F7ofSNU{p^8>O;ZFSY`b~cIj2wjQhC`Z@3NnsQ z^9o|S*+Mr9#h69YNKFss(AXe7@3x13I}eP#?^(g3a#j#H9P?M;pcYlrolAe2@f3{R z>=$o^Oidn#%HiafAAmm`vhT5$APn$EU8tGKVBu&%#|l%d)oxhCjSKcOOmnz<wsRb> zh|?XR3zO@<396J3Qk8^D<~lds#HJxp!W0b_ULvf)*N5b{Sv(?HMzk!AGb~O|bC_S- z-=Ph)n-<ce&1`eV7Pp6Yj&Twpv8PI%rCjeeTFHI+#oY&cnaoV>$RHn$sGCMmqEifI zZqAM?C3iF4hD#J(2{aB<G0v7NQBirY;j|sW3-j)y@z70x@yjpX^|$w6F+kT->R>cs zN+Pv*6Jo)BAhi^&l$yMA)e_RWu5<{x(9gjQ!I1iKfR=@<<44^j*DGxE+dR9$9jd=I zb$M>k-;g|d=S6i+7@+y7u>f;E%}@7lf3al8QAOg(qdk4(0XlOy*mosPcj?Y|+^fDK zt?J3Oy+-i|69~*$1^kzLDJ7slXiM<O?Cd0s3AQ6!f-oLINX7PugR}p_u81xmU>ckR zToEmS*#>8oLOCS*18FhV64ivIuD4K7bo-GOw6`^{PLfbNU75O1^p0XyTY^=@h($gs zor$xLa72X;b--4Z(5}hokwhQxrlV&U$v`6G#z;0(_oi4`O5<+J64A_i7p`q=IeM{c zI_$suRl9J(j4M*4F~cO@6ZDh(z3k39PYm+Isd4g-E%C){#6(}%@T8$W<!*ImY1sTR zWOZ+9R<9*icr09R1}l8kETZuCoZowaJZ0*l6LneN*!aoooq$D93)Mk%zh?ley$osw zSdmbbKei(W0$TEt#aR{IX~xD)^k?)y?(chBAIVV6AVA40-f82gRocgkr1Y2zmYJjw z4pouR2)Lgj@I{W*TsW-7e?A2BG{f<Nb$Am{?#jm4)1lgyO;X#!1P0PfSe^I5Re!i| z>V{}Oibu3^3eZTN;zXse!zmGY>%uQOcE+P&cmU;*lpV>H{7xiy5rp8yKDtmKLURaS zhU>&3^=ODkSr7txqke~Yt%4*~H!<|LG#UT|@2+t>B&rxwU-QjE3>jZ6Lz;QSML4$h z3i4l_R;cMRswKEJEV_r#HOoFlx)|NOFh~nf3ohN^6jP>h%vlt)F(t7sKE6r)Ar$;X zIas^4dNFHdyYiR`7G4ri9F#B$Noz0ux0F#r<pN<(b<RA&F7N|%E$@ESL;qO6cBiwB z^UdtEF|~{HVGg^~y}32Sy@eel%G!}*18c&s7^YmuySOHi#qO<Ze|)_!*s_w;)N5<} zh&gF*{~dcXr&{fh6THhma1~+PgSe9<{%wbo^)qmo_rQyu<&jOJV(5x%h*Uhh9ZS(M zLVFS$|LRMU$e6J4o{=E)JP-Qd@o;iRbu@X!_e^6+7g*l`<Bf3SmAkqLjF_C3LWu#o z2<s*{+Gh*)$pNH!^18pApMt8<c|R`2yPtq-<-z!#XRm2qA=W9gCt5Ul@OVvRYa_)= zYzqWI2|Rf$irB)8!W@%6a{H{&xe@|ol3VUiWj4P`*sQ~=L-ok7@>d@b09~4cgl&=i zbJX-O)pWQ_^|LJ10rHZ;I8W2#tmwGBY8nGhVbJKq{O=L-=(KhO7MR2HT+N}_g(VzU z^Jy-j^C5LE<@JRW-Sz-`7H^sph#@Ml818k_gI#%;{jQ!IDt?3_+J}MiAaF+*ifBMy zLq)4gXHKO6E%~n?yoBuB54g3G=3T=5_W-1LtMukKI^mULs*s{<q|7n89^Xk3pSJwG zfr1Fp@KHT7Knje}F$BIJ$MEwsNLB6CksNXzvbtN$?0v;U&#A^;NqSv5yYirqEI3is zkRzoWm?Jy+onsXhMOO-<oIp)iNL$4}f@oLaqD2{Dp{2N(lW5&+*#{kO*0@AhImj_F zv50;=tI#(bB4oHt@jza?PZwB}2<^2>@Gfc$kGKop1xK$|g6XrvlS2&@U;uMgyoF#P zuzv0A@6fiItVZB^u6OUaJWe;j#CPvd&|!ybYtwbfzQgqBsMUiX{dn4u5y1*mPfu;9 zt+Tz?0HT6;j+Yp}Z9W=8u-Ed^P6k~edSG*uF-I#BQbHd*&(N))@twB-M>o~}p=2eE z_omTX@dgQhWK4D*bOZsv%Ma1I%01GHyv)$+!nw}*_9`r)lMAP9T9${fZl`1M#1_@V z2&F%#B!mR_K_UnYR+<lqK|P?;a=k5i1d&_?uGBeFyPf=f-^U9l)N)}gFPxmpeOiU9 zb`k=t%xTWtx(uaus%pG<Ew0J}_S;X^v9WG|APcHmL!#!6u8DFG-AkRh_L3+be{)}- zQo!<rz3nXQjpx|d8*(`EXtg#35LEIjRuP5rHc^j%`6W6EYzRcu+l7L+T01Y+O9Zi` zF(p=w8)-oc8Vy_M3-#l)d|M3pnM6mD`4oLsd{P@=gUKlce)r%=gLs$P3#B>QNiFes zO1Q17IIH&65|%GXR!$<AkIqw0q8dfUypJmEnpC>=Acw$ivwH!X{`<fSyNmo5QaN3A zSMV&*>XO~X&I{N2Nhg1$2=4+^@Ds_PkV?Gc(Ct;AdkKPnU1_;z5Q8da^7i6t&3xTn zDz;FHlapsi$I%?3f0qxocg0DuF}o8+wzHpBj&hV>VOMYb3E`3S!>XLh7Dr;{m|=@t z%m6gjF++3jt945|{255Ta|lsqP>x0z!^>EV-R%qb-i6vvL6-8iu<We;e1^i55@8Es zwm?X{ay+t><6r<0^h!ty#xMM+IK{YjLP^@I3N-z&c#Hl1*Qh+{kF;n9X8Ra5_85EF zoLrgL^9fY&;eUw!BcehgL}8LICS!}Kxr8Ww{lOdfOq2%3#pPfw>j3*MvW*%Ymh(Mq zN(-YfA&kFuT7VM0JxCqfG2OazaqT0;dFiGN$<54CvLOAFSa%rsNp`p;W8x*BS9v*~ zWu028W(l4%%`fb{(ORgLd5a2Ii=s0SLQvugD5Hz%sb8F8gJ>yPJ4$KYG*Hwo81njN z<BrL9@W$gpyV|(dV4381)6}*Ts&@jZB7)MP6hcTYOHQP~B&tbgfrv4TjZ{=m*)mPV zu1Z5Y`+6QUloD*v?P;}1-q6$!2_#q<DBDL(?bbB_W7g)7WBqIeV3J<@!{LHjp9XQs zF&04E_4=p6+OiR2IJ-ui3K-S=<NwU_=@sPSwYzD?mOCvl=yQb(LAB9@aHzpgxZkZ= ze|m-j=V>{in8&xeR3R$bTPHOKvZjzw%VJyKh{T!jlM@rL$VMcX*p(C+Rne`<y+T-Z zkJtEo{I-1KgBCI_mR0pF@qT47t8u|eNxxC4M1Xw|*Id}k(=n1WaCF5fK`j?(alPI8 zf(i`wl4BB=a!TaC%hVW<xfHq&Mt}#nX=*q#iG|9?#VJkg+1%=$j@8u-qK(rs+V6?5 z`fEM~`6Ps2znILfz+8wm#P-pt#<yp7;%M2sWxgxkSpfLr-h=!1kk}&qF~TS3YN-jJ z@R=s2*(Zfa#v-eu8%ZPa&wMC%e^?IY@QSy)i1UW!<v0q1j)7vIy@SBY{m~P!eWVNC z(6P_>!P9&^nE=GAt-I)3Xav_|`>*|JA7C^MgM=LAjIv+&72IlNUu2u%l%NBP?Vb<Y zvQ6k_CTq%|JBy_HIC8igdbN3WC<X=-yvI{?1$aE2TC&%|`>X^av0K^I=3R&%*|Kns z`-HJ8_GoHMND34O(VoF9BPj5g9#scH8B5&i1?2H3$yXA=>yNV6pfZ$3EO4Z<?6?b; zf&|mLQO96xJo^M3ckM9@`m>hX1*QW@M5L!eKX74gFZAx;ffC*kR{=E7dRzYZb!cii zw@9EBkw=Tp5KZB4ILqc~rshZtLlhhnk(D9`C|05%8CVw39hOeN72+ddE?fjm(2P<t zT?kkJ6hPk+-s=l)E*lC4HRf}SQ5y2tlCUhOX`j6cu$<k(o$k&~_iNBcCl1?wy@vDY zeYF83KBL;7pPOG0+zmB`qVw5ovfJzZ<A0#Wys$fXVLwC3lX7x}zNgasJJ6Mphy#ol z$+8yX8$j&Ga#}&FpDc;j2h=-9!%#q*htFRbxaQ+3@79LwmeaEym-4_|-k%g*J*^&1 zqf0lohy2632R6I2Kw4fIM+nMYp`<|scv3xM*9}|H?OzNH+do3`ro*RQyNWZ5B7w`n zBp>~8IlcnyZJE*Gd<4n1*QjyJ9GQ$}nVI8`p9BDr*aA_<e+KU_+vOSZTVRaLm0PmG z%pj^Y-J*#B7NupsW?0$otgrDGM4?Tn6=4{>mqE<d2NvCT4xyZBw<I*ED+0!|GF}Kp z>}dzTTdvtfATR}4+qIy;{)z35ien(^I3HHAxhb+k$`T@`Q7?d9wXkz`2A*+9eNhN^ zmoo}gY<-B)%mEqKm`&cd!2TNSPg*>qj0!k}FUvEzvOQ?}i%DuP$-G6)O}op};LyV@ zlTlUIAEgWdt963SllfW2z=@y<c>pa;etYNcH)I9IDM$>CCNbAw!`<G(Sz9F2wuh_^ zsEr3kC#wk{&hC0*uND%ZbjHRp$ES9$f50k|+Uki#WtL1Jc59%2Kqo&+7aaml+vU3= zAG*()y`PYzbEw9(2V-{#h>ZEzUI|QyLmi<^qCYc*%Rmn_58fklQM|J)0C1e|C#|$H ztuMa)_Wr##MqP_$vTrvKW{GL9Cw+u<_?t!YChOW`Ix^el7&I?q%59sdumcs=WTUta zb!eX%3~K;ipc5hzqitTBs42l7V!ROuwgBKrh*fAZ=O5{W7O?8cXnt0ViKCcIE#la< zIOE8jU6_8x90%u5fT|z&4Wc~V9dIjS(6ZwksWn1((FaQly$5+^0%U5H=?8A%V1;VI z-1%Ych&+qe0q!@bM5K4qK9WSi7qjznJ_E(#Wd^=^m*sTmEI-*X3wM_vvnT_CeMQv_ zQ=@AG(?v6IFE{WtaDY{D0YF=f?aNotQ&0BaVCn?!%fXz14bCa>Ib~b#k1jz0jl2n{ z$}N2&>#7lafvJmLZu5fBxY5pr8DNaQ4l{7c?)1Syev1AS_%9H%fJqDoY6o64pUw(! zp>wQnh(MAk2A>KdPj)?~5Q>G-%)rtV6k49RKEw?$6}l~qZTOY}3j^2dGPj3{^{A6+ z&M!Ku$O#6(u^AZD*Vug5_?cVep%Ere1QM3MaoC427M-eOD@A)D>|5p$e5=B_SPXZH z^n!1My|EWkF@w2T26;48n^x_bqhlgA*Vh89%+%lsVgfo<zYCVTV-bLm$>;s*+z!o0 zcjfXJK;jg%fXFXBaf)uIE}_X~etR@Bh{LbyeR6w+_+h7Pn<@3ftHk?Z*BPy%>u7!> zZ(49H>B_L)Tf|BDftAn|m&w`6jTg2Uiw=wGJ6B7}`69*7$`N*hh{`8%*SQ!MHi>y0 ze1l(C^GPVSXh%uWV8Nb3lm6JSi6gc<Okl$B_|*Gjs2U(wKqKZO2l8X+tPr*7<Ko=v z2qob!4g>Q#oSUkEpE`PKf2Ga#Ask%4^v7OYBE70#++1}ir?_A%QzI@LvS~~ctVQ<E z(sIH(>Nm2h>4w@p2#GOy7hk=2`eIjzVmpZm#6W`=h+3o9*^g6;dEUt@hA)dm(7-o% z6GeR^;MRnWg9a9Tch9=$Hg<Lf(vn@w0z&-^OB9}AMKvB{NDyD!;-@bTw_w`vDA(q* zn|d8UCm3G#T04yBjfr4)@n6uQ)~Hh2AGNo;!Na79#9dF7blg0FJfZ^s?K>u$b{zpF z7#Xq#o<>;T610HqJle;!QVKVt{tKdg>Yc;Bz%(wxmp~;0EA3u1Xh>SR3r9&~J{A2q zVQ+%gMIulJGwqsR07n~$ZvbS?2wANw7#B%*bm|7<Z0u`f`J<6&3q7<B&Mkr8WokHe zsw@p;T%D-Vtv`7hkr$RRfpVjeD1OlIAb#+7Xiqq?fC`{)_>|@quG4<5;2y+}SHD`9 z*b9Xv$8m3f4xuz*5fzZw<Q(rTNtG^{BnxNV4LFM~1`P`<cyNq(Gg>WCF~%p)paml~ zAdN1W0(#00*ROg~N!QD;M6qdHR&UFk+gX2l(m%^Zyp9(hlzFp!#lzM@5aN{*mAaF8 zbskWdMx@6MTb@keU*UqIs!o2PzKi%Sz_!7=NqQB}L6b%CzR^+@5=<K{nI;MnD?bOV z7RzGj%U@VnOPw((52cnP=%6Tt9t@J5>>1U~L!)}oB~E-ojou(Kpz<T#!Lh$Z^dKgx z9AWcgr;1M1=~}|?#pU=%rX^`abb_Rg!$jO|@9Oqsgw7sF*jHW(160|MBa2B$aa1GB zoHC5&hHqrlBCOy8s3eKXpt2_u#gWWT^eH}a3=$-XMq*)#sZR3Qpi8`yUP{AY-20x} z1K@8gHl0%DcY^(sD|>e_QpbQ3&<2^@<K=sDG>F)r&<JV>ryG(G88N3-lN8yiRHQ_P z;fp9wGScIx<3+5!5)~HJVQ$&y;S+ev_RRw6KhlML(hIG0>mrJebag`h2jgn)Ii-_e z7Y=NI-F3W28Zb!+g(O@dQZf*(2xy1eCvKX>#Q0y`eWVJD(=jOrSDZ+@mRC8SPC=}Z zaV|^PEM5ti{TPvBVRRmhnE_9}6J?-;W6!8~e~{7j0xf`1Cg6HAw<Ar=Z6yx%GYz>e znfDR5gX`*5Ze2@KOds1Dy=^%6-Ro?@3dg0TeFx`_^FazVSg&Kg-C5`ftMgXpapd}R z43ZRuOcJhF_aP||@u0vbJ}RrD$p|ELgRngdmmR88?eM*PIqMJJ1hWC1QLC*mohn<B z0jwPa4Pff%F$%_<pccddIa+v~<f2_il^2ROoDeIPU#&HY0A#PxSlj4BU?m>P$BY;g zt#F-hc6sYJOun!r!ryO{lS<>Tb@w&wfbU~1ENF$%T0+F1o+PCmE&1tlvOXm4+W|aZ zdqHNBExnc};+MKQq4!l?jQCX#l@)ugMS@tfog5vjP6Oul{d&M>iEiDgssc7KgYO)* z=o!smm%?yhs12UoE^d~@7TYD*?Xc_?kQEph!V^srL~;N_3*5CpYP!2z94)^r^t4=& zJ$i(?aH8_r=^X?%Q(d%OG3)M>CXd4DP+QoXAC!)R7zZr#yDDFxF}{8Hi!DI$mbLtN zXePyh4E6WZaxky-cX>l)%7DBW;NGt*Naga5p4E2_ZmETjF#a0JYz)n)cc;VfPyCEN z7~BGNADt4f%fvc78R4Nh$;}XaH_NN|!ufl`)z}y(IHGPfyMpjsLdD4t>@SL@KirPA zkld`i9Ou)g(&KL29J%o^#AF1k-c$!}HWr=&a9QIG9#as`TP+jJ9^5?`BL7-gY~i3( zm6NgIFVuy{6j*PuT-J>*7bVCv@dR(x3o7D-TuOAi9_lO<)V*dUE08W&mUS5UM|~rj z0BvZituBwpr+B&JnSjWDT$Yod%=M&81ylGh(6j#ySP5ZiH<pBoccOwc63hd?Y!Ts! zy;E13PoIzBW+I+Kzr#D-ZKri&Xm?ka-RjPOF`t(6vvcDvQ9Hsfu;pFqn*k$29vBdi z)!k3s8xxcFZGP!lzPM|c=6JZ%z1O|FlEVAJ*E@G>W8Ja@{6#)OHD-EXb*wBwY2Ro~ zkZ;t2QGZ(WecZ{Q2HB2!!EQ7IQ20tiM+;~5Se6XYoEdU#<`c0h=#MG)F-DpUknrMF z)RA*AV-p+kngrTzYJnA~1>O+{#~!pV<JYk6e#<~6ek^piHJS!tMxcH{BR_{ySk?g{ zTV|CwRnje`?2i7uNt(HB3u<@rXr5i)v(e&G03lMrXcEcOb<IPhBm)}twS(A3!lnWb z9vG<ksgS+7CC;iDg^aC4lAfKGW%s0S&uagXd2gAL(o!wv1Ty!&e*M~9o9p#}5PnbE z7Th1&ufS3P3vnU_t8}aL;#4R}oGg8g2yM5?z}VARTBNdMKb&wy1#l7Lp29o~huktd zfnARp{D^8E*+$1Wa#M-e9>h~`sIS>Ly*HC`($Z9Y5~6l$Jf<3jw<uuOBprLLUJ(4S z)`t?^1eE?wW|lgXhRG$W>iN}xK+P_o23}YBOx|-7KIM^BG$0jUd3T{4$c{=Wj<nb^ ztQHT?s3irG*UM(J5J4q3RrW(rfV=w&`>Sc{hia`mE6>hGf`OO4FqY8S*l?mk#wX8D zwfzEWmh8g{LPKfRA?4DzBw1on5xOHcDu)d8IzQ%V`H06w0Z{Eo*4OeeY84kfF&g6D zn~1wJk}h1>zK`k(_zvR}kG~Ef1V|nT{w)UMPrw4d<M|us(dOY<yqK5;?5v04LMM#0 zM~iZ+!~o`W)IWnf-}BQ``;<705IsWaw&<mMQkFo6ILLJKbbJvWkLN>^ePNySC@PZa zwO@_&Co@)Suw>AjZDSO9N}|DN7njdAqCZI6q&8iu$X$$sUHYEt4P%bH#yN*XTz@!h zB`n57*(pou#O$ks9a*&VIO6X=PRn;!Eu}Xh3pA%LE;)>O@lSR-5i%9q+qp@*Enmb| z%AmnO$rR*Qv4F(Tl4yXgS<s9{tL&3(3lY=UJ$PFT=i~sSl{p(}s3Avs@TE7A5Y6(W zGA4$ehFj^gBQRfU+Msl*VH}Nz+wnuGUpk33AQwnZAapfQ0$-^B9(?Y&sQ07@I55a@ zw!qGq?F{5PRmo;o%=N)WUY1i7P6gLn2HZ%{nQIzIx@ROW;&1$urWt&*v{b#F{df!i z;*iZWZB%=pZSp>gRw&Se>HWQR^xNg`*6~;E->R=#-LKlWdaQL>b36=)tf4x^-gieG z@;Dup9}X=<smUFsc65a<)pdAXlP;rfluoc(ITcNCiF}3luq6#e$IkBrL?j5!Zt+(8 zJz!~}+LM<5K|vrLJ#YW7-Tg;djMLoUCe={6Ji`imUM%UjN;Q!#5QVZ)>btx{Pata< z8A8n154-=iw6JkupLomY+u}E1dcCu~{ms30QkWQFMN5k)tSBmn2En3<2#Y0+LusXn zD4E8_bZmAX`dVNkCk@d$Ar=v<&==w2&xl2qB9ZI$n#zJnD49k@9zf-M)(U1T3$lQ= zt=8{0DgnHj2-ce%?Qs3Y^HSVUbc=qBInbib(%V}ix|M{fY;NHldz<Ld>y8`40_Y+M zapM@PkiF5pcVN0?12u?8@V)v5Vw+<8nRYLv%sXxX3p<~0@9N~g-#ZrU>cPlbk13)d zdbT)9n(TMM`ii7Oti_QHb$l9XmC&hUZAi{b_>Yqu<Q#kdRu|>GZiTL_%X%rA4iO-p zeALE=DEh}ryAi{uYi&|L?a)z!#lUDz#TI2elM4ufR$7dVwpd_e?<r)m!BU2Uma57r zRtzgUl<hWl=U2tbkbqov4ls@~i6-Oi`pM*<C1|>PbO;l=K$_zQNF)K}GbWrpnid0V zuS%F$^o0U@j)=n#%Agur%g>taOC<j8Iz>VNUkZ6{klB$pOK>nIL7(J<HW+qW2_d<T zc+O58El^B`3&g1sB}@BNRGhpQQp5vt9LfX5T3BKn-eb_nU6Y;mhxzkyW@(aQnDg%! z^I2xDHBUkGc}KE8Jv%*h#yoWu?2#ewStjc14n(+HPW`Di<$c70CY^O99;X*%njGh| z>*`<Y#|;e0lm?0FGRd?dEe@1r2CLBY;LI>2=jCEsuIo&*yhUsUAzTOzjuF0eHJGkn zPoVGLTeKxIbYe?}90n}0DSks>2LM8!LHL3fp{}1G*;&k#;Bth~mE^qqWfT@mkvLwr z2p?;8bdU~pKwy1xi#I9!!T%l^b$rLsSVs=xqD3%KPKsRL9ylLv0nVAy$-)tIp;{Gh zwu5SW%fR|q19yXvp!+}be4Z<JSj@w#o<~veyR~UKb98q!Mj`7pjg~_zBp8SLx>lZB zXmcK^FT{;|eZB6<{bvk;^q=X;P2rpVU0k@2;3&k28&Or(?G4Il?tZW#i~aSxx_Cnh zZjQS}o>WMM<(LH95@NJ#K25cWlYd1?(rqWOeW^~i3b2*l!iZtv$N1X};_YDV)JI6l zbpf8*sWKmxJ}QMFV0I8&?I$36z86+2mh_^*s;%W&Lb^+eJBm%gpgM(7GTE*h82E7d z3!S@9Ewy#d)a*6dm$Jxt+8-9>e_@g+{dnSMMZ&U|F@ElfKgk-;l)l0bGFpY7%uOFL zE<o5Gduc-8wk$dK3@6?D?Kfw6iS2M0!8^KlDv-rvJRwS<Aoh{BkB<N%_Oa1%mJ*%l z{#NLs!>bKVVMLa8T8!)stXu1OLe0h46SEzyU+{KqI4O2(_Ffkjp7~HSWUQR~sRYMJ zT9{FbMMh>4KNf(MGzsu))IZ5bz7X%kt~eLsE%1dt>y}ugabR(8ev+~+k*8?@$rdVD zA#9CUHi!f$Lsr2Vhb8SKR;bxAwfm<`!5Hysj?9a4le&m>RZHk>1Zx8tzZEFi;s<(R z^-jZ-A`2%UL!92pS9UqtGOk~}g0x<KdIS|Bf9#Wi38wxMBapW!OX~~c)d>l|y1^7` z2>F%fa>s^d81m_)e3v=fEnkMv&erkx8c_aGJJq1i1I3-|{EGezWs?wcIiH?4j*m(? zXq%q~I)!AC&^z3pxBXG8Eh^}+2=aim+VOEXF;gqiM%#@A1qjMs<e{HL0&_m6sf9!f z8JWZN`VM$$Rr5uN5mZQCI~Z$LLC~Fn_X+mSKjcBM5!Q92WH@qwp?z;{87L6@9hc!J z8Hj;27z*X8=Z5)OmrpAaK`ogbvDFjerkS^P=ABen&C1F1i;H|%*gXV~rT$r;HXt&S zW_frYtcgHf>BW6^uTJtoUp!|;e1{i(nh$cjZisMaYqRAZN9hkLvZH5iLUEa>*`~SA z)vKj~UKY4pKf4rGT21(OGMZ0U>+mMBKKC$a9Mn!=Y=H@k{=Yh`!bWzPGK<)wb#=dz zI8;v~T;a_C^hWn)u^&Zh!i3oWO=f#DgoLM)d?V2alQXFU4hC{5a}M|LXcF<fk5?rU zS2~IlNp44HGx>-*pYYQ~f3kp_^h<KIKC^DhQr}^($XGPBc+m-`mx^2J?n#=Csl8_* zLWgLOtDp3;qfVT)<O#mfX|JgV%xk6u48+R3TSELZTE~2nrRE!U<no|7I$usA*c02= zAG;&VpddNbH~H0Shld59VZO>8!jAm}!U_Raxz)8?5P#^t{PFRVXXs6^xZblLUOoFs zje0ZaxYqjtii|urUwr$`HxD|X&_I)S@DsDokU7t%xeB0@b0TH;d?KSG{m`R%lFu$J zy=HiW@x`@&&nF!SmvD(z@+Y|&<);{$r$4qAlP8GNjZdi&oKXD^v%CSg-5h8L5&GvK zM50B7(VoqMM;e#VS_Doj0fj$ojxT~<e9qY*(iRQMDTfehVIIGJW$r*=3sz&BVVPr` zU9fOz*MJBgu-Fx+z0mYD<nhw%oy&-q&xrnLX#;>7zqgx`CV{rSLVFVAdtN&85~L>b z;a*5><m#MA@F7&ku|GBS%qyxSNetBcV?j!~Gol!l_C%~&x(g~xzD-hv*`^hVttN(5 z*~(w$Y`I_M{psM`Sh5@}9Rg3P04pfR7KkcUfic>k9FH;Tgb!u$^u-}^#e9a53e?3{ zZ+GF@VfYJ<8CHuQj!w%d3ATbB@S)F&AtuJmZXaiR>4)6*Ba>ipTR4o8)}_P?k?Fo# zkL#7I9QZF)f!2AIXS|*Jnk(6BKqBFMQ7D(3@yb*F=si(cr^B5O-ktM&G|8u1=f!ZC zkGCL2RRxRmgeBkB7y=4tzsrSz&{P`Ski81g`E>)`&O)k)K6FDaCkzv|uabyx1&^Je zD}@mkc(G|uvf4|waQ7SKG(k67R0Gd!w4vy=uay%C?=BSTG`fAsHgg4(I;9?1N~q8c zH4s^w#Z+42xe-bRo4K@LGG0XJkL)I12^3;1EZw`IOG4<4kT9SP{128(Si{N*FN05e zAU;|Y5eH7WSubX>u&o~dZvnZ%a*EpB>h)eCEqv$hee<RL_uD()y09ouy-2){v+$Mf z7$?9Kv1^FfG#Es0KxjbCupav{a-fu_T8`f!PH%9~(O{xF3hfFOp1x-HBdZ%rIi{mK zP#_^kUdC8HC1kA&0GLW$jOJaXCBltFG=~+2UQOJvn!I5}nNv+jmZTul+u0z%SZNDa z*}-4~8wdNGG8&Df)y1ye<J3;FKBTsdp&ljJyIiSDl9l%wP!C{?B!RF1-38An34)0g z0=pK{=RUN2?fB8d9{wY$G!-<!nJ)+Ds~=9Oq2AkQNzMQ|9}i!Zt#BD#%+~_%F1yj8 zEe!cm4eE-tE`B6?U=Bp{oU36;SIiH-{E|O7y{p;)Zvb(0tk7W4fqk>04w?^orVWLH zAvly>mav8Zf~RG|RUDYC0-aqv8T(xfD^R89Eh*R)MmcmO))G$5)2KP-YGEiK-NgRw z$ofOsbHHz;)56|?FLEH%G?m&eMw8*ZF^lIC*pEcB@nuWqvvISds~u3vWCjl<VK(E% z-U|rI+E!>fvSV(6b?b#(n^!d7m{8G(a}@w|lcVNMY){w~xvh|cib`FWGQR*LgGLLC zz{sMQ<rnr(m%xt#5TYQ2J{<?&s`<%9F$=#T-VQ%GnM_y_B`Y1%@0eYTU*mSAoyjAx ziZw<G8=_f-mp)MhkyIyIqjeMJU={kGr{W0?&LGsOaT8kNmgF}UQnjeWnT=w?b%0w! zPHzQKtwit5Mr^$>8qxb&#Z6CrfDDJ~XP6d)OochRsBi7Na`KDNx=VDt&t0}1il9!7 z*7amauaq_pbN&28d*MT@`ktcMrR~Z>J~>>%dZQ-mMtUq!NYn@<Zv&_-0#RP>f1*98 zd(QoyVw!nHRXNxP065Uya}T@v8w}z)1q@&7A0%@tbx&RGCPs|Ar@w9__o(k#bghHK z`-9GF!3n9wx)FGtnMTgee%PVrMJB|UJo7)(f*2Kr|JDY?e~`^EZUouy>GWbPFK6ex zgTQZx@SAR$vO|X?oYc#T&-?%+!J}P~YXA|_w=ZpnpM7%b?Z|UQ#+T>_xodVh6lEIR zIk(wn5{G`CdSfG_yuJ05fD?6rUf-UItJkEjbz;{3tV`2)3i%tUPR$aEEH`e_KPEW@ z9~aWvA(^7RygD>=5CAX}qbN)jiT+uVzYt^fsaRYe)zytmtQHx=$XQ^50S#lEAzktu zU_O&-4rWq>(<qyD?%iYU4aUuPddCaP;A4C~pU%Y9u3U8iou{ij32a`Q47=z>vP48- zuZOV9l8al@WkIYz*Dtn#lS#uzL&xnzC-ceDE`FZ44g$%v1L55yK)R4yqulOsImMXy zV>}D?Ip8o@*w0H&96^C`H8u%csv`o_El~l4i=+oGljo4~?V`XCv%Fr@f_zN&SSchT zY)VV@_L2b%@?+{f;HBxXgl+?#vG-_B{*4U=z9+Ns^Xf0~FpHai_wu|LaP%gkRw3l0 zx@VTW9OihxF#Ln*PvNaJeM><?XbtoHnfaDMmo{94sE8}UAOHTnJKJq?ReD}MK~#$N zxe1f(0hdOJQPcA|u!M>(X*)ynM4vA4D~IKAS75{M35Kn7Q?$P})FwaaPweUEat48u zJ?F1gV8Qp)qWwekZ4LQ$d=K0N>J0*MwJ!l55zwkGa2Fwyrg(Ij-`aI-Zw_@rvqU{8 zzhbr%xm6)Z$`IkEBp`X;)Zkls+z|Iuub$bc_aMt#WJMbthPTbY*b(+YP=3r~h-yz) z)3OM5hOPgyJa=inG%qYa*_T9S%igj$nC+ssY~f3`Qb#(Bk$ocI{a~y}R=Lysf9AND zS!o&Ke1a6LrB&*<%HjF_^g~{!6QGr%6R!8dPCbHNy-SDCxWo0tdlOjF-T1XhSkB+* zv0=`)3Fy|>Vxm)EF9b#PRvm^hg2T58Q-}^Iv{pHl$HKn<7LOLgJhC@AHCN^QHoPtP z_*ilwuEQqY@ci{5!wLkqF|UBL<F$~Lx4i&Jp`5zsiK7IgJ&XPP{MkdWg~Ny9vOxDA zFmJP<23auWWcYU3c_G+Q#9(y&(j3!ZKCQ}W*PvqY{{8#kQfDtEXsdlr9zJNGPKL@R z$JUeC(vEGp-{&ZfwY4$*DiK<jecVR><_fMs-m<`W^)0jEY(eFZLoh)DH|u1<L-T-g ziEI#vusALzw(C#03Y!NR=^K|)4ltg@kSqg<F4WgUYsxnCd%kcEI<kbvlFIgu`fzra zCw1%ikn9QGzvvMO5x9Olru{R`dGJ)5G5qiRMB#qbpQ#j`#i2lIk5`I_J22@ri^jW7 z+=a0S6OUntQhuJK5lS7GI*+?g!lq#_AA?U<g^-sqqa~NN7DYXENJ15g3;f5w;2i|; zTIvRwWEs3;iC4iflM!>Nc^D7J>C=>OPKW*3dH16Kj)Fnsul`Augwn2MZu7rcY?Aw5 z90F~5yI+HLzv9ui&7-=3h2)KGM+@S6r&iPZiV@FOy}Hp?&`7h?Nap}`gHOqMIf9pj z6U1~lfd_cwP3`M9hU7#P6Bu4JNl>hysc|}9FavjVg=%o_D^z2)p|PgXq=I3&r-(S~ zGR~)x=I}pL&grr={^tZsU^(F*Ck73qly1XNmnve*MyX{gF$r{0lW2;jBCothxEMLu zHe`B?tM0!mDwn7PvsHo_^Q-cuCD%B>m@1p~i!pho`>#mx*-rZw!ZQEmv95Gxudn(^ zVj2AbZ8&WwV%U!z6-YgO2g`Id%SnGw%&ycI)?@uxR)qw5_C<CVXSEMcUC^6vwlN)E zH7LOVKV$d%jJ{3F(a3Kf{eEe0fgR>8PT|hBDwyQpjL)CO{fQbCegZ)Wnq+$?Gx_$a z99d=*<;dI)0w1b||HLeJ3-ZVe5t)e}e?=(J{{$3POEDA471vWnBXk~gDczCO%<N># zEk@~sc~dJetP48y0NH-uY)uX7C4VKFdlMnl%6)m;!ggpc>B0$MBOnr5HTm0fmCEDy zFqfs<5N$6B6B2V<TRe3oJ#A7g;^-2xk`7voV139+G_&i5dkBAVY^^|mOyj&5Qv^>X zk4jjmHmWq;I3_u$NgrqEYSXx70mtAIq9}r<{*Wu`3{yr#)?Nxqz$=T~2H8qQv0%)k zUzEUt!+TtHggv+1HLM6i=RvZFs`w|ajle;Jy+5SV+q^==+y?n5o?F~u=0v2A%yuZW ziGyhWpLv0dK4wmbi0(8+3%~^jcFuih3KX#K`>Z&$|B7VxB0s9UXl&Wfa`5Im!2J;7 zzw4d>A7kynWb_qu?z%>p2w+MP^XZsXuR(D2FuE_!fcpD0G;qcsPDDV~Aih~r*N#Ti z#QX=rfYt*wJSPwn8v!y=nJ`ubdr(Wmm!tX28ICGTMe3csh`fzrX=_h^DTcFiS4Dja zt9_pX@fg<QZ@%K`X_c!w^s}uj1ypEF%R44FIW|)b_E)14UBD=UaUN&#t<?%JUhN__ zMHIyl`98T;Xj!UbQ=-gHf?lGJXhE3}s5d9T;qaFpi4`*oA*UVkHr?6&=Fa`ta|7;z za;yw<hqW7&QaS<B^Jfp(is;z`^o+bjaya{WTut&paa!1UVRFjMuvZMEYY;H*>wS`# zpXMR$?IXAemWp-x6_o(*LC5}QXFE&`@$jS^UOmFZ5F^|XsD#o)Q(YD_lq`Z=uHqee z@XeiVXZ6@HC*T2+B~C{ahBlQzKf|j`I0hot;n-9>Q&O98B-s&Y@Hl1$&+Y3w_jV-a zK*QA9U07yIiP$Vz2CHn*j$>-V;C+eNQ}?<odR}@x$_$3w99@0f?Y9MbI2n2v94=;} z&FGY7-{VIumsE8dsU>;o<pF!rADol$nFq0NOYW1WK`9LcI(G{vlx>Y0TM!uzFZ$#D z8K}K0OkYkh{B7k442U~V4wuAH`HQr!<hZUEr*hFBB{r~%0YF#gEBhbIv~C%pSIt>I z&WQyuTU3Z*b3|TJm{&SAvLI#qPFq^n&VS3^@Y^I{2YwPH&u-3D7d!36dv{^)b}_Cb zF}rtScGe$iKM$$0+r^hNQgF)=*um|4;U*@H?Kii~eNE%VuZyCbh=cjDuXaxw=^{#x zsM^tEkZh-m!bn#3mClEcBcE7q<y~T%VzJds*lMd{Ndk<LvB`@fe0Vcoc`shOkMhd; zQ)U1{K)t_o4ze+GQH(*fK*u2qk(!TBYSyCiL~6nmIn)<eP{qXIe=)p;FcF`t6vT%+ ziGIHp@Rf=#?l1)bR;MRDq8M>sixHD`ehupU%CmnwM2~v}Z&bz5^68#{?<7ZVX1rnV zawhVD43Gi5W+VGjfsI7jl_D?Y?_>Y8b>G=Xit(AR+IANt2Z~w=DPXWOJB6_*yco4= z=I@EG?rz#E3fRoYv>7nmUbZb^oipURGp93f@s<O24ifUod(l93|CA3t1<U?8&Efhm z8N!H_Poqj=QPgZ%j>1;{bAH}`Ta@z#%sQdI1%N39a3mB*D`Yr%hn`S0**hs`GfP_l zt|HRu3YZG0h)D@^$Zc;SU;xoFfJW_|BLym%VVHla=)OC}CUQ5d*5r#v7FOY?(0!|7 zUF02?G~)HRoL->W^-oay&se$6_<MDZs0d82_v~Fhn9p)Y?xEh*J_k5I49!*PBLwb= zq}cLkpX8^2$t{(KmfDt3l=v0?(#yMvgDibJi!sL1q$h@|B8lU8XP|Jztc|wgo9*qp zVg+F$ut>uIbmmoNwc}5z#6!H-M2oAZgt9V2G{VWQiSeu@_9nc~UB<@n2}QSHjGSnJ zHp)>G_(nl5S-|I{ZEN)W?0R07-me#o&?!DD<26-F#9vY`G<TqtQIHW?A5Aw8v^cu5 zn<H*S9%yZJJzLDi8d^0IDmWN^$E7ldbS4QD#vf?oaSj{;xF{i>8R`i94rCs*12(Sq zng_8pX^NA8I;d}|!XHn{i;3JUx;=IBX7%STqE!+P_G|lAfH+v1TCUnN+@A8aEDULy zD2=Ln4OBKUu+6E!7fVx$cAu&eG+CSuk8TLQbSM%@oCtCP^TJJVUVPto@#PXv56S*z z#q*;6`h-S2t@qcVF_pK2^}!<47Fz@$zd{iW9S?HKl#ZINT11o3$4yI~QGA((rf{$0 zmhep)-hc&w4Oxhv61v$))2A6T#KD)OpPUo>ycq5FPrwRAp5O*6P3$Ao95+19q0l?= zPW!HE8&OW0-f25nALobZJ}Tn<#R#d@w@^!}pSGrVc%<66x=<x9uP@P=cZ8yR(#VL< zGKv^c`?ui+{P4jvH}MU0{if=YpP?1x+ep;*W+vfx3YQ<|hnIn!A)pr8w!8gtaRDi> zl2m*LQr3ZnVV0W3Q<pDbXS>}HN|6li6fs&(vV{GLk3s>}H8q;>%zxj2ZkBXjr*yBE z-@d@SrA`-wB1J7y_^hN6LF=cHM$H#4lp<1ik53jO-bji_mKHuED?Cq>S!WN-=+I7} zWMUO08c3|ro5t2@IHwLzJ_>>rI!i*0Rt@ob?Y7SV<K88It<>%zkceweN@b}f2M|}R zL0gqD3iB^vEzpsM-+Ini0bQr(SZK`?s#Hl+g6Us2Hg3fy<)f%Cb3Nsb?Abb-cbvVZ zyz9Ebv^PlrKXEt%J>!)pwOb1fl>pSxN7<j5(}XG(BB9e;VJ!>vi-}RRsPqOhT71n3 z0H3?(1m9wv&8ZZ@Y+KcbM455J0}(oxPCT1P_XLEKO8A6#oYDuWp(vQjs2t}m;ZPj1 zf1J14VQ{E|BK6d(E4#jpNK!}Qc7a66oa<&!x~f*`{-&9+{Yexy=xF<x`~3l|Z$Ysq z&DsGvW%Hwx`B@d(AI&V<%4fX?Uw?g%<p#oryIhJEp*WkYv<wzpd&m|Vf_H*@5&99F zK$K6EQkP!1WicZIkIPaNpQ<G!6v^w&8N-x2D_U0YDBR)pv5$$Q;t~P%)atcR1o}Z3 zns%?<odJGP(qJz(b;L`uR4XEDh>==&)R>rkS`)Z|X<QF>ryu$sPTM`h^GkW{Yw>P7 z6~<e$6N-Py<e;)ZO_-J`s#%sN|L_x)j9MrE2ppFrF9CdpLe8R^nb2+paKU3pb&Q<` zjourQ18mx#n8ghl5&X4tOer(3bypcVnM3wEnO|MRAdDEyh}o~2_#^0)9k*BORXw>% z2H8cyo!P=c$slprs6a_B8<Y4#=##j?Sn?BeNCLkV`)pVSOCD(*EJ17>mP2V&Kb0lo ztL99cE>&x<1%Ze@0LpCl3J35mQDFa!Q}&{#8o$Z=Y4x-xM6^7mPAGwXfrz?5TSJlz z5I2MTQAt@a<)we<R2!$*ASQMd?Kx`I?EhPy5;W2l&7#lACB|7+*(5K@VR3q8tFai+ zl7oXe>DlZ(M#-fmfeR3{qDM;!Nyv$MCtr|V8gHkIWUg1^oCdlFuj%PPI!jdGd2vmp zhdn_HS(nuEotMpmXskbVPsJS?(h}8>fSl*gLN8qT;Jg?OWhNwZ<noS7&k%gJ&EV0| zo<8E8bCLJQ6*4e1xc#4M4tqTwjOIfk*=I=bV|)>}GPNl@RsN-CM9y>5Ty4jEVjBVl zrAhBV)d-l;TdN57tks9|Tsg?W#C@!<VN>;}ey0wF_N!pgNy!*)zdjiM0KZS>MQv?F zBh8gxSq?6h!$Dp0R$@Z@fV)W{W=B-M-C+#x5V^+&Ud}BOGp$G#pzj_&$S37=m{09A z(U>P|qg((Vinfx1yKPyuL)fHxk0Ql(cqSBcFR<>>aDgTn?iCJ=S{7~-;-Ol|WD)YV zl?4B}I~^xCtsPhZSCZr~c^Ir^XhnjVK!=Wxm)a}Hi4Fu!Z9WH!Va>pjgQF9T#lqn^ zY|ST)PZxtG5T3L)K1efKV#W|CGa^{i^jk&^V8}Ym;;t`mZ1=0)7D<g&TBDY)-kzTL zRXQLIVd8%1O{?i<8~D_?nrtLeQM;iTg)-e^?vd79t0Z=N!L&jJcbzz(P_I8%`Sc}1 z1+d2*GqC?p3b7=^yZq(nP-1lHc>>7tQc4ZS0F+&=t=BZ0{;o1{M8<HGog%CZ_=Zf) zvIRXJ39C(2Eh!dUi%`oZD+$zzfqKg;>=J#_Rd480=`_P0MYGvF$xWk+F4?|wYZ;B6 zR)#jtdy`_>y0UYz57l0?K+!7JojV|qGz;eB2=181hAAE2<j7?z*|Ia=?&yEQ$U~pH zhqzO!zkj>Eg1;^MI;Z3UcHfXQU2so=);Bp1k?;t^8}(b$1o{neT@T1|IzkdqJiz?Y z9^Vi)8RQK%voVIVje9NH_7C8+)b24OHsA*q<l?6z!XU~hBmqw9op!BbqKaN>6Fk-R zR+Ih^oErb)-*(rcvv?#&58h~?SB{2>$Ej`CfpK1`_F-Uv#UbILV7!IDQT|)|w8fXB zX#w~;r<c&&l$Y@nhn-6`TYQOq6@8IY-;vC?(dN)?R=eY__ip0bvi%|A<0ChSDVH1V zkf56SR^W40|4f9`I^&_n=YQborP%U9(I&$V@Y+hxv%x=+yQ*SSfq-MUC_(2ujM>ox zvtxIDYv=dk8pvDQ&ImSWZF4R9A8X&7nJF1cDxpg#sS1dLuW(J9L1(B=1Wl)tLo49~ z*v4DRQ@AzZ^HIs~4B*R9Qc;_NCqj4vTea0_Zt`{|{ecM{m_QKZR;I<@H~CAO;Wfc3 zD!W~KU|V`RbPzZlh(Dd+bGAkCRBr*SIWB^n+!ed!kBu1S&vkCt+rRYS{0!FqElv*S zbF-tvCehi&GKtXit7b^hF+}fJ{Nv`TI3M+%Lrs*wlPIE@`S~Q|!A6EPb8GiKZDMV_ z2LW~JNS@kkTu`%MFH?4TT(U2=8_wdgNmxN7t}?W2lq#U*$0GL&cPb#lWe1EW@{Poi zQq=-{-&_>$Ku!rx<Q;u#ft!W#rdnXe;0!#jAP~qUgtr5!st>>9jln77QW8>vi24a; zRh8Bsyf)k13>+lY>IBXLYk`Zs<5=p{CxO$ZowH&-Qq^{(n&T!@weGCe*<IBcRXR>( z7D*8LF%Q8}R#dE)lo6~_JU!H>4iaD)OfFMcEJ~YNM{y49X3JWyEeglp3CI358ha-_ zHfxR2LoZnOqoDIUi`RYU^R7D_`|jd(-(6+hKF>kfg}W?0_Igj;t%UF1pr6(4+wdQ8 znjRK!!A|ky%6=waJ21LO8(T6T^l2ZlxZ)_5Xxv2x0_KZ*55A$8m20eI#0kOivB)%Z zeAy%-A46ldTH(Iwifz;LUBS!c``t}cr@cw+r=3NsRTmAZ!>NHCSUoOkP&>^7!{pS> z29kzb;o4Av;g{Z~Z=7F3RMJ$uo!sQVB{unQsZIWy+T?A$$=k_I{+r+Aza=&~A=1<L zuZCIdHZN&XyRrvHsGpmT=GtxrYh>+?--9-PjI)W9U5M^N<k^)^XeN8nuvZNoybC+{ zHPykdNvqEqpG5a(?Gwpu2c&CTQ7;q?l<C)2?1{$MrM;N%iu?RSd9KaGwtO1Z{zr0K z4Qv)&=+ATNbSpmdu_rtIV_CL;i-Z3JW-Y;`p*`&)O;}*6+3bg2v-w?Q{zj`t+hNkm z{RCt5N171|MsJ02ft-=1sGgcSjGZ`4Dk4rISWXnGC*_a0K*R2$Dgk!hVDv6F7lE!= z(sEEO4AEs0n?RZmQ~%V~IXDwNcU-6SoQm~XzH6AJ7;i0`CM#4-;#>1Xx%1jgB?KW@ z0NR^;3D!O*^U)hq&E}`45T(_=#1I~WT+!f|*b_nv8o)YGd0_FZ(TB_aM|@ENPcAft zCzmoZd?(i+?&`>QM&>VI?kmo090afCua43F81bR2z`bw3{o2k2Emz6?G_dFCpF;RN zc59PE>;1h27w!YvTYUhh2&Wmryn><S<!TOfK?oZ>AiH+w>=}0?Fywp&e!+lu+GBu^ zAhB`k3`EY%3*5zsjS!y(PoXJ0u`+-S6zm<AJhPA~m^4X>BCnp93=QhC^-R2U(c7;} z-ZBp({UL;7)u95jT9`h{bW%k@Ml>jSpAsJeXI@Bqv|6Xonl0EZY(nynS#D90Ypqh1 zaMBE4B#vW}ypZ&(uGmHFk0;-hNfoA8sR_EE5AqRH(Nc&~m(31A*|mblKz=mljZH0q zbJMwwBv&3f&4vL7*>n&(WX~cpStLtwO3X!ZLRjj9@;vE{Ec?WNsUR~uj^mw=A<sxf zmWqYT6*eT-`K$5Zd|Hm-gX;`D;K7}DaNZxE<zy>pE>N9=xWEO^))6kqveNaBW`bSp z(rsP5W|3IA3f@Z$Bjs2uqa9P_q?KD3Us8@z_^$%lg-<%-YJ^OafRMUFUIec$#ZL&6 z-J*K&*87sJ#ozZiN(rHQuyiG`cRgFMVs{&)T|o5Vtz08`POr}e=<|aw+X$S^&z3TO z4W8cl@X5=U<`uv<{?y*$EW(wZJJMKUIM^;_0pJvk&Y7(*9^AYCO<URc>Ht94+~-;W zV_}GGWvgAlX!CLYZekG%goN*3K}wQuza>|74WEA6`%aSO@U^R^q7c`84_G#e0K1?C zn+H;5Vu2Ra)=B8Dd8_@b>oKU;9b+=!02JWDXfFZ8+|nCws&jB)ao#Q^xiCw6u={r2 zFZ|Fs2f*sQ5AKNKJOdO`cpx>L>L}(~$!qZtiABYB5<jv~4*|nnY#c8E+g)k)eR&CR z)8X_#5<AM{3&gybwII3~ko~4WcSnpJ>>?zO34YuZ0NSp60wHqo$6L`|<=#l-!6b%+ zIJ1k8q)A}OVHnh55th6$$|~&Yrx#^4dk*fQ739aX+rF;?W2_~y8nE2u<O<zL&09!i zjc-3bInuzsTdxc0w)zF0Cy0=;t~Vy6B>l7_!q7KJSy1|BwbHP06purZC#oQYwxe~Z zlJH?yDao65R)NQjPV1BRJW0DZ@Av|X)n)sgj()Oew-xJ%Y@njySSQ8)aq&559g{x; z-%2?d_%jRLDN`PKZqL^iUJza_tF(ldNH$?zNIeU6vVX500o5i%WOeICg(ir}`eszj zAYC)l4gwJ_wo*ZPVca8Jl>{pkuj_5TRg9V6wR~2^$&w%eGo_PJ>7kp*mjwN?BL@nB zBau9C=MEk>?Bz0MXCUteG|eT(Avot4U{x9CD~jf|izs6`q`(`sC9k8x&J+^xxg`j7 z13p(3P4)jL@6FrWIFh`<zsXNgLTlQ934)~D-P29#SXr`1dd9ZAmOQqHR_g_UB3U+w z!ixe#(iZo#Z^oICM*+~~d3(3#8H=dABCp8E$cSIW>q26_Zc$hX^dOczyC7e7f=jvW zE1!gP{6SZ+A1WzTi-^YPoXj1e-p6wF*_-kUS&!OvAK=xC8>j`T7(0xvE)26JZcDNi z@qSS+=WY@);N1!1;L~xWm7zMq<*F~mKeXtg!<9xv95JpXhCQyQ95`?*jQmmL=FxT_ zl9MEcTM7Y`lc@m8%I3^W=;tK@df^xZU4{FalQlu-!X9FmjL!+~VXmb~X@-N{+dRaQ zVcd8{1Sny;BGR=jp6AqqG0#Z-gKJA+eu---?VpO1;#Nt$o2ej3=cTuzj@7N;`%8Nx z-UxA34Kj^}b9e!4VHGD9j*<B-p@tZFQh26!C9FIoHe%`g=2o$va=gqp^`vy1lrKbl z)$x3RWlO@a*%R=agyDHCotQ}(ioa178tEq74h94(ubQ#Jzu1$IH!a$W;(Nu^Y<aIq zD2quw3VjGseD-zoHBLgizLjJX1fWm!403ZPQqPA@nrNW6qq2Hk?k#6y;3giL3u0Lo zT{u!F*S&Z^!$Toa6U1v1ZX?ea9m!-*ELpPLDsxO4Y{4K>mly6V%e5}5Cx#u_6BRHG zW;MiQtK0}&3rF!Yn?7ElN9n{&GhWQ``s{sVNj0Udv6>0*P<%?l)e}_bj<Wiq90XVI zErT9r7q2zk70Zz5T1fJaoE0kf(D4%}7x1XDvJo6g2(YLkj}tIXA!M%tHiE_}KH2)k z$#P*r`<mwIA}O^QCUA1ipkSFh;2^UsjNsHJIqk=bZ|(Jx>;oqgpu?;g)f*6sMZv5O zmjbXM=5A!oV(AlDN&Q00X?!rT!BFP{h+yL2mS!jA^NW>tF*+9Vo*-by7JN;zsN zsO7BwDSMNymkWP|_8IuO#i(!F<$!vY2n;$nBD85eCj`JY=PTDGII_Fr{j@Th1LG2g z`iK&iXE_dqDTpx+Eb}jaKj^I+h_<mkS|<{=t7FWaE2o|^_n)lxDnRG=_aB0R#X*Cu zX<nTYwk6K~HHNmFi>^mn^WxK{nm^$`eSpgP+usZyiV<mw^gbaSF)6LM%^CJ)imipD zTp^giVe{Ui$<*CB>M6paWrUP=`6AeDZzWV92DIGhM02P05WwIjLd72}P#Duh(Y58D z-=fzygq~ji<fZ}P{qx0w-mxS~ff|}i)&Tw=4Iao1nVVDqnZYai0*67EL+u!X&;3FW zvp0Bm$<UprQLH(c7zIESRH&GOSDplXf!}1XIpEj(jJ7g>l>;7(x3p>ooIm*y*F4dX zdy4A;|NT)0UFw!m*KYPwI$jw<HXeF1?%81E3k&O11)c%l)Qcz87-BbyJ$*~E>uNse zfWfWzE~hQEknRq&hgIm84iCYr$|(2_8lXIR@%2|7Pq6rdJ`=lzmYM=<{+qRm`>H4+ zaJeeuYvMVx`KU1$R`n_N)~_<I`gHu;I%9~Iz|CXDD6vOB8v9_Rs=(|g@Rxw;3&)fZ zP=dB%FUbH0`>tysiO6RzTUjR-5QqGjw&dCIHA6_hz{SDDP!=QbY)?KOb-P*WB7Jhp zG+eKr1~x6u%!4}f2C(IC-_fr~1GT!RUx|hDh7<8)ZX(!o<l_;zW-e^VQ1WAK+Z}dR z!qs)VD_b!{Wyp3b>J`C4XDeu{HtJC?8S~p+0)jBu2D=;5{LzTs$rBy!iPkNVANwD( z{b1mY_vi=K&|2|Z48Mn}*pTXvNcOr3&{JF6Q0QpF0Q(?8Nvarlc{34bI-G4P;N%W! zIz$Ih%@^XeM8<Du{Z?a20J{Nwe~u86;DAza4tP?+)!8}32PbO=-9uPb&bh)=?ly_L zaP491liNV+?Jy*fno+Zu<SnOlD+JvkLpWX~WLc$1_KH~qZCI$HLU4*CLEwq33C(Tt zOJwk`+vI;3K9P#vcbz2VhSyFJypW!_|DU-3hk%<C_m8`NyN@n!A6_||MQ{@c0gljD zDG1Pu->(kn4bcYaD6a0fk1l10>S=+S!1C8&dF=Z&6u(|koCXq?6L=wXE1@`;BL;%r zEe?*{V!aQF#G=~W?a|>g$(1>-UJ9TQro~X5TX46W2w`za>=hYYw^dGFVnN;VJaqz> zsJ5z2k4a8(Lwwg!vRh!#Q#aQ4i@7U|zpf!|A!*l;b|PuF?8ATBlpCm*xbFt_<+PkX zR;<MpS*>k{BP~lm{GPe(t*o_cR~T*gImKYdTS;3YnK)yz#v0%?uXc}^s>bDxj}=hE zQ{1Il;;<7py<RVH30>8V(9Qt{w3;r<qu8NSVqDX?iWUuewjxhN=f2@d(}mf(zT?g# zch8_oPlEIlNI$UYlOP>d!c|ay9;DA9Jt&VHuhIE1iaUNyrD4p3gHhzdzJL|#eremP z2F$RRbNoH|K!lvEYiN>hh@XJpq9w&=oV53yKy@(GUg~Z<|KOC&GfmNIMBeUdbrTLe z-~|6W!T&lkj#^hNo>Hq;?7^B9duPpxJy^41?|ifs`-iQ__uU#FW5xb~OY*HZhq<1t zX2I^5$gXGjFD`gdQ|8VZ_)q?zA=&h!pEB6jb!W_){vB<<l~lhNj(&Y7jqyb_ZB-Ft z!r8oD&d~J$9*YUt9p!vzvPZ5dUOFE-kuwTi>cK{DcZaO0{q5;=TwVq6qHwb_IZxVi z9&LN`2wY1@qL0YH2H-~pE;rXfN4=>TbA$BX)&TkOV7B=3Q3WB7!W#N8mLTKxG)TBc zs5P0olq;Zl<A)fn<s&~0gl_{fME+@jzWA2`$q_vaD7p23{``>70{&fq>u!4%FjTzq zWSB<*8?ncjySPM`y7%d=?c&qom;W2WZWP}?^{74vgM)*?Um%g=bJ)-v?(;UH{LHQ? zKmb?pC7?YFy$_?<<GTy;$<key8z}W13B=>V<;4I_W%2dX7saF+l~X4tCru9O`Pm+) za>JZHoK<1O5aIlL+Xy7&m$nmn;kwScLb6PzKoH~dw3?ReN6pzO0vRR@h8N>P!S{=Y zUq2qW4xClZLYxl3?_hcj)(7ySy_}$#Efww-$3=$-?0{Xe5&;Xv=o7&<k?j#FU^bWx za^|j#EpH>!r`t$as64<e#sTDDzyA(ap$LzKaUcom@MJh=z(<Zg-$?WfiY5iT@nU!- zLXG>=eHaE(lKX(r9`Xr)z{m4?Ui}95G`Obj!4dgpg!U3|D3mMYfpfSTQ4Y6PBm=qj zVh;5w-8=qy=jYv*KaY31KM#(79>3h_J@~f=n8!TV@BQ=V%N_by&PVh<viEPd;ma$N z?e^ewY7CaPHH^$zxlpqJj<MUP__d<@poPPG36PwS=YBb<hYKwtrskiz)g^?m$8D73 z0aae?IkpTw_y@$VvUMJ;t@D8EWJ*n?+W_ixV>*g0JOWQ86%W|g>pJM62cW!7j!l{D z27)qd#Es_T>H@Tq@IsG8sd89{^Wi1HqPcJGlse+Q=sperec=T-Cc{?zN0IvSvT_QF zio!Gi(Z+;xtC<q-+zc|kI_OGZxT^U9m9a>SDh57i`<TIEurWF2JL_O$@?d-zG3jx6 zI$TZ`?ey&jMD6DY!RkQ2uhK4m_|dj(>b6~vLCk~hC)z=2nNl^R?hUS(+t%a;4*h^T z<q;Edd<^e=aGC(q9Y<jaas}ihhXr|g;I{f5QWaLO*`VVt{D}dG?tL<@n%QJ{eTb0@ zkJQUh3@eXlaQ?bKyE@{rz`y1F>hK)jaF0H@Z!6`TZl}7eR0H4{K(0NPjsGh)C8&UT zjMTZ$0}MhkFWtD{9wN_dF+yRps4nEBclOHz6fvj@`v3@uSYL>f>}>_uR_XFiYXveb z(1x1?my<^y%ecxR4A^K=xs_{1p4;_CXC|&rc7pFg1G}zzk+B?)p)6oQWrZy;Dy^ng zzT$2HMiM3JUI*T#pG0Hm7-^@&anm?43|}P`?p~?M4}baTgEyg8Mdw2_DwU3yPGJx$ zo~}1<By?PuPEZ+6sNvS=^toGvjl)zKIOw$HpG?a?t!eqEe9L@BwKpvm0!Ml77Etq` z@El|iG7pM|5wOBw2-g<%kr!aC{eaZQYb^{6h0Fx=`3Q`+eI{H81iMdrT2{!t;PeS< z0011x{n(p++`1L!5|fzpYjmo{gUYlWh9v{?4h#7!q5~3C%We;upf2V4D2&Sa%fZpy zIc%(8zQVMyv^^C~))!DZmy@wg*`JlA+d~nd4+ei5TydKJq^9AVy)Z}Io}6WXupken z;Azcs*_fqiw|ubILqacgjYR|1793>5di4oETX7svWcvoM<3=8~4rc<VYOYJS<P$u_ zh~CNFp8`2Vg>4(_vab-14PRom$qx8e@E9ApJ0v<llJocFkU+L1hM1Jx-jeoXoCqZq zP7&CHLzd;;B16wJzUt5q!E&cxk`dyA`5?|?6<%Q;)P3!?4h#0Xzb(ugNz$GN+`<=; za|wzydU7R2{h{WMGAJ@~U#o_u$ye&X!dvs{qyne{4qaGu3O+peq5v`$`Uv{|xlfU> zE&*&sGN<1d%QGi`f;n*QE+vFw2s&nf_(hZppk_vP!wMY*!`P9m9TGFmB%#D0wCJOx zowzWEye)3o*$lH#-;Z#`VVG31fCj%Cg-ZxZqkHG}mR%9ak_!spy3=vExJJ##a6v9% zuS>SqHrHZE*Bh|ReS>viEO%F6i5@%`Rf7&G^<2PE`{2oPSxqM3*ue^IGU}!)^tM`6 z9~YgAYedOfkm?~6r7138V;9pg!&Bi>$}OWU-v{0|XsW<HdBy`R0wLkB<2yDSJqH2g zztIx#W!8Py%dz6PyB?0<F6=r({p(-`5}Z_v&{o5iEv9t=0U8$9=jfZfay!r(*AeW0 z9BMU3Qo#XLkfZj%7C(rJ)9&*A7QBnM(|LgE*$Sb&Do2(!pdy^1eC7kmtV#u53=CVH zH2I*2Kgj^>XO@M_9)8fw6lG$Y-E+pv5pGa)K(NT+jUpuaV26$8EHSyN8%hSmo6=_U z9B3X6e{mz*TQU6#&vdEvZGjx;&%v^1KB<Ya9?S<00J_cfcxLHC413@|sLb*vA2ZRj zQLkNWuTU2IW;GUj#ho@952Q*D`<GNHp&AV*UqR%-21I6RG(-;lS&&ifxkgsV2DlHh z10uD`l;sHWc@D@X+Xj!%*?Ljv0$vPW20>TEzR2hnE=@nmk(t%XU=BSq^SYTWAIVQ1 zkx(^ALYs~ASJ?by+}x7=g-1)$URgrv@14Rlz0+2gL<3S2W)O>v1(r4t^pk%`6J!M5 z(t?K537g>eZ3`5b$N+(Wz{7LBa@AcpIX9iF%-om&?Yb{6uG_f5R`}e#YsUF#dn>!i zg37{8wxTxPUp7*hsjr0%Yy}1gyLO6JQFpM8x}>&%x>>w+Woi^|VixUNpW(m<Jg!ay ztcduYc&g7OkZoGfg9zC5p%Y{SF5KXA>cr*72l>dqxa5cb9@W_`!p{-{H!$spb0U1R z55E?(7{N{R8}ZO=%5b|M`n@D*z*f*i%(FftrCC`MtTV^eJa8(ZCtxPx*q(!xoAZ}y zkhdn^F;@JtYh2*j0K_o%!+^`%<R=n%(_RW0v_#hXp<ntY>4{Ny2j!9xKFsj-C@Z%U z{*E(Ai_r(pCR&%{@OT3LXV-jRlM4wX5-fQZihzk7nw`iWhl@jVLaVVbTu(*YV1|eW zCvW;2G7fUM=P4)9il#U%%Q4_S!1HQTx~*hlKnU!ef<yFSle(*E!&uyuYE>EVV5Qp& zk6Yea_7*3$v%x;&F3tIHVQ(5M7VRcWgd@`1s>yQJ?n}<gG3oDdyoEpr*-aOij>|po z6N^O-^|x2(QHq3rkw8Cjk2Rf4%Oa{Z^|Ea<nFzLqcuu>KOiENrCj1c*nVSNQt(}Zv z@HUkv%@1Tun7_gt7IW51?}KulP#ifn!+rY3hpxY(NiA}-IV^ZWxe{cD6ikDwkfYJn zaZ!!Old_}8O&&1KEU&xf@cr|j0m`E*t8mVb(szRbY6T~2We_~a+q<bXp9`1XU3;oZ zv$RCHgTC1(=5ah|*F5n{Uz1ib%A)U-lZEhybgk!x&1b>mjB_X%y-dp$z+Ehcs3`CF z?ssz0jq-(r_JHDmWd(TE$YA=OZ86K!qt`xt8X?jgT*T83nYG<8yah1K8#S5=j_uQm zcN1+H!|c2gbGR55#+^h}m5?y7Je&Sj(KUX+5<Ro^l@q2PI8V?psch@3@)CP+NXoq< z6gY{#<m4PgvI)MqaScHSc8j<TpZ`1N<Ovl!QLDn;O>cICW~k0-dHGDLRS->i?*UA) ziVU2FQ!cDhP_DWAwmAbAXewk-=LsW5BHjYfk7!2qscD7JSs5f?KyEAhLAZMl1BdcH zupLRJWXD(Y*5h;(Li4ITt~Kr!;UKQ<GjWGZhl8txcE)rZ+Y9?0OWP^wD`|0j=$s}1 z!BLd5CQsV$2BXEyj3?HEU92JuCd7_+W=aGUBWQPn-ZHPd;ibH&>*7=drrrC+a8jMo zQl?Mk_^jN{481Nn4KdU<|3^_vG=^bQ^sTKeKh62ZcJKLYM=EBbg7E~c5Wy<S23{aW zli*mzgNG+m%)1iSlfAg1G>lJ6p`GZ*XWlO`2vEqoRhBY3h_EHA4+%IpYl4D1`D*_C zLK}OHp{`eR?;!W*A}z-h#7s#gXxpI`?3*gi@$UuTVQs>|xsm%plN+;e1~AJp?-wjQ zG7IA|$TDvopHQ`-)x5(n#oU{9B~qjEZW+N%7$(rTnsIYSOt+!27RJ3u*3hPW8%n}{ zUqw^Qv1vLCkr|GiQX~vp$2d0;Ygl$$KU+BVauzXBj`A6gwXCm%cZO3Pv*|HF!G;a+ zFt)L2GpX6Om`$6N^uBzWMl590#GzsqlhK)R)H`I;@R0qnrR_QZ>_`Oejbv-8Ban&T zRf_*8VtP{PZsAG(P(pfKqtVG@=|J^O*L;30-o<o(;pQjev=l1>xY$;{*cLs5+LtKI z7(BuS?PIdN%v%C-kAXtKZd*yAL5=Bm?-ZXB8MV<2CRdr@3rT6)iQIbE?Bq4q2c3f* zuY}wwG{W6GT`7>5pj{y7&71fe>I;<UUYqD|UI21brr@S4<WDnj@3L>!4VYcy=~$@f z?S=yTZoeaHNP63N=b`xMa%^qkq+&@nC$(k-R;t6wn(rnae{jJ!u23fSgG#+ol?*p7 zJWZe3Kv$VCOvs!tN3J>Mj>+?1!XCqdtN3F;RfaugNXQx@<QQb0iWMC4AmWfZl&S0+ zNL3mB*e0RB6@T1VY`0wDbFY~8EK)xzk9<K9U$a8?yK~5l=;z1s?YGgU{87Z#U?4=^ zjkqIq{BBmVf7ek61;{pytp!8UmY@JK<5gy~Nug@7zD$N)w^QKqy)6Ojirk3lG2+P5 z+qb@_gJoRg&PdL^?z@<#+aHAC7JPaR-ZgzI1r`-_8GK_3kAw)8w&J<|`SlBeLG&&( zDi@JMkd~q_7hDhmKUJ?gV*mL_LSS?do}6j|TL7RA)cSghxhNOs^;iQ0k|Fwl2Vr~5 z^kzld*r5kZ!l6=r6qLu&;OD~EZabY+lWKA8a+6C^r@tL~jRj6)6nL0_(C(9z;po>h zG&gWnP3tK<W8H|sFcPMrtN5)WouS{uD4ag7sEIV)**(|?|0w!~t5!dGgkJ(uDk=<x z5ci$K6Z_8t^uHn_f_q7R{LW^{rVM#hJp!*Q?^cy8L{}en-tiWlHTmNU4Mva@8&uP# zoG(5{nEURU#Xdm%1f+x(9=K6qm%wxAg&S{p!1Cj&PHOCVaj-x5_rH90$Ng`1b%aKy z!L9K&cTc@G1mmL3YUQ5UYL2lUkjln?x?3Dz_#iu)=tu@=qd;mWJ0u)Kng-l%2zV0f zp~D#eW4+srXD>Rp!~YTo_wUN4`VCR5|0O-#=R*GfDK744Z!1pjxKTTUy^&kW`U8Ra z_17iF0EYehu^i&JZx5&u2tPj10qgW>l^{9DfZSo<5ci>_05np`FTm5`+qvuEl}p7c zum}7IOeZ-+zQom39(qLI;k3GNd^-K|csU<3uWQiB(kFc}r03sGa|zMWF{J?@{O_QI zt;(&iC)L>2&X8ziO`%`U&g&-lJ+H>*Cx`2FEtdVJ&yypek~P=G@JdXNAZ|K;Vv{BP zQmK8?!9IWBEc6=!X+a3<fB(ndz}TB0Dh`W(?DxHeJB4{cHzFENshv?k{7*Oo;Fm^P zU)sRx>^c#+BzaGEObndXxss~+W_fWE1_IC2bj#%%e$#EKQKMA9Iv+OV#S^*;I$20| z85zRC$D$WI-?}`wQTd1teVG-y?MAQ>>Eeoh978nLu$m?CE$DcK9|{V3)9r|NXAmlY zpm-<8Qt?YGw~H+^$D6(38GP~V@v}q6OdP+s07gTBW*~TgV;-Z$5*6<f>!xbRGX{>- zz{*n8^<rg7!OkIq1W|&HS`ZDrI;9B8j@>(v2E&6=MG`oa3ZUhM=?4a~lMd(lc$Ajd zHx84opiVIfW04TeGcrX`O4?#>&aXfUKA$@IlBAgPp@d3Tgc=I1=mFtv_(Fimc{CXU z(#x{i^~|g%MwldFk+6-E^eW&Tw{CUof%!s~%0ZSOJ&1t*g<6vtiZI8knF3<L>=GLk ziTbcOraSX1;VHGi@*rR@awo>_B@XD;sm&5}b(g-w;-#H0mV|D`f0z$v!Q#QS0TFy4 z^eu!oDbQEG05@2%!40BA?vslw$p7w&xfq>y_x{;+<zEk*Hw!no5Y^>PHJvRNZ<-Rq zFuifd{Gy(|sV>fXxA&@^#QzB<?b6ZJB{SA8VF`?24)1;9ItFR3Kc5H^fZ_xc9w>mE z|A{vw(T#(a5Cceq8uvmR*C1!&Az+O6l6*OU*R);G&xDbY(>%zDI36<o!>D~Wr|bbK zC;=cTS|gSXSAQ7d)1UES1o@WMo;E+w6a=A{63S`Zt$8%<({OK4CylEFkB70HURUge zA4TK$u)Z9*M+7BFcd@=G`#towy@_sXk#rpPlP>OO$luQqwr^Ur4%*L$r^9)*9fpyn zkA-Z*f~13lSYkeM*KO}Qi*akZtI{4{ZS4YD$@K_XxmYuf=F02V>7p93+V!^@hUb8O z2;zvl)&u59hXzdo2ib9Z`o%xwt@L$Wjot6!m*vH*=$;SfV?7XQ4tlGnxsW^ly2ayU zlAE=o()F$f6m*y)!~+(y{7sk<-Qt#Gl7o=tV~%K>_r$S|^tvLu7HU@vgBsQ|6(ij; zNh&3&Ns<~#x=fNTwNzST<Eu;yHd=C;mYizIX<Bl6*<q6e8gv?SKc2T~s5RQM3~vBa ze$T^{_e>0fBAgop?3heEZfZDlooOG&{L+njzq#yB%f6${KnG7{`w0c)LEP!vJ?E?Y zodeb?5H_G(7k3MBpme`>b~L;mht~u*EZ2{V?)12N$*{*LT>*W;xOIvhmcl3(h6#Y- ziVx&?*%eq4>)a_i{xs%LT2K$~7`e;{0HE#*k&4~g{J{x)PFOvw(UThj=+4Urs+aD- z0)}y?rd8>TjRc}!<)*XXe|Oz|Zq{75soEV^!!y`-u=;vI5KBAS$Mi3Vw9)E{M=6v& z2}uZuF;TAlrhYYt5V`Y*G_ooT(@TrY9LA&<L3lPCe_PYPd<Zim5s(G`!wG?wl3<}! z(_oe93Q^fkI$gbN*#kPvQTA94QJkfqK~f&}NEPRVl;*s??55Ej(lV^c(ar^F3e=J( zjun=-v!vJ%?XT(_xnN}8LCpu4?sN_@&YZ+91!JC@UJ?N{FEhD2X6}H<3(~73=s<cl z+cTPz=nRl}c76c?)L(P?W?H_PUb+_EOy4wn<YZsL{TFvq=w5kfKC(b;s{Ixb3XY4; zj6&$DpT{0GF}1aK(BD;F6Zc&6j+CJNj`)~rrhk^VgACuPV+mc--8ym1qT5l9!@C2S zPP&17t~G~o$QjHD68uJ7*49OKqyB$-??)UL!w81p5V5F1_oyr(!!Ww(v~Eh5Y|qmQ z-WKwrgM<hT>u`b<WO|P45by12!=xaDTUip81Mzrq=U{t=ljwfIV+A%rz{;gFnkri) zAiYb=hnLwK_v6iFZ?6i#{jqhf68{06kNfxd;3Y41_zR@VvXgVYb60LwA~Jzt-`y2d zR?F>hhOqS(ZNx6r2}Sv$M?;9dM%^@$Bay*VF^*%~2WE{5Ma&NZE1Om>2%Jqt5X+n` zb(3=Vx_nRS+Sh}peC>!GX?#mdx0wjF@r*=j;@(fE6@`K!&D7ZOm3e)gs-{el$CQT` zKicIGD<P!~S7A@|@@l4jx%h+VYM+)O=&X!p_*KTN6V~<^?))92>B^*rsxZ#5oSpzf z=nT@NQ%cA&3eK_>M!=1D-1k!$AwczMKrDRx>}$1J*j{m1@|ekp#w-tR7+w<*h&$^q z<o+Vbb>vk+tO=4lsS-$ZKtYaB{e#+{pcSL|A-zwK>Qz2BJ$~JM2*IYilC20jAB?<T z-m5R?Z5jZqBpmRlq5y3YGU(pH&GBeBb17E0OL3?ativmJ5rcxV2Rih2IW@S)#F7qy zc`{p(Y))pSh+tkYHgRx7%WSh~@BmMmDD2rN#XM<P)w41^I8(TAI5y8CP<9;|!7*9R zDU6c)1LGl4fY_{}n?XvFmA|c#eu+C+C7qQazMa=s!os*+6&a?>3m#mGKx$Sct`8z_ zb#`3h_S`ftZ9Kx#><&z3m?4Do72JJkxV-?yz?1xDGpJ3Tq0`0z!|&Eflpp+cN^lc% z`!{|xVdHpFi!|^LcmY{0GB<gdV;wfbxyKoFm!ZS3rgD<6z<m$O9VJZQ`Fb*4CGFfz z5}$ln@?i8HSEr}qlAk99o%vfJqob?IZq!(2D8Ai%lB1Ge!ye8QHz5bP3L65_kYL`4 zFvbU&7u4Z*P$Et7J+;F~Y+(kx2X(v2^bQ0PJx!qj!F_R{JD$R2C#pkGXb`bi8pFZ{ z({2lAEj4=3+6TTKPz3Gr*;5=A8uuDs4BJFJFW>l!2;9zwXTwF=?cm#X$A&o!pH~gv zeH_Nhi`g!`l875RVx(ToVnui`_4EWNSx_;9=+^-FAH|<^RiOzG@g&N29cKH9v$=(1 zaxGlLXI`**MIqvkhc68yU(OumC20G<B~baQY`P}$3D>de2^<Z~;e^1PY<ftKp~n(; zV|?ZQ|GIeDOPc<#Y7Vc{pQBCB99pMtHRsjo;y=r4Rjg7WyNX>$qr60=5M)}x0$rM< zFs5ag+pQO<A69&nJ0klLAY@|}n`V}lN=c>yf<ckCaG)OHoY)~}fj~H{=z3Pad$3kM zxKFNm5}>vK_V|m7+2Z=y$uF+s9;zj%s%@2M2A=$G5%rse#AVfGUBFhp@1aN}>njj@ z0)tt*{bEr?S0@5&&ih5xz(h85RG;f#m+mhD-$#y{myil$Ea0Qom<bZ?+05^=RWn7x zWrIs@HkWyWXjFTmsN1W0q?($|twxWAPkI4h@KB2`54CuqVtuwh0qqt9qQIN29F-ol zRV%!d3Uk>n6=!~{QREvwXS<j+6io_XM_g}ojtALI#AE4KPjNf8Se*1Ro3Lo+VVeRg z?GX4mW{Mqt@MC;<6H`Tg2}TV^+v=OKs!6(bwYNwH^!WyXJ)8DyBxSO}2p)ZGvub40 z_#kvX&@1-xrf1#<wlc%4b1G-~QJj&c&*#J6Cc<CLm|6&5rT^61Pn!%t2ftye-oT(u z{bUdM{3#EXR+bUxHnD2^X)KZpambs5IpsKGV%Sd?1IQBrzj>RE1Xjt|as;cH!NYx> zES6i@SLI^kni^ab%qs90`>r>ZEgxp_iunZNcSHZi60Cm+1(Nic9DCX59I6?Z`(NaZ z)0tg$1OYhH2CnyfBLwkaTd}v&*ef#Mjvu+O5hEc7EnKoYa9nt0{TzfLZQwjWE}$09 z#kVdgZ`;@oS1=ki@^NnUE%@muT)>GGW@aBjwI3SuHNP6ZW<yga`F_o2seSw^5by9= z{yu3jw%exY#e{^YmaDWq#Vpj_)Fr8hhHCOl!H&IIY+90&xFr8_C7(`D0hNFd_KX#6 zuI(p$|KY~Pht0R%URct!eJv~m=q<BV(9KW6md*e;J{Y<_E#k}Kkz`jt%@aR}du`ce ztT49{{%L!5Te}p_)h<Vh@4$USkQ^t5#Cv|VnGl#<gJOT2*r_sgC|N#tT#Hb9*N|@N z@FSsF(;5`L?ZnQysl(7AKP=P%pIxv0K7^5s_9|XI%>Kknh(Bl6s;T@M(?yE@ek>08 zlQ4$c(Oj0L<!T~1CsUDeedS=atEyo!#nxn5A6MjM*;RFsD3eqrtlQ@~QlCK`aB%@p zLvnSg7M&|0>IZ!#&9qhR!Qbh%Kic-IM!*vZGOEdt*^s>m*>~-j*y^PA%a-jMULx7t zy}9hzs(8(eC<XzZw%w5#^IbFMBpS-HaHT{ZzX_X|hD}gjY=OiEZs0t?c(KCnyHRGv zKS<L3XtV{ZmWLjBc4N0FfU3rEiAybzn=o|m@(c;?j^^iGOTDl1yroJ}>q(s+a?+k$ zQY+_{YOCo+lnM*yN<G8RP+Cnlqf}YCR;p(}Lh1N2R>eiI@<odxluDns2&pkcq8)!J zwlJ4(F4@Fn=<bUnsAX?TmIeA<*fEV|Zkzk@vipGsD!X&dSVSe<x@u{`oM%D)))ws9 zrF?)F1Uy__W;lVHh28e<z@lGQGEXL~7$|w3vWD@wG}$sBYfB~_-P<d^tgb-Ogf_nA zd|uDNq|g=HV`an1@~rsNozFho7agh@Zn!kt(bV5q7Tf{l{7gtvp6HqSMm0leshHHr z$pCwH+rsG1%Eh;2iS_Md*?f*($v$Gy>TqmmRod6vDH?W>YYKTcHxe*pD~!KKsW0jo zPPzm%$Yw(8t@YW+3T%Bocrlb*kcp^eQ?xd6IoZTs$Y+p%3M;Z`M1&Q2I3xs;=O4Ta zvflj*n(b;7NE~*tUbMb*JOON-s7`re8eq!pgau_R@+Ivu`rYatq(;I<mtS`n-9yYI z`13)K=`)N5<24mI6;o<(!^S}ys?UQ*j=;muUCt+TLg`|T+-AJvRPvN=XJ%ts0>f)) zek1MjarILD6Ub`jd0AdG#iYVGZ@`%#P8D1r_{@WsPrsA7D27gOD+AaZ>c1~t>3Ip( z6vJXt*Rz4K#7k=llz~y2c4IY5>Ee(VR-*|YjO~pol*>5w-fp&Q_5pK0u*=aJF7>H6 zTLH^7P+mM}c#ViOs5TLKuf)XCqF=0YJyc*Gc%{}m+=^!iyBL$DDR%d<*IVNBb`;m; z-&cc1&3vqLcXOk9kTF@vdc66(t>_dPU$<ugeqTp0D^ka~XBN@Q=MztYogMWh*xRFB z^cdqJay&$dIHgO#4iuYcqS5|~T6Em>wZ-z)LMLXX&)B2+wMI|5WIK`ANx^e#_+a~c zVW%ha;=kjHkhKD$(_F5o5-+?>EKx&U{i2z*N!mvNH8gq6OePDShnd1r<F8?sq-l;M zcvSv?WZ_C_X1p@S*AjRhsq(kVYeQDEhAgc+SoImp3T)6;Ty9o#;C?J`{DUTVhF1U} zF($NG%QY|d9<!*q{DVlk+?b^4dyUfcV~o=D@(&_uvr)1F6TXKT>ZbB2#!x|k-!fUc zl}WJ`sN$)q+dt-$-&c2v4;b?3?_Z<E9$=c<0rb>Rn%V*+5B#~Tk|!rCMCKjhqp$rS zqH^LgFTU`G&Gxrb$L>IfN0Mcz!L$1}v!#PP--dO^pEVfpHl8MXpAvYD*l>RVYlLJo z#G0{_1l|}O>yX{y*Vs-UrGX~Ggd~q%e=}p#25;Y=_24$IHt?oxEJxYo0Ziss38npa zH+kr{nmmx5{#%<o^xw+lfpQCgR}ok|1PViM>`;V;4xv6$jT|`U_8)BF(Ep#Xa0u$> z_1PuhIx%S=G&0sxV1FL88aaTy=uJ-ojg1x1M=cQq<A?9g4C|xGg!4m*&7z#8lKPf6 z=rd8Cc<xsW8|L7F)8IzD7*-UcEKxa%w6w_-NePbIw9!J+fJfegW`_10x;w244el+L z^koZpy^~+?R{3<}y=LfNcd3*E2riX$Ui1;Z3*T7aBO>`Uh}Q>U?FyPP1SfP8WgUw$ zCU_=wjS-%~hU^)}8#C4-<gCU{T)As#i0}ET-tNHqz6RZ|`~ORpaAm+O5{<?ceS03v zcS=9oly!u9T0=A`r%MVpJu0N``V;}X9=LCS$Jj-jA;-LmJ;MKBO*IthVLo>cRb&uT zpdK0f#Zg)0RVhd(6IISVz@qCvl<`&U31(l=KA_c%@Fhr+y_KS^STD`Lo15akxeV@m zBeSq%Y@f5DtQMx>cx>5)3Lt>xr=<4VY7DdyL6N*Ie3(V`9v1TuuANNTH|{WH&jufX z?dB-Dc$Vp8zzL7aT6RS|CQsYGc+2+LS+?)}YaO2m<LiQ_4tnuxzyXDQ#Jvh`A4OKd z2{z<hlC?lRGwA7Dt0KX?bhpp0qTKMOY<_E5<@HTkmM|2(%3_9E$|7|7in4oU$czJB zo8>gp9UgU${8rABRC9ei(#NMv7Jb;>(%0iygo5DNW#599jbzn`wT!EsM#;YtXKM*d ztF6ljtfn^HH>1*SmQiiOB9MDU?J>cv+Bn=N=h1TKYsWlR7AJ!7WsN{*=k!n22*_>4 z*qhL&DZE<X?tZ=H8aok?nNEt!c62u;CCyLfJ8rUPyH4l|@}4aztw6LReB3O-iT zWl2K5bq%8s>?P^<Z&@}C!hW$wU^{yS%lfcJc*~2!qzxxHVu1G0V12|oqq~0bi6;^- z6R^p$_Uoaney@nXu#6kkMgm2*$O_xiQcnN{TJy~$qp_kbc<Q{GJh~{PH15%t*x)Li z3$=YGAtyuCJ&*Dh3|TVF3j|Qljq(B^`m=+a>4B)X-eQ;~L=2mZ9vbN`4imF}P}6xg zMl<g}sA9z0GDv<{8$~G2?kz7(-Mbe`bg96FW&;r~0`r17|NTaE<sv@iTg+@ezmJt( zw|A4a?7Z8sIl`!vwR;1Lcp)Ce6_|lE<;Bz@8uFt=Z=R<lmI~H3ofJ?zHBgJ!Bx`&< zT$~RmB5JBMpq1Xutn-9O!yyjMO*_sa*La$p^EE`+{kDz@*=V%eGc?$p*bCMNjm1vF zs_v(A7?@1AY|JG4F12v<$8$~31<#W{a$A{BhGyGs)TIS>sg<KYo{<?ZuqdbPM0|SC z$JpflXeDEe-2jeOErh_({%GZ3h9>h?#%pr%6#|{-$CB23uakSnCeoF@{oUq$%^%oj z8QP9addYUed=DR8+tixpQHdw^`8?+<=3N*JO9`BSSj>}CXj4JY&xL<YCZY7aPWa?* zcpDJmKN9@6L#UR`=zcr#^dnOZsOmYjRHW}$`17?&srOL!6U;Hd7HM<wJ>NXSqDG3F zIU>~pVaP_{JFc#|Cq1WQH4giz>MRm<s&Uje+R#WB%4Q>01IjM;NfxhHHFKfwRmsJX zpSG6OhkH|DLvo{A_YX?5I4NK(<8orI(yN{!>Q%-t>ElKnn7)`>c=lbOj=j)%I`YpJ zwRLSbs*sIVTe95x1+ITH{;L-r7U0*N8`h+|bwK7ebW}H8xBpU{y$A=@{qMNo7XY^{ zS*P!A!G|l7`yBF1lrC(#1rH<8TSrLWF92*nlfSi!zy(w>kGS(o2xQg8J|9EsOB}`? z7_{SRupf`SvLDJhmIwbhL1y18`zbC96}pG%);HE-V6nOecTJ<1KW49F58x0<ECQJd zCgx~E28b}`D|p}A?aCtAl44TAd&0kH5q^5KAN682si&o2!boNqA9GgJv*8E>0qqa& z{520boR~n#$=V4I4mC~*cCr}KSP1A?>67TSk?*yEY0zLtSrmYTM+99#5aF|f?r!wi z5wG64G9cbc$_P3=b*-J}Y&zd&I=!!xv}om8A|VS3-7?HEC+&xJZvop3kMhkV(zoo4 zzJo_D%-)?F)CK#!AdrvgI;DDXW25ahug1LFR!mQ1I2me5-|<`w_u+dUl|xBYw;Sjf zeALB^zYUCzTg%7%y)Ws2@yMT~jvs*`!yoR9AgCNo`bm=xY*KwCcX^EF)$JMsIDhi) z6<B-E-SzMfDtet3%^mVo_$Mj+6BeG9m*UVU%|HmfD@jyOMXd;uui2QxIEJorMUqB( zzSxtD8%f69NGZ^w-Vt<_OHtCI@%>!wHso7GJ|$}ahwRAvxO^SDsOm88P|hDiACs>m zZ&W|9od2gNf9QCsweRL@k9<sh?YlwkTww2?h;I6(?A=xmq*kqrG~IRs*R~>`6xYb~ z!#9xCEwI|kt@Z1ai01NR6Cvt!z2ntav075XUTTO?Vgz^ZX%J9}u1w71t`Wy_hVyWP zU1vB?w^Cy`-$I0q1-iE9n~Z-L1KzR_YH+v6o8%w8KM6aAOYKJGZtNI@!<`?3?Aq9D z?vo)9mPPHQBXAit@U8^xcqYCZmb(ehcN?ou4`CauFBh-xaW$OOXaAbP`o>86zfPn+ zj?E`O38!6uj_1R(Gm^%#k^NLvB_F)__A#UV>8j$Oe-H*@KqKF24f7WU^5eUJgi)1H zd(YhGLwsV!sHZp@8r;g=vzqeR^owRRoRvNoeug-luChn)cZcH00y%hTf!hdvlF{^K z&oQ*0SWAlNPoPBa6p-()aYR1;P>+Wb6X?%hKL`f}Zh<32@2067E}{?hDcC$f1a;Os zbFgNY?X=?c<0kcsX#@DPu%i~$Vp5)fN2Xh)lgr_CQ(!>a35N4olA&Y}LB6nx7RP7R z*d|ndQr6_jO!Tf=&W7WT^rxZ<5nujYQ>>Q@cdzT(PaVLF`#Heg`k#DF`)ofO^Y8=% zzv5c)MMmMzF#<r^U(dtHi1bOKBlgkrZ?tUu&l=aV{EFi&&KW>Cs8c>hF&E(@KE{^g zXLc9q{?O$tcUS&xaccZ00nU*x1_{T1iZWgLpZ3BIQ<9_X!!*1y_Fsgw`lwN?I#sL$ zVdub1h2!>ehW>Wmk<DiHI+YkOD3e*UWI=**1r#o6yTwz^<_-|N+7W8WdwHI?M5ti_ z-Id7uEgu9<qp$#&xXTwtfhc-e8eYH_jN`cs7Yl%i#O>KJ@gW2NdtnQOAH}&gsNX=o z(W+qF_ihRyhl(o-MzHPC<{yRxh1xBQXGAB*E(k5qS%@Eq$DDl8QlifiXBU>6dI^m$ zm=zn`XioVYcks7E(jNw}VG0p0rxpk$w+E+F^Cdv-gs32oB}tI%ay9yp0aBy?lGLca zDKS|5tEz$1I)GspZy?8KzXWDzq9g$DRkDLq+C&Hl2mwyo4gH(E0MTxd9WN^>bL4}r zmTIpi3)Tk=k}nb_s29a#y=~wRWUvj!y#^xZped3Uf^Bl>_(A!<#lUA(C<zX7>Li@3 zr%}7JqX)5_;+#BX)tg<1+~hMSvN@L6wvA}-d_S$+=sX<<8|oc)4vGK?_wKO_^Fy^b zcNZs!ZaZ|0XnIy)*rz^9HK$JSsUc=_aZ);YzibM(k097BM0m!^shI7E?92fuWxI6N z;D3vr!F>#uW5CnwTFf%GezuhEmnj8_PuypS-&$@93nIyeESRcu!$Z!=3%5oWb>WV& z5s7;=_P9zQp;|QM#C7LSfB)OTXT5E`5??KhM;83_=9|f}Q>dQFl_HrbJ_uqBNLv>< ztXZx!uYFo6Z7zYqJj!-q2kS$}!=^Rb2ba_E!?s9u?Z&_E&QrZEtxZM_0$5O*ndiyT zWPp&3Oeqd1Y}|+JvDHN)$4TWo3Y6v8drrvXT-(-NvERdv07ot7jx$X#NJ!@po5G7D zgjplrZDFR{qhPwf++e_E5-!7?@26mwRGn7tdXI299XG_IvVr@CcUTBUy*QoM7f|?a zbvhqjl=lhE{F?6$VcvTob0zsG$l~JxJ~!0%-G2`DCFLmvz`hHN_&(f_PA1Fwyc|O= zch7>@*O%2|bk29KhQeU~=`Vl1v+u7uAz=^|%6{;%*%tLz^<_DKG;G{VkOwUv0P2F~ zNP1F%lCKyRJnKnxZozj4QUROehw|h<tA&<tYWN5tzyZGlLwQf@1@ceF53tgr1_#}% z*`yjd4s}g6!8j1%h2i*EB`8^%!@a$e<ykYhEKh!|7O08=q3V_UI2fH(532FKzx?~b z-|y%>FC3QM09xq=w>n29jBS_kl-w}fgc|}wF@>AHAD-oqqaQO1_6YNvaujaI(7uCq z-AazbJ5x%)QSqXFk$KsZP*0q0<epp^aguJTNyv;K^H}%*G9y5ys75|En?K9kO&&0L zI2xPVLQdZ23qI`Oi{UJ_py0mk#JBO^cJYkqsP7Fv7xt8b^6KlMK3us=3%jDzy|qvp z4V&?$?%ykRLek?lgY&f|SKrjQQyeg%GF}pG$D4mq3fO%GgPh>k<GzSih+hO)i%eym zTP@~EmjfFaDMA>#iDg$LE2Rj*w2`0}!;=#)bJMO_eR9YM818OjSFYfe!F9zWcQg1< z;4ft_E}28e_leg9iC7ZW%c!PmDhzy==E*TAR9V$C$8g<=;{}?2apFY5dg{2<<#{=! zs-S;v?GK6<rZUHrmXk37w>Vxlgz#5ZGIEVUIpC8pVN}zF<Ixj$IB_P*;t2AkQFAAC zxZ`y6D_Z8bHm?Vv$jEdA7Z>`LtmQTPVOJKonQ6Spu4IXjqm3ozR#nU_X)Aax$<f$A zkO;={;-YkaE=o5g%bB}=;E=(5==sBE7;UO;KAkQ~M_*Bo0QwysMgVfEs84OxBtwBD zAZK5N$W)Mrs_}Cvr)2j}2m1$qz0=#am)0+-yYn*zP>T0G5Zy61uV8?ZT@JEDx!_*$ zV#P~Ifk7n?Da*m2c<4zdB(0&R6zrF)df7~_Df^v4@g>%gc2@d{wZq6B!@U?QdP#*p zbBmv;&6Srcm_N~7nZK+qL)ygIaLQx-SK42AhH@e${EZT1F7T$otnhr;;MgnfS17_N zd%UF?HAY)lFbX(o`rj!+)rM9TMMYUt<Kcpb;$7>LUFcOfAG~VO8{w_O2<soJekrWQ zSRWx50NowGmgVeA(r)K(Qu4JJotLWn@kYX{Mfm;bNFqzCs(CnKPp5!rFtveeRahql zwg+oUjntPE>lew%C#Ui)ZEdsD82+E*G0pMc$K~m8Ibla+KL~`ZV;<?lJJdGcpuiH~ z?<(kXm2i%s_Ct9o9gg{Sh0TKSkL?%3GdBzc=;r6<$_R(HnI*#l1AS^<!c`ro26eyR zX;-0o1yHIAf-j?b?!=T`H$sI-un-8|fC*}pM19L+4HCs_rItYv^SfU8$_1iJxGh4M zZg3nl%u`<%dd;OqIMZRV%K&uq8n}Ol-!iR@WT@;_{bRQm2v8ac+@H}%+OOp`L;-Kx zJ~>Tj@Y;!zEKPjX@SJ~3E1(>A5ha;YT|<wYOyfSVk#G1JHVzsC@Q1+{&mTSf_6z?` z*S@G_Qjo5$6_}$?y*GOQmW2%b3MK`#dhp~<vX<|6NaL-T#upDi_fF2)?ko8r9r~8Z z8#uj1WjHn)hSTwW&zH5z5=iq|-MVbc2}vDsT&2!-!|0+gBan+N2$Qsg_w~$L5RdOD zf<15ZG}1El%CL7I<ao{88*8gv53t_1>%u$s0LJQ_I^aFt(S~Bv?P#wxk|&}ycSxA` zYZaw`aH4I~xHFGr!{PM0D6gsp`PFb<4R^<7Gn!W?<@n^f0Ja7uGwudb4iTz#j~pDW zd??HmE>gq!uV7I#)9VS}mB0e$vLda}$s8)g;39#TIAjiq?axe%WmXp^(pW?-2xYmT zbh^(BlkUWYJJBoTQePQF$zF~5<sh`Nj$YTYck@7$N}mLzEZvp)L|gSLs8$vJL_05s zV8xUiXk?bXJDQZk`Dt|})w<=``fk{Ij0l~4oNTay^`$_V@Muywp#VfQBhbSG!QVgo zdryj>Oh9T#UShc9-1?dg=ZlJ7S`g^Ntu<!nudDJ>%8!PQFj`C}Y+vNAOH{($6x?;g z{e%L2p^HF=OD0clj2f>n;x#=we!yQ3)n3u8?2^LIZc!KqxirFXoUwpFQWfYF3Vct6 zZ*DO5|MpqW>}`KgSdNp~+lf&3y&GdNF}v4cn=X8=;kiJ=p2D4P?n46u27#-~tHnuu z1&~;v4u_ub*o0T#Daec6KmFsg1ApnwUKnIe^GqW#pU@A0{-wWkwbM`WY#g4Hlf#TW z@<JXVx2lmEdmuJo<rolHF}X>BB$^3V!RXfxjTt+ipq&=#H*+2+xvi#?y6V+kH}WRC z2#1Ha60W=UZM5o0X%mOc$_QGP32EFNTgQDFzNxm4#5(?w8v!iX4Vhq(dl~ionb<Qf zfC+Qwpm@xay*~XF+hF;jT$tC>;PJ_tdB}Nzm7gyz+;yq*=RY0%ZU4wzZz&ZPPd8^O z5?^BcoqY8@#^>Ak0PtFp{G}%4`gXXf!RKOCw{d%JE3Mf8rYord3MJYbeeivqR-3{% zP~O<6f<Fr%bkhvz@e^15_?lj!hH}=xp!ExSaWC-Ys!fq%qcO%KHz*-~t$or=g4znH z=x5r6<cIS)+<Scj$k6;tK@hW&OPi4c7nUcJNITC?ozkFD%Oc8IU*qn2Fl*pLeJ=3K z!^3M7Vd%z}-dvN*lSAt71+y`VNL>(@MLe||c1o2nfOH}fBZDJpSWF$aZk8t(6&;MK z=`$@ebSJ=cUW4hao@qCIA99eYrf`y8y1ZH-#G^mr#Sjx3KcS2lpr|m9kCgEqRXxC8 zekcZ#np_SrL7t{8ybC^i7<gsj(?@<?^N6cMH6L%(BL1-F7kvhWI~<6<E_h6E0=6lY zewI=Uv!@5NIg)iy2}qug=5TFDqGboJ$CkzT_s*ExuV6IRNH4Q9R~Ws?gQqn^+laH& zI`&DVNYyLSmAV{%U%_z}Sz^U5o#4}G9RRn;Rv8oMPlFPdjE<Vu(SbMu3koL;S$UKB zeZOdzLCK<XI31%xDU+|G@M?_N33?}1iFO!@IP`EX6o5d*6aSE#ol}u)g-h|95BeK_ z38ofJH%RdBBWm#MLwhGvz`Kax2+&-56{)!vHmp30Y#me%%ZhzubdCe8WVJk@y9gjz z3eF~DB>Qp(@i;2RPy6iAO$XpC1`#D|erz1A-034)^pofRPSM3w@WwA56rG(8IZV3* ziDsdCP$!T<B~S*)$`ny#MD!6rs>x_&drSG!mIc7cpJy#gWjWn=vG}OV?b8_wjDdaW zd$0<#*BbPaitJp)J7Qq{+u^OM@H|7jz}fF-j8`&uHlgWtb6yh9aFxJ&w7eFheB;is zB|LgE2wUM!J16+TgCAG!M%ALuCrU`fB2iZ!T9xDp@I?E>-b&iZ!0(>?)+uR=j{DBE zU-p~+W#3(Nn#;Zuyr!3(w`Qp+sJ(&5_%>v*0Y<*bre4~s7<410;Ez?z*?W?&W6taO zt4AEk#18Q83bLH!OKjY4(yjHsdNOFbL{H9!AJz}dmUuc3i(n;upmRY(sK52OVBA(V zWZo_Kt1Hij5Xk$3oDL>VE{aLKo&s1ch3J2$1LU1fj}YQa$r6~OqabsDoThmhH0kL7 zi>Fe{Lfz<8^3GHno=e+en(mo#Uzxa(aJ_#+iyfdUp4dN90vMc<cC}sG)M~*JJvLaI z;6z2*cG8+ETj*ZlCV&ZUA|wsWgO^i$y)n<*97Z{;CVQ|83W&E9$+SR__wYo*7vL%1 z<0({)ucPN(Iw&{1A?_Zi;hkh0G+_H$O18eYv$9ibiP(&I-RKBFWf!n!HJ~oVEkk)k zp+{ifxZ-3Wi~*yj_?6%fo*b4-`&Eo<j2RaQBIqtlVu(5H1PUBJli_IP7JQPSA6MxY zk{1|Kd#rCtvKxf!w0#nDpI{fTRr7K<5zf!@obG2ry^$Gh{)<d!6XC1^eqao1%_M4> ztm23~&yH-QcTH2f%21aU@S4q9Aw!5@4ZF^&FQ#WSGPCWn^*q20^`Ai6GU^e6Y!d~S zB4_!Qel4&26x}007WH(6Sq!MN`%Kfs&<LStY2mGy11RzU^uboq;-MPWV|sUtr2z{K zNsD#)SpPhNObxAOvu3lQ6JE5ia9`VNNw3u)+JY$2uy^`JGD9tE;c(Ri(GF0h4Itlt z7u=nU-A`mdwr$28d4aLj=}12$J87(fvwpRmkJX9ma<OLKrdc%W8FyAX+B8dW6-}34 zSeNLyIxTP6D@}p2)Op>ST{o$2K37)X-SXswHiE$`o;AAWsIG(qFoOXe7Ic5K4}KjG z>2P3jkg9&L6_!HJFTZ+Fm6BcKTCCTxws*EHsO1CJv6WHFIReP@sgnZV+=^-oD{FO> zjS!NxrxpwL_x25*l=C<oQV<@;!Nq6_jyGO2L2itocLz1Rey1_@ap79WG~gR{Ouw^E zzHMV_SxR<H+o;Bvgg`Z4Q`;J5wFNaFC@ogfqU^21^>_Mq|L2GchR+OZIHbHp0vf5} zTd}8JyAO2RVv%Rsz|(|YV6$6R%xMPcOK;4^bJ%;{jco~b7NE|e(`g*|Pr%>41w`dZ zl_g?g@VX)Ix0BjkG*P=ncTOn9;u!`>Av@D4%V4fq61gtKSGk@(qKZYvb8``Y8D527 z);t9``o6<<<gt}*hLN{2i(MY+k?|coq>EL(?8myCj-y<3_mU@)0Ah7calZ)f=RE)M zr9CdEoWpgD2Jn(hZ+*vLN=kQMy#RzFm`9!hx1+$u2)@9wkBt3cGsY8;)j5XH!DfVH z(1I=)bBzE&{D@#X;^xFvtm_6j75V|TDkhO?idKa|X^hou5n!XgX2gwZfn1|>KcRU~ zCpo?4<b1*XV4Ag+tat`y)wP!00MT@qV>k{Q9R)(q5BT|tjwgWWA6`1`=y-_Jlht!Z zOwOou^7;w#4*ndnr8jTprIe@50TKmW%wbWD=mz3Z9RjNi3*x&XKDlfesy#sE=L|Bj zHiwJ^11-ldx|~&DS%e_gS!zwJ!Yq2n`!7Qm*HBTm0)8VHT06fsAu!93N9`n62-5** z4Nt+^Z8(arAy)N8b{rcS`=zF);<0O;K*4hjW4V7v<|gN0aX{97PUfCfqhB4PtuAJs zWukd49hKyY;M%H2U=#R{zyG7>6(G0P8zpKBp4Q0lhTSLgGZI=!kpp7>RzpU``1(|! z#k9KMMQ)bV>R3GOsVE!g)7{_`cTG5}*<1XiEa+urLS~V7{=Wa0o?aB6k^5!rb=qRH zZSyO>!A*il(5~s?ZZyJrSoCB2f9yRRh||$|J#SD_siw0f&M6sULffy9Ah1LM??Nm{ zqNO`-&)xnS7sJuKZorOudTkVHl~mIVPfL(0!NAqXR}K4wLbDgkW`RQos{tPnfy6n` z2dJH1C{)FdbXr0ptW^+;kS#;%?c%NHgT`UC&=v7k%$T#U_Wo$s1e05F-VR<+<f98^ z;4-_`7LLvAB)@FY7L&N-MjnkiSCiUOcf6xpCp4YeV0HF60@KE8S-|@bQUIV2#2#9m zlTp>nq^#FrTcUT11Ea9JrIiGiCaH=Rz`z|sbU5?!mXmeMMh0kUFojv&cs_g&?WHmB z%MK2-Xh{mziVx1Bps5LB>hpTO!0Y6{BxY*E)c@<CriLh}jG_8RBAx=^sSKN2Y3Qzo zM76@7Qo%2PvAUD%w7PPsPy?i)v8+c2Z9_^WIgqeYud2qtiMquyEk_GL&I-SJ+Xw%3 zId|>a`yPFHXfuuH_3YUcjcPqOBl-<}3y4$a^<+%JW=$DPeuC!DQ3}8zo1bD8=RaT} zN0Qi#AX(L-ya4Rh`^Bdn!qems8XiT}(_+5jp=&!sukQvq6n{SlQ07JT8mqjsZxUu@ zIrg7wG<Y4;VTgn*Y9}_(%Vwv71GRBuk14;gJL$oG9(WY}j}gjJ5I+g>AjA<x<(h>e zEz@%D`e1&%h5_&(qNB2U9YBo&m-D}y+G372Ap~g?kV2u?129s+9C7VEq!p+e<qF;+ zPD{5!A+WG{B;l>&a)6zH<{=ww_<9$gRpj%Ilr_+S&6krJgT~tiVR=MN?17=e8|1Bf z9M%hRk%84I)Y0jYP553lb)s$g1~>372)bzjMhWfoVypT5?NsBtVW4_`DT_hlY@`+C zAL2yxAN+2K3tx)5k#SdR!L!@j`>I@g(nM+@VhrxH8n@C}=1pD<4L)Kv*7tN;fnOJl zIWjPk3L6xaD=#e?l$Rw0(W*jV4Ob&sC}H;i^-3G~0k0P14*-v|weJ~x@&Se4=Edr5 zo^y!ZM0(jg!QsnUlp#Ouk!$3@Ozf_<oZ7dfd5+AhDqX5!8Ki(NlFH(@N5sO4H0mc; zz;vxF(kl*qi|NB#JGnROkt<t}Br{bPwi)xBhox4IZsu9Boo2I&9}~^IQenZvE2CTX zvSn}vMA-n6uS)`3C-?8}Zm1@KoX6Em8gnDo8Z#hRLtsU<3wb*JDr5l13~HF8@6mAP zQZf<ffZw|#m5l=Z8!o?wJcVhzr###xO{y{F4PN(iK!?0D;RJR3HdL_q+dJj%Mvu2N zWgfRzT(q3XC~rRya<Q|jR^S(ER?EE4GeuC|42v4h3G_JE`Q)6?^M*!A*w2^Mlsr|d zQ}2Z0s04JrqU+|oo}&JsS~Sc@n;t@@i}?s{ifU?B1co-V8lav=k825C=f>(bT~)|( ziS6Mst3ty;t5Zubr#8@HGJxLb%QR@|e4B>jc7y)fMR3dHY@OM3xiIg+$efww%)#TL z?0vh$d&CtwpLWp7^>Zg<wT-{Dj-3p8;sfm2J)(vsR&RlwHTfb?y-c)Sk_&=?G{26_ z>P6N?NzIq@`hpfRHXCR+1OD(lvIEX?hrV0s4@rD<c}$SJs$T#KrHR26J-AuwABk{d z`33G(gl3b6K#+B1*NS;~(+|{UcBfK)c(^<%%c;kLv)nI|gS1waFCL*xhBs%rD`7Ki zu*ETNr4kLdYYi~y$`W!7lHusdZNhJIrFW`?R4VqZyC}JH#!~dD`;WVA?-mNsd<JlQ zbiv=H#24p?Ia-f?mBbPue&*MN*r}Fab243WwN)VCkz3syIhGnkGy|-3FD9LW05$@$ zCYLMYX=l3gHD&I`!YBd?)5Qo0Lq;b>>AQ(^uVWk}X{7)g#;v=~sK<o%wq_f>;aLgq zXUj(VkQZsqW-?-JoRv;#xYd~NYNlPm10l9C5SwL+mS{7pA-Ks6-?k-!sk%s-QlW$S z?}ghg=OrT`k`LoKE?7XFRqqo9m$OK$L=LNF-N^hXlo;YnWJjOzrzoRK_Ez&jgaC>% z1s|SSdw8MB<ob?3NxlLmwQA_Zw7p0tmnPI0W@?IK1Eb}HHwbYQM9c$`OzV`~<=Ag( zkH7E?3K44KB|K!%;+2WG#P<xcTCv;u6Yl|JX}0f2&lg}1Aq?)cIs<zukSB)4<q&T) zU?Jkk1gVpEumoGN+amP!>6>>%zj9rk7~4Ht+HY0jAmJ{TY%4-V$gEOvNl;E07sR!9 z&#uI5o}Yp|KQWOH$G^by2tjJnn+@*Ic;z#{b<$c#^imyIT>!8#smigdtXmHxiK1en z&L8WiWeF!Jb9JA!m-2SEzAju_kDq;=jMlimurW0dx#KY9I`FyMLu|QVLj`%52LkfZ zjoi9VgU&Vp)f`M;zc?3MMx9YWcm}=+c|kLQI4#rb0zk`(@p3LuDsV8kHIL{obnv=d zbgrBX$Mop!)~*rChz=l7f#6LKAONzt>)5_o^J9A&BNzADxd@KH=n(a20EgvaVN{l| z1kNfzy<^L5mQ9H4dSJ4~H~U9EDX`G%7P1^*-RR%90_%=~%*r647AT}Gkd)d?4j9Y( zD1(u%R5c5CXpbLJwf9i)VpkJtN?tnBgubVfn=lnVSLZ~<7J)DKKmEN>HSdm;-{};$ zstX`(I9(hSH+T0aGw3J$3mWz`7_@r8npYki{$)l-FOHT?akfq`w5KD&pK%=-_NL{$ zWp`^H7#txkB$+g^OfmgfM=<5e)BE34Lxx-_wSrpC0>m;|X2X0tFM&aL5zA~#D?<gF z(?Dk`2aGbi3(gr{@o;rNdGYmEofw(;bW&eF3j``#M<7wj?gn|?Dzrmb-A)tw1+rIB z^<)SNOxfw*m7^Bv8ZKCDU<(#;^Vg}69U4%#%Hc>cjW5Jb?uY`tBkD~6W8xFKP|Yp# zmg1JZGKrpt^h2r}@`ctZh$8iHbL=v`w2o>@Tz=r#N~wr!PyN!-j=-zU3~vOY0)V)D z<BQ?c9mEncI{YZy+~Ak%({Y%SuIdA5<MZ--2vEi?RnCYmT3QXOJiJihuf__z<(0s} z?#Zgl8DXcBX!BfUBD%Ou|HV}~TJlK*?U2@p1Y!$Q#w!rdUo?D?n<Il!3tkxLhuqC; zUXB)4SZKeUKMoNQh%)bP(MQD+{a0{r3w=!z$LKoe>8=25HuRF)ob|;_dQ81)60v6X zw!)tjczEJH_1sbh{h$<ar$!*f^6H_T3~-I#`a10Pjgq8#)1u)#kLxUlRP1w1^V+tL z#Xd!u)Xgwa4o#b_jd-a<Z{7_qX?NYZkUU9-5R-9r>QC$j&8&tsd3St6@WdGbdv<dd z$Fzfg7`3}uYFEzyJ1Vc30uHym8{DVgxldn_yZC0E`idj>ZZ-!$w#)%`@ed?;#WYy+ z3Y?S73d*^_uOUAsE>lH&)e*Tddab<2fG4^-*}FoUlKxR?-^tUS8QvdTXe3mE_oET( zSW)@gj4(qJgaf>q_>WBesxcNfvaYt_oq{k@;)deTTgpRLr2DQsv&x)QiKconuRH@R z_vZc1Yr1|LamdIGDwJy&#VaR4#gBaW5zor&;GUtH1&(3L02=|V_;IH*yXu(7qPJ@E zYGs=Q&k;81zL^$z?1%F?C<x^-c(Zq4Z<0)krPlzUiD2Voifkl0ylGU^CE{pL>mU)A z9=#C-FUm)f;1M72jkzMl3?-X-bk_A_17>00*7zIETfCp(En8Aw9GS?_(+(A^PQHv) zJ3-VDzDww9QNL(@t!Ch?#I?{XE?S{`Ge^Eg(WA&^J^!`Q7bCRTr#J{)!*EJ3vQ)>^ z+}==wJEdv~HP?6u`Ufn~C1Pwhw~<)JPrAf$i3U_h6ql0rF9&C!4pq~l(=1Q)j?#2U z-wb`=(s3J(*k7sz=&Mi4#U(s{p^j^b7LvGdrgnG+GG#RRY{`+R>$IDzC({uJ7apB` z3M`?KTp-I7QLQjG5?KH><SBq}^Y~mhhS8@H^kpcoJhtOZ(X(FF7*i#AlEQRkV5r#D z4$4|@(MC#i1KQGlP>;in;0hlAEX@?1r@?@7UcT<UBuy+-ZJXjMZ<zohN%f%SHD!8I zsM}`mP+nBK<Ll}0q8fD^B}wIiPnlFq#)@d!qSp>O)vCGf^L%f?lpTA!oOMjxfsjP8 zU=%NBtg7SVT87Nyx!d3kv5pA(el9#y9-lpb39YubPF&Vs1BoWm9ns^=3guB)i`9dG zipT490(Fj_fD5-Wb$3KIBIp&tHng-A-bIrFT86x`V*|xmy-siT7FXubAR#gt2(Yra zy=e{Vv*DRF5r8Au=qystqo;)QI|u(GjP0pI26_y5TH!}%5|@T2H6I?3v0cLy#lBvv zY=SKLQIB;5WYuImAYuR%uzArT_1iwe2t%pkUMh)j>a@BT%B#_hb(IhihRT!FqAEfy zCIXTpC3tn_CtMDv+x8xffLuPiSAE>es6Ga$>VHt|7r|q9?iSdKP*yUXxz2TlBroWT zd2SE8l7EN)7#(q!tXNC0hHlp8=eB(s=nbehWw+37;aeXV!7g$OtX~}Lqml7n_xDrl zO~%4Oc<`>h1LU22ZN_+?#s-ApeivlKfB>^AME5Gki_xThKkNQpEEp&ZtO$!6Md^vG zve=#m7J%CBhiY&0SO||H_EF{0^XH*uY^$0#;{jwV_E1YI;^3K}hVwAPEe8aN`hnT! zdewd}uh_4QTEFA1_8nvAfS8uAqahz3Ycj53U7<xeDuTk}x2<W%Y1g;8wONY=^w~ze zurCBLt5mF$+d1LML|b=a{&F%l!Xz9F?1Tem6}!a}j*!K2ih(9Ut|-WjtSKIT^_3c_ z!zCbiBL}n2TXw02Brw<c#^nl@X=^T7pAe!w+b7Ezvzy~qusKxU%&Fne6%_K5NZ_$X zi#@PC5>HZbsZk@~E!ptKF-Cl4;;*l!^_K|Us*WPUqHI5ni3Hj~c<j-9@&L_qy7BJK zZ17wSI4V7fe$iG-)~1>{VpGn^(ZMjq+8RXSRn9+*V7<-5hL&ZwW}5*L6U%Xr!AIu` z*$0m`HE@2xNJEjiX|YL#Cg%wF*S+1X$@ZS*Zw`D^4}1_PmjWR-@L=h50NuddU|o*# z3PZ?%z=3`(-N8=p_~+ewuU^7mdp&>GciCiy9MOZ>((waV0k}!Hk}mc5;N?!|_+_WJ z)4A8#;Uw&{Y2*RtED)IX_|D5-FU3jg-hvjGcVZ2$DsEicruugZ*I06tL8f2arKH>W zGij)B0v9#HKYqyRo8#LzOkZaHNbQqMp6mF6y72b%c2wM0qh9xq_HOUf;&U)lo0q4{ zi4TK(T7%y<9AIeoDTFj&@3|G-)6B?JY>mx>b9IopD|pMnt2-{)<=L^!$ULc&A{Vn> zXKNDE$!n<SdPPO&9_nNwsw^b~w$j9v#jn0e)p<!PCqRPaGc}H{A8~95D`-+!2q`<h zYR{vDkc%7N#ubRBn^8Y{K_0fB`#<cw5Yj8|7Yp)pi@x72PB?yG(AEzO7S!6*wP^|` zO!@;&P1vO_{C>BX=bC~+&2-b%kWzFMd6TbIBW%YZJjr*IGJILj{Y{)Rx9KNt1r>*< zrCC?U`1zFG1VIgg%Lnx!v_Lv9-2kD|bc3v*cnN(Of-wn1b(5((af6Mc-(9tjioN0v zdOrfB6%P87A?e*<Bkpce80M5Jz(+bQ4^M;Fs|a8~AVb0D^<v?qD6Qgp6$!RDE@3dW zDB!sk%UcJ!tp2&3L$z$V)*aU~$|`k8?dBMhFr$PWc&1`G$*Nu1x+yoL#=cLdoX2oO z!vf!P>yif;2zjI7<gw8n>NyF9D*qK{5EObRxc&xvwY}(*G>Zw&bSt1}mFJfc+05=F zkH>B|M~LfhmOcbv#Ep#8lIc8xSc0Ck=l1^{xAPCki|`OU0F&&%R996Zb#N%)-10{a z>bk{GI}tXLf5ds;r46jWEbhHKz1GE!tZ3ubH(km~04`?VzFFJ<bE`94Z29#RuG#!b zG)vC!LLE;!uv^O!{66SD<8p~kh>6HA(ba2I$?~g==xQmooLQPoAr;nXowrR<7G8W@ zP8P!!`BAihk&YXZjKoYefK;%Lou=RSDgJ<c`tYvF?JME!XtYY#m`F(5luBMF5_mxg zWe>N!&EN_**L5!Kt?qMq*W(aNWOIo41R>s31b@3b-4f7NaCtpP6j(PJ$C=!4xy*dF z6B^v@44M9V7dSfpf{vpEl;4*Jb;8=mp8z#emF9zK)|yesH)SDRo6*g5(EgUOBd~+9 zTB%5n5Vvj3$JNVzqV;Aq9+@ToqE80C>R-6(U$klrGk}p4&^6c<IQ~UyCa2&pmy-#s z9MKWF9%32b9`LU`$P#OCUlR9k4<^QgN>}CMAbep^l9VKFEu>!u@MK20OaC-_J5!$K zR&x!e^`aZW1+YFjlVntSogUTnG6!EKqRNV%1rnn6Ed5G73!)CO!uIz<@qYr#UpzKb z_oCv4h9qsGAK-qx-;h8}FMDD9sNs0bZpv(Si~Yhe@ex6A&~z8bz^&W?oXIVEP=^vA zhO|{Asv=RcdC9BAn>u|8!Ju(flXWL0*Kz_t?TDO{ah&gU%=4^pmD_`}dC8W35sF8l zqMv<w_~jn#Q+J~Ras)B5_+@9u_^(5f+pfqytp$*7xWo_Lui6A6GZ-#^rsU3^xO1fI zj2;i*JFbzVHm=JLN&t${FJAE+ixE8k{0ciBFlaM|5u^T4`wopS_<`;B_uXW?Q{L|o z@#r|@zx4bZ9!tQR@1!i|OL{Cp{EK2yU4Z%0yk4H27vp6~{-{lZo~V=hau-CRKky*> z|IIn{HmhdsX%!tg@#Z4RA<L>mX=5hK&&#?UeGy=}2V_$C%I~y*AJY>M&Go(gXy>}j zufo=es|A@tz9#S@QqC;|36X|OZoCpi$8r@?MPY|9;4oqHqH!65*pk<=Sn&8Jcz9)H z;!Gk}@=KMl-V6f^AfMeRoCkRF;<E1&(A;L9;hlpgDl77<RBrh1sk>o#1jWaS_jP$* zqJ<+dNHD)SDbf6f(8|C&UN1V6YvI&-$IV%^K1j5+foj`mwgiXGB2*FhE2FU?n7VaJ zLYq!N_#o%1dC69TWZuafOHBc(D`YTOFBf~&lvAxmM?d*u-S{zl0ojsS8z7TA(jo_5 zk=8WDsuDtQ1eHMoPcBE;>}dNfjfa14xBI1+^dH>NoK4~BM^O?CK1d_60QBNvtQ*LB zmY|)%+!LSkIZ6X^)Xhvub-Z#3RuWm`Jf5>fUBs4Ds`(dH=Y#mzjdS!p4Zv>ohqt}D zC3{J^iUv{)fZC6I1|OC&4R*k!&nVR_i7l`6x>w9pC$OcuIQYuyjI4#)XxV@&UdB88 zELV8{bP}xGHF>?<lPHzK<+`!)%PcJcCL}4$;AXZa>9B23C>qpFiuf3s?W8AbVtuve zL70sd^+qdc1qNJ#m0(T>57ebbjP4)i)JFmbCwd^`N;+Hw7*Ft4Ut5zFs3Z8$qPh{3 zFlhpw&TTR5URbk4BIV&o?_*mMJZ4;Sl}K;MOa_wdCjG1W62`wNHOPWgE^r8Nb<_Hs z*l@qo4@0v8+hR0o3wr4Lg=3mhp&52MMeDs;>)pV}%>cIh0l=t2j4z?`EL#xb>Uc4? zSQ^q^Ot2tTEHEHJ`M<mF$kq|t!hu@M)1iTbJ-~*L!Ih4wI4aIxDe?2oC{M<??;Bg& zNOf^$TT!r8u*E1k&3q(1vqNH1)wezd&iAVzt(`zR&{@2i5Eez}yc&<oX(y?TcX#Pu zj|GKE0d}nhQ+#J;eqT5d@L&Mpo`!x`qbCcXrZmMTcAwGyM$n@%V!+_rJ7O#}sJ||$ z4k+&qiJ9Bq=<tqGvl}LD@ea7;2<}SpNe=!Q-CUepS56805g?MVwTdkAVY-;)Vk$Jx z%29PnP(CDx_%4xCU9P1ykq#76N0!aFE*t1PniwjWBeUs~Yj$=ix|i(LLvh{<jv7XB zGEDGye6}hWTA5r~2trt@R8vH>vjc~h1qoWjWM}Ga3U_+_l`Kni`+4FWQ;nr@l#{Ta z9LI9>zNlxN-kUf3WP7}6DSFiL1;IMWQq10)L@@ox)BA(Ed2ZJ5SNQJn*7SZyZ@LM& zH(|i|l^{f}`tVEw8!mg?>Ha2pX}IwE*_b#*G<it4gKmKk0-3=$6PGw%4JjL9o5+wZ zsrY;34p<+eVzb+n?Ln7d%D%#2HL(4bzx{UIcZ{JdaCv@q@VC9s4*nfjcGywkJlHgM zEhfN<ApyI#(9BJ}ber|XT(06T=J^n_*dxh27=b;l8-zB%PCApu_y7E-gTL(`-Q9D4 zwj584R!rP{R8N}O5OCFeXz?hC%%={DB-oNCKY}(+oQGDTdi>Idt2p0EKxg(<>24p7 zE4pQ2JaI6nDd&r8f=TzkP+2-Hhy2>wFXYzVFVw*V_uEC?1c;n!<g2LyS42T9NQZES zL6A9vb(@4q^5zQS3yACWt?vdtKF<_Pi=i2C51o5#FK*G@*(db~u`QuN#`q$zUG+mm z&#Ta7E|kOiE97msd9Jv6%H=Dv)L3tb-_v6m99qE(>JvC(CWL2x3c);r-l8`r^!Ea8 z@g1Ck4vfLH5Hw(SPzr_Hs_slC8hy~C(P-&-zevmH#w8pW#Tv*hvb4RUFte<=>S#N$ z=mwuttxJw(9r!`Pt_uaaE^uHX@R4@sZPN_r*B{SIBIk1VA>AZsjRel#Xv?cg8eA}d z018qKU&+!5XpR4c(arqU5rvr_?dsH{1}+eQl$YvuZbW5cqdTeM=?I#S9fn}qS5Cva zqGn25sSW1j9cXd$bKtMs)^-zNS)FhW(}ReLZq;2DMhw3!NvQ~zC_mC_pbcSp7Rd8a zjb?C&-C;+0fv3B_(EOO*8zDf*zAA^3W5R?V+A^x!%%0ZNoR&84Bw<b<K#($quw;pJ z=&o(`43QDG>;V;JPON6J0DDK;jH5~A+W!%=(%(OI>@z~UqSU?|`G?S3tC(Q45-dkF z>eXLf>g#DMC$t<VF6G@2^P0{)TQ%;bL4~R-J2q3p+|`Q%HhdmmP;s9elN07kH)PPj z{XjMUOY!nJkTP68cd_&L*`R(4d+uAoz@o#GCf^>|0pp_9DtU>oDR$)FTXM@k>V)OR z)&<^>{{YRt4%rGU=EZO;fTti}hbFiY+(-HDDhTg+in6ZBTuBH7pAj)q5cPYR^E6z# ze!*+Vx44=tpKCq)is+yYAP845UauV4oCsmIyp7U<$&N9<*XKb6GNLp)I08_Dc>bnk zjThv4KEbseZND2l!R80u%G%6Pw+e%QMN9H{WbTjQML2vk$X*LG4fhk@cneAU0Z;h% zIN%ZY)81U4uqR~JvIPwqa~O*nDIl;HsP)b80V)mzr*bx%T&G4Q$F`T|pnyZ?u+ZY9 z#2if^0=4XcKm`IRU0vegdCu6{V+-EIA|Sw8BM!?D#FH^8!$2|#1;AU}2?=3Bc*YX9 zR`27rUX|G=hl0^Lf=$X{?ohNIt?-j_lSi$(y#}xi9*+9ndN^wDOpZX^{3xHJgV3PJ zuS}op+cUCbS>b~|XFb{t9y`DH=d*!K<#L$d0!bFK2QF@c@G3Ey6+K|#Gffn6k4J^) zQxtYlL!#8PP+M^mtkPWHhH5cmSa8vG#@2dN&MTMlsO{Fn^W+yF`cxvppZp^6gg{~! zzybUWiGyY~sTSQ%(J{RQu#u`k2U4swDD*qc%8vU*q9RNq{yKPxaawO|MJy**(?Y4+ z%KJeuJ=Ryk!gU0dvRU|MwXXCK+r>sH#OS(KVO6eclU`Y&PUCW7z&e5oPe`e}S)HrB z%%~q!VSBS`6K-uZ;>X1xq)A{50{1n-qs9nOanJ;tHAMfmN%WixhsmrCJxdcTZH_IW zF*EQr1Qf+Xf;)5f^UG4>O<dID>h#)W<7f$D0|NFj;3ho;ypg5?=_zy;me3-H+wyn> zPdPr&N*sSc00H|NWkB;HUa~fOf<b6GPzwf!F@ZTWI*flkVm&z1&z3dVbJPI~B?QsJ z>3y7)<g+UVhZsJxXyEM2^J;WnT$DowD5J*R|4eZh>*;8+98*+odc47~he7BOiIYR5 zimu&IL@G^p`|!iDoVkMV<YTodHhu@j77(<>HnibZXyW*)8<p#4@ot2-&1&X6Idpf6 zipgpL+TQJ%5vA1Xo^TbzQWf(qn(WCnVZ&jxbvOJc6nD3gm5LysdxW*h^U{#Eo^Ydv zyaQbesAU;Wi{+WC^ywGHX?4XI?Qe+=1fEV=Y#_mTR->DIdT4FHfh89g1n7Z~R8{H6 z9VHR6{gV@a-yG|F82Z3OGWJC`LKd<-1Vw}s3?=Vo0^i)6K*3-``#lr7NGE>N`d}F( z6-sa;Ww2rFpLS@WWc^EwmyUtHnB}bQg_ZD<wBy7B#hzkOzihMxlC!iIIXGy$p8F=o z(oB53R#Z<i+D7%$=JJn|sUzQtMZ#AY6Pha@TT_C3v2_jA6VaatnpEhks4IP4kDHZ$ z5soyi7fW~&njznXL;#S^SXo|9U1OWY7d0ct+f4F^9*`9VhsnEyfNEh>QyjgP=y+)e z8b&~%OOeQyVTN{~A0vxrDivPVA%Q$eC#>ZF0XJ+H<Ed}$NBC>9Dc8Wv^;Z{Oh3iH| zSN7;Z1mY}!(T7DIMtY6ho5;FELiYpEpkU#mXpfH=3mQfH-^2Z{lXGLy7N~w1+yc9M z|LjVOZ-}HfjEQtxLRW_|k;Fo;WFrTgCcwd?I+GZhZnAErd%HU-dmMd-5$WBMLsbBq zJ!N!3!2%p*P9;<8ij%0VNMKH4vbQdTQF_iM6y(m<H3USAur02jjKEG82lWA|$S;Oh zu0mci1la%~nr*a#!y^8&`}SkFyRr*xTa$L;tv4Hu@rpjuw(y;lZDM-qch1{R)aqV} z#nUF;+-!5IiAadBZcdglYLE=7D*vLFxY*HLjsiG{+~v<DkK;SUgW|xA)$W0b1*5Xm z%A3cn?jLgZc#tLtFSS(|@}D-})irWX;52((5Uk$-Pwnkh%-blV5y*+#B$71Qz`D_d zncCXfivEX}7K5u#PC@3@AL=TCWA0O&ke#41L`824Qwdh8PUI1>SuU1nDJW)&?%ot! zjS~_KOeztun|3Gih2aXtvXOR6Q*`<J4u2sFsIGuIC2PmswIBfdgJO5301c|_BAG`* zW2MhQZumd!2!UIhTZ^AMIwn5U++l71qm$<;*xLO+X7V^7#^FYD$C-nvi|>bFAgL7( zE(lPg2S)b!WtPSo)$dV!(SLO|SiCO}wCY3-fAAV{RLg2U4)u%p7KHJ2Nk7<x%b(YE z<CTVNRP6>d&<9Eh)%3OL>jGt6QA4D^i)u2|H>!C1fXb&Nn{Ahay_h&|c(@Twyi;zp zsl~nt{oRURmKU>TBeldktcul{TNH9R_GG;b<KW6(*OtZ<C$}88EMXKls`w-MMw&|- z*|@l<u0W-EHm}Bg8)ntS4p(=yC{i$ap?kb{uq4yaeb*dcnZwPZjm4?PPHjRvh$Lid zOIV}y$>VMj*I><Ugk5Cvv|?06c0TQ4v;BibhKPfZh@Wyq9K3A9>1w56#Yo&w8@RK< zNZk3LBatEEvkgY#vrR@qZD;BMtk#~_|LI8)M4R5BJH{OBD7)Q|Zkw@J>=jfc&f2H` z2Q}VCwd3UOoJ|!SW;F7X4s2pYsk`^`gZKbTIeF+E+LY3}zH@NsaPU9rdyl@c)0urz z3}bz#Bl}}+WPdaxyKhH!-;C^!ts|S!KiTD;-_>qxSC_kcFTYP7P&pXhcWGEF*!7)s zl}#kJpA15eKOTkFz-{*xTD0#e@%qKF8&^YEuzYlO<CyD$L$UJyvlU%D{?Mz>&ep&D zt*7n2L%ZsOOg$~k4?Oiy>HpZ=r#HcW#amPEzNChVX*iy$Ukv+B2%e9>BLSH2PD9tm zFt(t|#Uub21Tj^%YH4?eDd&sNF=SUhx>Yx}u(cqkT4zu{*Z@4QP9QL^I>i0ga9+6u z3!^+eYv?r?MRPar)x~TsJ`1yQjt{<oucCJjCrpy%9#}_|ix<^J>E@KYzc7YUQ^dF_ zdJn1Pbzf{m<u(BhIZH6{*Z6!~p%c5^`Z=%8;NC>;dnI0<XppJq&$MRnS#np6Q9Yx| z-5=NNa1mFJmL+6!Ol23+6LHCC7T{NaR~UDjqo)2cpr`OjxoGIBhRuSH0q8JApf~k_ z8Hj6yQJ_3F7ty1q82x-u?Cb;|4#{j1AHK3hJiOVfvD?zuiLV|4SaHdFVcEa~B!Qs3 zWtTXh_k8P?9S5=InHY}F$&L|MF1j^;^Xvso1~No&ehH%wus#-|=4=+{Dv1N6M)nZ$ zuPm_7XvQD`WHbsM**vgmE7|LK|4+m$XM>*DXA|&nFzN~60*qm)P=mPiaM#dd@f3Ck z#H?_6&YTpYeun5vQX=5b3nHNLfeeUpLI@K|m);b3>=<!u2^6}kJ|*uzSI;*!c&C#e z`4}vNB($G(Y(>=r`@cz-x+h?^<mPDJ>%+yr!mS2dmo^q;0VmZz{bm2}fA86tpEmkP zj6FkE0&H^?ny4mWyG{(Bi=AL@bWPjFjK8E@SvNIBbxn0E+UQ|`BY)40QjV*atejdd zYJ;+rW^ns^QH?rL=)Evs(dopPe;+XZQWBRcAAKnRwSn{g*>ZuwK|#NgY`$~_6B1XV zH!LDkeD=a$VMcBn?`hBteqv9_^G~{A$eJvm5vFuk!D+&3$yP~Pv3#Yxrg24m*x{m` z-|o2pqvMz_*D8!cf)&bs2QI8k0~i>&FpP~km^#>qlU(B?!D5j|RD`sJ+??YEuAlDA zT$IWJ9h)5(gzmLbPJwmg#_OHe7i@{u1J+)>uYbhBVi1)xX>{~fD;k?UDqPbZ$*JEm zC?A@-l?zCS1L`&>?nXQ{)`ag=*i`Jy7m&%x?$;oEc^S|9x<>H@6r_M0imfv^`7U`6 zD5_HgaIRWAsb3T-<|e_meJk`VbgA8Z$p+mIBg@&bw$5IFjZkEwlWpugy#XQQLA?P5 zZ|g*Dg1bJhoe<?Du1m*1MCs&&Vt3NcCQEpd4<gg>!M2<`rd(LTK&^Wi3W-6L7{+IW z1-LI!CEg*4zCTw?m>?M2&31CgKbs9lK6HIzNmx^|v>Fv^sq??l1FEgc-!L_*@xR$I z-^&^goV1`Gb3wg&iU%<wy;Qv2&TJzlO41j^n_cNM$FuxD9xw2{qX2G)u9_Hqlk6YA zgR-tE<4qr!0wRt{7CMm-PS!^O3{#Es_|2*bBhCfL(-rveM%!KRTPqLN8fC#v?Ag5y zW@^L<xH)k_o`uX}X*OCWiQHx`Ys~UnN8jHKxzWTFm0W~=K$KZ0<JF5A&IBdWIQhA& z{rn8MNkf+4NJU_Oi3BKPpoXbKrrlQv>FdE`2oxE=S|~rOGnTN92p>#8=v~}`^I&3x z>36$({F0Q9-kpu|@lSe-k6!*bPyCtkvK4qx%fpjK;k!A>g1X^TJzV}AmDJA%^so3$ z78-66ZFaY}@m7C>ily!Cy-#m#7oW<$|Nd$5VtCRN2ZMuy!CxTZe6g4v?(O{oSi;xK z${jHm?(;UjjLxpfA&Lus32z$Y_5so;J)6UkgmL?7Cw#b4-<1IF0A3zIGBS>@pS~z2 z)u@~{<sfO&4b<5lr*gxbKAcqpOV*ydF*JMI`0(mQGPjTbX7QT#JTVG#c^j9f0OmwW zO3seY)|4<9UW^Nm7X0w*#{)<FS=E3xVhDBtU>Y#J2BirYa4aV!2-sA(i{_afBCmsU z)EVqSv_btr*vlRF>t){)2{UAnG$583d3qFQllsK%2@sDcb63V43vJ(+KHnz71<s#w zp53ABMhZr$gCR|wbkN{}?9g-rX~<R%i_i7}c3Fcaz&=6wsPxfKNA+YfoFUAe33Q6= zhCnGszhYm><_}MJ`0kbiSO{Z^<2SxOxbn&`>bZ^WF4CFLPlw^dmhWHH!?FK1(O()$ zs`(1Ej)z4z6OLu>E>?hNy7#BSr?>a4QJf!Q$BoXtJOria%lGq1pHP@wHupo^#*1b- zn_=wNr(gU#e{z2*aF1%G$cb!To)$B~mq5&6(7C^^hM*0vW{UtZK+eCS`=@^}1lbmo za*rt>=Vmx!yEHEaTM;XPJ}b22PCjI8UFvrq1Q|MWOgA8kB>!4fh&wheNA(zCr-#?5 zM7@OVQqJe~T<)^pfA<ypo_+t~%iX_2fBt%aN~^7fThkKt+*6EomfwH(^ih2=a~%X} z*{91PIf59j0ONsex!Ji1YYe-TtJCIKQLDKV$ymB^kQ>VV;s7{_q5s~!a8)oj?t#mN z`qgKH0~x?KIwV?x1*zh7Ii1D=ruC!W4p3QvC+q@G0LWG16aKGV-mdV)F)w$q*mZld zLqKnXMSXV0k&%2gyM`|~HsfOs>DR(U_ju*jIKWZCp+iTz!ljP_OCI(u#O+=hpU>g1 zWkKNy&~gd-0h@%-F@4Bb6jGnO`1&hGj{-=i;RrSAcvi83hG98r<4vwbVN!TE=OT`Y zfX0`<n|bjm0CcdNR_+W)i@{aRtp<9pygj%W&RBqjF1QQTWPunWs0&*-(srew8~nau zLzAkAgOwnnA68Sr{e$wbB9mUt+#L-RY@y?!H#6cjJbYbOPSmG0k1U8Mq52JV>4^0L z5md5qOnLrpi72O9XWA2bm$xEbH0N-w<OwgLYV#UYEq}WkNw^Y`#l)#AOpzQhaAvf$ z>*EocMVZ~ZVUNPfIG%~$7f~*g)VJLD2^~(J9RuHKmM7%7-vt~--$^0h9$jDxjV90Y zjULYKN{WJ_JCCOefRUZc^P1z*dcO+V4{lJn*h0)ncyM)}{o<s3)TNICAPMh!$YbX9 zqyZR7%O-<%ME)QwysehtJQBpiV#)_gdx-5{4ClXs%9LsZe!(0=``R*WTj6}#P1dq` zktI^8j!_;7o?|U7xqN**;sI_HI@C&vyLgySy9cXilVBA1jPA$DsDj+}AHv(YsxM9u zhI3k;p@~5sf<?ef)?C9rcw+pn=EgS}7r@AtZB+Oe>g#%AcgO>7^)S_G@q5}3ob`)T zHYE%>*{D3gj7V)7fHT{ZvkBu;I`?B&WJ<9S_6S24HGL5BB;go=CDZWa(6T5t)t;74 zX1$eRT>zfrA)64o!R7t3p1Y$p;B`glz3JNd&+;0~5e{3FyTHdz>(SC(+FV_P0-t#6 zQQZ<?q6ac)1NPNLXHs<-7`<@<2!zuRP|IYkm{zF7S?xHQ>%--6K2|KXfPcTD^$R9* z-wa=S!t>aU&1J=c9NJ_4T3$Z_GZS&^19NWlJLiPKcTfN0$&15$+T&+Ge1l10zjk(r z6`i=b{`Dwd^!smH>ip`9FR8h>=Z41xt?llvZ|#e39%ty3@sC#ZuAq#qs`1IQufNDw zxxc>f^KTzM;?i)f=KC9(Wq>t-?%nAbMK&PI**X6ExI7&$CmI0*O%m9a#jbIJNwjM6 zS8{*s79q);$)Ks_2Jpof-zmi}Q0gtZq>oZPoHPvP6d@Cup7lOVPlA|52$EYg7{*MR z0v)UnQf|<BeSVLm9M5Lg4c3^taTt9Up8O?jXtIUyPm*-jDdq`*jkvMK=Lk1EO@l9> z?ZdUfU}cy3E95WVlvfMni9w!z5$rg<U^u2yol(Vzo58}$-l)E~fFlLz28$ymw1C$D zK-(CZ6`@BB^=Y)2PaMz1Cu#a}Q7(q?#XvnX%p6KcLTOQ5T$JMq)$!z-;ckWxU!X}C ziE<#_7{d`MIN(a3flBVOa#QO{!QI?-=XBYS&H?O70L33oBhU?Gh`=z{iku_sNSf+% zweE_gt>a)w`vhNtWyVmoSXj}Lm`>gOYeXl8ll80Syu>%^Eq@LKf}->W!b0Ez?bw$j zl`*0<+gb&jCaScESCK54ym^*|`h%)TzUybV%Z)_$L!+ng0)glGn&bCf&pI$3a0_i` zIYT_-hE7+pa}!e|H)`7!`P44X@Q?&%5uIYv@(RvoB^4wfRN%u2Fj?$?!LGZ5@4-0a zsD-M*_;C-xkzkp1Ri1Net8olA9GsPdN#qVEi_QA^?Zf~0;+5}g%u;i#CC60V$=X+; zIlyAk2%_&pAc!OHOX3cY2-K{gkQOdn&ABQ&)K!j^st^eVm##o6{#n_>8YrkgR@c7s zVI#%;usXE~3j~pysL)*q(i7#h)f~maT`T#DTgn|(aPosXXv*p!Lt;N1Q==fd6<lqk z;b4>=Foiqlh)#d+D*9$Z56^;`(aolz3eQ77i!FsTEUj|ain*%U%vsvpUG~{5a$1Gc zvR}L&PL`$Jk8p<4OS;~ZMM>coagR<GzOGhNS4%afx*Ds(vvZK!3*7oqhGT}r7=@dX zLw8I$Fj-s5&oQ4gg-$tA$r7vvl3&gqbNWguIRA16Is`vpMyI1BT2*VX_a)%UCK_5x zitFO@a=~c&$rYNGzsQ>7qoM}jQ!<IglT3HpEvhsQx|dw7gX7dp(tZ)eatr&7{4ne> z4KQA<n_ze|#m$RUu97D{IjTvP_7L=bzm?DNw6BBEE$3coCGec^<pKWVA5Hd-Z*^|} z+n+z__CDR|4}RV|Ji2@D{)7MP=i{GW{`}AX_4}Kf|L5i2nUhg|{`vNwfyP6!MYRD= zv--yT+W@H#tHv;042rE0V~Wn9qpv$WhNqpEy^fcEVS($iM)f+X(%0zM(ZUe-E5?f@ zBoCG$i<7!`0{oO>QIw1y=oPfvEt+&xkx#0(QH~o0Bu@sE7sV7L`oP`!_Xu{M2GdMg z_Hf5?*Hjn_Sy`>?`^_8C)ns)?$y<lN=4bWUObRQ6Q0(^VLy-H=>S?(hhIPxRis0U1 zJn(}xf%Y+dTS_cuJQoD>lX-c;e$u!oz=c^RAvDOb2RsZ+@(>aZ$*M8Q4+>Hw7ZVW_ zS*{HOrnHDf_7GHL9l(!E1vp$@fe3e#PK%imaz-hy+`u-`g9U^cfyb+6IWMIMovnZk zTF=2-D7!}T8rJZABKPbOhNjP>#>K}}i$HU<o#nbgZkD>EtO0Kg@*AdX9|*CdU=|*B zlP+~QkkQ5NQ0|6(pIBbG<7u2EE?DXV;2#N3#YSszn%Q<&D^&SC6zmxYo6wNQBru-W zAzwSUx0LU=h48g51aRu&y(|t+?ic#mg~o90?^Y_Q?fbj0^wb^q`zznhwzu++!~BF% zD92S%&BO}(f7$!;{<e)I(Z5%p0%kNrLgHaL*No0}Y-j9E9Q#@J%j}AZ42qD1m?Rj0 zw5*Ag&;IJ_3uu6lY|rkz-)4V17J)|fRb5?oiKV8zAvEQ#{np+Q`>oj$r@(hJr8bO% z<0h)cWHy1Z!0N(?<mLisWQ|9PLoQR+$<!|%GTATaTJ>w1jY(HUzZ}$`aM=$%{U71C z!m#ol&7$|XLF~fTgHz6?eECgUv$N!bW!=AsBlN-Y8utZrvXq#_mJ9~p3iWy^3NKU} z30FWeffP=+I0iPzC#UZS@E8!|oak>0WVi%@Q`{LxL`o_H0*&cd@_B^r=v8j#+N#KP z>5{yPEii_}IyEc@`h*^ronZH`?z~l^6w!bZ3CBb(5=BRv4CULSbc4^H2n=_%te9a= z6)oXo?AAjOUZN3$JAbmwls4~YRg6@{qg}$aaTP=(wA?w+)wM_w#so<~C>KFaB21fv z-=GH{FgddxwZ=6xEm`ACF9ZnoKna1P+0|u4UK7qX8#^e?h}3uZ`Rd)S*ye(9snNDm zN4R>0y>_pfB8M!V?TDyF4%u@GrF+2$bF3&KeCcAqqqR*ZOQ>JrK5_;Zxs-&6JaWXP zrBXhBsFoC`^&li3Zf8w<fOsi9Z%*YnQ8N$QL<;Q&1D-3|w%#dE!{aPa_NU85yy~)W zDgQhhcP-bjXJfWUs;|Z0=GnNT@4jTL?2kC!LUW&)QhV$^ggfJrI49u37u3;~--330 zllry7eF_(h1)9a*(DEBp8>XgdIpu+<sFHlpjNz4PRdV#u%~WY`CHph#a_>cnwWHx_ zMivH-9`K9U%Q~a8;+f`06kStlevSsW*QBeyQYp;P|1TjM08^!i-2!_NMjBX-Y1Wi$ z)|<VrgWqqQ9VaaBC*z&sy0*SRQX`O8E}2;xt1Q?(`k*MRxL{Oud3@GU-RVkC41j~K zA5w){sSryC1!H?qz&O^$(be^DlPdvYugZii53PARNfz27qVoL&G7dMa_us6J)!>EY z1;QYoxPeY6<@%0=h6tNAjuw$kP@GNcR(x-TTd4iE`DXq7wtM_#^3f=s0Hq&Y!Fxp! z)(qe1SuXQMSAS8~1Mq58kxE{lIxk68v7?HYA_$h6<stgo1yeYHaDfA(_AU=PUu@mK z|MfSa;`=qD>1eFdvorI`5?B`8(q^A^Q{hT&u}W^2iVt2E#UVkRFen;x*z%2WXIVlH zz`&1_OOvYeNGMHNPEch4yu~@@nu}+c+ydwP?YCQBhwLqb%x;y7jKd(SxM24fx6(;> ziEFHcp&hq|)l2rJu`Z#ptGJ_j$>ZexeqkFEv>syPPlX<Zb2EkuDN8AaEfd|NR;e4| z+#b1QYWUsbvRZakWs+8<g0a+Ymd}`_Q!0L_{RsSOE*qdOhv>L&@q49Hqadn)!gtV; z(*>m23CNAr;(jC;l7gw6X_?OUxI4NmjKwDD29>56tdWi0vP`l4+?`=ARV$0U=(o0g zxp<kno!H3&YWv}a4}HBA)#ZM@&7PjPi&Ct=sdN95P`^F6ad#XerCPXk=IF#yX=+7v z%T_7P?CV8m=ttHYO1^MHzn_x9Cu{AjS+e??L!uniqYKO;fz|_;YLV#~xQ|?mXJv7Y zN6XI7mU>hAMh!FUan}{@#g`04sqIR+wMGcNaaB>=jnjebhOZ52AA;Y}*1<jnEz7~L z72J3~;&mx}X1gZHhx$t`6*?<zAYb4G;CpW&-BUX($g-c<YCw&D)98a_IOkj4E*+() z{#;j$QW$E(l2lZr-{3vaFaeNc#!~eNcHH;9LQhU943+Foy)-aN*0`KAI^i+jexE3_ zT|pL77(&MmJ~aN8N<7ighM2Q=A~{F`Q!-D9Bf>URB<%&FIQQl0Dnt|5%%`&=)U&-3 z=C;zTlskQGZ3;b{M8zsNT^a>Iqke^>^#eArWW!w5ztu0VhNWY|x|w?SH-i$S&=?2! ze&_ws6&|`OWZYK7`Vm&zl@a#-PP1v+-<S!S<5V6!1#($ak%{Qn2BNDswTX4zRZ?T2 zbWI$V+p`XETi0Gn?7s9m%Fw_VDs{dS16LC4i6+P6XZb_jQ8Z%n7Ou8s?s7si$Q!Kq z?VtY~RK;m5(nI8W_bdm{Ro>a!;dzlh<sj^PxAE>)I`FP`#zOaURq^NF(#e<{M64CX zXTkt;mtCoheMv2SBNul+Y@@%#iAv^<8jnrw#0CQ1MU>aEIzX0`=Ahuph~YTOC%6oV z7-wnXf;o*)Qz4GuW1wiHeZZi-L>EOX1kPC>bDl@#%O9}9oGq`IvDw;s$%5#?lY8D6 zII9<N7bbsV8lCMpia_1S{-EWCzM3F^v-P3lWZ`!ZELj$vT~{8!Wpg9j&DV<N*y7AB z#MyD&7(ZONX++?6KN`95XkzIi)U?gkjB*9}0+>&XQG<nXqu95D=Se=r&`q3@C(5bc zD*A|c;alNg{?+IPmbKHQL1XWmj%RmvjKs_iO*!h-F9&ErB<YxSP|CcHVHyOhL|END zud-2TiliI&)hTwVj(M->gD<R9hhbQbdeiwNCNC{nv1n0_Lsc&<OpfYsSZ|H)hs}GI z)2W&Zx(XMq0=KbZ?ihWUivr}r1Y=f*1xFA#YP1s?lzi4Lx9;lI@yUYHo5}Zv_l{c3 zlAuh*NhvUEbQN5Xh6Q_!d1cHm0m1ZAW>q*!uJJuFQ82>7qb*zA4duoj8;yfIzWpc( zx~sN?w76zrZc2vh&(fu=6dUvDNg)}ZG_b{fF)X`6e`$0d>9e5aLRQ9K#_cSYi%k)V zuB3|Od^{7fznTO++LfSR0D^veOd`>>OFKHz>Np^6_nHQ9&4nU(`7Vy<lG#;XHFVF< z%77{kql3p`1s;^$9(r44cDtI`+i{#V7B=CWi@nM1d*3m*RgZ{qiiYCHDLdAoMD^;B z%6L}Pd0n_Z7dJ*uH#s*7N*wE|VRqZYzB|#|iHe61_rUCmcD@i%qF6lvq+Cj^AW_4t zdmPj%f*?$13bV0h?v!c`2a#d%?5GHb-P7!d*XPD3wCL_lW)6vfV9j*DWOLO9T3$O_ znCeJ4C`vlp_If)qkn_f6!MB5T5V)zvnzgxRd#bkAcI&p-Nk<eZx`o@(u7Xs4;OPDq zFQT5l+F^gri7Jyji6mlxhnUzJZ>NZJqOk3gvLM0cV0?0fvCDCmU=C^O!4MD5^J6BU zirW`G@f`)C<5efmw96@(|JV20XiroQ`>pnI%a}r{{NY8b?@f`_oG*41D&E_zc^Z$v z=MP@+y_56~|5kC6eo~JkN54(BvY_laP%{|Ufx!o@{KBHy*2_2Aq+D8zK4-w|_#9VC zev4(*vtLak1{<~maW=G)HOTT9FgK5zv#wxc;5I9)48~W*=7oZiY#so{OWK8&<JeNN zYWdNwz<3!uS%rP0urXfq$HekL^t~S~^Q*e|`l_t!!`O>!TFG5q(?Vap{x%xjoy6;v z*)=RL8M2BMG{lr=c@JLIo8;{z4D^XYuu0-EZCRFlZtTqCaf6N=1ckwsSE=-c*DSB4 zC2!&xTZwv)qhvVcm_u9z602tUla|SRrL>yyEE-K}`5)V~=`*@%)rVu2bfRB;QAp;_ z!Zdl9QBE0mz1CTKW!(@jbr0J&bQ25lzm;Pz)DzpL2Ul+?{}4XIh35_r==ZixpJ}qQ z*w|3+%`#`%*^as&)up4JDfqfO?(MYu^5oNRzl2zR<nHUB%sXzrHi)xbw%RCeS%Plv zggr5EsGZ<QMsaNSWhJ7j#0dT2T{e+Z|M{)Z-k?bDqItDyWN+}Y!LHQ;)zy`pzsc)j zkD$UlP}c2pni!><m;5j~81F_58KQsMv)19)-~RseRhMM^W$yY@%QG<;!v3^uH(KK> zh8boh#bDRA!io18sp<W!n$gr--gwnFxNXm*af=8DL$R1<N~RkxV*SGQ^HriJYVFz2 z(G9IH_-7V^o_ryi*fU~x^lPNVg%kW+0w{9@%B!8%qOf)`7uEIdR{t;j#(E$r<#V|= z#6LWXfl1A&A}HGqIFe41M8`Aol#}cXnCSZ~08m{u;t<4b@_taTBU##X^eb>h{gP;+ zbcQIFFowLwV0^w}rGInBqGqD3e=Y2L**%Xo+?$&Ly5+DAEPQ0S4ujA!2Z|djRPM?& zG*VPAGQX5;vZLjBF6m@BnJii}7K5#=Z@-ncrfyPMC#2?r6=uztwC`t0?~Mylq4Sn6 zv=+E{QdOq2uJQl9k%*VGD4BFt9r1tGg4}KbjxE_fM%$&FtKEjCk7AzZWj0Y-5`}Xp z%_|yg&ds)mOv-2qcVbZ7SCf2J@2>a{^x?3?cnAE>Ft-(Gce1*pn-alLcb~0evF?d& zZ{RC=(TS6MZR)+9f^%ijjhrsqk{daDR+HzXWFgkMr43H3cMTsy8Eys}l*jqaEFHl? z&rv4ithQwR97l6Zv5aOgMo*RVIR~sfPZk%;5g}v-*q%$4=-%?zT(U#I0<xIE2~@ZZ zsNKJhLA$8%%lf)iT^ed`G+0{;0!*W_#5zrvGo>ZuTzN=PlRU@t1EdL`$LX9h6GUT* zcAhP$q{8WBNsh2Q&J!4Cu(*U?81(2W7{eK1Qy*qAfJx<Ip|%rmE>v-87=O^l1O%wc zI$gAPaE!u`(Si^`cG<=N{!=#6wplMKA7e80KsQL0;_<yU>|PMu$m|c{yeuxLyiCd= zt1y}fR%)@pu%IZ%bdjiCMU~QgIf5k&cq9q|WPvb$65LPpu8-SAE}ryrM}Dm9vet;O z>PJYERP);l)W1A47~+qZ{zw(t4n~-U99Pyx4ft;Yt*CILiQ8{SM<^lVIXFwQDR8Fp zU>Ywj(y{r?EQ9$id}a^lRC;>c?yjk!eYadJ0Bu$dZba>h!{evU5Vp~G3Jd(nCt)|R zTdA3pnptDw4pxsTna!6At}kSbiM1w$Wuc~pXA7Ws5nz||*c!(7IJ%XCz&RW)N7H0s zjR7APA<+<;!Fxs%E3EaI26BXo<Gq|Z#oX+L7s)g_kJWQod(RjAhW3G8ABSBJ_#<q4 z+%3abFFYL-UePbRpA{>kWh5#0PNOBzIi`cBPo<5uJk}07$iK}xlCg`16-``}sAyE~ zslJm{@b&u@>ypJiX(%NJeG9`anyiaamsBr|X;Zf{rj>7LYWrE)g=tV+os93%abcOL zje181sk9igXbSkN+6Zc@Zr~W`fvjj)9MM@q_iJf1_}o7dIyLyZ4mRB$LVI;6f(`<s ztbg+~XSb~^W&{unk%+khj^IV}xO9N-cyoNpfiZ%VhvvCvyn|iU&K~}od2f;SC?(UQ z3`W^IOyJK~BD2DNo+ER%NZ-Xgw$nU2dyT&e7P5fxO-$}>G#V1#?BNGJ`u?~rTy0xa zz0AM>3u6uE)sN`q9Zgw6m@e~$s&Pg<-J`=--xo&n5}V&@G}J+p(U^n}G#W0B`w#>H zE!1O0m)tip{P{9V7hFu(8XgG9dW6JG(Km`+>g)CG$Z(i#q()&tLVdiD?RiR8x=#D= zJ?yPVpS8OTusj*y3Go^+(?LcMX=g5hp<D)aX%K<{bxyHH*;rbty+EfG5b#4GGnA_Y z2SH<SGBT*C!ZuhpG;Kz!4MK^THf<#NYPVasJMW`Or?e>LdFdLk$cvM@kP6%ANO)q` zeTo@w3?oO&S|TrnQf0O}IUW7l4RFNW0FRNoeGCOPOk5fc+v%-?FZ)XB6ls_ssP}@R z?2#)Y(Mh{YGZjaHK$u6MHPIwJ?^1@)QLMuG#uy1hIZ)y7kfV^@8dXoiqW9$upCta< zn)Ni!G3?LGRt76A_4~?UqQtDhts13vFtEml00=1lVebcP?@J>Sm6>{7IWUZ6Mn8sl zVc`i@!p4FraOjKUgtMZCL`?`D{$-b0mSXb7G0Ahxy^UX##zcif^PpuB>lPs>>S<w+ zl1R^1Bucew5bjWcCQo@#N&bpJG#?n79^2e=J1mH$nAEbmogYhC3V<o8*)Zk6V~96y z&fBi{mM6G+*c4wx;$AmcV(}gvP?vx`0<Hvog(HlP!pE<vqNS<0V(2LEBA)M#PUX=i z^kS7zJ2X88Mc@+1V^#y-_fAcNHbuO%Jxjq*<0*ZNOb>t1VZ>G1C0up)NnZg8^<;QD z3SyEob#;dy$bwm2^Nq)k+u@GYbV-$V+;$vY=e8TOSwja)#Tk_viP^~HG$rSuX-Xx$ zIYFN!r6Uh?=6V*wtyrJoPV>Xknt^n<&7bwSg*!G}5|N{wW#CbB8Bck?<GfzgOP4m) z`RGRfZTTu%`@xvzk<C|a5szW@7Rgw%NwfXwlvc_GL`+eR2qX~bAGnMEjJLGE?M|aL z@aRl#w+47d+CZ(_|5}UjQM+ue8%+vpCgzT$OoVO>*)V}!_V|z(ZL3k@a{ukg>oyb9 zZK1S^25lP>>z;MAGtN~iqn1TfQCZ&-Mv1abN=|-qCbhU}3!GQW58SU&@fS}xZem`f zm#%TX_(@Q~Pe-Sx@q7W(Z*L4Xc7EHt-~Sr^hK<+oxkcV*b$Ef8+?2+(>ej(|LU%{b z1dqe=cy+>9;VBtN&Yz=XQ5Z=X5iJhDy1sowzp=MBU!G#RHES~%DU>nKk!otk%7AdT zB?!kZfwlWrR;m&<(AUknRxr#;)5kTvk}lrgWtU$z>zSGsx)lI*b4Gdmaf%5%w}l=g z`6KhN1C$~(N8Dl!P%65JLCyoIW|o%N7&O^Dd-6^1FJ!f_ziK^U?Zk{~3k83F{^Qfv zuU{%VWDDWx_<9?`3q822qMU7D^4}-%WL%^@B|dAr_`qHvFHysq3A4#nFvoPaNI-#e zev3>0R?|C7W19lEF^OjHoU!972EXf3GWmu7-LX56BV*)}f|TJoYra!<Qx-|2P)P1^ z7l;@If-!A(k<))<qlZROo{hybb2^`g%E?6+1Ly22QV9s~)LcUL7jy#^i%RZT;Gw@} zu;m*r@o3$3Za=v0E*fKsO<ao0G<z3iWG$fd#Lu1plX%{*1!X;OPsg(})-++M<I{Aa zrGK<PQg7nFF6s`>goOq_POP0ehh_sLn2q2fg-yd`IpSyom<Wr3MmRcz3$>d)cQ<W7 z9ZA}UHFi)0rBDYfbHfMrTauw*-blz`H%7@MSzKXF+c@kyM?sYjLEAL&-JEe(riw6V ztf?vR8J$N|k=T?6x51S@?H6(UUZ>N!XVzPP0E~p^Dc;HLZD3O{Qq<a|6e~hsUt5R0 z<DjAj0DRbBfcLSBsW>Ts?NAm^_xkHX*VajvI-;>n$8>5nCac=;3rv^J-w112*m#SE zmsX7(11ku_Q;9ciS$57AYPML0hHDgL=zLo>-{rWAz1DyNGX`I`0_(%Q7Q0-vpzFzA zYnGm+7|SeeM4_|SdI(dyN|&S}JZSAdrf+r!(Y__9KPP||!NKvk6i3dV#lcb=bG2z^ z7@rq7Vbh93X;do~NcoxFN~;Ea8dSF#=@*@5qH#3MNJEJ>?e;GHsg`e^Vop^Shgoe& zlSEDB{_X&q?zi0uMmR09b^yHgE}KJG>v^JflVoBBCrg3=i5K5%DPQ%$e%sMtn3<GR zHD)bJukQKy2b_b$WV++tEDjt8YPzSfT2nB+SIweuZIfP`HWcq)Tts)5yMh9tbrVx7 zj`{49r^UGA3|c*Xop#!o>(tz8^d(F6ow921DTTrqEhH((wbt0NfU{wOC<LDQd>)@- zl=?V$ba<%EK5K?#u+}>l{W?(g2=l6D)0Wmyn>75YBw?PXrwLVK(%q)ZMUDYhTnRK4 z0|{#GRbNz)dNF0CzLoSJ1PX0Zmpj>J<neJ=54@x&q;)g;C5kJ<KT)Hp1{bQxD+6Vl zKP0y#{j{*`8-duk3QN2#Bj^Q>(Dsn)g<>TVT%M$&VM`hrz1l1gg9Mtz`r}tz#ld`z z22IvJG9b7C+a>#1+pL_1bQs(AcwO%ss~!Ojr)C=i+aUja^-^04%u=D%RQ7^j6m0vx zm?V9n*dJJZch)<ITh`T9*n;vWO;xZ`A_E&}@>EiCAlfKB9Ux8{v9k@R(T4SJ8ykp* zRMKcT8)KNrvbxU3g|1e*i+fNfbZlvMhxe-V14R(lM`4MQ>D*R;8G6ttk|TPQvHq3v zV6c#?;sDg(u-N4+#cJKDfQy5ea`HWX>p|1EVFPqGCNjZy?(I{cyX&#B8rw@fuSE9J z7tL_}w)jlf8i%yj<0%_a+8X`fK@sa#0MJvdL_pdwcO3u$VGV@x3GZhSJ%fASlY8b{ zY4Vm8cm_!>(#u?u1W*H#55>w@fPt+P9Ib{?0Hy6KxoqF!nR(0Ny19>0w<x_`p!7tQ zq_7Yo@b4fXUB&rM@RlYE62B6E6vzE=v4}YNLL^*lrYhDM<6mK(E(Z`X@T<3S+*pBG zIsH3zTwIv?5uk@>&YXi<q_wi%p^ti?>K^c8@*TRoh;h-lX3oNtnT%%nWsD8T90_k( zN|rfTlNEA6DUu!*T^=e97nzSsBwt}<Xsg0_94eHqOHQn#==7a^=I$ATwIgA<45wEW ztNXOcjH{`z#^4yw3uf?Y`4Oa9EJBw~Vs`OG;aEL@RSf$$C)EV5Fbv)}eTS_a*hZp} zCC~%%&&knx@)V9kSL)O#BQr!v!dc%MKAEe+p0W`e)fA*(V<!))jS}(A)|_c30L06C zm{j%Iq0Tu!OK0EV7cO#1|CH5U-0`G>+Ut}o?v8HTWFRkfK(-M6Ub(}y9mJeWo~gdP z4DVW@UCq6gh_op8nAvoD;K3fZqr1rRo}(=or5}#F*263sC+RWWRpz5@YD(A5c5v?= zzd&Cbt4BO3Zm(F@-dbwc^7EL=Tb!m#3?iQieB+r&!$6osndK+(Fga$CMd6ZkCH!5% zFz21Eo){K_*GnrxNV%b!vgLNfU|HV8r)}eRWOA^3j3!J{(9PjpGDkv4rA`T&V;r_; zp%8@spmYQDr{`SX6kUVl8=YTJfNfVeU#vWzSS{qEzLrpL4-RElBPz^Fdp%tDiV zi+7M}k?TRMSc0yqUS}mKK`NW%l=EN|g9x3V+INO^Ux*$6uki$3{V)#V+`h-mJk~pL zU$hg()<gW6{_qgZp|NG$jVTiInW_!_5_q-fJYq7ivsPs^ux6%2CEH~Q<$XFzxMf~x zmK;q{2B3;DlH8v@)NqlTQrVU5;xfs?mJ%Cs&7V)6<FLJuv4N!;<q1w%FzzVhG1x`| z9_18i(-N^mm?$vXT^CDOZO#jNw#<m^sfG31lw73i#FbJE6#$XRE13|8D{6?;-qK>o z(Z`B+T9g}I1#NdT+gOH3R7kv*4R*QgFX0z$RxkQW`G$5nrYWM!sc*XtNGruf85V&$ zrHYozISbDPE=Ylq)G@woW+>vqt;(S&7&kh|%VNlMs1&ed^mscWq2N2{0<HYab4u(N z8Wvw>aWSKrO1`Ui_=S3aX7}GYuFRw_H5%T4cwrih>yJ!c$iNxjs57WcZQ`VnX75<I zp$j_VzcK7g$8>%`2ME40k_AZ-Ir~RzZKSFnPesE4G)JxV<-G}Vikk!t4mgBw@a5Ov z`o0`P*ArAz^rz`RlF20Mr`h=+p7q`w4qyZF!5g&EoS-y%mVP+d>VJK5%90tceCHCj zBfSj!urzHPFs3fyt+$SL(6KK7<q}$}xCk5$PbCXik#oZ5tyMcBm5+qOmbhcEl_6!P zA)Cc0O~Mlk@!vU<X0vc+qYs)XX;wKk<$YtxMk_T<el64L?!CbrcNsvns;k)=I1YFy zAR6*kyuPg49KSR>+^x6WDYrE1o$^VeFC&hT0j{8rzkZ0XNWSf#E;6iP;7If0YGD)# zY()%LUYo8;K=lcN0*y+0CHgQvbT#Q}wW(u|8?o}XRwMh}L4T)j8jASVsU<|^AG+DG zAzUI0DpVI@S+#tnjfK^EsD^6EW;)3MsfazFNX7OzAueSU8&8M`%WT9Mig2850vYJ3 zrC8&Mx}#El;qLMFoutB8J<e)2WX_u49FrQTTnVGBHF5dtwUYBH?@jp#+Q#qVz-t_R z8d8V59Zl^cT_nF1=SO))W3}r70?Vsg9WMT+=;piPNZCY8dt$HM2Ez;f+n*W3o8fmA znJ$dAgyFZrZy#J6%WtYB$dy>=@lr=DqzAXWA)3%|9|qozxUZsocUgpT1Usw&I}EH` z1MN4$x1>cH97NW$CCiv;Mv9PEcCc=4UMfAu_bPlgUv<z4dgHZ32@7>utel&q=gBE& zv(WlG(gbqxcnVV`JpzaMF6Sf_BvhR#H})YMndQ+jO94iLL51zG+9%ty40`Fxx*~q= z4RLnuUYcNez{AaJ32O|PSu@J06_2-72dF>yKqz`?HxueDKGtC?2s><m<;~YC;ws^s zMJYvE7gnMS)tv;Q#Dt2+EI4rxmOCa{k7PnSZink0vyFIi73c_yu?w!FGLpnmenpB% zmNYG^nEsSc6AB5~vsPX(7KV=E-jmqq_sR>0*9fU*H`w~p@w=uJ*}UPdJ;jF+xVnf9 z<yAbkMIgDG#MEDKB7$Au1sI7Qz#&;d$5a`a!FSQ5nB*WVXvy!%;PBR{U6!)JzOX8; z?pj%f7`oT@+Cz&OVk4%@aj^V!NcU+_<K`AuM>$zZ4I}ryq&2-GGq-}uzt?GbG(MiA z;yY7i0`j~f5D&*hhM7Hi?$}DYYlT20YI+d-j{k0Rs5G6|ZTXn&OE)^%r+h9iRXGT8 zF{_Efvx2AZc%kcnnU%XjejKP1!~2ROw3WAFH5%PkFs~k?QVo3kI6X(cYM7mJ+`hVI z3nBg;>sulRH(^Jm@^Z3@@jzL>*5^$2569DFCRHloJGOia))zmt(o2zYj?-YFif$V@ z51-;>z0>ZG(2RA$4!ik@w(w4pAZlYdaX6NpDrQbB`mWi=YpsbrRkUmcfbwvV<t}<S zgym=vYk~UHbR11i*vUcx>lR?K5f9ZXW;!R-z{i#7CW+_Lw-RPB1Y_9p_!0<&or=($ zu;`0b5gnsuQ{9z^7&qHw#1_xM&93W7IJ*y&%HBly2^;tyhcABWb4*BbcBPijUOyPm z7xs8g)Xos;ga5Byit109<XY}r=I@f+SA-%xyXc}`6$K^y7|RQ=bwHMqffQV(<zHNy z^-il|3tFL73I>{OEANCp*T*`+asp*Ty8;RaEt#RO;)xj(W<{LDT=n6E{%-j!^|$(* z{(U4vdrc$DI(7TxhYgTUD}fZ(*`;PIV&lg8N39pGN<mz^Wcq96|IqR~H|W9D>}R#x zisv*((PJQ&n2YgwJX>~Jd;_&yYEiHH`|M+qlT<UPqNQO?ZpsxmmQBJ7$OV+7JYH>J zDPp2F`$-g9Tu2-wMImxEWIMAt^rX{YSZ_5XDkCU=s}>5L+{|8}IzOsv>=qphozH-f zCDxtD&&al_my~lQxfAD5Ep*>u2zEYfmss3$C*^qWU1aHHFpDpPC!A38k)FD;TcM}p z83q)#tIs@jux>9K<CE2C@u-`DneW&wtZk7$ub)wA&@KKTpz<r~G&di(>Fz{-ycaYW zTLt;znG2*iuY_gD7S|B28jM1Not1ciSmVco!kGF@Qad&5P>~smz0~l8(RG}RSuv^x zXB>Za)=HdDiSMx&&a(h_7;U4$@(MnjO!TN5jJClxlvcyu6TPc?gi_A6Q`{rvsApUe zJ%@oJUyEM~ThR-)w#%zfxys}g@7@m5GYg~@H$cq@K2`5JeyG^{&8@ejwCDcwf;Wex zm{5JmPhBOUY7TAVIeNg}c-u~%5kHmSYx))#u1Y^l3LXL-cv8EVGLMSgY;dwCw>TvN ztgtim624Hmkh#KAf0W_BvVf*FaCJ4@!Yz3Xo4u)LG#o}qa~WP|zB}+3#w|qta^9{N zy+-;)9}k-iF@d?!IDR&Jyv!nwEqHLh>%4ohT$q<z_pP^LU1hb|vqe08B);v=(f=g; zPLjWvQy{Wq3g&6U6qnyA9iOuj>i!+euAE@glVW-+1LemgUo?Y(h0sneGmMDM+C?^O znM}sd1zZCj&Bhsv{G>ABihEhFh#l+hPNmOV+i~jhxZ7PA-8{_`uh%SB6R;0y#i&W) z*ksrh8>z<)XjdM%g^PC{p_G%W8RL4vT`{aWW)&2=(J&I_`B=ex*%aSGaZ~lZq_9{u zZ%LnftKM`4liT(trkPuHW>?C&ZGTcO)9UYCd?lLlf*J&t{^bOC>KEjefbD$h!YXQo z$IYcw-2g%Cls#VHad3~ZWJL!@(DZnfLa+1z42$OHXKX4K$|X;Ar(l-M=aX1+HjI<^ z!71*{UdyF~+zN9wK$HC{s*2iNN-1E2_OkNk6IFk@(WEMcn01w{KvdIrmIrW0Pb?Z% zp%mdJL<T!mSq&S>H1^5(1Vg{4#;!|+g}yv*bu$dACs&ye?L@HF&bsVLh_<#Wh1x2f zu?jKNjaJREGdpl{3M4(wREF=9Nqn}@KQgqPb^~q_kA(%G7Va}?NPjDUjO+R*n`^jb z#aY3UjO|4_Z+FX>U~cF>mLA<Kw@8=J&r_=BNEx5E?(2oO=BC*kKWuDL_=+ds`;L12 zIT<f5pu<7%pztA0RU13G_ss&-4fB<?cur@uG*w+Wi>yE6r<EVsTR~(_xvF1sTh*?- z?<;20vnSz)(qvIKePAe2O?g1O!TqqLTyrrB+qE48FFO)A>*o1NPtaL#-{t3<?!L3+ ztHw)>+U|*go^7mZG64nVRx@a{lI3l<#e&*sUO5<_SZq_e6*94_m@kOL_AB}R_6A{N z<Z=b1cF8Kh#_R@yH`3(qfz!C4G1((N!>4d&zL$T?ayY$_An?6XzIE6!ytz&&Zm-0S zqHY+6WLmcfP|N+yy>__6S-MD0<4@5eLu$~ax#BW(vyEq`4VZ1+)P<<E7X(_3W~)ny zrnV~PKmd&$UVY?TX$wxyO<)u!jQTD5y{%{Kd}B|CogO+Z<UaRXp^-*fj0*I>Cs=<C zLBfp)JbEc>fC9qk6Xz|R-pcLIaWJr^>|@~#8^moo<?Yg^*S~9a2ezWO23;)2t52iU zF7a_CCd=7-xTLr4-@m^C9cvT-UR1OyxO<45Ap}C@8W0aOY@J|HU1W1Hof5hz01Kdb z!Ca`F$GxRsLq@h6O~{eB;G^_?GL2?eCp_vJzvX$9Q8?csmA0!rTlf>psYQElnSQlB z$da^F556zYC@pNfXj?KyX+1jJb73IHbEGh9mC(N%9O=Hh^3id5ScM(dd%LO^Lb}>c zjK@mjeFG9w7xzIE!$#0XR<26{-Cb2SS?y~UpT{3Q+nyHI#*E7<htjqurHd@UdKGtq z#6JT9Wk4S0OCEGl7F5-sWf1J&qC2CvoC#eToL(f8G5lp?n`KTi^u-3~1|!+9w}Z`1 z`eV&!YoK*U-5Xq<uj2D3ALa!|9Evr+NGD@lPr!k5I|n=k^%uRyDA!cjmoW7X^&tCg zeX8b0pW`QCKbhrmw)l=#wwPI@!7*EX5^!VnF)#>O+~Aw~(_lPd$|%Rxs}!|74z^7Z zq4mAi(TQkFk6XunKN;mC>zQpe#<#<w&y!8E)#0gd?C~y+_cV1~xP}8Qbm+USR1~f# zbLmf3g{@vhs<ei6&UMcU1qn=FPgJWV7w~vHXzyzz)0uGC`J3LQ6A+-p8(hCf2g+^V z@;mEm6{ZoRq2~);A6g#ITYHfNkFBL5tT|!tWc3MmtqGv~f!UDJ13x`eKCK7p)wUby zWMCF)ky=2ttd^1oa|XxHfI50V=t1Avf{EAtu2GG+=g>>fsyw3Dlt+i;M6w~N-uSmM zzFCbd8btP`mfBu^yYHUEwmFCGW8+rk_H$d1EtRT=mv}R1Il!stgVTY>kw9^#ZaZ|2 zbY@#jj&u;TF}I)Ew#`j1CA+zuk=FL<^@?Kb`)M+q6_2{Q=-;7;p{kOlbNmFjRr(*1 ziMql2ZXnh_9=Y5rEzWJ6jQ55u9?6OL$qrk=B3Vpgc+n!o4hv4O>ciIl?sBp(QV_=P zbU1C(tmH&1@)SSj+L88l4SvDW5%C;r0A<(8AbyQfQMf(;=?I802}({OCY}bSQYN@< zk1l7S>V33zrmhMQ`n?AV8eX`RQE3pI*7`^)>mog8J4aisce{PuwfcefNB57}ur5Eh zj(M}>=Y!*}S}y$g<#COI$Mp<ry_rc-23`4+OSt@w8>h|+NUtJx;;)-l$*+sBNQ7Tr zJF_=!5rQ$lrCupQq0PMj#NA1<Kb-AOqEQTZ0q_YS(4i@NxaizR&F>prh({5MZ!)NU zj+MJRTOmGZ?GE^B0D}P3%E22>IL%n7CIiUHwjF-VL+9s|>Wd$%$pXT*u#*lg_d(F{ zJBre^&<%iSbfpqtZZkf)I3gS!@7OuQgH8eu@6&he1)=<cc7i0>#mDdmPz*<`eJ@Rq zlH+3aA%k`A!?MYSM#0sqTC`GxQMgQ!ejEON54eSo_W8&CV_smp^?t$E)n^N->5L(- z23s9<Uszximc#z9X##f`C8KLo61I-Ox6pyN67eP3Zy5pYY>T$0aOSoOhi<EI>b45U zZVS#`SDyrW@YS(#`87BX{R0V<bnmSK`^UU?G5L63qBqnc6ZvPaFU1>i3(^>2^;x<r zfNO-yLaqtTMX{6!t<09a_+h(BiJ~qL&Ee`OIWZ}RKHn%UbMUy^#1=cXt&C^QBZ^Vn zUZKUQfLM~Z?U2|zU#~CY>?N!EYTTcsQH|%*Kf%lCRu0lK;%1J~j!vJ`uP9s73FT9w z^!<5Jm*wfB+FtGSp&U^@)|d6f9`aEe4)h7C_1ow|aN>4VNLPt`D~9)!K+xwNG}q;9 z@;J&)FGycOA9WlEw{QpaET6U5)rQ?^m+Kt^8d7__hE!Md06vxAxx%0^GKWKw;6Alf zGTfc<;Lq?l3_3@@{CV$qGu*>JjyJ-A_Wr!Qz(D>EQ_Ft*AwKO;$IeA0D>?>|YaG9M z_3RNyUg-=KJX0XAA#RcP-Gj<xvkcLzPnES?VK<s{tAfEuz74Cir<N^9VrDSlN#UBL zxdieg(3@L?oI#{>EFZgq3~?hxhPFP+19R(tvI}OkT%_o#;a+?J8SQ@Nt6OIsY<(e@ zdFwN}aNfdulhl&p5H#1@D(klHmP^HYD(x`zM|QXX+|MzGEFvVoE{9)OE}IH#8eAIO z@{>4g%E<2St64E@_4+5WEH`lIEKllVd^zoDeY`7Yd2F}v;<R&Dmhj*+IDD1|>)_X2 zT<&DpE1d1-y5kyOJGZIrV^`#Fq=|6>Ei7K$d~4kC984(FsecJSJ(U<h&qLASDnC!d z$*r2)${?!Ru=%Ere5)2=Re{rnZhduO>#K06K;IfW@Ts%nx=s0=*wn71XJ>i55WhF= zRHxro_>Z|gX`t%hRDI?>Wp%z*Za=F}pG*4d=#A66?QvLI7~9#<Sr@;j;VSQ^`jvt? z*E;a|eFbDCR`Iq%#JWDVvZ03ob3JZ=9uRnCn3I}onBgEp-*8mrnm3&HF301`9Vv@4 zJE9XL<=)M&*gG6fq-Jn2N}JNyseoCy43|=9fdF7@{B6*}*iiJN9d7HiK|Lr#S8q>F z@+C6yCte7$_Nvpa)H9^%k*tK~vKN=Lms0Ae<ka=rlPSRA?x}aWffV)%)9L%N8(7VY z?oF?~NePOQx38611beYjCpEbuMCk@mcE03_Z4RsGg?1Zd!;0Y$fck;#G#g3voxN%Z z_+{-73iO~D)4V{9Ua%P7#YaCbU;ZkJnBC8)5R?g;u44u$ZV?CYD28L{2}W+h95h|- zTgLk$DOu0b%bkXMQUbqXgAg|Hox1BjA9lPLEPk1s<4lM(S@b;ngWxRAk!An5E~?)C z&<O<ce0%GKR-5XqacukaY2^hymbvrPJ(2f}rv7WlHy(8-tq4i=TvxtCDuuht*I|Q; zY`wosM0IR0*I9bH%mL)6$}_?~%FE<21E8-uP4&v_{j*t7X<p@op-f0=7xT!H6_%GB zep$*mwjk1=G+;LSgqC5|u`R(TD@;qNSPzX=2|7JW`($}V4N>2Uzq+wk2ii4Vi`zS0 z6VvO>+~RitqRk;E8DoNE9~HQpAL~b<-^0h&ly!>=d#^eRd%>J&(PBGjUtRU4)82U8 zF6xpjHIn0vWyaW(Chc-gCH;Xk?bN8EO3s4qJ{GIUPB>RWell9j%9+bb-kg!8Pj;OD zv|_kQnLM8)KuZ2>PlJ8f2ETNE8y;Q%_NTAE!~Ypw<F;R)rqgM%2nU5p`=KMN^cn51 zJhuiG*tt}I7HxLf4ttN@^r;9EyV%v6W2yNkFn{W0xA&iS{zQ@@N*=Ci9?bEpX|o?q zTUX}wmlv?8B$pK=9{}SQ5!RP9^$+%h9FqEc+)tv}_(ZTkE7!$Rw0bUiGQuRNs`yvC zl>dS9O$M#s$Wh3e2RaJ1Jf$L3rZmUSimV>0&M+Yurd`8-I#!~yPDP?Q_OxTCqD7ic z@}MGDRokNzmYMoLV2yA{(x~Oag2E-t7AW;;XY2m`KcVC5{rLy@ha4~}VA+Bx+0o}8 zLQA{eJ_8cIXag1GAf$$AukhqPkFs|dI|Fa+s;3{&FNO0_wm7YN3lqV~Ye}fguN4Zk zLd;Hj8N<!O70Dg}eMx8kafqDqc|Z6m9moA&fythx<K=`?rl{W0%)wpmti`H6t@Tpf zzH3zE1~c(u9#u?uLdA3wtbukqS&q31ZvfN7Vp%X(7;2Q0g?NP7XfM*`WQ;&Yaj=N6 z&^Z;}ih?<Oe}UDc^JuaFvV(=WFh>)t7N<#xW>?cRi~DQvH3IngB1Wg?44umm#p5oO zQ>F1@rSJfRw}_)O0sZ6N=&FbR1~^Il9=gK(tuNzj5&#%X2#n9vocq!ZRrE<@EGm&O z`5uxtU~)c_!H%LF=R3IyeqH9!c8#hoWmshmXGKQFfXt1_V#&J1Ab3Xg$D)iXt06;x zWyJ7HtUQFGlhiejuDYbz3f{$V4+0=PRaV_gF;P|92qEy`q{b;HjZQd8G_C-N|7URo z=O@n9T%Th>tYnJsquF9|WvwWccmqI_<Q>*cl{K1A5YeV-PAeJ%A4~auaAt=oVB#o1 zStQ|mEXRtk!8pYtUO*{&REZtE>67>pKL<$v5xtM{(=3_8reQs`1*T9Zm3jb;XA458 zr>~#?7*Kh6G&N?ZR<id>W*3jS;F9qk*DMdPjEgJWlqZj#KMWpx^Pr0#e+irLWX#^B zounW4t<eNq{jWoq)N`0Ao}L(QX_(yzWEdDiPJ2zLjq}5t?9do}_f1(j90y#6%L!?f zC~GkGq_%*D@N<lxN5KSe4Tgsmq;S9DDSWkHRBh+NQ#h09t78dRcKYrr;Jbn95^{B0 zv`*tT0e0d((ui7AMC;uo8f~}md-5a0Nk+e>RK*sE-&qgFI*DcxoMr=djHN2oq8|b_ zV21HCI8Q{s2}K@e(Ff@Gc?^OzSB`)KPl5(ai0dOR=lHo9A1ze@wIVE`d$ye534ozJ z1mKGW0=bMMssjfQF5<~N-{#h*>6~`f0;9{U2dyt!+(~ONXsLsyU#=q|Qw`{E=<qvC znw`<0;V|LxxV%UfaXyDn@M}a;qAD?GAg4u96zUB+es0STX48mR0?F2tbt6kp-{l+q z){fH-Zd1T()-@yMXsYx`y}-LwHy5W={Z$`N{ZlLsM=qfTb_5dRg8i)2!=KUx-2N0* zB*n^5m5go(imHs##Uh<D!AuC(X}>tm1Z$PTHG_u}$Wp>+u~w*f<!a~nC@-!$AFNtE zA9jS<)6MwB_h@l+TCxpNsoiw*r)m1`k<QymI#X%lzHyYGRuNXJiM?&rDZ7Br*fkiR z6<JtZc3mux<<TSc#c|n4b5FGm3uYFNTk3N5Zicvl;D{+vaNW%K4A_hTSOK-NzE14% zi3sivQ(yZlzvK0B_5_~lp}?DP$7bTYc1ro?ORSSXngM*|>fK^RtU*WP@lPoRUz7)4 z9C8V$+L0>2gx+_8Y#ooH`=8QNX{zC#0QlH_VCom1pDZ&V;YilbPsoiu=X&Hpl#LQ# zsNfdBqUJpbh!?&l$MS~n;;Xz*cd&wX8Z9w3KHU0T>X0UgurDa=H|OH6L}M}_pfQ39 zxo(QCo-Q3Jki^Iyq1<?kSJctT2_5H?ljDBya6INR@pCNy_(72`;N_QaKF~ZPv3p$e zU4iW6365r#5~s016ONcL0tzC@<xa>?TEGJw#<BVk3ny+523Vtv3yq^;2?T*ls=oN! zGR}$Z8GQ5AH(!4}Kz0;v&)(&9+#4;=b?@i!coC1glIRg<KsA^|r-idn&Ze*xDcm)e z#AwhxPFBox2G_b?2wgier7IUF1J~{}bgAVbeEk$-z?n|sJN2kQAS;fpFX@tnskmC` zVD3p?<Q#$X64a`i(FLe0asH8Yg;v*JoKKcOv+y`*2hR)nfi$IfsaO$?=EJ@ah)!#c z*`|I>X764j{{Tdg&QyYoU=+N0^&^+!z;d#10I<?GouSbcmYxM>E9j_#08l`$zb(kW zEazcYag}-zVlEX$d;|gmevmhsdm)s^I-!Zwbgmw17V`?_BsuQLft_HQGR?FiMaR2^ zx`R>cP85I9C$5u~GKxWv{+IwKxqSu|TNdQ$GCPfBIfOerh4xnU5&x)xhjoYT8TA?6 zhYXIT1>|OKIaJsM3<x1!lIOZ+RavnMuDr~W_sE`e#b6OD4Fjjb;I{40?eG6KNk>>r znsOF&10tD#5`djay37NR6-i#nU_`)a<_`KYz1}H2W5Qj0id^5xXoCFajx&HaIal@u z0(JV1$*)o(kc<ZOJI%&~sz7p=GxY;gBie8}c^n5PFM*>4;RbW4pqpV1M-DXtW1y1B zBoDU>qoVwZ6D&Pz4T@7v$hte{m-tzmZ7b}D4COhB&gv`Pc^WlJ30%{eD|MkfPBpm% zhft>wBzX}WmUw|{JOX^j(@pndG9_PETc9Vg6Ib$rVi<%&E&@AwlAlKN_z;V*N0Ub& z{pUX?SZn5WbpCJw_bJHvF)UkG*Y1gCSHVUbi&F<DZISBYU^m(?g2r*}Ce!o%U=hKk z48)ZPjV>AN!$7-oF&#y^PGkm&L4PfBV<=G>z47?SBGUC0*=MWRd+-<~NECK)e*F^H z$7tPv*?SeAE`b!h=MBWAFUvr7Xiae(kFppKEf?}}jxk-ixjQuBj`(UYH|S2Gk?>8c znpx+upq=OU=47CrzQFp6AZZgxhoURNuY@65<_}(p<ogFx&OcszQDTBsqL2)smMNKx zsggBvbcDnxHIYs!dY>laU^@O<=vWyRwoNg44p2z^3g|4NPp&x2s~yC1s<|X3v2(zY zA{;n$$tj)yEkP5`qN=3tTOj;L$NLZd7@T*5)*r81%~obzR_1ZBttgZdyue}EVTIOd zS%RDowV7b?OQNo%FC=}1jEtO4nU!8WiQziW;<0ZQhj19jQ8vaBaJFKi0oZIfBfvv- zuReZph+F$+mV9XPx%=_+=v04Prq1t_UIjsoV!&Y*I$*T9(g*{CgqjFI7dS^amwekd z4CoR%Mau>L-jv_vl@WfB70S_w_$Jch<X*%%c?=iUsOlIU!d}gZF4Mq}>f~@-sj4HA zPt^DlY*u4JcYW{aV(lzmA~DDdfCQx60~9gZ+RH3ifPg%TNt%M28P%xeV}Tkq90d?W zw90TDNEsb1=wLY891yuiH8Tz{#X`MBltX?hoh>*hmQ;CzqhPo=-k{GLoUvc1`R4jy ziumBe(br_NLBiK#@<u$GP(nCUDbWy={7`%D-5jK-_|<pxQT;9v!%USj6Nyzr+XR_N zm{$4spFYOh{;~Pg+mZU<)pAC|`CBwaH~5;CZ)S0c1!zRDdEjFZNH76C@a7H9^&gMv zV6LyXnn5Qb-vsV!CPS^T!PVrj?cS*t??dYvHP^0P_s*3L0iqLUW-Q%`b*$OYg2Y*7 zC+X9?gh|ZlAPB)JmLNdTlXK5ANJ__*@LMOw%2zUHKT5~Us|x>zX5#JOm!o8SydA&_ z1ugc2KzR*2ZWX|6tlrZS!v%-=`1kwWFK>oNo&IJxgr0Cb31uhR3T*s2$C6MdWL`y+ zY6%omk<#Pg?4bCF3ECBigd6EB-caPfDa74_&hT*aAlyH2AmR$apdXalcMkT3`Sp5O z7{LTEH@ZMtiQ<b<``aXx<Z);>iZ9TolD*kLdW$FN<tJGHRQKF+`kf%~!RyS^1<NoY zqX#a=musHJL1#GI2#bP+y6LdY@tjhbuYYB4e|Z_au=#TEziM@k{p0DwZo1>qGx)j! zRCrw7eR<8o1Miw~FK|t(gXO`UZMYW!dEBFRKD8aJe((4DHwE^8W3blfDlMEobrm1* z9|qMG5*HeDXfJVPX%TT<_(gcYLl1GRrD+*?`|={4#Ltnt=myg*`2Pp+|6juYe+B>l zbvfKbLi91Iz;vs>NPkQ(Rr-n@Z&N1jeT+Ro_$N<DUVS*7=MQJ&hqH4apq=T1P!v=| z2%kMxGJ78PFf-Q-qafbLUief*@~f(W%0|CP=fD<FIVhWPA_?4hA}~Jm>j1r60y~RZ z6p|>(we%upvo*<;#OPm=>bnk-+-lP={cC2WTB+UxTNc&JJN?>VSBviNKmWE&7dx%6 zVta1Z)+(m@NXkJ1w<}2ran9y;l*{pgnf$eyX|`JBzHgi-VWV5$cj@~W#j^S+z-GzW zmCcE67u)<CGjD$x!5#vWIu>0kUJoU17WFR}q5xbu2!?o#0PoW+f<zHN?<yGqHwwf8 zQtDdlK8O`4;YzO<*&FQ6_wfiIz7|2Y(4Foa8eQZq(H^1Inj-Ho%MDgT@7cq3M;gsQ zO81O(evx4zr+7LC-X)PS!+ki*S-XZap&JqPPOLq|8-c7DY35O>q0>u`R8!j}yDAOu z1VNo(UF6pMdYrt!zBt<IeRF(GFA-_uYY@G!Y2B{Jlk0SHy_{ULzsB_}l|PV4x>m`( zu9LGYn#R{4EnQp#;kX{hlU7~tqtDfQtAv5yCs~fJN~np(6$A2v5*XuRm+W38j09c> zqeIJ&YhKU>(U#1x79YV6rs%OWiYXH!8l(DNkOMzV?{lC2hkWSJ3xx+kosxwukox3g z&6-9Tsts|7bi9<m2%%gNEPllkk@bS1<g2IibF5Xh>J*DN1H0-VLyyj8fYzfpBf|xa zK%Gj}$}fhKM#`Dk8E$UymNw-r9~}&{E4-z3eA}-R(nx8*4nXKk1#^r)%<=wvA1l>T za7M+ZKLPXKslMlOG(N&Et#5e=`!5w=(V762Ak7q8yMn<q^upNftlM-TbYQ?UKQm7p z^~l@%Wtzcx%Hrr<<$dY-%3Ayjyx5uQ2JcW>9n4PwM@GwYVDS9x<}btSc;jF=D|6Gc z<rGj$Ee4$MDcqY=@*gBDD(YqQvJ8d~_C2iXMXbL=EgG&+4F_EQ9!r#yha#!12B@;~ zGvmN$0^3;pp8Y}DaurpIEMcQ{UXT?AuPw5=%;1tz8bCZUI6GK275Px&ybFx?O^NYd z&3AWpJD>B;35O$%8M{N=P~p~jZHXr*9l;ZwQ)C5s{VBZ^;$xF7^x(`BVAHOc8G8%e z0bT$J0>TIM2LB$;-qvd${?#eR=wF#~lwf`Y<>+seX~+Lkj(-ixVJHUdVwqwLXANjZ zaHxz^$jOtFIx<<i7g;da?+4GsF-035&^BS4w78IK+4i8ClEVmD)tNydN`%>k$pIX= zupsyZq{X>Q9lKXX<`*tt5LsfpM{&klm8Pn*6(kF`{2~iI<f@j`6v<69GSfNwWq1EL z+&J))uff57_)(|3`r!WlpnDTm9NL<-E-J>lE{fjvd<|!6^E$lj!;xMRn!R-_Xv85Z zIc{+*@I>TfLnT)`@g5@o=6w5;psx>sYwwY}p!VIasZ}ccPH?;bR-c{Sdwz`T^*RUJ z*YN*GzwGypuY2&%aY#S;R}VHk?DazFB#xCc=H=yO|MJUznw<|`zZ&3G+hbq4L4Gw` zL?8P2=nJ)@B#NzY;~f0;>jz(d;~nPy$DX7Wi}&Am%B*v?d#~|s?BC(^y?pwTcH!aS z%U-^?nxG>NIgq97TZ9QX$kx``J%CI3V4t0w{se#jX+QiFyz0TWpO_X->Mc)V_=#?p z;)%Z9iLIL;v&u&Ye>x5o<eIxm*pKSF?1BF@g#W^~4Vg%Qx9aG_aIh^arsTH=x4&{4 zE3YjW1v`u{7=<{^*F25sR{5a4nT=7~wZs^#iQ`C0S+lIK_1_j>i{2j<?i@LJS!gl9 zvY*_h2k3zPntWX-hb-h~RE|E{F>w__5)TKm)B59w4?na}69%m32Z~BvP+&q>ITUgi z`r`+R{dIg0I5=H54e@+Y<nIqY2O|}UteUSdOO$;@y0AAtrHeN+-1XHS39m2WoFyId zXQI%*XqKN*G6tfTr2D5L1(vqI#Ji&+mb`q7*`TY<6%yVCf&$eo>DP@(yG^A}`Rgi& zmd9!EG|iHKU}~UA@M<|J`gI{P+kSDFG@N7<TJ@$z(+4+rY7d4R_`l)rUv_W!oUW6g zWWf(_4YT*@L7p@KS+U&cXss99-{es`j$KbFe>-aPe^6Mh+`XR>;W%>%;9JSQ7K$Fd zYrANoD>KF}BSx0|AtTc8i#KT&T{6opE-pH_?YSE`z+pzgBALb|OBEZR2q3$X#u80| zZ{CaGdrE%4W8-3d8FN%CS;~qacjw|zEh?O%`K*5nA2nY~Ori2ppFa;dxU=~a=*;0f znprMspNg`ir>Dy-*tjIm^^MO*V`@+uXI8te%^dCP0FX1ncff7sSe}sKRh|urd=ML| z6(m475<J7d#W)3$h1h*c_^WJ8_m0le^!VuPm~4Wwf^g&*dWFww%AM37^M`EXt(pdT z=c21yjutx!m6@qMe7h_1Qv87;g-J--e_H~gXUV*>)op0(Xjkcy>{$5sE-hHezBrC2 z$uz<2JzOV;6u>+>8qX10?~XgW%WSeAR;|jz<swDb5%0n@aCLl1oC!=?oSQK+2;&5q zDM?jaAtmX?vB7d-!bGegH!FC8)!>=y^isQp&*1J%PO<fO>114U)lzN=(kc19r`?GL z!KOHY2fL$epPaexN_uW__*T*+{*oz44{L5mGh#L4#bq4N6zbqB4tEKThQZrlBRDx` z0v}(M(29sXmTZD`T<F-bBqLn3;|owDgfQVs<3$(yZI;f?S2}KfN4YB^(TFZ6H^kU@ zh!7~HjKHKBaU6V~CGi;ZJd`{;o=5qDVq`J?fD%bO(TODTRyTMs!weSvZZMzsg9rET z_a5BeDqE8epKMDahp|MeQTIrk7s{uRhP&qB$|RdrXZI-T{bM+|w|?Ad9sSZe-e_I7 zkA7(%Z?v!BpBC!l_OEZFIRK$4*;(xpClwog{%JlxC`!3NT3FN067Txq?r?B`o4XI< zTR&t+>8-adk24g5VLs)NitYgXjo=##xRh=JNdYtS+-n5~AYlyOZk!BSSO=N@6e1E$ za?SYUT(KAtPwS@qbVY0&fa*=dkN^7hU;py$T7~ZwjK7f8`R*saaI>uDG!U*nXXIR+ z!{>|B<wD{B{!S-lH`@2GStWQC9yMG>(Rf>nmWi&A?chj<(;f%tN&U~Wg(`Lx{kaH% z#DH6^3K|~y6(-fzf*Q>a13da=cznDuJT|%|3icmiBq)Y8iB}D(!ppo}@xSZZx6swm zu{(ESk|gBIn|(s-bvACHTN)m(RcX==DmDS<r=90Hxl6@*l45itJg9{rHb+Nq#n#ca zTWxHA;~?}8m>uxHteSrVWn{?zSFs@Th}^iNgzs6v1{1AN)Uk1d5+8lI-0z}i8y<CV zZ8bVxBeKAsa5)T*ao?<!M_*`Im*H`!=HMN}Du)S@v6!8#qzD~fR7Lo|B;s?D2<Yse zLL$76JC%DdK@o&Azs0j#tF*&PxU&?_GN~aZF&YBazeFF~#g*S$cF?JUbHQnG*T1^^ zPIr!e31Oqdps>?=XOTPXoTgb8pJF00-uRH0B&RYNaB!X<KK?2EC>-d7!~D2rpZzun zC)~#)YBkxW>LXYYXTm1=cI!ASeL+4S93BnZ@=f*U9wLvtkqU76w%X$Ijd!Tp+D{{> zw&(c0c_hmj`WadNJX+GiY=as$NiY7r4i74qa&=G*O)gw*+*x_?eC*8wM}loTA)GvH zrjE$9U@0IY;GGJ!Aw=NI=^GVgGYs!^J^dKfu&$a(b}lQw9?xi-K*AuU1-Us~rAyR> zk_d91E;O8caeTB@0)>f|OoPtgEKUDOx8SF_{bWx!LyMfNBs%Dzvx7<~RtHed&Gu0n z=iEMSe>{WL2|bJz$4dM&*eX4Bi(hKOF*TO@Trex*#o+(Hf&c&3m+5W#EsD&`8ATA` zy@C%)u|X)&Qy(Xc3~cKxw!rN@ku{k<Fe|b>91I5>w)|40@Pd@xQ(`tNw$F9SrM{J? zh%=0gIns;uo0K_7eUC11%R+3n9u~3g(=Y2{<FGA<t4_ZvzfrM|({DZL0O>PaHlI2K z8|X1qHBu)82iGHFLE%Y=4e@jok1@rscB&*PT|^rnATwjVCGNy6-Q$5$J^IuyWoJEJ zAk68xsk+%&^G;bp4A0|*ntd4Db5PB{3fzO|>z&F-LmhB;>(1yD%g%bCRK@45e&Q|f zWyWkBCrLHm84Nqa9PYXG!8Am@>eh<*$&w2lW{piwG3zigv$&F#pUXbBYC|1=Ull58 zP2z3~<^JM9u`>B3C(wJ7NumaLSJ(_`UDOT2V?bxp_jy#Ql!pv$+YvGEQhFUhQRVfP z=WsKA+^agd3VkA_UT3ocf96wZO8c@>6JL0T&MQts$70?LLRF0?aBA@G+OAaq*w?35 zWpCLXMEe!a75v>wC8TWvyQL0Na(cN+NRv=&mAe0y8c58y9E*(*c)5E=(S+Svj{kX@ z$lEbk_Zn)dNOoKp2J55rba&U!{gd=^pGzNi2X>Kg|Bl?^J*`=5u5q*aYou_KqabEn zh50t>H`2LD{y4a4D1WFJ{WgeGIr;zcq<A0aB{lR58{Ms(CH{P5ReG;at?#;np3BML zf=-6nsmkE;)yL{}n(K4!sK>Drlr+=d+*WVXNa^w!lr5izz5wDnsukJnrh1erqEjKW zmehfoStv0|UY3C}+|Rf&1V!1Yk^vDqY8XYhvddmxaHv@xEa#Nv&+14jvEY$UMUpGg zwi#75k<4)MjH`Q4wr6-giWbRK`^W)<-H|#OK^|e=jeo$WoF96TE@-sm`~fY)s<kp( zw9gqq&M_Z|dAiF_C+<@>dq@Kvf!eh@stB41{;;q{?%(<E5Ww&8rs_ssM*e@Sl&;qA ze}(k_K|*>H5w}j5b$(bUq$Kwh>7i;Hk}P<1+zDHsRPqJE3NQAe=!;{NXL__=nb?hm zd2W@CiN-*FS@*#ErKd)IHOzSSePIR^t12l$mggn+sTE@QZA9=ph~Kvty$6G8;X4?7 zq@?Y5`g^h}9me=Z#9eXtEhn*ID23o9e6c70m0nbVcu;!Llm8k-E))Z~`<ptM+TNx~ zfqI*CX;y)h*6zg?DLY)3>?wzo><-{9hn1|ze6@P8y~cwjQt~}|w3i3_pmwkinhloD z=Z97M|3x(heDOu~)>`k_eN)*cIjJkWFMU!>w!mQUKLzTWPp@_Pr8E5E_pR<XRy^A} zrpJ?ta3I)!(aswucPytuTz`P|TzL52OlwtnC%@PzIWZ~8Q7t8mEa+hFJ1$l+4n6VA zn{}xVgS+QG)XOGf0p%}b%>LrmClR^Ks!N>;Xz4`j(=Am4wKiql?gf<=lFv3plUX<~ z57c=nwv`C7`b+#{95Jn+pp`06j6RW~dQ#Y-!zo6P4??ceRD9@+mJ`hR2QMgf-Aeyw z>w1PO*<|G)iKdtnC6CUcEWvBHL?p!56<+22%XsuISx|^~evw|D;5B`Eo*X3Oy{)YW zUv8Cg3opAr?zen#g}o&eWew&qQmpEytJ9$e1dcX?(Jm(_t)&y1bbS^8Bc@PH%U&?J zQxv@-60B@;3T@m5)QXVanq&dD4>M-n$;M{y_<A_rJnDOVV%ERJS{{_`Oh^1k>}I{b zWAiql#Tc2pd2r|Ts`jAz<9_Xz8o4Q7aGJei<la#=d`5AwzIJ=3D2^(waqHR}9)>lq z@70a@r}#Xgbn$Ms<7mc-TpI7v3eA+Ipm#8&W^=1Ic(t;sPB&FPpucoXe79$Gp&(S} zkNelW7rf-KvMTc1H>r@)czI-hyRe7Xis!iv&49aizT#xMMXgD($%z#Hg4;`5gK2t$ zb7cxX2wKYtg)^j+*3McbI4$XwYXb39bbsMaWt!R7Su!PJtOLxATDwc$8%xfjsCbsQ zyMuKNxDc3TEA{58pv^psPh+YahuRW?iG_0#42j7F_A<-3M8|TTjH^JJ<grp9xUZ`R zM||C3{#GpND%Tz-$IUXVUR(u~zvFr+^g+3o3Pwd1pZ~A|?eoob70O@xVQZJQHVP*c zlcOX^<ZQ|<yo^naXsH>Q!f+}L|L)=KAS-qK%W!rOe!gS8^GOdWYCG!=YPOsKa;`q9 zqT_6Mn!jv#nm@^5u183k-=-J8xRT313B&5RRZeQ5uJi^WqW8V&F;?;HxUz&YxRTH5 zj>SS3zXP*L(PD&(tuAn&@RK&KRZ-o-yDKL!4SQ!+$^truS!&oVC=v~1)F?pWI*F?* z!F7Xtj@6mD3~&iB>7bL@IC-CpvA$lzv=aEK*?u5_aYCF4;Vg^+k+#3)%Qn33RM0x- zB70aqJ(ogvSYf+d>yCOWsR^D$AQE7@0ZbG?B}t`a7at_E(~NUfB#RvdR1BTctemAF z7{~HeKX`V=Y3BbCXK7akgkm?<h@zE(8xZs9ty(LtAT9}wC4;z`BZIW&NuyVp#TS?p zp_JT36$#>KYlOVLYQKWu86ZB#F@p3sKhGk%UZD@E0OR@OFMY|vKT9ul4NKbb1?Ot; ze8VNTmZP3;&x-9I<_3v%B7!dLLOxHV1l(D4%2_I;wmh2sco<v=wzP?yeP*1TCyU-Z z&XRQ8V|zQ7b2?qUUuZOhX;dL1)_2x347)ry8j*OTmXa;-V&T%z98}&^Yn`A|%nBd8 zn=HrY!0%ivFAfx=QZ6V6kmm6z!B7fzKvYhqrYew9kU6qq$d3fD5N8x2;#)4vC;$XH z<vdy_Z39i{VL}o3-NzF57tvhCo=%orFC2CDr6N@n!pseMFd3$j;Y9YdOlrbTrg7e~ zatb3!>~)Hz)5ukbG$1=%Z@9J9XJQlei^RqzGMk%a4Z{N2S6^-<_Y^5&O^&ksr=1!J z*%e~iJQ4ZzT9$aaoS;Et_z!=7m8y|vg$yjZ4-{uF5e=-1h0?enb#bfEs@sW^e5g3C zat`-s!Acjv+kwr44aAgfrEJlu*Mr?jvfrf=)9j{=)zp%l;H;!j+TqW-sApqUjQ8i~ zkA08TM~8s!^GZv@-Ty0r-0F+6ME_TQ;yf-vc+gi=O#N4W;yy0V3zs&tn}69aJ<_r^ zzgc}rnFIuh6fh<S2d<Wm)l%S@v))FO63&D(0|E%D#n|<d=HH(`eD%YVS2qBjEAvq` zLB=f#YC&AXD`3u55>X=5IK5p_G<2i+!7Z!)ei46`YK_c<Nulk$wdZp(>!`_vq9XHv z!V5%FqxmaeiA+?ZATk;tVta$ys!^L^6Hmv3J^%NA+z+mU;e+zbRx5mNU2X~aZoM)^ z2K-3lz_HJKErngV256^6drF(yL0Lthf}j%e^G#f37CncQ-5nNygwWwu#Rp*s9DnP4 z>a(6>6xRvv$H_%BK8a2^q2Gz}Y~2GM2E^u_#yFbAx3B(GC%h7>>{V7SqA4(jpD5(6 zlXKCH>IBbnd7_l1bbZjrn6wUd8&-pnz^=RurLu$TYnqFRh@eY&z*2LC)SXa#tiLOO zSHE|4J}0uOg|vYuFO~}=m^}L~kS0567_{FQ0FjIvJEg2}L(w)9D!H6;W*p6AZLb`> zvP!wbt{9#5A#H=j3@PmubAjn}&VZUMp0Ul<AdG)uRvx@6Oj=<_1TF@t01c899`N7} z#=*wgi`on8kNf@<oHm!+>+Sed917S<(_}FjVRM~?=Gxxw&a-%bmlF59l@dv1%l@ay z4b1w*@YYs5Wx->1WgLsjw%21eBvXYtxXhfAKSZJ=(uk4Qw@&DbTFl`1_pffQhl_%v zz>nk$SdxXX@))IAz(0Cy<1^)pdlhED$^rB@iY@^fWjC8}2gBKhQsW-|0@wd=c6<#t z<{$UNu+}bF;0S{5?HGc>`B4&-G2?O3tcfU&h7U=k8U7dS9a*i1WWq+<byM?mUB+QR zIE*)UHj@@M+zjhh2u|-ObBREtWt^?QqEQ%o#P0Ex>S!C5B)da0V6Fn)pz1zwAaH4J z^Udl{^xuV)#^>fLAxT|v-^z9NE`aS!#$^?N;p<l~Rm-AtcuAOdROWnlKyP*j*s979 zr!E>*CA|QHAF4h4Y`4y*)R{Z^vFRr9UL^kWg}Z)@I~3}hu4=WalR_`N`JfxzdsfEM zmDk=zfO$tj8h*zSAzbrxna6CR-<7?mf20y)5kwi}e_9DQr_0GAnPUWl^ph*Cp`CN{ zjFNPUj<~FYO=hQ)<v7;yLI#$k@TI#Chu04d(=H4A$!xw{Z2M{q`kn><fmar(ncluV zOVi-(D9Yg4kN)xYttz26&wvkH^qYbF8C9p0)Rt6Zi?sPrcIW$MG`t1Qh}3?#!-5mK z->i$*s1K%kv#{Hv1O}O5;bqtiR;tBT^(V8`utQ}~YMWtCX+Lp0$<l!P$<+@pvY2%# zz|xZ!hz9A~X#7y6!dz0EH~d6YH0aU|;>BryC1TrHD13$(-OFesD;bZ^<GlGk!Husl zMm7ij@VS5bcL8WXek;7t{RvZwT`F8Ccl#+g(_b)C&G6U?Iny5Gs+MIsk12iITS;#+ zLaV|^B{MFAe7hM29^cXz0w!C|5bfTsWQCQd*K3FMtt)d@@$T)h|Dv&dC=^F#>W??z zGKUXJBYv*J@6eCL<LT5nxcBz+RQc9hi5t+76~W1e!w1ysolA7rvUfFF8hm$ZyW)!0 z(&lQ)ddeoCbas22Jt}iXRgi4n@ic5S_~t2J`oT}>0w^QOnn-pj7b}Jp^VPq>N$k~A zseSzOZIi<E>$tS(7U=*C!^bKC{{8v<g{@U>#+&d514&+c3KPe)Njk_lS4K=NvD1>3 zr!S`Zd78|`zbVoyjJyJ7u(F^=nPxP~6{;zZe9FanlT4Sb(?gJ?(JS2zcy5&ZKAO&< zTL7Hzu-g@~wu?kqu~}L&xajwsJqXCHy8^@qt)>Wn=GaQ;ey8P6>rI$tho1&{igk%# z4aU*zG;WaV+Yak&P_M#{4J{Apr}VO`av572rt6PSqx0m{POI%5U^x<sk_NPf8z;Zt z932mbtuE`gJtO$_SCy&>R%V3d=sD}T*JS~%ZG}f00a^go%D4L#Fs{o{;(w|C(^V2- z@Y})0s{U@{%kRte?g_Tq<&@<6tl>FN*(BHi5jsc1pHGfa<uKeBZd{+7gyI>eY8)LN z!3F^NhwF%&u9p-It@SO{|N57^1NG-utw!-n_6V+>?x|xK!K%LFDfNs0eAW7xz==`` zl+sFnh6JxaH_t0koyk>9i(G@vBu;4Ww-pa<IfHnsXK5AQX1PWoKvH=~Ov&<EC>;b7 zmST+Z<%peQ7LMdmt!-f+_zmB>kvm0xH)Z1|<K8;%!sD!E>M-hXGrVoYU?s;k`ps9_ z%g-U(!8JdmGg$8o1hp^wU-!Q%$JbaOTE-m#nzbw*um{Hu<6SW#9bfrJL1P^K=9D?I z7Kaucb)lAK%t<ecnhtakX)wi8;6P{S#*K4rHkc~&#){Ezay2GmSZ%i+!?5<!+2pDQ zhY4`OdN=w_z&S?@ZEJDE(ShJVg@37NK@e0qbn9H8ie(p(J3r0hOEv<Ko>BRGQkIs> zSabw<kFcZHcB4_%#(xYjtsHeGo(H=_QeOHG$z2bNeQ4%cor(Dq9v<}{cL@J$VG(pN zJy(c-+pjI8t@~0gIry}?-A!1pBsL1w)~+dBEl%06(V}&>Uaigo;a9LWxQka7#cE(U zgwLm5t<gHs@}3I9C5e!YjC3BzmZPeEt%`9xB(=9XT$F}GiL@S1KYy^RWs7K1p0%n} zB4RwO*IBN<A(w3Jym0PuD52&rme|YDaZO<)<1zD!yf6Ovp)(wBhCd8eX8t1XMlEKo z^d%l2m|O!#<qgC|g=2?2O`zHR9r$M#zkxqCH>*m(u(_LH9wo<~Gk_V~&O|qjMR{1- z<LP#RF3zutF73+QLoErrp+HAr6;)CT%_anFxzjW)2zE3W9u8J_!ZUSU9sFIH){X~& ztLuSXYt?*<hE3FMw?1ORHF-<QsKh5fIlHo=pz^wJC?ih|(V!(Z7>A>+ivGSW;wj`i z!+Yf6><W)$wydDez)Aq~-%)Kb7Xt?gOrtBlh;z&e1p+22QM%~IF6B_i(ITQ&qgXQX zSKp&%Bpxp@-`2rtv6cpYS=W*}|L0ZFPRV%H1>I<A3O9#ij>9~e_19f92cNp^IjUcU zAHSx_tizVmu#sNPQ`W7VW9)E>vYA{$cy&-1uGT+^1GSTHjFc;iNgKtI1#w)ChIy#K z^r#6}bU{0!#J69e-|J5R>={Vyc{|4smWyZsBY6Hgm`|4H$;@+!>X`iLe4h4a@d8-6 z^w;=wkq;sTph2dUKX(r9eQ|K~;qR1l^5}l=uTk&pVek9n&FkUiX1Ej9E5k%xH;dlE zgmw#=H2jJ$4Edw-We4|;um5<ArN=By*hlG5{iPyTb1KZL#EUrF4v3*B*Or6-c}1ha zgqdV16z-)fjy$AtwlIj~bjoz9YWS4xKCTiAiJ{aZllYZeWq4p!E-Gk)OCU&#RL3GE zxvsE>t`#M<X;JSN>V<6(Y*ep3Y@ycB;|AI2+qbNE?1cMYZ1(#1DgYJX_WOOb6mU2X z>cN33&*vN$my^*`v?!e%HYXHMV&l}FW~D_YrUcWoOp||56;`4T-^1xWOF#4jc8=G` zc#h=ZG@4*`;VAg=#p`|pMaFR084l^N6&K?KK_UJ$VoryhBU(1BJD?Ws_*QUlRdLR( z?CH^q&QgjRK}Ga}v60LTUDEJ#nu9m5bj4ws6BobbD#sUBKs?EQLqSz4TX(CqkD01V zw(a=CX*^$S(DooaRW0@M^0I%HrdXP9pVFk44-(7-E9{<9)<%ruQDrSf6kX1uahlCw z99Sk<kE>*>C;jh8#kE^mjtAep_?|%8`HyGmtaq7a<G~Ynsa5wS_P@$<In2WjPBA~Y zK3mMg4w>7IdJlX51%!O_&;S0#aPX&ty+2N_5gh=-!h74@VSnd%qtHe*ISxDP*TbKM zCa-Vpu0L4+(x=qL^Q+1tni5eIr0A(oyI(KZ$c&I1F7Pr_Z!Rw<Wjh<~h8!Hvx8+l; z*xLt~$qbPb3&NZ1S(x9vz++V0Q})VkQ(etre!Lm()8eQx`|iXk$e)NpSR51+Ebq$S z|2|H!rW<17{>N*zcYXe{*!3da4$C%uziQ~H*B@S1<Nz7|d&MVkdjskmZ+3=#^CR4V zU-09&iJxg<`naGrHPNK06RvU`-3Z1B<`AL^WxVjFTBqXFb$Riz)Ek%F6M3AyM-h{w znj7&hW`#SlcEf*Pxgv}+m1=04Z?D#?3Hl4GLrC_J@v0M?yqU$Ng1?0Gx7838^0hR- z47?*~#(y1NMsqgYqtRB%p4%opv1f7x`HN&cj%WQ_=M?<o35iTkZsVm}>%sv8L!<rc z^p#{J-s2G5XEP!<wUGzHWS(W|^pU{nlmLD{?VfV{ZMHwJ;wf5m9a8~SZd6(~DpH2w zDCH!#^*rmXbiE&8AgRi6x41@M?yc@uH(|jzQsL&lb{C6CmHRC#5$|j*B{yu}4wBks zFkFbnikgI#C5Wk~(w!_;ioM{dMOI!+I;{So|7{(+$0&anU!rQpefqvyqO;tRK%8G3 zyQ&Pi`O~wrJYH1gX_j2nxaX)3sM5;u$QTqb0b8{vvr&d$ni?i{5uiQlBn<u(d{zFm zLI2V>FZ$8@<8o1G4=Pv(mDn+Zif<MP$bnaSIrBB&air`gbGN(>CG|PjK5Df$Iw3HG z+ajXx*xd#f@ds9BpdAaV+bw6y9Mg)l1YC=#BY7bMcTfJM(fc$R6R$r8L7R73TIZhR z@YThCe8`T^s}{ACx0s_KXE0UxOe-9HXo~L@mKIm)&d3Tx<}u)^7QESs7i5Acs|_Le z(}S-(PG~OV?aD)d?F0j%Ax^&+Y++dB0ChgY!LbkvoU&9=HwYVs;i?Ky&~<||qvyh* zx2j}2-g?mC{jk4C`DW~FeG}Fm0uRRc-IoXvU#F}Q>aw0j>xn$7K&l#q93zFqFLaG~ za)U0pSmn%6dh*MlhxKTgOi%}41iMq{6|Tyqa^;wMgrW2J11|!`pmdJN6VaZ8<GF)! z-H-+R)^NDK)gm$HIP~Scub(^bkJI@O{^N{L`f+U%Cp~^QNZa}xBdeQO+31scokgQ- zb2XY6S)-oyb6Gy#2~Jq+V6Z=+<&P(77oE>xr=FBUS8jILnQ^QXRXVl$BXM)h9BtLw zO^6i~sCGp>&OOchziLnZX^J_I*48?PdTF%{)m?zA15;q#n0tJl=2U&7@OYUN9*k3T z{=H0Q(0LzzEU_o^nr!RxmJ!3en?>)<OZbtTqx#ysKYa4~^|PP;c1X#&koEkLsP=a7 z?SlYDu%--DIjiGs4|TeqMp=59qig>1oU;97u^ds52`QK&j$or=s<7%Pf0xnWEIB)i z(MDCcck*XXwu8YmPhugRFz!A8%O0L%Rw<{1L)a~Sd-8RfeIo#ZZyJCgVoj~TzC(vE z=5ZE5cPakc;Cq9VI|ez%@maK-EOI`}xw9stbTZx!T8HF&Xxt$mEwahxcdf3|PE<qC zoSV_PZFS9QO~~mI-anbnFQPoj1N1RuV9zXI+|GcDx%od34GJJpB>*j+D#cx}8wtQ4 zEr9q2xSG=}p=8_$lG2UQ7uE|ZH&gr$#MShCo9wo`qy1+ySlUIPJKP<NFj#OO-j+3F zgJ4*wx;13mt~CSl`2g_WX$O$N_7maB{2yyj^xQ0t`Ob!lY!<vkx)dBz)4+;*WS~D- zK=HA);4`L1<5;bT*&D3#08Oa!jFj;sXn(Ue5MTNhoNEErtT=z^U2^KNez~~>#Q?rP z&!TDn*ZH|`14h|C{{K&C<x^V6wxv=&Pt$V&$cZWre%m|C;&_w5Z(gKCP1+zIW2Lmc z_6fO6w)e4(%uw1KpklJP;VC7&4q87+KJWlDI0U=tL>BUewH!-n`<<i+m$pmQ_KkzA zi+Boce^l9J>`pIOrpKcq(mmEr7+_5ThV;~eB#jL|$Ttqa44<c2@(;|-F$rER5ydVt z0r$#o3j{lb)^Fe+;7{rOf3@r@gkHaj&FlXxyq-p<g%*bw$=QOySi_#op_Psfc!K4n zV5U#ud23BkJ$0+}K2dTh6w?0l#hX{bqo)sl`rDJk;BPO2r%zrzS+j&WO#OvQE+DXc zmBE<>688`0KS|3@0f!Qd@ea+$&`PCaOBE2Zv_PAv|0!p&W<`z2UBKKM8+hjPScE=u zji9s1(WXH4KX8^kI^8M_nUn$-Gbed>;GuZTpkFgz*pdS$jFKuORoUosY}=Ec9tSVJ zcXsb{tSb{B5G{dQr(AAb5+hg=aqP(;jKZ~o!7kf+km~b3qW5>p#e!Kjsrm?~5F<#R zVBpnLej);z^KEXf_R{SNVgr_;;H%Yq{I&@9txgm+!T4$EUmN9cco@tD<I~vr>@0X& z9zFs>7ERUyQ`}h}V=tVRZmi+FEzIMsSwPHUjb0s-iQ=pCXc}898AQ1TBiMbYpioQ; zx#nI;^ekn?gNIp$p;p9YiaX;t$w7#@5?3IOc*E|H)k4cdL>9>2=!z?cjgY_TQb9T$ z6pe#aJ7Eqr=DIwi3Z#nww&HvVXQf}D9^V5Tlx8lY3`7CAndZ?V8L>JDb6pa8;b_!K z!Q8TQV%2F{(InUXjbff9HMe&q9igKM=M{V_<D_kSt6|{Bs6BX}M0!yTh(6u0ZzZjq z$<U8tO(IEc<MZhBsyMyZh4gd40idG{4+uSIS;&bO7wOm>jUL+MwKN0*56flJ*u;n_ z=}N#6Rm0qha}e5@96Ran#8ZGe$d*`d1w_gv8IU<+sl-m>5bZhy$~S;qMsTZ5)FT@( zIl>KOV7Q=hG5WzHXl4>EVt6qOZU)$N8gqj4S=vkIeQP{1Fd6y9%PfAM#FyyOk!BR> z%_-OMp*Sur=VLlTycfK5RI?JD>ZA8jGNBS3JX)S6t_e?qd(;x=6W)$JM>odr^zx%? z+DqVi&Jqyt1qp3o+ps_U4ppb}7f3+A+xeHN92oG|aGo{s5Mo10VKs^td-Rph1v+$L z?!%<u^kKUGJuq0it)JicDqNOHXz_`R-_gmHh+a|gPyj+L%dq(|bWjG!hs`%)@<5Ik zTH#}MjZ;CMC2?k1-V0qGnMTLhb3r<^U+>tOBE9{XT}=NC031y%)dfOBK4o!AU_$Z( z6-yf7(A573ZpByviOejic|RJDe@fGNr<Km+D7@l>(bC}`n8%C{Bsob@?gu7_xfMvP z&J2>6Q5?_I0ka%F3q8(ZVn*b8gclW|;!d$gbvIyQ-&kf6Y*5!5^wJ1<eDe6t(-cMN zzAz}2=now1-YD)RBn`=ZT^{B4=!Dv7aVrv;9uvo=<7_sZQKI#4ZrtReK<Ukdj1*^t zntr)wiK(OH7c|B>m-)k4@>KF#&r|<@8|2Mps>bs)5GM1TlIsL#TU@7X8S~Xe#9Ymy zM4t6bPC-VisKUH*j5IbZt%#YVXCRxgr@Jr%rx+}ZorSVGYQ*Y(B1hq_WQAdVTi9wz zKusBG`ga+dWeB3<W#5nvDX<7YiI(pav+2{7$p_ZeK+U6BJjr(oonlgpLSH4VHGf%U z-eF^{c#9=igO|jm@tUW1As#RBheb3r4f4ciU>bEmmFLk6HZl_ckDP}cI#FFiNIhVL zdbnU-IuCspB@eq>*bF|wMS=#jujFz~3SE$;rHgK`Oyo~r>D<BaV1_EwRMdmx^t6xS zC-&S&-G?{s!GbUIdSjk+s<+mPxw2NFpXu3Dnz8gGLUAy(xD;{h;Q(1Y$dyM!L+JyX zibF=70biJh3nWUuA>61v@w_91Mp8?vR#BLn`JYvm&^612Ls7_u9w8Nra8~sKPhY>t z`K_*2yXIXNwVTh>URrFMLQDs_+@0(e&Q90EnN%N|M!U0C4)y>ZSIz@bq0(}cC|d>k zv8S<9>_ehZbO-jzs&+SPMs~s^K-)U^t@djoeTk?@jBez+C*Qw#^+cS~gfMAto>+m# zpdNnz`pGLFBt7v*7fW>6#p#;?lf?20&2D(PgY2=KU_97|IeM7kR}_n?s-06T`y$e6 zoOm{_`nL2jTDH`uJd{2N;foYG`98LK9TE3zHp+~xt9x>sjoCN{pk9oAmFs6`tz?xf zNDc;S$#Gd3G0_^<hgIfI(UxfsrG<_#>*XX1NC+ee)SmsTVBK6*8@7sIsEPJzEU;LZ za;Nlcv&xgD;2N<qO10ry{L=D;MAGaHSG!ku@Gr9>9%6|o<VD8%MN^;Dqt8EY$znQh zXvroolFj0q&xt_RTGXHq3t@ZKkAI0ZaBtfiqnHLxKVy%|#NqI*ngdjKCz|DFah8?z zh)hfdqL7Kt=~68k5$rx#;wf~2Zqux=@B1k+CRzB|E`wlJl|kFfN*OX}T;jW$iK~tI zX^94|3Zx8;?8FW<Eb4B9LzTbnIpNEkUV>m<D0ue~dmwarb1%qutQ{@zNX5Q=kQAEc zSP@=7r~rCX5QG|>cl1}yH^M=;FtO0`2f_xJpxqg-;G#BZm3BIRm&`dmwLP;LJ^GIN z>IVGl;Tg##cu7C`02um{B<gkOAMUCBG3nxfQ;gxWxD=J@wzQoiZ+svh@+z-}C=DwB z+Pz}oAkVi>Jt56QymmZ{tmqX~7`=9VX(>Z~M*b(ub4pUFykb!MyVzDSoYQy_;Wc&o z4($nNlk}2I%D*kq8wC#c;F~YMy#KA0_@Q?`Nq|uGl39<n%lH>})%&K0p{CyszWMsE zfBE_g`d@b$m3NKh`axu`Gk8Q01|>1C_4k%)(h2(m|8>|HjWG!@p|MNuxw*N&-QVbg z)?eS+xl4c0-FjH8xk;@x-M4?~t{RQ3YF;au!HRx-Luxda@-69EG*XzGG5FaQF{u{t zS}5+CCvM(8Oub&EU*T(&jeR(r9khH-&~AsD?ABfDaflQ0Qlsh-@BlVSaBs)LqiCE7 z1Hz+4UXC`VTbxNX|7bSrlWqmkug|{|pJ^j*#Q_%gp}`Im*fDXm<XcfceF);V(hwRw z_B_oNn2TGuE?vXeGQ<XtA}XcES)4fROt}(c{Yzx*s1BpVh(CVuTz~oy4W}3BWSj>{ z%y3?jV+U%h)sw^13`X`kop;5PQCkmp$nlZV;E?a5;|!AI`7+iP(P!v}F^d-{q)z~^ zGcs&we|*w?KRP@N@_B{<<!o@5qzC9Qi3vcA3rD`l`vF!{oUwVF%>J@As9Zm1S4`H1 zw-^|lm1j>#jjc5hM7udkJ%yX?16n_43--O^$Y4ycndGNb@X%Iph!#Xo7#frFiv;Sc zQicl?5RXnXxSU#%g6$1J?U5mqpdq)>^ok01G&@KJTl6rEv7Y1E1PFDY3ir(=*Pk^g za+1@&rz&&Ac@~Y_xlmP57#S>~@|Zx_S{XDOlYa<REQPK)8#tRX2=Qnl$qd#m8go*& zIJ**TD=kpTybeqA;-??~6F5k$BAFXRd7==dv!FaDxHM8vG!MS%2H#o(4E_?*KLjbA zDSr*Z3&fNk;;T`Lo0wm~fjV76KZv<&I%YhZvK3wDSvdp7DThUSA7@<IHFq|ypx`QM z_~)YEx5yFGbQ;%pR6PT=-RJS*$%Kf;cURBGoz~@a+~YRAQIt`Dami9ZfaY4eSOrE} z)WBd3UNr=IU;f^rWUrK01IT;I&IIHIWFsk$n+NZc9If7x$W`N!9aBlU%wwt{aHf1& zI4_e#d2`f0`5(YJ6~afteUkrQhVKXx*nLSr5MOVyI$^pJplge(iKj+#@I1wUdUoK> zectsIps3$28QnsB`H~%duKsT{S;n1~%&Zj#_s~@UXVUW7$aM-R1lN~R^i^Yh_QW^9 z(w9fN_v4!0Z6CykW6VNBq&A+B<<J;kBWII=5x^9tIod$@ltvs&dzKhY0ue83<D&7H z9JosR*5#&M-LpMuy($!Xc0mxli$cC6LX2BL`f+$@8bC4R%C%k=;dQ9}W@#9eTUF}* z1)-}#AYX4X`5y&#r_h(ldR)Cf93t!AA`J5V6r03)l8@P^ar|lb$%6M!*e7fLciAdM z+t|FC2g7VQ<1$hio}%H*T52G#Pf{HbX_mSeZR^j$0)ROl%gIqy(bm(l6wG7|{|V_& zbFYb}uX7ZkLzs@gQlE0E-nodLsFUTpMAe<K0676Qlu7*z!0B*O!^W^@B_*`dXlqPH zxVlz}b9mk(7tA?Ud?lYr!yL`V3B$%h^$S2)Ed2~e6UPjal~R7fhhg9L21MRSiu25* zu5FR4;mMMloCF@xD&XjN{+aUK%q<+SHPr>}C#kIGs20QTOLyB`bYA4|aeW=kSLwhw z?`X?={}4bNr2|nts0K+b3NRhL)f}iSuy!O~!h}rdW$5a+Xn|d=mP&ZA(CbeELp+@? zB-sr!#tU{-gtKdc$#k#smvt5foul()ddw<Je@X`G?IkeR#rg6u_DlnRAfCM(VR2HV zFDG6c<0I`lOd<w&j$D(8b$%HRu7?9p(JSjCI+p4;A53d}GJcVErI{>;VgyYX+)v*> z`{~)?(<hJZgA&1j&u7dC&XhF(ShY!-&VkCmgWK!Ze1fGQPP1tC?#lRPw<i-7VZfD; z;K0WV3X8&T(PKH|)+$sG`7Mx8J=au{KbsY<Csv~7=-jl&l%6Ax0f1{LxaaxU(tY5k zE(E{>&sE3kN&RhBcj%tNo8nF|0GB-5vws>V=NAhvAME1}c>wYe9B_J=lcdiNt9$yH zYDV6!BmTzihn`h;^AcqDLkvVI`fEA+Xo2bm<?-t<58Os+MSrVC_JMr1XmeS6xUa7$ zy+$UC6Q`f#Fi)a9^0>r1{J-wrb-isPOBDU@r=StH4M-Fv*-1JfLvj0-j;5VBpY2S# zw<KpE60$I+2sQv(RxF+OIj?b^?5s;wp{^h(C)4}ez4tgGP^inQs&&7RnLnGK4YWae z_wV=U8Bg!W^y5G66QZp`2xO<l?8=3c*<NkAGvc;AV5^{EjVJmzXy&0GmOpsv-myFK zaDkz<6W48MeR)C6sSRTfKl>Ai?ZDHDQ(<Z=)%i2F%QH!R8{M5<yN}Y~Bcyped!EOG z={(2qnb1mJqYX(ZTZ%Je)noX-uX~rfBw0Lt^Ut531HqaCbt2cZB)r`4_-mKHZt9(m zbrNFz%>}kEfDXzAv)0<T94yYV{ZS4CJjeL}e#Zt@Yvy7xO3+e`X?@Di4P58)`$ux< ze$!Pygep%Q$$*2esvhQhmZ{K}1!ul|BlKkKJ4bp&a`eQAN$ICoH3Yx$m|kFrl<@ch zQ5Ke&qn{;l=_qtriZ|W$Q_8=}Wzwb<ID?SC7QTB;LsDXN*2wc5;B??y{H42&bEa`< z@H3^=-Wy52CkGb!qg3GwEewBb?jEXVT~!Q)8>UrFkW+o)6Hgy?et{N$(Fi#Tc!0@1 zI4XtUE_}YF`ky|rXybCl!vSziiugK{NgQUGD2U8l7?yX!G^ZNrBY0%>kGw3+te;)} zNcFuI#p~2{yP$kB_|08%|HP&~{z*VfwD6~;x$7T6p?`Qs%iP#Sl~ex6%nSp}rhvSR zoOT3!JjNjV1}1P5BA0s;3ztutO2234ZM(7b5DwL2e4}kykHxegC+T<<G{c)AIKb?Z zJ3GB{_Q@U+Bm?7?$I?gF>c`5xBH*Fq$dPxV!nUqEC%5|T%gZECi)G>q?)=)_*-KjH z2RDlX$J-_*6KzREabWm|czUEr@^v8!3R@kij<<XJCw{?01)+@Ar#-h4#ozcOR#x6L z7>N)+R*M4Ry8?l2V6JK91Ce({=>H~Q8YiKwRth(Ut~r*Vpy=>ZM1-)j6lu>h-PuPv zLP`z9jA(U`$=B6^^j9ZU!w$qsLoV^Eq4!$)vs49cxpdYyclxB|@&)G9bh5Lfy3rRB z41G}Pk6KduH@Q=9n}6SXl`Xp1MAfk2YCsmc*vWs?+}=28ImmD(F>qM(R&Qd2vJDR` z_QnVHP8jmr+ub1F1?p`O|F^^TXJ7}l2mv;8*IaqK;p{BFK_ci@%tuc5z)#7RCP@N< z+;S~kdainE!J3}B88?3JW!%mN(1>eMmySEs^hTZ2+^w5v>-Yh(vIAs=f{c*SX^@~V z3uqW+ZEqveYPi}CD{4ohX8X{90T2d=r+1)rw=r}R!|WGx=9nnvpa0ubqDd>6bLRPz zSyRWwnIc>6rqJo%vnx`w(F64Jga=;C#P&CGn!xZe%v6o4uWGeKpCgqzZs4u3^gg?K z%BVz)ELt~1ix#7{&(YikUHDQHixxfvSzV$lYA@D0u@jelx)VT~KxU(>C|uD^BK49m zdbrd~vm@<=Y^WyfsBJdCx6Fo+27?o;Ak|_k+oEjc0#=Lm1>6MRwD2OELh0s@g5So% zn&>}-=NP7<D7eV$6N0R-ZQQArm*#bneF&HZ$eN(F889X%myvMYrcDXJO^Z}N%g{DT zZZ?bFB^BhZdhZJHzzFth9G^_g^dnzGG}o+0XxgEc`0D=s-re;G%ZGOqmhl2#qKMwX zxcBH04kI6YH|~A8M+pw~HeWw__~@b444-|Kw8$FJ@eXu0B%jRQYPmaOGjv*(#U=Js zg}&tBc6f-E?{Och^eioNzgmNJF0o=iHmWnHAUf`SgYeLPfBCibVE^G?TLAIRkc$qX zH8#}d%ddxM<;?0}3mBudiCQhS`K<NsKWbUc{s3P<pueMG?>V|6w$EZA9FK25i&mH- zFgSl~`!u-ChLcdU_^!8aZ1q9!AzTja9suk2?S31uzTSDb$6gIcr~19Do(@8dzuh19 z=Gj>-@E#5lYI;Zs=-!JYM5O6H&B*1cuCaJ_Mp=?p%f@dLy)4S$;esy<@{$GlX9-LP zX$I(uaS8c{dxLg3*H_C<M=s3%L05X_vZ__!F<j+hT|(>kBA7Qh1w?%x&h@Nb?&de& z4trN^4Za0z_PZaWu46Re(8LC6CdBfs!x!S?Z}*ZvmgwI2LiCwL{S4wnyKt#wAV<v` zn{p;B(RiSwBSV7zfD}AwOO7sdk1Z}WKFNKF3yH!UQ>&7Dog}}J*2aSMy0eNt>~K_d z@yAZVut^UM&#_4_%9}pwuQ>{9sH$_+jLiq^BF>w3`bKT-XC*nWc$?cO1e4CR9%UQH zv?_8uCGNau$Vh_*Gl(58AQ9K1ndFT8oy<cvkq<b)uBbs?4UB+*oXX}=xI&JpAjy*5 z*bh&yIHM6NmM=se4bv>x$uOZanG_3?gGA=o_oThUH5t-^9^+cfyYIN!uh}lPE*b9Z zvFbYsYp2$!d+wU+m97A&^Zbxm{sHDgbP;c6z{P1fR}^_tR-9S2PESusOi;xInxr5d zr|io^P#?;XU&{!U*BJZwd@*y(H}r)JPwHutZl1dOoVzM<j>6^qi7^~v{@^?GgxvF* z`&8HZWQZ69*M4IQXO$M8BeJQvSywnjjVn|wv+}GcFEAEoq4!nD#6W{P>w&yp<^4w- zQm4}(jPL5Ckz_=jG?UWGD<?J`dbQYQ6MJ9PjpumVPM<!fg3{_kEE3)JnRZ;8!ThJy zV+)p!EoyW>3`DD2-1U~s6Km^vcLYCKp@q7jY0jzn5OY%qqVGfcXn;0I+O9ZKbxweu z?^yRu6xwO+264(C--&({HeH2z{(@ig_IJ}dug9w$uD&F2MwBRW`=5b7y+_vsfQi$M zPDbHRxx~Bws{TPYtTMR&u@l7+TL;Of$z~P&yr{Cu8(rEkOGIyFOsr49#fSzBcEq&0 zy_XA$bj`GY(<V(p?}rTI2w;^M4#5F-nAe)NweRZ~I;zw6nPJ)YU1jeP!8ENpFvT@j zSKQkpz)^nhfh^yE+KjR`{o=~^oU!Hj<KADRmPTq2@yWJ6^tN~!x`SfpwT}EF(Mfo7 z`(x6M^|ayFAuBQAW{IP&*AHhuAiuVkXE8%1>309<OEl&knqT*J1a$rN(3B?}l}$4) zoA>}aSPRT>-((KW7D0N~3i1YkVTfyC0?@{v8bO7UXlKrs_#g=5?Qy8K;7!Z2Jjb95 zU00b=%^U77)aG(FE`m^b1x8xV01j@S7mIh8mz|yMjq%)>dGU@k=K48wFE#8&P04#i z1{&dfNw&%t!nwg`DG^>J{LxxcTiJRgg9&!t+GjrGE!Z@%FVxz+B%PqOIfrXO^=~Nn zq*fLTO#8se(JBsW6)>(fRl>l{E6g9Xf?8#8lsR@qj!JV?)S^ku;$R#TGgYfo4(p5e z98S*Lv6ke=&gv!_Xwq5d!Of8^e$+b;l?2E?3z-gO^BDw3Tz5!(&WZHpsKu(uY?Pt= z(aUX6RS&9;h}#aQOJ+cJ#beJ2qOY7|WE~LW=eD)WZJ;&wVOxLc&DJQ0vp$?6c1~+1 z$DX#$3>AA8>_kuv{{q!1wPxO`tg#M)v9XQ@Ew-{xG^sbtq}Ee6nf200Tm4k?=CPtF zsE3fYuV(*X^I<kmmsK`H-(mAbF`peu_Qwg@c$Q&?i*fJK-rnBG);GdQxuQakXyL@7 zE|K!@=R6o#r)1t^Ob+xXf_bmfd1UG`F?$0ijFFM*6hR@<0aUh0YPBSVv3cMLqd%u0 zN<GNGMcb}@5pnhqZ(zP67tbj`P$|o0({M|nCT|*coQ!5G3(TkWTVXNq<ruJZ^FVx_ z71P(+DPKc^R2=G_$E{0vhO|VTX`!X6oFzIE{PQKnw5=0%gNmb$VPxv^h80I*ZmnN; zHCqR5X`xWB;8e7bL+|(=CfE~)>pKA$*er0;5B0^o{RD90RJL2^7<;PK;87Jo2#?vH zY2UC654U?(41$Uq(OIyn!5#N#3XJcXHC>guRHpMMV*~xQ=!Q8lm^2GvMleiXW+YYE zC@e-FR%E_dTRs>8gZNvpfzQb7Md9S|(9uvxDyRzG;&$Uc$3h=r?-P)l>558haZ#57 zQ>W2>;h4f~!d$K>*fMZV2!<t-Jxt`yAi}^M2t|>J>IYu0>DEP>z*R&|IMLFdI|@{` z>2syB-RqDDuxVP58YajPg*2$DNRQKhq?r0CxFlQ-R&=?Ny{r|e1m*U+?_!L%jQo-9 zM&2MU9?BE86tHVFq?{5i2`U}*Y?}$5U@xGo&^Uv!#v6nXp6t%cpsbPd`P&1<sjM4A zw(Ek$8%Sy)R~E|bbI+YUs<EWQG@WPPr&GHY7~!s9jTbZC{X2o`T4SR%La^T<oJt=C z*@0c}$UDA)M{O=dly6RP8CA!UHi`&%7G<_D`1IKO&YXMm)`Z@cwLA7qI@>QwRb)fY zi}SBl4o?MV@4ft<HfyMcFTJ{TLgU-SZ0bmB1H(;2G6X_i8*Avj^Ntfq^*xrX!A9Tb zbKMvFj%l8l6&X?Gc~(=dO-%mC3@H*Vk@QbX_$P{nWSnk^^EOdJryAq9_0D6Jl#G)} zRvcoSFVLfssu*IKmfp?|Q@OOJHi#WC379@^pR|TD-K6NASe3pAPUHk{gWf;0N+gEg z%B!tjna^?{&&A4$W6rbJ>6zSdbeC?+$)$4=oRiT!<eutGlqQCg@X)2<2R}Ih6Lj74 z(>YhmldTspf!F-hb}A~_ha5H6PtWuDEcRbC*;BKTK5mKlM=^Zj!5B0c=hkW)%*(lp zuepjEXL6RG_vMn4V9ta^v3R|jzQ20HsWvv)C<|MK0bnPuQbU+38S~xR;YGHtrmGM` zZVu?>F6;8jgJy!Di31ihV<2P@LmgNs3vMID;doWfcBl4*S~CsbT*C~2#ejM@!MRqH zJ51Om%p_8V(_q52Ty>#7_JtF6ps-zc!ctVZw8D1wv$z58{2YAmH57P=LLdaCgLe;E za#zau^9KOg^vw;pZAucmz7m|!moPu`<O-Gca=tt2eE5s9?cIh0xXpMso4JA7M?)(1 zEJs+K7qJHPusVM%JGs|ofj*TlO4D4v)6VmKnw`s9U*{kql}!R~SUX_J)8b>3@*Goo z7nh59k<LVIOZkct{}!?=rmVY)w3J*?F+KU|sus28KPZ76SqxQ$jgjV#$gMhsZZL5e zP-NhVddLikgpav!gm}`dqBYOisooAXSp2zArD1mA4^d*eZ&aB17g{%;4(QRyt$eIC zna<Oy`Y9z=QzViu;ArkNO(IVR)bT*xar`trr7Y;WuR1rX=@dkJdO-nx^E>$n;LH8J zJ>&iQ%g;TW<#VPtQ956qr*W}Nr+Ixf{%S9Yx+WE)j>LyF(ZN@3IW1L^I$!QO9d~ob z=Q3fF{PJl31WP$AKi+1&6i3shTzvrzMxGBZH_gq}0cK({w6oz6ac}?P2dGla>O5t0 z?%V`c%{vEEaGm%3f^=_aSH37_>0B1GB?npzva8-#D(O8I5WW;81@7ohRTg4F8HEZ9 z2!|{?`zs=zAsKAWksFcSE7x6xibRE7C4BNnvhFThct}<eb+a5NVAYchL+2h88c_mP z_A#4co^s*1&6-HK)%b3fR~I=3QuTXT&Uw-DwD<DwxX!1PJ4y{h|2xEL6w@r{?9(Wi zVzG8n!FnY7;MBRS$R<o2!<mLosh%{|H%@x8LNUJLk&J<~rV43_Y1<rL-+^VnH}x6% z*pdbZxJfJ~3nQFnBA*@AN@5}~&pu@HCc5m3)BaXk4Q}WVb_I@EoiFDN=q-7YkKL$e zPD4A512?k3X-#0nlgmOi3gZM}^LP&Km}tZXOnVkzw{<9^uT0jA+S;D5kqM<ON3oQH z-t%gzj#s4}yMf*d29i;!iidy2<M{mb(}7iHGn>ADP63X_zQ1>);kke^1xn#-BP{{` zZn6s491VXJ49A?Jlcq0JCg>yd%vg4VJgmDbk5I+uUlz~9IjLeUQ#^E>&8RlwXo6j+ zS__vH4k^O9RXrGSmMk#i60Lk-+@m)tQOk|4tZ#;~RNFRBk!U?cLK>AkGK+r#njvOg zYLEaY4)FRu|Cm*jim*UEZAG!5Sy>i#DtK))GnM*Vs-|{~X{7P5YI1#6FB5vO+wVQN zw?Ew7eUJoF)$P8GCqw5mu7geDq2I4gOyq$m<n{nd|E;rfF_zJEOooDp-`ZTh%4^~g zRl}*mj2pnbx?VR}hOS_&%B~QG%ri)zJY%f5&Txt-k+^Cf7H!tu!Y+?|U<&cS{5tY} zBe-9YJf3)*<;PKLTa8mDN6fayigo&OZ;$xIU`vC8-j7CJpb5B`C_rw3tO3{=Z1RIO zx<u8?fz?-`CFxwC{5<h5=`uT|Q>C=erDD4j)kJ>J;Mfd31%B*ZGQP1TD_y$6_qJR` z4odhO##)_TxN^GkXd}8JN=WE_Pnt~CK+4ZpUjXlwFT(GqRrNgxyF|*7Mc;@!*Tgn} z<Kub$jz*di<Kb<mpX@RN?i(1z_4|v^3hZq|@0`Fwy@HXoZR~#Jb2=K-!oLc;jC>8G zm#obUjlAMDf8#j;3=dh*2nM7q;_cx7CIEfj<QFVq>5pCsaWYC*brE@vpblkLw)w$a zycf5_xf{j%CtOaeJD}w!3f7_oTcB03U^(kHw?uU!cP)DP_sG9fs%dbun!B{`Vp?ZE z*;3WMp?}RTBHOt}K%5ivhM>-GH-^0aSv&NNmYsHh`CoejjDFN6Fy|K72;-Cg`ORp( zBl3_WYwnW1hNRUIaYOdlAm~C__LYMcj8;<fvZmP@ROBk1e*3B@zxHw8L0-nA^=nyI zt5YDbwh#CAly0oGyD$Jualor#@^ipahlF}yp&cj|S?}@pZ=S!BWrAvrn<_-vK;R<) zkWz)DhtXkCA}(hFolS*uWDwpiKL4yV--+E?A9CWo-QL5*3nx!^f`pj;k*?3*T}ZzD z_56x0_j$$U{ok{)*b#2!!pmo3xDsG$V5?pz)^%ZpIToyLng^{oCgRbgh1i$+1?V@D z?H3e7W)pL-r@IPBZw*Ed#@M*w<a?uaEjj$QnQEu_RPMuynD$M}3AOGXW{rV3=tvUV z70$W^$u%q5EO@%ZccI{C4=d-yplh}}CzRlqLm5RNDqc1*1gj>gi3%uCzeUn<_4_=V zFJCT64cI6DCkl#jOgc2fC&fq0$JP`zWYF)p_vwcGWu*v%GwQ2fs9WN+TU>f+TCdW% zUI7qfo;$jU?={ugoiY7-Ra_buNTk}6mH!mk8U+m$DjkD9cdHBb!1pQ>J>K^Kn7-<v z@9O;=M_Vdj3&^#~r0Pr7ienz?J*sa-E!(P)Dska^#M%zmeVWyXO}Z=msVBR-ix1Ly zEz=m{Pd!)Xnk<GbO3K#EsjusGiBrv#sO!_HLSNx*)0n9Av?WpLtaystV=PbOX)&KA z8)x-w#>zJsE3Z@d{W+t}Hy91?+2@S)uMNif*Q%(q&l&9f27^sqz4%6Bz1w8V(0cYc zgB2SLR-g;{=M1*mV6fHa4tBo5VCPvnGri<C9<JPExbkyGy4qkQO!D<PW39`nY$NGj z%l|f<+h^rfc23jcmSeR*NU*`fmN2Pcs-HU{V0O!-?6&l$bo{p^Qoae6>U_Maiyh2= z0n7|$<Hf_XlNsq@Lo5t(KC5NaZ?|09$5Js9dX8j+`S|olvKGWY2_C$+|A_3c-sHDt z^4hi>x};SHMpJ39KHd0FWYdUr%r8;gJq1{c(m!!DD-iq){U~rB<ke|9OK!j0<h%v! zv#?`>xIRtM?fvjM2Mh^^bxd9OQKi1aztPM9YkmIu=?0!WZ3o9mRrx-=_0wkGgZtdU z)E&0)1;A)}X&aS5I4vD}>(Qn>sGO23YHcR=bAveqU>cFmxj?7-DGKIA(?q$p3KpV? zRfMV|#!|T>+iUgsO~X}NiI5F4v8fCfmCUiw<i>~t`KYMyqpZ)@o2OXf8bqjwyr&}R zH6-*(z21MMAJS@C=F8ffkt#*^1z7fcenmoO$PEh*$ge*>qa*CiK$T-b-~#hCuc(ZS z6y7+)j;4lVf2Jh`#|?a4kxoxgp-TT!Rzf~}aG{cq;@mE>bWwRzcZv03Wk8ilYo5R7 zyf8!0C%#@N$x%*ONZ4Th0)8|)EzcJS$R9=G3Tzw)WD@^)hl{EPzEQckR&|-8G7&E7 zWm@8L>+^zM6ZRurov$AOwL=!NvDSK8Vce$h<zdgWODgIpHp|xwXTNavkNwd^Np^yc z^tDZVy>PvFiAR<|$6yt97;G3M|I8|teJH(rPhh~Em)Xa2tco&yU-hN;Z<#&to(Kxx zhSQBoPF8SIGPXIVt7V@-?3h;+IP0vR6Y!`+_!7miv4UAG6DVSx`J7cm2DR1lP)ktT zqDSqBVGSBWNTiK-W_+VEsmL!nMcSKvtf{wVD&u6FpchXEa*Qp2@W3Ts5#yng5Hab# z1<fGhRvm=^WA@X5mfQr1oVZlJk<1nbz3bw<rcMfl4=^(&M#U7$&ll)6IrGNUEP&dl z^MAfZCYBr$9E$`yLsry9({AUXzvVe#ra59Kt?8HkrhL291_GfI2BqrB)tmGkI`qU* z1(Y{Rj`mJGT7P|E&hBF8!i>`R9RJ+dy~L>h;Aw96BKUvX1~^8cZ7LR&l)U(mm230U zcbW@DjaoCY0NL$sSQA{;f8PAsA$1eXomrPTmj-5&fE^dYheDdar5|$b$KEQ_I8Yv< zD5%Q;<d3E8t3v6MVK7fxO<#uv#*T=5^Mekx20{=u_ksLuyKIDV0Pda#*o?{g#K}J& z0Oi5TV8}8#9_W1pjUb6g|H1(2!o;rEYy@)sNh5MN&uGUEUwhIOvb}Ciu9(h>jJskx z^Xi9ezFfQKUbl?a{igfXT-tRCF01+N>Ul}o4LfVCJJBXr`iHo=MRnxcp=*;abwt=c zB-y@s_F1{{8N}2Vx+a8qbD!!69epsL9W(EgA%rvWMJ~fE8(C({BYuA3_w_Xvz%2(9 zL>Sw~PZ<ePp{G#m()?yfA78-$eL~d&#jRA2M*mheBrsK2iH?;l$F0@eR%5BJ2Kh|- z9rLrDvbe;<DJ;^V&vdWl2j<rg0^g{E3P3a?u4D_3-~LDK7VWvOFLZ^U7D+Jc_v*Z! zXZ;@Exqh!v()d{NQ_bzo3&MHs(*%l(=eTft{ok|?3@4&yi6Pe`t;M+a@T*bF5)K7h z8d?W)q``^NX@GwM`>(ZhH}EiEWs@Qf?gz4C_}^fwf5;R6j{s7X*}q^f+X$J`?D8KY zU*NVQY<S{r%v0|!ItfLpi?2p^TBx=>!LPA|oym<aRu`eOTFKU%omKwKJ*%R-=1<~} zR~Nw^8jNAIUw>w72=eF2hUeX4b95H~$_*tELd-W29?R>f`NqT%zKD`OBkR6x0C+-g zy+~7f0C)!D7vACc6%EK(-x=~ywD5$-^ZAJP1M?B;JbO0y*gF?|!87^Nor#rywojY- zv&sq7lAnqgyIFxM!j~l>1AiC&p3lMSCIoHrO7JX?o_p6vZ+L-U`*#<eQAMl3sKU5m z4~mbyW8w=Q@*D4vPw9Q=KnbMnoF{zlKTi0D$J^ig_iUmsII-pMJ`Aj#+$B6~r{~_a z(;Kn&hkwZ0)uOBVb5?6OWq6jf3NC4-E$PeusU>Z63x)58XI0{jcU|J0SegGa{vg|g zMlOAWmj3ZdF_ixj{!o<p?-;N(f3=!tZK(E9Xlt<qoM&g@v43OXg+%&1B@7^K>0D}2 z4QAj%Sr3W*Q9orZI#GPv(OYr8-&yfSuwEDgDMCIM>4(8`p4Jp*U{y1pIHyTl5%w1) zz2Ukx7b(!P5!;WZWL4m7(hCq0ekH$&swXE<`AIs}-gAMCj~igC^%0OCt_3o-zZH;0 z@o@*pRQ|hhzzuP2*yPFWqzv=(+j96#4+axvb=>}8K+x$i9+)q~f{)fo!$0buw6Txc z$N$iTXOCvy9*T5c!K&|COP0t=8QiwEXDQ7X$Zoz|1NcTmqn((6aQpE2%xXeP)6Is0 zO7mgx6U6TXr>5<?9AH>=^A%hPZcTm$rr*2Yz~leSqhVU(HQ|bH(nDSMrI@CRUkEoQ zqfR~G9d~+om3ew-uYBfPC8wbEy%8PUSkVDb4MkVHoUh*Hiyw;Oz3t?0jDC&{P;J#T zA360(_*?z>8nso~yN5;xhM`6zY)%H#qSOT{0Y^s3RaxJnS6y9zfK_3odKMci(*Ml> zOCO*fNHO4A>27^Q^xHe5gb8pN<H_*&xcc;E|K=M0yLCYS?!Z6W^w;t6Z2S0la6N`! z+t)kSzrlaEuD=lPj*i|QFHTON#mO*<n(4lxlmzaKRnZqN+R^Cu-8rrnmu0&2*X+=7 zcg>k2vP&RVaTLRZU`7f26Ho5O@Skf$ej@j(SoL-fxDy~`kx>ZPEzx3E(~!9$YD`EI z-P`Zodl*^KC&m)|3+VT(QdKlLUanZ8Sw^DF-cc3+wZ_4x{XVV=%W1({Zj!jSeSHts zI^k705$=?BNS494#e!)Dy5kxKXZA&{G#`GEQ+><8PiqBym|v7ImxP_P)EY&{imXFc zW}XEC!YH+6xB+%w>Mk7od%HBtmYroChHr1f!h<OTJ}Jt>knHfVZ{ZSFsAL~gG-@i& zIxw?CsX+Nt=C<$7jkPbK*`X5*cE!o8R2f{Xj8KR~z~m5iiW#OTGI_>z!nSs|wqy?! zfmaQC`<zpl285&ZkbWX;?kMLW%s|WOw+<<Av-jUCkQbZGUy`YUA<({~tN|1ON~xyE zd*~h3AL8CbekkVvl!xnq+!s^tYcsP`Sp6-lF?BI|X<eS@a5WI66H`wfCV21hDrmkz ze0Tx;7r&|x;#;Az-Q&flhy9yfm?&N!%XRhz5I6!c=Bvj9ic}|vQmvt@*Pw@Spba{g z>Ho!zTrG`|(M3^<1ZXwo>|(TbfoW$kbx*oLv-DY-&z%}N)e~8eX*WLJ+PatQl8h1S z)r(9&5cTC_QIKgjehXikAJQ85J0}4!Z5n*{V_KgNF7idJ%|pbR_O%h3%7JEOIii9L zJS~U~Jse~bGI<`;Db`EF>|1s5?%g~a7(T~wGpB>GI8qd`roFg3hWl`RE#BhKeFwX? z)VI=*eH<NaoqQtAGxvo==3YcdQNxU8r)KFZJ|B9QZ#{i_yR>o>l9k;)&|ErC0N-Au zEV6;;Nw}+$qc_~HE56*Mf5d7l8D7)0yc$p<Ji-*XWtH6@x`g)9@-(kYXboep&dx;C z^I$_*?7oeUwthQ-vls+r`~JWks3yrh-{&7_kqU*3Vfll5`=bp?oN1S4TkEPNbEE@$ z^pmMLyL;6a(eonr8HaE#uB>Y4h)`?<ZFdWuJOC>34(my(&-)FkkpzWEN3A7Z6xpg6 zk$WoYc#hWH@Y(WX*9Nz@3U*w|i{lG0EgVjMwH$b?R`|RpFFMw;*zZkx(N@$O!oOQw zL##SSe_RAB2P^>0PjN>l8*Dd^)OMZ4TmqHgv<2#3Kwi!ST^N?+51pM={+y51n*so2 z&_{o+wxiz3r@j88o8zMx<dX!XkE7mkeX<2CF#qx0BtCw<JxLBG)(a4K;^W0uaumfU z@c>#JMac=jN+u`^Er69ycHdo?9JDss0=SPKk!r!=p7nbit1W4?u#9`NY{>N;<+Br9 zlIlojKDWFVTjQ%~n2;L~`uro9`ACo!g<XyXdk4g~%Fv~{&gNHxP)OO@X&S%_PFQ0s z<-AcE@LQ;FLQ;TTz{B9{<-*j>^PaqPHWTO0D~<6hC!ik$mY-G^r*sSURMkE#po9)~ z@HT@#0Lw0@k(nS=!cYbJ8>KBNn*<@MlqeI($5d15^r}a>{K!ookR3Tg7psb0%qd+( zZlxo&uD2*Bsa-UKNzyM_8@CwjMm1{dNurKmFVw*7!2zF@s#KSQfdC#QG2T^FKb*kj zKDmZJj^NK^D~XTcI-l@WhCkp|V{60`@CGinH5QzWXWB+Lr(?!P!aR|p;r8~(&a=u{ zKUz@~-jiPM2zj99Yylf|GIWv`A^=43Xmn-E&VmKF6j!Z3OcO!?Wd^6U%0F;Q1Y|pb ze7>M?1?INj6+pV^RKd}ZadB`8o1>=p3jYHUMd$)3KOooqx=gQ-Z{^agJykZA<(Xoh z31lhrs*B!E6W|jl3<AzS=HlV(yztQ?<Mf@xpmF};YPDPzNWgJ+yfm1FHMvDW4j*)T zdh>!}`Kk;^GkQ^GFvgrJlQp$zw1HB(W0`O=PV9<QFW3p7IUV}K<lQ2W^jS1I<iC+X zV9{J#MMA(E^M7qEix|$6*49AHJ`$iGW~+7BlSc9aJgIGM{?<Xw7PAiOm<BTbGuurB zu^?dxLmI*kE?&0jnDTsMRhYX;HxBi9N$#Txf({JYC8jnA=<=&~C9MJous;sXzPaOJ zidzQgs9W$2<b?twJB98lm&P+d9o<r$z86`Usm>Hg&@xZCD&h_YgKqaOykut(5uQc? zf%v`btXhe<EKD9RLm7)DAc=G?*(qodE%Ip=4NQXqqrdsp^94$mGdh754Qce6?@d|( zY+pRsnj}cHs_h6^t0V%t#mu0EbS@a_Fx%;6HigF$r4MiRVluFL``0Qfua;QMJgkCM zZM2TINm<kr_Gb}7Kn;70`1?o<<|~eNOM60{g@wZ~<~s*k6bw1mra#LNj=#J*d|F&A zfj%s15gLi3uHZKb@n=}!rcV)z90dxJ=IV4#y2JuKAADW&x6n2B*sSdVF73fz9{%-# z_V73sProsqCgSP05B&50bHV?Yho@o#Sd(;#B$1lT81}?o3geKmM@uRqPwXYMqq_rA z!J@bnbqPd1`l8I=;jssr$>5r`ZW>qS3`jnPb1JDVL7HuT#0iMC{L{D+j5@jrN9GXf zlZb$Ywy;s;Y-x1=i!b-g=ZSp2Z#@5wAJ5HR4*2OieA<C9@)Re0KDK)gdeH+Z4&hJu zHKcc@2}8q~mI7MyBI}}u&MS67(8Zi?dSu`Qv5tL3J8&1+Y1o8ahsy@098egr*ppq$ zex=v-@Q|^LdY3iq4|@Bkf)O-@%B1Qq_uRaJM$3jA$xqdGiJ1p<ZafQ5!AO!~8VOQ@ zS2)3RV=rti(61DRB_utXDdEZtDGp2m0oIT&P3Gde9s?cYKrUG?7)K<lZ_-3~*<)@= z(Q->LyBq+$#mO(XkOimkuS-A&8AijXZBKw%rue&x&;-qn(q7{15uJ#n8TN>(ZWBj+ zKWDlu3!w?hP2~{a`wWw(66?OW>YbL*AgilEH_k)u{kGF&+t}SvmxE&*1P90MB9kJ# zysW{Jpr>H)^mK`&yK$>6=+;~(A%YfE&bdj=YB5cn5k3WU@F<s`r$~&}G3F?!P|qq@ zE&dQzRtb6R%++K1c71GGk>7jc*R=vxfjS399U-r(jOK`8kOb?nzAO$0)7{$-eT4r* zPlFTpEu3Fb!X36rSRqncQ8iDi^R^zz7326g*|K}&XiZi$aY!Is{pox)gA0V2S`)lM zYKW`~4Uz<bFd2t{a8}Ic#U)AJt<XUAiw_#WKW7V42XIvq{8QZTO{W=Zf4C6tkC#O` ztC0OfKS;tTIBy<oAW8*E3mo1I(E_m=JfWN>QUnMtR#b6;qgTrc?ufTV-XK|0s>(0& zd0Gxaz5JvbLuG<bF;gu`G3qgj_bGb%HVT>;&_3xfaLj@fE*bE4FdvCGJp~S=xP%54 zF-*>S7ZNDo-zyvt-$&Mwje07htE4zsv$iKB5uh1)a4XqJL6_i^k}OrLi$;q>+&lLZ zgcM@52oMyy+%?h!8ONDDWwZcuh=7!4%Zf!hwUK4U`W<&wY3)!gedcvT*_2>I;nAe@ zLP}X6N)$Dd8=7;P0pnar{jNHFzh+YFRu%IPS$Kn>`%}zqIz2B)jYb{4ZMI)*0i6JK zf|}uJ-eUOrvQTG&{Tf2Ua&8yQjw6#lbDDKN9C8rsdeD1KT!`HW>xa!gq|&S{bbvB1 zb?brTV<3;^l%`T6v7#-Ts(a>cp)3nhfv~uk`OlEcHpCnuY}0Se!b-SZp<|HC$AsTl zJh-=id<=2`D>|LHAurEoQ$;pKM7^VLzy0=PNVD<j4?;;>C@gk$K}<ked-w}i{ng6( z2-yH_jCYU7$aoaBecJFyCr3?yT67Y%B$=@dt?L5cHF>2i;N54u0Fc<xJU}Tau@y9l z{;Y(L>!-q+pU;@dO$WP~Dfl^gwXH2ODv^5Xm<GxZ2ls}yy7842CBdn=$b;qK3IpY_ zRE5CUaXF(s<r+>&pS5}-3niBe^bK;0%3|Re&{nDmi2HW?@uiNy@T9-7m7TvLQfy2d zIjX)ua3>>%mc^1C>M*AVaQh{iEGxj1g+{tjS1LOd$XyyXMP5v@#teLVhbDbvHy=Z@ zCYbPaekTotmYE%cgtQAJa!YJvJlKto7uRnSX@854wzhXpu8(KiM}w0@dIOLmi4@L` zx?`i>5B|6gp`YzQKUTp@Cp}A_RR_F_xYw6yg<PuGT9ZG`hE{iI6f3Eq1t;HG&U5of zsMI;VU3Q%!Rr{{yXx<zsDNsntJf}o_n00MdWR;OYuqNvQvNM+jaOc^@vMAFspI>SD ze~dmccbHg6!gIi^e$(?j`@m`X26xuF_Ml-__<;c2(Unk><=NnI3zN!Q@`K-Uwe@5O z>*hq{Gn{qsg=o7zHaaoDv;LlJ59na)5E9OoKA-RAYKzcF@3QSij>o&5M5SfQ2cJ93 zCRBOtT$`r1nQ?qvU*oL5?B67}pDvXGST|9s8_;!%#$1il)8!JldN#{F%zx0MC`96H z7wZPUY({A|uu;AxZ!l!|%aiR%Lcah9cX0laK21-A`JcVm<kL0YgVO3gwz?Sw+DpJ2 z-M4|=>mAh+8?lZ^2}0KqHmCD+@%{zIcXUF1s<|tbjc(-^w%Gxwt`CxJ$F#Jz4|KM+ z*+M$4DimU5m#S7~HKwCve@oGsWi<!pDEml?SfRQ_{d<o>6pG8<#R|l5OU*8dllQh} zc?mO`UkP81ElVRH-SRKVy}TjXLv40j9>a`4OWF>0Ix5GDiC|*<4hG%MTPzXhLL9uU zgLnY^QL;7IO18DfK*IZX+D@ap08R33nmOg@qsX<y;s3UFtz9LD@(b8W3U#XsgTMM) zK_V8Wp(X$R3$$;rFJy`+tjbR@y1K&sC2dXy42{E1p+}dl*oh9JKAa_^$!WswSmb>T z%v5~^Y~jagwya4_(l~QFUry=ECDwrlL3zgNr`~FDS{Cm?;Fz9cU0!s|Lai!x%nPvG zuRvtrECy&KDA>FpG*s5q*>r$1Mv4p_>LBqfC@rJm%C_MAjkB5Sk2XupUTDCx)%*;^ zAAm%1$D=w%|4R{j!8wBA!l73J@uX?9S3ANwC*9ppm0ztY1SjqotWfWAn$}fa7R&Q| zN?p{b%VKNR4Ap);R^74ol}n@nh|bf6W|KmlV+PDRW=R$Wp|Lywp4RDm%ujbV$JAiO z#jY%$TkU@P&E8)Jfo1-X*^U89w}|R#tZ&ar%`cFJmRm(J5bp}|3n+`#yK@`mh_j39 z!WvB#9j+8);M1hfkCTBZ^RW&Q>Ap!iFhkc%&b#NlGD82_P?Dxq<1p9&P7>&SK+;WY zAt%{MzIaM!-CJP-*BMhQb_mXU-|?uj_FOOD-VP-wcvn!8zCf--I=Ex*?I=I-Rhg3$ zlYfCMgUvO|IC+D>RYnA3-c*%rT?T7G2VTX^?%RW1Gd9zsu}%HT8nHruE&wHx1*gBC z^tAc6qYku>w4e|9O?a&?SpCz!X+n^s+<4Cg5IM7M4wIWUouc?sOmO7aolld-@hxXd zBX2qa3B_%CR5kAAL^jA?qjdJLHcB6Y&ao7truh~4fp_CQIym8wu9gwNHXm>&P`492 z6t37F%kDh!!RCPD&_FGEI69=e@!M<QG~`{N-ki&Tra*Vsoq4*$H|VfK=1_-Wu{yPw zDLK5!cnbZ`6zNU&M|zUJ1zyj`>fPC-kM68q(n0nJ3mnR5;p6$%2^Z>@9jhSL@dPE9 z>TrP$GlsAVWd8{pw!FDe#pf5SO>G*ZDdwO@rWl_aig_$rgsk;$QOAooKDa)v0K7yc z{i*J~Ql3oj&}O5N0A<%+`GqG=LPl!c!`LewE=dq$_*7sw0a)?wcQ_q}Q<{F#H8A~O z1f?6xClBu9<gOYm*}drI>qK&Jlfk0jd;R>)o5P>}_8RjiW-pk^@AMufquV-@zoix9 zrAX|g#?B3lJt=%d$L}c`$;zhlc_9JX?(`-+OM8xODLz7LkQwAW^y#go2Msu+xsH^d zi78;Thc{jeg(uookWzD|gROgOC;RzVmF5|qW|+>}F>q|dL``F(i+n1I*ElP%ZqnV| z&YprBsjCipErigBOQO@%VavCL2Cll5;h|N9E6UexY9<5@AML13-iPDY=w<9xn~!{7 zs=N<)H@A*od(1p0kMs*5fCp!2E+rkwgC=*8<KP3VHvS6|2E4XKV|4z41{bS&os)!P z=5e@d%nuDx#!?g1DYl=R&GQA2;o-(d+PgAPfg7T}>7ur6IZclGR{6LPs(!+Lqx+-4 z`|m}uD{A6;?0$v?hN24fIqa=tHi%KshU#EmYzAo-ve$}PZBo`uv2XU|r5+vpa2%2l z;nQf;L6vVS#8J<!>BBenz>u=H2&R4Al_9a5wnG={PIqUXb({%-DB#gUi^FKCGu9-c zT&_?=AB)bBq~4UhAxxCcP#eoZJR_yBWMxOOsPd{tv7yO$K?c>{X?C7|$cu8#(i#g? zXmedbzePabh=fgsjFYa_zSfDKacYy-TSG1cN+)G(j%v#IzY^5B&a!!aA^jVWIFUVM z;JaYqxENn-%zt52%zy2+T{(H55bbwkby}hm{wwmQi0JBP_gPnWof<`{&5T($>t4@~ zHpep@!O<alrxT9p5((0F1OvR!3r<wsAu@{tgtM9Sny{>fl@&fI%{s!p=L3fIk=OA; znjA9S85T_*?1sH8i_`Q}gu$yYdgu-i37H-B&=GQn=X6P!JxQ;?D6?c?a*D$`yQp3@ zsTqja#_e7usOuSQUvus;ZZg=i8;RG#G3xbTi$rhW0ZoPv{n^Yp014juGiR{tnssHe zq0`lTj-K^s+?%D<IfYnJY(hm_C=GrC$AXADZJ+@hIZ_}+P<S0ftnw*Yh<|wV;|noJ zU+;p53Yl)whH>R~=B|keVus(yU51D-p?YZxaVE+8%j|?*kM~DT7CR~?hJIq4?GXfi zvSvlSef)<EMP|Q9Hh0u3o}70`KufsEKXbor1+>K3bW$C&->QAn9Oqd%fT(20j?Duf zd4zX%9*|Dh#u`HG2$iks;2~-+%}NLIJta7$QzNsT3eP`|kWsFDl>=XfZ8k$VoArL+ zfs?n;IW>52&*mv*(^xGkSQ5pXVdfEGQdWMWgEbpNC9hTs%0dz-;b^t*QNZx=Ot5)s z#_Q5?y~=p<yJ8pEoPzdqPWWxjRCJ4m8S$q_31lLi<I2e;WlCPZtts1WoP2MQQJduu zAId4VrQvAU7e?G$p+#)(x*@N&S(g1P1EQ61zO*@U$p^G1D%`epQfmS^O$W0(?TT}^ zK3G~k%ip1Rk9r3JfPc;#%wprj8O$GRX*oC1CVEtzZc=@@O5gEA?*S1eSBe`VQuEO* zp<=}%@<|k04v~xQh9HxU_ic={R?Y9AkY4K&+e2-wWG*aJ|FX2GUKj0)%O-_XcRHH& zOTm~XgzjZx<GFC*NkQ&Ci6H$Vp0?Coa%x5uD*a)P*_-tCdqZ1QVPY<Q2ZLDIQJk)k zVAe}6a~vuPC+ATl*g>wIZGXlkTK6}~-(#KTTWq;8_`hQ-yh5;LSn+G3ep&Xl={p4# z9878RG^!3;rCv6;aiG%A+}Y6h#9cP2dT)i8B}&FzsnnkYSwIN<L6!E|L<im^4;D^! zyLFkOvgn<iA{y}BYKk5kaQe`%RKSf>48KDkFJAR6Q=z-S-r)QAEmaYyw(oJ^r0o!U zNGXvi^J_M<lXEu#E+S2A9~+~Lqjy0<YASNaJw%j$-ot2V%x}O^ZIrrKPX;@<4YJY5 z`WIjH)>3vGA&F8=0d0z{Zs>jSMdT~o8pLP3;ui!2@=epY^Xy~JS?&Z_RGPh7Psh%H z@ti;O#%j8d;Kd(G&ctI_5xW3A>Z1&T+~ybCXqG{Z8UFW+Z9QcS(K>k4iBB|Fj=8zh zs^)B^!YeQ6f!s0k2ZFJ@63G*duqXqdAmCuAK1o3!%<d3W#?q6@_UAp#=9qIpH!B5! zg={w_+^Ht<&i3_qJ8^(DHi0FSitV7<59NN_-MK|?54}ed6;JPT@&+~{4@CiX@{6T# zQ~l&9=Z8DDQP0@~X}{mwx3JEynS(WWWH$7b!k5n4=7EK{w9EqfIUpp(k>MD)j?Rgy z=86AmaCfA@k&gOuX8Yn3;eO1C4rYVU)qhhwWoVAg-2sdM48lWT5cJ1821mnnw%o3K z8J7fN5xAN>2YDMSHE%rp4@rbCX~Vhe%E>D8>-iN~J}4<iPMQhKP28h$+&VI+j;l$p z_iK~%I;ETvSz6_Y?J0+NmM*e#;)-<C$<uQxIqh90=FXp>QVcz=#-6ItSZl>4bvBNX zpv2Y(J~qV1>2cSd#%&^xeFq%ZAK(*!`r}M?cGmh*Y>zb<-AdVQR{z_q`iM(ochvuk zb+yNm*?0dTS1W0lPe4s~ZW3hkV^@EOn_R5w<q8;$r^Vs}=8G4g&}y=0A2APY#YNeR z)BlEvM5x*jugmOTs~m+vd@aX_&~+4ZY)IeQlnOo-i~o4ti%CIB>5cxo!i=~xfSy_r z&j&LW^03WX)eMR1(V%fO*!@u=PxU@Z2G(jEZzna%B~=a_$WHvDaciejGo(;7LJla! zM8dzrj_aNH)wdiV-n7ChLh36cFP(fS9CXN0IgapzaeFjopsO<vp8Zf?%y04eX*$Pz zCP;-7Cp>6s1HeoNst+BX<M?hOP<*T<89aJ>aI$qU*?pHcGjH@vH!2H2T%(gI;Xfpy zrx~SK%4WM<Jtyg1>rLQVVYJO0NKv8=`Y9mI>2J{JHxei2Qi&RWcf31^Pp_LGv1_yf zUeB`m^=x)MgMaJm?Be=-|N8vl_4%Xg{QCXr?0TMG7xU}oHOOk$)pfO6!vCFKV?@m2 z9sVbOpIxu!$-(t^@o9N|UM9fIz(5Ddz1@5ym-QV`Qjqn=(W;ye27`zauNErvDtx?~ z9;g+hJaaMY^tj@0;}}C{s>$_Py-bG3yT`lN$GgeV&f}f`o$ma;xAX1x{r~mF@$O$H z<NxQk>$}7LV00WGCnwucd|c5m<LKyZ^xXkG!33-m81)#2<%z19<`?gJRXO!cl@sDL zzt1x&de}Tj=lU-iQmqNPHC6?`k1HBStZKsr(PYNa@$A!n|Itl^IT|aTko6EICD*;h zPYhUWF)W%L^B;9Mt9b78gHD(;eK#Pl_1JUj$l<AJA$HYzs^DVzYsmOkT_KFP?M{o& zk-A2(jnxWBSb24zo?uFXi)Bs8xA^X}#f@&0VCC`BitI+}J0o#F2u!O5hgZye$<MGe z_2uD@KfiqS=J8K&hR8T>r4{DK+Tu~sB)BDb!Y#Pwz$U2gB+O?VAXmYIvuqchW-_5S zF8~I-t3GPhIZKx)^$~0O^yRbXuYWrH`RC^_iO1i3_3i$%Cy#fY?LT|8v%mlB`Oddr z{`Kk3lgD3u_0`wUzWMg6Zyz-P+%+Jm4upm`73woNO@twm$S4WzmE~lQHv)0f@#Qw5 zNetS(cYQ$l{Pl<!M#`8kue?&mRLoyjQo=0ZMbjjG7T-~tl$4TdVa9j>Ehfz`E|zJT zSH+?dT&7ugkX`)=i5oS3#i=c`#7@<(ohFR*1?gg98huA7Yg0B}dnisgHx`&3uE)_y z;;^6Mx{0>H_j|#MGqwN>A1%@g3}V;s65*tG3ph<PvDoOl<pH9lgYQnugYV|~!FT87 zfmNo#ick^VFVh^Y17n!C^G;-NbKfnpY*vvXBAt7(!Jx}!Q7l!YqP%qSx}FJtx}uzE zd#B>~rZq8}dn5kqI|XKb;0E&vD4~7_MmWMoCmQ`m(h27?8Bpfpd;7MU2d^!P!-yfI zs3*XpaDo;2O6}!x@R0I$kdbB7V{Ad$3X!t}zW8j1c>p&zv)lomH69>sXMv?oOE|L8 zcT}%YEOQ&<#S)NXcJ>ob&It}Fv`kA3(gr+s4R8*9+S&KJwF3x+?xFUm9AwP9v^h1Y zC84#iC9g^zgQ`bbd72!iY?8I@9K7re`dskJ=%j3e=*$oFGqdoX88a`I+Jyz}0tyZY zD*lBC@w;8m4us=IBtRFn&o@e0f#9sYAKfaUn8&AIj5+om3+u+J%Po$bh=pX$ZOQO2 zxwYdu;pWm+(4#51z46<S>G!Taw=RegBm6RSNTF=$MY%i&@+z>4QtAj!z?5MmVo^_- z;F%0R<_ysbq<eg?nf6s4Ku&;2_J+O?Lq=Ub^)YtkPibJRpFziRGW_peENh`-f<(Ys zN_JMV+r7(+*>CxRg~)sHg8`Nwr{6L+KEhvXrbR9H4CX*<f_V^{p(ric$DR$KdxQ*d zQ2fKfxA!>ta$T44gM9X&-+Q3uwex@qo<Nu0ZwQG37J4vPVxBpWg?~c@`GbVCvSNW` z+08EDp*@6n(|Hj32F}*p9Do&UJEv*s8KZd_97Y$Vm14jzlG}bIETB|ezRJ9rv%D^( zaISiNPETVsVxLrLVp@IGUE=F&P_7n6G*;4_!O@-Ftvhd4<!ONl^{U=igT2Atou|d} zii^qrfB$dq;okn&y(hqUP1B2IzxU$B(>s)+Lp!FQLVwdfG~JIssX9YLt(B}{wwllH zj)jf{K7^@X4VJ6woa&6<zi+%poeXU5<3)Z!!9w4cfX{E@r2ioY?y~7U>z8VPdVoZ= zEavm998f!YebXoZ%cpQ3GS9S(ubP%|a&vQ&4AA|G?}qVXM4Z>yTK^~nCu|K<8R1yV ztCytq8msrUYS3Sd$}yZ6K<hC_ktd6BeUzQ_OZaCDZv`T{>DTi7YyD`j$i!r6{n^-> zOWn_8SM^w;r-A(AIs0z)c|+oCtj0<v8U*FEdA0<LQ8r3G<!5m=SQNAD&DAm+kH@5( zd;a42kI#R4^V?4#EZx6f^6avHog{L?qimdM*~$U>u-h;xtP^LzN_<dd^_%=6D^|el z^!F2l$Skjxh|qPAWIRg%ZNKQ}{YtJoAM^4uSkkAPel^Yqby~vh?w9cAl#;lom|A85 zKWAy3_KOBmtge5K^-|)9{!>LszZhWAFMeA0@9sfQ<MG`+e1RQ^0T+`64jA*VYElgw z`XCp;eH8E|F6+XxCV3F#HfI2U(zDHcrn+yn_@k76!0{W1R0o{etSA#$Ks~t3PT%Kj zDb!z;@am#+9%uNt_}zNWJG@%uGw;mlV3p%2>eu6Jygz#M^}#qB)#L5$EGf6g-vV^& z>+Ah5#ec=`hxB^__;a}b7618VG<>*6f5udg_zZa0GX8Rlev}|56c=%lY=4u094ai% z`(GzRt?m9-R%4@Ob1e-d(bqBM;6*VdOr|fjaTnK+zz9JPlf8dGuE$v3w{#93?^+zC z_;x^=ySkYX0F?;$X;sWub@t1v7h`S&hyeabD{0&9KRn1L)K;KdY-)cyjMudoR9L<| z-s|sVa%f7vEeGS*`$=-6&|JSzhmssmd>5Rm&enJl3wD&7)I%hi_$M^Oo3TXW37QU& zEWf1GU}F!4cjn7EY<8pmqh#>k1?sMMBe%n!VaHoAr??^YxWSY5K&;5vMXlq}+v8nS zyTBil5mqlw;8q;%pA0_~`K-5>z~W#M-Z`iOPE}}eqG6mgOG^~kojzZrmD%r_ZkzFA z*(-=HM|&qu&(CEb#O7f0%}c3*c8>=~ZwDB^N>JM~pk@IruTV+UvLrRhrhAO2x;`Gj zzrey@BO8DHkrZzUjA(Z+9l@Slxg=aJ5-u7%<I9j&&;PYb=Whyla(!LI_9-FUZ4Mzm z@ZJjhYLCZ)l+=^jxVHjCX5V!|+|A#!s}O{mi*A4UAFp5j)Zu#BpD|Y2_(KpfSJ}(6 zPTzSMge<Nbv=ArTb#qNjo~Zc*i7Vb6I9ByGUB|*tcWZ_7WD2GPHX^&}FWTGhSj}r7 zfj0q?K?lm;osWx6m&^GTuvEar5Ul`?^#&NuAL@Gfinr8Dd4R$qIu^V<%Ioid!i>wl zei*o>O*R{6vF~x8=dQm()@=52Ra;-k$DS{~Pjhz!e&}iaqDW^>Ykufy{c~Bo!_1J* z7tIU(t5rE4Hw2qKBdNTBycx1{U`<QlPVKfuV%%?*R*7=|<A+zU;fi_t>G_*qU%vYL zZ{I&YeDTYx=VM?Q2X794eE#y6H|p8WK0K_M(;a_}Et)%0Web;e8tK>M<9T`iKIfAs zbvdtoQPla_)nhm@InSG;=fydp`pS}vs4@klcuzcoPHE_-4bTwacN>d6urFlLkA;jR z&y@lqjgieJwe=uQB;FGLy)hQde0c~b&|;gls=2181un?jqkBSpNLSoiq)e+C#e#_g z9B4zwZx=bSI-R!;CysAm9ROOf6|rYBHj0q@{cvyZJC@dHe?X{SRmuJPkM{PE%TrsR zE^mRZlmPNy^ZNW%RsqSa5M|=WrT9s?`1ujwPTA-O@^p!#M)2K{=RZmk;1>sHe3#)! zxa0Db#z9}x6e-`bKIgtW2SC_2j35&)I0f$bTyU!0zQz18pu8?uDAw55dd=h&s{B7? z`W6OSGkrxH)=%H+paT~2b*iM~II7hN9E#cOkQY?c|AZ3v@DpJ2p+xC@I8{T56F^d1 zGa1S-BIfdZG2475u<%>VL(z#ABsWGe=pR46&}e&un9-&aM}K?%CQ`(#e^<xcl9ude zkG7aJX?rhT>Uh2uL&$6Yc#6T(Q9nYJ?k=*)eJp({;kHYh^Y+J!d6cwuqhXI%f{;cg zUDZA>7E6I=$1UVrG(|i-4)6t{3G@&0X@JuZZ6ut6{EKKu)Mf1Bi_D#EE<%v6hYmv& z+B%LvdIi@H6i;U$1-V7vp(|i?y+lYOTVWA~I%=TqBkoy%xHsD}@etV9=-EF*v4D2o zMyI~}$tK*#_xU2P&a)Z9&UzFp5DHG1+{c@n2ftvde>&SP7xpAA0}3O-v4e0meLv46 zUn_p<+-y}}%`;e9CbfNIjUjz)zm)5j`{ViMXY*CedYw{f!N$OHu;vzHMxMTYJ&pzq ze%z5gqwS^l>3GpoMb3sj60Aq~3{mSmy&7_U5qeY?ON`ONKQT|I{F^<phP_A2kMz5# z$TaMIvA6fvug}it`R_YqO&RvSh5vDfWx9|fv*TH`U2aDg<gSwKARg=$%XFI8SNLZ4 zA-!w<qE`8$=?lo$#gPA;1E3zwKtSx_|4*RJO=QTo)p>Cl!trRlKqix~hS0!?heXy% zuYlUI`8>FT;=Qw5@>HO=Fr60C8CrUR^L&=AnE@6S>FJ%6E1)U#An+FdP;)#3#A{EW zBNMY)gcks_FP7Tm;faFIKKzig*jKDegJx<I5&kEt8G;Czln~=u(IuG2d2Fj|0{h?r zpVH%^v$!bj#Y|7^zp8!n3o7(S1zi1eus{{sK<jSvumkpX-0QbA5tm`S-w#<5Jd3ir zYCb(JW>-loXg$X#xK-^l-s_w8qQO^Nr8QXSz;%UUW4oFJp`(}J^>q?Brp8?zhfJ$F z0XW2XMmW6_-@~Er;TQlU|2Aof4JhOCd1gaKRBu=Eq1bhM225NH?V+G<fh~~tH*PNL zwqd8)-QTk{pyH@`y7bzdyP~VMJGH;J{q5dXEhZTKCDJ6S+Ts0M5sAqK1r0+qI`ZEG z?0C$q`n0N$1mWLLfxT_0y2k%EM7v-6Cf9N|I!<ktf1rs?=V?{_1P~ra0p=j0Dg5cI z))Ou$@tAyi%aD>(uv?9<fK-tp9oM-viOS8#IzzV9T9ZLb=k|z~vTW7Be(QSN{$gC& zI);7@&n&^cUyQ%nGZlv96#=6y(aG^mA=Ngh4tP8@t&@iO+FUv#r2oXee0@lBv^}m+ z@%a^Oc~z}4r6|DjLD|-SU_TLhf^r>MFJ`Y7=@J0!XcTCeSB64yExiDkH+Tf)WHegZ z!(3lSSUeACT67nri$O|VPJBB}g4(kTc-J@?`Wm!NdW{+~IPV7kv~;dCegPFHfLG}O zTe|USkgQ`<UFN72fxpNpd@*F-@S$mE!U5xCBv8&UG?A8>2$?MiE97F=L4FNXxP1Go zjB7;MJ)nEr;R5h_K1=Jc4ot4q62n6WXC21@jRh++*0~xV+9}${>@X62Vo%)yY?p5E z6S&6292iq}SLG-gNu%SAA$-N=()gl*c^%a-Ooq3i8zgC@vl+SSyr5K~sMW#=M18NW z5Vcyd`vwI%R07`JN8BUuotFyH!8DZ<LNX~9KNm}KqeHv1`GhHtv^gzowlc_C2?LE3 zLEWV;izU@RitIV?QnXIc3F@Z5uvo}-Bgf1vf5xc$4Lhw5jy{KDuLoh~nDV4Y%W8=i z9EOK)qdxP*3*(HEQ}S)Q6`%Wh*7mmP+;D0$m12~s@(195=b8L4PVV22^Twr%w!Y4i z$wJf1D3^-ZHE3EFEdkCVA230r2Zxkd^DNIwQ+X!cJYgbBo8Nfl`#eUB<=-{m!p6Sq zgg$rXrwnD|!sG4`r={Fd#-B7;eDW@CSOPH;OFF8zBbq~W5-&&>OH9wA1@Y7a$xwK& zcc%M*;U1vK-^a6qf-(aZABlY|C*?52V`DR^eaDYAU&qiV*ep_LBHPF-i&Z^kae<yU z<eHVKpKU%e!RgmzJV3Pu+<EFnAUf<-Hp|pFEvf<KF!l*yGOP!{IFwh?0Z~B;SMR<Q zFrjfYK?p;EeL^@4mC14BW^rp&3dCrH;c?`)m@n;d(BfJYwa;%*of4^Wb$qE_XH?Z3 zFbi}Mq1P0;m-SiPkX^>5J0x+wPnp%XbYqSul^SG<AMFSMA+kCJcKR{<1M2%zmscL` z1wqByg`<2neh_WLeS2^MeNR)tTHct$kYg5x4WN16opiJ)WLyEU@L~zha^uAAmYRe+ zrL}L=Wdk{%4|ubw%^@-%@)&SSgq01CFve;8K$D&ol+e@js1#lcJNqYng#d8$$8}xi zrz<2pQ&t2-4bIKh3fxC0?9BwS^Q#O~lw@HWg=rc<1sHzdx(6CQp^LF%wT|{qfK_XL z!cyw-qwkt0VvQ5w@UEWsA11@26U%>#XmYa?V@<z79{mfF$AJcoCD*qAtS+a;e*1BO zzFWnl7%o_g)30?9-H^MtG9JMXUNYP@_U6`k27K|Ka3X^Oj3T6XZhy_^a|XDu5oVW9 zScPgEt*E)!o0-|z)*DON#hgaVEHrT^_Uo^vWxlL^I9W&k5e1`0=#_09Nwk>nXoot3 z@yI1F4pWSZ#w40ysJHZA{gMI>Y*%?VM4+GcSLA!11E-YAiNRwy`S9f)g#?Ju;l%+Q z?(OZQ8s|qP9yfqA1_H0fLLb>riQfbXz0y}%^jC>GSZTYO3#0--0?**a=ksc<`?y>| ze@bg$9}H>4>+3(O@u!>qbgVxbOi?wB6shW0u+r6dDp$HXs74j6G#^ios*`@cCd4C7 z0Z1UrG5zk_BuY*pIZ96^8T>QEe}D&r4u?gY!-1wkZnNP6f5_%=rBODNKN+-n$g|v_ zLE@|+>uGqunygLFn4RO`{Dvnb`g)zeTcq%5TYQc6hC_UeLEtzYo$y}a1j+<)cYQJt z0O(_AlsH4`#4Pl)B3#%#9_+?dtbQu$!-aE<YS%$pw5Mndpi;QW`nT%3^*vtrj`sSG z99H%19eP~{?RS1uSld#`ZCOz8I2`=qXmQfVbB!ZXoRDgq-lgCZ&q<3H$@R53sU?sz zwTJHM`nfDnC54$y<XQqDJyJi67-?b7y9pj!B*l1v!DH39;3?<$hd5R>{M{Tu4o14Z z&L`5>@n9e0v~b#j6qfzE3FR2tue2bTei3lTPA2l?3`_piY-l6%c|ML<v(trI(DEY3 z!P}BNfH0)*(D-0xp6JW@v3GWPyDrG~f<0VcM>r|^`~H1>wVs8*66pqSXz$RpLyd_- znsdhW4W0%{&4ni-OH|}tfjWWus5lvC@K1wSH10^_S@n}jJkkQ5{PtV5T4v>MznLu& zZl7-OBD}m@psgV*>#I>C{JK12X)J@dG+qg35L8k#>#~rQQICYeLA2EAB#S!Qli1fM z@z;s!w?hZo=+?)`UyYqMDAFjg8u&@z0~Zbx7{rUUL2#<aWp*g5n8b<jxwy#6cjS~C zD{H!BEMr||6jX64^%brlMkeYE_^j%C^fq|Bstfvs5|HMC5ht2&h444gdCAyPW2s4o zm`sd}{fT$Lr6F=<dLx6jHA^Q0dvhE-IMvgcx0P4JN1GgqNr8tSVEx#}KfU|{!=v&2 z&slkqE*jSW)g-MdU@Ly&<77{w<v0Z4>RgQ$MkYqt#&a23KQX7+x{pC}#)MYM&}|2y zK%$pnti)I)kSq_fQ3lLu%>=Jta%(!z0I7m|A$%_y=DP?_-`K)Ur*7~6A2MytaZm3b z*ArS$mmAS_ZENq<Z5L_y#dO)5&sap;mH(3uSIhNpVf5VjhY(2KGJC-bN}pKFlOeX# z*IQg9$t35M7Mg35M1x|bq^%dtg#ADT*qcia<Hn6w?p&=7%Ql@}jk{Ao2b~rgTA7Zp z+noMRb^ZVwoBg!Y+@Pn8il<fE+CsOJNzLQLej`g8>J1SXmr}ILfN_8<CBdl#kIR~A z1f}2ZQ|OL2*VEh%Ohzku>b~;MBdtY6);Lcb{XA)-kMh~cku8ZWWxuGkH&1#y?(s3h z#wD^X1Ybnk^&p>ZM;pu`gibbJywp9qYwUEHyDac1m7VZ9fb&+W_y0?!#pf8I<BE#4 z;gu)-A<$q5vsY3U>LV-{l2$3})&kQrv1?@bM8T<D1c<}2bWV3|XT){7R(4Ve4zvG1 zg8Kd+Kz7SE_2wo3YrDl|r`uHzY>SC$$oKl`NIiULUXA&^lNs1H$0~P4`y-zP(&LJt z6z58Lq1)T_6<GZ_*UQkaDrR_G4=T}f9~~Sh3J>*{jq#S@gxLrm%SZ7-#<~>~?Y64b z7BJXQdqJ23P(Wr)(&*HS3MPgrq-xbON?US2ip1!d;p5-oQ!fzReKAv<*;+JdUNp{I zU#P{5L($jvRX8DeXF%`^4R4_3(AWg|KizK|ZhtYK|Clb)cR>Sm*kO*pmfqU(x9Kcb z|8dT86?Gq(qc<*V@=5G-oU8v3$GJ5#@Hx#H15^7qMOzq-Xmq%!3#kJ1b@8(Z_iOWh zpfm=AB(D0x`%HcwyAdgBJ3|DXJ;3C^@u!bN(J4Cc{^RA@8C>@MmHzOb{P4yO5;8hk z7d<PR>ACcbfYgbEitO<zdA-ZvAn{P!kxuSq<bkq=G*$WU>NdR3uF%*e4ua?et;44G zhUL_=Hv3Vg?5V0xhYWc-$<IV6VTx(KlIB1#ice=Mvr=8Grsp)0+3#{yx5P1AmN{T$ zeB9nkX(+4PGCZl}0n20dL1TI7qULt!>t=B>wkAW9^jsLbBLODd(E)|KzC1(vnH}ux zi_|Fe3e$v5Gq_3e`qR_ZqB_sdYWzUPXI<E=13v4dY17A1Cr&8XYMW`SM>Q~wAS@i! zje?DH2Rjhfm22hL!>_x}wp!Y&_<w{pQEW_yd`oUP5l5Dc3lS=ml^9cO5-a1O9$1ts zPt`G}Rg~mJI_`S18i`Rw@RJ?rBc3Y~0f#xlB$s(Q$KnZsn$-D4zIgXzhS7QoZ8XVB z*HclWPicXm;U+R&)3hjOZ?tjZsEH|x5@UjbltsqUj1VLtgLO<Xq^sLh=hiGuEu4rX zOgJ|K_NQ!4^h<bgnbV$%tPxRQULsCq)0wry@A+b8K~IhY@C#>D5I{|=5E@*s`9#l3 zVQ1&H8u^!vxomE=WU(C1h0}d49Njdj^<O-{_QX_rv|3xbT@Fj4W`fo?QT}7&vg(Ng zjkG8e6)rH;PzIp>g(4*lr~zTdMz_*V>hW(EADh!-9<(%EVw+ICATLVZ`iDkPAE$U8 z8&_mv#sJCibMaQ%;G5V-;c@9(kdZV-bRg1{`S(ov>dt(!uzt?&#<hbPosYjSN+oU^ z^GlNJYt6-3Z7(ND#ViVqi*)R3Vn-h~drlu4j?Zx-k5g?$Y}rAL?P283^6UsOHyAT~ z>NUS~yHoUG7za;`?#^K6(=LrGMPAsttZQwT=;M=QB!*dE!3{y>5>{_QnbL<cq@ykR zOBoL&@>5&FlVYp~01cc=J^rzMmt>B#Nei58<l}{uye^C_#ijIsk2E$zW9-hbtJ`5$ z`(ejfMDlq|ndR2)>g{Hhwa+XI&#c)@*iAqEGU7+W0iyg~50aAkRk(+2Ci|Gg7Ec%I zz;g+RYzQia{)w{bW6VwEi^p2ic^etA=Z%D<EhnNAu<gtF<YQ#?@1sqQo|TEx^VFdH zn<S3BWhyQ242^VJ{uk@#=}q?-(DLb*Xq*Y%MTr)m&}nc4i!w<(?6)0=E-EX8Q#!Ur znFppD9M+%ukobwf9Gv*_4UZ&q*Bc&4IjVIcRf4kcR-4jdh%=+N8r!LOi?P95OtjW- z3dRoEOsUX-DKQ$nDV8eVfp{cX8gI+KF&CG|42|1b$--2!X}IZGTBokAO~6nl(sQYv zt*}J)I)uc`MYoe}i@ysG+{P5HoynW9rnqg5pFR%v`d7of8|O~g$2^Si%#ASA1Iba1 z0UtF6eAFl77&-iBl$-Azr!ue^O@6HD7yKn$WLcHiGo<ZQF49xfoSveQrj)b!rerc2 zQAg?Q1IqBxP;|@JN_LA%txfv8aWXep{IN%m61d8Dr9#zazlV1n?T5x422qHvXP%i^ z>hxkdK2Fp8*1h;^EcHJ9$r<Kp8n4OT)Nan_E;!Yr@OcQC>h&3f07TtQxTQ6r=Dl`% z|8#xi(?-weS4v8K<UF6gf3i9~)l#wR&vb1gJ%0)WY*ku~<wGOsQTi@3leRZc^man| zASHj1{zq#-)?0o{MkYPerC|}|HinfjHd4bI<N;&h#0s<$P~BCSX#JAKuT;i$X^?a6 zfdr?>14zo%>$ZRP@<$QI$RLYssA`rxeZ@Qn!>p*KR5DGC!bf3|o(huePtBTF{$S{y z`T4$uzHV)}YzLM1lh1&b#+<<4Az1APw1DdD1Sv1Q6h~7>h4KELFFTRNp^M~TI-MO8 zXO2!(Wc>*w8qpFoKSr^vA`1o3NTsvNl8M1*9C8y<D#5#WA=#^9Tnf69Op2i*dLF*J zEzuaPX8|I;m04t*`B|FQd}9WTpjU#D76z*B<s>eYBI=cS{l70tP3m3f`~9D?l3f3j zg)@f5jc*B_xqB4D`l$%oXPm?<VX50P`N#r$#{HKMWeLsBiedLIuUSzuJYFbEOxcVP zY8O&H?aMVrugro5$JX8s6r1ykfBJGhb8|OM+2g}dqt2@m<YJ=v8MfZcwOS|R$|`=i zA4upE?yhg&^+n&biy-Tqtlb(R5=*pb<%{#kIzgjCYb>fFE!YM50Zc@qnn2kTmL{Hd z;r5Z?vfK-`q$qLHQGoE|Z+GXQVj2UrA+RwJEnTP>2PWCqfU=ai=H_Xo^tg>CQ$i}) zOtiQ5K~GQ7M58~sI;4moQ=QV}FfvspYo+imZde|+#u~N`^y>9%THmdvAMy2T`8KUR z$W7RVg$l^S+U#>&uMr<@MIjv&>9^>~Q)(nQ2?lz0yUu3PmLO1rbx?Sco=)Wv4)PP8 zV?Nd+QwTv?#3592f<<jN?`3-pqwo~EjQX?a-@z`1%;`(v+(m$p!Ym2_9Yiy&xo0*~ zS`L)+bwwlLheaRL(1#TU(*o6*rgS%notHO3G2t)r#d{zJKXJVtu2q|0+l8mC05Ose z_zbo2VpK;C_@1mZC<s8qhTNl<65`?kIxE8*pK+4bSb3OX@`9;3MqgD2sN+Td6Uzw0 zEM(^FIu)N=xs@c#e~6wUgx!^q=ignG>iTD1pk1wHt-!PvjRmf?BY2@wIa@QEO%@n( z-S!qM5{La0pQmBgZ|W75W{t(BB=Yd?-c7esPGOj3>n3(e9qiC)GRi1rpEE52+h@#b z-E=y_#bRT+*On4c;hb|_%W0X!rz_-{Myj=n_&2!DT`OmW6r`c5Su|Xyz9n_=Es9kl z8Q{f?R3d@lI8U!#ovX32=;a&9mf%@<BWkQkEvias+Y}gGqHG62?X?~}#Uc%N@3u6> z{BFnI;ViU)9F@u)(y6HIXjTz*QPVsPW`(WHH_y19dTzOz^;b%<ON&L*EUkAH5F&Z> zbdnC0@?+&Fb`9%Lg)J-xw}L*BwLA?LWwmj_@D4mp?bx*9#K&2<%z<abyK(K%j_Yg5 zAfTkiiqPjXW)1M&<#|3mKiJ1V(|P^(><a&y*5zFMiOD6!pX3k@f4hRJk1_FL8HUI# zvlNOXbyeu*1#)_Ng!Rc!h5)(vh^Ky%L_xQ`5ToN}NY+xMnyF9iM3^{!lvo12K4mIy zADEB933V}xu1R9WtdmIFDiy3YW;7rgTsdWP)*x+%NT1*+A{pb|@wjZCS>##_J+KN@ zcxWnT$A-{uhANWRG*|KV=|{YhVM|oxZPiK6$ZZ{UHHF(g38pa|Q`&aOTn}PJ9W+Cg zs6r8bwwf^(op<zT1Jri(Yp14%;VK(&Vi=EwR=TO+2)#Sc#=zHd;ORJ2u~r&F8tWuR zP>WCmeq|PCL0zX=WZSL<pp8F9-M}KI<0KZR1NJ7-p&S)NAC!kq@1mHku*MnxcaVKV z6GAmHe~#;+>)g`=beu2XQ~vKDy_m_rk>u*bj_zpQn!QhVdcAupuS_z4hYu{4<w3uv Xe{cgm+-dF6dHw$b{Ay8&SMUn}PmP_r literal 0 HcmV?d00001 diff --git a/public/assets/active_admin/application-3ee24c8b7a313a28f1352e08dc4dc31bd7d4489b6ad5f6331f1f42bbded33a50.js b/public/assets/active_admin/application-3ee24c8b7a313a28f1352e08dc4dc31bd7d4489b6ad5f6331f1f42bbded33a50.js new file mode 100644 index 000000000..ff2866229 --- /dev/null +++ b/public/assets/active_admin/application-3ee24c8b7a313a28f1352e08dc4dc31bd7d4489b6ad5f6331f1f42bbded33a50.js @@ -0,0 +1,47 @@ +(function() { + $(document).on('ready page:load', function() { + var batch_actions_selector; + $(document).on('focus', '.datepicker:not(.hasDatepicker)', function() { + var defaults, options; + defaults = { + dateFormat: 'yy-mm-dd' + }; + options = $(this).data('datepicker-options'); + return $(this).datepicker($.extend(defaults, options)); + }); + $('.clear_filters_btn').click(function() { + var param, params, regex; + params = window.location.search.split('&'); + regex = /^(q\[|q%5B|q%5b|page|commit)/; + return window.location.search = ((function() { + var i, len, results; + results = []; + for (i = 0, len = params.length; i < len; i++) { + param = params[i]; + if (!param.match(regex)) { + results.push(param); + } + } + return results; + })()).join('&'); + }); + $('.filter_form').submit(function() { + return $(this).find(':input').filter(function() { + return this.value === ''; + }).prop('disabled', true); + }); + $('.filter_form_field.select_and_search select').change(function() { + return $(this).siblings('input').prop({ + name: "q[" + this.value + "]" + }); + }); + $('#active_admin_content .tabs').tabs(); + if ((batch_actions_selector = $('.table_tools .batch_actions_selector')).length) { + return batch_actions_selector.next().css({ + width: "calc(100% - 10px - " + (batch_actions_selector.outerWidth()) + "px)", + 'float': 'right' + }); + } + }); + +}).call(this); diff --git a/public/assets/active_admin/application-3ee24c8b7a313a28f1352e08dc4dc31bd7d4489b6ad5f6331f1f42bbded33a50.js.gz b/public/assets/active_admin/application-3ee24c8b7a313a28f1352e08dc4dc31bd7d4489b6ad5f6331f1f42bbded33a50.js.gz new file mode 100644 index 0000000000000000000000000000000000000000..f50627cbe7ba717d19be6f2888ba71d6fb4caa22 GIT binary patch literal 669 zcmV;O0%H9iiwFQ+-*;C61C3O{a@!yfz56S+Zc<=u6X(#2U0*t#{z4CKszDO6Xb~uY z5@#C!dlyNzRa@!wBGB%>$G+VKS~MmL${Nbx_XOaE<~D08X#(SDBu<L_1!}RAD{Vzi z=5PT3coGg$5wbE7t-~i?YMBM=)~)}NvcNx&M1<!e$XaE;q+1yqC@+Qoax$^8v%1rA zS%^jlKL=a4C$4+v(E*!NJQ|Vmt96wKD<Cf~i>g}WIqBVpBeZ8i<P8m_@+@X2C^_f2 z=tBrQVw?<(GebZhN^iK_2WfJ8l`8Ae2X?Fu;hC1gC56&KI-jJ$5Qa8nqHh$S7EV<2 zZb51%cXEGBsxzXFXJvBx%(cx#q~IP8$x7~PtpX(<hB6S2fV&^`@%#4m@%H2A_(@-5 z+g~$VRVuK%3(@23$U?`G?$TCs(9*<weXPm)<m?TI-aeeIg>^s`8ka2&H=Q<)Kf6$_ zLBXf!z|CwnJgYCl39wZIRsdB1eb;(;73Y?=1z>+OoRZ>o<4f9xvmwi2a=q(obD{6R zC}aGmRc283VgI|%C#bi=&if|Cf{#`4V%`dD0VOMC>Lw7@vy4~2M@Aff61tJF*=&H2 zbBernw#IQ+UZh&aiymAf|D7z3tkgO0u6rU(p7c}DS>hCz!tCUKXz?o5%IrKPM>%ai zX9Y%7as|`J?G$E19W$6dOiwDV(tRJ_q$in(yiz8~tif9ufCrJ{J#H7;2gj+P<L_Ae zD3BPfWfH8_9{6}9!A5t}d8Kq5zzseW6bt43K<u;1Ly2lLp)-2FT;9S0?w9o*mni>@ zG`VfCGv6W>2QF5o-m~fa#7YW$!UMrq(5YP+$Ys?g-F||@fCuZYGwaD87`RRfBL)Bf D(7!?< literal 0 HcmV?d00001 diff --git a/public/assets/application-2fb50a7174d540a1e61def8f3733ef9b16048a46d710d6b766260ee4589d4840.css b/public/assets/application-2fb50a7174d540a1e61def8f3733ef9b16048a46d710d6b766260ee4589d4840.css new file mode 100644 index 000000000..4783383d7 --- /dev/null +++ b/public/assets/application-2fb50a7174d540a1e61def8f3733ef9b16048a46d710d6b766260ee4589d4840.css @@ -0,0 +1,10 @@ +.select2-container{margin:0;position:relative;display:inline-block;vertical-align:middle}.select2-container,.select2-drop,.select2-search,.select2-search input{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.select2-container .select2-choice{display:block;height:26px;padding:0 0 0 8px;overflow:hidden;position:relative;border:1px solid #aaa;white-space:nowrap;line-height:26px;color:#444;text-decoration:none;border-radius:4px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;background-image:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(0.5, #fff));background-image:-webkit-linear-gradient(center bottom, #eee 0%, #fff 50%);background-image:-moz-linear-gradient(center bottom, #eee 0%, #fff 50%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr = '#ffffff', endColorstr = '#eeeeee', GradientType = 0);background-image:linear-gradient(to top, #eee 0%, #fff 50%)}html[dir="rtl"] .select2-container .select2-choice{padding:0 8px 0 0}.select2-container.select2-drop-above .select2-choice{border-bottom-color:#aaa;border-radius:0 0 4px 4px;background-image:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(0.9, #fff));background-image:-webkit-linear-gradient(center bottom, #eee 0%, #fff 90%);background-image:-moz-linear-gradient(center bottom, #eee 0%, #fff 90%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);background-image:linear-gradient(to bottom, #eee 0%, #fff 90%)}.select2-container.select2-allowclear .select2-choice .select2-chosen{margin-right:42px}.select2-container .select2-choice>.select2-chosen{margin-right:26px;display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;float:none;width:auto}html[dir="rtl"] .select2-container .select2-choice>.select2-chosen{margin-left:26px;margin-right:0}.select2-container .select2-choice abbr{display:none;width:12px;height:12px;position:absolute;right:24px;top:8px;font-size:1px;text-decoration:none;border:0;background:url(/assets/select2-d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8.png) right top no-repeat;cursor:pointer;outline:0}.select2-container.select2-allowclear .select2-choice abbr{display:inline-block}.select2-container .select2-choice abbr:hover{background-position:right -11px;cursor:pointer}.select2-drop-mask{border:0;margin:0;padding:0;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:9998;background-color:#fff;filter:alpha(opacity=0)}.select2-drop{width:100%;margin-top:-1px;position:absolute;z-index:9999;top:100%;background:#fff;color:#000;border:1px solid #aaa;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 4px 5px rgba(0,0,0,0.15);box-shadow:0 4px 5px rgba(0,0,0,0.15)}.select2-drop.select2-drop-above{margin-top:1px;border-top:1px solid #aaa;border-bottom:0;border-radius:4px 4px 0 0;-webkit-box-shadow:0 -4px 5px rgba(0,0,0,0.15);box-shadow:0 -4px 5px rgba(0,0,0,0.15)}.select2-drop-active{border:1px solid #5897fb;border-top:none}.select2-drop.select2-drop-above.select2-drop-active{border-top:1px solid #5897fb}.select2-drop-auto-width{border-top:1px solid #aaa;width:auto}.select2-container .select2-choice .select2-arrow{display:inline-block;width:18px;height:100%;position:absolute;right:0;top:0;border-left:1px solid #aaa;border-radius:0 4px 4px 0;background-clip:padding-box;background:#ccc;background-image:-webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee));background-image:-webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%);background-image:-moz-linear-gradient(center bottom, #ccc 0%, #eee 60%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr = '#eeeeee', endColorstr = '#cccccc', GradientType = 0);background-image:linear-gradient(to top, #ccc 0%, #eee 60%)}html[dir="rtl"] .select2-container .select2-choice .select2-arrow{left:0;right:auto;border-left:none;border-right:1px solid #aaa;border-radius:4px 0 0 4px}.select2-container .select2-choice .select2-arrow b{display:block;width:100%;height:100%;background:url(/assets/select2-d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8.png) no-repeat 0 1px}html[dir="rtl"] .select2-container .select2-choice .select2-arrow b{background-position:2px 1px}.select2-search{display:inline-block;width:100%;min-height:26px;margin:0;padding:4px 4px 0 4px;position:relative;z-index:10000;white-space:nowrap}.select2-search input{width:100%;height:auto !important;min-height:26px;padding:4px 20px 4px 5px;margin:0;outline:0;font-family:sans-serif;font-size:1em;border:1px solid #aaa;border-radius:0;-webkit-box-shadow:none;box-shadow:none;background:#fff url(/assets/select2-d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8.png) no-repeat 100% -22px;background:url(/assets/select2-d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8.png) no-repeat 100% -22px,-webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));background:url(/assets/select2-d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8.png) no-repeat 100% -22px,-webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);background:url(/assets/select2-d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8.png) no-repeat 100% -22px,-moz-linear-gradient(center bottom, #fff 85%, #eee 99%);background:url(/assets/select2-d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8.png) no-repeat 100% -22px,linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0}html[dir="rtl"] .select2-search input{padding:4px 5px 4px 20px;background:#fff url(/assets/select2-d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8.png) no-repeat -37px -22px;background:url(/assets/select2-d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8.png) no-repeat -37px -22px,-webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));background:url(/assets/select2-d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8.png) no-repeat -37px -22px,-webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);background:url(/assets/select2-d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8.png) no-repeat -37px -22px,-moz-linear-gradient(center bottom, #fff 85%, #eee 99%);background:url(/assets/select2-d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8.png) no-repeat -37px -22px,linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0}.select2-search input.select2-active{background:#fff url(/assets/select2-spinner-f6ecff617ec2ba7f559e6f535cad9b70a3f91120737535dab4d4548a6c83576c.gif) no-repeat 100%;background:url(/assets/select2-spinner-f6ecff617ec2ba7f559e6f535cad9b70a3f91120737535dab4d4548a6c83576c.gif) no-repeat 100%,-webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));background:url(/assets/select2-spinner-f6ecff617ec2ba7f559e6f535cad9b70a3f91120737535dab4d4548a6c83576c.gif) no-repeat 100%,-webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);background:url(/assets/select2-spinner-f6ecff617ec2ba7f559e6f535cad9b70a3f91120737535dab4d4548a6c83576c.gif) no-repeat 100%,-moz-linear-gradient(center bottom, #fff 85%, #eee 99%);background:url(/assets/select2-spinner-f6ecff617ec2ba7f559e6f535cad9b70a3f91120737535dab4d4548a6c83576c.gif) no-repeat 100%,linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0}.select2-container-active .select2-choice,.select2-container-active .select2-choices{border:1px solid #5897fb;outline:none;-webkit-box-shadow:0 0 5px rgba(0,0,0,0.3);box-shadow:0 0 5px rgba(0,0,0,0.3)}.select2-dropdown-open .select2-choice{border-bottom-color:transparent;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;border-bottom-left-radius:0;border-bottom-right-radius:0;background-color:#eee;background-image:-webkit-gradient(linear, left bottom, left top, color-stop(0, #fff), color-stop(0.5, #eee));background-image:-webkit-linear-gradient(center bottom, #fff 0%, #eee 50%);background-image:-moz-linear-gradient(center bottom, #fff 0%, #eee 50%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);background-image:linear-gradient(to top, #fff 0%, #eee 50%)}.select2-dropdown-open.select2-drop-above .select2-choice,.select2-dropdown-open.select2-drop-above .select2-choices{border:1px solid #5897fb;border-top-color:transparent;background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), color-stop(0.5, #eee));background-image:-webkit-linear-gradient(center top, #fff 0%, #eee 50%);background-image:-moz-linear-gradient(center top, #fff 0%, #eee 50%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%)}.select2-dropdown-open .select2-choice .select2-arrow{background:transparent;border-left:none;filter:none}html[dir="rtl"] .select2-dropdown-open .select2-choice .select2-arrow{border-right:none}.select2-dropdown-open .select2-choice .select2-arrow b{background-position:-18px 1px}html[dir="rtl"] .select2-dropdown-open .select2-choice .select2-arrow b{background-position:-16px 1px}.select2-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.select2-results{max-height:200px;padding:0 0 0 4px;margin:4px 4px 4px 0;position:relative;overflow-x:hidden;overflow-y:auto;-webkit-tap-highlight-color:transparent}html[dir="rtl"] .select2-results{padding:0 4px 0 0;margin:4px 0 4px 4px}.select2-results ul.select2-result-sub{margin:0;padding-left:0}.select2-results li{list-style:none;display:list-item;background-image:none}.select2-results li.select2-result-with-children>.select2-result-label{font-weight:bold}.select2-results .select2-result-label{padding:3px 7px 4px;margin:0;cursor:pointer;min-height:1em;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.select2-results-dept-1 .select2-result-label{padding-left:20px}.select2-results-dept-2 .select2-result-label{padding-left:40px}.select2-results-dept-3 .select2-result-label{padding-left:60px}.select2-results-dept-4 .select2-result-label{padding-left:80px}.select2-results-dept-5 .select2-result-label{padding-left:100px}.select2-results-dept-6 .select2-result-label{padding-left:110px}.select2-results-dept-7 .select2-result-label{padding-left:120px}.select2-results .select2-highlighted{background:#3875d7;color:#fff}.select2-results li em{background:#feffde;font-style:normal}.select2-results .select2-highlighted em{background:transparent}.select2-results .select2-highlighted ul{background:#fff;color:#000}.select2-results .select2-no-results,.select2-results .select2-searching,.select2-results .select2-ajax-error,.select2-results .select2-selection-limit{background:#f4f4f4;display:list-item;padding-left:5px}.select2-results .select2-disabled.select2-highlighted{color:#666;background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-disabled{background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-selected{display:none}.select2-more-results.select2-active{background:#f4f4f4 url(/assets/select2-spinner-f6ecff617ec2ba7f559e6f535cad9b70a3f91120737535dab4d4548a6c83576c.gif) no-repeat 100%}.select2-results .select2-ajax-error{background:rgba(255,50,50,0.2)}.select2-more-results{background:#f4f4f4;display:list-item}.select2-container.select2-container-disabled .select2-choice{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container.select2-container-disabled .select2-choice .select2-arrow{background-color:#f4f4f4;background-image:none;border-left:0}.select2-container.select2-container-disabled .select2-choice abbr{display:none}.select2-container-multi .select2-choices{height:auto !important;height:1%;margin:0;padding:0 5px 0 0;position:relative;border:1px solid #aaa;cursor:text;overflow:hidden;background-color:#fff;background-image:-webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eee), color-stop(15%, #fff));background-image:-webkit-linear-gradient(top, #eee 1%, #fff 15%);background-image:-moz-linear-gradient(top, #eee 1%, #fff 15%);background-image:linear-gradient(to bottom, #eee 1%, #fff 15%)}html[dir="rtl"] .select2-container-multi .select2-choices{padding:0 0 0 5px}.select2-locked{padding:3px 5px 3px 5px !important}.select2-container-multi .select2-choices{min-height:26px}.select2-container-multi.select2-container-active .select2-choices{border:1px solid #5897fb;outline:none;-webkit-box-shadow:0 0 5px rgba(0,0,0,0.3);box-shadow:0 0 5px rgba(0,0,0,0.3)}.select2-container-multi .select2-choices li{float:left;list-style:none}html[dir="rtl"] .select2-container-multi .select2-choices li{float:right}.select2-container-multi .select2-choices .select2-search-field{margin:0;padding:0;white-space:nowrap}.select2-container-multi .select2-choices .select2-search-field input{padding:5px;margin:1px 0;font-family:sans-serif;font-size:100%;color:#666;outline:0;border:0;-webkit-box-shadow:none;box-shadow:none;background:transparent !important}.select2-container-multi .select2-choices .select2-search-field input.select2-active{background:#fff url(/assets/select2-spinner-f6ecff617ec2ba7f559e6f535cad9b70a3f91120737535dab4d4548a6c83576c.gif) no-repeat 100% !important}.select2-default{color:#999 !important}.select2-container-multi .select2-choices .select2-search-choice{padding:3px 5px 3px 18px;margin:3px 0 3px 5px;position:relative;line-height:13px;color:#333;cursor:default;border:1px solid #aaaaaa;border-radius:3px;-webkit-box-shadow:0 0 2px #fff inset,0 1px 0 rgba(0,0,0,0.05);box-shadow:0 0 2px #fff inset,0 1px 0 rgba(0,0,0,0.05);background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#e4e4e4;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#f4f4f4', GradientType=0);background-image:-webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eee));background-image:-webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);background-image:-moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);background-image:linear-gradient(to bottom, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%)}html[dir="rtl"] .select2-container-multi .select2-choices .select2-search-choice{margin:3px 5px 3px 0;padding:3px 18px 3px 5px}.select2-container-multi .select2-choices .select2-search-choice .select2-chosen{cursor:default}.select2-container-multi .select2-choices .select2-search-choice-focus{background:#d4d4d4}.select2-search-choice-close{display:block;width:12px;height:13px;position:absolute;right:3px;top:4px;font-size:1px;outline:none;background:url(/assets/select2-d6b5d8d83dbc18fb8d77c8761d331cd9e5123c9684950bab0406e98a24ac5ae8.png) right top no-repeat}html[dir="rtl"] .select2-search-choice-close{right:auto;left:3px}.select2-container-multi .select2-search-choice-close{left:3px}html[dir="rtl"] .select2-container-multi .select2-search-choice-close{left:auto;right:2px}.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover{background-position:right -11px}.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close{background-position:right -11px}.select2-container-multi.select2-container-disabled .select2-choices{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice{padding:3px 5px 3px 5px;border:1px solid #ddd;background-image:none;background-color:#f4f4f4}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close{display:none;background:none}.select2-result-selectable .select2-match,.select2-result-unselectable .select2-match{text-decoration:underline}.select2-offscreen,.select2-offscreen:focus{clip:rect(0 0 0 0) !important;width:1px !important;height:1px !important;border:0 !important;margin:0 !important;padding:0 !important;overflow:hidden !important;position:absolute !important;outline:0 !important;left:0px !important;top:0px !important}.select2-display-none{display:none}.select2-measure-scrollbar{position:absolute;top:-10000px;left:-10000px;width:100px;height:100px;overflow:scroll}@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 2dppx){.select2-search input,.select2-search-choice-close,.select2-container .select2-choice abbr,.select2-container .select2-choice .select2-arrow b{background-image:url(/assets/select2x2-6fe28d687dc0ed4d96016238c608ba1e7198c9c9accfa0b360b78018b9fb9bc2.png) !important;background-repeat:no-repeat !important;background-size:60px 40px !important}.select2-search input{background-position:100% -21px !important}}body.agendadescommuns{font-family:georgia, serif}body.agendadescommuns header.top{padding-left:120px;padding-right:120px;background-image:url(agendadescommuns.png);background-repeat:no-repeat;background-position:20px top}body.agendadescommuns header.top img.logo{display:none}body.agendadescommuns ul.countries,body.agendadescommuns form#orga_search,body.agendadescommuns a#banner{display:none}body.agendadescommuns .city{text-transform:uppercase}body.agendadescommuns.events.index table tr .day_number{color:#727070}body.agendadescommuns.events.index table tr td.current-month.past,body.agendadescommuns.events.index table tr td.current-month.past .day_number{color:#FFFAEB;background-color:#7494B5}body.agendadescommuns.events.index table tr td.current-month.today{border-color:#FFFAEB;background-color:#DBEDFF}body.agendadescommuns.events.index table tr td.current-month.future{color:#444;border-color:#EAE4D3;background-color:#F0E8D1}/*! + * Font Awesome 4.6.2 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url("/assets/font-awesome/fontawesome-webfont-a280856e20cc0af53390b729ca0ac3edbf8fc889a828a379c5d634c91e80c808.eot?v=4.6.2");src:url("/assets/font-awesome/fontawesome-webfont-a280856e20cc0af53390b729ca0ac3edbf8fc889a828a379c5d634c91e80c808.eot?v=4.6.2#iefix") format("embedded-opentype"),url("/assets/font-awesome/fontawesome-webfont-2932abf996373e87fbf2e950876b1962f1b57db954a1643ea68831d9fbb74da4.woff2?v=4.6.2") format("woff2"),url("/assets/font-awesome/fontawesome-webfont-35fa8302dd7d3d191ebb7acac543efcfa2b85a0da573b3ab45cc122ffcc45ce5.woff?v=4.6.2") format("woff"),url("/assets/font-awesome/fontawesome-webfont-8630313bee77f64206067ed80eb6a7c721b0bbfc91c94210966969d4dcc43ba7.ttf?v=4.6.2") format("truetype"),url("/assets/font-awesome/fontawesome-webfont-6b0adce775f4d57ac800f23b05af72ced748ae51ba67a65b67b7316f1ed331b3.svg?v=4.6.2#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:0.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:0.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:"ï€"}.fa-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-remove:before,.fa-close:before,.fa-times:before{content:"ï€"}.fa-search-plus:before{content:""}.fa-search-minus:before{content:"ï€"}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:"ï€"}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before{content:"ï€"}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:"ï€"}.fa-map-marker:before{content:"ï"}.fa-adjust:before{content:"ï‚"}.fa-tint:before{content:"ïƒ"}.fa-edit:before,.fa-pencil-square-o:before{content:"ï„"}.fa-share-square-o:before{content:"ï…"}.fa-check-square-o:before{content:"ï†"}.fa-arrows:before{content:"ï‡"}.fa-step-backward:before{content:"ïˆ"}.fa-fast-backward:before{content:"ï‰"}.fa-backward:before{content:"ïŠ"}.fa-play:before{content:"ï‹"}.fa-pause:before{content:"ïŒ"}.fa-stop:before{content:"ï"}.fa-forward:before{content:"ïŽ"}.fa-fast-forward:before{content:"ï"}.fa-step-forward:before{content:"ï‘"}.fa-eject:before{content:"ï’"}.fa-chevron-left:before{content:"ï“"}.fa-chevron-right:before{content:"ï”"}.fa-plus-circle:before{content:"ï•"}.fa-minus-circle:before{content:"ï–"}.fa-times-circle:before{content:"ï—"}.fa-check-circle:before{content:"ï˜"}.fa-question-circle:before{content:"ï™"}.fa-info-circle:before{content:"ïš"}.fa-crosshairs:before{content:"ï›"}.fa-times-circle-o:before{content:"ïœ"}.fa-check-circle-o:before{content:"ï"}.fa-ban:before{content:"ïž"}.fa-arrow-left:before{content:"ï "}.fa-arrow-right:before{content:"ï¡"}.fa-arrow-up:before{content:"ï¢"}.fa-arrow-down:before{content:"ï£"}.fa-mail-forward:before,.fa-share:before{content:"ï¤"}.fa-expand:before{content:"ï¥"}.fa-compress:before{content:"ï¦"}.fa-plus:before{content:"ï§"}.fa-minus:before{content:"ï¨"}.fa-asterisk:before{content:"ï©"}.fa-exclamation-circle:before{content:"ïª"}.fa-gift:before{content:"ï«"}.fa-leaf:before{content:"ï¬"}.fa-fire:before{content:"ï"}.fa-eye:before{content:"ï®"}.fa-eye-slash:before{content:"ï°"}.fa-warning:before,.fa-exclamation-triangle:before{content:"ï±"}.fa-plane:before{content:"ï²"}.fa-calendar:before{content:"ï³"}.fa-random:before{content:"ï´"}.fa-comment:before{content:"ïµ"}.fa-magnet:before{content:"ï¶"}.fa-chevron-up:before{content:"ï·"}.fa-chevron-down:before{content:"ï¸"}.fa-retweet:before{content:"ï¹"}.fa-shopping-cart:before{content:"ïº"}.fa-folder:before{content:"ï»"}.fa-folder-open:before{content:"ï¼"}.fa-arrows-v:before{content:"ï½"}.fa-arrows-h:before{content:"ï¾"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"ï‚€"}.fa-twitter-square:before{content:"ï‚"}.fa-facebook-square:before{content:"ï‚‚"}.fa-camera-retro:before{content:""}.fa-key:before{content:"ï‚„"}.fa-gears:before,.fa-cogs:before{content:"ï‚…"}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:"ï‚Š"}.fa-sign-out:before{content:"ï‚‹"}.fa-linkedin-square:before{content:"ï‚Œ"}.fa-thumb-tack:before{content:"ï‚"}.fa-external-link:before{content:"ï‚Ž"}.fa-sign-in:before{content:"ï‚"}.fa-trophy:before{content:"ï‚‘"}.fa-github-square:before{content:"ï‚’"}.fa-upload:before{content:"ï‚“"}.fa-lemon-o:before{content:"ï‚”"}.fa-phone:before{content:"ï‚•"}.fa-square-o:before{content:"ï‚–"}.fa-bookmark-o:before{content:"ï‚—"}.fa-phone-square:before{content:""}.fa-twitter:before{content:"ï‚™"}.fa-facebook-f:before,.fa-facebook:before{content:"ï‚š"}.fa-github:before{content:"ï‚›"}.fa-unlock:before{content:"ï‚œ"}.fa-credit-card:before{content:"ï‚"}.fa-feed:before,.fa-rss:before{content:"ï‚ž"}.fa-hdd-o:before{content:"ï‚ "}.fa-bullhorn:before{content:"ï‚¡"}.fa-bell:before{content:""}.fa-certificate:before{content:"ï‚£"}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:"ï‚¥"}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before{content:""}.fa-arrow-circle-right:before{content:"ï‚©"}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:"ï‚«"}.fa-globe:before{content:""}.fa-wrench:before{content:"ï‚"}.fa-tasks:before{content:"ï‚®"}.fa-filter:before{content:"ï‚°"}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before{content:"ïƒ"}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:"ïƒ"}.fa-table:before{content:""}.fa-magic:before{content:"ïƒ"}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:"ïƒ"}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:"ïƒ "}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:"ïƒ"}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:"ï‚¢"}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:"ï„€"}.fa-angle-double-right:before{content:"ï„"}.fa-angle-double-up:before{content:"ï„‚"}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:"ï„„"}.fa-angle-right:before{content:"ï„…"}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:"ï„Š"}.fa-mobile-phone:before,.fa-mobile:before{content:"ï„‹"}.fa-circle-o:before{content:"ï„Œ"}.fa-quote-left:before{content:"ï„"}.fa-quote-right:before{content:"ï„Ž"}.fa-spinner:before{content:"ï„"}.fa-circle:before{content:"ï„‘"}.fa-mail-reply:before,.fa-reply:before{content:"ï„’"}.fa-github-alt:before{content:"ï„“"}.fa-folder-o:before{content:"ï„”"}.fa-folder-open-o:before{content:"ï„•"}.fa-smile-o:before{content:""}.fa-frown-o:before{content:"ï„™"}.fa-meh-o:before{content:"ï„š"}.fa-gamepad:before{content:"ï„›"}.fa-keyboard-o:before{content:"ï„œ"}.fa-flag-o:before{content:"ï„"}.fa-flag-checkered:before{content:"ï„ž"}.fa-terminal:before{content:"ï„ "}.fa-code:before{content:"ï„¡"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"ï„¢"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"ï„£"}.fa-location-arrow:before{content:""}.fa-crop:before{content:"ï„¥"}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:"ï„©"}.fa-exclamation:before{content:""}.fa-superscript:before{content:"ï„«"}.fa-subscript:before{content:""}.fa-eraser:before{content:"ï„"}.fa-puzzle-piece:before{content:"ï„®"}.fa-microphone:before{content:"ï„°"}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:"ï„´"}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:"ï„·"}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:"ï„»"}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:"ï…€"}.fa-ellipsis-h:before{content:"ï…"}.fa-ellipsis-v:before{content:"ï…‚"}.fa-rss-square:before{content:"ï…ƒ"}.fa-play-circle:before{content:"ï…„"}.fa-ticket:before{content:"ï……"}.fa-minus-square:before{content:"ï…†"}.fa-minus-square-o:before{content:"ï…‡"}.fa-level-up:before{content:"ï…ˆ"}.fa-level-down:before{content:"ï…‰"}.fa-check-square:before{content:"ï…Š"}.fa-pencil-square:before{content:"ï…‹"}.fa-external-link-square:before{content:"ï…Œ"}.fa-share-square:before{content:"ï…"}.fa-compass:before{content:"ï…Ž"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"ï…"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"ï…‘"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"ï…’"}.fa-euro:before,.fa-eur:before{content:"ï…“"}.fa-gbp:before{content:"ï…”"}.fa-dollar:before,.fa-usd:before{content:"ï…•"}.fa-rupee:before,.fa-inr:before{content:"ï…–"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"ï…—"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"ï…˜"}.fa-won:before,.fa-krw:before{content:"ï…™"}.fa-bitcoin:before,.fa-btc:before{content:"ï…š"}.fa-file:before{content:"ï…›"}.fa-file-text:before{content:"ï…œ"}.fa-sort-alpha-asc:before{content:"ï…"}.fa-sort-alpha-desc:before{content:"ï…ž"}.fa-sort-amount-asc:before{content:"ï… "}.fa-sort-amount-desc:before{content:"ï…¡"}.fa-sort-numeric-asc:before{content:"ï…¢"}.fa-sort-numeric-desc:before{content:"ï…£"}.fa-thumbs-up:before{content:"ï…¤"}.fa-thumbs-down:before{content:"ï…¥"}.fa-youtube-square:before{content:"ï…¦"}.fa-youtube:before{content:"ï…§"}.fa-xing:before{content:"ï…¨"}.fa-xing-square:before{content:"ï…©"}.fa-youtube-play:before{content:"ï…ª"}.fa-dropbox:before{content:"ï…«"}.fa-stack-overflow:before{content:"ï…¬"}.fa-instagram:before{content:"ï…"}.fa-flickr:before{content:"ï…®"}.fa-adn:before{content:"ï…°"}.fa-bitbucket:before{content:"ï…±"}.fa-bitbucket-square:before{content:"ï…²"}.fa-tumblr:before{content:"ï…³"}.fa-tumblr-square:before{content:"ï…´"}.fa-long-arrow-down:before{content:"ï…µ"}.fa-long-arrow-up:before{content:"ï…¶"}.fa-long-arrow-left:before{content:"ï…·"}.fa-long-arrow-right:before{content:"ï…¸"}.fa-apple:before{content:"ï…¹"}.fa-windows:before{content:"ï…º"}.fa-android:before{content:"ï…»"}.fa-linux:before{content:"ï…¼"}.fa-dribbble:before{content:"ï…½"}.fa-skype:before{content:"ï…¾"}.fa-foursquare:before{content:""}.fa-trello:before{content:"ï†"}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:"ï†"}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:"ï†"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:"ï†"}.fa-yahoo:before{content:""}.fa-google:before{content:"ï† "}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:"ï†"}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:"ï‡"}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"ï‡"}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"ï‡"}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:"ï‡"}.fa-sliders:before{content:""}.fa-share-alt:before{content:"ï‡ "}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:"ï‡"}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:"ïˆ"}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:"ïˆ"}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:"ïˆ"}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:"ïˆ"}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:"ïˆ"}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-hotel:before,.fa-bed:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-yc:before,.fa-y-combinator:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"ï‰"}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:"ï‰"}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:"ï‰"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:"ï‰"}.fa-creative-commons:before{content:""}.fa-gg:before{content:"ï‰ "}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-tv:before,.fa-television:before{content:""}.fa-contao:before{content:"ï‰"}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:"ïŠ"}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:"ïŠ"}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:"ïŠ"}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:"ïŠ"}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:"ïŠ "}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:""}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-signing:before,.fa-sign-language:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:"ïŠ"}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.awesome-marker{background:url(/assets/markers-soft-e78784e4ed70aaffddd73c315fab590233cc4e7b72388d7dd47a14796fc7c739.png) no-repeat 0 0;width:35px;height:46px;position:absolute;left:0;top:0;display:block;text-align:center}.awesome-marker-shadow{background:url(/assets/markers-shadow-8703a2262710f5e3d29e65d2acdf90d6512e159e119d27b8234731d8a6208a20.png) no-repeat 0 0;width:36px;height:16px}@media (min--moz-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5), (min-resolution: 1.5dppx){.awesome-marker{background-image:url(/assets/markers-soft@2x-c1e77253a8bfbe30cec24885d7046f443b76ebb66f4c961f77083b03f4a5cbaf.png);background-size:720px 46px}.awesome-marker-shadow{background-image:url(/assets/markers-shadow@2x-b21a536be27313fb504f69f5899ff0b1245b276571769ac08d6c32c35676e47a.png);background-size:35px 16px}}.awesome-marker i{color:#333;margin-top:10px;display:inline-block;font-size:14px}.awesome-marker .icon-white{color:#fff}.awesome-marker-icon-red{background-position:0 0}.awesome-marker-icon-darkred{background-position:-180px 0}.awesome-marker-icon-lightred{background-position:-360px 0}.awesome-marker-icon-orange{background-position:-36px 0}.awesome-marker-icon-beige{background-position:-396px 0}.awesome-marker-icon-green{background-position:-72px 0}.awesome-marker-icon-darkgreen{background-position:-252px 0}.awesome-marker-icon-lightgreen{background-position:-432px 0}.awesome-marker-icon-blue{background-position:-108px 0}.awesome-marker-icon-darkblue{background-position:-216px 0}.awesome-marker-icon-lightblue{background-position:-468px 0}.awesome-marker-icon-purple{background-position:-144px 0}.awesome-marker-icon-darkpurple{background-position:-288px 0}.awesome-marker-icon-pink{background-position:-504px 0}.awesome-marker-icon-cadetblue{background-position:-324px 0}.awesome-marker-icon-white{background-position:-574px 0}.awesome-marker-icon-gray{background-position:-648px 0}.awesome-marker-icon-lightgray{background-position:-612px 0}.awesome-marker-icon-black{background-position:-682px 0}*{height:auto;padding:0;max-width:100%;margin-left:auto;margin-right:auto;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}html{color:black;height:100%;text-align:center;font-family:Palatino, "URW Palladio L", "dejavu serif", georgia, serif;background-color:#9CC5EE}html.iframe{background-color:transparent}html.iframe body{border:none;margin:0;padding:0;background-color:transparent}html.iframe body>header,html.iframe body>footer,html.iframe body h2,html.iframe body nav,html.iframe body .region_selector,html.iframe body .orga_search,html.iframe body .formats,html.iframe body #banner{display:none}html.iframe body ul{margin:0}body{border:1px solid #68A6E5;margin:0.3em;padding:10px;padding-top:0;background-color:white}body header *,body main *,body footer *{-moz-transition-duration:0.5s;-o-transition-duration:0.5s;-webkit-transition-duration:0.5s;transition-duration:0.5s}a{color:#258}a:visited{color:#258}a:focus{color:#2E97FF}a:hover{color:#2E97FF}a:active{color:#2E97FF}a:link,a:visited{text-decoration:none}#flash_messages .flash{color:white;border:solid 1px #007ba0;margin:1em auto;padding:0.5em 1.1em;max-width:50em;font-size:x-large;text-align:justify;background-color:#008cba;-moz-box-shadow:0 0 0.3em gray;-webkit-box-shadow:0 0 0.3em gray;box-shadow:0 0 0.3em gray;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}#flash_messages .flash.notice{border-color:#3a945b;background-color:#43ac6a}#flash_messages .flash.alert{border-color:#de2b0f;background-color:#f04124}h3.warning{color:white;margin:0;padding:1em;text-align:center;background-color:orange;-moz-box-shadow:0 0 0.3em gray;-webkit-box-shadow:0 0 0.3em gray;box-shadow:0 0 0.3em gray;display:inline-block;vertical-align:middle;*vertical-align:auto;*zoom:1;*display:inline;-moz-border-radius:1em;-webkit-border-radius:1em;border-radius:1em}header.top img.logo{float:left;margin-left:20px}header.top ul.countries{float:right;font-size:smaller;margin-top:0.2em;line-height:1em;margin-left:2em;margin-right:1em;list-style-type:none}header.top ul.countries li{text-align:left}header.top ul.countries li a:before{margin-right:0.75em}header.top ul.countries li.map_france a:before{content:url(/assets/france-f4341a7ec8331161a9c8d5298f808014c3fc9c799b5a29ed95eb56a7f3ccd0df.png)}header.top ul.countries li.map_quebec a:before{content:url(/assets/quebec-776d563b6a4ac4312cae9f0bfe630c20711346e8dbddd41040998eba79f4b588.png)}header.top ul.countries li.map_belgique a:before{content:url(/assets/belgique-3b8b772a522de2cbae7714b35a956faf2c394419b532a14bba982fed3f341091.png)}header.top ul.countries li.map_suisse a:before{content:url(/assets/suisse-58d067f1c3fcdc4000fa13e95896cd5369a2b91aafd314475aa5e29da0b543d1.png)}header.top h1{margin:0.5em 0;font-size:2.1em}header.top h2{font-size:1.2em;font-style:italic;font-weight:normal;margin-top:-0.8em}main,body.mce-content-body{position:relative}main>*,body.mce-content-body>*{max-width:80em}main h1,body.mce-content-body h1{margin:10px auto 5px auto;letter-spacing:2px}main h3,body.mce-content-body h3{text-align:left}main ul,main ol,body.mce-content-body ul,body.mce-content-body ol{text-align:left;padding-left:1em;list-style-position:inside}main p,body.mce-content-body p{text-align:justify}main p.label,body.mce-content-body p.label{text-align:center}main p span.label:after,body.mce-content-body p span.label:after{content:":"}main hr,body.mce-content-body hr{margin:10px 20px}main.mce-content-body,body.mce-content-body.mce-content-body{margin:0;border:solid thin transparent;font-size:initial;min-height:100%;font-family:Palatino, "URW Palladio L", "dejavu serif", georgia, serif}aside{float:right;width:16em;border:1px solid #96CFFF;margin:0 1.2em;padding:5px;font-size:0.7em;margin-right:-4em;background-color:#D6ECFF;-moz-box-shadow:4px 4px 1em gray;-webkit-box-shadow:4px 4px 1em gray;box-shadow:4px 4px 1em gray;-moz-border-radius:10px;-webkit-border-radius:10px;border-radius:10px}aside h1{font-weight:normal;border-bottom:1px black solid;padding-bottom:0.3em}aside h2{margin:0;font-size:larger}aside h2 a{padding:0.5em 0;display:block}iframe{border:none;max-width:100%;margin-bottom:1.6em;-moz-border-radius:1em;-webkit-border-radius:1em;border-radius:1em}fieldset{border:none;margin:1em auto;padding:1em;-moz-box-shadow:1px 1px 5px gray;-webkit-box-shadow:1px 1px 5px gray;box-shadow:1px 1px 5px gray;-moz-border-radius:0.4em;-webkit-border-radius:0.4em;border-radius:0.4em}fieldset legend{float:left;color:gray;padding:0 1em;margin-top:-1.6em;background-color:white}fieldset h2{margin-top:0}label{text-align:right;padding-right:0.4em}.mce-tinymce{border:1px solid darkgray;-moz-box-shadow:1px 1px 2px lightgray;-webkit-box-shadow:1px 1px 2px lightgray;box-shadow:1px 1px 2px lightgray;-moz-border-radius:0.4em;-webkit-border-radius:0.4em;border-radius:0.4em}input,textarea,select,a.button,button,.select2-container ul{color:black;margin:3px 0;border:1px solid darkgray;outline:none;padding:0.2em 0.4em;font-size:inherit;font-family:inherit;background-color:white;-moz-box-shadow:1px 1px 2px lightgray;-webkit-box-shadow:1px 1px 2px lightgray;box-shadow:1px 1px 2px lightgray;-moz-border-radius:0.4em;-webkit-border-radius:0.4em;border-radius:0.4em}input:focus,textarea:focus,select:focus,a.button:focus,button:focus,.select2-container ul:focus{background-color:#F0F8FF;-moz-box-shadow:1px 1px 4px gray;-webkit-box-shadow:1px 1px 4px gray;box-shadow:1px 1px 4px gray}input[type=radio],textarea[type=radio],select[type=radio],a.button[type=radio],button[type=radio],.select2-container ul[type=radio]{-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}input[type=radio]+label,textarea[type=radio]+label,select[type=radio]+label,a.button[type=radio]+label,button[type=radio]+label,.select2-container ul[type=radio]+label{text-align:left}input[type=submit],input.button,input button,textarea[type=submit],textarea.button,textarea button,select[type=submit],select.button,select button,a.button[type=submit],a.button.button,a.button button,button[type=submit],button.button,button button,.select2-container ul[type=submit],.select2-container ul.button,.select2-container ul button{color:black;border:none;cursor:pointer;margin:3px 0.4em;padding:0.2em 0.6em;font-size:larger;font-weight:bolder;background-color:#9CC5EE;-moz-box-shadow:2px 2px 2px gray;-webkit-box-shadow:2px 2px 2px gray;box-shadow:2px 2px 2px gray}select,option{color:black;padding:2px 4px;background-color:white}button.ws-popover-opener{color:darkgray;background-color:transparent}.field_with_errors{display:inline}.field_with_errors input,.field_with_errors textarea,.field_with_errors select,.field_with_errors a.button{background-color:pink}footer.bottom nav{clear:both}footer.bottom nav a{padding:1.8%;font-weight:bolder;display:inline-block;vertical-align:middle;*vertical-align:auto;*zoom:1;*display:inline}footer.bottom nav a em.fa{font-size:x-large}footer.bottom nav a:hover{text-shadow:0 0 1em lightgray}#loading{top:45%;left:45%;color:gray;display:none;position:fixed;font-size:10vw;vertical-align:baseline;text-shadow:0 0 4px gray}.pagination span{display:none}.pagination span.next{display:block}.select2-container ul{min-width:46em}.select2-container-multi.select2-container-active .select2-choices,.select2-drop{border:none !important;-moz-box-shadow:1px 1px 4px gray;-webkit-box-shadow:1px 1px 4px gray;box-shadow:1px 1px 4px gray}.select2-container *,.select2-choices *{margin:initial;-moz-transition-duration:0;-o-transition-duration:0;-webkit-transition-duration:0;transition-duration:0}body.digests main{padding:1em;max-width:60em;-moz-box-shadow:1px 1px 5px gray;-webkit-box-shadow:1px 1px 5px gray;box-shadow:1px 1px 5px gray;-moz-border-radius:0.4em;-webkit-border-radius:0.4em;border-radius:0.4em}body.digests main h2{margin:0;padding:0;font-size:larger;text-align:left}body.digests main .description p,body.digests main .second_part p{white-space:pre-line}body.digests main textarea{width:40em;height:20em}header.calendar-header{font-size:1.5em;margin-top:0.4em;font-weight:bolder}header.calendar-header a{font-weight:normal}header.calendar-header a:first-child,header.calendar-header a:last-child{margin:0 0.3em}em.locality.fa{color:gray}span.city:after,strong.city:after,em.city:after{content:":"}p.full_address span:after{content:","}p.full_address span:last-child:after{content:""}.calendar-header,.month{text-transform:capitalize}body.events.index table{width:90%;max-width:100%;table-layout:fixed}body.events.index table tr th{padding-bottom:0.35em;text-transform:capitalize}body.events.index table tr td{width:14%;height:4.8em;border:1px solid #89B7E5;padding:1px;position:relative;vertical-align:top;background-color:#A1C3E7}body.events.index table tr td.past .event{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}body.events.index table tr td.today{border:1px solid #FFB578;background-color:#FFE0C7}body.events.index table tr td.today .day_number{color:#531}body.events.index table tr td.today .event a:link,body.events.index table tr td.today .event a:visited{color:#730}body.events.index table tr td.future{border-color:#96cfff;background-color:#C6E5FF}body.events.index table tr td.prev-month,body.events.index table tr td.next-month{border:none;background-color:#ededed}body.events.index table tr td.prev-month li,body.events.index table tr td.next-month li{color:#555}body.events.index table tr td.prev-month .event a:link,body.events.index table tr td.prev-month .event a:visited,body.events.index table tr td.next-month .event a:link,body.events.index table tr td.next-month .event a:visited{color:#444}body.events.index table tr td .day_number{float:left;color:#111;font-size:0.6em;font-weight:bolder;line-height:1.2em;letter-spacing:2px}body.events.index table tr td:hover .day_number{color:black}body.events.index table tr td ul{clear:left;margin:0;padding:0}body.events.index table tr td ul li{color:#444;margin:0;padding:0}body.events.index table tr td ul li em.fa.fa-globe{color:red;font-size:smaller}body.events.index table tr td ul .event{padding-left:0.2em}body.events.index table tr td ul .event img{vertical-align:middle}body.events.index table tr td ul .event a:link,body.events.index table tr td ul .event a:visited{color:#111;font-size:smaller}body.events.index table tr td ul .event a:link:hover,body.events.index table tr td ul .event a:visited:hover{color:black;font-weight:bolder}.formats{float:right;font-size:smaller;margin-right:5%;padding-right:2px}a#banner{float:left;margin-left:5%;padding-left:2px}body.events.show main,body.orgas.show main{padding:1em;max-width:60em;-moz-box-shadow:1px 1px 5px gray;-webkit-box-shadow:1px 1px 5px gray;box-shadow:1px 1px 5px gray;-moz-border-radius:0.4em;-webkit-border-radius:0.4em;border-radius:0.4em}body.events.show main h2,body.orgas.show main h2{margin-top:1em}#advises{border:1px solid #FFB578;padding-left:10px;padding-right:10px;margin-bottom:1.2em;background-color:#ffe0c7}#advises h1{font-size:1.9em;font-weight:normal}#advises a{color:#8F4900}.description img,body.mce-content-body img{margin-left:1%;margin-right:1%}/*! + * Font Awesome 4.6.2 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url("/assets/font-awesome/fontawesome-webfont-a280856e20cc0af53390b729ca0ac3edbf8fc889a828a379c5d634c91e80c808.eot?v=4.6.2");src:url("/assets/font-awesome/fontawesome-webfont-a280856e20cc0af53390b729ca0ac3edbf8fc889a828a379c5d634c91e80c808.eot?v=4.6.2#iefix") format("embedded-opentype"),url("/assets/font-awesome/fontawesome-webfont-2932abf996373e87fbf2e950876b1962f1b57db954a1643ea68831d9fbb74da4.woff2?v=4.6.2") format("woff2"),url("/assets/font-awesome/fontawesome-webfont-35fa8302dd7d3d191ebb7acac543efcfa2b85a0da573b3ab45cc122ffcc45ce5.woff?v=4.6.2") format("woff"),url("/assets/font-awesome/fontawesome-webfont-8630313bee77f64206067ed80eb6a7c721b0bbfc91c94210966969d4dcc43ba7.ttf?v=4.6.2") format("truetype"),url("/assets/font-awesome/fontawesome-webfont-6b0adce775f4d57ac800f23b05af72ced748ae51ba67a65b67b7316f1ed331b3.svg?v=4.6.2#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:0.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:0.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:"ï€"}.fa-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-remove:before,.fa-close:before,.fa-times:before{content:"ï€"}.fa-search-plus:before{content:""}.fa-search-minus:before{content:"ï€"}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:"ï€"}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before{content:"ï€"}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:"ï€"}.fa-map-marker:before{content:"ï"}.fa-adjust:before{content:"ï‚"}.fa-tint:before{content:"ïƒ"}.fa-edit:before,.fa-pencil-square-o:before{content:"ï„"}.fa-share-square-o:before{content:"ï…"}.fa-check-square-o:before{content:"ï†"}.fa-arrows:before{content:"ï‡"}.fa-step-backward:before{content:"ïˆ"}.fa-fast-backward:before{content:"ï‰"}.fa-backward:before{content:"ïŠ"}.fa-play:before{content:"ï‹"}.fa-pause:before{content:"ïŒ"}.fa-stop:before{content:"ï"}.fa-forward:before{content:"ïŽ"}.fa-fast-forward:before{content:"ï"}.fa-step-forward:before{content:"ï‘"}.fa-eject:before{content:"ï’"}.fa-chevron-left:before{content:"ï“"}.fa-chevron-right:before{content:"ï”"}.fa-plus-circle:before{content:"ï•"}.fa-minus-circle:before{content:"ï–"}.fa-times-circle:before{content:"ï—"}.fa-check-circle:before{content:"ï˜"}.fa-question-circle:before{content:"ï™"}.fa-info-circle:before{content:"ïš"}.fa-crosshairs:before{content:"ï›"}.fa-times-circle-o:before{content:"ïœ"}.fa-check-circle-o:before{content:"ï"}.fa-ban:before{content:"ïž"}.fa-arrow-left:before{content:"ï "}.fa-arrow-right:before{content:"ï¡"}.fa-arrow-up:before{content:"ï¢"}.fa-arrow-down:before{content:"ï£"}.fa-mail-forward:before,.fa-share:before{content:"ï¤"}.fa-expand:before{content:"ï¥"}.fa-compress:before{content:"ï¦"}.fa-plus:before{content:"ï§"}.fa-minus:before{content:"ï¨"}.fa-asterisk:before{content:"ï©"}.fa-exclamation-circle:before{content:"ïª"}.fa-gift:before{content:"ï«"}.fa-leaf:before{content:"ï¬"}.fa-fire:before{content:"ï"}.fa-eye:before{content:"ï®"}.fa-eye-slash:before{content:"ï°"}.fa-warning:before,.fa-exclamation-triangle:before{content:"ï±"}.fa-plane:before{content:"ï²"}.fa-calendar:before{content:"ï³"}.fa-random:before{content:"ï´"}.fa-comment:before{content:"ïµ"}.fa-magnet:before{content:"ï¶"}.fa-chevron-up:before{content:"ï·"}.fa-chevron-down:before{content:"ï¸"}.fa-retweet:before{content:"ï¹"}.fa-shopping-cart:before{content:"ïº"}.fa-folder:before{content:"ï»"}.fa-folder-open:before{content:"ï¼"}.fa-arrows-v:before{content:"ï½"}.fa-arrows-h:before{content:"ï¾"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"ï‚€"}.fa-twitter-square:before{content:"ï‚"}.fa-facebook-square:before{content:"ï‚‚"}.fa-camera-retro:before{content:""}.fa-key:before{content:"ï‚„"}.fa-gears:before,.fa-cogs:before{content:"ï‚…"}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:"ï‚Š"}.fa-sign-out:before{content:"ï‚‹"}.fa-linkedin-square:before{content:"ï‚Œ"}.fa-thumb-tack:before{content:"ï‚"}.fa-external-link:before{content:"ï‚Ž"}.fa-sign-in:before{content:"ï‚"}.fa-trophy:before{content:"ï‚‘"}.fa-github-square:before{content:"ï‚’"}.fa-upload:before{content:"ï‚“"}.fa-lemon-o:before{content:"ï‚”"}.fa-phone:before{content:"ï‚•"}.fa-square-o:before{content:"ï‚–"}.fa-bookmark-o:before{content:"ï‚—"}.fa-phone-square:before{content:""}.fa-twitter:before{content:"ï‚™"}.fa-facebook-f:before,.fa-facebook:before{content:"ï‚š"}.fa-github:before{content:"ï‚›"}.fa-unlock:before{content:"ï‚œ"}.fa-credit-card:before{content:"ï‚"}.fa-feed:before,.fa-rss:before{content:"ï‚ž"}.fa-hdd-o:before{content:"ï‚ "}.fa-bullhorn:before{content:"ï‚¡"}.fa-bell:before{content:""}.fa-certificate:before{content:"ï‚£"}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:"ï‚¥"}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before{content:""}.fa-arrow-circle-right:before{content:"ï‚©"}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:"ï‚«"}.fa-globe:before{content:""}.fa-wrench:before{content:"ï‚"}.fa-tasks:before{content:"ï‚®"}.fa-filter:before{content:"ï‚°"}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before{content:"ïƒ"}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:"ïƒ"}.fa-table:before{content:""}.fa-magic:before{content:"ïƒ"}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:"ïƒ"}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:"ïƒ "}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:"ïƒ"}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:"ï‚¢"}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:"ï„€"}.fa-angle-double-right:before{content:"ï„"}.fa-angle-double-up:before{content:"ï„‚"}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:"ï„„"}.fa-angle-right:before{content:"ï„…"}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:"ï„Š"}.fa-mobile-phone:before,.fa-mobile:before{content:"ï„‹"}.fa-circle-o:before{content:"ï„Œ"}.fa-quote-left:before{content:"ï„"}.fa-quote-right:before{content:"ï„Ž"}.fa-spinner:before{content:"ï„"}.fa-circle:before{content:"ï„‘"}.fa-mail-reply:before,.fa-reply:before{content:"ï„’"}.fa-github-alt:before{content:"ï„“"}.fa-folder-o:before{content:"ï„”"}.fa-folder-open-o:before{content:"ï„•"}.fa-smile-o:before{content:""}.fa-frown-o:before{content:"ï„™"}.fa-meh-o:before{content:"ï„š"}.fa-gamepad:before{content:"ï„›"}.fa-keyboard-o:before{content:"ï„œ"}.fa-flag-o:before{content:"ï„"}.fa-flag-checkered:before{content:"ï„ž"}.fa-terminal:before{content:"ï„ "}.fa-code:before{content:"ï„¡"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"ï„¢"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"ï„£"}.fa-location-arrow:before{content:""}.fa-crop:before{content:"ï„¥"}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:"ï„©"}.fa-exclamation:before{content:""}.fa-superscript:before{content:"ï„«"}.fa-subscript:before{content:""}.fa-eraser:before{content:"ï„"}.fa-puzzle-piece:before{content:"ï„®"}.fa-microphone:before{content:"ï„°"}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:"ï„´"}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:"ï„·"}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:"ï„»"}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:"ï…€"}.fa-ellipsis-h:before{content:"ï…"}.fa-ellipsis-v:before{content:"ï…‚"}.fa-rss-square:before{content:"ï…ƒ"}.fa-play-circle:before{content:"ï…„"}.fa-ticket:before{content:"ï……"}.fa-minus-square:before{content:"ï…†"}.fa-minus-square-o:before{content:"ï…‡"}.fa-level-up:before{content:"ï…ˆ"}.fa-level-down:before{content:"ï…‰"}.fa-check-square:before{content:"ï…Š"}.fa-pencil-square:before{content:"ï…‹"}.fa-external-link-square:before{content:"ï…Œ"}.fa-share-square:before{content:"ï…"}.fa-compass:before{content:"ï…Ž"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"ï…"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"ï…‘"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"ï…’"}.fa-euro:before,.fa-eur:before{content:"ï…“"}.fa-gbp:before{content:"ï…”"}.fa-dollar:before,.fa-usd:before{content:"ï…•"}.fa-rupee:before,.fa-inr:before{content:"ï…–"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"ï…—"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"ï…˜"}.fa-won:before,.fa-krw:before{content:"ï…™"}.fa-bitcoin:before,.fa-btc:before{content:"ï…š"}.fa-file:before{content:"ï…›"}.fa-file-text:before{content:"ï…œ"}.fa-sort-alpha-asc:before{content:"ï…"}.fa-sort-alpha-desc:before{content:"ï…ž"}.fa-sort-amount-asc:before{content:"ï… "}.fa-sort-amount-desc:before{content:"ï…¡"}.fa-sort-numeric-asc:before{content:"ï…¢"}.fa-sort-numeric-desc:before{content:"ï…£"}.fa-thumbs-up:before{content:"ï…¤"}.fa-thumbs-down:before{content:"ï…¥"}.fa-youtube-square:before{content:"ï…¦"}.fa-youtube:before{content:"ï…§"}.fa-xing:before{content:"ï…¨"}.fa-xing-square:before{content:"ï…©"}.fa-youtube-play:before{content:"ï…ª"}.fa-dropbox:before{content:"ï…«"}.fa-stack-overflow:before{content:"ï…¬"}.fa-instagram:before{content:"ï…"}.fa-flickr:before{content:"ï…®"}.fa-adn:before{content:"ï…°"}.fa-bitbucket:before{content:"ï…±"}.fa-bitbucket-square:before{content:"ï…²"}.fa-tumblr:before{content:"ï…³"}.fa-tumblr-square:before{content:"ï…´"}.fa-long-arrow-down:before{content:"ï…µ"}.fa-long-arrow-up:before{content:"ï…¶"}.fa-long-arrow-left:before{content:"ï…·"}.fa-long-arrow-right:before{content:"ï…¸"}.fa-apple:before{content:"ï…¹"}.fa-windows:before{content:"ï…º"}.fa-android:before{content:"ï…»"}.fa-linux:before{content:"ï…¼"}.fa-dribbble:before{content:"ï…½"}.fa-skype:before{content:"ï…¾"}.fa-foursquare:before{content:""}.fa-trello:before{content:"ï†"}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:"ï†"}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:"ï†"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:"ï†"}.fa-yahoo:before{content:""}.fa-google:before{content:"ï† "}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:"ï†"}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:"ï‡"}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"ï‡"}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"ï‡"}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:"ï‡"}.fa-sliders:before{content:""}.fa-share-alt:before{content:"ï‡ "}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:"ï‡"}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:"ïˆ"}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:"ïˆ"}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:"ïˆ"}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:"ïˆ"}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:"ïˆ"}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-hotel:before,.fa-bed:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-yc:before,.fa-y-combinator:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"ï‰"}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:"ï‰"}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:"ï‰"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:"ï‰"}.fa-creative-commons:before{content:""}.fa-gg:before{content:"ï‰ "}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-tv:before,.fa-television:before{content:""}.fa-contao:before{content:"ï‰"}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:"ïŠ"}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:"ïŠ"}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:"ïŠ"}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:"ïŠ"}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:"ïŠ "}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:""}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-signing:before,.fa-sign-language:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:"ïŠ"}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.events form .field,.events form .actions,.moderations form .field,.moderations form .actions,.orgas .field,.orgas .actions,.digests form .field,.digests form .actions{max-width:70em;text-align:left;margin-left:auto;margin-right:auto}.events form .field .helper p,.events form .actions .helper p,.moderations form .field .helper p,.moderations form .actions .helper p,.orgas .field .helper p,.orgas .actions .helper p,.digests form .field .helper p,.digests form .actions .helper p{color:gray;margin:0;font-style:italic;margin-left:8em;padding-left:0.4em}.events form .field label,.events form .actions label,.moderations form .field label,.moderations form .actions label,.orgas .field label,.orgas .actions label,.digests form .field label,.digests form .actions label{width:8em;display:inline-block;vertical-align:middle;*vertical-align:auto;*zoom:1;*display:inline}.events form .field input,.events form .field select,.events form .field .select2-container ul,.events form .actions input,.events form .actions select,.events form .actions .select2-container ul,.moderations form .field input,.moderations form .field select,.moderations form .field .select2-container ul,.moderations form .actions input,.moderations form .actions select,.moderations form .actions .select2-container ul,.orgas .field input,.orgas .field select,.orgas .field .select2-container ul,.orgas .actions input,.orgas .actions select,.orgas .actions .select2-container ul,.digests form .field input,.digests form .field select,.digests form .field .select2-container ul,.digests form .actions input,.digests form .actions select,.digests form .actions .select2-container ul{-moz-border-radius-topleft:0;-webkit-border-top-left-radius:0;border-top-left-radius:0;-moz-border-radius-bottomleft:0;-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0}.events form .field input[type=radio]+label,.events form .actions input[type=radio]+label,.moderations form .field input[type=radio]+label,.moderations form .actions input[type=radio]+label,.orgas .field input[type=radio]+label,.orgas .actions input[type=radio]+label,.digests form .field input[type=radio]+label,.digests form .actions input[type=radio]+label{width:20em}.events form .field input[type=radio]+label:after,.events form .actions input[type=radio]+label:after,.moderations form .field input[type=radio]+label:after,.moderations form .actions input[type=radio]+label:after,.orgas .field input[type=radio]+label:after,.orgas .actions input[type=radio]+label:after,.digests form .field input[type=radio]+label:after,.digests form .actions input[type=radio]+label:after{content:""}.events form .field input[type=text],.events form .field input[type=url],.events form .field input[type=email],.events form .field .select2-container,.events form .field .select2-container ul,.events form .field .mce-tinymce,.events form .actions input[type=text],.events form .actions input[type=url],.events form .actions input[type=email],.events form .actions .select2-container,.events form .actions .select2-container ul,.events form .actions .mce-tinymce,.moderations form .field input[type=text],.moderations form .field input[type=url],.moderations form .field input[type=email],.moderations form .field .select2-container,.moderations form .field .select2-container ul,.moderations form .field .mce-tinymce,.moderations form .actions input[type=text],.moderations form .actions input[type=url],.moderations form .actions input[type=email],.moderations form .actions .select2-container,.moderations form .actions .select2-container ul,.moderations form .actions .mce-tinymce,.orgas .field input[type=text],.orgas .field input[type=url],.orgas .field input[type=email],.orgas .field .select2-container,.orgas .field .select2-container ul,.orgas .field .mce-tinymce,.orgas .actions input[type=text],.orgas .actions input[type=url],.orgas .actions input[type=email],.orgas .actions .select2-container,.orgas .actions .select2-container ul,.orgas .actions .mce-tinymce,.digests form .field input[type=text],.digests form .field input[type=url],.digests form .field input[type=email],.digests form .field .select2-container,.digests form .field .select2-container ul,.digests form .field .mce-tinymce,.digests form .actions input[type=text],.digests form .actions input[type=url],.digests form .actions input[type=email],.digests form .actions .select2-container,.digests form .actions .select2-container ul,.digests form .actions .mce-tinymce{min-width:22em}.events form .field .mce-tinymce,.events form .actions .mce-tinymce,.moderations form .field .mce-tinymce,.moderations form .actions .mce-tinymce,.orgas .field .mce-tinymce,.orgas .actions .mce-tinymce,.digests form .field .mce-tinymce,.digests form .actions .mce-tinymce{font-size:inherit;font-family:inherit;display:inline-block;vertical-align:middle;*vertical-align:auto;*zoom:1;*display:inline;-moz-border-radius:0.4em;-webkit-border-radius:0.4em;border-radius:0.4em;-moz-border-radius-topleft:0;-webkit-border-top-left-radius:0;border-top-left-radius:0;-moz-border-radius-bottomleft:0;-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0}.events form .field .mce-tinymce .mce-container-body .mce-panel.mce-first,.events form .actions .mce-tinymce .mce-container-body .mce-panel.mce-first,.moderations form .field .mce-tinymce .mce-container-body .mce-panel.mce-first,.moderations form .actions .mce-tinymce .mce-container-body .mce-panel.mce-first,.orgas .field .mce-tinymce .mce-container-body .mce-panel.mce-first,.orgas .actions .mce-tinymce .mce-container-body .mce-panel.mce-first,.digests form .field .mce-tinymce .mce-container-body .mce-panel.mce-first,.digests form .actions .mce-tinymce .mce-container-body .mce-panel.mce-first{-moz-border-radius-topright:0.4em;-webkit-border-top-right-radius:0.4em;border-top-right-radius:0.4em}.events form .field .mce-tinymce .mce-container-body .mce-panel.mce-last,.events form .actions .mce-tinymce .mce-container-body .mce-panel.mce-last,.moderations form .field .mce-tinymce .mce-container-body .mce-panel.mce-last,.moderations form .actions .mce-tinymce .mce-container-body .mce-panel.mce-last,.orgas .field .mce-tinymce .mce-container-body .mce-panel.mce-last,.orgas .actions .mce-tinymce .mce-container-body .mce-panel.mce-last,.digests form .field .mce-tinymce .mce-container-body .mce-panel.mce-last,.digests form .actions .mce-tinymce .mce-container-body .mce-panel.mce-last{-moz-border-radius-bottomright:0.4em;-webkit-border-bottom-right-radius:0.4em;border-bottom-right-radius:0.4em}.events form .field label:before,.events form th:before,.events form th a:before,.moderations form .field label:before,.moderations form th:before,.moderations form th a:before,.orgas .field label:before,.orgas th:before,.orgas th a:before,.digests form .field label:before,.digests form th:before,.digests form th a:before{color:gray;margin-right:0.4em;display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.events form .field.title label:before,.moderations form .field.title label:before,.orgas .field.title label:before,.digests form .field.title label:before{content:""}.events form .field.start_time label:before,.moderations form .field.start_time label:before,.orgas .field.start_time label:before,.digests form .field.start_time label:before{content:""}.events form .field.end_time label:before,.moderations form .field.end_time label:before,.orgas .field.end_time label:before,.digests form .field.end_time label:before{content:""}.events form .field.repeat label:before,.moderations form .field.repeat label:before,.orgas .field.repeat label:before,.digests form .field.repeat label:before{content:""}.events form .field.rule>label:before,.moderations form .field.rule>label:before,.orgas .field.rule>label:before,.digests form .field.rule>label:before{content:""}.events form .field.description label:before,.moderations form .field.description label:before,.orgas .field.description label:before,.digests form .field.description label:before{content:"ï„"}.events form .field.place_name label:before,.moderations form .field.place_name label:before,.orgas .field.place_name label:before,.digests form .field.place_name label:before{content:""}.events form .field.address label:before,.moderations form .field.address label:before,.orgas .field.address label:before,.digests form .field.address label:before{content:"ï"}.events form .field.city label:before,.events form th.city a:before,.moderations form .field.city label:before,.moderations form th.city a:before,.orgas .field.city label:before,.orgas th.city a:before,.digests form .field.city label:before,.digests form th.city a:before{content:""}.events form .field.department label:before,.events form th.department a:before,.moderations form .field.department label:before,.moderations form th.department a:before,.orgas .field.department label:before,.orgas th.department a:before,.digests form .field.department label:before,.digests form th.department a:before{content:"ï„®"}.events form .field.region label:before,.events form th.region a:before,.moderations form .field.region label:before,.moderations form th.region a:before,.orgas .field.region label:before,.orgas th.region a:before,.digests form .field.region label:before,.digests form th.region a:before{content:""}.events form .field.locality>label:before,.moderations form .field.locality>label:before,.orgas .field.locality>label:before,.digests form .field.locality>label:before{content:"ï¥"}.events form .field.contact label:before,.moderations form .field.contact label:before,.orgas .field.contact label:before,.digests form .field.contact label:before{content:"ïƒ "}.events form .field.submitter label:before,.moderations form .field.submitter label:before,.orgas .field.submitter label:before,.digests form .field.submitter label:before{content:""}.events form .field.url label:before,.events form th.url:before,.moderations form .field.url label:before,.moderations form th.url:before,.orgas .field.url label:before,.orgas th.url:before,.digests form .field.url label:before,.digests form th.url:before{content:"ï‚Ž"}.events form .field.diaspora label:before,.events form th.diaspora:before,.moderations form .field.diaspora label:before,.moderations form th.diaspora:before,.orgas .field.diaspora label:before,.orgas th.diaspora:before,.digests form .field.diaspora label:before,.digests form th.diaspora:before{content:"ï‚¡"}.events form .field.tags label:before,.events form th.tags a:before,.moderations form .field.tags label:before,.moderations form th.tags a:before,.orgas .field.tags label:before,.orgas th.tags a:before,.digests form .field.tags label:before,.digests form th.tags a:before{content:""}.events form .field.active label:before,.moderations form .field.active label:before,.orgas .field.active label:before,.digests form .field.active label:before{content:""}.events form .field.kind>label:before,.events form th.kind:before,.moderations form .field.kind>label:before,.moderations form th.kind:before,.orgas .field.kind>label:before,.orgas th.kind:before,.digests form .field.kind>label:before,.digests form th.kind:before{content:""}.events form .field.feed label:before,.events form th.feed:before,.moderations form .field.feed label:before,.moderations form th.feed:before,.orgas .field.feed label:before,.orgas th.feed:before,.digests form .field.feed label:before,.digests form th.feed:before{content:"ï‚ž"}.events form .field .radios label,.moderations form .field .radios label,.orgas .field .radios label,.digests form .field .radios label{width:auto !important;margin-right:1em}.events form [type=radio],.moderations form [type=radio],.orgas [type=radio],.digests form [type=radio]{display:none}.events form [type=radio]+label:before,.moderations form [type=radio]+label:before,.orgas [type=radio]+label:before,.digests form [type=radio]+label:before{color:black;content:"ï„Œ";font-size:larger}.events form [type=radio]:checked+label:before,.moderations form [type=radio]:checked+label:before,.orgas [type=radio]:checked+label:before,.digests form [type=radio]:checked+label:before{color:black;content:"";text-shadow:0 0 1px gray}.events form .actions,.moderations form .actions,.orgas .actions,.digests form .actions{text-align:center}.events form .actions input,.moderations form .actions input,.orgas .actions input,.digests form .actions input{font-size:x-large}.quantity{text-align:right !important;white-space:nowrap}table{margin:1em auto;border-spacing:2px}table th{padding:0.3em 0.6em}table.list tbody tr:nth-child(odd){background-color:#D1EAFF}table.list tbody tr:nth-child(even){background-color:#C9E2F5}table.list th{font-size:larger}table.list td{padding:0.2em;text-align:left}table.list td.updated_at{text-align:center}dl{margin:1em auto;max-width:40em}dl dt{clear:left;float:left;padding:0.2em 1em;min-width:50%;text-align:right}dl dd{padding:0.2em 1em;text-align:left}dl dd.quantity{padding-right:16em}dl dd h3{display:inline}dl dt+dd+dt+dd{border-top:1px solid #999}ul.counters{text-align:center}ul.counters li{display:inline}ul.counters li a:link,ul.counters li a:visited{color:white;display:inline-block;padding:0.2em 0.8em;background-color:darkblue;-moz-border-radius:1em;-webkit-border-radius:1em;border-radius:1em}.edit_link:link,.delete_link:link{display:none}.leaflet-map-pane,.leaflet-tile,.leaflet-marker-icon,.leaflet-marker-shadow,.leaflet-tile-pane,.leaflet-tile-container,.leaflet-overlay-pane,.leaflet-shadow-pane,.leaflet-marker-pane,.leaflet-popup-pane,.leaflet-overlay-pane svg,.leaflet-zoom-box,.leaflet-image-layer,.leaflet-layer{position:absolute;left:0;top:0}.leaflet-container{overflow:hidden;-ms-touch-action:none;touch-action:none}.leaflet-tile,.leaflet-marker-icon,.leaflet-marker-shadow{-webkit-user-select:none;-moz-user-select:none;user-select:none;-webkit-user-drag:none}.leaflet-marker-icon,.leaflet-marker-shadow{display:block}.leaflet-container img{max-width:none !important}.leaflet-container img.leaflet-image-layer{max-width:15000px !important}.leaflet-tile{filter:inherit;visibility:hidden}.leaflet-tile-loaded{visibility:inherit}.leaflet-zoom-box{width:0;height:0}.leaflet-overlay-pane svg{-moz-user-select:none}.leaflet-tile-pane{z-index:2}.leaflet-objects-pane{z-index:3}.leaflet-overlay-pane{z-index:4}.leaflet-shadow-pane{z-index:5}.leaflet-marker-pane{z-index:6}.leaflet-popup-pane{z-index:7}.leaflet-vml-shape{width:1px;height:1px}.lvml{behavior:url(#default#VML);display:inline-block;position:absolute}.leaflet-control{position:relative;z-index:7;pointer-events:auto}.leaflet-top,.leaflet-bottom{position:absolute;z-index:1000;pointer-events:none}.leaflet-top{top:0}.leaflet-right{right:0}.leaflet-bottom{bottom:0}.leaflet-left{left:0}.leaflet-control{float:left;clear:both}.leaflet-right .leaflet-control{float:right}.leaflet-top .leaflet-control{margin-top:10px}.leaflet-bottom .leaflet-control{margin-bottom:10px}.leaflet-left .leaflet-control{margin-left:10px}.leaflet-right .leaflet-control{margin-right:10px}.leaflet-fade-anim .leaflet-tile,.leaflet-fade-anim .leaflet-popup{opacity:0;-webkit-transition:opacity 0.2s linear;-moz-transition:opacity 0.2s linear;-o-transition:opacity 0.2s linear;transition:opacity 0.2s linear}.leaflet-fade-anim .leaflet-tile-loaded,.leaflet-fade-anim .leaflet-map-pane .leaflet-popup{opacity:1}.leaflet-zoom-anim .leaflet-zoom-animated{-webkit-transition:-webkit-transform 0.25s cubic-bezier(0, 0, 0.25, 1);-moz-transition:-moz-transform 0.25s cubic-bezier(0, 0, 0.25, 1);-o-transition:-o-transform 0.25s cubic-bezier(0, 0, 0.25, 1);transition:transform 0.25s cubic-bezier(0, 0, 0.25, 1)}.leaflet-zoom-anim .leaflet-tile,.leaflet-pan-anim .leaflet-tile,.leaflet-touching .leaflet-zoom-animated{-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.leaflet-zoom-anim .leaflet-zoom-hide{visibility:hidden}.leaflet-clickable{cursor:pointer}.leaflet-container{cursor:-webkit-grab;cursor:-moz-grab}.leaflet-popup-pane,.leaflet-control{cursor:auto}.leaflet-dragging .leaflet-container,.leaflet-dragging .leaflet-clickable{cursor:move;cursor:-webkit-grabbing;cursor:-moz-grabbing}.leaflet-container{background:#ddd;outline:0}.leaflet-container a{color:#0078A8}.leaflet-container a.leaflet-active{outline:2px solid orange}.leaflet-zoom-box{border:2px dotted #38f;background:rgba(255,255,255,0.5)}.leaflet-container{font:12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif}.leaflet-bar{box-shadow:0 1px 5px rgba(0,0,0,0.65);border-radius:4px}.leaflet-bar a,.leaflet-bar a:hover{background-color:#fff;border-bottom:1px solid #ccc;width:26px;height:26px;line-height:26px;display:block;text-align:center;text-decoration:none;color:black}.leaflet-bar a,.leaflet-control-layers-toggle{background-position:50% 50%;background-repeat:no-repeat;display:block}.leaflet-bar a:hover{background-color:#f4f4f4}.leaflet-bar a:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.leaflet-bar a:last-child{border-bottom-left-radius:4px;border-bottom-right-radius:4px;border-bottom:none}.leaflet-bar a.leaflet-disabled{cursor:default;background-color:#f4f4f4;color:#bbb}.leaflet-touch .leaflet-bar a{width:30px;height:30px;line-height:30px}.leaflet-control-zoom-in,.leaflet-control-zoom-out{font:bold 18px 'Lucida Console', Monaco, monospace;text-indent:1px}.leaflet-control-zoom-out{font-size:20px}.leaflet-touch .leaflet-control-zoom-in{font-size:22px}.leaflet-touch .leaflet-control-zoom-out{font-size:24px}.leaflet-control-layers{box-shadow:0 1px 5px rgba(0,0,0,0.4);background:#fff;border-radius:5px}.leaflet-control-layers-toggle{background-image:url(/assets/layers-0908aa2a72a082fb2563a2427a5e4fb247571862b448b80fb6f720af1109923e.png);width:36px;height:36px}.leaflet-retina .leaflet-control-layers-toggle{background-image:url(/assets/layers-2x-0c02a2388f637d21f86e6d4b314ec9a968e7b05ad4c3a005280a3f76c0fd3cb8.png);background-size:26px 26px}.leaflet-touch .leaflet-control-layers-toggle{width:44px;height:44px}.leaflet-control-layers .leaflet-control-layers-list,.leaflet-control-layers-expanded .leaflet-control-layers-toggle{display:none}.leaflet-control-layers-expanded .leaflet-control-layers-list{display:block;position:relative}.leaflet-control-layers-expanded{padding:6px 10px 6px 6px;color:#333;background:#fff}.leaflet-control-layers-selector{margin-top:2px;position:relative;top:1px}.leaflet-control-layers label{display:block}.leaflet-control-layers-separator{height:0;border-top:1px solid #ddd;margin:5px -10px 5px -6px}.leaflet-container .leaflet-control-attribution{background:#fff;background:rgba(255,255,255,0.7);margin:0}.leaflet-control-attribution,.leaflet-control-scale-line{padding:0 5px;color:#333}.leaflet-control-attribution a{text-decoration:none}.leaflet-control-attribution a:hover{text-decoration:underline}.leaflet-container .leaflet-control-attribution,.leaflet-container .leaflet-control-scale{font-size:11px}.leaflet-left .leaflet-control-scale{margin-left:5px}.leaflet-bottom .leaflet-control-scale{margin-bottom:5px}.leaflet-control-scale-line{border:2px solid #777;border-top:none;line-height:1.1;padding:2px 5px 1px;font-size:11px;white-space:nowrap;overflow:hidden;-moz-box-sizing:content-box;box-sizing:content-box;background:#fff;background:rgba(255,255,255,0.5)}.leaflet-control-scale-line:not(:first-child){border-top:2px solid #777;border-bottom:none;margin-top:-2px}.leaflet-control-scale-line:not(:first-child):not(:last-child){border-bottom:2px solid #777}.leaflet-touch .leaflet-control-attribution,.leaflet-touch .leaflet-control-layers,.leaflet-touch .leaflet-bar{box-shadow:none}.leaflet-touch .leaflet-control-layers,.leaflet-touch .leaflet-bar{border:2px solid rgba(0,0,0,0.2);background-clip:padding-box}.leaflet-popup{position:absolute;text-align:center}.leaflet-popup-content-wrapper{padding:1px;text-align:left;border-radius:12px}.leaflet-popup-content{margin:13px 19px;line-height:1.4}.leaflet-popup-content p{margin:18px 0}.leaflet-popup-tip-container{margin:0 auto;width:40px;height:20px;position:relative;overflow:hidden}.leaflet-popup-tip{width:17px;height:17px;padding:1px;margin:-10px auto 0;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.leaflet-popup-content-wrapper,.leaflet-popup-tip{background:white;box-shadow:0 3px 14px rgba(0,0,0,0.4)}.leaflet-container a.leaflet-popup-close-button{position:absolute;top:0;right:0;padding:4px 4px 0 0;text-align:center;width:18px;height:14px;font:16px/14px Tahoma, Verdana, sans-serif;color:#c3c3c3;text-decoration:none;font-weight:bold;background:transparent}.leaflet-container a.leaflet-popup-close-button:hover{color:#999}.leaflet-popup-scrolled{overflow:auto;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.leaflet-oldie .leaflet-popup-content-wrapper{zoom:1}.leaflet-oldie .leaflet-popup-tip{width:24px;margin:0 auto;-ms-filter:"progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";filter:progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)}.leaflet-oldie .leaflet-popup-tip-container{margin-top:-1px}.leaflet-oldie .leaflet-control-zoom,.leaflet-oldie .leaflet-control-layers,.leaflet-oldie .leaflet-popup-content-wrapper,.leaflet-oldie .leaflet-popup-tip{border:1px solid #999}.leaflet-div-icon{background:#fff;border:1px solid #666}.leaflet-cluster-anim .leaflet-marker-icon,.leaflet-cluster-anim .leaflet-marker-shadow{-webkit-transition:-webkit-transform 0.3s ease-out, opacity 0.3s ease-in;-moz-transition:-moz-transform 0.3s ease-out, opacity 0.3s ease-in;-o-transition:-o-transform 0.3s ease-out, opacity 0.3s ease-in;transition:transform 0.3s ease-out, opacity 0.3s ease-in}.marker-cluster-small{background-color:rgba(181,226,140,0.6)}.marker-cluster-small div{background-color:rgba(110,204,57,0.6)}.marker-cluster-medium{background-color:rgba(241,211,87,0.6)}.marker-cluster-medium div{background-color:rgba(240,194,12,0.6)}.marker-cluster-large{background-color:rgba(253,156,115,0.6)}.marker-cluster-large div{background-color:rgba(241,128,23,0.6)}.leaflet-oldie .marker-cluster-small{background-color:#b5e28c}.leaflet-oldie .marker-cluster-small div{background-color:#6ecc39}.leaflet-oldie .marker-cluster-medium{background-color:#f1d357}.leaflet-oldie .marker-cluster-medium div{background-color:#f0c20c}.leaflet-oldie .marker-cluster-large{background-color:#fd9c73}.leaflet-oldie .marker-cluster-large div{background-color:#f18017}.marker-cluster{background-clip:padding-box;border-radius:20px}.marker-cluster div{width:30px;height:30px;margin-left:5px;margin-top:5px;text-align:center;border-radius:15px;font:12px "Helvetica Neue", Arial, Helvetica, sans-serif}.marker-cluster span{line-height:30px}#map{height:60em;-moz-box-shadow:0 0 1em SteelBlue;-webkit-box-shadow:0 0 1em SteelBlue;box-shadow:0 0 1em SteelBlue;-moz-transition:none;-o-transition:none;-webkit-transition:none;transition:none}#map *{max-width:initial}#map.event,#map.orga{height:20em}.tags #map{width:40%;height:60em;margin:1.6em 2%;display:inline-block;vertical-align:middle;*vertical-align:auto;*zoom:1;*display:inline}form.leaflet-control-layers-list label{text-align:left}form.leaflet-control-layers-list label .awesome-marker{height:auto !important;display:inline-block !important;position:relative !important}html.iframe #map{width:100%;max-width:100%;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}@media all and (min-width: 1600px){body{font-size:larger}aside#orga-list{width:auto}#advises{max-width:60em}}@media all and (max-width: 1024px){body.events.index table{width:100%}form#orga_search{right:0}.formats,a#banner{margin:0.6em auto}table,table.list,table.dates,table.list.dates{border-spacing:1px}table tbody th,table.list tbody th,table.dates tbody th,table.list.dates tbody th{overflow:hidden;max-width:3em}}@media all and (max-width: 900px){header.top img.logo{margin-left:0}header.top ul.countries{margin-right:0}body{border:none;margin:0}body header.top h1{margin-top:0}body main ul{margin-left:0}form#orga_search{font-size:smaller}}@media all and (max-width: 34em){body{padding:0}p{padding-left:0.4em;padding-right:0.4em}header.top ul.countries{display:none}header.top h1{letter-spacing:initial}header.top h2{font-size:initial}form#orga_search{display:none}body.index table thead{display:none}body.index.events table tr td{clear:both;width:auto;height:auto;margin:1px;display:block;font-size:larger;min-height:0.8em;border-width:1px !important}body.index.events table tr td.prev-month,body.index.events table tr td.next-month{display:none}body.index.events table tr td .day_number{float:right}body.index.versions table tbody tr td,body.index.orgas table tbody tr td{width:auto;padding:0 0.2em;display:block}body.index.versions table tbody tr td:first-child,body.index.orgas table tbody tr td:first-child{float:left}body.index.versions table tbody td+td+td,body.index.orgas table tbody td+td+td{display:inline-block}body.index.versions table tbody td:first-child+td,body.index.orgas table tbody td:first-child+td{width:100%;display:block}dl dt{min-width:auto;text-align:left}dl dd,dl dd.quantity{padding-right:1em}aside{display:none}.formats,a#banner{float:none;padding:0.4em 0}.events h2+p,.events #advises,.events .helper,.moderations h2+p,.moderations #advises,.moderations .helper{display:none}.events form .field,.events form .actions,.moderations form .field,.moderations form .actions{max-width:100%}.events form .field .helper p,.events form .actions .helper p,.moderations form .field .helper p,.moderations form .actions .helper p{margin-left:0;padding-left:0}.events form .field label,.events form .actions label,.moderations form .field label,.moderations form .actions label{width:auto;display:block;text-align:left;margin-left:0}.events form .field input,.events form .field .select2-container ul,.events form .field .mce-tinymce,.events form .actions input,.events form .actions .select2-container ul,.events form .actions .mce-tinymce,.moderations form .field input,.moderations form .field .select2-container ul,.moderations form .field .mce-tinymce,.moderations form .actions input,.moderations form .actions .select2-container ul,.moderations form .actions .mce-tinymce{width:100%;-moz-border-radius-bottomleft:0.4em;-webkit-border-bottom-left-radius:0.4em;border-bottom-left-radius:0.4em}.events form .field .select2-container ul,.events form .actions .select2-container ul,.moderations form .field .select2-container ul,.moderations form .actions .select2-container ul{min-width:20em}}h2.warning{color:red}.moderations table.list,.notes table.list{min-width:90%;margin-top:15px}.moderations table.list td,.notes table.list td{padding-top:0.5em;padding-bottom:0.5em}.moderations table.list td.empty,.notes table.list td.empty{background-color:white}.moderations table.list td.note,.notes table.list td.note{text-align:left}.moderations table.list td pre,.notes table.list td pre{width:70%;margin:auto;padding:5px;overflow:auto;text-align:left;background-color:#eee}.moderations table.list td em.author,.notes table.list td em.author{display:block;font-size:smaller;text-align:right;font-style:italic;margin-top:15px}.moderations table.list th.actions,.notes table.list th.actions{padding:0}.moderations table.list th.actions a,.notes table.list th.actions a{padding:0.2em;font-weight:normal;display:inline-block;vertical-align:middle;*vertical-align:auto;*zoom:1;*display:inline}.fa.fa-check,.fa.fa-thumbs-up{color:green}.fa.fa-thumbs-down{color:red}.notes form label:after{content:":"}img.favicon{max-height:2em;vertical-align:middle;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}form#orga_search{right:5%;width:12em;position:absolute;font-size:larger;text-align:right;margin-top:-1.2em;white-space:nowrap;padding-right:2px}form#orga_search label{display:none}form#orga_search em.fa{color:#258}form#orga_search input{border:solid thin #258;margin-left:-1.5em;margin-right:-1.6em;padding-left:1.5em;padding-right:1.2em;background-color:transparent}form#orga_search button.search{color:#258;border:none;padding:0;margin-top:-0.1em;margin-left:0;vertical-align:middle;background-color:transparent;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}form#orga_search button.search:hover em.fa{color:#2E97FF}form#orga_search button.search span.label{display:none}body.orgas.show main fieldset.orga{min-width:60em}body.orgas.show main dl,body.orgas.show main iframe,body.orgas.show main fieldset{min-width:30em;display:inline-block;vertical-align:middle;*vertical-align:auto;*zoom:1;*display:inline;vertical-align:top}table tr.inactive{color:gray}.region_selector{display:inline-block;vertical-align:middle;*vertical-align:auto;*zoom:1;*display:inline}.region_selector h3{margin:0}.region_selector h3 .placeholder{color:gray}.region_selector ul{margin:0;z-index:10;display:none;position:absolute;margin-top:-7em;background-color:white;list-style:none;-moz-box-shadow:1px 1px 4px gray;-webkit-box-shadow:1px 1px 4px gray;box-shadow:1px 1px 4px gray;-moz-border-radius-bottomleft:0.4em;-webkit-border-bottom-left-radius:0.4em;border-bottom-left-radius:0.4em;-moz-border-radius-bottomright:0.4em;-webkit-border-bottom-right-radius:0.4em;border-bottom-right-radius:0.4em}.region_selector ul li{list-style-image:none;list-style-type:none;margin-left:0}.region_selector ul li{margin:0}.region_selector ul li a{display:block;padding:0.2em 1em;border-top:solid thin black}.region_selector ul li a:hover{background-color:#eee;text-shadow:1px 1px 0.2em gray}.region_selector ul li a em.fa-globe{color:red}.region_selector:hover ul{display:block}body.stats h3{text-align:center}table.list.dates th,table.list.dates td{padding:0 0.6em}table.list.dates .sparkline{padding:0}div.field,div.actions{margin-bottom:10px}#notice{color:green}#error_explanation{width:450px;border:2px solid red;padding-bottom:0;margin-bottom:20px;background-color:#f0f0f0}#error_explanation h2{text-align:left;font-weight:bold;padding:15px;font-size:12px;background-color:#c00;color:#fff}#error_explanation p,#error_explanation ul{padding:0 1em}#error_explanation p li,#error_explanation ul li{font-size:12px;list-style:square}.sessions form{margin:1em auto;display:inline-block;vertical-align:middle;*vertical-align:auto;*zoom:1;*display:inline}.sessions form .field,.sessions form .actions{text-align:left;margin:0.5em}.sessions form .field *,.sessions form .actions *{vertical-align:middle}.sessions form .field .helper p,.sessions form .actions .helper p{margin:1px 5px 1px 6.6em}.sessions form .field label,.sessions form .actions label{width:8em;display:inline-block;vertical-align:middle;*vertical-align:auto;*zoom:1;*display:inline}.sessions form .field label:after,.sessions form .actions label:after{content:":"}.sessions form .actions{margin-left:6.75em;margin-bottom:10px}.logout{margin:2em auto}table tfoot td canvas{width:100% !important;background-color:white}p.tags a:after{color:black;content:","}p.tags a:last-child:after{content:""}.tag{vertical-align:middle}.tag.size_1{font-size:60%;letter-spacing:-1px}.tag.size_2{font-size:80%;letter-spacing:-1px}.tag.size_3{font-size:100%}.tag.size_4{font-size:120%}.tag.size_5{font-size:180%}.tag.size_6{font-size:200%}.tag.size_7{font-size:220%}.tag.size_8{font-size:240%}/*! + * Font Awesome 4.6.2 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url("/assets/font-awesome/fontawesome-webfont-a280856e20cc0af53390b729ca0ac3edbf8fc889a828a379c5d634c91e80c808.eot?v=4.6.2");src:url("/assets/font-awesome/fontawesome-webfont-a280856e20cc0af53390b729ca0ac3edbf8fc889a828a379c5d634c91e80c808.eot?v=4.6.2#iefix") format("embedded-opentype"),url("/assets/font-awesome/fontawesome-webfont-2932abf996373e87fbf2e950876b1962f1b57db954a1643ea68831d9fbb74da4.woff2?v=4.6.2") format("woff2"),url("/assets/font-awesome/fontawesome-webfont-35fa8302dd7d3d191ebb7acac543efcfa2b85a0da573b3ab45cc122ffcc45ce5.woff?v=4.6.2") format("woff"),url("/assets/font-awesome/fontawesome-webfont-8630313bee77f64206067ed80eb6a7c721b0bbfc91c94210966969d4dcc43ba7.ttf?v=4.6.2") format("truetype"),url("/assets/font-awesome/fontawesome-webfont-6b0adce775f4d57ac800f23b05af72ced748ae51ba67a65b67b7316f1ed331b3.svg?v=4.6.2#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:0.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:0.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:"ï€"}.fa-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-remove:before,.fa-close:before,.fa-times:before{content:"ï€"}.fa-search-plus:before{content:""}.fa-search-minus:before{content:"ï€"}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:"ï€"}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before{content:"ï€"}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:"ï€"}.fa-map-marker:before{content:"ï"}.fa-adjust:before{content:"ï‚"}.fa-tint:before{content:"ïƒ"}.fa-edit:before,.fa-pencil-square-o:before{content:"ï„"}.fa-share-square-o:before{content:"ï…"}.fa-check-square-o:before{content:"ï†"}.fa-arrows:before{content:"ï‡"}.fa-step-backward:before{content:"ïˆ"}.fa-fast-backward:before{content:"ï‰"}.fa-backward:before{content:"ïŠ"}.fa-play:before{content:"ï‹"}.fa-pause:before{content:"ïŒ"}.fa-stop:before{content:"ï"}.fa-forward:before{content:"ïŽ"}.fa-fast-forward:before{content:"ï"}.fa-step-forward:before{content:"ï‘"}.fa-eject:before{content:"ï’"}.fa-chevron-left:before{content:"ï“"}.fa-chevron-right:before{content:"ï”"}.fa-plus-circle:before{content:"ï•"}.fa-minus-circle:before{content:"ï–"}.fa-times-circle:before{content:"ï—"}.fa-check-circle:before{content:"ï˜"}.fa-question-circle:before{content:"ï™"}.fa-info-circle:before{content:"ïš"}.fa-crosshairs:before{content:"ï›"}.fa-times-circle-o:before{content:"ïœ"}.fa-check-circle-o:before{content:"ï"}.fa-ban:before{content:"ïž"}.fa-arrow-left:before{content:"ï "}.fa-arrow-right:before{content:"ï¡"}.fa-arrow-up:before{content:"ï¢"}.fa-arrow-down:before{content:"ï£"}.fa-mail-forward:before,.fa-share:before{content:"ï¤"}.fa-expand:before{content:"ï¥"}.fa-compress:before{content:"ï¦"}.fa-plus:before{content:"ï§"}.fa-minus:before{content:"ï¨"}.fa-asterisk:before{content:"ï©"}.fa-exclamation-circle:before{content:"ïª"}.fa-gift:before{content:"ï«"}.fa-leaf:before{content:"ï¬"}.fa-fire:before{content:"ï"}.fa-eye:before{content:"ï®"}.fa-eye-slash:before{content:"ï°"}.fa-warning:before,.fa-exclamation-triangle:before{content:"ï±"}.fa-plane:before{content:"ï²"}.fa-calendar:before{content:"ï³"}.fa-random:before{content:"ï´"}.fa-comment:before{content:"ïµ"}.fa-magnet:before{content:"ï¶"}.fa-chevron-up:before{content:"ï·"}.fa-chevron-down:before{content:"ï¸"}.fa-retweet:before{content:"ï¹"}.fa-shopping-cart:before{content:"ïº"}.fa-folder:before{content:"ï»"}.fa-folder-open:before{content:"ï¼"}.fa-arrows-v:before{content:"ï½"}.fa-arrows-h:before{content:"ï¾"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"ï‚€"}.fa-twitter-square:before{content:"ï‚"}.fa-facebook-square:before{content:"ï‚‚"}.fa-camera-retro:before{content:""}.fa-key:before{content:"ï‚„"}.fa-gears:before,.fa-cogs:before{content:"ï‚…"}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:"ï‚Š"}.fa-sign-out:before{content:"ï‚‹"}.fa-linkedin-square:before{content:"ï‚Œ"}.fa-thumb-tack:before{content:"ï‚"}.fa-external-link:before{content:"ï‚Ž"}.fa-sign-in:before{content:"ï‚"}.fa-trophy:before{content:"ï‚‘"}.fa-github-square:before{content:"ï‚’"}.fa-upload:before{content:"ï‚“"}.fa-lemon-o:before{content:"ï‚”"}.fa-phone:before{content:"ï‚•"}.fa-square-o:before{content:"ï‚–"}.fa-bookmark-o:before{content:"ï‚—"}.fa-phone-square:before{content:""}.fa-twitter:before{content:"ï‚™"}.fa-facebook-f:before,.fa-facebook:before{content:"ï‚š"}.fa-github:before{content:"ï‚›"}.fa-unlock:before{content:"ï‚œ"}.fa-credit-card:before{content:"ï‚"}.fa-feed:before,.fa-rss:before{content:"ï‚ž"}.fa-hdd-o:before{content:"ï‚ "}.fa-bullhorn:before{content:"ï‚¡"}.fa-bell:before{content:""}.fa-certificate:before{content:"ï‚£"}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:"ï‚¥"}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before{content:""}.fa-arrow-circle-right:before{content:"ï‚©"}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:"ï‚«"}.fa-globe:before{content:""}.fa-wrench:before{content:"ï‚"}.fa-tasks:before{content:"ï‚®"}.fa-filter:before{content:"ï‚°"}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before{content:"ïƒ"}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:"ïƒ"}.fa-table:before{content:""}.fa-magic:before{content:"ïƒ"}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:"ïƒ"}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:"ïƒ "}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:"ïƒ"}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:"ï‚¢"}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:"ï„€"}.fa-angle-double-right:before{content:"ï„"}.fa-angle-double-up:before{content:"ï„‚"}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:"ï„„"}.fa-angle-right:before{content:"ï„…"}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:"ï„Š"}.fa-mobile-phone:before,.fa-mobile:before{content:"ï„‹"}.fa-circle-o:before{content:"ï„Œ"}.fa-quote-left:before{content:"ï„"}.fa-quote-right:before{content:"ï„Ž"}.fa-spinner:before{content:"ï„"}.fa-circle:before{content:"ï„‘"}.fa-mail-reply:before,.fa-reply:before{content:"ï„’"}.fa-github-alt:before{content:"ï„“"}.fa-folder-o:before{content:"ï„”"}.fa-folder-open-o:before{content:"ï„•"}.fa-smile-o:before{content:""}.fa-frown-o:before{content:"ï„™"}.fa-meh-o:before{content:"ï„š"}.fa-gamepad:before{content:"ï„›"}.fa-keyboard-o:before{content:"ï„œ"}.fa-flag-o:before{content:"ï„"}.fa-flag-checkered:before{content:"ï„ž"}.fa-terminal:before{content:"ï„ "}.fa-code:before{content:"ï„¡"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"ï„¢"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"ï„£"}.fa-location-arrow:before{content:""}.fa-crop:before{content:"ï„¥"}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:"ï„©"}.fa-exclamation:before{content:""}.fa-superscript:before{content:"ï„«"}.fa-subscript:before{content:""}.fa-eraser:before{content:"ï„"}.fa-puzzle-piece:before{content:"ï„®"}.fa-microphone:before{content:"ï„°"}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:"ï„´"}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:"ï„·"}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:"ï„»"}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:"ï…€"}.fa-ellipsis-h:before{content:"ï…"}.fa-ellipsis-v:before{content:"ï…‚"}.fa-rss-square:before{content:"ï…ƒ"}.fa-play-circle:before{content:"ï…„"}.fa-ticket:before{content:"ï……"}.fa-minus-square:before{content:"ï…†"}.fa-minus-square-o:before{content:"ï…‡"}.fa-level-up:before{content:"ï…ˆ"}.fa-level-down:before{content:"ï…‰"}.fa-check-square:before{content:"ï…Š"}.fa-pencil-square:before{content:"ï…‹"}.fa-external-link-square:before{content:"ï…Œ"}.fa-share-square:before{content:"ï…"}.fa-compass:before{content:"ï…Ž"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"ï…"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"ï…‘"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"ï…’"}.fa-euro:before,.fa-eur:before{content:"ï…“"}.fa-gbp:before{content:"ï…”"}.fa-dollar:before,.fa-usd:before{content:"ï…•"}.fa-rupee:before,.fa-inr:before{content:"ï…–"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"ï…—"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"ï…˜"}.fa-won:before,.fa-krw:before{content:"ï…™"}.fa-bitcoin:before,.fa-btc:before{content:"ï…š"}.fa-file:before{content:"ï…›"}.fa-file-text:before{content:"ï…œ"}.fa-sort-alpha-asc:before{content:"ï…"}.fa-sort-alpha-desc:before{content:"ï…ž"}.fa-sort-amount-asc:before{content:"ï… "}.fa-sort-amount-desc:before{content:"ï…¡"}.fa-sort-numeric-asc:before{content:"ï…¢"}.fa-sort-numeric-desc:before{content:"ï…£"}.fa-thumbs-up:before{content:"ï…¤"}.fa-thumbs-down:before{content:"ï…¥"}.fa-youtube-square:before{content:"ï…¦"}.fa-youtube:before{content:"ï…§"}.fa-xing:before{content:"ï…¨"}.fa-xing-square:before{content:"ï…©"}.fa-youtube-play:before{content:"ï…ª"}.fa-dropbox:before{content:"ï…«"}.fa-stack-overflow:before{content:"ï…¬"}.fa-instagram:before{content:"ï…"}.fa-flickr:before{content:"ï…®"}.fa-adn:before{content:"ï…°"}.fa-bitbucket:before{content:"ï…±"}.fa-bitbucket-square:before{content:"ï…²"}.fa-tumblr:before{content:"ï…³"}.fa-tumblr-square:before{content:"ï…´"}.fa-long-arrow-down:before{content:"ï…µ"}.fa-long-arrow-up:before{content:"ï…¶"}.fa-long-arrow-left:before{content:"ï…·"}.fa-long-arrow-right:before{content:"ï…¸"}.fa-apple:before{content:"ï…¹"}.fa-windows:before{content:"ï…º"}.fa-android:before{content:"ï…»"}.fa-linux:before{content:"ï…¼"}.fa-dribbble:before{content:"ï…½"}.fa-skype:before{content:"ï…¾"}.fa-foursquare:before{content:""}.fa-trello:before{content:"ï†"}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:"ï†"}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:"ï†"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:"ï†"}.fa-yahoo:before{content:""}.fa-google:before{content:"ï† "}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:"ï†"}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:"ï‡"}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"ï‡"}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"ï‡"}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:"ï‡"}.fa-sliders:before{content:""}.fa-share-alt:before{content:"ï‡ "}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:"ï‡"}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:"ïˆ"}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:"ïˆ"}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:"ïˆ"}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:"ïˆ"}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:"ïˆ"}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-hotel:before,.fa-bed:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-yc:before,.fa-y-combinator:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"ï‰"}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:"ï‰"}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:"ï‰"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:"ï‰"}.fa-creative-commons:before{content:""}.fa-gg:before{content:"ï‰ "}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-tv:before,.fa-television:before{content:""}.fa-contao:before{content:"ï‰"}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:"ïŠ"}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:"ïŠ"}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:"ïŠ"}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:"ïŠ"}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:"ïŠ "}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:""}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-signing:before,.fa-sign-language:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:"ïŠ"}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}body.application.infos h4{text-align:left}body.application.infos main h2:first-child:before,body.application.contact main h2:first-child:before,body.application.rules main h2:first-child:before{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;margin-right:0.4em}body.application.infos main h2:first-child:before{content:"ï„©"}body.application.contact main h2:first-child:before{content:"ïƒ "}body.application.rules main h2:first-child:before{content:""} diff --git a/public/assets/application-2fb50a7174d540a1e61def8f3733ef9b16048a46d710d6b766260ee4589d4840.css.gz b/public/assets/application-2fb50a7174d540a1e61def8f3733ef9b16048a46d710d6b766260ee4589d4840.css.gz new file mode 100644 index 0000000000000000000000000000000000000000..616c765863976fa487e42517295049ed30185f8b GIT binary patch literal 32188 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 literal 0 HcmV?d00001 diff --git a/public/assets/application-e0182820be578ba7db1bc56b9933acaa65e9d2ec18d340e667afe68de5d750cc.js b/public/assets/application-e0182820be578ba7db1bc56b9933acaa65e9d2ec18d340e667afe68de5d750cc.js new file mode 100644 index 000000000..bc7b9504b --- /dev/null +++ b/public/assets/application-e0182820be578ba7db1bc56b9933acaa65e9d2ec18d340e667afe68de5d750cc.js @@ -0,0 +1,75399 @@ +/*! + * jQuery JavaScript Library v1.11.3 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2015-04-28T16:19Z + */ + + +(function( global, factory ) { + + if ( typeof module === "object" && typeof module.exports === "object" ) { + // For CommonJS and CommonJS-like environments where a proper window is present, + // execute the factory and get jQuery + // For environments that do not inherently posses a window with a document + // (such as Node.js), expose a jQuery-making factory as module.exports + // This accentuates the need for the creation of a real window + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Can't do this because several apps including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// Support: Firefox 18+ +// + +var deletedIds = []; + +var slice = deletedIds.slice; + +var concat = deletedIds.concat; + +var push = deletedIds.push; + +var indexOf = deletedIds.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var support = {}; + + + +var + version = "1.11.3", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android<4.1, IE<9 + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num != null ? + + // Return just the one element from the set + ( num < 0 ? this[ num + this.length ] : this[ num ] ) : + + // Return all the elements in a clean array + slice.call( this ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: deletedIds.sort, + splice: deletedIds.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var src, copyIsArray, copy, name, options, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + /* jshint eqeqeq: false */ + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + // parseFloat NaNs numeric-cast false positives (null|true|false|"") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + // adding 1 corrects loss of precision from parseFloat (#15100) + return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0; + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + isPlainObject: function( obj ) { + var key; + + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Support: IE<9 + // Handle iteration over inherited properties before own properties. + if ( support.ownLast ) { + for ( key in obj ) { + return hasOwn.call( obj, key ); + } + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call(obj) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && jQuery.trim( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + // Support: Android<4.1, IE<9 + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArraylike( Object(arr) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( indexOf ) { + return indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + while ( j < len ) { + first[ i++ ] = second[ j++ ]; + } + + // Support: IE<9 + // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists) + if ( len !== len ) { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var args, proxy, tmp; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: function() { + return +( new Date() ); + }, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + + // Support: iOS 8.2 (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = "length" in obj && obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.2.0-pre + * http://sizzlejs.com/ + * + * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-12-16 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // General-purpose constants + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // http://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + characterEncoding + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + nodeType = context.nodeType; + + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + if ( !seed && documentIsHTML ) { + + // Try to shortcut find operations when possible (e.g., not under DocumentFragment) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document (jQuery #6963) + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType !== 1 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, parent, + doc = node ? node.ownerDocument || node : preferredDoc; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + parent = doc.defaultView; + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent !== parent.top ) { + // IE11 does not have attachEvent, so all must suffer + if ( parent.addEventListener ) { + parent.addEventListener( "unload", unloadHandler, false ); + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", unloadHandler ); + } + } + + /* Support tests + ---------------------------------------------------------------------- */ + documentIsHTML = !isXML( doc ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( doc.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [ m ] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" + + "<select id='" + expando + "-\f]' msallowcapture=''>" + + "<option selected=''></option></select>"; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( div.querySelectorAll("[msallowcapture^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+ + if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push("~="); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibing-combinator selector` fails + if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push(".#.+[+~]"); + } + }); + + assert(function( div ) { + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( div.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch (e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + // Don't keep the element (issue #299) + input[0] = null; + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (oldCache = outerCache[ dir ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + outerCache[ dir ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context !== document && context; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is no seed and only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = "<a href='#'></a>"; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = "<input/>"; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + + +var rneedsContext = jQuery.expr.match.needsContext; + +var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not; + }); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); +}; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + ret = [], + self = this, + len = self.length; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + filter: function( selector ) { + return this.pushStack( winnow(this, selector || [], false) ); + }, + not: function( selector ) { + return this.pushStack( winnow(this, selector || [], true) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +}); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + + // A simple way to check for HTML strings + // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + init = jQuery.fn.init = function( selector, context ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return typeof rootjQuery.ready !== "undefined" ? + rootjQuery.ready( selector ) : + // Execute immediately if ready is not present + selector( jQuery ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.extend({ + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +jQuery.fn.extend({ + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments + if ( cur.nodeType < 11 && (pos ? + pos.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector(cur, selectors)) ) { + + matched.push( cur ); + break; + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.unique( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + if ( this.length > 1 ) { + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + ret = jQuery.unique( ret ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + } + + return this.pushStack( ret ); + }; +}); +var rnotwhite = (/\S+/g); + + + +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // First callback to fire (used internally by add and fireWith) + firingStart, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + firingLength = 0; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( list && ( !fired || stack ) ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( values === progressValues ) { + deferred.notifyWith( contexts, values ); + + } else if ( !(--remaining) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); + + +// The deferred used on DOM ready +var readyList; + +jQuery.fn.ready = function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; +}; + +jQuery.extend({ + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.triggerHandler ) { + jQuery( document ).triggerHandler( "ready" ); + jQuery( document ).off( "ready" ); + } + } +}); + +/** + * Clean-up method for dom ready events + */ +function detach() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + + } else { + document.detachEvent( "onreadystatechange", completed ); + window.detachEvent( "onload", completed ); + } +} + +/** + * The ready event handler and self cleanup method + */ +function completed() { + // readyState === "complete" is good enough for us to call the dom ready in oldIE + if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { + detach(); + jQuery.ready(); + } +} + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", completed ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", completed ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // detach all dom ready events + detach(); + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + + +var strundefined = typeof undefined; + + + +// Support: IE<9 +// Iteration over object's inherited properties before its own +var i; +for ( i in jQuery( support ) ) { + break; +} +support.ownLast = i !== "0"; + +// Note: most support tests are defined in their respective modules. +// false until the test is run +support.inlineBlockNeedsLayout = false; + +// Execute ASAP in case we need to set body.style.zoom +jQuery(function() { + // Minified: var a,b,c,d + var val, div, body, container; + + body = document.getElementsByTagName( "body" )[ 0 ]; + if ( !body || !body.style ) { + // Return for frameset docs that don't have a body + return; + } + + // Setup + div = document.createElement( "div" ); + container = document.createElement( "div" ); + container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; + body.appendChild( container ).appendChild( div ); + + if ( typeof div.style.zoom !== strundefined ) { + // Support: IE<8 + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1"; + + support.inlineBlockNeedsLayout = val = div.offsetWidth === 3; + if ( val ) { + // Prevent IE 6 from affecting layout for positioned elements #11048 + // Prevent IE from shrinking the body in IE 7 mode #12869 + // Support: IE<8 + body.style.zoom = 1; + } + } + + body.removeChild( container ); +}); + + + + +(function() { + var div = document.createElement( "div" ); + + // Execute the test only if not already executed in another module. + if (support.deleteExpando == null) { + // Support: IE<9 + support.deleteExpando = true; + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + } + + // Null elements to avoid leaks in IE. + div = null; +})(); + + +/** + * Determines whether an object can have data + */ +jQuery.acceptData = function( elem ) { + var noData = jQuery.noData[ (elem.nodeName + " ").toLowerCase() ], + nodeType = +elem.nodeType || 1; + + // Do not set data on non-element DOM nodes because it will not be cleared (#8335). + return nodeType !== 1 && nodeType !== 9 ? + false : + + // Nodes accept data unless otherwise specified; rejection can be conditional + !noData || noData !== true && elem.getAttribute("classid") === noData; +}; + + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /([A-Z])/g; + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + +function internalData( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var ret, thisCache, + internalKey = jQuery.expando, + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + // Avoid exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + cache[ id ] = isNode ? {} : { toJSON: jQuery.noop }; + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( typeof name === "string" ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; +} + +function internalRemoveData( elem, name, pvt ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } else { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = name.concat( jQuery.map( name, jQuery.camelCase ) ); + } + + i = name.length; + while ( i-- ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + /* jshint eqeqeq: false */ + } else if ( support.deleteExpando || cache != cache.window ) { + /* jshint eqeqeq: true */ + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = null; + } +} + +jQuery.extend({ + cache: {}, + + // The following elements (space-suffixed to avoid Object.prototype collisions) + // throw uncatchable exceptions if you attempt to set expando properties + noData: { + "applet ": true, + "embed ": true, + // ...but Flash objects (which have this classid) *can* handle expandos + "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data ) { + return internalData( elem, name, data ); + }, + + removeData: function( elem, name ) { + return internalRemoveData( elem, name ); + }, + + // For internal use only. + _data: function( elem, name, data ) { + return internalData( elem, name, data, true ); + }, + + _removeData: function( elem, name ) { + return internalRemoveData( elem, name, true ); + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var i, name, data, + elem = this[0], + attrs = elem && elem.attributes; + + // Special expections of .data basically thwart jQuery.access, + // so implement the relevant behavior ourselves + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE11+ + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice(5) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + return arguments.length > 1 ? + + // Sets one value + this.each(function() { + jQuery.data( this, key, value ); + }) : + + // Gets one value + // Try to fetch any internally stored data first + elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined; + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + + +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery._removeData( elem, type + "queue" ); + jQuery._removeData( elem, key ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHidden = function( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); + }; + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + length = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < length; i++ ) { + fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; +}; +var rcheckableType = (/^(?:checkbox|radio)$/i); + + + +(function() { + // Minified: var a,b,c + var input = document.createElement( "input" ), + div = document.createElement( "div" ), + fragment = document.createDocumentFragment(); + + // Setup + div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>"; + + // IE strips leading whitespace when .innerHTML is used + support.leadingWhitespace = div.firstChild.nodeType === 3; + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + support.tbody = !div.getElementsByTagName( "tbody" ).length; + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + support.htmlSerialize = !!div.getElementsByTagName( "link" ).length; + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + support.html5Clone = + document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav></:nav>"; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + input.type = "checkbox"; + input.checked = true; + fragment.appendChild( input ); + support.appendChecked = input.checked; + + // Make sure textarea (and checkbox) defaultValue is properly cloned + // Support: IE6-IE11+ + div.innerHTML = "<textarea>x</textarea>"; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // #11217 - WebKit loses check when the name is after the checked attribute + fragment.appendChild( div ); + div.innerHTML = "<input type='radio' checked='checked' name='t'/>"; + + // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 + // old WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<9 + // Opera does not clone events (and typeof div.attachEvent === undefined). + // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() + support.noCloneEvent = true; + if ( div.attachEvent ) { + div.attachEvent( "onclick", function() { + support.noCloneEvent = false; + }); + + div.cloneNode( true ).click(); + } + + // Execute the test only if not already executed in another module. + if (support.deleteExpando == null) { + // Support: IE<9 + support.deleteExpando = true; + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + } +})(); + + +(function() { + var i, eventName, + div = document.createElement( "div" ); + + // Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event) + for ( i in { submit: true, change: true, focusin: true }) { + eventName = "on" + i; + + if ( !(support[ i + "Bubbles" ] = eventName in window) ) { + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) + div.setAttribute( eventName, "t" ); + support[ i + "Bubbles" ] = div.attributes[ eventName ].expando === false; + } + } + + // Null elements to avoid leaks in IE. + div = null; +})(); + + +var rformElems = /^(?:input|select|textarea)$/i, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + var tmp, events, t, handleObjIn, + special, eventHandle, handleObj, + handlers, type, namespaces, origType, + elemData = jQuery._data( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + var j, handleObj, tmp, + origCount, t, events, + special, handlers, type, + namespaces, origType, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery._removeData( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + var handle, ontype, cur, + bubbleType, special, tmp, i, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && jQuery.acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && + jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + try { + elem[ type ](); + } catch ( e ) { + // IE<9 dies on focus/blur to hidden element (#1486,#12518) + // only reproducible on winXP IE8 native, not IE9 in IE8 mode + } + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, ret, handleObj, matched, j, + handlerQueue = [], + args = slice.call( arguments ), + handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( (event.result = ret) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var sel, handleObj, matches, i, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG <use> instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + /* jshint eqeqeq: false */ + for ( ; cur != this; cur = cur.parentNode || this ) { + /* jshint eqeqeq: true */ + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: IE<9 + // Fix target property (#1925) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Support: Chrome 23+, Safari? + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Support: IE<9 + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) + event.metaKey = !!event.metaKey; + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var body, eventDoc, doc, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + try { + this.focus(); + return false; + } catch ( e ) { + // Support: IE<9 + // If we error on focus to hidden element (#1486, #12518), + // let .trigger() run the handlers + } + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === strundefined ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + // Support: IE < 9, Android < 4.0 + src.returnValue === false ? + returnTrue : + returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + if ( !e ) { + return; + } + + // If preventDefault exists, run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // Support: IE + // Otherwise set the returnValue property of the original event to false + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + if ( !e ) { + return; + } + // If stopPropagation exists, run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + + // Support: IE + // Set the cancelBubble property of the original event to true + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && e.stopImmediatePropagation ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "submitBubbles" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "submitBubbles", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "changeBubbles", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = jQuery._data( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + jQuery._data( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = jQuery._data( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + jQuery._removeData( doc, fix ); + } else { + jQuery._data( doc, fix, attaches ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var type, origFn; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +}); + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /<tbody/i, + rhtml = /<|&#?\w+;/, + rnoInnerhtml = /<(?:script|style|link)/i, + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /^$|\/(?:java|ecma)script/i, + rscriptTypeMasked = /^true\/(.*)/, + rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + option: [ 1, "<select multiple='multiple'>", "</select>" ], + legend: [ 1, "<fieldset>", "</fieldset>" ], + area: [ 1, "<map>", "</map>" ], + param: [ 1, "<object>", "</object>" ], + thead: [ 1, "<table>", "</table>" ], + tr: [ 2, "<table><tbody>", "</tbody></table>" ], + col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ], + td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], + + // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, + // unless wrapped in a div with non-breaking characters in front of it. + _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +function getAll( context, tag ) { + var elems, elem, + i = 0, + found = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || "*" ) : + undefined; + + if ( !found ) { + for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { + if ( !tag || jQuery.nodeName( elem, tag ) ) { + found.push( elem ); + } else { + jQuery.merge( found, getAll( elem, tag ) ); + } + } + } + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], found ) : + found; +} + +// Used in buildFragment, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +// Support: IE<8 +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName("tbody")[0] || + elem.appendChild( elem.ownerDocument.createElement("tbody") ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + if ( match ) { + elem.type = match[1]; + } else { + elem.removeAttribute("type"); + } + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var elem, + i = 0; + for ( ; (elem = elems[i]) != null; i++ ) { + jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) ); + } +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function fixCloneNodeIssues( src, dest ) { + var nodeName, e, data; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + nodeName = dest.nodeName.toLowerCase(); + + // IE6-8 copies events bound via attachEvent when using cloneNode. + if ( !support.noCloneEvent && dest[ jQuery.expando ] ) { + data = jQuery._data( dest ); + + for ( e in data.events ) { + jQuery.removeEvent( dest, e, data.handle ); + } + + // Event data gets referenced instead of copied if the expando gets copied too + dest.removeAttribute( jQuery.expando ); + } + + // IE blanks contents when cloning scripts, and tries to evaluate newly-set text + if ( nodeName === "script" && dest.text !== src.text ) { + disableScript( dest ).text = src.text; + restoreScript( dest ); + + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + } else if ( nodeName === "object" ) { + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.defaultSelected = dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var destElements, node, clone, i, srcElements, + inPage = jQuery.contains( elem.ownerDocument, elem ); + + if ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!support.noCloneEvent || !support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + // Fix all IE cloning issues + for ( i = 0; (node = srcElements[i]) != null; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + fixCloneNodeIssues( node, destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0; (node = srcElements[i]) != null; i++ ) { + cloneCopyEvent( node, destElements[i] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + destElements = srcElements = node = null; + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var j, elem, contains, + tmp, tag, tbody, wrap, + l = elems.length, + + // Ensure a safe fragment + safe = createSafeFragment( context ), + + nodes = [], + i = 0; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || safe.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = (rtagName.exec( elem ) || [ "", "" ])[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + + tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[2]; + + // Descend through wrappers to the right content + j = wrap[0]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Manually add leading whitespace removed by IE + if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); + } + + // Remove IE's autoinserted <tbody> from table fragments + if ( !support.tbody ) { + + // String was a <table>, *may* have spurious <tbody> + elem = tag === "table" && !rtbody.test( elem ) ? + tmp.firstChild : + + // String was a bare <thead> or <tfoot> + wrap[1] === "<table>" && !rtbody.test( elem ) ? + tmp : + 0; + + j = elem && elem.childNodes.length; + while ( j-- ) { + if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) { + elem.removeChild( tbody ); + } + } + } + + jQuery.merge( nodes, tmp.childNodes ); + + // Fix #12392 for WebKit and IE > 9 + tmp.textContent = ""; + + // Fix #12392 for oldIE + while ( tmp.firstChild ) { + tmp.removeChild( tmp.firstChild ); + } + + // Remember the top-level container for proper cleanup + tmp = safe.lastChild; + } + } + } + + // Fix #11356: Clear elements from fragment + if ( tmp ) { + safe.removeChild( tmp ); + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !support.appendChecked ) { + jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); + } + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( safe.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + tmp = null; + + return safe; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var elem, type, id, data, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( typeof elem.removeAttribute !== strundefined ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + deletedIds.push( id ); + } + } + } + } + } +}); + +jQuery.fn.extend({ + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + append: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + remove: function( selector, keepData /* Internal Use Only */ ) { + var elem, + elems = selector ? jQuery.filter( selector, this ) : this, + i = 0; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + + // If this is a select, ensure that it displays empty (#12336) + // Support: IE<9 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) { + elem.options.length = 0; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map(function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1></$2>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var arg = arguments[ 0 ]; + + // Make the changes, replacing each context element with the new content + this.domManip( arguments, function( elem ) { + arg = this.parentNode; + + jQuery.cleanData( getAll( this ) ); + + if ( arg ) { + arg.replaceChild( elem, this ); + } + }); + + // Force removal if there was no new content (e.g., from empty arguments) + return arg && (arg.length || arg.nodeType) ? this : this.remove(); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, callback ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var first, node, hasScripts, + scripts, doc, fragment, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[0], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[0] = value.call( this, index, self.html() ); + } + self.domManip( args, callback ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( this[i], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + } + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + } + } + + return this; + } +}); + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone(true); + jQuery( insert[i] )[ original ]( elems ); + + // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + + +var iframe, + elemdisplay = {}; + +/** + * Retrieve the actual display of a element + * @param {String} name nodeName of the element + * @param {Object} doc Document object + */ +// Called only from within defaultDisplay +function actualDisplay( name, doc ) { + var style, + elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), + + // getDefaultComputedStyle might be reliably used only on attached element + display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? + + // Use of this method is a temporary fix (more like optmization) until something better comes along, + // since it was removed from specification and supported only in FF + style.display : jQuery.css( elem[ 0 ], "display" ); + + // We don't have any data stored on the element, + // so use "detach" method as fast way to get rid of the element + elem.detach(); + + return display; +} + +/** + * Try to determine the default display value of an element + * @param {String} nodeName + */ +function defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + + // Use the already-created iframe if possible + iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement ); + + // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse + doc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document; + + // Support: IE + doc.write(); + doc.close(); + + display = actualDisplay( nodeName, doc ); + iframe.detach(); + } + + // Store the correct default display + elemdisplay[ nodeName ] = display; + } + + return display; +} + + +(function() { + var shrinkWrapBlocksVal; + + support.shrinkWrapBlocks = function() { + if ( shrinkWrapBlocksVal != null ) { + return shrinkWrapBlocksVal; + } + + // Will be changed later if needed. + shrinkWrapBlocksVal = false; + + // Minified: var b,c,d + var div, body, container; + + body = document.getElementsByTagName( "body" )[ 0 ]; + if ( !body || !body.style ) { + // Test fired too early or in an unsupported environment, exit. + return; + } + + // Setup + div = document.createElement( "div" ); + container = document.createElement( "div" ); + container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; + body.appendChild( container ).appendChild( div ); + + // Support: IE6 + // Check if elements with layout shrink-wrap their children + if ( typeof div.style.zoom !== strundefined ) { + // Reset CSS: box-sizing; display; margin; border + div.style.cssText = + // Support: Firefox<29, Android 2.3 + // Vendor-prefix box-sizing + "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" + + "box-sizing:content-box;display:block;margin:0;border:0;" + + "padding:1px;width:1px;zoom:1"; + div.appendChild( document.createElement( "div" ) ).style.width = "5px"; + shrinkWrapBlocksVal = div.offsetWidth !== 3; + } + + body.removeChild( container ); + + return shrinkWrapBlocksVal; + }; + +})(); +var rmargin = (/^margin/); + +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + + + +var getStyles, curCSS, + rposition = /^(top|right|bottom|left)$/; + +if ( window.getComputedStyle ) { + getStyles = function( elem ) { + // Support: IE<=11+, Firefox<=30+ (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + if ( elem.ownerDocument.defaultView.opener ) { + return elem.ownerDocument.defaultView.getComputedStyle( elem, null ); + } + + return window.getComputedStyle( elem, null ); + }; + + curCSS = function( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is only needed for .css('filter') in IE9, see #12537 + ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined; + + if ( computed ) { + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right + // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + // Support: IE + // IE returns zIndex value as an integer. + return ret === undefined ? + ret : + ret + ""; + }; +} else if ( document.documentElement.currentStyle ) { + getStyles = function( elem ) { + return elem.currentStyle; + }; + + curCSS = function( elem, name, computed ) { + var left, rs, rsLeft, ret, + style = elem.style; + + computed = computed || getStyles( elem ); + ret = computed ? computed[ name ] : undefined; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret == null && style && style[ name ] ) { + ret = style[ name ]; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + // but not position css attributes, as those are proportional to the parent element instead + // and we can't measure the parent instead because it might trigger a "stacking dolls" problem + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { + + // Remember the original values + left = style.left; + rs = elem.runtimeStyle; + rsLeft = rs && rs.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + rs.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ret; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + rs.left = rsLeft; + } + } + + // Support: IE + // IE returns zIndex value as an integer. + return ret === undefined ? + ret : + ret + "" || "auto"; + }; +} + + + + +function addGetHookIf( conditionFn, hookFn ) { + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + var condition = conditionFn(); + + if ( condition == null ) { + // The test was not ready at this point; screw the hook this time + // but check again when needed next time. + return; + } + + if ( condition ) { + // Hook not needed (or it's not possible to use it due to missing dependency), + // remove it. + // Since there are no other hooks for marginRight, remove the whole object. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + + return (this.get = hookFn).apply( this, arguments ); + } + }; +} + + +(function() { + // Minified: var b,c,d,e,f,g, h,i + var div, style, a, pixelPositionVal, boxSizingReliableVal, + reliableHiddenOffsetsVal, reliableMarginRightVal; + + // Setup + div = document.createElement( "div" ); + div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>"; + a = div.getElementsByTagName( "a" )[ 0 ]; + style = a && a.style; + + // Finish early in limited (non-browser) environments + if ( !style ) { + return; + } + + style.cssText = "float:left;opacity:.5"; + + // Support: IE<9 + // Make sure that element opacity exists (as opposed to filter) + support.opacity = style.opacity === "0.5"; + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + support.cssFloat = !!style.cssFloat; + + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + // Support: Firefox<29, Android 2.3 + // Vendor-prefix box-sizing + support.boxSizing = style.boxSizing === "" || style.MozBoxSizing === "" || + style.WebkitBoxSizing === ""; + + jQuery.extend(support, { + reliableHiddenOffsets: function() { + if ( reliableHiddenOffsetsVal == null ) { + computeStyleTests(); + } + return reliableHiddenOffsetsVal; + }, + + boxSizingReliable: function() { + if ( boxSizingReliableVal == null ) { + computeStyleTests(); + } + return boxSizingReliableVal; + }, + + pixelPosition: function() { + if ( pixelPositionVal == null ) { + computeStyleTests(); + } + return pixelPositionVal; + }, + + // Support: Android 2.3 + reliableMarginRight: function() { + if ( reliableMarginRightVal == null ) { + computeStyleTests(); + } + return reliableMarginRightVal; + } + }); + + function computeStyleTests() { + // Minified: var b,c,d,j + var div, body, container, contents; + + body = document.getElementsByTagName( "body" )[ 0 ]; + if ( !body || !body.style ) { + // Test fired too early or in an unsupported environment, exit. + return; + } + + // Setup + div = document.createElement( "div" ); + container = document.createElement( "div" ); + container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; + body.appendChild( container ).appendChild( div ); + + div.style.cssText = + // Support: Firefox<29, Android 2.3 + // Vendor-prefix box-sizing + "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" + + "box-sizing:border-box;display:block;margin-top:1%;top:1%;" + + "border:1px;padding:1px;width:4px;position:absolute"; + + // Support: IE<9 + // Assume reasonable values in the absence of getComputedStyle + pixelPositionVal = boxSizingReliableVal = false; + reliableMarginRightVal = true; + + // Check for getComputedStyle so that this code is not run in IE<9. + if ( window.getComputedStyle ) { + pixelPositionVal = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; + boxSizingReliableVal = + ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + + // Support: Android 2.3 + // Div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container (#3333) + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + contents = div.appendChild( document.createElement( "div" ) ); + + // Reset CSS: box-sizing; display; margin; border; padding + contents.style.cssText = div.style.cssText = + // Support: Firefox<29, Android 2.3 + // Vendor-prefix box-sizing + "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" + + "box-sizing:content-box;display:block;margin:0;border:0;padding:0"; + contents.style.marginRight = contents.style.width = "0"; + div.style.width = "1px"; + + reliableMarginRightVal = + !parseFloat( ( window.getComputedStyle( contents, null ) || {} ).marginRight ); + + div.removeChild( contents ); + } + + // Support: IE8 + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>"; + contents = div.getElementsByTagName( "td" ); + contents[ 0 ].style.cssText = "margin:0;border:0;padding:0;display:none"; + reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0; + if ( reliableHiddenOffsetsVal ) { + contents[ 0 ].style.display = ""; + contents[ 1 ].style.display = "none"; + reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0; + } + + body.removeChild( container ); + } + +})(); + + +// A method for quickly swapping in/out CSS properties to get correct calculations. +jQuery.swap = function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var + ralpha = /alpha\([^)]*\)/i, + ropacity = /opacity\s*=\s*([^)]*)/, + + // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ), + rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ), + + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }, + + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; + + +// return a css property mapped to a potentially vendor prefixed property +function vendorPropName( style, name ) { + + // shortcut for names that are not vendor prefixed + if ( name in style ) { + return name; + } + + // check for vendor prefixed names + var capName = name.charAt(0).toUpperCase() + name.slice(1), + origName = name, + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in style ) { + return name; + } + } + + return origName; +} + +function showHide( elements, show ) { + var display, elem, hidden, + values = [], + index = 0, + length = elements.length; + + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + values[ index ] = jQuery._data( elem, "olddisplay" ); + display = elem.style.display; + if ( show ) { + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !values[ index ] && display === "none" ) { + elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( elem.style.display === "" && isHidden( elem ) ) { + values[ index ] = jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) ); + } + } else { + hidden = isHidden( elem ); + + if ( display && display !== "none" || !hidden ) { + jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) ); + } + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( index = 0; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + if ( !show || elem.style.display === "none" || elem.style.display === "" ) { + elem.style.display = show ? values[ index ] || "" : "none"; + } + } + + return elements; +} + +function setPositiveNumber( elem, value, subtract ) { + var matches = rnumsplit.exec( value ); + return matches ? + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { + var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation + 4 : + // Otherwise initialize for horizontal or vertical properties + name === "width" ? 1 : 0, + + val = 0; + + for ( ; i < 4; i += 2 ) { + // both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); + } + + if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // at this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } else { + // at this point, extra isn't content, so add padding + val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // at this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with offset property, which is equivalent to the border-box value + var valueIsBorderBox = true, + val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + styles = getStyles( elem ), + isBorderBox = support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name, styles ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // we need the check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] ); + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + } + + // use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles + ) + ) + "px"; +} + +jQuery.extend({ + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + // normalize float css property + "float": support.cssFloat ? "cssFloat" : "styleFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + style = elem.style; + + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && (ret = rrelNum.exec( value )) ) { + value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set. See: #7116 + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add 'px' to the (except for certain CSS properties) + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + value += "px"; + } + + // Fixes #8908, it can be done more correctly by specifing setters in cssHooks, + // but it would mean to define eight (for every problematic property) identical functions + if ( !support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { + + // Support: IE + // Swallow errors from 'invalid' CSS values (#5509) + try { + style[ name ] = value; + } catch(e) {} + } + + } else { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var num, val, hooks, + origName = jQuery.camelCase( name ); + + // Make sure that we're working with the right name + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + //convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Return, converting to number if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; + } + return val; + } +}); + +jQuery.each([ "height", "width" ], function( i, name ) { + jQuery.cssHooks[ name ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + // certain elements can have dimension info if we invisibly show them + // however, it must have a current display style that would benefit from this + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ? + jQuery.swap( elem, cssShow, function() { + return getWidthOrHeight( elem, name, extra ); + }) : + getWidthOrHeight( elem, name, extra ); + } + }, + + set: function( elem, value, extra ) { + var styles = extra && getStyles( elem ); + return setPositiveNumber( elem, value, extra ? + augmentWidthOrHeight( + elem, + name, + extra, + support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + styles + ) : 0 + ); + } + }; +}); + +if ( !support.opacity ) { + jQuery.cssHooks.opacity = { + get: function( elem, computed ) { + // IE uses filters for opacity + return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? + ( 0.01 * parseFloat( RegExp.$1 ) ) + "" : + computed ? "1" : ""; + }, + + set: function( elem, value ) { + var style = elem.style, + currentStyle = elem.currentStyle, + opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "", + filter = currentStyle && currentStyle.filter || style.filter || ""; + + // IE has trouble with opacity if it does not have layout + // Force it by setting the zoom level + style.zoom = 1; + + // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652 + // if value === "", then remove inline opacity #12685 + if ( ( value >= 1 || value === "" ) && + jQuery.trim( filter.replace( ralpha, "" ) ) === "" && + style.removeAttribute ) { + + // Setting style.filter to null, "" & " " still leave "filter:" in the cssText + // if "filter:" is present at all, clearType is disabled, we want to avoid this + // style.removeAttribute is IE Only, but so apparently is this code path... + style.removeAttribute( "filter" ); + + // if there is no filter style applied in a css rule or unset inline opacity, we are done + if ( value === "" || currentStyle && !currentStyle.filter ) { + return; + } + } + + // otherwise, set new filter values + style.filter = ralpha.test( filter ) ? + filter.replace( ralpha, opacity ) : + filter + " " + opacity; + } + }; +} + +jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight, + function( elem, computed ) { + if ( computed ) { + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + // Work around by temporarily setting element display to inline-block + return jQuery.swap( elem, { "display": "inline-block" }, + curCSS, [ elem, "marginRight" ] ); + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each({ + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // assumes a single number if not a string + parts = typeof value === "string" ? value.split(" ") : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( !rmargin.test( prefix ) ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +}); + +jQuery.fn.extend({ + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( jQuery.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each(function() { + if ( isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || "swing"; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + if ( tween.elem[ tween.prop ] != null && + (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) { + return tween.elem[ tween.prop ]; + } + + // passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails + // so, simple values such as "10px" are parsed to Float. + // complex values such as "rotate(1rad)" are returned as is. + result = jQuery.css( tween.elem, tween.prop, "" ); + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + // use step hook for back compat - use cssHook if its there - use .style if its + // available and use plain properties where available + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 +// Panic based approach to setting things on disconnected nodes + +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + } +}; + +jQuery.fx = Tween.prototype.init; + +// Back Compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, timerId, + rfxtypes = /^(?:toggle|show|hide)$/, + rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ), + rrun = /queueHooks$/, + animationPrefilters = [ defaultPrefilter ], + tweeners = { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ), + target = tween.cur(), + parts = rfxnum.exec( value ), + unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) && + rfxnum.exec( jQuery.css( tween.elem, prop ) ), + scale = 1, + maxIterations = 20; + + if ( start && start[ 3 ] !== unit ) { + // Trust units reported by jQuery.css + unit = unit || start[ 3 ]; + + // Make sure we update the tween properties later on + parts = parts || []; + + // Iteratively approximate from a nonzero starting point + start = +target || 1; + + do { + // If previous iteration zeroed out, double until we get *something* + // Use a string for doubling factor so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + start = start / scale; + jQuery.style( tween.elem, prop, start + unit ); + + // Update scale, tolerating zero or NaN from tween.cur() + // And breaking the loop if scale is unchanged or perfect, or if we've just had enough + } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations ); + } + + // Update tween properties + if ( parts ) { + start = tween.start = +start || +target || 0; + tween.unit = unit; + // If a +=/-= token was provided, we're doing a relative animation + tween.end = parts[ 1 ] ? + start + ( parts[ 1 ] + 1 ) * parts[ 2 ] : + +parts[ 2 ]; + } + + return tween; + } ] + }; + +// Animations created synchronously will run synchronously +function createFxNow() { + setTimeout(function() { + fxNow = undefined; + }); + return ( fxNow = jQuery.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + attrs = { height: type }, + i = 0; + + // if we include width, step value is 1 to do all cssExpand values, + // if we don't include width, step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4 ; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( (tween = collection[ index ].call( animation, prop, value )) ) { + + // we're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + /* jshint validthis: true */ + var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHidden( elem ), + dataShow = jQuery._data( elem, "fxshow" ); + + // handle queue: false promises + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always(function() { + // doing this makes sure that the complete handler will be called + // before this completes + anim.always(function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + }); + }); + } + + // height/width overflow pass + if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { + // Make sure that nothing sneaks out + // Record all 3 overflow attributes because IE does not + // change the overflow attribute when overflowX and + // overflowY are set to the same value + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Set display property to inline-block for height/width + // animations on inline elements that are having width/height animated + display = jQuery.css( elem, "display" ); + + // Test default display if display is currently "none" + checkDisplay = display === "none" ? + jQuery._data( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display; + + if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) { + + // inline-level elements accept inline-block; + // block-level elements need to be inline with layout + if ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === "inline" ) { + style.display = "inline-block"; + } else { + style.zoom = 1; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + if ( !support.shrinkWrapBlocks() ) { + anim.always(function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + }); + } + } + + // show/hide pass + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.exec( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + + // Any non-fx value stops us from restoring the original display value + } else { + display = undefined; + } + } + + if ( !jQuery.isEmptyObject( orig ) ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = jQuery._data( elem, "fxshow", {} ); + } + + // store state if its toggle - enables .stop().toggle() to "reverse" + if ( toggle ) { + dataShow.hidden = !hidden; + } + if ( hidden ) { + jQuery( elem ).show(); + } else { + anim.done(function() { + jQuery( elem ).hide(); + }); + } + anim.done(function() { + var prop; + jQuery._removeData( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + }); + for ( prop in orig ) { + tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = tween.start; + if ( hidden ) { + tween.end = tween.start; + tween.start = prop === "width" || prop === "height" ? 1 : 0; + } + } + } + + // If this is a noop like .hide().hide(), restore an overwritten display value + } else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) { + style.display = display; + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = jQuery.camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( jQuery.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // not quite $.extend, this wont overwrite keys already present. + // also - reusing 'index' from above because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = animationPrefilters.length, + deferred = jQuery.Deferred().always( function() { + // don't match elem in the :animated selector + delete tick.elem; + }), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ]); + + if ( percent < 1 && length ) { + return remaining; + } else { + deferred.resolveWith( elem, [ animation ] ); + return false; + } + }, + animation = deferred.promise({ + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { specialEasing: {} }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + // if we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // resolve when we played the last frame + // otherwise, reject + if ( gotoEnd ) { + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + }), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length ; index++ ) { + result = animationPrefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( jQuery.isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + }) + ); + + // attach callbacks from options + return animation.progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); +} + +jQuery.Animation = jQuery.extend( Animation, { + tweener: function( props, callback ) { + if ( jQuery.isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.split(" "); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length ; index++ ) { + prop = props[ index ]; + tweeners[ prop ] = tweeners[ prop ] || []; + tweeners[ prop ].unshift( callback ); + } + }, + + prefilter: function( callback, prepend ) { + if ( prepend ) { + animationPrefilters.unshift( callback ); + } else { + animationPrefilters.push( callback ); + } + } +}); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + jQuery.isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing + }; + + opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : + opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; + + // normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( jQuery.isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend({ + fadeTo: function( speed, to, easing, callback ) { + + // show any hidden elements after setting opacity to 0 + return this.filter( isHidden ).css( "opacity", 0 ).show() + + // animate to the value specified + .end().animate({ opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || jQuery._data( this, "finish" ) ) { + anim.stop( true ); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each(function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = jQuery._data( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // start the next in the queue if the last step wasn't forced + // timers currently will call their complete callbacks, which will dequeue + // but only if they were gotoEnd + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + }); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each(function() { + var index, + data = jQuery._data( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // enable finishing flag on private data + data.finish = true; + + // empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // turn off finishing flag + delete data.finish; + }); + } +}); + +jQuery.each([ "toggle", "show", "hide" ], function( i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +}); + +// Generate shortcuts for custom animations +jQuery.each({ + slideDown: genFx("show"), + slideUp: genFx("hide"), + slideToggle: genFx("toggle"), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +}); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + timers = jQuery.timers, + i = 0; + + fxNow = jQuery.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + // Checks the timer has not already been removed + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + if ( timer() ) { + jQuery.fx.start(); + } else { + jQuery.timers.pop(); + } +}; + +jQuery.fx.interval = 13; + +jQuery.fx.start = function() { + if ( !timerId ) { + timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); + } +}; + +jQuery.fx.stop = function() { + clearInterval( timerId ); + timerId = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); +}; + + +(function() { + // Minified: var a,b,c,d,e + var input, div, select, a, opt; + + // Setup + div = document.createElement( "div" ); + div.setAttribute( "className", "t" ); + div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>"; + a = div.getElementsByTagName("a")[ 0 ]; + + // First batch of tests. + select = document.createElement("select"); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName("input")[ 0 ]; + + a.style.cssText = "top:1px"; + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + support.getSetAttribute = div.className !== "t"; + + // Get the style information from getAttribute + // (IE uses .cssText instead) + support.style = /top/.test( a.getAttribute("style") ); + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + support.hrefNormalized = a.getAttribute("href") === "/a"; + + // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere) + support.checkOn = !!input.value; + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + support.optSelected = opt.selected; + + // Tests for enctype support on a form (#6743) + support.enctype = !!document.createElement("form").enctype; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Support: IE8 only + // Check if we can trust getAttribute("value") + input = document.createElement( "input" ); + input.setAttribute( "value", "" ); + support.input = input.getAttribute( "value" ) === ""; + + // Check if an input maintains its value after becoming a radio + input.value = "t"; + input.setAttribute( "type", "radio" ); + support.radioValue = input.value === "t"; +})(); + + +var rreturn = /\r/g; + +jQuery.fn.extend({ + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + // Support: IE10-11+ + // option.text throws exceptions (#14686, #14858) + jQuery.trim( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one" || index < 0, + values = one ? null : [], + max = one ? index + 1 : options.length, + i = index < 0 ? + max : + one ? index : 0; + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // oldIE doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + // Don't return options that are disabled or in a disabled optgroup + ( support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && + ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + if ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) >= 0 ) { + + // Support: IE6 + // When new option element is added to select box we need to + // force reflow of newly added node in order to workaround delay + // of initialization properties + try { + option.selected = optionSet = true; + + } catch ( _ ) { + + // Will be executed only in IE6 + option.scrollHeight; + } + + } else { + option.selected = false; + } + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + + return options; + } + } + } +}); + +// Radios and checkboxes getter/setter +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + // Support: Webkit + // "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + }; + } +}); + + + + +var nodeHook, boolHook, + attrHandle = jQuery.expr.attrHandle, + ruseDefault = /^(?:checked|selected)$/i, + getSetAttribute = support.getSetAttribute, + getSetInput = support.input; + +jQuery.fn.extend({ + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + } +}); + +jQuery.extend({ + attr: function( elem, name, value ) { + var hooks, ret, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === strundefined ) { + return jQuery.prop( elem, name, value ); + } + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + + } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, value + "" ); + return value; + } + + } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var name, propName, + i = 0, + attrNames = value && value.match( rnotwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( (name = attrNames[i++]) ) { + propName = jQuery.propFix[ name ] || name; + + // Boolean attributes get special treatment (#10870) + if ( jQuery.expr.match.bool.test( name ) ) { + // Set corresponding property to false + if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { + elem[ propName ] = false; + // Support: IE<9 + // Also clear defaultChecked/defaultSelected (if appropriate) + } else { + elem[ jQuery.camelCase( "default-" + name ) ] = + elem[ propName ] = false; + } + + // See #9699 for explanation of this approach (setting first, then removal) + } else { + jQuery.attr( elem, name, "" ); + } + + elem.removeAttribute( getSetAttribute ? name : propName ); + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to default in case type is set after value during creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + } +}); + +// Hook for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { + // IE<8 needs the *property* name + elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name ); + + // Use defaultChecked and defaultSelected for oldIE + } else { + elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true; + } + + return name; + } +}; + +// Retrieve booleans specially +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { + + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ? + function( elem, name, isXML ) { + var ret, handle; + if ( !isXML ) { + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ name ]; + attrHandle[ name ] = ret; + ret = getter( elem, name, isXML ) != null ? + name.toLowerCase() : + null; + attrHandle[ name ] = handle; + } + return ret; + } : + function( elem, name, isXML ) { + if ( !isXML ) { + return elem[ jQuery.camelCase( "default-" + name ) ] ? + name.toLowerCase() : + null; + } + }; +}); + +// fix oldIE attroperties +if ( !getSetInput || !getSetAttribute ) { + jQuery.attrHooks.value = { + set: function( elem, value, name ) { + if ( jQuery.nodeName( elem, "input" ) ) { + // Does not return so that setAttribute is also used + elem.defaultValue = value; + } else { + // Use nodeHook if defined (#1954); otherwise setAttribute is fine + return nodeHook && nodeHook.set( elem, value, name ); + } + } + }; +} + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = { + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + elem.setAttributeNode( + (ret = elem.ownerDocument.createAttribute( name )) + ); + } + + ret.value = value += ""; + + // Break association with cloned elements by also using setAttribute (#9646) + if ( name === "value" || value === elem.getAttribute( name ) ) { + return value; + } + } + }; + + // Some attributes are constructed with empty-string values when not defined + attrHandle.id = attrHandle.name = attrHandle.coords = + function( elem, name, isXML ) { + var ret; + if ( !isXML ) { + return (ret = elem.getAttributeNode( name )) && ret.value !== "" ? + ret.value : + null; + } + }; + + // Fixing value retrieval on a button requires this module + jQuery.valHooks.button = { + get: function( elem, name ) { + var ret = elem.getAttributeNode( name ); + if ( ret && ret.specified ) { + return ret.value; + } + }, + set: nodeHook.set + }; + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + set: function( elem, value, name ) { + nodeHook.set( elem, value === "" ? false : value, name ); + } + }; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }; + }); +} + +if ( !support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Note: IE uppercases css property names, but if we were to .toLowerCase() + // .cssText, that would destroy case senstitivity in URL's, like in "background" + return elem.style.cssText || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = value + "" ); + } + }; +} + + + + +var rfocusable = /^(?:input|select|textarea|button|object)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend({ + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + } +}); + +jQuery.extend({ + propFix: { + "for": "htmlFor", + "class": "className" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ? + ret : + ( elem[ name ] = value ); + + } else { + return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ? + ret : + elem[ name ]; + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + return tabindex ? + parseInt( tabindex, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + -1; + } + } + } +}); + +// Some attributes require a special call on IE +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !support.hrefNormalized ) { + // href/src property should get the full normalized URL (#10299/#12915) + jQuery.each([ "href", "src" ], function( i, name ) { + jQuery.propHooks[ name ] = { + get: function( elem ) { + return elem.getAttribute( name, 4 ); + } + }; + }); +} + +// Support: Safari, IE9+ +// mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }; +} + +jQuery.each([ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +}); + +// IE6/7 call enctype encoding +if ( !support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + + + + +var rclass = /[\t\r\n\f]/g; + +jQuery.fn.extend({ + addClass: function( value ) { + var classes, elem, cur, clazz, j, finalValue, + i = 0, + len = this.length, + proceed = typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call( this, j, this.className ) ); + }); + } + + if ( proceed ) { + // The disjunction here is for better compressibility (see removeClass) + classes = ( value || "" ).match( rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + " " + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // only assign if different to avoid unneeded rendering. + finalValue = jQuery.trim( cur ); + if ( elem.className !== finalValue ) { + elem.className = finalValue; + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, clazz, j, finalValue, + i = 0, + len = this.length, + proceed = arguments.length === 0 || typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call( this, j, this.className ) ); + }); + } + if ( proceed ) { + classes = ( value || "" ).match( rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + "" + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // only assign if different to avoid unneeded rendering. + finalValue = value ? jQuery.trim( cur ) : ""; + if ( elem.className !== finalValue ) { + elem.className = finalValue; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value; + + if ( typeof stateVal === "boolean" && type === "string" ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + classNames = value.match( rnotwhite ) || []; + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( type === strundefined || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // If the element has a class name or if we're passed "false", + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { + return true; + } + } + + return false; + } +}); + + + + +// Return jQuery for attributes-only inclusion + + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; +}); + +jQuery.fn.extend({ + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); + } +}); + + +var nonce = jQuery.now(); + +var rquery = (/\?/); + + + +var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g; + +jQuery.parseJSON = function( data ) { + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + // Support: Android 2.3 + // Workaround failure to string-cast null input + return window.JSON.parse( data + "" ); + } + + var requireNonComma, + depth = null, + str = jQuery.trim( data + "" ); + + // Guard against invalid (and possibly dangerous) input by ensuring that nothing remains + // after removing valid tokens + return str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) { + + // Force termination if we see a misplaced comma + if ( requireNonComma && comma ) { + depth = 0; + } + + // Perform no more replacements after returning to outermost depth + if ( depth === 0 ) { + return token; + } + + // Commas must not follow "[", "{", or "," + requireNonComma = open || comma; + + // Determine new depth + // array/object open ("[" or "{"): depth += true - false (increment) + // array/object close ("]" or "}"): depth += false - true (decrement) + // other cases ("," or primitive): depth += true - true (numeric cast) + depth += !close - !open; + + // Remove this token + return ""; + }) ) ? + ( Function( "return " + str ) )() : + jQuery.error( "Invalid JSON: " + data ); +}; + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data, "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; +}; + + +var + // Document location + ajaxLocParts, + ajaxLocation, + + rhash = /#.*$/, + rts = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat("*"); + +// #8138, IE may throw an exception when accessing +// a field from window.location if document.domain has been set +try { + ajaxLocation = location.href; +} catch( e ) { + // Use the href attribute of an A element + // since IE will modify it given document.location + ajaxLocation = document.createElement( "a" ); + ajaxLocation.href = ""; + ajaxLocation = ajaxLocation.href; +} + +// Segment location into parts +ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || []; + + if ( jQuery.isFunction( func ) ) { + // For each dataType in the dataTypeExpression + while ( (dataType = dataTypes[i++]) ) { + // Prepend if requested + if ( dataType.charAt( 0 ) === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + (structure[ dataType ] = structure[ dataType ] || []).unshift( func ); + + // Otherwise append + } else { + (structure[ dataType ] = structure[ dataType ] || []).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + }); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var deep, key, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + var firstDataType, ct, finalDataType, type, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader("Content-Type"); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s[ "throws" ] ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend({ + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: ajaxLocation, + type: "GET", + isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /xml/, + html: /html/, + json: /json/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": jQuery.parseJSON, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var // Cross-domain detection vars + parts, + // Loop variable + i, + // URL without anti-cache param + cacheURL, + // Response headers as string + responseHeadersString, + // timeout handle + timeoutTimer, + + // To know if global events are to be dispatched + fireGlobals, + + transport, + // Response headers + responseHeaders, + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + // Callbacks context + callbackContext = s.context || s, + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks("once memory"), + // Status-dependent callbacks + statusCode = s.statusCode || {}, + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + // The jqXHR state + state = 0, + // Default abort message + strAbort = "canceled", + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( state === 2 ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( (match = rheaders.exec( responseHeadersString )) ) { + responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; + } + } + match = responseHeaders[ key.toLowerCase() ]; + } + return match == null ? null : match; + }, + + // Raw string + getAllResponseHeaders: function() { + return state === 2 ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + var lname = name.toLowerCase(); + if ( !state ) { + name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( !state ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( state < 2 ) { + for ( code in map ) { + // Lazy-add the new callback in a way that preserves old ones + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } else { + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ).complete = completeDeferred.add; + jqXHR.success = jqXHR.done; + jqXHR.error = jqXHR.fail; + + // Remove hash character (#7531: and string promotion) + // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ]; + + // A cross-domain request is in order when we have a protocol:host:port mismatch + if ( s.crossDomain == null ) { + parts = rurl.exec( s.url.toLowerCase() ); + s.crossDomain = !!( parts && + ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || + ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !== + ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) ) + ); + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( state === 2 ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger("ajaxStart"); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + cacheURL = s.url; + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // If data is available, append data to url + if ( s.data ) { + cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data ); + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add anti-cache in url if needed + if ( s.cache === false ) { + s.url = rts.test( cacheURL ) ? + + // If there is already a '_' parameter, set its value + cacheURL.replace( rts, "$1_=" + nonce++ ) : + + // Otherwise add one to the end + cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++; + } + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? + s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { + // Abort if not done already and return + return jqXHR.abort(); + } + + // aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + for ( i in { success: 1, error: 1, complete: 1 } ) { + jqXHR[ i ]( s[ i ] ); + } + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = setTimeout(function() { + jqXHR.abort("timeout"); + }, s.timeout ); + } + + try { + state = 1; + transport.send( requestHeaders, done ); + } catch ( e ) { + // Propagate exception as error if not done + if ( state < 2 ) { + done( -1, e ); + // Simply rethrow otherwise + } else { + throw e; + } + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Called once + if ( state === 2 ) { + return; + } + + // State is "done" now + state = 2; + + // Clear timeout if it exists + if ( timeoutTimer ) { + clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader("Last-Modified"); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader("etag"); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + // We extract error from statusText + // then normalize statusText and status for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger("ajaxStop"); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +}); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + // shift arguments if data argument was omitted + if ( jQuery.isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + return jQuery.ajax({ + url: url, + type: method, + dataType: type, + data: data, + success: callback + }); + }; +}); + + +jQuery._evalUrl = function( url ) { + return jQuery.ajax({ + url: url, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); +}; + + +jQuery.fn.extend({ + wrapAll: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); + }); + } + + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + + if ( this[0].parentNode ) { + wrap.insertBefore( this[0] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { + elem = elem.firstChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function(i) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + } +}); + + +jQuery.expr.filters.hidden = function( elem ) { + // Support: Opera <= 12.12 + // Opera reports offsetWidths and offsetHeights less than zero on some elements + return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 || + (!support.reliableHiddenOffsets() && + ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none"); +}; + +jQuery.expr.filters.visible = function( elem ) { + return !jQuery.expr.filters.hidden( elem ); +}; + + + + +var r20 = /%20/g, + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( jQuery.isArray( obj ) ) { + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + // Item is non-scalar (array or object), encode its numeric index. + buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); + } + }); + + } else if ( !traditional && jQuery.type( obj ) === "object" ) { + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, value ) { + // If value is a function, invoke it and return its value + value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); + s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); + }; + + // Set traditional to true for jQuery <= 1.3.2 behavior. + if ( traditional === undefined ) { + traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + }); + + } else { + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ).replace( r20, "+" ); +}; + +jQuery.fn.extend({ + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map(function() { + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + }) + .filter(function() { + var type = this.type; + // Use .is(":disabled") so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + }) + .map(function( i, elem ) { + var val = jQuery( this ).val(); + + return val == null ? + null : + jQuery.isArray( val ) ? + jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }) : + { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }).get(); + } +}); + + +// Create the request object +// (This is still attached to ajaxSettings for backward compatibility) +jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ? + // Support: IE6+ + function() { + + // XHR cannot access local files, always use ActiveX for that case + return !this.isLocal && + + // Support: IE7-8 + // oldIE XHR does not support non-RFC2616 methods (#13240) + // See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx + // and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9 + // Although this check for six methods instead of eight + // since IE also does not support "trace" and "connect" + /^(get|post|head|put|delete|options)$/i.test( this.type ) && + + createStandardXHR() || createActiveXHR(); + } : + // For all other browsers, use the standard XMLHttpRequest object + createStandardXHR; + +var xhrId = 0, + xhrCallbacks = {}, + xhrSupported = jQuery.ajaxSettings.xhr(); + +// Support: IE<10 +// Open requests must be manually aborted on unload (#5280) +// See https://support.microsoft.com/kb/2856746 for more info +if ( window.attachEvent ) { + window.attachEvent( "onunload", function() { + for ( var key in xhrCallbacks ) { + xhrCallbacks[ key ]( undefined, true ); + } + }); +} + +// Determine support properties +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +xhrSupported = support.ajax = !!xhrSupported; + +// Create transport if the browser can provide an xhr +if ( xhrSupported ) { + + jQuery.ajaxTransport(function( options ) { + // Cross domain only allowed if supported through XMLHttpRequest + if ( !options.crossDomain || support.cors ) { + + var callback; + + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(), + id = ++xhrId; + + // Open the socket + xhr.open( options.type, options.url, options.async, options.username, options.password ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers["X-Requested-With"] ) { + headers["X-Requested-With"] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + // Support: IE<9 + // IE's ActiveXObject throws a 'Type Mismatch' exception when setting + // request header to a null-value. + // + // To keep consistent with other XHR implementations, cast the value + // to string and ignore `undefined`. + if ( headers[ i ] !== undefined ) { + xhr.setRequestHeader( i, headers[ i ] + "" ); + } + } + + // Do send the request + // This may raise an exception which is actually + // handled in jQuery.ajax (so no try/catch here) + xhr.send( ( options.hasContent && options.data ) || null ); + + // Listener + callback = function( _, isAbort ) { + var status, statusText, responses; + + // Was never called and is aborted or complete + if ( callback && ( isAbort || xhr.readyState === 4 ) ) { + // Clean up + delete xhrCallbacks[ id ]; + callback = undefined; + xhr.onreadystatechange = jQuery.noop; + + // Abort manually if needed + if ( isAbort ) { + if ( xhr.readyState !== 4 ) { + xhr.abort(); + } + } else { + responses = {}; + status = xhr.status; + + // Support: IE<10 + // Accessing binary-data responseText throws an exception + // (#11426) + if ( typeof xhr.responseText === "string" ) { + responses.text = xhr.responseText; + } + + // Firefox throws an exception when accessing + // statusText for faulty cross-domain requests + try { + statusText = xhr.statusText; + } catch( e ) { + // We normalize with Webkit giving an empty statusText + statusText = ""; + } + + // Filter status for non standard behaviors + + // If the request is local and we have data: assume a success + // (success with no data won't get notified, that's the best we + // can do given current implementations) + if ( !status && options.isLocal && !options.crossDomain ) { + status = responses.text ? 200 : 404; + // IE - #1450: sometimes returns 1223 when it should be 204 + } else if ( status === 1223 ) { + status = 204; + } + } + } + + // Call complete if needed + if ( responses ) { + complete( status, statusText, responses, xhr.getAllResponseHeaders() ); + } + }; + + if ( !options.async ) { + // if we're in sync mode we fire the callback + callback(); + } else if ( xhr.readyState === 4 ) { + // (IE6 & IE7) if it's in cache and has been + // retrieved directly we need to fire the callback + setTimeout( callback ); + } else { + // Add to the list of active xhr callbacks + xhr.onreadystatechange = xhrCallbacks[ id ] = callback; + } + }, + + abort: function() { + if ( callback ) { + callback( undefined, true ); + } + } + }; + } + }); +} + +// Functions to create xhrs +function createStandardXHR() { + try { + return new window.XMLHttpRequest(); + } catch( e ) {} +} + +function createActiveXHR() { + try { + return new window.ActiveXObject( "Microsoft.XMLHTTP" ); + } catch( e ) {} +} + + + + +// Install script dataType +jQuery.ajaxSetup({ + accepts: { + script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /(?:java|ecma)script/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +}); + +// Handle cache's special case and global +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + s.global = false; + } +}); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function(s) { + + // This transport only deals with cross domain requests + if ( s.crossDomain ) { + + var script, + head = document.head || jQuery("head")[0] || document.documentElement; + + return { + + send: function( _, callback ) { + + script = document.createElement("script"); + + script.async = true; + + if ( s.scriptCharset ) { + script.charset = s.scriptCharset; + } + + script.src = s.url; + + // Attach handlers for all browsers + script.onload = script.onreadystatechange = function( _, isAbort ) { + + if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { + + // Handle memory leak in IE + script.onload = script.onreadystatechange = null; + + // Remove the script + if ( script.parentNode ) { + script.parentNode.removeChild( script ); + } + + // Dereference the script + script = null; + + // Callback if not abort + if ( !isAbort ) { + callback( 200, "success" ); + } + } + }; + + // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending + // Use native DOM manipulation to avoid our domManip AJAX trickery + head.insertBefore( script, head.firstChild ); + }, + + abort: function() { + if ( script ) { + script.onload( undefined, true ); + } + } + }; + } +}); + + + + +var oldCallbacks = [], + rjsonp = /(=)\?(?=&|$)|\?\?/; + +// Default jsonp settings +jQuery.ajaxSetup({ + jsonp: "callback", + jsonpCallback: function() { + var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); + this[ callback ] = true; + return callback; + } +}); + +// Detect, normalize options and install callbacks for jsonp requests +jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { + + var callbackName, overwritten, responseContainer, + jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? + "url" : + typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data" + ); + + // Handle iff the expected data type is "jsonp" or we have a parameter to set + if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { + + // Get callback name, remembering preexisting value associated with it + callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? + s.jsonpCallback() : + s.jsonpCallback; + + // Insert callback into url or form data + if ( jsonProp ) { + s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); + } else if ( s.jsonp !== false ) { + s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; + } + + // Use data converter to retrieve json after script execution + s.converters["script json"] = function() { + if ( !responseContainer ) { + jQuery.error( callbackName + " was not called" ); + } + return responseContainer[ 0 ]; + }; + + // force json dataType + s.dataTypes[ 0 ] = "json"; + + // Install callback + overwritten = window[ callbackName ]; + window[ callbackName ] = function() { + responseContainer = arguments; + }; + + // Clean-up function (fires after converters) + jqXHR.always(function() { + // Restore preexisting value + window[ callbackName ] = overwritten; + + // Save back as free + if ( s[ callbackName ] ) { + // make sure that re-using the options doesn't screw things around + s.jsonpCallback = originalSettings.jsonpCallback; + + // save the callback name for future use + oldCallbacks.push( callbackName ); + } + + // Call if it was a function and we have a response + if ( responseContainer && jQuery.isFunction( overwritten ) ) { + overwritten( responseContainer[ 0 ] ); + } + + responseContainer = overwritten = undefined; + }); + + // Delegate to script + return "script"; + } +}); + + + + +// data: string of html +// context (optional): If specified, the fragment will be created in this context, defaults to document +// keepScripts (optional): If true, will include scripts passed in the html string +jQuery.parseHTML = function( data, context, keepScripts ) { + if ( !data || typeof data !== "string" ) { + return null; + } + if ( typeof context === "boolean" ) { + keepScripts = context; + context = false; + } + context = context || document; + + var parsed = rsingleTag.exec( data ), + scripts = !keepScripts && []; + + // Single tag + if ( parsed ) { + return [ context.createElement( parsed[1] ) ]; + } + + parsed = jQuery.buildFragment( [ data ], context, scripts ); + + if ( scripts && scripts.length ) { + jQuery( scripts ).remove(); + } + + return jQuery.merge( [], parsed.childNodes ); +}; + + +// Keep a copy of the old load method +var _load = jQuery.fn.load; + +/** + * Load a url into a page + */ +jQuery.fn.load = function( url, params, callback ) { + if ( typeof url !== "string" && _load ) { + return _load.apply( this, arguments ); + } + + var selector, response, type, + self = this, + off = url.indexOf(" "); + + if ( off >= 0 ) { + selector = jQuery.trim( url.slice( off, url.length ) ); + url = url.slice( 0, off ); + } + + // If it's a function + if ( jQuery.isFunction( params ) ) { + + // We assume that it's the callback + callback = params; + params = undefined; + + // Otherwise, build a param string + } else if ( params && typeof params === "object" ) { + type = "POST"; + } + + // If we have elements to modify, make the request + if ( self.length > 0 ) { + jQuery.ajax({ + url: url, + + // if "type" variable is undefined, then "GET" method will be used + type: type, + dataType: "html", + data: params + }).done(function( responseText ) { + + // Save response for use in complete callback + response = arguments; + + self.html( selector ? + + // If a selector was specified, locate the right elements in a dummy div + // Exclude scripts to avoid IE 'Permission Denied' errors + jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) : + + // Otherwise use the full result + responseText ); + + }).complete( callback && function( jqXHR, status ) { + self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); + }); + } + + return this; +}; + + + + +// Attach a bunch of functions for handling common AJAX events +jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) { + jQuery.fn[ type ] = function( fn ) { + return this.on( type, fn ); + }; +}); + + + + +jQuery.expr.filters.animated = function( elem ) { + return jQuery.grep(jQuery.timers, function( fn ) { + return elem === fn.elem; + }).length; +}; + + + + + +var docElem = window.document.documentElement; + +/** + * Gets a window from an element + */ +function getWindow( elem ) { + return jQuery.isWindow( elem ) ? + elem : + elem.nodeType === 9 ? + elem.defaultView || elem.parentWindow : + false; +} + +jQuery.offset = { + setOffset: function( elem, options, i ) { + var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, + position = jQuery.css( elem, "position" ), + curElem = jQuery( elem ), + props = {}; + + // set position first, in-case top/left are set even on static elem + if ( position === "static" ) { + elem.style.position = "relative"; + } + + curOffset = curElem.offset(); + curCSSTop = jQuery.css( elem, "top" ); + curCSSLeft = jQuery.css( elem, "left" ); + calculatePosition = ( position === "absolute" || position === "fixed" ) && + jQuery.inArray("auto", [ curCSSTop, curCSSLeft ] ) > -1; + + // need to be able to calculate position if either top or left is auto and position is either absolute or fixed + if ( calculatePosition ) { + curPosition = curElem.position(); + curTop = curPosition.top; + curLeft = curPosition.left; + } else { + curTop = parseFloat( curCSSTop ) || 0; + curLeft = parseFloat( curCSSLeft ) || 0; + } + + if ( jQuery.isFunction( options ) ) { + options = options.call( elem, i, curOffset ); + } + + if ( options.top != null ) { + props.top = ( options.top - curOffset.top ) + curTop; + } + if ( options.left != null ) { + props.left = ( options.left - curOffset.left ) + curLeft; + } + + if ( "using" in options ) { + options.using.call( elem, props ); + } else { + curElem.css( props ); + } + } +}; + +jQuery.fn.extend({ + offset: function( options ) { + if ( arguments.length ) { + return options === undefined ? + this : + this.each(function( i ) { + jQuery.offset.setOffset( this, options, i ); + }); + } + + var docElem, win, + box = { top: 0, left: 0 }, + elem = this[ 0 ], + doc = elem && elem.ownerDocument; + + if ( !doc ) { + return; + } + + docElem = doc.documentElement; + + // Make sure it's not a disconnected DOM node + if ( !jQuery.contains( docElem, elem ) ) { + return box; + } + + // If we don't have gBCR, just use 0,0 rather than error + // BlackBerry 5, iOS 3 (original iPhone) + if ( typeof elem.getBoundingClientRect !== strundefined ) { + box = elem.getBoundingClientRect(); + } + win = getWindow( doc ); + return { + top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ), + left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 ) + }; + }, + + position: function() { + if ( !this[ 0 ] ) { + return; + } + + var offsetParent, offset, + parentOffset = { top: 0, left: 0 }, + elem = this[ 0 ]; + + // fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent + if ( jQuery.css( elem, "position" ) === "fixed" ) { + // we assume that getBoundingClientRect is available when computed position is fixed + offset = elem.getBoundingClientRect(); + } else { + // Get *real* offsetParent + offsetParent = this.offsetParent(); + + // Get correct offsets + offset = this.offset(); + if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) { + parentOffset = offsetParent.offset(); + } + + // Add offsetParent borders + parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ); + parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true ); + } + + // Subtract parent offsets and element margins + // note: when an element has margin: auto the offsetLeft and marginLeft + // are the same in Safari causing offset.left to incorrectly be 0 + return { + top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), + left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true) + }; + }, + + offsetParent: function() { + return this.map(function() { + var offsetParent = this.offsetParent || docElem; + + while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) { + offsetParent = offsetParent.offsetParent; + } + return offsetParent || docElem; + }); + } +}); + +// Create scrollLeft and scrollTop methods +jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { + var top = /Y/.test( prop ); + + jQuery.fn[ method ] = function( val ) { + return access( this, function( elem, method, val ) { + var win = getWindow( elem ); + + if ( val === undefined ) { + return win ? (prop in win) ? win[ prop ] : + win.document.documentElement[ method ] : + elem[ method ]; + } + + if ( win ) { + win.scrollTo( + !top ? val : jQuery( win ).scrollLeft(), + top ? val : jQuery( win ).scrollTop() + ); + + } else { + elem[ method ] = val; + } + }, method, val, arguments.length, null ); + }; +}); + +// Add the top/left cssHooks using jQuery.fn.position +// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 +// getComputedStyle returns percent when specified for top/left/bottom/right +// rather than make the css module depend on the offset module, we just check for it here +jQuery.each( [ "top", "left" ], function( i, prop ) { + jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, + function( elem, computed ) { + if ( computed ) { + computed = curCSS( elem, prop ); + // if curCSS returns percentage, fallback to offset + return rnumnonpx.test( computed ) ? + jQuery( elem ).position()[ prop ] + "px" : + computed; + } + } + ); +}); + + +// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods +jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { + jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { + // margin is only for outerHeight, outerWidth + jQuery.fn[ funcName ] = function( margin, value ) { + var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), + extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); + + return access( this, function( elem, type, value ) { + var doc; + + if ( jQuery.isWindow( elem ) ) { + // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there + // isn't a whole lot we can do. See pull request at this URL for discussion: + // https://github.com/jquery/jquery/pull/764 + return elem.document.documentElement[ "client" + name ]; + } + + // Get document width or height + if ( elem.nodeType === 9 ) { + doc = elem.documentElement; + + // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest + // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it. + return Math.max( + elem.body[ "scroll" + name ], doc[ "scroll" + name ], + elem.body[ "offset" + name ], doc[ "offset" + name ], + doc[ "client" + name ] + ); + } + + return value === undefined ? + // Get width or height on the element, requesting but not forcing parseFloat + jQuery.css( elem, type, extra ) : + + // Set width or height on the element + jQuery.style( elem, type, value, extra ); + }, type, chainable ? margin : undefined, chainable, null ); + }; + }); +}); + + +// The number of elements contained in the matched element set +jQuery.fn.size = function() { + return this.length; +}; + +jQuery.fn.andSelf = jQuery.fn.addBack; + + + + +// Register as a named AMD module, since jQuery can be concatenated with other +// files that may use define, but not via a proper concatenation script that +// understands anonymous AMD modules. A named AMD is safest and most robust +// way to register. Lowercase jquery is used because AMD module names are +// derived from file names, and jQuery is normally delivered in a lowercase +// file name. Do this after creating the global so that if an AMD module wants +// to call noConflict to hide this version of jQuery, it will work. + +// Note that for maximum portability, libraries that are not jQuery should +// declare themselves as anonymous modules, and avoid setting a global if an +// AMD loader is present. jQuery is a special case. For more information, see +// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon + +if ( typeof define === "function" && define.amd ) { + define( "jquery", [], function() { + return jQuery; + }); +} + + + + +var + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$; + +jQuery.noConflict = function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; +}; + +// Expose jQuery and $ identifiers, even in +// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557) +// and CommonJS for browser emulators (#13566) +if ( typeof noGlobal === strundefined ) { + window.jQuery = window.$ = jQuery; +} + + + + +return jQuery; + +})); +(function($, undefined) { + +/** + * Unobtrusive scripting adapter for jQuery + * https://github.com/rails/jquery-ujs + * + * Requires jQuery 1.8.0 or later. + * + * Released under the MIT license + * + */ + + // Cut down on the number of issues from people inadvertently including jquery_ujs twice + // by detecting and raising an error when it happens. + 'use strict'; + + if ( $.rails !== undefined ) { + $.error('jquery-ujs has already been loaded!'); + } + + // Shorthand to make it a little easier to call public rails functions from within rails.js + var rails; + var $document = $(document); + + $.rails = rails = { + // Link elements bound by jquery-ujs + linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote], a[data-disable-with], a[data-disable]', + + // Button elements bound by jquery-ujs + buttonClickSelector: 'button[data-remote]:not(form button), button[data-confirm]:not(form button)', + + // Select elements bound by jquery-ujs + inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]', + + // Form elements bound by jquery-ujs + formSubmitSelector: 'form', + + // Form input elements bound by jquery-ujs + formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])', + + // Form input elements disabled during form submission + disableSelector: 'input[data-disable-with]:enabled, button[data-disable-with]:enabled, textarea[data-disable-with]:enabled, input[data-disable]:enabled, button[data-disable]:enabled, textarea[data-disable]:enabled', + + // Form input elements re-enabled after form submission + enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled', + + // Form required input elements + requiredInputSelector: 'input[name][required]:not([disabled]),textarea[name][required]:not([disabled])', + + // Form file input elements + fileInputSelector: 'input[type=file]:not([disabled])', + + // Link onClick disable selector with possible reenable after remote submission + linkDisableSelector: 'a[data-disable-with], a[data-disable]', + + // Button onClick disable selector with possible reenable after remote submission + buttonDisableSelector: 'button[data-remote][data-disable-with], button[data-remote][data-disable]', + + // Up-to-date Cross-Site Request Forgery token + csrfToken: function() { + return $('meta[name=csrf-token]').attr('content'); + }, + + // URL param that must contain the CSRF token + csrfParam: function() { + return $('meta[name=csrf-param]').attr('content'); + }, + + // Make sure that every Ajax request sends the CSRF token + CSRFProtection: function(xhr) { + var token = rails.csrfToken(); + if (token) xhr.setRequestHeader('X-CSRF-Token', token); + }, + + // making sure that all forms have actual up-to-date token(cached forms contain old one) + refreshCSRFTokens: function(){ + $('form input[name="' + rails.csrfParam() + '"]').val(rails.csrfToken()); + }, + + // Triggers an event on an element and returns false if the event result is false + fire: function(obj, name, data) { + var event = $.Event(name); + obj.trigger(event, data); + return event.result !== false; + }, + + // Default confirm dialog, may be overridden with custom confirm dialog in $.rails.confirm + confirm: function(message) { + return confirm(message); + }, + + // Default ajax function, may be overridden with custom function in $.rails.ajax + ajax: function(options) { + return $.ajax(options); + }, + + // Default way to get an element's href. May be overridden at $.rails.href. + href: function(element) { + return element[0].href; + }, + + // Checks "data-remote" if true to handle the request through a XHR request. + isRemote: function(element) { + return element.data('remote') !== undefined && element.data('remote') !== false; + }, + + // Submits "remote" forms and links with ajax + handleRemote: function(element) { + var method, url, data, withCredentials, dataType, options; + + if (rails.fire(element, 'ajax:before')) { + withCredentials = element.data('with-credentials') || null; + dataType = element.data('type') || ($.ajaxSettings && $.ajaxSettings.dataType); + + if (element.is('form')) { + method = element.attr('method'); + url = element.attr('action'); + data = element.serializeArray(); + // memoized value from clicked submit button + var button = element.data('ujs:submit-button'); + if (button) { + data.push(button); + element.data('ujs:submit-button', null); + } + } else if (element.is(rails.inputChangeSelector)) { + method = element.data('method'); + url = element.data('url'); + data = element.serialize(); + if (element.data('params')) data = data + '&' + element.data('params'); + } else if (element.is(rails.buttonClickSelector)) { + method = element.data('method') || 'get'; + url = element.data('url'); + data = element.serialize(); + if (element.data('params')) data = data + '&' + element.data('params'); + } else { + method = element.data('method'); + url = rails.href(element); + data = element.data('params') || null; + } + + options = { + type: method || 'GET', data: data, dataType: dataType, + // stopping the "ajax:beforeSend" event will cancel the ajax request + beforeSend: function(xhr, settings) { + if (settings.dataType === undefined) { + xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script); + } + if (rails.fire(element, 'ajax:beforeSend', [xhr, settings])) { + element.trigger('ajax:send', xhr); + } else { + return false; + } + }, + success: function(data, status, xhr) { + element.trigger('ajax:success', [data, status, xhr]); + }, + complete: function(xhr, status) { + element.trigger('ajax:complete', [xhr, status]); + }, + error: function(xhr, status, error) { + element.trigger('ajax:error', [xhr, status, error]); + }, + crossDomain: rails.isCrossDomain(url) + }; + + // There is no withCredentials for IE6-8 when + // "Enable native XMLHTTP support" is disabled + if (withCredentials) { + options.xhrFields = { + withCredentials: withCredentials + }; + } + + // Only pass url to `ajax` options if not blank + if (url) { options.url = url; } + + return rails.ajax(options); + } else { + return false; + } + }, + + // Determines if the request is a cross domain request. + isCrossDomain: function(url) { + var originAnchor = document.createElement('a'); + originAnchor.href = location.href; + var urlAnchor = document.createElement('a'); + + try { + urlAnchor.href = url; + // This is a workaround to a IE bug. + urlAnchor.href = urlAnchor.href; + + // If URL protocol is false or is a string containing a single colon + // *and* host are false, assume it is not a cross-domain request + // (should only be the case for IE7 and IE compatibility mode). + // Otherwise, evaluate protocol and host of the URL against the origin + // protocol and host. + return !(((!urlAnchor.protocol || urlAnchor.protocol === ':') && !urlAnchor.host) || + (originAnchor.protocol + '//' + originAnchor.host === + urlAnchor.protocol + '//' + urlAnchor.host)); + } catch (e) { + // If there is an error parsing the URL, assume it is crossDomain. + return true; + } + }, + + // Handles "data-method" on links such as: + // <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a> + handleMethod: function(link) { + var href = rails.href(link), + method = link.data('method'), + target = link.attr('target'), + csrfToken = rails.csrfToken(), + csrfParam = rails.csrfParam(), + form = $('<form method="post" action="' + href + '"></form>'), + metadataInput = '<input name="_method" value="' + method + '" type="hidden" />'; + + if (csrfParam !== undefined && csrfToken !== undefined && !rails.isCrossDomain(href)) { + metadataInput += '<input name="' + csrfParam + '" value="' + csrfToken + '" type="hidden" />'; + } + + if (target) { form.attr('target', target); } + + form.hide().append(metadataInput).appendTo('body'); + form.submit(); + }, + + // Helper function that returns form elements that match the specified CSS selector + // If form is actually a "form" element this will return associated elements outside the from that have + // the html form attribute set + formElements: function(form, selector) { + return form.is('form') ? $(form[0].elements).filter(selector) : form.find(selector); + }, + + /* Disables form elements: + - Caches element value in 'ujs:enable-with' data store + - Replaces element text with value of 'data-disable-with' attribute + - Sets disabled property to true + */ + disableFormElements: function(form) { + rails.formElements(form, rails.disableSelector).each(function() { + rails.disableFormElement($(this)); + }); + }, + + disableFormElement: function(element) { + var method, replacement; + + method = element.is('button') ? 'html' : 'val'; + replacement = element.data('disable-with'); + + element.data('ujs:enable-with', element[method]()); + if (replacement !== undefined) { + element[method](replacement); + } + + element.prop('disabled', true); + }, + + /* Re-enables disabled form elements: + - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`) + - Sets disabled property to false + */ + enableFormElements: function(form) { + rails.formElements(form, rails.enableSelector).each(function() { + rails.enableFormElement($(this)); + }); + }, + + enableFormElement: function(element) { + var method = element.is('button') ? 'html' : 'val'; + if (typeof element.data('ujs:enable-with') !== 'undefined') element[method](element.data('ujs:enable-with')); + element.prop('disabled', false); + }, + + /* For 'data-confirm' attribute: + - Fires `confirm` event + - Shows the confirmation dialog + - Fires the `confirm:complete` event + + Returns `true` if no function stops the chain and user chose yes; `false` otherwise. + Attaching a handler to the element's `confirm` event that returns a `falsy` value cancels the confirmation dialog. + Attaching a handler to the element's `confirm:complete` event that returns a `falsy` value makes this function + return false. The `confirm:complete` event is fired whether or not the user answered true or false to the dialog. + */ + allowAction: function(element) { + var message = element.data('confirm'), + answer = false, callback; + if (!message) { return true; } + + if (rails.fire(element, 'confirm')) { + try { + answer = rails.confirm(message); + } catch (e) { + (console.error || console.log).call(console, e.stack || e); + } + callback = rails.fire(element, 'confirm:complete', [answer]); + } + return answer && callback; + }, + + // Helper function which checks for blank inputs in a form that match the specified CSS selector + blankInputs: function(form, specifiedSelector, nonBlank) { + var inputs = $(), input, valueToCheck, + selector = specifiedSelector || 'input,textarea', + allInputs = form.find(selector); + + allInputs.each(function() { + input = $(this); + valueToCheck = input.is('input[type=checkbox],input[type=radio]') ? input.is(':checked') : !!input.val(); + if (valueToCheck === nonBlank) { + + // Don't count unchecked required radio if other radio with same name is checked + if (input.is('input[type=radio]') && allInputs.filter('input[type=radio]:checked[name="' + input.attr('name') + '"]').length) { + return true; // Skip to next input + } + + inputs = inputs.add(input); + } + }); + return inputs.length ? inputs : false; + }, + + // Helper function which checks for non-blank inputs in a form that match the specified CSS selector + nonBlankInputs: function(form, specifiedSelector) { + return rails.blankInputs(form, specifiedSelector, true); // true specifies nonBlank + }, + + // Helper function, needed to provide consistent behavior in IE + stopEverything: function(e) { + $(e.target).trigger('ujs:everythingStopped'); + e.stopImmediatePropagation(); + return false; + }, + + // replace element's html with the 'data-disable-with' after storing original html + // and prevent clicking on it + disableElement: function(element) { + var replacement = element.data('disable-with'); + + element.data('ujs:enable-with', element.html()); // store enabled state + if (replacement !== undefined) { + element.html(replacement); + } + + element.bind('click.railsDisable', function(e) { // prevent further clicking + return rails.stopEverything(e); + }); + }, + + // restore element to its original state which was disabled by 'disableElement' above + enableElement: function(element) { + if (element.data('ujs:enable-with') !== undefined) { + element.html(element.data('ujs:enable-with')); // set to old enabled state + element.removeData('ujs:enable-with'); // clean up cache + } + element.unbind('click.railsDisable'); // enable element + } + }; + + if (rails.fire($document, 'rails:attachBindings')) { + + $.ajaxPrefilter(function(options, originalOptions, xhr){ if ( !options.crossDomain ) { rails.CSRFProtection(xhr); }}); + + // This event works the same as the load event, except that it fires every + // time the page is loaded. + // + // See https://github.com/rails/jquery-ujs/issues/357 + // See https://developer.mozilla.org/en-US/docs/Using_Firefox_1.5_caching + $(window).on('pageshow.rails', function () { + $($.rails.enableSelector).each(function () { + var element = $(this); + + if (element.data('ujs:enable-with')) { + $.rails.enableFormElement(element); + } + }); + + $($.rails.linkDisableSelector).each(function () { + var element = $(this); + + if (element.data('ujs:enable-with')) { + $.rails.enableElement(element); + } + }); + }); + + $document.delegate(rails.linkDisableSelector, 'ajax:complete', function() { + rails.enableElement($(this)); + }); + + $document.delegate(rails.buttonDisableSelector, 'ajax:complete', function() { + rails.enableFormElement($(this)); + }); + + $document.delegate(rails.linkClickSelector, 'click.rails', function(e) { + var link = $(this), method = link.data('method'), data = link.data('params'), metaClick = e.metaKey || e.ctrlKey; + if (!rails.allowAction(link)) return rails.stopEverything(e); + + if (!metaClick && link.is(rails.linkDisableSelector)) rails.disableElement(link); + + if (rails.isRemote(link)) { + if (metaClick && (!method || method === 'GET') && !data) { return true; } + + var handleRemote = rails.handleRemote(link); + // response from rails.handleRemote() will either be false or a deferred object promise. + if (handleRemote === false) { + rails.enableElement(link); + } else { + handleRemote.fail( function() { rails.enableElement(link); } ); + } + return false; + + } else if (method) { + rails.handleMethod(link); + return false; + } + }); + + $document.delegate(rails.buttonClickSelector, 'click.rails', function(e) { + var button = $(this); + + if (!rails.allowAction(button) || !rails.isRemote(button)) return rails.stopEverything(e); + + if (button.is(rails.buttonDisableSelector)) rails.disableFormElement(button); + + var handleRemote = rails.handleRemote(button); + // response from rails.handleRemote() will either be false or a deferred object promise. + if (handleRemote === false) { + rails.enableFormElement(button); + } else { + handleRemote.fail( function() { rails.enableFormElement(button); } ); + } + return false; + }); + + $document.delegate(rails.inputChangeSelector, 'change.rails', function(e) { + var link = $(this); + if (!rails.allowAction(link) || !rails.isRemote(link)) return rails.stopEverything(e); + + rails.handleRemote(link); + return false; + }); + + $document.delegate(rails.formSubmitSelector, 'submit.rails', function(e) { + var form = $(this), + remote = rails.isRemote(form), + blankRequiredInputs, + nonBlankFileInputs; + + if (!rails.allowAction(form)) return rails.stopEverything(e); + + // skip other logic when required values are missing or file upload is present + if (form.attr('novalidate') === undefined) { + blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector, false); + if (blankRequiredInputs && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) { + return rails.stopEverything(e); + } + } + + if (remote) { + nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector); + if (nonBlankFileInputs) { + // slight timeout so that the submit button gets properly serialized + // (make it easy for event handler to serialize form without disabled values) + setTimeout(function(){ rails.disableFormElements(form); }, 13); + var aborted = rails.fire(form, 'ajax:aborted:file', [nonBlankFileInputs]); + + // re-enable form elements if event bindings return false (canceling normal form submission) + if (!aborted) { setTimeout(function(){ rails.enableFormElements(form); }, 13); } + + return aborted; + } + + rails.handleRemote(form); + return false; + + } else { + // slight timeout so that the submit button gets properly serialized + setTimeout(function(){ rails.disableFormElements(form); }, 13); + } + }); + + $document.delegate(rails.formInputClickSelector, 'click.rails', function(event) { + var button = $(this); + + if (!rails.allowAction(button)) return rails.stopEverything(event); + + // register the pressed submit button + var name = button.attr('name'), + data = name ? {name:name, value:button.val()} : null; + + button.closest('form').data('ujs:submit-button', data); + }); + + $document.delegate(rails.formSubmitSelector, 'ajax:send.rails', function(event) { + if (this === event.target) rails.disableFormElements($(this)); + }); + + $document.delegate(rails.formSubmitSelector, 'ajax:complete.rails', function(event) { + if (this === event.target) rails.enableFormElements($(this)); + }); + + $(function(){ + rails.refreshCSRFTokens(); + }); + } + +})( jQuery ); +/** +* +* jquery.sparkline.js +* +* v2.1.1 +* (c) Splunk, Inc +* Contact: Gareth Watts (gareth@splunk.com) +* http://omnipotent.net/jquery.sparkline/ +* +* Generates inline sparkline charts from data supplied either to the method +* or inline in HTML +* +* Compatible with Internet Explorer 6.0+ and modern browsers equipped with the canvas tag +* (Firefox 2.0+, Safari, Opera, etc) +* +* License: New BSD License +* +* Copyright (c) 2012, Splunk Inc. +* 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 Splunk Inc 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. +* +* +* Usage: +* $(selector).sparkline(values, options) +* +* If values is undefined or set to 'html' then the data values are read from the specified tag: +* <p>Sparkline: <span class="sparkline">1,4,6,6,8,5,3,5</span></p> +* $('.sparkline').sparkline(); +* There must be no spaces in the enclosed data set +* +* Otherwise values must be an array of numbers or null values +* <p>Sparkline: <span id="sparkline1">This text replaced if the browser is compatible</span></p> +* $('#sparkline1').sparkline([1,4,6,6,8,5,3,5]) +* $('#sparkline2').sparkline([1,4,6,null,null,5,3,5]) +* +* Values can also be specified in an HTML comment, or as a values attribute: +* <p>Sparkline: <span class="sparkline"><!--1,4,6,6,8,5,3,5 --></span></p> +* <p>Sparkline: <span class="sparkline" values="1,4,6,6,8,5,3,5"></span></p> +* $('.sparkline').sparkline(); +* +* For line charts, x values can also be specified: +* <p>Sparkline: <span class="sparkline">1:1,2.7:4,3.4:6,5:6,6:8,8.7:5,9:3,10:5</span></p> +* $('#sparkline1').sparkline([ [1,1], [2.7,4], [3.4,6], [5,6], [6,8], [8.7,5], [9,3], [10,5] ]) +* +* By default, options should be passed in as teh second argument to the sparkline function: +* $('.sparkline').sparkline([1,2,3,4], {type: 'bar'}) +* +* Options can also be set by passing them on the tag itself. This feature is disabled by default though +* as there's a slight performance overhead: +* $('.sparkline').sparkline([1,2,3,4], {enableTagOptions: true}) +* <p>Sparkline: <span class="sparkline" sparkType="bar" sparkBarColor="red">loading</span></p> +* Prefix all options supplied as tag attribute with "spark" (configurable by setting tagOptionPrefix) +* +* Supported options: +* lineColor - Color of the line used for the chart +* fillColor - Color used to fill in the chart - Set to '' or false for a transparent chart +* width - Width of the chart - Defaults to 3 times the number of values in pixels +* height - Height of the chart - Defaults to the height of the containing element +* chartRangeMin - Specify the minimum value to use for the Y range of the chart - Defaults to the minimum value supplied +* chartRangeMax - Specify the maximum value to use for the Y range of the chart - Defaults to the maximum value supplied +* chartRangeClip - Clip out of range values to the max/min specified by chartRangeMin and chartRangeMax +* chartRangeMinX - Specify the minimum value to use for the X range of the chart - Defaults to the minimum value supplied +* chartRangeMaxX - Specify the maximum value to use for the X range of the chart - Defaults to the maximum value supplied +* composite - If true then don't erase any existing chart attached to the tag, but draw +* another chart over the top - Note that width and height are ignored if an +* existing chart is detected. +* tagValuesAttribute - Name of tag attribute to check for data values - Defaults to 'values' +* enableTagOptions - Whether to check tags for sparkline options +* tagOptionPrefix - Prefix used for options supplied as tag attributes - Defaults to 'spark' +* disableHiddenCheck - If set to true, then the plugin will assume that charts will never be drawn into a +* hidden dom element, avoding a browser reflow +* disableInteraction - If set to true then all mouseover/click interaction behaviour will be disabled, +* making the plugin perform much like it did in 1.x +* disableTooltips - If set to true then tooltips will be disabled - Defaults to false (tooltips enabled) +* disableHighlight - If set to true then highlighting of selected chart elements on mouseover will be disabled +* defaults to false (highlights enabled) +* highlightLighten - Factor to lighten/darken highlighted chart values by - Defaults to 1.4 for a 40% increase +* tooltipContainer - Specify which DOM element the tooltip should be rendered into - defaults to document.body +* tooltipClassname - Optional CSS classname to apply to tooltips - If not specified then a default style will be applied +* tooltipOffsetX - How many pixels away from the mouse pointer to render the tooltip on the X axis +* tooltipOffsetY - How many pixels away from the mouse pointer to render the tooltip on the r axis +* tooltipFormatter - Optional callback that allows you to override the HTML displayed in the tooltip +* callback is given arguments of (sparkline, options, fields) +* tooltipChartTitle - If specified then the tooltip uses the string specified by this setting as a title +* tooltipFormat - A format string or SPFormat object (or an array thereof for multiple entries) +* to control the format of the tooltip +* tooltipPrefix - A string to prepend to each field displayed in a tooltip +* tooltipSuffix - A string to append to each field displayed in a tooltip +* tooltipSkipNull - If true then null values will not have a tooltip displayed (defaults to true) +* tooltipValueLookups - An object or range map to map field values to tooltip strings +* (eg. to map -1 to "Lost", 0 to "Draw", and 1 to "Win") +* numberFormatter - Optional callback for formatting numbers in tooltips +* numberDigitGroupSep - Character to use for group separator in numbers "1,234" - Defaults to "," +* numberDecimalMark - Character to use for the decimal point when formatting numbers - Defaults to "." +* numberDigitGroupCount - Number of digits between group separator - Defaults to 3 +* +* There are 7 types of sparkline, selected by supplying a "type" option of 'line' (default), +* 'bar', 'tristate', 'bullet', 'discrete', 'pie' or 'box' +* line - Line chart. Options: +* spotColor - Set to '' to not end each line in a circular spot +* minSpotColor - If set, color of spot at minimum value +* maxSpotColor - If set, color of spot at maximum value +* spotRadius - Radius in pixels +* lineWidth - Width of line in pixels +* normalRangeMin +* normalRangeMax - If set draws a filled horizontal bar between these two values marking the "normal" +* or expected range of values +* normalRangeColor - Color to use for the above bar +* drawNormalOnTop - Draw the normal range above the chart fill color if true +* defaultPixelsPerValue - Defaults to 3 pixels of width for each value in the chart +* highlightSpotColor - The color to use for drawing a highlight spot on mouseover - Set to null to disable +* highlightLineColor - The color to use for drawing a highlight line on mouseover - Set to null to disable +* valueSpots - Specify which points to draw spots on, and in which color. Accepts a range map +* +* bar - Bar chart. Options: +* barColor - Color of bars for postive values +* negBarColor - Color of bars for negative values +* zeroColor - Color of bars with zero values +* nullColor - Color of bars with null values - Defaults to omitting the bar entirely +* barWidth - Width of bars in pixels +* colorMap - Optional mappnig of values to colors to override the *BarColor values above +* can be an Array of values to control the color of individual bars or a range map +* to specify colors for individual ranges of values +* barSpacing - Gap between bars in pixels +* zeroAxis - Centers the y-axis around zero if true +* +* tristate - Charts values of win (>0), lose (<0) or draw (=0) +* posBarColor - Color of win values +* negBarColor - Color of lose values +* zeroBarColor - Color of draw values +* barWidth - Width of bars in pixels +* barSpacing - Gap between bars in pixels +* colorMap - Optional mappnig of values to colors to override the *BarColor values above +* can be an Array of values to control the color of individual bars or a range map +* to specify colors for individual ranges of values +* +* discrete - Options: +* lineHeight - Height of each line in pixels - Defaults to 30% of the graph height +* thesholdValue - Values less than this value will be drawn using thresholdColor instead of lineColor +* thresholdColor +* +* bullet - Values for bullet graphs msut be in the order: target, performance, range1, range2, range3, ... +* options: +* targetColor - The color of the vertical target marker +* targetWidth - The width of the target marker in pixels +* performanceColor - The color of the performance measure horizontal bar +* rangeColors - Colors to use for each qualitative range background color +* +* pie - Pie chart. Options: +* sliceColors - An array of colors to use for pie slices +* offset - Angle in degrees to offset the first slice - Try -90 or +90 +* borderWidth - Width of border to draw around the pie chart, in pixels - Defaults to 0 (no border) +* borderColor - Color to use for the pie chart border - Defaults to #000 +* +* box - Box plot. Options: +* raw - Set to true to supply pre-computed plot points as values +* values should be: low_outlier, low_whisker, q1, median, q3, high_whisker, high_outlier +* When set to false you can supply any number of values and the box plot will +* be computed for you. Default is false. +* showOutliers - Set to true (default) to display outliers as circles +* outlierIQR - Interquartile range used to determine outliers. Default 1.5 +* boxLineColor - Outline color of the box +* boxFillColor - Fill color for the box +* whiskerColor - Line color used for whiskers +* outlierLineColor - Outline color of outlier circles +* outlierFillColor - Fill color of the outlier circles +* spotRadius - Radius of outlier circles +* medianColor - Line color of the median line +* target - Draw a target cross hair at the supplied value (default undefined) +* +* +* +* Examples: +* $('#sparkline1').sparkline(myvalues, { lineColor: '#f00', fillColor: false }); +* $('.barsparks').sparkline('html', { type:'bar', height:'40px', barWidth:5 }); +* $('#tristate').sparkline([1,1,-1,1,0,0,-1], { type:'tristate' }): +* $('#discrete').sparkline([1,3,4,5,5,3,4,5], { type:'discrete' }); +* $('#bullet').sparkline([10,12,12,9,7], { type:'bullet' }); +* $('#pie').sparkline([1,1,2], { type:'pie' }); +*/ + +/*jslint regexp: true, browser: true, jquery: true, white: true, nomen: false, plusplus: false, maxerr: 500, indent: 4 */ + + +(function(factory) { + if(typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } + else { + factory(jQuery); + } +} +(function($) { + 'use strict'; + + var UNSET_OPTION = {}, + getDefaults, createClass, SPFormat, clipval, quartile, normalizeValue, normalizeValues, + remove, isNumber, all, sum, addCSS, ensureArray, formatNumber, RangeMap, + MouseHandler, Tooltip, barHighlightMixin, + line, bar, tristate, discrete, bullet, pie, box, defaultStyles, initStyles, + VShape, VCanvas_base, VCanvas_canvas, VCanvas_vml, pending, shapeCount = 0; + + /** + * Default configuration settings + */ + getDefaults = function () { + return { + // Settings common to most/all chart types + common: { + type: 'line', + lineColor: '#00f', + fillColor: '#cdf', + defaultPixelsPerValue: 3, + width: 'auto', + height: 'auto', + composite: false, + tagValuesAttribute: 'values', + tagOptionsPrefix: 'spark', + enableTagOptions: false, + enableHighlight: true, + highlightLighten: 1.4, + tooltipSkipNull: true, + tooltipPrefix: '', + tooltipSuffix: '', + disableHiddenCheck: false, + numberFormatter: false, + numberDigitGroupCount: 3, + numberDigitGroupSep: ',', + numberDecimalMark: '.', + disableTooltips: false, + disableInteraction: false + }, + // Defaults for line charts + line: { + spotColor: '#f80', + highlightSpotColor: '#5f5', + highlightLineColor: '#f22', + spotRadius: 1.5, + minSpotColor: '#f80', + maxSpotColor: '#f80', + lineWidth: 1, + normalRangeMin: undefined, + normalRangeMax: undefined, + normalRangeColor: '#ccc', + drawNormalOnTop: false, + chartRangeMin: undefined, + chartRangeMax: undefined, + chartRangeMinX: undefined, + chartRangeMaxX: undefined, + tooltipFormat: new SPFormat('<span style="color: {{color}}">●</span> {{prefix}}{{y}}{{suffix}}') + }, + // Defaults for bar charts + bar: { + barColor: '#3366cc', + negBarColor: '#f44', + stackedBarColor: ['#3366cc', '#dc3912', '#ff9900', '#109618', '#66aa00', + '#dd4477', '#0099c6', '#990099'], + zeroColor: undefined, + nullColor: undefined, + zeroAxis: true, + barWidth: 4, + barSpacing: 1, + chartRangeMax: undefined, + chartRangeMin: undefined, + chartRangeClip: false, + colorMap: undefined, + tooltipFormat: new SPFormat('<span style="color: {{color}}">●</span> {{prefix}}{{value}}{{suffix}}') + }, + // Defaults for tristate charts + tristate: { + barWidth: 4, + barSpacing: 1, + posBarColor: '#6f6', + negBarColor: '#f44', + zeroBarColor: '#999', + colorMap: {}, + tooltipFormat: new SPFormat('<span style="color: {{color}}">●</span> {{value:map}}'), + tooltipValueLookups: { map: { '-1': 'Loss', '0': 'Draw', '1': 'Win' } } + }, + // Defaults for discrete charts + discrete: { + lineHeight: 'auto', + thresholdColor: undefined, + thresholdValue: 0, + chartRangeMax: undefined, + chartRangeMin: undefined, + chartRangeClip: false, + tooltipFormat: new SPFormat('{{prefix}}{{value}}{{suffix}}') + }, + // Defaults for bullet charts + bullet: { + targetColor: '#f33', + targetWidth: 3, // width of the target bar in pixels + performanceColor: '#33f', + rangeColors: ['#d3dafe', '#a8b6ff', '#7f94ff'], + base: undefined, // set this to a number to change the base start number + tooltipFormat: new SPFormat('{{fieldkey:fields}} - {{value}}'), + tooltipValueLookups: { fields: {r: 'Range', p: 'Performance', t: 'Target'} } + }, + // Defaults for pie charts + pie: { + offset: 0, + sliceColors: ['#3366cc', '#dc3912', '#ff9900', '#109618', '#66aa00', + '#dd4477', '#0099c6', '#990099'], + borderWidth: 0, + borderColor: '#000', + tooltipFormat: new SPFormat('<span style="color: {{color}}">●</span> {{value}} ({{percent.1}}%)') + }, + // Defaults for box plots + box: { + raw: false, + boxLineColor: '#000', + boxFillColor: '#cdf', + whiskerColor: '#000', + outlierLineColor: '#333', + outlierFillColor: '#fff', + medianColor: '#f00', + showOutliers: true, + outlierIQR: 1.5, + spotRadius: 1.5, + target: undefined, + targetColor: '#4a2', + chartRangeMax: undefined, + chartRangeMin: undefined, + tooltipFormat: new SPFormat('{{field:fields}}: {{value}}'), + tooltipFormatFieldlistKey: 'field', + tooltipValueLookups: { fields: { lq: 'Lower Quartile', med: 'Median', + uq: 'Upper Quartile', lo: 'Left Outlier', ro: 'Right Outlier', + lw: 'Left Whisker', rw: 'Right Whisker'} } + } + }; + }; + + // You can have tooltips use a css class other than jqstooltip by specifying tooltipClassname + defaultStyles = '.jqstooltip { ' + + 'position: absolute;' + + 'left: 0px;' + + 'top: 0px;' + + 'visibility: hidden;' + + 'background: rgb(0, 0, 0) transparent;' + + 'background-color: rgba(0,0,0,0.6);' + + 'filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000);' + + '-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000)";' + + 'color: white;' + + 'font: 10px arial, san serif;' + + 'text-align: left;' + + 'white-space: nowrap;' + + 'padding: 5px;' + + 'border: 1px solid white;' + + 'z-index: 10000;' + + '}' + + '.jqsfield { ' + + 'color: white;' + + 'font: 10px arial, san serif;' + + 'text-align: left;' + + '}'; + + /** + * Utilities + */ + + createClass = function (/* [baseclass, [mixin, ...]], definition */) { + var Class, args; + Class = function () { + this.init.apply(this, arguments); + }; + if (arguments.length > 1) { + if (arguments[0]) { + Class.prototype = $.extend(new arguments[0](), arguments[arguments.length - 1]); + Class._super = arguments[0].prototype; + } else { + Class.prototype = arguments[arguments.length - 1]; + } + if (arguments.length > 2) { + args = Array.prototype.slice.call(arguments, 1, -1); + args.unshift(Class.prototype); + $.extend.apply($, args); + } + } else { + Class.prototype = arguments[0]; + } + Class.prototype.cls = Class; + return Class; + }; + + /** + * Wraps a format string for tooltips + * {{x}} + * {{x.2} + * {{x:months}} + */ + $.SPFormatClass = SPFormat = createClass({ + fre: /\{\{([\w.]+?)(:(.+?))?\}\}/g, + precre: /(\w+)\.(\d+)/, + + init: function (format, fclass) { + this.format = format; + this.fclass = fclass; + }, + + render: function (fieldset, lookups, options) { + var self = this, + fields = fieldset, + match, token, lookupkey, fieldvalue, prec; + return this.format.replace(this.fre, function () { + var lookup; + token = arguments[1]; + lookupkey = arguments[3]; + match = self.precre.exec(token); + if (match) { + prec = match[2]; + token = match[1]; + } else { + prec = false; + } + fieldvalue = fields[token]; + if (fieldvalue === undefined) { + return ''; + } + if (lookupkey && lookups && lookups[lookupkey]) { + lookup = lookups[lookupkey]; + if (lookup.get) { // RangeMap + return lookups[lookupkey].get(fieldvalue) || fieldvalue; + } else { + return lookups[lookupkey][fieldvalue] || fieldvalue; + } + } + if (isNumber(fieldvalue)) { + if (options.get('numberFormatter')) { + fieldvalue = options.get('numberFormatter')(fieldvalue); + } else { + fieldvalue = formatNumber(fieldvalue, prec, + options.get('numberDigitGroupCount'), + options.get('numberDigitGroupSep'), + options.get('numberDecimalMark')); + } + } + return fieldvalue; + }); + } + }); + + // convience method to avoid needing the new operator + $.spformat = function(format, fclass) { + return new SPFormat(format, fclass); + }; + + clipval = function (val, min, max) { + if (val < min) { + return min; + } + if (val > max) { + return max; + } + return val; + }; + + quartile = function (values, q) { + var vl; + if (q === 2) { + vl = Math.floor(values.length / 2); + return values.length % 2 ? values[vl] : (values[vl-1] + values[vl]) / 2; + } else { + if (values.length % 2 ) { // odd + vl = (values.length * q + q) / 4; + return vl % 1 ? (values[Math.floor(vl)] + values[Math.floor(vl) - 1]) / 2 : values[vl-1]; + } else { //even + vl = (values.length * q + 2) / 4; + return vl % 1 ? (values[Math.floor(vl)] + values[Math.floor(vl) - 1]) / 2 : values[vl-1]; + + } + } + }; + + normalizeValue = function (val) { + var nf; + switch (val) { + case 'undefined': + val = undefined; + break; + case 'null': + val = null; + break; + case 'true': + val = true; + break; + case 'false': + val = false; + break; + default: + nf = parseFloat(val); + if (val == nf) { + val = nf; + } + } + return val; + }; + + normalizeValues = function (vals) { + var i, result = []; + for (i = vals.length; i--;) { + result[i] = normalizeValue(vals[i]); + } + return result; + }; + + remove = function (vals, filter) { + var i, vl, result = []; + for (i = 0, vl = vals.length; i < vl; i++) { + if (vals[i] !== filter) { + result.push(vals[i]); + } + } + return result; + }; + + isNumber = function (num) { + return !isNaN(parseFloat(num)) && isFinite(num); + }; + + formatNumber = function (num, prec, groupsize, groupsep, decsep) { + var p, i; + num = (prec === false ? parseFloat(num).toString() : num.toFixed(prec)).split(''); + p = (p = $.inArray('.', num)) < 0 ? num.length : p; + if (p < num.length) { + num[p] = decsep; + } + for (i = p - groupsize; i > 0; i -= groupsize) { + num.splice(i, 0, groupsep); + } + return num.join(''); + }; + + // determine if all values of an array match a value + // returns true if the array is empty + all = function (val, arr, ignoreNull) { + var i; + for (i = arr.length; i--; ) { + if (ignoreNull && arr[i] === null) continue; + if (arr[i] !== val) { + return false; + } + } + return true; + }; + + // sums the numeric values in an array, ignoring other values + sum = function (vals) { + var total = 0, i; + for (i = vals.length; i--;) { + total += typeof vals[i] === 'number' ? vals[i] : 0; + } + return total; + }; + + ensureArray = function (val) { + return $.isArray(val) ? val : [val]; + }; + + // http://paulirish.com/2008/bookmarklet-inject-new-css-rules/ + addCSS = function(css) { + var tag; + //if ('\v' == 'v') /* ie only */ { + if (document.createStyleSheet) { + document.createStyleSheet().cssText = css; + } else { + tag = document.createElement('style'); + tag.type = 'text/css'; + document.getElementsByTagName('head')[0].appendChild(tag); + tag[(typeof document.body.style.WebkitAppearance == 'string') /* webkit only */ ? 'innerText' : 'innerHTML'] = css; + } + }; + + // Provide a cross-browser interface to a few simple drawing primitives + $.fn.simpledraw = function (width, height, useExisting, interact) { + var target, mhandler; + if (useExisting && (target = this.data('_jqs_vcanvas'))) { + return target; + } + if (width === undefined) { + width = $(this).innerWidth(); + } + if (height === undefined) { + height = $(this).innerHeight(); + } + if ($.fn.sparkline.hasCanvas) { + target = new VCanvas_canvas(width, height, this, interact); + } else if ($.fn.sparkline.hasVML) { + target = new VCanvas_vml(width, height, this); + } else { + return false; + } + mhandler = $(this).data('_jqs_mhandler'); + if (mhandler) { + mhandler.registerCanvas(target); + } + return target; + }; + + $.fn.cleardraw = function () { + var target = this.data('_jqs_vcanvas'); + if (target) { + target.reset(); + } + }; + + $.RangeMapClass = RangeMap = createClass({ + init: function (map) { + var key, range, rangelist = []; + for (key in map) { + if (map.hasOwnProperty(key) && typeof key === 'string' && key.indexOf(':') > -1) { + range = key.split(':'); + range[0] = range[0].length === 0 ? -Infinity : parseFloat(range[0]); + range[1] = range[1].length === 0 ? Infinity : parseFloat(range[1]); + range[2] = map[key]; + rangelist.push(range); + } + } + this.map = map; + this.rangelist = rangelist || false; + }, + + get: function (value) { + var rangelist = this.rangelist, + i, range, result; + if ((result = this.map[value]) !== undefined) { + return result; + } + if (rangelist) { + for (i = rangelist.length; i--;) { + range = rangelist[i]; + if (range[0] <= value && range[1] >= value) { + return range[2]; + } + } + } + return undefined; + } + }); + + // Convenience function + $.range_map = function(map) { + return new RangeMap(map); + }; + + MouseHandler = createClass({ + init: function (el, options) { + var $el = $(el); + this.$el = $el; + this.options = options; + this.currentPageX = 0; + this.currentPageY = 0; + this.el = el; + this.splist = []; + this.tooltip = null; + this.over = false; + this.displayTooltips = !options.get('disableTooltips'); + this.highlightEnabled = !options.get('disableHighlight'); + }, + + registerSparkline: function (sp) { + this.splist.push(sp); + if (this.over) { + this.updateDisplay(); + } + }, + + registerCanvas: function (canvas) { + var $canvas = $(canvas.canvas); + this.canvas = canvas; + this.$canvas = $canvas; + $canvas.mouseenter($.proxy(this.mouseenter, this)); + $canvas.mouseleave($.proxy(this.mouseleave, this)); + $canvas.click($.proxy(this.mouseclick, this)); + }, + + reset: function (removeTooltip) { + this.splist = []; + if (this.tooltip && removeTooltip) { + this.tooltip.remove(); + this.tooltip = undefined; + } + }, + + mouseclick: function (e) { + var clickEvent = $.Event('sparklineClick'); + clickEvent.originalEvent = e; + clickEvent.sparklines = this.splist; + this.$el.trigger(clickEvent); + }, + + mouseenter: function (e) { + $(document.body).unbind('mousemove.jqs'); + $(document.body).bind('mousemove.jqs', $.proxy(this.mousemove, this)); + this.over = true; + this.currentPageX = e.pageX; + this.currentPageY = e.pageY; + this.currentEl = e.target; + if (!this.tooltip && this.displayTooltips) { + this.tooltip = new Tooltip(this.options); + this.tooltip.updatePosition(e.pageX, e.pageY); + } + this.updateDisplay(); + }, + + mouseleave: function () { + $(document.body).unbind('mousemove.jqs'); + var splist = this.splist, + spcount = splist.length, + needsRefresh = false, + sp, i; + this.over = false; + this.currentEl = null; + + if (this.tooltip) { + this.tooltip.remove(); + this.tooltip = null; + } + + for (i = 0; i < spcount; i++) { + sp = splist[i]; + if (sp.clearRegionHighlight()) { + needsRefresh = true; + } + } + + if (needsRefresh) { + this.canvas.render(); + } + }, + + mousemove: function (e) { + this.currentPageX = e.pageX; + this.currentPageY = e.pageY; + this.currentEl = e.target; + if (this.tooltip) { + this.tooltip.updatePosition(e.pageX, e.pageY); + } + this.updateDisplay(); + }, + + updateDisplay: function () { + var splist = this.splist, + spcount = splist.length, + needsRefresh = false, + offset = this.$canvas.offset(), + localX = this.currentPageX - offset.left, + localY = this.currentPageY - offset.top, + tooltiphtml, sp, i, result, changeEvent; + if (!this.over) { + return; + } + for (i = 0; i < spcount; i++) { + sp = splist[i]; + result = sp.setRegionHighlight(this.currentEl, localX, localY); + if (result) { + needsRefresh = true; + } + } + if (needsRefresh) { + changeEvent = $.Event('sparklineRegionChange'); + changeEvent.sparklines = this.splist; + this.$el.trigger(changeEvent); + if (this.tooltip) { + tooltiphtml = ''; + for (i = 0; i < spcount; i++) { + sp = splist[i]; + tooltiphtml += sp.getCurrentRegionTooltip(); + } + this.tooltip.setContent(tooltiphtml); + } + if (!this.disableHighlight) { + this.canvas.render(); + } + } + if (result === null) { + this.mouseleave(); + } + } + }); + + + Tooltip = createClass({ + sizeStyle: 'position: static !important;' + + 'display: block !important;' + + 'visibility: hidden !important;' + + 'float: left !important;', + + init: function (options) { + var tooltipClassname = options.get('tooltipClassname', 'jqstooltip'), + sizetipStyle = this.sizeStyle, + offset; + this.container = options.get('tooltipContainer') || document.body; + this.tooltipOffsetX = options.get('tooltipOffsetX', 10); + this.tooltipOffsetY = options.get('tooltipOffsetY', 12); + // remove any previous lingering tooltip + $('#jqssizetip').remove(); + $('#jqstooltip').remove(); + this.sizetip = $('<div/>', { + id: 'jqssizetip', + style: sizetipStyle, + 'class': tooltipClassname + }); + this.tooltip = $('<div/>', { + id: 'jqstooltip', + 'class': tooltipClassname + }).appendTo(this.container); + // account for the container's location + offset = this.tooltip.offset(); + this.offsetLeft = offset.left; + this.offsetTop = offset.top; + this.hidden = true; + $(window).unbind('resize.jqs scroll.jqs'); + $(window).bind('resize.jqs scroll.jqs', $.proxy(this.updateWindowDims, this)); + this.updateWindowDims(); + }, + + updateWindowDims: function () { + this.scrollTop = $(window).scrollTop(); + this.scrollLeft = $(window).scrollLeft(); + this.scrollRight = this.scrollLeft + $(window).width(); + this.updatePosition(); + }, + + getSize: function (content) { + this.sizetip.html(content).appendTo(this.container); + this.width = this.sizetip.width() + 1; + this.height = this.sizetip.height(); + this.sizetip.remove(); + }, + + setContent: function (content) { + if (!content) { + this.tooltip.css('visibility', 'hidden'); + this.hidden = true; + return; + } + this.getSize(content); + this.tooltip.html(content) + .css({ + 'width': this.width, + 'height': this.height, + 'visibility': 'visible' + }); + if (this.hidden) { + this.hidden = false; + this.updatePosition(); + } + }, + + updatePosition: function (x, y) { + if (x === undefined) { + if (this.mousex === undefined) { + return; + } + x = this.mousex - this.offsetLeft; + y = this.mousey - this.offsetTop; + + } else { + this.mousex = x = x - this.offsetLeft; + this.mousey = y = y - this.offsetTop; + } + if (!this.height || !this.width || this.hidden) { + return; + } + + y -= this.height + this.tooltipOffsetY; + x += this.tooltipOffsetX; + + if (y < this.scrollTop) { + y = this.scrollTop; + } + if (x < this.scrollLeft) { + x = this.scrollLeft; + } else if (x + this.width > this.scrollRight) { + x = this.scrollRight - this.width; + } + + this.tooltip.css({ + 'left': x, + 'top': y + }); + }, + + remove: function () { + this.tooltip.remove(); + this.sizetip.remove(); + this.sizetip = this.tooltip = undefined; + $(window).unbind('resize.jqs scroll.jqs'); + } + }); + + initStyles = function() { + addCSS(defaultStyles); + }; + + $(initStyles); + + pending = []; + $.fn.sparkline = function (userValues, userOptions) { + return this.each(function () { + var options = new $.fn.sparkline.options(this, userOptions), + $this = $(this), + render, i; + render = function () { + var values, width, height, tmp, mhandler, sp, vals; + if (userValues === 'html' || userValues === undefined) { + vals = this.getAttribute(options.get('tagValuesAttribute')); + if (vals === undefined || vals === null) { + vals = $this.html(); + } + values = vals.replace(/(^\s*<!--)|(-->\s*$)|\s+/g, '').split(','); + } else { + values = userValues; + } + + width = options.get('width') === 'auto' ? values.length * options.get('defaultPixelsPerValue') : options.get('width'); + if (options.get('height') === 'auto') { + if (!options.get('composite') || !$.data(this, '_jqs_vcanvas')) { + // must be a better way to get the line height + tmp = document.createElement('span'); + tmp.innerHTML = 'a'; + $this.html(tmp); + height = $(tmp).innerHeight() || $(tmp).height(); + $(tmp).remove(); + tmp = null; + } + } else { + height = options.get('height'); + } + + if (!options.get('disableInteraction')) { + mhandler = $.data(this, '_jqs_mhandler'); + if (!mhandler) { + mhandler = new MouseHandler(this, options); + $.data(this, '_jqs_mhandler', mhandler); + } else if (!options.get('composite')) { + mhandler.reset(); + } + } else { + mhandler = false; + } + + if (options.get('composite') && !$.data(this, '_jqs_vcanvas')) { + if (!$.data(this, '_jqs_errnotify')) { + alert('Attempted to attach a composite sparkline to an element with no existing sparkline'); + $.data(this, '_jqs_errnotify', true); + } + return; + } + + sp = new $.fn.sparkline[options.get('type')](this, values, options, width, height); + + sp.render(); + + if (mhandler) { + mhandler.registerSparkline(sp); + } + }; + // jQuery 1.3.0 completely changed the meaning of :hidden :-/ + if (($(this).html() && !options.get('disableHiddenCheck') && $(this).is(':hidden')) || ($.fn.jquery < '1.3.0' && $(this).parents().is(':hidden')) || !$(this).parents('body').length) { + if (!options.get('composite') && $.data(this, '_jqs_pending')) { + // remove any existing references to the element + for (i = pending.length; i; i--) { + if (pending[i - 1][0] == this) { + pending.splice(i - 1, 1); + } + } + } + pending.push([this, render]); + $.data(this, '_jqs_pending', true); + } else { + render.call(this); + } + }); + }; + + $.fn.sparkline.defaults = getDefaults(); + + + $.sparkline_display_visible = function () { + var el, i, pl; + var done = []; + for (i = 0, pl = pending.length; i < pl; i++) { + el = pending[i][0]; + if ($(el).is(':visible') && !$(el).parents().is(':hidden')) { + pending[i][1].call(el); + $.data(pending[i][0], '_jqs_pending', false); + done.push(i); + } else if (!$(el).closest('html').length && !$.data(el, '_jqs_pending')) { + // element has been inserted and removed from the DOM + // If it was not yet inserted into the dom then the .data request + // will return true. + // removing from the dom causes the data to be removed. + $.data(pending[i][0], '_jqs_pending', false); + done.push(i); + } + } + for (i = done.length; i; i--) { + pending.splice(done[i - 1], 1); + } + }; + + + /** + * User option handler + */ + $.fn.sparkline.options = createClass({ + init: function (tag, userOptions) { + var extendedOptions, defaults, base, tagOptionType; + this.userOptions = userOptions = userOptions || {}; + this.tag = tag; + this.tagValCache = {}; + defaults = $.fn.sparkline.defaults; + base = defaults.common; + this.tagOptionsPrefix = userOptions.enableTagOptions && (userOptions.tagOptionsPrefix || base.tagOptionsPrefix); + + tagOptionType = this.getTagSetting('type'); + if (tagOptionType === UNSET_OPTION) { + extendedOptions = defaults[userOptions.type || base.type]; + } else { + extendedOptions = defaults[tagOptionType]; + } + this.mergedOptions = $.extend({}, base, extendedOptions, userOptions); + }, + + + getTagSetting: function (key) { + var prefix = this.tagOptionsPrefix, + val, i, pairs, keyval; + if (prefix === false || prefix === undefined) { + return UNSET_OPTION; + } + if (this.tagValCache.hasOwnProperty(key)) { + val = this.tagValCache.key; + } else { + val = this.tag.getAttribute(prefix + key); + if (val === undefined || val === null) { + val = UNSET_OPTION; + } else if (val.substr(0, 1) === '[') { + val = val.substr(1, val.length - 2).split(','); + for (i = val.length; i--;) { + val[i] = normalizeValue(val[i].replace(/(^\s*)|(\s*$)/g, '')); + } + } else if (val.substr(0, 1) === '{') { + pairs = val.substr(1, val.length - 2).split(','); + val = {}; + for (i = pairs.length; i--;) { + keyval = pairs[i].split(':', 2); + val[keyval[0].replace(/(^\s*)|(\s*$)/g, '')] = normalizeValue(keyval[1].replace(/(^\s*)|(\s*$)/g, '')); + } + } else { + val = normalizeValue(val); + } + this.tagValCache.key = val; + } + return val; + }, + + get: function (key, defaultval) { + var tagOption = this.getTagSetting(key), + result; + if (tagOption !== UNSET_OPTION) { + return tagOption; + } + return (result = this.mergedOptions[key]) === undefined ? defaultval : result; + } + }); + + + $.fn.sparkline._base = createClass({ + disabled: false, + + init: function (el, values, options, width, height) { + this.el = el; + this.$el = $(el); + this.values = values; + this.options = options; + this.width = width; + this.height = height; + this.currentRegion = undefined; + }, + + /** + * Setup the canvas + */ + initTarget: function () { + var interactive = !this.options.get('disableInteraction'); + if (!(this.target = this.$el.simpledraw(this.width, this.height, this.options.get('composite'), interactive))) { + this.disabled = true; + } else { + this.canvasWidth = this.target.pixelWidth; + this.canvasHeight = this.target.pixelHeight; + } + }, + + /** + * Actually render the chart to the canvas + */ + render: function () { + if (this.disabled) { + this.el.innerHTML = ''; + return false; + } + return true; + }, + + /** + * Return a region id for a given x/y co-ordinate + */ + getRegion: function (x, y) { + }, + + /** + * Highlight an item based on the moused-over x,y co-ordinate + */ + setRegionHighlight: function (el, x, y) { + var currentRegion = this.currentRegion, + highlightEnabled = !this.options.get('disableHighlight'), + newRegion; + if (x > this.canvasWidth || y > this.canvasHeight || x < 0 || y < 0) { + return null; + } + newRegion = this.getRegion(el, x, y); + if (currentRegion !== newRegion) { + if (currentRegion !== undefined && highlightEnabled) { + this.removeHighlight(); + } + this.currentRegion = newRegion; + if (newRegion !== undefined && highlightEnabled) { + this.renderHighlight(); + } + return true; + } + return false; + }, + + /** + * Reset any currently highlighted item + */ + clearRegionHighlight: function () { + if (this.currentRegion !== undefined) { + this.removeHighlight(); + this.currentRegion = undefined; + return true; + } + return false; + }, + + renderHighlight: function () { + this.changeHighlight(true); + }, + + removeHighlight: function () { + this.changeHighlight(false); + }, + + changeHighlight: function (highlight) {}, + + /** + * Fetch the HTML to display as a tooltip + */ + getCurrentRegionTooltip: function () { + var options = this.options, + header = '', + entries = [], + fields, formats, formatlen, fclass, text, i, + showFields, showFieldsKey, newFields, fv, + formatter, format, fieldlen, j; + if (this.currentRegion === undefined) { + return ''; + } + fields = this.getCurrentRegionFields(); + formatter = options.get('tooltipFormatter'); + if (formatter) { + return formatter(this, options, fields); + } + if (options.get('tooltipChartTitle')) { + header += '<div class="jqs jqstitle">' + options.get('tooltipChartTitle') + '</div>\n'; + } + formats = this.options.get('tooltipFormat'); + if (!formats) { + return ''; + } + if (!$.isArray(formats)) { + formats = [formats]; + } + if (!$.isArray(fields)) { + fields = [fields]; + } + showFields = this.options.get('tooltipFormatFieldlist'); + showFieldsKey = this.options.get('tooltipFormatFieldlistKey'); + if (showFields && showFieldsKey) { + // user-selected ordering of fields + newFields = []; + for (i = fields.length; i--;) { + fv = fields[i][showFieldsKey]; + if ((j = $.inArray(fv, showFields)) != -1) { + newFields[j] = fields[i]; + } + } + fields = newFields; + } + formatlen = formats.length; + fieldlen = fields.length; + for (i = 0; i < formatlen; i++) { + format = formats[i]; + if (typeof format === 'string') { + format = new SPFormat(format); + } + fclass = format.fclass || 'jqsfield'; + for (j = 0; j < fieldlen; j++) { + if (!fields[j].isNull || !options.get('tooltipSkipNull')) { + $.extend(fields[j], { + prefix: options.get('tooltipPrefix'), + suffix: options.get('tooltipSuffix') + }); + text = format.render(fields[j], options.get('tooltipValueLookups'), options); + entries.push('<div class="' + fclass + '">' + text + '</div>'); + } + } + } + if (entries.length) { + return header + entries.join('\n'); + } + return ''; + }, + + getCurrentRegionFields: function () {}, + + calcHighlightColor: function (color, options) { + var highlightColor = options.get('highlightColor'), + lighten = options.get('highlightLighten'), + parse, mult, rgbnew, i; + if (highlightColor) { + return highlightColor; + } + if (lighten) { + // extract RGB values + parse = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(color) || /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(color); + if (parse) { + rgbnew = []; + mult = color.length === 4 ? 16 : 1; + for (i = 0; i < 3; i++) { + rgbnew[i] = clipval(Math.round(parseInt(parse[i + 1], 16) * mult * lighten), 0, 255); + } + return 'rgb(' + rgbnew.join(',') + ')'; + } + + } + return color; + } + + }); + + barHighlightMixin = { + changeHighlight: function (highlight) { + var currentRegion = this.currentRegion, + target = this.target, + shapeids = this.regionShapes[currentRegion], + newShapes; + // will be null if the region value was null + if (shapeids) { + newShapes = this.renderRegion(currentRegion, highlight); + if ($.isArray(newShapes) || $.isArray(shapeids)) { + target.replaceWithShapes(shapeids, newShapes); + this.regionShapes[currentRegion] = $.map(newShapes, function (newShape) { + return newShape.id; + }); + } else { + target.replaceWithShape(shapeids, newShapes); + this.regionShapes[currentRegion] = newShapes.id; + } + } + }, + + render: function () { + var values = this.values, + target = this.target, + regionShapes = this.regionShapes, + shapes, ids, i, j; + + if (!this.cls._super.render.call(this)) { + return; + } + for (i = values.length; i--;) { + shapes = this.renderRegion(i); + if (shapes) { + if ($.isArray(shapes)) { + ids = []; + for (j = shapes.length; j--;) { + shapes[j].append(); + ids.push(shapes[j].id); + } + regionShapes[i] = ids; + } else { + shapes.append(); + regionShapes[i] = shapes.id; // store just the shapeid + } + } else { + // null value + regionShapes[i] = null; + } + } + target.render(); + } + }; + + /** + * Line charts + */ + $.fn.sparkline.line = line = createClass($.fn.sparkline._base, { + type: 'line', + + init: function (el, values, options, width, height) { + line._super.init.call(this, el, values, options, width, height); + this.vertices = []; + this.regionMap = []; + this.xvalues = []; + this.yvalues = []; + this.yminmax = []; + this.hightlightSpotId = null; + this.lastShapeId = null; + this.initTarget(); + }, + + getRegion: function (el, x, y) { + var i, + regionMap = this.regionMap; // maps regions to value positions + for (i = regionMap.length; i--;) { + if (regionMap[i] !== null && x >= regionMap[i][0] && x <= regionMap[i][1]) { + return regionMap[i][2]; + } + } + return undefined; + }, + + getCurrentRegionFields: function () { + var currentRegion = this.currentRegion; + return { + isNull: this.yvalues[currentRegion] === null, + x: this.xvalues[currentRegion], + y: this.yvalues[currentRegion], + color: this.options.get('lineColor'), + fillColor: this.options.get('fillColor'), + offset: currentRegion + }; + }, + + renderHighlight: function () { + var currentRegion = this.currentRegion, + target = this.target, + vertex = this.vertices[currentRegion], + options = this.options, + spotRadius = options.get('spotRadius'), + highlightSpotColor = options.get('highlightSpotColor'), + highlightLineColor = options.get('highlightLineColor'), + highlightSpot, highlightLine; + + if (!vertex) { + return; + } + if (spotRadius && highlightSpotColor) { + highlightSpot = target.drawCircle(vertex[0], vertex[1], + spotRadius, undefined, highlightSpotColor); + this.highlightSpotId = highlightSpot.id; + target.insertAfterShape(this.lastShapeId, highlightSpot); + } + if (highlightLineColor) { + highlightLine = target.drawLine(vertex[0], this.canvasTop, vertex[0], + this.canvasTop + this.canvasHeight, highlightLineColor); + this.highlightLineId = highlightLine.id; + target.insertAfterShape(this.lastShapeId, highlightLine); + } + }, + + removeHighlight: function () { + var target = this.target; + if (this.highlightSpotId) { + target.removeShapeId(this.highlightSpotId); + this.highlightSpotId = null; + } + if (this.highlightLineId) { + target.removeShapeId(this.highlightLineId); + this.highlightLineId = null; + } + }, + + scanValues: function () { + var values = this.values, + valcount = values.length, + xvalues = this.xvalues, + yvalues = this.yvalues, + yminmax = this.yminmax, + i, val, isStr, isArray, sp; + for (i = 0; i < valcount; i++) { + val = values[i]; + isStr = typeof(values[i]) === 'string'; + isArray = typeof(values[i]) === 'object' && values[i] instanceof Array; + sp = isStr && values[i].split(':'); + if (isStr && sp.length === 2) { // x:y + xvalues.push(Number(sp[0])); + yvalues.push(Number(sp[1])); + yminmax.push(Number(sp[1])); + } else if (isArray) { + xvalues.push(val[0]); + yvalues.push(val[1]); + yminmax.push(val[1]); + } else { + xvalues.push(i); + if (values[i] === null || values[i] === 'null') { + yvalues.push(null); + } else { + yvalues.push(Number(val)); + yminmax.push(Number(val)); + } + } + } + if (this.options.get('xvalues')) { + xvalues = this.options.get('xvalues'); + } + + this.maxy = this.maxyorg = Math.max.apply(Math, yminmax); + this.miny = this.minyorg = Math.min.apply(Math, yminmax); + + this.maxx = Math.max.apply(Math, xvalues); + this.minx = Math.min.apply(Math, xvalues); + + this.xvalues = xvalues; + this.yvalues = yvalues; + this.yminmax = yminmax; + + }, + + processRangeOptions: function () { + var options = this.options, + normalRangeMin = options.get('normalRangeMin'), + normalRangeMax = options.get('normalRangeMax'); + + if (normalRangeMin !== undefined) { + if (normalRangeMin < this.miny) { + this.miny = normalRangeMin; + } + if (normalRangeMax > this.maxy) { + this.maxy = normalRangeMax; + } + } + if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < this.miny)) { + this.miny = options.get('chartRangeMin'); + } + if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > this.maxy)) { + this.maxy = options.get('chartRangeMax'); + } + if (options.get('chartRangeMinX') !== undefined && (options.get('chartRangeClipX') || options.get('chartRangeMinX') < this.minx)) { + this.minx = options.get('chartRangeMinX'); + } + if (options.get('chartRangeMaxX') !== undefined && (options.get('chartRangeClipX') || options.get('chartRangeMaxX') > this.maxx)) { + this.maxx = options.get('chartRangeMaxX'); + } + + }, + + drawNormalRange: function (canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey) { + var normalRangeMin = this.options.get('normalRangeMin'), + normalRangeMax = this.options.get('normalRangeMax'), + ytop = canvasTop + Math.round(canvasHeight - (canvasHeight * ((normalRangeMax - this.miny) / rangey))), + height = Math.round((canvasHeight * (normalRangeMax - normalRangeMin)) / rangey); + this.target.drawRect(canvasLeft, ytop, canvasWidth, height, undefined, this.options.get('normalRangeColor')).append(); + }, + + render: function () { + var options = this.options, + target = this.target, + canvasWidth = this.canvasWidth, + canvasHeight = this.canvasHeight, + vertices = this.vertices, + spotRadius = options.get('spotRadius'), + regionMap = this.regionMap, + rangex, rangey, yvallast, + canvasTop, canvasLeft, + vertex, path, paths, x, y, xnext, xpos, xposnext, + last, next, yvalcount, lineShapes, fillShapes, plen, + valueSpots, hlSpotsEnabled, color, xvalues, yvalues, i; + + if (!line._super.render.call(this)) { + return; + } + + this.scanValues(); + this.processRangeOptions(); + + xvalues = this.xvalues; + yvalues = this.yvalues; + + if (!this.yminmax.length || this.yvalues.length < 2) { + // empty or all null valuess + return; + } + + canvasTop = canvasLeft = 0; + + rangex = this.maxx - this.minx === 0 ? 1 : this.maxx - this.minx; + rangey = this.maxy - this.miny === 0 ? 1 : this.maxy - this.miny; + yvallast = this.yvalues.length - 1; + + if (spotRadius && (canvasWidth < (spotRadius * 4) || canvasHeight < (spotRadius * 4))) { + spotRadius = 0; + } + if (spotRadius) { + // adjust the canvas size as required so that spots will fit + hlSpotsEnabled = options.get('highlightSpotColor') && !options.get('disableInteraction'); + if (hlSpotsEnabled || options.get('minSpotColor') || (options.get('spotColor') && yvalues[yvallast] === this.miny)) { + canvasHeight -= Math.ceil(spotRadius); + } + if (hlSpotsEnabled || options.get('maxSpotColor') || (options.get('spotColor') && yvalues[yvallast] === this.maxy)) { + canvasHeight -= Math.ceil(spotRadius); + canvasTop += Math.ceil(spotRadius); + } + if (hlSpotsEnabled || + ((options.get('minSpotColor') || options.get('maxSpotColor')) && (yvalues[0] === this.miny || yvalues[0] === this.maxy))) { + canvasLeft += Math.ceil(spotRadius); + canvasWidth -= Math.ceil(spotRadius); + } + if (hlSpotsEnabled || options.get('spotColor') || + (options.get('minSpotColor') || options.get('maxSpotColor') && + (yvalues[yvallast] === this.miny || yvalues[yvallast] === this.maxy))) { + canvasWidth -= Math.ceil(spotRadius); + } + } + + + canvasHeight--; + + if (options.get('normalRangeMin') !== undefined && !options.get('drawNormalOnTop')) { + this.drawNormalRange(canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey); + } + + path = []; + paths = [path]; + last = next = null; + yvalcount = yvalues.length; + for (i = 0; i < yvalcount; i++) { + x = xvalues[i]; + xnext = xvalues[i + 1]; + y = yvalues[i]; + xpos = canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex)); + xposnext = i < yvalcount - 1 ? canvasLeft + Math.round((xnext - this.minx) * (canvasWidth / rangex)) : canvasWidth; + next = xpos + ((xposnext - xpos) / 2); + regionMap[i] = [last || 0, next, i]; + last = next; + if (y === null) { + if (i) { + if (yvalues[i - 1] !== null) { + path = []; + paths.push(path); + } + vertices.push(null); + } + } else { + if (y < this.miny) { + y = this.miny; + } + if (y > this.maxy) { + y = this.maxy; + } + if (!path.length) { + // previous value was null + path.push([xpos, canvasTop + canvasHeight]); + } + vertex = [xpos, canvasTop + Math.round(canvasHeight - (canvasHeight * ((y - this.miny) / rangey)))]; + path.push(vertex); + vertices.push(vertex); + } + } + + lineShapes = []; + fillShapes = []; + plen = paths.length; + for (i = 0; i < plen; i++) { + path = paths[i]; + if (path.length) { + if (options.get('fillColor')) { + path.push([path[path.length - 1][0], (canvasTop + canvasHeight)]); + fillShapes.push(path.slice(0)); + path.pop(); + } + // if there's only a single point in this path, then we want to display it + // as a vertical line which means we keep path[0] as is + if (path.length > 2) { + // else we want the first value + path[0] = [path[0][0], path[1][1]]; + } + lineShapes.push(path); + } + } + + // draw the fill first, then optionally the normal range, then the line on top of that + plen = fillShapes.length; + for (i = 0; i < plen; i++) { + target.drawShape(fillShapes[i], + options.get('fillColor'), options.get('fillColor')).append(); + } + + if (options.get('normalRangeMin') !== undefined && options.get('drawNormalOnTop')) { + this.drawNormalRange(canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey); + } + + plen = lineShapes.length; + for (i = 0; i < plen; i++) { + target.drawShape(lineShapes[i], options.get('lineColor'), undefined, + options.get('lineWidth')).append(); + } + + if (spotRadius && options.get('valueSpots')) { + valueSpots = options.get('valueSpots'); + if (valueSpots.get === undefined) { + valueSpots = new RangeMap(valueSpots); + } + for (i = 0; i < yvalcount; i++) { + color = valueSpots.get(yvalues[i]); + if (color) { + target.drawCircle(canvasLeft + Math.round((xvalues[i] - this.minx) * (canvasWidth / rangex)), + canvasTop + Math.round(canvasHeight - (canvasHeight * ((yvalues[i] - this.miny) / rangey))), + spotRadius, undefined, + color).append(); + } + } + + } + if (spotRadius && options.get('spotColor') && yvalues[yvallast] !== null) { + target.drawCircle(canvasLeft + Math.round((xvalues[xvalues.length - 1] - this.minx) * (canvasWidth / rangex)), + canvasTop + Math.round(canvasHeight - (canvasHeight * ((yvalues[yvallast] - this.miny) / rangey))), + spotRadius, undefined, + options.get('spotColor')).append(); + } + if (this.maxy !== this.minyorg) { + if (spotRadius && options.get('minSpotColor')) { + x = xvalues[$.inArray(this.minyorg, yvalues)]; + target.drawCircle(canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex)), + canvasTop + Math.round(canvasHeight - (canvasHeight * ((this.minyorg - this.miny) / rangey))), + spotRadius, undefined, + options.get('minSpotColor')).append(); + } + if (spotRadius && options.get('maxSpotColor')) { + x = xvalues[$.inArray(this.maxyorg, yvalues)]; + target.drawCircle(canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex)), + canvasTop + Math.round(canvasHeight - (canvasHeight * ((this.maxyorg - this.miny) / rangey))), + spotRadius, undefined, + options.get('maxSpotColor')).append(); + } + } + + this.lastShapeId = target.getLastShapeId(); + this.canvasTop = canvasTop; + target.render(); + } + }); + + /** + * Bar charts + */ + $.fn.sparkline.bar = bar = createClass($.fn.sparkline._base, barHighlightMixin, { + type: 'bar', + + init: function (el, values, options, width, height) { + var barWidth = parseInt(options.get('barWidth'), 10), + barSpacing = parseInt(options.get('barSpacing'), 10), + chartRangeMin = options.get('chartRangeMin'), + chartRangeMax = options.get('chartRangeMax'), + chartRangeClip = options.get('chartRangeClip'), + stackMin = Infinity, + stackMax = -Infinity, + isStackString, groupMin, groupMax, stackRanges, + numValues, i, vlen, range, zeroAxis, xaxisOffset, min, max, clipMin, clipMax, + stacked, vlist, j, slen, svals, val, yoffset, yMaxCalc, canvasHeightEf; + bar._super.init.call(this, el, values, options, width, height); + + // scan values to determine whether to stack bars + for (i = 0, vlen = values.length; i < vlen; i++) { + val = values[i]; + isStackString = typeof(val) === 'string' && val.indexOf(':') > -1; + if (isStackString || $.isArray(val)) { + stacked = true; + if (isStackString) { + val = values[i] = normalizeValues(val.split(':')); + } + val = remove(val, null); // min/max will treat null as zero + groupMin = Math.min.apply(Math, val); + groupMax = Math.max.apply(Math, val); + if (groupMin < stackMin) { + stackMin = groupMin; + } + if (groupMax > stackMax) { + stackMax = groupMax; + } + } + } + + this.stacked = stacked; + this.regionShapes = {}; + this.barWidth = barWidth; + this.barSpacing = barSpacing; + this.totalBarWidth = barWidth + barSpacing; + this.width = width = (values.length * barWidth) + ((values.length - 1) * barSpacing); + + this.initTarget(); + + if (chartRangeClip) { + clipMin = chartRangeMin === undefined ? -Infinity : chartRangeMin; + clipMax = chartRangeMax === undefined ? Infinity : chartRangeMax; + } + + numValues = []; + stackRanges = stacked ? [] : numValues; + var stackTotals = []; + var stackRangesNeg = []; + for (i = 0, vlen = values.length; i < vlen; i++) { + if (stacked) { + vlist = values[i]; + values[i] = svals = []; + stackTotals[i] = 0; + stackRanges[i] = stackRangesNeg[i] = 0; + for (j = 0, slen = vlist.length; j < slen; j++) { + val = svals[j] = chartRangeClip ? clipval(vlist[j], clipMin, clipMax) : vlist[j]; + if (val !== null) { + if (val > 0) { + stackTotals[i] += val; + } + if (stackMin < 0 && stackMax > 0) { + if (val < 0) { + stackRangesNeg[i] += Math.abs(val); + } else { + stackRanges[i] += val; + } + } else { + stackRanges[i] += Math.abs(val - (val < 0 ? stackMax : stackMin)); + } + numValues.push(val); + } + } + } else { + val = chartRangeClip ? clipval(values[i], clipMin, clipMax) : values[i]; + val = values[i] = normalizeValue(val); + if (val !== null) { + numValues.push(val); + } + } + } + this.max = max = Math.max.apply(Math, numValues); + this.min = min = Math.min.apply(Math, numValues); + this.stackMax = stackMax = stacked ? Math.max.apply(Math, stackTotals) : max; + this.stackMin = stackMin = stacked ? Math.min.apply(Math, numValues) : min; + + if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < min)) { + min = options.get('chartRangeMin'); + } + if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > max)) { + max = options.get('chartRangeMax'); + } + + this.zeroAxis = zeroAxis = options.get('zeroAxis', true); + if (min <= 0 && max >= 0 && zeroAxis) { + xaxisOffset = 0; + } else if (zeroAxis == false) { + xaxisOffset = min; + } else if (min > 0) { + xaxisOffset = min; + } else { + xaxisOffset = max; + } + this.xaxisOffset = xaxisOffset; + + range = stacked ? (Math.max.apply(Math, stackRanges) + Math.max.apply(Math, stackRangesNeg)) : max - min; + + // as we plot zero/min values a single pixel line, we add a pixel to all other + // values - Reduce the effective canvas size to suit + this.canvasHeightEf = (zeroAxis && min < 0) ? this.canvasHeight - 2 : this.canvasHeight - 1; + + if (min < xaxisOffset) { + yMaxCalc = (stacked && max >= 0) ? stackMax : max; + yoffset = (yMaxCalc - xaxisOffset) / range * this.canvasHeight; + if (yoffset !== Math.ceil(yoffset)) { + this.canvasHeightEf -= 2; + yoffset = Math.ceil(yoffset); + } + } else { + yoffset = this.canvasHeight; + } + this.yoffset = yoffset; + + if ($.isArray(options.get('colorMap'))) { + this.colorMapByIndex = options.get('colorMap'); + this.colorMapByValue = null; + } else { + this.colorMapByIndex = null; + this.colorMapByValue = options.get('colorMap'); + if (this.colorMapByValue && this.colorMapByValue.get === undefined) { + this.colorMapByValue = new RangeMap(this.colorMapByValue); + } + } + + this.range = range; + }, + + getRegion: function (el, x, y) { + var result = Math.floor(x / this.totalBarWidth); + return (result < 0 || result >= this.values.length) ? undefined : result; + }, + + getCurrentRegionFields: function () { + var currentRegion = this.currentRegion, + values = ensureArray(this.values[currentRegion]), + result = [], + value, i; + for (i = values.length; i--;) { + value = values[i]; + result.push({ + isNull: value === null, + value: value, + color: this.calcColor(i, value, currentRegion), + offset: currentRegion + }); + } + return result; + }, + + calcColor: function (stacknum, value, valuenum) { + var colorMapByIndex = this.colorMapByIndex, + colorMapByValue = this.colorMapByValue, + options = this.options, + color, newColor; + if (this.stacked) { + color = options.get('stackedBarColor'); + } else { + color = (value < 0) ? options.get('negBarColor') : options.get('barColor'); + } + if (value === 0 && options.get('zeroColor') !== undefined) { + color = options.get('zeroColor'); + } + if (colorMapByValue && (newColor = colorMapByValue.get(value))) { + color = newColor; + } else if (colorMapByIndex && colorMapByIndex.length > valuenum) { + color = colorMapByIndex[valuenum]; + } + return $.isArray(color) ? color[stacknum % color.length] : color; + }, + + /** + * Render bar(s) for a region + */ + renderRegion: function (valuenum, highlight) { + var vals = this.values[valuenum], + options = this.options, + xaxisOffset = this.xaxisOffset, + result = [], + range = this.range, + stacked = this.stacked, + target = this.target, + x = valuenum * this.totalBarWidth, + canvasHeightEf = this.canvasHeightEf, + yoffset = this.yoffset, + y, height, color, isNull, yoffsetNeg, i, valcount, val, minPlotted, allMin; + + vals = $.isArray(vals) ? vals : [vals]; + valcount = vals.length; + val = vals[0]; + isNull = all(null, vals); + allMin = all(xaxisOffset, vals, true); + + if (isNull) { + if (options.get('nullColor')) { + color = highlight ? options.get('nullColor') : this.calcHighlightColor(options.get('nullColor'), options); + y = (yoffset > 0) ? yoffset - 1 : yoffset; + return target.drawRect(x, y, this.barWidth - 1, 0, color, color); + } else { + return undefined; + } + } + yoffsetNeg = yoffset; + for (i = 0; i < valcount; i++) { + val = vals[i]; + + if (stacked && val === xaxisOffset) { + if (!allMin || minPlotted) { + continue; + } + minPlotted = true; + } + + if (range > 0) { + height = Math.floor(canvasHeightEf * ((Math.abs(val - xaxisOffset) / range))) + 1; + } else { + height = 1; + } + if (val < xaxisOffset || (val === xaxisOffset && yoffset === 0)) { + y = yoffsetNeg; + yoffsetNeg += height; + } else { + y = yoffset - height; + yoffset -= height; + } + color = this.calcColor(i, val, valuenum); + if (highlight) { + color = this.calcHighlightColor(color, options); + } + result.push(target.drawRect(x, y, this.barWidth - 1, height - 1, color, color)); + } + if (result.length === 1) { + return result[0]; + } + return result; + } + }); + + /** + * Tristate charts + */ + $.fn.sparkline.tristate = tristate = createClass($.fn.sparkline._base, barHighlightMixin, { + type: 'tristate', + + init: function (el, values, options, width, height) { + var barWidth = parseInt(options.get('barWidth'), 10), + barSpacing = parseInt(options.get('barSpacing'), 10); + tristate._super.init.call(this, el, values, options, width, height); + + this.regionShapes = {}; + this.barWidth = barWidth; + this.barSpacing = barSpacing; + this.totalBarWidth = barWidth + barSpacing; + this.values = $.map(values, Number); + this.width = width = (values.length * barWidth) + ((values.length - 1) * barSpacing); + + if ($.isArray(options.get('colorMap'))) { + this.colorMapByIndex = options.get('colorMap'); + this.colorMapByValue = null; + } else { + this.colorMapByIndex = null; + this.colorMapByValue = options.get('colorMap'); + if (this.colorMapByValue && this.colorMapByValue.get === undefined) { + this.colorMapByValue = new RangeMap(this.colorMapByValue); + } + } + this.initTarget(); + }, + + getRegion: function (el, x, y) { + return Math.floor(x / this.totalBarWidth); + }, + + getCurrentRegionFields: function () { + var currentRegion = this.currentRegion; + return { + isNull: this.values[currentRegion] === undefined, + value: this.values[currentRegion], + color: this.calcColor(this.values[currentRegion], currentRegion), + offset: currentRegion + }; + }, + + calcColor: function (value, valuenum) { + var values = this.values, + options = this.options, + colorMapByIndex = this.colorMapByIndex, + colorMapByValue = this.colorMapByValue, + color, newColor; + + if (colorMapByValue && (newColor = colorMapByValue.get(value))) { + color = newColor; + } else if (colorMapByIndex && colorMapByIndex.length > valuenum) { + color = colorMapByIndex[valuenum]; + } else if (values[valuenum] < 0) { + color = options.get('negBarColor'); + } else if (values[valuenum] > 0) { + color = options.get('posBarColor'); + } else { + color = options.get('zeroBarColor'); + } + return color; + }, + + renderRegion: function (valuenum, highlight) { + var values = this.values, + options = this.options, + target = this.target, + canvasHeight, height, halfHeight, + x, y, color; + + canvasHeight = target.pixelHeight; + halfHeight = Math.round(canvasHeight / 2); + + x = valuenum * this.totalBarWidth; + if (values[valuenum] < 0) { + y = halfHeight; + height = halfHeight - 1; + } else if (values[valuenum] > 0) { + y = 0; + height = halfHeight - 1; + } else { + y = halfHeight - 1; + height = 2; + } + color = this.calcColor(values[valuenum], valuenum); + if (color === null) { + return; + } + if (highlight) { + color = this.calcHighlightColor(color, options); + } + return target.drawRect(x, y, this.barWidth - 1, height - 1, color, color); + } + }); + + /** + * Discrete charts + */ + $.fn.sparkline.discrete = discrete = createClass($.fn.sparkline._base, barHighlightMixin, { + type: 'discrete', + + init: function (el, values, options, width, height) { + discrete._super.init.call(this, el, values, options, width, height); + + this.regionShapes = {}; + this.values = values = $.map(values, Number); + this.min = Math.min.apply(Math, values); + this.max = Math.max.apply(Math, values); + this.range = this.max - this.min; + this.width = width = options.get('width') === 'auto' ? values.length * 2 : this.width; + this.interval = Math.floor(width / values.length); + this.itemWidth = width / values.length; + if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < this.min)) { + this.min = options.get('chartRangeMin'); + } + if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > this.max)) { + this.max = options.get('chartRangeMax'); + } + this.initTarget(); + if (this.target) { + this.lineHeight = options.get('lineHeight') === 'auto' ? Math.round(this.canvasHeight * 0.3) : options.get('lineHeight'); + } + }, + + getRegion: function (el, x, y) { + return Math.floor(x / this.itemWidth); + }, + + getCurrentRegionFields: function () { + var currentRegion = this.currentRegion; + return { + isNull: this.values[currentRegion] === undefined, + value: this.values[currentRegion], + offset: currentRegion + }; + }, + + renderRegion: function (valuenum, highlight) { + var values = this.values, + options = this.options, + min = this.min, + max = this.max, + range = this.range, + interval = this.interval, + target = this.target, + canvasHeight = this.canvasHeight, + lineHeight = this.lineHeight, + pheight = canvasHeight - lineHeight, + ytop, val, color, x; + + val = clipval(values[valuenum], min, max); + x = valuenum * interval; + ytop = Math.round(pheight - pheight * ((val - min) / range)); + color = (options.get('thresholdColor') && val < options.get('thresholdValue')) ? options.get('thresholdColor') : options.get('lineColor'); + if (highlight) { + color = this.calcHighlightColor(color, options); + } + return target.drawLine(x, ytop, x, ytop + lineHeight, color); + } + }); + + /** + * Bullet charts + */ + $.fn.sparkline.bullet = bullet = createClass($.fn.sparkline._base, { + type: 'bullet', + + init: function (el, values, options, width, height) { + var min, max, vals; + bullet._super.init.call(this, el, values, options, width, height); + + // values: target, performance, range1, range2, range3 + this.values = values = normalizeValues(values); + // target or performance could be null + vals = values.slice(); + vals[0] = vals[0] === null ? vals[2] : vals[0]; + vals[1] = values[1] === null ? vals[2] : vals[1]; + min = Math.min.apply(Math, values); + max = Math.max.apply(Math, values); + if (options.get('base') === undefined) { + min = min < 0 ? min : 0; + } else { + min = options.get('base'); + } + this.min = min; + this.max = max; + this.range = max - min; + this.shapes = {}; + this.valueShapes = {}; + this.regiondata = {}; + this.width = width = options.get('width') === 'auto' ? '4.0em' : width; + this.target = this.$el.simpledraw(width, height, options.get('composite')); + if (!values.length) { + this.disabled = true; + } + this.initTarget(); + }, + + getRegion: function (el, x, y) { + var shapeid = this.target.getShapeAt(el, x, y); + return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined; + }, + + getCurrentRegionFields: function () { + var currentRegion = this.currentRegion; + return { + fieldkey: currentRegion.substr(0, 1), + value: this.values[currentRegion.substr(1)], + region: currentRegion + }; + }, + + changeHighlight: function (highlight) { + var currentRegion = this.currentRegion, + shapeid = this.valueShapes[currentRegion], + shape; + delete this.shapes[shapeid]; + switch (currentRegion.substr(0, 1)) { + case 'r': + shape = this.renderRange(currentRegion.substr(1), highlight); + break; + case 'p': + shape = this.renderPerformance(highlight); + break; + case 't': + shape = this.renderTarget(highlight); + break; + } + this.valueShapes[currentRegion] = shape.id; + this.shapes[shape.id] = currentRegion; + this.target.replaceWithShape(shapeid, shape); + }, + + renderRange: function (rn, highlight) { + var rangeval = this.values[rn], + rangewidth = Math.round(this.canvasWidth * ((rangeval - this.min) / this.range)), + color = this.options.get('rangeColors')[rn - 2]; + if (highlight) { + color = this.calcHighlightColor(color, this.options); + } + return this.target.drawRect(0, 0, rangewidth - 1, this.canvasHeight - 1, color, color); + }, + + renderPerformance: function (highlight) { + var perfval = this.values[1], + perfwidth = Math.round(this.canvasWidth * ((perfval - this.min) / this.range)), + color = this.options.get('performanceColor'); + if (highlight) { + color = this.calcHighlightColor(color, this.options); + } + return this.target.drawRect(0, Math.round(this.canvasHeight * 0.3), perfwidth - 1, + Math.round(this.canvasHeight * 0.4) - 1, color, color); + }, + + renderTarget: function (highlight) { + var targetval = this.values[0], + x = Math.round(this.canvasWidth * ((targetval - this.min) / this.range) - (this.options.get('targetWidth') / 2)), + targettop = Math.round(this.canvasHeight * 0.10), + targetheight = this.canvasHeight - (targettop * 2), + color = this.options.get('targetColor'); + if (highlight) { + color = this.calcHighlightColor(color, this.options); + } + return this.target.drawRect(x, targettop, this.options.get('targetWidth') - 1, targetheight - 1, color, color); + }, + + render: function () { + var vlen = this.values.length, + target = this.target, + i, shape; + if (!bullet._super.render.call(this)) { + return; + } + for (i = 2; i < vlen; i++) { + shape = this.renderRange(i).append(); + this.shapes[shape.id] = 'r' + i; + this.valueShapes['r' + i] = shape.id; + } + if (this.values[1] !== null) { + shape = this.renderPerformance().append(); + this.shapes[shape.id] = 'p1'; + this.valueShapes.p1 = shape.id; + } + if (this.values[0] !== null) { + shape = this.renderTarget().append(); + this.shapes[shape.id] = 't0'; + this.valueShapes.t0 = shape.id; + } + target.render(); + } + }); + + /** + * Pie charts + */ + $.fn.sparkline.pie = pie = createClass($.fn.sparkline._base, { + type: 'pie', + + init: function (el, values, options, width, height) { + var total = 0, i; + + pie._super.init.call(this, el, values, options, width, height); + + this.shapes = {}; // map shape ids to value offsets + this.valueShapes = {}; // maps value offsets to shape ids + this.values = values = $.map(values, Number); + + if (options.get('width') === 'auto') { + this.width = this.height; + } + + if (values.length > 0) { + for (i = values.length; i--;) { + total += values[i]; + } + } + this.total = total; + this.initTarget(); + this.radius = Math.floor(Math.min(this.canvasWidth, this.canvasHeight) / 2); + }, + + getRegion: function (el, x, y) { + var shapeid = this.target.getShapeAt(el, x, y); + return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined; + }, + + getCurrentRegionFields: function () { + var currentRegion = this.currentRegion; + return { + isNull: this.values[currentRegion] === undefined, + value: this.values[currentRegion], + percent: this.values[currentRegion] / this.total * 100, + color: this.options.get('sliceColors')[currentRegion % this.options.get('sliceColors').length], + offset: currentRegion + }; + }, + + changeHighlight: function (highlight) { + var currentRegion = this.currentRegion, + newslice = this.renderSlice(currentRegion, highlight), + shapeid = this.valueShapes[currentRegion]; + delete this.shapes[shapeid]; + this.target.replaceWithShape(shapeid, newslice); + this.valueShapes[currentRegion] = newslice.id; + this.shapes[newslice.id] = currentRegion; + }, + + renderSlice: function (valuenum, highlight) { + var target = this.target, + options = this.options, + radius = this.radius, + borderWidth = options.get('borderWidth'), + offset = options.get('offset'), + circle = 2 * Math.PI, + values = this.values, + total = this.total, + next = offset ? (2*Math.PI)*(offset/360) : 0, + start, end, i, vlen, color; + + vlen = values.length; + for (i = 0; i < vlen; i++) { + start = next; + end = next; + if (total > 0) { // avoid divide by zero + end = next + (circle * (values[i] / total)); + } + if (valuenum === i) { + color = options.get('sliceColors')[i % options.get('sliceColors').length]; + if (highlight) { + color = this.calcHighlightColor(color, options); + } + + return target.drawPieSlice(radius, radius, radius - borderWidth, start, end, undefined, color); + } + next = end; + } + }, + + render: function () { + var target = this.target, + values = this.values, + options = this.options, + radius = this.radius, + borderWidth = options.get('borderWidth'), + shape, i; + + if (!pie._super.render.call(this)) { + return; + } + if (borderWidth) { + target.drawCircle(radius, radius, Math.floor(radius - (borderWidth / 2)), + options.get('borderColor'), undefined, borderWidth).append(); + } + for (i = values.length; i--;) { + if (values[i]) { // don't render zero values + shape = this.renderSlice(i).append(); + this.valueShapes[i] = shape.id; // store just the shapeid + this.shapes[shape.id] = i; + } + } + target.render(); + } + }); + + /** + * Box plots + */ + $.fn.sparkline.box = box = createClass($.fn.sparkline._base, { + type: 'box', + + init: function (el, values, options, width, height) { + box._super.init.call(this, el, values, options, width, height); + this.values = $.map(values, Number); + this.width = options.get('width') === 'auto' ? '4.0em' : width; + this.initTarget(); + if (!this.values.length) { + this.disabled = 1; + } + }, + + /** + * Simulate a single region + */ + getRegion: function () { + return 1; + }, + + getCurrentRegionFields: function () { + var result = [ + { field: 'lq', value: this.quartiles[0] }, + { field: 'med', value: this.quartiles[1] }, + { field: 'uq', value: this.quartiles[2] } + ]; + if (this.loutlier !== undefined) { + result.push({ field: 'lo', value: this.loutlier}); + } + if (this.routlier !== undefined) { + result.push({ field: 'ro', value: this.routlier}); + } + if (this.lwhisker !== undefined) { + result.push({ field: 'lw', value: this.lwhisker}); + } + if (this.rwhisker !== undefined) { + result.push({ field: 'rw', value: this.rwhisker}); + } + return result; + }, + + render: function () { + var target = this.target, + values = this.values, + vlen = values.length, + options = this.options, + canvasWidth = this.canvasWidth, + canvasHeight = this.canvasHeight, + minValue = options.get('chartRangeMin') === undefined ? Math.min.apply(Math, values) : options.get('chartRangeMin'), + maxValue = options.get('chartRangeMax') === undefined ? Math.max.apply(Math, values) : options.get('chartRangeMax'), + canvasLeft = 0, + lwhisker, loutlier, iqr, q1, q2, q3, rwhisker, routlier, i, + size, unitSize; + + if (!box._super.render.call(this)) { + return; + } + + if (options.get('raw')) { + if (options.get('showOutliers') && values.length > 5) { + loutlier = values[0]; + lwhisker = values[1]; + q1 = values[2]; + q2 = values[3]; + q3 = values[4]; + rwhisker = values[5]; + routlier = values[6]; + } else { + lwhisker = values[0]; + q1 = values[1]; + q2 = values[2]; + q3 = values[3]; + rwhisker = values[4]; + } + } else { + values.sort(function (a, b) { return a - b; }); + q1 = quartile(values, 1); + q2 = quartile(values, 2); + q3 = quartile(values, 3); + iqr = q3 - q1; + if (options.get('showOutliers')) { + lwhisker = rwhisker = undefined; + for (i = 0; i < vlen; i++) { + if (lwhisker === undefined && values[i] > q1 - (iqr * options.get('outlierIQR'))) { + lwhisker = values[i]; + } + if (values[i] < q3 + (iqr * options.get('outlierIQR'))) { + rwhisker = values[i]; + } + } + loutlier = values[0]; + routlier = values[vlen - 1]; + } else { + lwhisker = values[0]; + rwhisker = values[vlen - 1]; + } + } + this.quartiles = [q1, q2, q3]; + this.lwhisker = lwhisker; + this.rwhisker = rwhisker; + this.loutlier = loutlier; + this.routlier = routlier; + + unitSize = canvasWidth / (maxValue - minValue + 1); + if (options.get('showOutliers')) { + canvasLeft = Math.ceil(options.get('spotRadius')); + canvasWidth -= 2 * Math.ceil(options.get('spotRadius')); + unitSize = canvasWidth / (maxValue - minValue + 1); + if (loutlier < lwhisker) { + target.drawCircle((loutlier - minValue) * unitSize + canvasLeft, + canvasHeight / 2, + options.get('spotRadius'), + options.get('outlierLineColor'), + options.get('outlierFillColor')).append(); + } + if (routlier > rwhisker) { + target.drawCircle((routlier - minValue) * unitSize + canvasLeft, + canvasHeight / 2, + options.get('spotRadius'), + options.get('outlierLineColor'), + options.get('outlierFillColor')).append(); + } + } + + // box + target.drawRect( + Math.round((q1 - minValue) * unitSize + canvasLeft), + Math.round(canvasHeight * 0.1), + Math.round((q3 - q1) * unitSize), + Math.round(canvasHeight * 0.8), + options.get('boxLineColor'), + options.get('boxFillColor')).append(); + // left whisker + target.drawLine( + Math.round((lwhisker - minValue) * unitSize + canvasLeft), + Math.round(canvasHeight / 2), + Math.round((q1 - minValue) * unitSize + canvasLeft), + Math.round(canvasHeight / 2), + options.get('lineColor')).append(); + target.drawLine( + Math.round((lwhisker - minValue) * unitSize + canvasLeft), + Math.round(canvasHeight / 4), + Math.round((lwhisker - minValue) * unitSize + canvasLeft), + Math.round(canvasHeight - canvasHeight / 4), + options.get('whiskerColor')).append(); + // right whisker + target.drawLine(Math.round((rwhisker - minValue) * unitSize + canvasLeft), + Math.round(canvasHeight / 2), + Math.round((q3 - minValue) * unitSize + canvasLeft), + Math.round(canvasHeight / 2), + options.get('lineColor')).append(); + target.drawLine( + Math.round((rwhisker - minValue) * unitSize + canvasLeft), + Math.round(canvasHeight / 4), + Math.round((rwhisker - minValue) * unitSize + canvasLeft), + Math.round(canvasHeight - canvasHeight / 4), + options.get('whiskerColor')).append(); + // median line + target.drawLine( + Math.round((q2 - minValue) * unitSize + canvasLeft), + Math.round(canvasHeight * 0.1), + Math.round((q2 - minValue) * unitSize + canvasLeft), + Math.round(canvasHeight * 0.9), + options.get('medianColor')).append(); + if (options.get('target')) { + size = Math.ceil(options.get('spotRadius')); + target.drawLine( + Math.round((options.get('target') - minValue) * unitSize + canvasLeft), + Math.round((canvasHeight / 2) - size), + Math.round((options.get('target') - minValue) * unitSize + canvasLeft), + Math.round((canvasHeight / 2) + size), + options.get('targetColor')).append(); + target.drawLine( + Math.round((options.get('target') - minValue) * unitSize + canvasLeft - size), + Math.round(canvasHeight / 2), + Math.round((options.get('target') - minValue) * unitSize + canvasLeft + size), + Math.round(canvasHeight / 2), + options.get('targetColor')).append(); + } + target.render(); + } + }); + + // Setup a very simple "virtual canvas" to make drawing the few shapes we need easier + // This is accessible as $(foo).simpledraw() + + // Detect browser renderer support + (function() { + if (document.namespaces && !document.namespaces.v) { + $.fn.sparkline.hasVML = true; + document.namespaces.add('v', 'urn:schemas-microsoft-com:vml', '#default#VML'); + } else { + $.fn.sparkline.hasVML = false; + } + + var el = document.createElement('canvas'); + $.fn.sparkline.hasCanvas = !!(el.getContext && el.getContext('2d')); + + })() + + VShape = createClass({ + init: function (target, id, type, args) { + this.target = target; + this.id = id; + this.type = type; + this.args = args; + }, + append: function () { + this.target.appendShape(this); + return this; + } + }); + + VCanvas_base = createClass({ + _pxregex: /(\d+)(px)?\s*$/i, + + init: function (width, height, target) { + if (!width) { + return; + } + this.width = width; + this.height = height; + this.target = target; + this.lastShapeId = null; + if (target[0]) { + target = target[0]; + } + $.data(target, '_jqs_vcanvas', this); + }, + + drawLine: function (x1, y1, x2, y2, lineColor, lineWidth) { + return this.drawShape([[x1, y1], [x2, y2]], lineColor, lineWidth); + }, + + drawShape: function (path, lineColor, fillColor, lineWidth) { + return this._genShape('Shape', [path, lineColor, fillColor, lineWidth]); + }, + + drawCircle: function (x, y, radius, lineColor, fillColor, lineWidth) { + return this._genShape('Circle', [x, y, radius, lineColor, fillColor, lineWidth]); + }, + + drawPieSlice: function (x, y, radius, startAngle, endAngle, lineColor, fillColor) { + return this._genShape('PieSlice', [x, y, radius, startAngle, endAngle, lineColor, fillColor]); + }, + + drawRect: function (x, y, width, height, lineColor, fillColor) { + return this._genShape('Rect', [x, y, width, height, lineColor, fillColor]); + }, + + getElement: function () { + return this.canvas; + }, + + /** + * Return the most recently inserted shape id + */ + getLastShapeId: function () { + return this.lastShapeId; + }, + + /** + * Clear and reset the canvas + */ + reset: function () { + alert('reset not implemented'); + }, + + _insert: function (el, target) { + $(target).html(el); + }, + + /** + * Calculate the pixel dimensions of the canvas + */ + _calculatePixelDims: function (width, height, canvas) { + // XXX This should probably be a configurable option + var match; + match = this._pxregex.exec(height); + if (match) { + this.pixelHeight = match[1]; + } else { + this.pixelHeight = $(canvas).height(); + } + match = this._pxregex.exec(width); + if (match) { + this.pixelWidth = match[1]; + } else { + this.pixelWidth = $(canvas).width(); + } + }, + + /** + * Generate a shape object and id for later rendering + */ + _genShape: function (shapetype, shapeargs) { + var id = shapeCount++; + shapeargs.unshift(id); + return new VShape(this, id, shapetype, shapeargs); + }, + + /** + * Add a shape to the end of the render queue + */ + appendShape: function (shape) { + alert('appendShape not implemented'); + }, + + /** + * Replace one shape with another + */ + replaceWithShape: function (shapeid, shape) { + alert('replaceWithShape not implemented'); + }, + + /** + * Insert one shape after another in the render queue + */ + insertAfterShape: function (shapeid, shape) { + alert('insertAfterShape not implemented'); + }, + + /** + * Remove a shape from the queue + */ + removeShapeId: function (shapeid) { + alert('removeShapeId not implemented'); + }, + + /** + * Find a shape at the specified x/y co-ordinates + */ + getShapeAt: function (el, x, y) { + alert('getShapeAt not implemented'); + }, + + /** + * Render all queued shapes onto the canvas + */ + render: function () { + alert('render not implemented'); + } + }); + + VCanvas_canvas = createClass(VCanvas_base, { + init: function (width, height, target, interact) { + VCanvas_canvas._super.init.call(this, width, height, target); + this.canvas = document.createElement('canvas'); + if (target[0]) { + target = target[0]; + } + $.data(target, '_jqs_vcanvas', this); + $(this.canvas).css({ display: 'inline-block', width: width, height: height, verticalAlign: 'top' }); + this._insert(this.canvas, target); + this._calculatePixelDims(width, height, this.canvas); + this.canvas.width = this.pixelWidth; + this.canvas.height = this.pixelHeight; + this.interact = interact; + this.shapes = {}; + this.shapeseq = []; + this.currentTargetShapeId = undefined; + $(this.canvas).css({width: this.pixelWidth, height: this.pixelHeight}); + }, + + _getContext: function (lineColor, fillColor, lineWidth) { + var context = this.canvas.getContext('2d'); + if (lineColor !== undefined) { + context.strokeStyle = lineColor; + } + context.lineWidth = lineWidth === undefined ? 1 : lineWidth; + if (fillColor !== undefined) { + context.fillStyle = fillColor; + } + return context; + }, + + reset: function () { + var context = this._getContext(); + context.clearRect(0, 0, this.pixelWidth, this.pixelHeight); + this.shapes = {}; + this.shapeseq = []; + this.currentTargetShapeId = undefined; + }, + + _drawShape: function (shapeid, path, lineColor, fillColor, lineWidth) { + var context = this._getContext(lineColor, fillColor, lineWidth), + i, plen; + context.beginPath(); + context.moveTo(path[0][0] + 0.5, path[0][1] + 0.5); + for (i = 1, plen = path.length; i < plen; i++) { + context.lineTo(path[i][0] + 0.5, path[i][1] + 0.5); // the 0.5 offset gives us crisp pixel-width lines + } + if (lineColor !== undefined) { + context.stroke(); + } + if (fillColor !== undefined) { + context.fill(); + } + if (this.targetX !== undefined && this.targetY !== undefined && + context.isPointInPath(this.targetX, this.targetY)) { + this.currentTargetShapeId = shapeid; + } + }, + + _drawCircle: function (shapeid, x, y, radius, lineColor, fillColor, lineWidth) { + var context = this._getContext(lineColor, fillColor, lineWidth); + context.beginPath(); + context.arc(x, y, radius, 0, 2 * Math.PI, false); + if (this.targetX !== undefined && this.targetY !== undefined && + context.isPointInPath(this.targetX, this.targetY)) { + this.currentTargetShapeId = shapeid; + } + if (lineColor !== undefined) { + context.stroke(); + } + if (fillColor !== undefined) { + context.fill(); + } + }, + + _drawPieSlice: function (shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) { + var context = this._getContext(lineColor, fillColor); + context.beginPath(); + context.moveTo(x, y); + context.arc(x, y, radius, startAngle, endAngle, false); + context.lineTo(x, y); + context.closePath(); + if (lineColor !== undefined) { + context.stroke(); + } + if (fillColor) { + context.fill(); + } + if (this.targetX !== undefined && this.targetY !== undefined && + context.isPointInPath(this.targetX, this.targetY)) { + this.currentTargetShapeId = shapeid; + } + }, + + _drawRect: function (shapeid, x, y, width, height, lineColor, fillColor) { + return this._drawShape(shapeid, [[x, y], [x + width, y], [x + width, y + height], [x, y + height], [x, y]], lineColor, fillColor); + }, + + appendShape: function (shape) { + this.shapes[shape.id] = shape; + this.shapeseq.push(shape.id); + this.lastShapeId = shape.id; + return shape.id; + }, + + replaceWithShape: function (shapeid, shape) { + var shapeseq = this.shapeseq, + i; + this.shapes[shape.id] = shape; + for (i = shapeseq.length; i--;) { + if (shapeseq[i] == shapeid) { + shapeseq[i] = shape.id; + } + } + delete this.shapes[shapeid]; + }, + + replaceWithShapes: function (shapeids, shapes) { + var shapeseq = this.shapeseq, + shapemap = {}, + sid, i, first; + + for (i = shapeids.length; i--;) { + shapemap[shapeids[i]] = true; + } + for (i = shapeseq.length; i--;) { + sid = shapeseq[i]; + if (shapemap[sid]) { + shapeseq.splice(i, 1); + delete this.shapes[sid]; + first = i; + } + } + for (i = shapes.length; i--;) { + shapeseq.splice(first, 0, shapes[i].id); + this.shapes[shapes[i].id] = shapes[i]; + } + + }, + + insertAfterShape: function (shapeid, shape) { + var shapeseq = this.shapeseq, + i; + for (i = shapeseq.length; i--;) { + if (shapeseq[i] === shapeid) { + shapeseq.splice(i + 1, 0, shape.id); + this.shapes[shape.id] = shape; + return; + } + } + }, + + removeShapeId: function (shapeid) { + var shapeseq = this.shapeseq, + i; + for (i = shapeseq.length; i--;) { + if (shapeseq[i] === shapeid) { + shapeseq.splice(i, 1); + break; + } + } + delete this.shapes[shapeid]; + }, + + getShapeAt: function (el, x, y) { + this.targetX = x; + this.targetY = y; + this.render(); + return this.currentTargetShapeId; + }, + + render: function () { + var shapeseq = this.shapeseq, + shapes = this.shapes, + shapeCount = shapeseq.length, + context = this._getContext(), + shapeid, shape, i; + context.clearRect(0, 0, this.pixelWidth, this.pixelHeight); + for (i = 0; i < shapeCount; i++) { + shapeid = shapeseq[i]; + shape = shapes[shapeid]; + this['_draw' + shape.type].apply(this, shape.args); + } + if (!this.interact) { + // not interactive so no need to keep the shapes array + this.shapes = {}; + this.shapeseq = []; + } + } + + }); + + VCanvas_vml = createClass(VCanvas_base, { + init: function (width, height, target) { + var groupel; + VCanvas_vml._super.init.call(this, width, height, target); + if (target[0]) { + target = target[0]; + } + $.data(target, '_jqs_vcanvas', this); + this.canvas = document.createElement('span'); + $(this.canvas).css({ display: 'inline-block', position: 'relative', overflow: 'hidden', width: width, height: height, margin: '0px', padding: '0px', verticalAlign: 'top'}); + this._insert(this.canvas, target); + this._calculatePixelDims(width, height, this.canvas); + this.canvas.width = this.pixelWidth; + this.canvas.height = this.pixelHeight; + groupel = '<v:group coordorigin="0 0" coordsize="' + this.pixelWidth + ' ' + this.pixelHeight + '"' + + ' style="position:absolute;top:0;left:0;width:' + this.pixelWidth + 'px;height=' + this.pixelHeight + 'px;"></v:group>'; + this.canvas.insertAdjacentHTML('beforeEnd', groupel); + this.group = $(this.canvas).children()[0]; + this.rendered = false; + this.prerender = ''; + }, + + _drawShape: function (shapeid, path, lineColor, fillColor, lineWidth) { + var vpath = [], + initial, stroke, fill, closed, vel, plen, i; + for (i = 0, plen = path.length; i < plen; i++) { + vpath[i] = '' + (path[i][0]) + ',' + (path[i][1]); + } + initial = vpath.splice(0, 1); + lineWidth = lineWidth === undefined ? 1 : lineWidth; + stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="' + lineWidth + 'px" strokeColor="' + lineColor + '" '; + fill = fillColor === undefined ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" '; + closed = vpath[0] === vpath[vpath.length - 1] ? 'x ' : ''; + vel = '<v:shape coordorigin="0 0" coordsize="' + this.pixelWidth + ' ' + this.pixelHeight + '" ' + + ' id="jqsshape' + shapeid + '" ' + + stroke + + fill + + ' style="position:absolute;left:0px;top:0px;height:' + this.pixelHeight + 'px;width:' + this.pixelWidth + 'px;padding:0px;margin:0px;" ' + + ' path="m ' + initial + ' l ' + vpath.join(', ') + ' ' + closed + 'e">' + + ' </v:shape>'; + return vel; + }, + + _drawCircle: function (shapeid, x, y, radius, lineColor, fillColor, lineWidth) { + var stroke, fill, vel; + x -= radius; + y -= radius; + stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="' + lineWidth + 'px" strokeColor="' + lineColor + '" '; + fill = fillColor === undefined ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" '; + vel = '<v:oval ' + + ' id="jqsshape' + shapeid + '" ' + + stroke + + fill + + ' style="position:absolute;top:' + y + 'px; left:' + x + 'px; width:' + (radius * 2) + 'px; height:' + (radius * 2) + 'px"></v:oval>'; + return vel; + + }, + + _drawPieSlice: function (shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) { + var vpath, startx, starty, endx, endy, stroke, fill, vel; + if (startAngle === endAngle) { + return ''; // VML seems to have problem when start angle equals end angle. + } + if ((endAngle - startAngle) === (2 * Math.PI)) { + startAngle = 0.0; // VML seems to have a problem when drawing a full circle that doesn't start 0 + endAngle = (2 * Math.PI); + } + + startx = x + Math.round(Math.cos(startAngle) * radius); + starty = y + Math.round(Math.sin(startAngle) * radius); + endx = x + Math.round(Math.cos(endAngle) * radius); + endy = y + Math.round(Math.sin(endAngle) * radius); + + if (startx === endx && starty === endy) { + if ((endAngle - startAngle) < Math.PI) { + // Prevent very small slices from being mistaken as a whole pie + return ''; + } + // essentially going to be the entire circle, so ignore startAngle + startx = endx = x + radius; + starty = endy = y; + } + + if (startx === endx && starty === endy && (endAngle - startAngle) < Math.PI) { + return ''; + } + + vpath = [x - radius, y - radius, x + radius, y + radius, startx, starty, endx, endy]; + stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="1px" strokeColor="' + lineColor + '" '; + fill = fillColor === undefined ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" '; + vel = '<v:shape coordorigin="0 0" coordsize="' + this.pixelWidth + ' ' + this.pixelHeight + '" ' + + ' id="jqsshape' + shapeid + '" ' + + stroke + + fill + + ' style="position:absolute;left:0px;top:0px;height:' + this.pixelHeight + 'px;width:' + this.pixelWidth + 'px;padding:0px;margin:0px;" ' + + ' path="m ' + x + ',' + y + ' wa ' + vpath.join(', ') + ' x e">' + + ' </v:shape>'; + return vel; + }, + + _drawRect: function (shapeid, x, y, width, height, lineColor, fillColor) { + return this._drawShape(shapeid, [[x, y], [x, y + height], [x + width, y + height], [x + width, y], [x, y]], lineColor, fillColor); + }, + + reset: function () { + this.group.innerHTML = ''; + }, + + appendShape: function (shape) { + var vel = this['_draw' + shape.type].apply(this, shape.args); + if (this.rendered) { + this.group.insertAdjacentHTML('beforeEnd', vel); + } else { + this.prerender += vel; + } + this.lastShapeId = shape.id; + return shape.id; + }, + + replaceWithShape: function (shapeid, shape) { + var existing = $('#jqsshape' + shapeid), + vel = this['_draw' + shape.type].apply(this, shape.args); + existing[0].outerHTML = vel; + }, + + replaceWithShapes: function (shapeids, shapes) { + // replace the first shapeid with all the new shapes then toast the remaining old shapes + var existing = $('#jqsshape' + shapeids[0]), + replace = '', + slen = shapes.length, + i; + for (i = 0; i < slen; i++) { + replace += this['_draw' + shapes[i].type].apply(this, shapes[i].args); + } + existing[0].outerHTML = replace; + for (i = 1; i < shapeids.length; i++) { + $('#jqsshape' + shapeids[i]).remove(); + } + }, + + insertAfterShape: function (shapeid, shape) { + var existing = $('#jqsshape' + shapeid), + vel = this['_draw' + shape.type].apply(this, shape.args); + existing[0].insertAdjacentHTML('afterEnd', vel); + }, + + removeShapeId: function (shapeid) { + var existing = $('#jqsshape' + shapeid); + this.group.removeChild(existing[0]); + }, + + getShapeAt: function (el, x, y) { + var shapeid = el.id.substr(8); + return shapeid; + }, + + render: function () { + if (!this.rendered) { + // batch the intial render into a single repaint + this.group.innerHTML = this.prerender; + this.rendered = true; + } + } + }); + +})); +/* +Turbolinks 5.0.0 +Copyright © 2016 Basecamp, LLC + */ + +(function(){(function(){(function(){this.Turbolinks={supported:function(){return null!=window.history.pushState&&null!=window.requestAnimationFrame}(),visit:function(e,r){return t.controller.visit(e,r)},clearCache:function(){return t.controller.clearCache()}}}).call(this)}).call(this);var t=this.Turbolinks;(function(){(function(){var e,r;t.copyObject=function(t){var e,r,n;r={};for(e in t)n=t[e],r[e]=n;return r},t.closest=function(t,r){return e.call(t,r)},e=function(){var t,e;return t=document.documentElement,null!=(e=t.closest)?e:function(t){var e;for(e=this;e;){if(e.nodeType===Node.ELEMENT_NODE&&r.call(e,t))return e;e=e.parentNode}}}(),t.defer=function(t){return setTimeout(t,1)},t.dispatch=function(t,e){var r,n,o,i,s;return i=null!=e?e:{},s=i.target,r=i.cancelable,n=i.data,o=document.createEvent("Events"),o.initEvent(t,!0,r===!0),o.data=null!=n?n:{},(null!=s?s:document).dispatchEvent(o),o},t.match=function(t,e){return r.call(t,e)},r=function(){var t,e,r,n;return t=document.documentElement,null!=(e=null!=(r=null!=(n=t.matchesSelector)?n:t.webkitMatchesSelector)?r:t.msMatchesSelector)?e:t.mozMatchesSelector}(),t.uuid=function(){var t,e,r;for(r="",t=e=1;36>=e;t=++e)r+=9===t||14===t||19===t||24===t?"-":15===t?"4":20===t?(Math.floor(4*Math.random())+8).toString(16):Math.floor(15*Math.random()).toString(16);return r}}).call(this),function(){t.Location=function(){function t(t){var e,r;null==t&&(t=""),r=document.createElement("a"),r.href=t.toString(),this.absoluteURL=r.href,e=r.hash.length,2>e?this.requestURL=this.absoluteURL:(this.requestURL=this.absoluteURL.slice(0,-e),this.anchor=r.hash.slice(1))}var e,r,n,o;return t.wrap=function(t){return t instanceof this?t:new this(t)},t.prototype.getOrigin=function(){return this.absoluteURL.split("/",3).join("/")},t.prototype.getPath=function(){var t,e;return null!=(t=null!=(e=this.absoluteURL.match(/\/\/[^\/]*(\/[^?;]*)/))?e[1]:void 0)?t:"/"},t.prototype.getPathComponents=function(){return this.getPath().split("/").slice(1)},t.prototype.getLastPathComponent=function(){return this.getPathComponents().slice(-1)[0]},t.prototype.getExtension=function(){var t,e;return null!=(t=null!=(e=this.getLastPathComponent().match(/\.[^.]*$/))?e[0]:void 0)?t:""},t.prototype.isHTML=function(){return this.getExtension().match(/^(?:|\.(?:htm|html|xhtml))$/)},t.prototype.isPrefixedBy=function(t){var e;return e=r(t),this.isEqualTo(t)||o(this.absoluteURL,e)},t.prototype.isEqualTo=function(t){return this.absoluteURL===(null!=t?t.absoluteURL:void 0)},t.prototype.toCacheKey=function(){return this.requestURL},t.prototype.toJSON=function(){return this.absoluteURL},t.prototype.toString=function(){return this.absoluteURL},t.prototype.valueOf=function(){return this.absoluteURL},r=function(t){return e(t.getOrigin()+t.getPath())},e=function(t){return n(t,"/")?t:t+"/"},o=function(t,e){return t.slice(0,e.length)===e},n=function(t,e){return t.slice(-e.length)===e},t}()}.call(this),function(){var e=function(t,e){return function(){return t.apply(e,arguments)}};t.HttpRequest=function(){function r(r,n,o){this.delegate=r,this.requestCanceled=e(this.requestCanceled,this),this.requestTimedOut=e(this.requestTimedOut,this),this.requestFailed=e(this.requestFailed,this),this.requestLoaded=e(this.requestLoaded,this),this.requestProgressed=e(this.requestProgressed,this),this.url=t.Location.wrap(n).requestURL,this.referrer=t.Location.wrap(o).absoluteURL,this.createXHR()}return r.NETWORK_FAILURE=0,r.TIMEOUT_FAILURE=-1,r.timeout=60,r.prototype.send=function(){var t;return this.xhr&&!this.sent?(this.notifyApplicationBeforeRequestStart(),this.setProgress(0),this.xhr.send(),this.sent=!0,"function"==typeof(t=this.delegate).requestStarted?t.requestStarted():void 0):void 0},r.prototype.cancel=function(){return this.xhr&&this.sent?this.xhr.abort():void 0},r.prototype.requestProgressed=function(t){return t.lengthComputable?this.setProgress(t.loaded/t.total):void 0},r.prototype.requestLoaded=function(){return this.endRequest(function(t){return function(){var e;return 200<=(e=t.xhr.status)&&300>e?t.delegate.requestCompletedWithResponse(t.xhr.responseText,t.xhr.getResponseHeader("Turbolinks-Location")):(t.failed=!0,t.delegate.requestFailedWithStatusCode(t.xhr.status,t.xhr.responseText))}}(this))},r.prototype.requestFailed=function(){return this.endRequest(function(t){return function(){return t.failed=!0,t.delegate.requestFailedWithStatusCode(t.constructor.NETWORK_FAILURE)}}(this))},r.prototype.requestTimedOut=function(){return this.endRequest(function(t){return function(){return t.failed=!0,t.delegate.requestFailedWithStatusCode(t.constructor.TIMEOUT_FAILURE)}}(this))},r.prototype.requestCanceled=function(){return this.endRequest()},r.prototype.notifyApplicationBeforeRequestStart=function(){return t.dispatch("turbolinks:request-start",{data:{url:this.url,xhr:this.xhr}})},r.prototype.notifyApplicationAfterRequestEnd=function(){return t.dispatch("turbolinks:request-end",{data:{url:this.url,xhr:this.xhr}})},r.prototype.createXHR=function(){return this.xhr=new XMLHttpRequest,this.xhr.open("GET",this.url,!0),this.xhr.timeout=1e3*this.constructor.timeout,this.xhr.setRequestHeader("Accept","text/html, application/xhtml+xml"),this.xhr.setRequestHeader("Turbolinks-Referrer",this.referrer),this.xhr.onprogress=this.requestProgressed,this.xhr.onload=this.requestLoaded,this.xhr.onerror=this.requestFailed,this.xhr.ontimeout=this.requestTimedOut,this.xhr.onabort=this.requestCanceled},r.prototype.endRequest=function(t){return this.xhr?(this.notifyApplicationAfterRequestEnd(),null!=t&&t.call(this),this.destroy()):void 0},r.prototype.setProgress=function(t){var e;return this.progress=t,"function"==typeof(e=this.delegate).requestProgressed?e.requestProgressed(this.progress):void 0},r.prototype.destroy=function(){var t;return this.setProgress(1),"function"==typeof(t=this.delegate).requestFinished&&t.requestFinished(),this.delegate=null,this.xhr=null},r}()}.call(this),function(){var e=function(t,e){return function(){return t.apply(e,arguments)}};t.ProgressBar=function(){function t(){this.trickle=e(this.trickle,this),this.stylesheetElement=this.createStylesheetElement(),this.progressElement=this.createProgressElement()}var r;return r=300,t.defaultCSS=".turbolinks-progress-bar {\n position: fixed;\n display: block;\n top: 0;\n left: 0;\n height: 3px;\n background: #0076ff;\n z-index: 9999;\n transition: width "+r+"ms ease-out, opacity "+r/2+"ms "+r/2+"ms ease-in;\n transform: translate3d(0, 0, 0);\n}",t.prototype.show=function(){return this.visible?void 0:(this.visible=!0,this.installStylesheetElement(),this.installProgressElement(),this.startTrickling())},t.prototype.hide=function(){return this.visible&&!this.hiding?(this.hiding=!0,this.fadeProgressElement(function(t){return function(){return t.uninstallProgressElement(),t.stopTrickling(),t.visible=!1,t.hiding=!1}}(this))):void 0},t.prototype.setValue=function(t){return this.value=t,this.refresh()},t.prototype.installStylesheetElement=function(){return document.head.insertBefore(this.stylesheetElement,document.head.firstChild)},t.prototype.installProgressElement=function(){return this.progressElement.style.width=0,this.progressElement.style.opacity=1,document.documentElement.insertBefore(this.progressElement,document.body),this.refresh()},t.prototype.fadeProgressElement=function(t){return this.progressElement.style.opacity=0,setTimeout(t,1.5*r)},t.prototype.uninstallProgressElement=function(){return this.progressElement.parentNode?document.documentElement.removeChild(this.progressElement):void 0},t.prototype.startTrickling=function(){return null!=this.trickleInterval?this.trickleInterval:this.trickleInterval=setInterval(this.trickle,r)},t.prototype.stopTrickling=function(){return clearInterval(this.trickleInterval),this.trickleInterval=null},t.prototype.trickle=function(){return this.setValue(this.value+Math.random()/100)},t.prototype.refresh=function(){return requestAnimationFrame(function(t){return function(){return t.progressElement.style.width=10+90*t.value+"%"}}(this))},t.prototype.createStylesheetElement=function(){var t;return t=document.createElement("style"),t.type="text/css",t.textContent=this.constructor.defaultCSS,t},t.prototype.createProgressElement=function(){var t;return t=document.createElement("div"),t.className="turbolinks-progress-bar",t},t}()}.call(this),function(){var e=function(t,e){return function(){return t.apply(e,arguments)}};t.BrowserAdapter=function(){function r(r){this.controller=r,this.showProgressBar=e(this.showProgressBar,this),this.progressBar=new t.ProgressBar}var n,o,i,s;return s=t.HttpRequest,n=s.NETWORK_FAILURE,i=s.TIMEOUT_FAILURE,o=500,r.prototype.visitProposedToLocationWithAction=function(t,e){return this.controller.startVisitToLocationWithAction(t,e)},r.prototype.visitStarted=function(t){return t.issueRequest(),t.changeHistory(),t.loadCachedSnapshot()},r.prototype.visitRequestStarted=function(t){return this.progressBar.setValue(0),t.hasCachedSnapshot()||"restore"!==t.action?this.showProgressBarAfterDelay():this.showProgressBar()},r.prototype.visitRequestProgressed=function(t){return this.progressBar.setValue(t.progress)},r.prototype.visitRequestCompleted=function(t){return t.loadResponse()},r.prototype.visitRequestFailedWithStatusCode=function(t,e){switch(e){case n:case i:return this.reload();default:return t.loadResponse()}},r.prototype.visitRequestFinished=function(t){return this.hideProgressBar()},r.prototype.visitCompleted=function(t){return t.followRedirect()},r.prototype.pageInvalidated=function(){return this.reload()},r.prototype.showProgressBarAfterDelay=function(){return this.progressBarTimeout=setTimeout(this.showProgressBar,o)},r.prototype.showProgressBar=function(){return this.progressBar.show()},r.prototype.hideProgressBar=function(){return this.progressBar.hide(),clearTimeout(this.progressBarTimeout)},r.prototype.reload=function(){return window.location.reload()},r}()}.call(this),function(){var e,r=function(t,e){return function(){return t.apply(e,arguments)}};e=!1,addEventListener("load",function(){return t.defer(function(){return e=!0})},!1),t.History=function(){function n(t){this.delegate=t,this.onPopState=r(this.onPopState,this)}return n.prototype.start=function(){return this.started?void 0:(addEventListener("popstate",this.onPopState,!1),this.started=!0)},n.prototype.stop=function(){return this.started?(removeEventListener("popstate",this.onPopState,!1),this.started=!1):void 0},n.prototype.push=function(e,r){return e=t.Location.wrap(e),this.update("push",e,r)},n.prototype.replace=function(e,r){return e=t.Location.wrap(e),this.update("replace",e,r)},n.prototype.onPopState=function(e){var r,n,o,i;return this.shouldHandlePopState()&&(i=null!=(n=e.state)?n.turbolinks:void 0)?(r=t.Location.wrap(window.location),o=i.restorationIdentifier,this.delegate.historyPoppedToLocationWithRestorationIdentifier(r,o)):void 0},n.prototype.shouldHandlePopState=function(){return e===!0},n.prototype.update=function(t,e,r){var n;return n={turbolinks:{restorationIdentifier:r}},history[t+"State"](n,null,e)},n}()}.call(this),function(){t.Snapshot=function(){function e(t){var e,r;r=t.head,e=t.body,this.head=null!=r?r:document.createElement("head"),this.body=null!=e?e:document.createElement("body")}return e.wrap=function(t){return t instanceof this?t:this.fromHTML(t)},e.fromHTML=function(t){var e;return e=document.createElement("html"),e.innerHTML=t,this.fromElement(e)},e.fromElement=function(t){return new this({head:t.querySelector("head"),body:t.querySelector("body")})},e.prototype.clone=function(){return new e({head:this.head.cloneNode(!0),body:this.body.cloneNode(!0)})},e.prototype.getRootLocation=function(){var e,r;return r=null!=(e=this.getSetting("root"))?e:"/",new t.Location(r)},e.prototype.getCacheControlValue=function(){return this.getSetting("cache-control")},e.prototype.hasAnchor=function(t){try{return null!=this.body.querySelector("[id='"+t+"']")}catch(e){}},e.prototype.isPreviewable=function(){return"no-preview"!==this.getCacheControlValue()},e.prototype.isCacheable=function(){return"no-cache"!==this.getCacheControlValue()},e.prototype.getSetting=function(t){var e,r;return r=this.head.querySelectorAll("meta[name='turbolinks-"+t+"']"),e=r[r.length-1],null!=e?e.getAttribute("content"):void 0},e}()}.call(this),function(){var e=[].slice;t.Renderer=function(){function t(){}var r;return t.render=function(){var t,r,n,o;return n=arguments[0],r=arguments[1],t=3<=arguments.length?e.call(arguments,2):[],o=function(t,e,r){r.prototype=t.prototype;var n=new r,o=t.apply(n,e);return Object(o)===o?o:n}(this,t,function(){}),o.delegate=n,o.render(r),o},t.prototype.renderView=function(t){return this.delegate.viewWillRender(this.newBody),t(),this.delegate.viewRendered(this.newBody)},t.prototype.invalidateView=function(){return this.delegate.viewInvalidated()},t.prototype.createScriptElement=function(t){var e;return"false"===t.getAttribute("data-turbolinks-eval")?t:(e=document.createElement("script"),e.textContent=t.textContent,r(e,t),e)},r=function(t,e){var r,n,o,i,s,a,u;for(i=e.attributes,a=[],r=0,n=i.length;n>r;r++)s=i[r],o=s.name,u=s.value,a.push(t.setAttribute(o,u));return a},t}()}.call(this),function(){t.HeadDetails=function(){function t(t){var e,r,i,s,a,u,c;for(this.element=t,this.elements={},c=this.element.childNodes,s=0,u=c.length;u>s;s++)i=c[s],i.nodeType===Node.ELEMENT_NODE&&(a=i.outerHTML,r=null!=(e=this.elements)[a]?e[a]:e[a]={type:o(i),tracked:n(i),elements:[]},r.elements.push(i))}var e,r,n,o;return t.prototype.hasElementWithKey=function(t){return t in this.elements},t.prototype.getTrackedElementSignature=function(){var t,e;return function(){var r,n;r=this.elements,n=[];for(t in r)e=r[t].tracked,e&&n.push(t);return n}.call(this).join("")},t.prototype.getScriptElementsNotInDetails=function(t){return this.getElementsMatchingTypeNotInDetails("script",t)},t.prototype.getStylesheetElementsNotInDetails=function(t){return this.getElementsMatchingTypeNotInDetails("stylesheet",t)},t.prototype.getElementsMatchingTypeNotInDetails=function(t,e){var r,n,o,i,s,a;o=this.elements,s=[];for(n in o)i=o[n],a=i.type,r=i.elements,a!==t||e.hasElementWithKey(n)||s.push(r[0]);return s},t.prototype.getProvisionalElements=function(){var t,e,r,n,o,i,s;r=[],n=this.elements;for(e in n)o=n[e],s=o.type,i=o.tracked,t=o.elements,null!=s||i?t.length>1&&r.push.apply(r,t.slice(1)):r.push.apply(r,t);return r},o=function(t){return e(t)?"script":r(t)?"stylesheet":void 0},n=function(t){return"reload"===t.getAttribute("data-turbolinks-track")},e=function(t){var e;return e=t.tagName.toLowerCase(),"script"===e},r=function(t){var e;return e=t.tagName.toLowerCase(),"style"===e||"link"===e&&"stylesheet"===t.getAttribute("rel")},t}()}.call(this),function(){var e=function(t,e){function n(){this.constructor=t}for(var o in e)r.call(e,o)&&(t[o]=e[o]);return n.prototype=e.prototype,t.prototype=new n,t.__super__=e.prototype,t},r={}.hasOwnProperty;t.SnapshotRenderer=function(r){function n(e,r){this.currentSnapshot=e,this.newSnapshot=r,this.currentHeadDetails=new t.HeadDetails(this.currentSnapshot.head),this.newHeadDetails=new t.HeadDetails(this.newSnapshot.head),this.newBody=this.newSnapshot.body}return e(n,r),n.prototype.render=function(t){return this.trackedElementsAreIdentical()?(this.mergeHead(),this.renderView(function(e){return function(){return e.replaceBody(),e.focusFirstAutofocusableElement(),t()}}(this))):this.invalidateView()},n.prototype.mergeHead=function(){return this.copyNewHeadStylesheetElements(),this.copyNewHeadScriptElements(),this.removeCurrentHeadProvisionalElements(),this.copyNewHeadProvisionalElements()},n.prototype.replaceBody=function(){return this.activateBodyScriptElements(),this.importBodyPermanentElements(),this.assignNewBody()},n.prototype.trackedElementsAreIdentical=function(){return this.currentHeadDetails.getTrackedElementSignature()===this.newHeadDetails.getTrackedElementSignature()},n.prototype.copyNewHeadStylesheetElements=function(){var t,e,r,n,o;for(n=this.getNewHeadStylesheetElements(),o=[],e=0,r=n.length;r>e;e++)t=n[e],o.push(document.head.appendChild(t));return o},n.prototype.copyNewHeadScriptElements=function(){var t,e,r,n,o;for(n=this.getNewHeadScriptElements(),o=[],e=0,r=n.length;r>e;e++)t=n[e],o.push(document.head.appendChild(this.createScriptElement(t)));return o},n.prototype.removeCurrentHeadProvisionalElements=function(){var t,e,r,n,o;for(n=this.getCurrentHeadProvisionalElements(),o=[],e=0,r=n.length;r>e;e++)t=n[e],o.push(document.head.removeChild(t));return o},n.prototype.copyNewHeadProvisionalElements=function(){var t,e,r,n,o;for(n=this.getNewHeadProvisionalElements(),o=[],e=0,r=n.length;r>e;e++)t=n[e],o.push(document.head.appendChild(t));return o},n.prototype.importBodyPermanentElements=function(){var t,e,r,n,o,i;for(n=this.getNewBodyPermanentElements(),i=[],e=0,r=n.length;r>e;e++)o=n[e],(t=this.findCurrentBodyPermanentElement(o))?i.push(o.parentNode.replaceChild(t,o)):i.push(void 0);return i},n.prototype.activateBodyScriptElements=function(){var t,e,r,n,o,i;for(n=this.getNewBodyScriptElements(),i=[],e=0,r=n.length;r>e;e++)o=n[e],t=this.createScriptElement(o),i.push(o.parentNode.replaceChild(t,o));return i},n.prototype.assignNewBody=function(){return document.body=this.newBody},n.prototype.focusFirstAutofocusableElement=function(){var t;return null!=(t=this.findFirstAutofocusableElement())?t.focus():void 0},n.prototype.getNewHeadStylesheetElements=function(){return this.newHeadDetails.getStylesheetElementsNotInDetails(this.currentHeadDetails)},n.prototype.getNewHeadScriptElements=function(){return this.newHeadDetails.getScriptElementsNotInDetails(this.currentHeadDetails)},n.prototype.getCurrentHeadProvisionalElements=function(){return this.currentHeadDetails.getProvisionalElements()},n.prototype.getNewHeadProvisionalElements=function(){return this.newHeadDetails.getProvisionalElements()},n.prototype.getNewBodyPermanentElements=function(){return this.newBody.querySelectorAll("[id][data-turbolinks-permanent]")},n.prototype.findCurrentBodyPermanentElement=function(t){return document.body.querySelector("#"+t.id+"[data-turbolinks-permanent]")},n.prototype.getNewBodyScriptElements=function(){return this.newBody.querySelectorAll("script")},n.prototype.findFirstAutofocusableElement=function(){return document.body.querySelector("[autofocus]")},n}(t.Renderer)}.call(this),function(){var e=function(t,e){function n(){this.constructor=t}for(var o in e)r.call(e,o)&&(t[o]=e[o]);return n.prototype=e.prototype,t.prototype=new n,t.__super__=e.prototype,t},r={}.hasOwnProperty;t.ErrorRenderer=function(t){function r(t){this.html=t}return e(r,t),r.prototype.render=function(t){return this.renderView(function(e){return function(){return e.replaceDocumentHTML(),e.activateBodyScriptElements(),t()}}(this))},r.prototype.replaceDocumentHTML=function(){return document.documentElement.innerHTML=this.html},r.prototype.activateBodyScriptElements=function(){var t,e,r,n,o,i;for(n=this.getScriptElements(),i=[],e=0,r=n.length;r>e;e++)o=n[e],t=this.createScriptElement(o),i.push(o.parentNode.replaceChild(t,o));return i},r.prototype.getScriptElements=function(){return document.documentElement.querySelectorAll("script")},r}(t.Renderer)}.call(this),function(){t.View=function(){function e(t){this.delegate=t,this.element=document.documentElement}return e.prototype.getRootLocation=function(){return this.getSnapshot().getRootLocation()},e.prototype.getSnapshot=function(){return t.Snapshot.fromElement(this.element)},e.prototype.render=function(t,e){var r,n,o;return o=t.snapshot,r=t.error,n=t.isPreview,this.markAsPreview(n),null!=o?this.renderSnapshot(o,e):this.renderError(r,e)},e.prototype.markAsPreview=function(t){return t?this.element.setAttribute("data-turbolinks-preview",""):this.element.removeAttribute("data-turbolinks-preview")},e.prototype.renderSnapshot=function(e,r){return t.SnapshotRenderer.render(this.delegate,r,this.getSnapshot(),t.Snapshot.wrap(e))},e.prototype.renderError=function(e,r){return t.ErrorRenderer.render(this.delegate,r,e)},e}()}.call(this),function(){var e=function(t,e){return function(){return t.apply(e,arguments)}};t.ScrollManager=function(){function t(t){this.delegate=t,this.onScroll=e(this.onScroll,this)}return t.prototype.start=function(){return this.started?void 0:(addEventListener("scroll",this.onScroll,!1),this.onScroll(),this.started=!0)},t.prototype.stop=function(){return this.started?(removeEventListener("scroll",this.onScroll,!1),this.started=!1):void 0},t.prototype.scrollToElement=function(t){return t.scrollIntoView()},t.prototype.scrollToPosition=function(t){var e,r;return e=t.x,r=t.y,window.scrollTo(e,r)},t.prototype.onScroll=function(t){return this.updatePosition({x:window.pageXOffset,y:window.pageYOffset})},t.prototype.updatePosition=function(t){var e;return this.position=t,null!=(e=this.delegate)?e.scrollPositionChanged(this.position):void 0},t}()}.call(this),function(){t.SnapshotCache=function(){function e(t){this.size=t,this.keys=[],this.snapshots={}}var r;return e.prototype.has=function(t){var e;return e=r(t),e in this.snapshots},e.prototype.get=function(t){var e;if(this.has(t))return e=this.read(t),this.touch(t),e},e.prototype.put=function(t,e){return this.write(t,e),this.touch(t),e},e.prototype.read=function(t){var e;return e=r(t),this.snapshots[e]},e.prototype.write=function(t,e){var n;return n=r(t),this.snapshots[n]=e},e.prototype.touch=function(t){var e,n;return n=r(t),e=this.keys.indexOf(n),e>-1&&this.keys.splice(e,1),this.keys.unshift(n),this.trim()},e.prototype.trim=function(){var t,e,r,n,o;for(n=this.keys.splice(this.size),o=[],t=0,r=n.length;r>t;t++)e=n[t],o.push(delete this.snapshots[e]);return o},r=function(e){return t.Location.wrap(e).toCacheKey()},e}()}.call(this),function(){var e=function(t,e){return function(){return t.apply(e,arguments)}};t.Visit=function(){function r(r,n,o){this.controller=r,this.action=o,this.performScroll=e(this.performScroll,this),this.identifier=t.uuid(),this.location=t.Location.wrap(n),this.adapter=this.controller.adapter,this.state="initialized",this.timingMetrics={}}var n;return r.prototype.start=function(){return"initialized"===this.state?(this.recordTimingMetric("visitStart"),this.state="started",this.adapter.visitStarted(this)):void 0},r.prototype.cancel=function(){var t;return"started"===this.state?(null!=(t=this.request)&&t.cancel(),this.cancelRender(),this.state="canceled"):void 0},r.prototype.complete=function(){var t;return"started"===this.state?(this.recordTimingMetric("visitEnd"),this.state="completed","function"==typeof(t=this.adapter).visitCompleted&&t.visitCompleted(this),this.controller.visitCompleted(this)):void 0},r.prototype.fail=function(){var t;return"started"===this.state?(this.state="failed","function"==typeof(t=this.adapter).visitFailed?t.visitFailed(this):void 0):void 0},r.prototype.changeHistory=function(){var t,e;return this.historyChanged?void 0:(t=this.location.isEqualTo(this.referrer)?"replace":this.action,e=n(t),this.controller[e](this.location,this.restorationIdentifier),this.historyChanged=!0)},r.prototype.issueRequest=function(){return this.shouldIssueRequest()&&null==this.request?(this.progress=0,this.request=new t.HttpRequest(this,this.location,this.referrer),this.request.send()):void 0},r.prototype.getCachedSnapshot=function(){var t;return!(t=this.controller.getCachedSnapshotForLocation(this.location))||null!=this.location.anchor&&!t.hasAnchor(this.location.anchor)||"restore"!==this.action&&!t.isPreviewable()?void 0:t},r.prototype.hasCachedSnapshot=function(){return null!=this.getCachedSnapshot()},r.prototype.loadCachedSnapshot=function(){var t,e;return(e=this.getCachedSnapshot())?(t=this.shouldIssueRequest(),this.render(function(){var r;return this.cacheSnapshot(),this.controller.render({snapshot:e,isPreview:t},this.performScroll),"function"==typeof(r=this.adapter).visitRendered&&r.visitRendered(this),t?void 0:this.complete()})):void 0},r.prototype.loadResponse=function(){return null!=this.response?this.render(function(){var t,e;return this.cacheSnapshot(),this.request.failed?(this.controller.render({error:this.response},this.performScroll),"function"==typeof(t=this.adapter).visitRendered&&t.visitRendered(this),this.fail()):(this.controller.render({snapshot:this.response},this.performScroll),"function"==typeof(e=this.adapter).visitRendered&&e.visitRendered(this),this.complete())}):void 0},r.prototype.followRedirect=function(){return this.redirectedToLocation&&!this.followedRedirect?(this.location=this.redirectedToLocation,this.controller.replaceHistoryWithLocationAndRestorationIdentifier(this.redirectedToLocation,this.restorationIdentifier),this.followedRedirect=!0):void 0},r.prototype.requestStarted=function(){var t;return this.recordTimingMetric("requestStart"),"function"==typeof(t=this.adapter).visitRequestStarted?t.visitRequestStarted(this):void 0},r.prototype.requestProgressed=function(t){var e;return this.progress=t,"function"==typeof(e=this.adapter).visitRequestProgressed?e.visitRequestProgressed(this):void 0},r.prototype.requestCompletedWithResponse=function(e,r){return this.response=e,null!=r&&(this.redirectedToLocation=t.Location.wrap(r)),this.adapter.visitRequestCompleted(this)},r.prototype.requestFailedWithStatusCode=function(t,e){return this.response=e,this.adapter.visitRequestFailedWithStatusCode(this,t)},r.prototype.requestFinished=function(){var t;return this.recordTimingMetric("requestEnd"),"function"==typeof(t=this.adapter).visitRequestFinished?t.visitRequestFinished(this):void 0},r.prototype.performScroll=function(){return this.scrolled?void 0:("restore"===this.action?this.scrollToRestoredPosition()||this.scrollToTop():this.scrollToAnchor()||this.scrollToTop(),this.scrolled=!0)},r.prototype.scrollToRestoredPosition=function(){var t,e;return t=null!=(e=this.restorationData)?e.scrollPosition:void 0,null!=t?(this.controller.scrollToPosition(t),!0):void 0},r.prototype.scrollToAnchor=function(){return null!=this.location.anchor?(this.controller.scrollToAnchor(this.location.anchor),!0):void 0},r.prototype.scrollToTop=function(){return this.controller.scrollToPosition({x:0,y:0})},r.prototype.recordTimingMetric=function(t){var e;return null!=(e=this.timingMetrics)[t]?e[t]:e[t]=(new Date).getTime()},r.prototype.getTimingMetrics=function(){return t.copyObject(this.timingMetrics)},n=function(t){switch(t){case"replace":return"replaceHistoryWithLocationAndRestorationIdentifier";case"advance":case"restore":return"pushHistoryWithLocationAndRestorationIdentifier"}},r.prototype.shouldIssueRequest=function(){return"restore"===this.action?!this.hasCachedSnapshot():!0},r.prototype.cacheSnapshot=function(){return this.snapshotCached?void 0:(this.controller.cacheSnapshot(),this.snapshotCached=!0)},r.prototype.render=function(t){return this.cancelRender(),this.frame=requestAnimationFrame(function(e){return function(){return e.frame=null,t.call(e)}}(this))},r.prototype.cancelRender=function(){return this.frame?cancelAnimationFrame(this.frame):void 0},r}()}.call(this),function(){var e=function(t,e){return function(){return t.apply(e,arguments)}};t.Controller=function(){function r(){this.clickBubbled=e(this.clickBubbled,this),this.clickCaptured=e(this.clickCaptured,this),this.pageLoaded=e(this.pageLoaded,this),this.history=new t.History(this),this.view=new t.View(this),this.scrollManager=new t.ScrollManager(this),this.restorationData={},this.clearCache()}return r.prototype.start=function(){return t.supported&&!this.started?(addEventListener("click",this.clickCaptured,!0),addEventListener("DOMContentLoaded",this.pageLoaded,!1),this.scrollManager.start(),this.startHistory(),this.started=!0,this.enabled=!0):void 0},r.prototype.disable=function(){return this.enabled=!1},r.prototype.stop=function(){return this.started?(removeEventListener("click",this.clickCaptured,!0),removeEventListener("DOMContentLoaded",this.pageLoaded,!1),this.scrollManager.stop(),this.stopHistory(),this.started=!1):void 0},r.prototype.clearCache=function(){return this.cache=new t.SnapshotCache(10)},r.prototype.visit=function(e,r){var n,o;return null==r&&(r={}),e=t.Location.wrap(e),this.applicationAllowsVisitingLocation(e)?this.locationIsVisitable(e)?(n=null!=(o=r.action)?o:"advance",this.adapter.visitProposedToLocationWithAction(e,n)):window.location=e:void 0},r.prototype.startVisitToLocationWithAction=function(e,r,n){var o;return t.supported?(o=this.getRestorationDataForIdentifier(n),this.startVisit(e,r,{restorationData:o})):window.location=e},r.prototype.startHistory=function(){return this.location=t.Location.wrap(window.location),this.restorationIdentifier=t.uuid(),this.history.start(),this.history.replace(this.location,this.restorationIdentifier)},r.prototype.stopHistory=function(){return this.history.stop()},r.prototype.pushHistoryWithLocationAndRestorationIdentifier=function(e,r){return this.restorationIdentifier=r,this.location=t.Location.wrap(e),this.history.push(this.location,this.restorationIdentifier)},r.prototype.replaceHistoryWithLocationAndRestorationIdentifier=function(e,r){return this.restorationIdentifier=r,this.location=t.Location.wrap(e),this.history.replace(this.location,this.restorationIdentifier)},r.prototype.historyPoppedToLocationWithRestorationIdentifier=function(e,r){var n;return this.restorationIdentifier=r,this.enabled?(n=this.getRestorationDataForIdentifier(this.restorationIdentifier),this.startVisit(e,"restore",{restorationIdentifier:this.restorationIdentifier,restorationData:n,historyChanged:!0}),this.location=t.Location.wrap(e)):this.adapter.pageInvalidated()},r.prototype.getCachedSnapshotForLocation=function(t){var e;return e=this.cache.get(t),e?e.clone():void 0},r.prototype.shouldCacheSnapshot=function(){return this.view.getSnapshot().isCacheable()},r.prototype.cacheSnapshot=function(){var t;return this.shouldCacheSnapshot()?(this.notifyApplicationBeforeCachingSnapshot(),t=this.view.getSnapshot(),this.cache.put(this.lastRenderedLocation,t.clone())):void 0},r.prototype.scrollToAnchor=function(t){var e;return(e=document.getElementById(t))?this.scrollToElement(e):this.scrollToPosition({x:0,y:0})},r.prototype.scrollToElement=function(t){return this.scrollManager.scrollToElement(t)},r.prototype.scrollToPosition=function(t){return this.scrollManager.scrollToPosition(t)},r.prototype.scrollPositionChanged=function(t){var e;return e=this.getCurrentRestorationData(),e.scrollPosition=t},r.prototype.render=function(t,e){return this.view.render(t,e)},r.prototype.viewInvalidated=function(){return this.adapter.pageInvalidated()},r.prototype.viewWillRender=function(t){return this.notifyApplicationBeforeRender(t)},r.prototype.viewRendered=function(){return this.lastRenderedLocation=this.currentVisit.location,this.notifyApplicationAfterRender()},r.prototype.pageLoaded=function(){return this.lastRenderedLocation=this.location,this.notifyApplicationAfterPageLoad()},r.prototype.clickCaptured=function(){return removeEventListener("click",this.clickBubbled,!1),addEventListener("click",this.clickBubbled,!1)},r.prototype.clickBubbled=function(t){var e,r,n;return this.enabled&&this.clickEventIsSignificant(t)&&(r=this.getVisitableLinkForNode(t.target))&&(n=this.getVisitableLocationForLink(r))&&this.applicationAllowsFollowingLinkToLocation(r,n)?(t.preventDefault(),e=this.getActionForLink(r),this.visit(n,{action:e})):void 0},r.prototype.applicationAllowsFollowingLinkToLocation=function(t,e){var r;return r=this.notifyApplicationAfterClickingLinkToLocation(t,e),!r.defaultPrevented},r.prototype.applicationAllowsVisitingLocation=function(t){var e;return e=this.notifyApplicationBeforeVisitingLocation(t),!e.defaultPrevented},r.prototype.notifyApplicationAfterClickingLinkToLocation=function(e,r){return t.dispatch("turbolinks:click",{target:e,data:{url:r.absoluteURL},cancelable:!0})},r.prototype.notifyApplicationBeforeVisitingLocation=function(e){return t.dispatch("turbolinks:before-visit",{data:{url:e.absoluteURL},cancelable:!0})},r.prototype.notifyApplicationAfterVisitingLocation=function(e){return t.dispatch("turbolinks:visit",{data:{url:e.absoluteURL}})},r.prototype.notifyApplicationBeforeCachingSnapshot=function(){return t.dispatch("turbolinks:before-cache")},r.prototype.notifyApplicationBeforeRender=function(e){return t.dispatch("turbolinks:before-render",{data:{newBody:e}})},r.prototype.notifyApplicationAfterRender=function(){return t.dispatch("turbolinks:render")},r.prototype.notifyApplicationAfterPageLoad=function(e){return null==e&&(e={}),t.dispatch("turbolinks:load",{data:{url:this.location.absoluteURL,timing:e}})},r.prototype.startVisit=function(t,e,r){var n;return null!=(n=this.currentVisit)&&n.cancel(),this.currentVisit=this.createVisit(t,e,r),this.currentVisit.start(),this.notifyApplicationAfterVisitingLocation(t)},r.prototype.createVisit=function(e,r,n){ +var o,i,s,a,u;return i=null!=n?n:{},a=i.restorationIdentifier,s=i.restorationData,o=i.historyChanged,u=new t.Visit(this,e,r),u.restorationIdentifier=null!=a?a:t.uuid(),u.restorationData=t.copyObject(s),u.historyChanged=o,u.referrer=this.location,u},r.prototype.visitCompleted=function(t){return this.notifyApplicationAfterPageLoad(t.getTimingMetrics())},r.prototype.clickEventIsSignificant=function(t){return!(t.defaultPrevented||t.target.isContentEditable||t.which>1||t.altKey||t.ctrlKey||t.metaKey||t.shiftKey)},r.prototype.getVisitableLinkForNode=function(e){return this.nodeIsVisitable(e)?t.closest(e,"a[href]:not([target])"):void 0},r.prototype.getVisitableLocationForLink=function(e){var r;return r=new t.Location(e.getAttribute("href")),this.locationIsVisitable(r)?r:void 0},r.prototype.getActionForLink=function(t){var e;return null!=(e=t.getAttribute("data-turbolinks-action"))?e:"advance"},r.prototype.nodeIsVisitable=function(e){var r;return(r=t.closest(e,"[data-turbolinks]"))?"false"!==r.getAttribute("data-turbolinks"):!0},r.prototype.locationIsVisitable=function(t){return t.isPrefixedBy(this.view.getRootLocation())&&t.isHTML()},r.prototype.getCurrentRestorationData=function(){return this.getRestorationDataForIdentifier(this.restorationIdentifier)},r.prototype.getRestorationDataForIdentifier=function(t){var e;return null!=(e=this.restorationData)[t]?e[t]:e[t]={}},r}()}.call(this),function(){var e,r,n;t.start=function(){return r()?(null==t.controller&&(t.controller=e()),t.controller.start()):void 0},r=function(){return null==window.Turbolinks&&(window.Turbolinks=t),n()},e=function(){var e;return e=new t.Controller,e.adapter=new t.BrowserAdapter(e),e},n=function(){return window.Turbolinks===t},n()&&t.start()}.call(this)}).call(this),"object"==typeof module&&module.exports?module.exports=t:"function"==typeof define&&define.amd&&define(t)}).call(this); +window.tinymce = window.tinymce || { + base: '/assets/tinymce', + suffix: '' +}; +// 4.3.13 (2016-06-08) + +/** + * Compiled inline version. (Library mode) + */ + +/*jshint smarttabs:true, undef:true, latedef:true, curly:true, bitwise:true, camelcase:true */ +/*globals $code */ + + +(function(exports, undefined) { + "use strict"; + + var modules = {}; + + function require(ids, callback) { + var module, defs = []; + + for (var i = 0; i < ids.length; ++i) { + module = modules[ids[i]] || resolve(ids[i]); + if (!module) { + throw 'module definition dependecy not found: ' + ids[i]; + } + + defs.push(module); + } + + callback.apply(null, defs); + } + + function define(id, dependencies, definition) { + if (typeof id !== 'string') { + throw 'invalid module definition, module id must be defined and be a string'; + } + + if (dependencies === undefined) { + throw 'invalid module definition, dependencies must be specified'; + } + + if (definition === undefined) { + throw 'invalid module definition, definition function must be specified'; + } + + require(dependencies, function() { + modules[id] = definition.apply(null, arguments); + }); + } + + function defined(id) { + return !!modules[id]; + } + + function resolve(id) { + var target = exports; + var fragments = id.split(/[.\/]/); + + for (var fi = 0; fi < fragments.length; ++fi) { + if (!target[fragments[fi]]) { + return; + } + + target = target[fragments[fi]]; + } + + return target; + } + + function expose(ids) { + var i, target, id, fragments, privateModules; + + for (i = 0; i < ids.length; i++) { + target = exports; + id = ids[i]; + fragments = id.split(/[.\/]/); + + for (var fi = 0; fi < fragments.length - 1; ++fi) { + if (target[fragments[fi]] === undefined) { + target[fragments[fi]] = {}; + } + + target = target[fragments[fi]]; + } + + target[fragments[fragments.length - 1]] = modules[id]; + } + + // Expose private modules for unit tests + if (exports.AMDLC_TESTS) { + privateModules = exports.privateModules || {}; + + for (id in modules) { + privateModules[id] = modules[id]; + } + + for (i = 0; i < ids.length; i++) { + delete privateModules[ids[i]]; + } + + exports.privateModules = privateModules; + } + } + +// Included from: js/tinymce/classes/geom/Rect.js + +/** + * Rect.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Contains various tools for rect/position calculation. + * + * @class tinymce.geom.Rect + */ +define("tinymce/geom/Rect", [ +], function() { + "use strict"; + + var min = Math.min, max = Math.max, round = Math.round; + + /** + * Returns the rect positioned based on the relative position name + * to the target rect. + * + * @method relativePosition + * @param {Rect} rect Source rect to modify into a new rect. + * @param {Rect} targetRect Rect to move relative to based on the rel option. + * @param {String} rel Relative position. For example: tr-bl. + */ + function relativePosition(rect, targetRect, rel) { + var x, y, w, h, targetW, targetH; + + x = targetRect.x; + y = targetRect.y; + w = rect.w; + h = rect.h; + targetW = targetRect.w; + targetH = targetRect.h; + + rel = (rel || '').split(''); + + if (rel[0] === 'b') { + y += targetH; + } + + if (rel[1] === 'r') { + x += targetW; + } + + if (rel[0] === 'c') { + y += round(targetH / 2); + } + + if (rel[1] === 'c') { + x += round(targetW / 2); + } + + if (rel[3] === 'b') { + y -= h; + } + + if (rel[4] === 'r') { + x -= w; + } + + if (rel[3] === 'c') { + y -= round(h / 2); + } + + if (rel[4] === 'c') { + x -= round(w / 2); + } + + return create(x, y, w, h); + } + + /** + * Tests various positions to get the most suitable one. + * + * @method findBestRelativePosition + * @param {Rect} rect Rect to use as source. + * @param {Rect} targetRect Rect to move relative to. + * @param {Rect} constrainRect Rect to constrain within. + * @param {Array} rels Array of relative positions to test against. + */ + function findBestRelativePosition(rect, targetRect, constrainRect, rels) { + var pos, i; + + for (i = 0; i < rels.length; i++) { + pos = relativePosition(rect, targetRect, rels[i]); + + if (pos.x >= constrainRect.x && pos.x + pos.w <= constrainRect.w + constrainRect.x && + pos.y >= constrainRect.y && pos.y + pos.h <= constrainRect.h + constrainRect.y) { + return rels[i]; + } + } + + return null; + } + + /** + * Inflates the rect in all directions. + * + * @method inflate + * @param {Rect} rect Rect to expand. + * @param {Number} w Relative width to expand by. + * @param {Number} h Relative height to expand by. + * @return {Rect} New expanded rect. + */ + function inflate(rect, w, h) { + return create(rect.x - w, rect.y - h, rect.w + w * 2, rect.h + h * 2); + } + + /** + * Returns the intersection of the specified rectangles. + * + * @method intersect + * @param {Rect} rect The first rectangle to compare. + * @param {Rect} cropRect The second rectangle to compare. + * @return {Rect} The intersection of the two rectangles or null if they don't intersect. + */ + function intersect(rect, cropRect) { + var x1, y1, x2, y2; + + x1 = max(rect.x, cropRect.x); + y1 = max(rect.y, cropRect.y); + x2 = min(rect.x + rect.w, cropRect.x + cropRect.w); + y2 = min(rect.y + rect.h, cropRect.y + cropRect.h); + + if (x2 - x1 < 0 || y2 - y1 < 0) { + return null; + } + + return create(x1, y1, x2 - x1, y2 - y1); + } + + /** + * Returns a rect clamped within the specified clamp rect. This forces the + * rect to be inside the clamp rect. + * + * @method clamp + * @param {Rect} rect Rectangle to force within clamp rect. + * @param {Rect} clampRect Rectable to force within. + * @param {Boolean} fixedSize True/false if size should be fixed. + * @return {Rect} Clamped rect. + */ + function clamp(rect, clampRect, fixedSize) { + var underflowX1, underflowY1, overflowX2, overflowY2, + x1, y1, x2, y2, cx2, cy2; + + x1 = rect.x; + y1 = rect.y; + x2 = rect.x + rect.w; + y2 = rect.y + rect.h; + cx2 = clampRect.x + clampRect.w; + cy2 = clampRect.y + clampRect.h; + + underflowX1 = max(0, clampRect.x - x1); + underflowY1 = max(0, clampRect.y - y1); + overflowX2 = max(0, x2 - cx2); + overflowY2 = max(0, y2 - cy2); + + x1 += underflowX1; + y1 += underflowY1; + + if (fixedSize) { + x2 += underflowX1; + y2 += underflowY1; + x1 -= overflowX2; + y1 -= overflowY2; + } + + x2 -= overflowX2; + y2 -= overflowY2; + + return create(x1, y1, x2 - x1, y2 - y1); + } + + /** + * Creates a new rectangle object. + * + * @method create + * @param {Number} x Rectangle x location. + * @param {Number} y Rectangle y location. + * @param {Number} w Rectangle width. + * @param {Number} h Rectangle height. + * @return {Rect} New rectangle object. + */ + function create(x, y, w, h) { + return {x: x, y: y, w: w, h: h}; + } + + /** + * Creates a new rectangle object form a clientRects object. + * + * @method fromClientRect + * @param {ClientRect} clientRect DOM ClientRect object. + * @return {Rect} New rectangle object. + */ + function fromClientRect(clientRect) { + return create(clientRect.left, clientRect.top, clientRect.width, clientRect.height); + } + + return { + inflate: inflate, + relativePosition: relativePosition, + findBestRelativePosition: findBestRelativePosition, + intersect: intersect, + clamp: clamp, + create: create, + fromClientRect: fromClientRect + }; +}); + +// Included from: js/tinymce/classes/util/Promise.js + +/** + * Promise.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * Promise polyfill under MIT license: https://github.com/taylorhakes/promise-polyfill + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/* eslint-disable */ +/* jshint ignore:start */ + +/** + * Modifed to be a feature fill and wrapped as tinymce module. + */ +define("tinymce/util/Promise", [], function() { + if (window.Promise) { + return window.Promise; + } + + // Use polyfill for setImmediate for performance gains + var asap = Promise.immediateFn || (typeof setImmediate === 'function' && setImmediate) || + function(fn) { setTimeout(fn, 1); }; + + // Polyfill for Function.prototype.bind + function bind(fn, thisArg) { + return function() { + fn.apply(thisArg, arguments); + }; + } + + var isArray = Array.isArray || function(value) { return Object.prototype.toString.call(value) === "[object Array]"; }; + + function Promise(fn) { + if (typeof this !== 'object') throw new TypeError('Promises must be constructed via new'); + if (typeof fn !== 'function') throw new TypeError('not a function'); + this._state = null; + this._value = null; + this._deferreds = []; + + doResolve(fn, bind(resolve, this), bind(reject, this)); + } + + function handle(deferred) { + var me = this; + if (this._state === null) { + this._deferreds.push(deferred); + return; + } + asap(function() { + var cb = me._state ? deferred.onFulfilled : deferred.onRejected; + if (cb === null) { + (me._state ? deferred.resolve : deferred.reject)(me._value); + return; + } + var ret; + try { + ret = cb(me._value); + } + catch (e) { + deferred.reject(e); + return; + } + deferred.resolve(ret); + }); + } + + function resolve(newValue) { + try { //Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure + if (newValue === this) throw new TypeError('A promise cannot be resolved with itself.'); + if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) { + var then = newValue.then; + if (typeof then === 'function') { + doResolve(bind(then, newValue), bind(resolve, this), bind(reject, this)); + return; + } + } + this._state = true; + this._value = newValue; + finale.call(this); + } catch (e) { reject.call(this, e); } + } + + function reject(newValue) { + this._state = false; + this._value = newValue; + finale.call(this); + } + + function finale() { + for (var i = 0, len = this._deferreds.length; i < len; i++) { + handle.call(this, this._deferreds[i]); + } + this._deferreds = null; + } + + function Handler(onFulfilled, onRejected, resolve, reject){ + this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; + this.onRejected = typeof onRejected === 'function' ? onRejected : null; + this.resolve = resolve; + this.reject = reject; + } + + /** + * Take a potentially misbehaving resolver function and make sure + * onFulfilled and onRejected are only called once. + * + * Makes no guarantees about asynchrony. + */ + function doResolve(fn, onFulfilled, onRejected) { + var done = false; + try { + fn(function (value) { + if (done) return; + done = true; + onFulfilled(value); + }, function (reason) { + if (done) return; + done = true; + onRejected(reason); + }); + } catch (ex) { + if (done) return; + done = true; + onRejected(ex); + } + } + + Promise.prototype['catch'] = function (onRejected) { + return this.then(null, onRejected); + }; + + Promise.prototype.then = function(onFulfilled, onRejected) { + var me = this; + return new Promise(function(resolve, reject) { + handle.call(me, new Handler(onFulfilled, onRejected, resolve, reject)); + }); + }; + + Promise.all = function () { + var args = Array.prototype.slice.call(arguments.length === 1 && isArray(arguments[0]) ? arguments[0] : arguments); + + return new Promise(function (resolve, reject) { + if (args.length === 0) return resolve([]); + var remaining = args.length; + function res(i, val) { + try { + if (val && (typeof val === 'object' || typeof val === 'function')) { + var then = val.then; + if (typeof then === 'function') { + then.call(val, function (val) { res(i, val); }, reject); + return; + } + } + args[i] = val; + if (--remaining === 0) { + resolve(args); + } + } catch (ex) { + reject(ex); + } + } + for (var i = 0; i < args.length; i++) { + res(i, args[i]); + } + }); + }; + + Promise.resolve = function (value) { + if (value && typeof value === 'object' && value.constructor === Promise) { + return value; + } + + return new Promise(function (resolve) { + resolve(value); + }); + }; + + Promise.reject = function (value) { + return new Promise(function (resolve, reject) { + reject(value); + }); + }; + + Promise.race = function (values) { + return new Promise(function (resolve, reject) { + for(var i = 0, len = values.length; i < len; i++) { + values[i].then(resolve, reject); + } + }); + }; + + return Promise; +}); + +/* jshint ignore:end */ +/* eslint-enable */ + +// Included from: js/tinymce/classes/util/Delay.js + +/** + * Delay.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Utility class for working with delayed actions like setTimeout. + * + * @class tinymce.util.Delay + */ +define("tinymce/util/Delay", [ + "tinymce/util/Promise" +], function(Promise) { + var requestAnimationFramePromise; + + function requestAnimationFrame(callback, element) { + var i, requestAnimationFrameFunc = window.requestAnimationFrame, vendors = ['ms', 'moz', 'webkit']; + + function featurefill(callback) { + window.setTimeout(callback, 0); + } + + for (i = 0; i < vendors.length && !requestAnimationFrameFunc; i++) { + requestAnimationFrameFunc = window[vendors[i] + 'RequestAnimationFrame']; + } + + if (!requestAnimationFrameFunc) { + requestAnimationFrameFunc = featurefill; + } + + requestAnimationFrameFunc(callback, element); + } + + function wrappedSetTimeout(callback, time) { + if (typeof time != 'number') { + time = 0; + } + + return setTimeout(callback, time); + } + + function wrappedSetInterval(callback, time) { + if (typeof time != 'number') { + time = 0; + } + + return setInterval(callback, time); + } + + function wrappedClearTimeout(id) { + return clearTimeout(id); + } + + function wrappedClearInterval(id) { + return clearInterval(id); + } + + return { + /** + * Requests an animation frame and fallbacks to a timeout on older browsers. + * + * @method requestAnimationFrame + * @param {function} callback Callback to execute when a new frame is available. + * @param {DOMElement} element Optional element to scope it to. + */ + requestAnimationFrame: function(callback, element) { + if (requestAnimationFramePromise) { + requestAnimationFramePromise.then(callback); + return; + } + + requestAnimationFramePromise = new Promise(function(resolve) { + if (!element) { + element = document.body; + } + + requestAnimationFrame(resolve, element); + }).then(callback); + }, + + /** + * Sets a timer in ms and executes the specified callback when the timer runs out. + * + * @method setTimeout + * @param {function} callback Callback to execute when timer runs out. + * @param {Number} time Optional time to wait before the callback is executed, defaults to 0. + * @return {Number} Timeout id number. + */ + setTimeout: wrappedSetTimeout, + + /** + * Sets an interval timer in ms and executes the specified callback at every interval of that time. + * + * @method setInterval + * @param {function} callback Callback to execute when interval time runs out. + * @param {Number} time Optional time to wait before the callback is executed, defaults to 0. + * @return {Number} Timeout id number. + */ + setInterval: wrappedSetInterval, + + /** + * Sets an editor timeout it's similar to setTimeout except that it checks if the editor instance is + * still alive when the callback gets executed. + * + * @method setEditorTimeout + * @param {tinymce.Editor} editor Editor instance to check the removed state on. + * @param {function} callback Callback to execute when timer runs out. + * @param {Number} time Optional time to wait before the callback is executed, defaults to 0. + * @return {Number} Timeout id number. + */ + setEditorTimeout: function(editor, callback, time) { + return wrappedSetTimeout(function() { + if (!editor.removed) { + callback(); + } + }, time); + }, + + /** + * Sets an interval timer it's similar to setInterval except that it checks if the editor instance is + * still alive when the callback gets executed. + * + * @method setEditorInterval + * @param {function} callback Callback to execute when interval time runs out. + * @param {Number} time Optional time to wait before the callback is executed, defaults to 0. + * @return {Number} Timeout id number. + */ + setEditorInterval: function(editor, callback, time) { + var timer; + + timer = wrappedSetInterval(function() { + if (!editor.removed) { + callback(); + } else { + clearInterval(timer); + } + }, time); + + return timer; + }, + + /** + * Creates throttled callback function that only gets executed once within the specified time. + * + * @method throttle + * @param {function} callback Callback to execute when timer finishes. + * @param {Number} time Optional time to wait before the callback is executed, defaults to 0. + * @return {Function} Throttled function callback. + */ + throttle: function(callback, time) { + var timer, func; + + func = function() { + var args = arguments; + + clearTimeout(timer); + + timer = wrappedSetTimeout(function() { + callback.apply(this, args); + }, time); + }; + + func.stop = function() { + clearTimeout(timer); + }; + + return func; + }, + + /** + * Clears an interval timer so it won't execute. + * + * @method clearInterval + * @param {Number} Interval timer id number. + */ + clearInterval: wrappedClearInterval, + + /** + * Clears an timeout timer so it won't execute. + * + * @method clearTimeout + * @param {Number} Timeout timer id number. + */ + clearTimeout: wrappedClearTimeout + }; +}); + +// Included from: js/tinymce/classes/Env.js + +/** + * Env.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class contains various environment constants like browser versions etc. + * Normally you don't want to sniff specific browser versions but sometimes you have + * to when it's impossible to feature detect. So use this with care. + * + * @class tinymce.Env + * @static + */ +define("tinymce/Env", [], function() { + var nav = navigator, userAgent = nav.userAgent; + var opera, webkit, ie, ie11, ie12, gecko, mac, iDevice, android, fileApi, phone, tablet, windowsPhone; + + function matchMediaQuery(query) { + return "matchMedia" in window ? matchMedia(query).matches : false; + } + + opera = window.opera && window.opera.buildNumber; + android = /Android/.test(userAgent); + webkit = /WebKit/.test(userAgent); + ie = !webkit && !opera && (/MSIE/gi).test(userAgent) && (/Explorer/gi).test(nav.appName); + ie = ie && /MSIE (\w+)\./.exec(userAgent)[1]; + ie11 = userAgent.indexOf('Trident/') != -1 && (userAgent.indexOf('rv:') != -1 || nav.appName.indexOf('Netscape') != -1) ? 11 : false; + ie12 = (userAgent.indexOf('Edge/') != -1 && !ie && !ie11) ? 12 : false; + ie = ie || ie11 || ie12; + gecko = !webkit && !ie11 && /Gecko/.test(userAgent); + mac = userAgent.indexOf('Mac') != -1; + iDevice = /(iPad|iPhone)/.test(userAgent); + fileApi = "FormData" in window && "FileReader" in window && "URL" in window && !!URL.createObjectURL; + phone = matchMediaQuery("only screen and (max-device-width: 480px)") && (android || iDevice); + tablet = matchMediaQuery("only screen and (min-width: 800px)") && (android || iDevice); + windowsPhone = userAgent.indexOf('Windows Phone') != -1; + + if (ie12) { + webkit = false; + } + + // Is a iPad/iPhone and not on iOS5 sniff the WebKit version since older iOS WebKit versions + // says it has contentEditable support but there is no visible caret. + var contentEditable = !iDevice || fileApi || userAgent.match(/AppleWebKit\/(\d*)/)[1] >= 534; + + return { + /** + * Constant that is true if the browser is Opera. + * + * @property opera + * @type Boolean + * @final + */ + opera: opera, + + /** + * Constant that is true if the browser is WebKit (Safari/Chrome). + * + * @property webKit + * @type Boolean + * @final + */ + webkit: webkit, + + /** + * Constant that is more than zero if the browser is IE. + * + * @property ie + * @type Boolean + * @final + */ + ie: ie, + + /** + * Constant that is true if the browser is Gecko. + * + * @property gecko + * @type Boolean + * @final + */ + gecko: gecko, + + /** + * Constant that is true if the os is Mac OS. + * + * @property mac + * @type Boolean + * @final + */ + mac: mac, + + /** + * Constant that is true if the os is iOS. + * + * @property iOS + * @type Boolean + * @final + */ + iOS: iDevice, + + /** + * Constant that is true if the os is android. + * + * @property android + * @type Boolean + * @final + */ + android: android, + + /** + * Constant that is true if the browser supports editing. + * + * @property contentEditable + * @type Boolean + * @final + */ + contentEditable: contentEditable, + + /** + * Transparent image data url. + * + * @property transparentSrc + * @type Boolean + * @final + */ + transparentSrc: "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7", + + /** + * Returns true/false if the browser can or can't place the caret after a inline block like an image. + * + * @property noCaretAfter + * @type Boolean + * @final + */ + caretAfter: ie != 8, + + /** + * Constant that is true if the browser supports native DOM Ranges. IE 9+. + * + * @property range + * @type Boolean + */ + range: window.getSelection && "Range" in window, + + /** + * Returns the IE document mode for non IE browsers this will fake IE 10. + * + * @property documentMode + * @type Number + */ + documentMode: ie && !ie12 ? (document.documentMode || 7) : 10, + + /** + * Constant that is true if the browser has a modern file api. + * + * @property fileApi + * @type Boolean + */ + fileApi: fileApi, + + /** + * Constant that is true if the browser supports contentEditable=false regions. + * + * @property ceFalse + * @type Boolean + */ + ceFalse: (ie === false || ie > 8), + + desktop: !phone && !tablet, + windowsPhone: windowsPhone + }; +}); + +// Included from: js/tinymce/classes/dom/EventUtils.js + +/** + * EventUtils.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/*jshint loopfunc:true*/ +/*eslint no-loop-func:0 */ + +/** + * This class wraps the browsers native event logic with more convenient methods. + * + * @class tinymce.dom.EventUtils + */ +define("tinymce/dom/EventUtils", [ + "tinymce/util/Delay", + "tinymce/Env" +], function(Delay, Env) { + "use strict"; + + var eventExpandoPrefix = "mce-data-"; + var mouseEventRe = /^(?:mouse|contextmenu)|click/; + var deprecated = { + keyLocation: 1, layerX: 1, layerY: 1, returnValue: 1, + webkitMovementX: 1, webkitMovementY: 1, keyIdentifier: 1 + }; + + /** + * Binds a native event to a callback on the speified target. + */ + function addEvent(target, name, callback, capture) { + if (target.addEventListener) { + target.addEventListener(name, callback, capture || false); + } else if (target.attachEvent) { + target.attachEvent('on' + name, callback); + } + } + + /** + * Unbinds a native event callback on the specified target. + */ + function removeEvent(target, name, callback, capture) { + if (target.removeEventListener) { + target.removeEventListener(name, callback, capture || false); + } else if (target.detachEvent) { + target.detachEvent('on' + name, callback); + } + } + + /** + * Gets the event target based on shadow dom properties like path and deepPath. + */ + function getTargetFromShadowDom(event, defaultTarget) { + var path, target = defaultTarget; + + // When target element is inside Shadow DOM we need to take first element from path + // otherwise we'll get Shadow Root parent, not actual target element + + // Normalize target for WebComponents v0 implementation (in Chrome) + path = event.path; + if (path && path.length > 0) { + target = path[0]; + } + + // Normalize target for WebComponents v1 implementation (standard) + if (event.deepPath) { + path = event.deepPath(); + if (path && path.length > 0) { + target = path[0]; + } + } + + return target; + } + + /** + * Normalizes a native event object or just adds the event specific methods on a custom event. + */ + function fix(originalEvent, data) { + var name, event = data || {}, undef; + + // Dummy function that gets replaced on the delegation state functions + function returnFalse() { + return false; + } + + // Dummy function that gets replaced on the delegation state functions + function returnTrue() { + return true; + } + + // Copy all properties from the original event + for (name in originalEvent) { + // layerX/layerY is deprecated in Chrome and produces a warning + if (!deprecated[name]) { + event[name] = originalEvent[name]; + } + } + + // Normalize target IE uses srcElement + if (!event.target) { + event.target = event.srcElement || document; + } + + // Experimental shadow dom support + if (Env.experimentalShadowDom) { + event.target = getTargetFromShadowDom(originalEvent, event.target); + } + + // Calculate pageX/Y if missing and clientX/Y available + if (originalEvent && mouseEventRe.test(originalEvent.type) && originalEvent.pageX === undef && originalEvent.clientX !== undef) { + var eventDoc = event.target.ownerDocument || document; + var doc = eventDoc.documentElement; + var body = eventDoc.body; + + event.pageX = originalEvent.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - + (doc && doc.clientLeft || body && body.clientLeft || 0); + + event.pageY = originalEvent.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - + (doc && doc.clientTop || body && body.clientTop || 0); + } + + // Add preventDefault method + event.preventDefault = function() { + event.isDefaultPrevented = returnTrue; + + // Execute preventDefault on the original event object + if (originalEvent) { + if (originalEvent.preventDefault) { + originalEvent.preventDefault(); + } else { + originalEvent.returnValue = false; // IE + } + } + }; + + // Add stopPropagation + event.stopPropagation = function() { + event.isPropagationStopped = returnTrue; + + // Execute stopPropagation on the original event object + if (originalEvent) { + if (originalEvent.stopPropagation) { + originalEvent.stopPropagation(); + } else { + originalEvent.cancelBubble = true; // IE + } + } + }; + + // Add stopImmediatePropagation + event.stopImmediatePropagation = function() { + event.isImmediatePropagationStopped = returnTrue; + event.stopPropagation(); + }; + + // Add event delegation states + if (!event.isDefaultPrevented) { + event.isDefaultPrevented = returnFalse; + event.isPropagationStopped = returnFalse; + event.isImmediatePropagationStopped = returnFalse; + } + + // Add missing metaKey for IE 8 + if (typeof event.metaKey == 'undefined') { + event.metaKey = false; + } + + return event; + } + + /** + * Bind a DOMContentLoaded event across browsers and executes the callback once the page DOM is initialized. + * It will also set/check the domLoaded state of the event_utils instance so ready isn't called multiple times. + */ + function bindOnReady(win, callback, eventUtils) { + var doc = win.document, event = {type: 'ready'}; + + if (eventUtils.domLoaded) { + callback(event); + return; + } + + // Gets called when the DOM is ready + function readyHandler() { + if (!eventUtils.domLoaded) { + eventUtils.domLoaded = true; + callback(event); + } + } + + function waitForDomLoaded() { + // Check complete or interactive state if there is a body + // element on some iframes IE 8 will produce a null body + if (doc.readyState === "complete" || (doc.readyState === "interactive" && doc.body)) { + removeEvent(doc, "readystatechange", waitForDomLoaded); + readyHandler(); + } + } + + function tryScroll() { + try { + // If IE is used, use the trick by Diego Perini licensed under MIT by request to the author. + // http://javascript.nwbox.com/IEContentLoaded/ + doc.documentElement.doScroll("left"); + } catch (ex) { + Delay.setTimeout(tryScroll); + return; + } + + readyHandler(); + } + + // Use W3C method + if (doc.addEventListener) { + if (doc.readyState === "complete") { + readyHandler(); + } else { + addEvent(win, 'DOMContentLoaded', readyHandler); + } + } else { + // Use IE method + addEvent(doc, "readystatechange", waitForDomLoaded); + + // Wait until we can scroll, when we can the DOM is initialized + if (doc.documentElement.doScroll && win.self === win.top) { + tryScroll(); + } + } + + // Fallback if any of the above methods should fail for some odd reason + addEvent(win, 'load', readyHandler); + } + + /** + * This class enables you to bind/unbind native events to elements and normalize it's behavior across browsers. + */ + function EventUtils() { + var self = this, events = {}, count, expando, hasFocusIn, hasMouseEnterLeave, mouseEnterLeave; + + expando = eventExpandoPrefix + (+new Date()).toString(32); + hasMouseEnterLeave = "onmouseenter" in document.documentElement; + hasFocusIn = "onfocusin" in document.documentElement; + mouseEnterLeave = {mouseenter: 'mouseover', mouseleave: 'mouseout'}; + count = 1; + + // State if the DOMContentLoaded was executed or not + self.domLoaded = false; + self.events = events; + + /** + * Executes all event handler callbacks for a specific event. + * + * @private + * @param {Event} evt Event object. + * @param {String} id Expando id value to look for. + */ + function executeHandlers(evt, id) { + var callbackList, i, l, callback, container = events[id]; + + callbackList = container && container[evt.type]; + if (callbackList) { + for (i = 0, l = callbackList.length; i < l; i++) { + callback = callbackList[i]; + + // Check if callback exists might be removed if a unbind is called inside the callback + if (callback && callback.func.call(callback.scope, evt) === false) { + evt.preventDefault(); + } + + // Should we stop propagation to immediate listeners + if (evt.isImmediatePropagationStopped()) { + return; + } + } + } + } + + /** + * Binds a callback to an event on the specified target. + * + * @method bind + * @param {Object} target Target node/window or custom object. + * @param {String} names Name of the event to bind. + * @param {function} callback Callback function to execute when the event occurs. + * @param {Object} scope Scope to call the callback function on, defaults to target. + * @return {function} Callback function that got bound. + */ + self.bind = function(target, names, callback, scope) { + var id, callbackList, i, name, fakeName, nativeHandler, capture, win = window; + + // Native event handler function patches the event and executes the callbacks for the expando + function defaultNativeHandler(evt) { + executeHandlers(fix(evt || win.event), id); + } + + // Don't bind to text nodes or comments + if (!target || target.nodeType === 3 || target.nodeType === 8) { + return; + } + + // Create or get events id for the target + if (!target[expando]) { + id = count++; + target[expando] = id; + events[id] = {}; + } else { + id = target[expando]; + } + + // Setup the specified scope or use the target as a default + scope = scope || target; + + // Split names and bind each event, enables you to bind multiple events with one call + names = names.split(' '); + i = names.length; + while (i--) { + name = names[i]; + nativeHandler = defaultNativeHandler; + fakeName = capture = false; + + // Use ready instead of DOMContentLoaded + if (name === "DOMContentLoaded") { + name = "ready"; + } + + // DOM is already ready + if (self.domLoaded && name === "ready" && target.readyState == 'complete') { + callback.call(scope, fix({type: name})); + continue; + } + + // Handle mouseenter/mouseleaver + if (!hasMouseEnterLeave) { + fakeName = mouseEnterLeave[name]; + + if (fakeName) { + nativeHandler = function(evt) { + var current, related; + + current = evt.currentTarget; + related = evt.relatedTarget; + + // Check if related is inside the current target if it's not then the event should + // be ignored since it's a mouseover/mouseout inside the element + if (related && current.contains) { + // Use contains for performance + related = current.contains(related); + } else { + while (related && related !== current) { + related = related.parentNode; + } + } + + // Fire fake event + if (!related) { + evt = fix(evt || win.event); + evt.type = evt.type === 'mouseout' ? 'mouseleave' : 'mouseenter'; + evt.target = current; + executeHandlers(evt, id); + } + }; + } + } + + // Fake bubbling of focusin/focusout + if (!hasFocusIn && (name === "focusin" || name === "focusout")) { + capture = true; + fakeName = name === "focusin" ? "focus" : "blur"; + nativeHandler = function(evt) { + evt = fix(evt || win.event); + evt.type = evt.type === 'focus' ? 'focusin' : 'focusout'; + executeHandlers(evt, id); + }; + } + + // Setup callback list and bind native event + callbackList = events[id][name]; + if (!callbackList) { + events[id][name] = callbackList = [{func: callback, scope: scope}]; + callbackList.fakeName = fakeName; + callbackList.capture = capture; + //callbackList.callback = callback; + + // Add the nativeHandler to the callback list so that we can later unbind it + callbackList.nativeHandler = nativeHandler; + + // Check if the target has native events support + + if (name === "ready") { + bindOnReady(target, nativeHandler, self); + } else { + addEvent(target, fakeName || name, nativeHandler, capture); + } + } else { + if (name === "ready" && self.domLoaded) { + callback({type: name}); + } else { + // If it already has an native handler then just push the callback + callbackList.push({func: callback, scope: scope}); + } + } + } + + target = callbackList = 0; // Clean memory for IE + + return callback; + }; + + /** + * Unbinds the specified event by name, name and callback or all events on the target. + * + * @method unbind + * @param {Object} target Target node/window or custom object. + * @param {String} names Optional event name to unbind. + * @param {function} callback Optional callback function to unbind. + * @return {EventUtils} Event utils instance. + */ + self.unbind = function(target, names, callback) { + var id, callbackList, i, ci, name, eventMap; + + // Don't bind to text nodes or comments + if (!target || target.nodeType === 3 || target.nodeType === 8) { + return self; + } + + // Unbind event or events if the target has the expando + id = target[expando]; + if (id) { + eventMap = events[id]; + + // Specific callback + if (names) { + names = names.split(' '); + i = names.length; + while (i--) { + name = names[i]; + callbackList = eventMap[name]; + + // Unbind the event if it exists in the map + if (callbackList) { + // Remove specified callback + if (callback) { + ci = callbackList.length; + while (ci--) { + if (callbackList[ci].func === callback) { + var nativeHandler = callbackList.nativeHandler; + var fakeName = callbackList.fakeName, capture = callbackList.capture; + + // Clone callbackList since unbind inside a callback would otherwise break the handlers loop + callbackList = callbackList.slice(0, ci).concat(callbackList.slice(ci + 1)); + callbackList.nativeHandler = nativeHandler; + callbackList.fakeName = fakeName; + callbackList.capture = capture; + + eventMap[name] = callbackList; + } + } + } + + // Remove all callbacks if there isn't a specified callback or there is no callbacks left + if (!callback || callbackList.length === 0) { + delete eventMap[name]; + removeEvent(target, callbackList.fakeName || name, callbackList.nativeHandler, callbackList.capture); + } + } + } + } else { + // All events for a specific element + for (name in eventMap) { + callbackList = eventMap[name]; + removeEvent(target, callbackList.fakeName || name, callbackList.nativeHandler, callbackList.capture); + } + + eventMap = {}; + } + + // Check if object is empty, if it isn't then we won't remove the expando map + for (name in eventMap) { + return self; + } + + // Delete event object + delete events[id]; + + // Remove expando from target + try { + // IE will fail here since it can't delete properties from window + delete target[expando]; + } catch (ex) { + // IE will set it to null + target[expando] = null; + } + } + + return self; + }; + + /** + * Fires the specified event on the specified target. + * + * @method fire + * @param {Object} target Target node/window or custom object. + * @param {String} name Event name to fire. + * @param {Object} args Optional arguments to send to the observers. + * @return {EventUtils} Event utils instance. + */ + self.fire = function(target, name, args) { + var id; + + // Don't bind to text nodes or comments + if (!target || target.nodeType === 3 || target.nodeType === 8) { + return self; + } + + // Build event object by patching the args + args = fix(null, args); + args.type = name; + args.target = target; + + do { + // Found an expando that means there is listeners to execute + id = target[expando]; + if (id) { + executeHandlers(args, id); + } + + // Walk up the DOM + target = target.parentNode || target.ownerDocument || target.defaultView || target.parentWindow; + } while (target && !args.isPropagationStopped()); + + return self; + }; + + /** + * Removes all bound event listeners for the specified target. This will also remove any bound + * listeners to child nodes within that target. + * + * @method clean + * @param {Object} target Target node/window object. + * @return {EventUtils} Event utils instance. + */ + self.clean = function(target) { + var i, children, unbind = self.unbind; + + // Don't bind to text nodes or comments + if (!target || target.nodeType === 3 || target.nodeType === 8) { + return self; + } + + // Unbind any element on the specified target + if (target[expando]) { + unbind(target); + } + + // Target doesn't have getElementsByTagName it's probably a window object then use it's document to find the children + if (!target.getElementsByTagName) { + target = target.document; + } + + // Remove events from each child element + if (target && target.getElementsByTagName) { + unbind(target); + + children = target.getElementsByTagName('*'); + i = children.length; + while (i--) { + target = children[i]; + + if (target[expando]) { + unbind(target); + } + } + } + + return self; + }; + + /** + * Destroys the event object. Call this on IE to remove memory leaks. + */ + self.destroy = function() { + events = {}; + }; + + // Legacy function for canceling events + self.cancel = function(e) { + if (e) { + e.preventDefault(); + e.stopImmediatePropagation(); + } + + return false; + }; + } + + EventUtils.Event = new EventUtils(); + EventUtils.Event.bind(window, 'ready', function() {}); + + return EventUtils; +}); + +// Included from: js/tinymce/classes/dom/Sizzle.js + +/** + * Sizzle.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + * + * @ignore-file + */ + +/*jshint bitwise:false, expr:true, noempty:false, sub:true, eqnull:true, latedef:false, maxlen:255 */ +/*eslint-disable */ + +/** + * Sizzle CSS Selector Engine v@VERSION + * http://sizzlejs.com/ + * + * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: @DATE + */ +define("tinymce/dom/Sizzle", [], function() { +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + -(new Date()), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // General-purpose constants + strundefined = typeof undefined, + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf if we can't use a native one + indexOf = arr.indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { + return []; + } + + if ( documentIsHTML && !seed ) { + + // Shortcuts + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document (jQuery #6963) + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== strundefined && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, + doc = node ? node.ownerDocument || node : preferredDoc, + parent = doc.defaultView; + + function getTop(win) { + // Edge throws a lovely Object expected if you try to get top on a detached reference see #2642 + try { + return win.top; + } catch (ex) { + // Ignore + } + + return null; + } + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + + // Support tests + documentIsHTML = !isXML( doc ); + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent !== getTop(parent) ) { + // IE11 does not have attachEvent, so all must suffer + if ( parent.addEventListener ) { + parent.addEventListener( "unload", function() { + setDocument(); + }, false ); + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", function() { + setDocument(); + }); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( doc.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== strundefined && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [ m ] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var elem, + tmp = [], + i = 0, + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = "<select msallowcapture=''><option selected=''></option></select>"; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( div.querySelectorAll("[msallowcapture^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( div.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (oldCache = outerCache[ dir ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + outerCache[ dir ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context !== document && context; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is no seed and only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = "<a href='#'></a>"; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = "<input/>"; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +// EXPOSE +return Sizzle; +}); + +/*eslint-enable */ + +// Included from: js/tinymce/classes/util/Arr.js + +/** + * Arr.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Array utility class. + * + * @private + * @class tinymce.util.Arr + */ +define("tinymce/util/Arr", [], function() { + var isArray = Array.isArray || function(obj) { + return Object.prototype.toString.call(obj) === "[object Array]"; + }; + + function toArray(obj) { + var array = obj, i, l; + + if (!isArray(obj)) { + array = []; + for (i = 0, l = obj.length; i < l; i++) { + array[i] = obj[i]; + } + } + + return array; + } + + function each(o, cb, s) { + var n, l; + + if (!o) { + return 0; + } + + s = s || o; + + if (o.length !== undefined) { + // Indexed arrays, needed for Safari + for (n = 0, l = o.length; n < l; n++) { + if (cb.call(s, o[n], n, o) === false) { + return 0; + } + } + } else { + // Hashtables + for (n in o) { + if (o.hasOwnProperty(n)) { + if (cb.call(s, o[n], n, o) === false) { + return 0; + } + } + } + } + + return 1; + } + + function map(array, callback) { + var out = []; + + each(array, function(item, index) { + out.push(callback(item, index, array)); + }); + + return out; + } + + function filter(a, f) { + var o = []; + + each(a, function(v, index) { + if (!f || f(v, index, a)) { + o.push(v); + } + }); + + return o; + } + + function indexOf(a, v) { + var i, l; + + if (a) { + for (i = 0, l = a.length; i < l; i++) { + if (a[i] === v) { + return i; + } + } + } + + return -1; + } + + function reduce(collection, iteratee, accumulator, thisArg) { + var i = 0; + + if (arguments.length < 3) { + accumulator = collection[0]; + } + + for (; i < collection.length; i++) { + accumulator = iteratee.call(thisArg, accumulator, collection[i], i); + } + + return accumulator; + } + + function findIndex(array, predicate, thisArg) { + var i, l; + + for (i = 0, l = array.length; i < l; i++) { + if (predicate.call(thisArg, array[i], i, array)) { + return i; + } + } + + return -1; + } + + function find(array, predicate, thisArg) { + var idx = findIndex(array, predicate, thisArg); + + if (idx !== -1) { + return array[idx]; + } + + return undefined; + } + + function last(collection) { + return collection[collection.length - 1]; + } + + return { + isArray: isArray, + toArray: toArray, + each: each, + map: map, + filter: filter, + indexOf: indexOf, + reduce: reduce, + findIndex: findIndex, + find: find, + last: last + }; +}); + +// Included from: js/tinymce/classes/util/Tools.js + +/** + * Tools.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class contains various utlity functions. These are also exposed + * directly on the tinymce namespace. + * + * @class tinymce.util.Tools + */ +define("tinymce/util/Tools", [ + "tinymce/Env", + "tinymce/util/Arr" +], function(Env, Arr) { + /** + * Removes whitespace from the beginning and end of a string. + * + * @method trim + * @param {String} s String to remove whitespace from. + * @return {String} New string with removed whitespace. + */ + var whiteSpaceRegExp = /^\s*|\s*$/g; + + function trim(str) { + return (str === null || str === undefined) ? '' : ("" + str).replace(whiteSpaceRegExp, ''); + } + + /** + * Checks if a object is of a specific type for example an array. + * + * @method is + * @param {Object} obj Object to check type of. + * @param {string} type Optional type to check for. + * @return {Boolean} true/false if the object is of the specified type. + */ + function is(obj, type) { + if (!type) { + return obj !== undefined; + } + + if (type == 'array' && Arr.isArray(obj)) { + return true; + } + + return typeof obj == type; + } + + /** + * Makes a name/object map out of an array with names. + * + * @method makeMap + * @param {Array/String} items Items to make map out of. + * @param {String} delim Optional delimiter to split string by. + * @param {Object} map Optional map to add items to. + * @return {Object} Name/value map of items. + */ + function makeMap(items, delim, map) { + var i; + + items = items || []; + delim = delim || ','; + + if (typeof items == "string") { + items = items.split(delim); + } + + map = map || {}; + + i = items.length; + while (i--) { + map[items[i]] = {}; + } + + return map; + } + + /** + * Creates a class, subclass or static singleton. + * More details on this method can be found in the Wiki. + * + * @method create + * @param {String} s Class name, inheritance and prefix. + * @param {Object} p Collection of methods to add to the class. + * @param {Object} root Optional root object defaults to the global window object. + * @example + * // Creates a basic class + * tinymce.create('tinymce.somepackage.SomeClass', { + * SomeClass: function() { + * // Class constructor + * }, + * + * method: function() { + * // Some method + * } + * }); + * + * // Creates a basic subclass class + * tinymce.create('tinymce.somepackage.SomeSubClass:tinymce.somepackage.SomeClass', { + * SomeSubClass: function() { + * // Class constructor + * this.parent(); // Call parent constructor + * }, + * + * method: function() { + * // Some method + * this.parent(); // Call parent method + * }, + * + * 'static': { + * staticMethod: function() { + * // Static method + * } + * } + * }); + * + * // Creates a singleton/static class + * tinymce.create('static tinymce.somepackage.SomeSingletonClass', { + * method: function() { + * // Some method + * } + * }); + */ + function create(s, p, root) { + var self = this, sp, ns, cn, scn, c, de = 0; + + // Parse : <prefix> <class>:<super class> + s = /^((static) )?([\w.]+)(:([\w.]+))?/.exec(s); + cn = s[3].match(/(^|\.)(\w+)$/i)[2]; // Class name + + // Create namespace for new class + ns = self.createNS(s[3].replace(/\.\w+$/, ''), root); + + // Class already exists + if (ns[cn]) { + return; + } + + // Make pure static class + if (s[2] == 'static') { + ns[cn] = p; + + if (this.onCreate) { + this.onCreate(s[2], s[3], ns[cn]); + } + + return; + } + + // Create default constructor + if (!p[cn]) { + p[cn] = function() {}; + de = 1; + } + + // Add constructor and methods + ns[cn] = p[cn]; + self.extend(ns[cn].prototype, p); + + // Extend + if (s[5]) { + sp = self.resolve(s[5]).prototype; + scn = s[5].match(/\.(\w+)$/i)[1]; // Class name + + // Extend constructor + c = ns[cn]; + if (de) { + // Add passthrough constructor + ns[cn] = function() { + return sp[scn].apply(this, arguments); + }; + } else { + // Add inherit constructor + ns[cn] = function() { + this.parent = sp[scn]; + return c.apply(this, arguments); + }; + } + ns[cn].prototype[cn] = ns[cn]; + + // Add super methods + self.each(sp, function(f, n) { + ns[cn].prototype[n] = sp[n]; + }); + + // Add overridden methods + self.each(p, function(f, n) { + // Extend methods if needed + if (sp[n]) { + ns[cn].prototype[n] = function() { + this.parent = sp[n]; + return f.apply(this, arguments); + }; + } else { + if (n != cn) { + ns[cn].prototype[n] = f; + } + } + }); + } + + // Add static methods + /*jshint sub:true*/ + /*eslint dot-notation:0*/ + self.each(p['static'], function(f, n) { + ns[cn][n] = f; + }); + } + + function extend(obj, ext) { + var i, l, name, args = arguments, value; + + for (i = 1, l = args.length; i < l; i++) { + ext = args[i]; + for (name in ext) { + if (ext.hasOwnProperty(name)) { + value = ext[name]; + + if (value !== undefined) { + obj[name] = value; + } + } + } + } + + return obj; + } + + /** + * Executed the specified function for each item in a object tree. + * + * @method walk + * @param {Object} o Object tree to walk though. + * @param {function} f Function to call for each item. + * @param {String} n Optional name of collection inside the objects to walk for example childNodes. + * @param {String} s Optional scope to execute the function in. + */ + function walk(o, f, n, s) { + s = s || this; + + if (o) { + if (n) { + o = o[n]; + } + + Arr.each(o, function(o, i) { + if (f.call(s, o, i, n) === false) { + return false; + } + + walk(o, f, n, s); + }); + } + } + + /** + * Creates a namespace on a specific object. + * + * @method createNS + * @param {String} n Namespace to create for example a.b.c.d. + * @param {Object} o Optional object to add namespace to, defaults to window. + * @return {Object} New namespace object the last item in path. + * @example + * // Create some namespace + * tinymce.createNS('tinymce.somepackage.subpackage'); + * + * // Add a singleton + * var tinymce.somepackage.subpackage.SomeSingleton = { + * method: function() { + * // Some method + * } + * }; + */ + function createNS(n, o) { + var i, v; + + o = o || window; + + n = n.split('.'); + for (i = 0; i < n.length; i++) { + v = n[i]; + + if (!o[v]) { + o[v] = {}; + } + + o = o[v]; + } + + return o; + } + + /** + * Resolves a string and returns the object from a specific structure. + * + * @method resolve + * @param {String} n Path to resolve for example a.b.c.d. + * @param {Object} o Optional object to search though, defaults to window. + * @return {Object} Last object in path or null if it couldn't be resolved. + * @example + * // Resolve a path into an object reference + * var obj = tinymce.resolve('a.b.c.d'); + */ + function resolve(n, o) { + var i, l; + + o = o || window; + + n = n.split('.'); + for (i = 0, l = n.length; i < l; i++) { + o = o[n[i]]; + + if (!o) { + break; + } + } + + return o; + } + + /** + * Splits a string but removes the whitespace before and after each value. + * + * @method explode + * @param {string} s String to split. + * @param {string} d Delimiter to split by. + * @example + * // Split a string into an array with a,b,c + * var arr = tinymce.explode('a, b, c'); + */ + function explode(s, d) { + if (!s || is(s, 'array')) { + return s; + } + + return Arr.map(s.split(d || ','), trim); + } + + function _addCacheSuffix(url) { + var cacheSuffix = Env.cacheSuffix; + + if (cacheSuffix) { + url += (url.indexOf('?') === -1 ? '?' : '&') + cacheSuffix; + } + + return url; + } + + return { + trim: trim, + + /** + * Returns true/false if the object is an array or not. + * + * @method isArray + * @param {Object} obj Object to check. + * @return {boolean} true/false state if the object is an array or not. + */ + isArray: Arr.isArray, + + is: is, + + /** + * Converts the specified object into a real JavaScript array. + * + * @method toArray + * @param {Object} obj Object to convert into array. + * @return {Array} Array object based in input. + */ + toArray: Arr.toArray, + makeMap: makeMap, + + /** + * Performs an iteration of all items in a collection such as an object or array. This method will execure the + * callback function for each item in the collection, if the callback returns false the iteration will terminate. + * The callback has the following format: cb(value, key_or_index). + * + * @method each + * @param {Object} o Collection to iterate. + * @param {function} cb Callback function to execute for each item. + * @param {Object} s Optional scope to execute the callback in. + * @example + * // Iterate an array + * tinymce.each([1,2,3], function(v, i) { + * console.debug("Value: " + v + ", Index: " + i); + * }); + * + * // Iterate an object + * tinymce.each({a: 1, b: 2, c: 3], function(v, k) { + * console.debug("Value: " + v + ", Key: " + k); + * }); + */ + each: Arr.each, + + /** + * Creates a new array by the return value of each iteration function call. This enables you to convert + * one array list into another. + * + * @method map + * @param {Array} array Array of items to iterate. + * @param {function} callback Function to call for each item. It's return value will be the new value. + * @return {Array} Array with new values based on function return values. + */ + map: Arr.map, + + /** + * Filters out items from the input array by calling the specified function for each item. + * If the function returns false the item will be excluded if it returns true it will be included. + * + * @method grep + * @param {Array} a Array of items to loop though. + * @param {function} f Function to call for each item. Include/exclude depends on it's return value. + * @return {Array} New array with values imported and filtered based in input. + * @example + * // Filter out some items, this will return an array with 4 and 5 + * var items = tinymce.grep([1,2,3,4,5], function(v) {return v > 3;}); + */ + grep: Arr.filter, + + /** + * Returns true/false if the object is an array or not. + * + * @method isArray + * @param {Object} obj Object to check. + * @return {boolean} true/false state if the object is an array or not. + */ + inArray: Arr.indexOf, + + extend: extend, + create: create, + walk: walk, + createNS: createNS, + resolve: resolve, + explode: explode, + _addCacheSuffix: _addCacheSuffix + }; +}); + +// Included from: js/tinymce/classes/dom/DomQuery.js + +/** + * DomQuery.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class mimics most of the jQuery API: + * + * This is whats currently implemented: + * - Utility functions + * - DOM traversial + * - DOM manipulation + * - Event binding + * + * This is not currently implemented: + * - Dimension + * - Ajax + * - Animation + * - Advanced chaining + * + * @example + * var $ = tinymce.dom.DomQuery; + * $('p').attr('attr', 'value').addClass('class'); + * + * @class tinymce.dom.DomQuery + */ +define("tinymce/dom/DomQuery", [ + "tinymce/dom/EventUtils", + "tinymce/dom/Sizzle", + "tinymce/util/Tools", + "tinymce/Env" +], function(EventUtils, Sizzle, Tools, Env) { + var doc = document, push = Array.prototype.push, slice = Array.prototype.slice; + var rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/; + var Event = EventUtils.Event, undef; + var skipUniques = Tools.makeMap('children,contents,next,prev'); + + function isDefined(obj) { + return typeof obj !== 'undefined'; + } + + function isString(obj) { + return typeof obj === 'string'; + } + + function isWindow(obj) { + return obj && obj == obj.window; + } + + function createFragment(html, fragDoc) { + var frag, node, container; + + fragDoc = fragDoc || doc; + container = fragDoc.createElement('div'); + frag = fragDoc.createDocumentFragment(); + container.innerHTML = html; + + while ((node = container.firstChild)) { + frag.appendChild(node); + } + + return frag; + } + + function domManipulate(targetNodes, sourceItem, callback, reverse) { + var i; + + if (isString(sourceItem)) { + sourceItem = createFragment(sourceItem, getElementDocument(targetNodes[0])); + } else if (sourceItem.length && !sourceItem.nodeType) { + sourceItem = DomQuery.makeArray(sourceItem); + + if (reverse) { + for (i = sourceItem.length - 1; i >= 0; i--) { + domManipulate(targetNodes, sourceItem[i], callback, reverse); + } + } else { + for (i = 0; i < sourceItem.length; i++) { + domManipulate(targetNodes, sourceItem[i], callback, reverse); + } + } + + return targetNodes; + } + + if (sourceItem.nodeType) { + i = targetNodes.length; + while (i--) { + callback.call(targetNodes[i], sourceItem); + } + } + + return targetNodes; + } + + function hasClass(node, className) { + return node && className && (' ' + node.className + ' ').indexOf(' ' + className + ' ') !== -1; + } + + function wrap(elements, wrapper, all) { + var lastParent, newWrapper; + + wrapper = DomQuery(wrapper)[0]; + + elements.each(function() { + var self = this; + + if (!all || lastParent != self.parentNode) { + lastParent = self.parentNode; + newWrapper = wrapper.cloneNode(false); + self.parentNode.insertBefore(newWrapper, self); + newWrapper.appendChild(self); + } else { + newWrapper.appendChild(self); + } + }); + + return elements; + } + + var numericCssMap = Tools.makeMap('fillOpacity fontWeight lineHeight opacity orphans widows zIndex zoom', ' '); + var booleanMap = Tools.makeMap('checked compact declare defer disabled ismap multiple nohref noshade nowrap readonly selected', ' '); + var propFix = { + 'for': 'htmlFor', + 'class': 'className', + 'readonly': 'readOnly' + }; + var cssFix = { + 'float': 'cssFloat' + }; + + var attrHooks = {}, cssHooks = {}; + + function DomQuery(selector, context) { + /*eslint new-cap:0 */ + return new DomQuery.fn.init(selector, context); + } + + function inArray(item, array) { + var i; + + if (array.indexOf) { + return array.indexOf(item); + } + + i = array.length; + while (i--) { + if (array[i] === item) { + return i; + } + } + + return -1; + } + + var whiteSpaceRegExp = /^\s*|\s*$/g; + + function trim(str) { + return (str === null || str === undef) ? '' : ("" + str).replace(whiteSpaceRegExp, ''); + } + + function each(obj, callback) { + var length, key, i, undef, value; + + if (obj) { + length = obj.length; + + if (length === undef) { + // Loop object items + for (key in obj) { + if (obj.hasOwnProperty(key)) { + value = obj[key]; + if (callback.call(value, key, value) === false) { + break; + } + } + } + } else { + // Loop array items + for (i = 0; i < length; i++) { + value = obj[i]; + if (callback.call(value, i, value) === false) { + break; + } + } + } + } + + return obj; + } + + function grep(array, callback) { + var out = []; + + each(array, function(i, item) { + if (callback(item, i)) { + out.push(item); + } + }); + + return out; + } + + function getElementDocument(element) { + if (!element) { + return doc; + } + + if (element.nodeType == 9) { + return element; + } + + return element.ownerDocument; + } + + DomQuery.fn = DomQuery.prototype = { + constructor: DomQuery, + + /** + * Selector for the current set. + * + * @property selector + * @type String + */ + selector: "", + + /** + * Context used to create the set. + * + * @property context + * @type Element + */ + context: null, + + /** + * Number of items in the current set. + * + * @property length + * @type Number + */ + length: 0, + + /** + * Constructs a new DomQuery instance with the specified selector or context. + * + * @constructor + * @method init + * @param {String/Array/DomQuery} selector Optional CSS selector/Array or array like object or HTML string. + * @param {Document/Element} context Optional context to search in. + */ + init: function(selector, context) { + var self = this, match, node; + + if (!selector) { + return self; + } + + if (selector.nodeType) { + self.context = self[0] = selector; + self.length = 1; + + return self; + } + + if (context && context.nodeType) { + self.context = context; + } else { + if (context) { + return DomQuery(selector).attr(context); + } + + self.context = context = document; + } + + if (isString(selector)) { + self.selector = selector; + + if (selector.charAt(0) === "<" && selector.charAt(selector.length - 1) === ">" && selector.length >= 3) { + match = [null, selector, null]; + } else { + match = rquickExpr.exec(selector); + } + + if (match) { + if (match[1]) { + node = createFragment(selector, getElementDocument(context)).firstChild; + + while (node) { + push.call(self, node); + node = node.nextSibling; + } + } else { + node = getElementDocument(context).getElementById(match[2]); + + if (!node) { + return self; + } + + if (node.id !== match[2]) { + return self.find(selector); + } + + self.length = 1; + self[0] = node; + } + } else { + return DomQuery(context).find(selector); + } + } else { + this.add(selector, false); + } + + return self; + }, + + /** + * Converts the current set to an array. + * + * @method toArray + * @return {Array} Array of all nodes in set. + */ + toArray: function() { + return Tools.toArray(this); + }, + + /** + * Adds new nodes to the set. + * + * @method add + * @param {Array/tinymce.dom.DomQuery} items Array of all nodes to add to set. + * @param {Boolean} sort Optional sort flag that enables sorting of elements. + * @return {tinymce.dom.DomQuery} New instance with nodes added. + */ + add: function(items, sort) { + var self = this, nodes, i; + + if (isString(items)) { + return self.add(DomQuery(items)); + } + + if (sort !== false) { + nodes = DomQuery.unique(self.toArray().concat(DomQuery.makeArray(items))); + self.length = nodes.length; + for (i = 0; i < nodes.length; i++) { + self[i] = nodes[i]; + } + } else { + push.apply(self, DomQuery.makeArray(items)); + } + + return self; + }, + + /** + * Sets/gets attributes on the elements in the current set. + * + * @method attr + * @param {String/Object} name Name of attribute to get or an object with attributes to set. + * @param {String} value Optional value to set. + * @return {tinymce.dom.DomQuery/String} Current set or the specified attribute when only the name is specified. + */ + attr: function(name, value) { + var self = this, hook; + + if (typeof name === "object") { + each(name, function(name, value) { + self.attr(name, value); + }); + } else if (isDefined(value)) { + this.each(function() { + var hook; + + if (this.nodeType === 1) { + hook = attrHooks[name]; + if (hook && hook.set) { + hook.set(this, value); + return; + } + + if (value === null) { + this.removeAttribute(name, 2); + } else { + this.setAttribute(name, value, 2); + } + } + }); + } else { + if (self[0] && self[0].nodeType === 1) { + hook = attrHooks[name]; + if (hook && hook.get) { + return hook.get(self[0], name); + } + + if (booleanMap[name]) { + return self.prop(name) ? name : undef; + } + + value = self[0].getAttribute(name, 2); + + if (value === null) { + value = undef; + } + } + + return value; + } + + return self; + }, + + /** + * Removes attributse on the elements in the current set. + * + * @method removeAttr + * @param {String/Object} name Name of attribute to remove. + * @return {tinymce.dom.DomQuery/String} Current set. + */ + removeAttr: function(name) { + return this.attr(name, null); + }, + + /** + * Sets/gets properties on the elements in the current set. + * + * @method attr + * @param {String/Object} name Name of property to get or an object with properties to set. + * @param {String} value Optional value to set. + * @return {tinymce.dom.DomQuery/String} Current set or the specified property when only the name is specified. + */ + prop: function(name, value) { + var self = this; + + name = propFix[name] || name; + + if (typeof name === "object") { + each(name, function(name, value) { + self.prop(name, value); + }); + } else if (isDefined(value)) { + this.each(function() { + if (this.nodeType == 1) { + this[name] = value; + } + }); + } else { + if (self[0] && self[0].nodeType && name in self[0]) { + return self[0][name]; + } + + return value; + } + + return self; + }, + + /** + * Sets/gets styles on the elements in the current set. + * + * @method css + * @param {String/Object} name Name of style to get or an object with styles to set. + * @param {String} value Optional value to set. + * @return {tinymce.dom.DomQuery/String} Current set or the specified style when only the name is specified. + */ + css: function(name, value) { + var self = this, elm, hook; + + function camel(name) { + return name.replace(/-(\D)/g, function(a, b) { + return b.toUpperCase(); + }); + } + + function dashed(name) { + return name.replace(/[A-Z]/g, function(a) { + return '-' + a; + }); + } + + if (typeof name === "object") { + each(name, function(name, value) { + self.css(name, value); + }); + } else { + if (isDefined(value)) { + name = camel(name); + + // Default px suffix on these + if (typeof value === 'number' && !numericCssMap[name]) { + value += 'px'; + } + + self.each(function() { + var style = this.style; + + hook = cssHooks[name]; + if (hook && hook.set) { + hook.set(this, value); + return; + } + + try { + this.style[cssFix[name] || name] = value; + } catch (ex) { + // Ignore + } + + if (value === null || value === '') { + if (style.removeProperty) { + style.removeProperty(dashed(name)); + } else { + style.removeAttribute(name); + } + } + }); + } else { + elm = self[0]; + + hook = cssHooks[name]; + if (hook && hook.get) { + return hook.get(elm); + } + + if (elm.ownerDocument.defaultView) { + try { + return elm.ownerDocument.defaultView.getComputedStyle(elm, null).getPropertyValue(dashed(name)); + } catch (ex) { + return undef; + } + } else if (elm.currentStyle) { + return elm.currentStyle[camel(name)]; + } + } + } + + return self; + }, + + /** + * Removes all nodes in set from the document. + * + * @method remove + * @return {tinymce.dom.DomQuery} Current set with the removed nodes. + */ + remove: function() { + var self = this, node, i = this.length; + + while (i--) { + node = self[i]; + Event.clean(node); + + if (node.parentNode) { + node.parentNode.removeChild(node); + } + } + + return this; + }, + + /** + * Empties all elements in set. + * + * @method empty + * @return {tinymce.dom.DomQuery} Current set with the empty nodes. + */ + empty: function() { + var self = this, node, i = this.length; + + while (i--) { + node = self[i]; + while (node.firstChild) { + node.removeChild(node.firstChild); + } + } + + return this; + }, + + /** + * Sets or gets the HTML of the current set or first set node. + * + * @method html + * @param {String} value Optional innerHTML value to set on each element. + * @return {tinymce.dom.DomQuery/String} Current set or the innerHTML of the first element. + */ + html: function(value) { + var self = this, i; + + if (isDefined(value)) { + i = self.length; + + try { + while (i--) { + self[i].innerHTML = value; + } + } catch (ex) { + // Workaround for "Unknown runtime error" when DIV is added to P on IE + DomQuery(self[i]).empty().append(value); + } + + return self; + } + + return self[0] ? self[0].innerHTML : ''; + }, + + /** + * Sets or gets the text of the current set or first set node. + * + * @method text + * @param {String} value Optional innerText value to set on each element. + * @return {tinymce.dom.DomQuery/String} Current set or the innerText of the first element. + */ + text: function(value) { + var self = this, i; + + if (isDefined(value)) { + i = self.length; + while (i--) { + if ("innerText" in self[i]) { + self[i].innerText = value; + } else { + self[0].textContent = value; + } + } + + return self; + } + + return self[0] ? (self[0].innerText || self[0].textContent) : ''; + }, + + /** + * Appends the specified node/html or node set to the current set nodes. + * + * @method append + * @param {String/Element/Array/tinymce.dom.DomQuery} content Content to append to each element in set. + * @return {tinymce.dom.DomQuery} Current set. + */ + append: function() { + return domManipulate(this, arguments, function(node) { + // Either element or Shadow Root + if (this.nodeType === 1 || (this.host && this.host.nodeType === 1)) { + this.appendChild(node); + } + }); + }, + + /** + * Prepends the specified node/html or node set to the current set nodes. + * + * @method prepend + * @param {String/Element/Array/tinymce.dom.DomQuery} content Content to prepend to each element in set. + * @return {tinymce.dom.DomQuery} Current set. + */ + prepend: function() { + return domManipulate(this, arguments, function(node) { + // Either element or Shadow Root + if (this.nodeType === 1 || (this.host && this.host.nodeType === 1)) { + this.insertBefore(node, this.firstChild); + } + }, true); + }, + + /** + * Adds the specified elements before current set nodes. + * + * @method before + * @param {String/Element/Array/tinymce.dom.DomQuery} content Content to add before to each element in set. + * @return {tinymce.dom.DomQuery} Current set. + */ + before: function() { + var self = this; + + if (self[0] && self[0].parentNode) { + return domManipulate(self, arguments, function(node) { + this.parentNode.insertBefore(node, this); + }); + } + + return self; + }, + + /** + * Adds the specified elements after current set nodes. + * + * @method after + * @param {String/Element/Array/tinymce.dom.DomQuery} content Content to add after to each element in set. + * @return {tinymce.dom.DomQuery} Current set. + */ + after: function() { + var self = this; + + if (self[0] && self[0].parentNode) { + return domManipulate(self, arguments, function(node) { + this.parentNode.insertBefore(node, this.nextSibling); + }, true); + } + + return self; + }, + + /** + * Appends the specified set nodes to the specified selector/instance. + * + * @method appendTo + * @param {String/Element/Array/tinymce.dom.DomQuery} val Item to append the current set to. + * @return {tinymce.dom.DomQuery} Current set with the appended nodes. + */ + appendTo: function(val) { + DomQuery(val).append(this); + + return this; + }, + + /** + * Prepends the specified set nodes to the specified selector/instance. + * + * @method prependTo + * @param {String/Element/Array/tinymce.dom.DomQuery} val Item to prepend the current set to. + * @return {tinymce.dom.DomQuery} Current set with the prepended nodes. + */ + prependTo: function(val) { + DomQuery(val).prepend(this); + + return this; + }, + + /** + * Replaces the nodes in set with the specified content. + * + * @method replaceWith + * @param {String/Element/Array/tinymce.dom.DomQuery} content Content to replace nodes with. + * @return {tinymce.dom.DomQuery} Set with replaced nodes. + */ + replaceWith: function(content) { + return this.before(content).remove(); + }, + + /** + * Wraps all elements in set with the specified wrapper. + * + * @method wrap + * @param {String/Element/Array/tinymce.dom.DomQuery} content Content to wrap nodes with. + * @return {tinymce.dom.DomQuery} Set with wrapped nodes. + */ + wrap: function(content) { + return wrap(this, content); + }, + + /** + * Wraps all nodes in set with the specified wrapper. If the nodes are siblings all of them + * will be wrapped in the same wrapper. + * + * @method wrapAll + * @param {String/Element/Array/tinymce.dom.DomQuery} content Content to wrap nodes with. + * @return {tinymce.dom.DomQuery} Set with wrapped nodes. + */ + wrapAll: function(content) { + return wrap(this, content, true); + }, + + /** + * Wraps all elements inner contents in set with the specified wrapper. + * + * @method wrapInner + * @param {String/Element/Array/tinymce.dom.DomQuery} content Content to wrap nodes with. + * @return {tinymce.dom.DomQuery} Set with wrapped nodes. + */ + wrapInner: function(content) { + this.each(function() { + DomQuery(this).contents().wrapAll(content); + }); + + return this; + }, + + /** + * Unwraps all elements by removing the parent element of each item in set. + * + * @method unwrap + * @return {tinymce.dom.DomQuery} Set with unwrapped nodes. + */ + unwrap: function() { + return this.parent().each(function() { + DomQuery(this).replaceWith(this.childNodes); + }); + }, + + /** + * Clones all nodes in set. + * + * @method clone + * @return {tinymce.dom.DomQuery} Set with cloned nodes. + */ + clone: function() { + var result = []; + + this.each(function() { + result.push(this.cloneNode(true)); + }); + + return DomQuery(result); + }, + + /** + * Adds the specified class name to the current set elements. + * + * @method addClass + * @param {String} className Class name to add. + * @return {tinymce.dom.DomQuery} Current set. + */ + addClass: function(className) { + return this.toggleClass(className, true); + }, + + /** + * Removes the specified class name to the current set elements. + * + * @method removeClass + * @param {String} className Class name to remove. + * @return {tinymce.dom.DomQuery} Current set. + */ + removeClass: function(className) { + return this.toggleClass(className, false); + }, + + /** + * Toggles the specified class name on the current set elements. + * + * @method toggleClass + * @param {String} className Class name to add/remove. + * @param {Boolean} state Optional state to toggle on/off. + * @return {tinymce.dom.DomQuery} Current set. + */ + toggleClass: function(className, state) { + var self = this; + + // Functions are not supported + if (typeof className != 'string') { + return self; + } + + if (className.indexOf(' ') !== -1) { + each(className.split(' '), function() { + self.toggleClass(this, state); + }); + } else { + self.each(function(index, node) { + var existingClassName, classState; + + classState = hasClass(node, className); + if (classState !== state) { + existingClassName = node.className; + + if (classState) { + node.className = trim((" " + existingClassName + " ").replace(' ' + className + ' ', ' ')); + } else { + node.className += existingClassName ? ' ' + className : className; + } + } + }); + } + + return self; + }, + + /** + * Returns true/false if the first item in set has the specified class. + * + * @method hasClass + * @param {String} className Class name to check for. + * @return {Boolean} True/false if the set has the specified class. + */ + hasClass: function(className) { + return hasClass(this[0], className); + }, + + /** + * Executes the callback function for each item DomQuery collection. If you return false in the + * callback it will break the loop. + * + * @method each + * @param {function} callback Callback function to execute for each item. + * @return {tinymce.dom.DomQuery} Current set. + */ + each: function(callback) { + return each(this, callback); + }, + + /** + * Binds an event with callback function to the elements in set. + * + * @method on + * @param {String} name Name of the event to bind. + * @param {function} callback Callback function to execute when the event occurs. + * @return {tinymce.dom.DomQuery} Current set. + */ + on: function(name, callback) { + return this.each(function() { + Event.bind(this, name, callback); + }); + }, + + /** + * Unbinds an event with callback function to the elements in set. + * + * @method off + * @param {String} name Optional name of the event to bind. + * @param {function} callback Optional callback function to execute when the event occurs. + * @return {tinymce.dom.DomQuery} Current set. + */ + off: function(name, callback) { + return this.each(function() { + Event.unbind(this, name, callback); + }); + }, + + /** + * Triggers the specified event by name or event object. + * + * @method trigger + * @param {String/Object} name Name of the event to trigger or event object. + * @return {tinymce.dom.DomQuery} Current set. + */ + trigger: function(name) { + return this.each(function() { + if (typeof name == 'object') { + Event.fire(this, name.type, name); + } else { + Event.fire(this, name); + } + }); + }, + + /** + * Shows all elements in set. + * + * @method show + * @return {tinymce.dom.DomQuery} Current set. + */ + show: function() { + return this.css('display', ''); + }, + + /** + * Hides all elements in set. + * + * @method hide + * @return {tinymce.dom.DomQuery} Current set. + */ + hide: function() { + return this.css('display', 'none'); + }, + + /** + * Slices the current set. + * + * @method slice + * @param {Number} start Start index to slice at. + * @param {Number} end Optional end index to end slice at. + * @return {tinymce.dom.DomQuery} Sliced set. + */ + slice: function() { + return new DomQuery(slice.apply(this, arguments)); + }, + + /** + * Makes the set equal to the specified index. + * + * @method eq + * @param {Number} index Index to set it equal to. + * @return {tinymce.dom.DomQuery} Single item set. + */ + eq: function(index) { + return index === -1 ? this.slice(index) : this.slice(index, +index + 1); + }, + + /** + * Makes the set equal to first element in set. + * + * @method first + * @return {tinymce.dom.DomQuery} Single item set. + */ + first: function() { + return this.eq(0); + }, + + /** + * Makes the set equal to last element in set. + * + * @method last + * @return {tinymce.dom.DomQuery} Single item set. + */ + last: function() { + return this.eq(-1); + }, + + /** + * Finds elements by the specified selector for each element in set. + * + * @method find + * @param {String} selector Selector to find elements by. + * @return {tinymce.dom.DomQuery} Set with matches elements. + */ + find: function(selector) { + var i, l, ret = []; + + for (i = 0, l = this.length; i < l; i++) { + DomQuery.find(selector, this[i], ret); + } + + return DomQuery(ret); + }, + + /** + * Filters the current set with the specified selector. + * + * @method filter + * @param {String/function} selector Selector to filter elements by. + * @return {tinymce.dom.DomQuery} Set with filtered elements. + */ + filter: function(selector) { + if (typeof selector == 'function') { + return DomQuery(grep(this.toArray(), function(item, i) { + return selector(i, item); + })); + } + + return DomQuery(DomQuery.filter(selector, this.toArray())); + }, + + /** + * Gets the current node or any parent matching the specified selector. + * + * @method closest + * @param {String/Element/tinymce.dom.DomQuery} selector Selector or element to find. + * @return {tinymce.dom.DomQuery} Set with closest elements. + */ + closest: function(selector) { + var result = []; + + if (selector instanceof DomQuery) { + selector = selector[0]; + } + + this.each(function(i, node) { + while (node) { + if (typeof selector == 'string' && DomQuery(node).is(selector)) { + result.push(node); + break; + } else if (node == selector) { + result.push(node); + break; + } + + node = node.parentNode; + } + }); + + return DomQuery(result); + }, + + /** + * Returns the offset of the first element in set or sets the top/left css properties of all elements in set. + * + * @method offset + * @param {Object} offset Optional offset object to set on each item. + * @return {Object/tinymce.dom.DomQuery} Returns the first element offset or the current set if you specified an offset. + */ + offset: function(offset) { + var elm, doc, docElm; + var x = 0, y = 0, pos; + + if (!offset) { + elm = this[0]; + + if (elm) { + doc = elm.ownerDocument; + docElm = doc.documentElement; + + if (elm.getBoundingClientRect) { + pos = elm.getBoundingClientRect(); + x = pos.left + (docElm.scrollLeft || doc.body.scrollLeft) - docElm.clientLeft; + y = pos.top + (docElm.scrollTop || doc.body.scrollTop) - docElm.clientTop; + } + } + + return { + left: x, + top: y + }; + } + + return this.css(offset); + }, + + push: push, + sort: [].sort, + splice: [].splice + }; + + // Static members + Tools.extend(DomQuery, { + /** + * Extends the specified object with one or more objects. + * + * @static + * @method extend + * @param {Object} target Target object to extend with new items. + * @param {Object..} object Object to extend the target with. + * @return {Object} Extended input object. + */ + extend: Tools.extend, + + /** + * Creates an array out of an array like object. + * + * @static + * @method makeArray + * @param {Object} object Object to convert to array. + * @return {Array} Array produced from object. + */ + makeArray: function(object) { + if (isWindow(object) || object.nodeType) { + return [object]; + } + + return Tools.toArray(object); + }, + + /** + * Returns the index of the specified item inside the array. + * + * @static + * @method inArray + * @param {Object} item Item to look for. + * @param {Array} array Array to look for item in. + * @return {Number} Index of the item or -1. + */ + inArray: inArray, + + /** + * Returns true/false if the specified object is an array or not. + * + * @static + * @method isArray + * @param {Object} array Object to check if it's an array or not. + * @return {Boolean} True/false if the object is an array. + */ + isArray: Tools.isArray, + + /** + * Executes the callback function for each item in array/object. If you return false in the + * callback it will break the loop. + * + * @static + * @method each + * @param {Object} obj Object to iterate. + * @param {function} callback Callback function to execute for each item. + */ + each: each, + + /** + * Removes whitespace from the beginning and end of a string. + * + * @static + * @method trim + * @param {String} str String to remove whitespace from. + * @return {String} New string with removed whitespace. + */ + trim: trim, + + /** + * Filters out items from the input array by calling the specified function for each item. + * If the function returns false the item will be excluded if it returns true it will be included. + * + * @static + * @method grep + * @param {Array} array Array of items to loop though. + * @param {function} callback Function to call for each item. Include/exclude depends on it's return value. + * @return {Array} New array with values imported and filtered based in input. + * @example + * // Filter out some items, this will return an array with 4 and 5 + * var items = DomQuery.grep([1, 2, 3, 4, 5], function(v) {return v > 3;}); + */ + grep: grep, + + // Sizzle + find: Sizzle, + expr: Sizzle.selectors, + unique: Sizzle.uniqueSort, + text: Sizzle.getText, + contains: Sizzle.contains, + filter: function(expr, elems, not) { + var i = elems.length; + + if (not) { + expr = ":not(" + expr + ")"; + } + + while (i--) { + if (elems[i].nodeType != 1) { + elems.splice(i, 1); + } + } + + if (elems.length === 1) { + elems = DomQuery.find.matchesSelector(elems[0], expr) ? [elems[0]] : []; + } else { + elems = DomQuery.find.matches(expr, elems); + } + + return elems; + } + }); + + function dir(el, prop, until) { + var matched = [], cur = el[prop]; + + if (typeof until != 'string' && until instanceof DomQuery) { + until = until[0]; + } + + while (cur && cur.nodeType !== 9) { + if (until !== undefined) { + if (cur === until) { + break; + } + + if (typeof until == 'string' && DomQuery(cur).is(until)) { + break; + } + } + + if (cur.nodeType === 1) { + matched.push(cur); + } + + cur = cur[prop]; + } + + return matched; + } + + function sibling(node, siblingName, nodeType, until) { + var result = []; + + if (until instanceof DomQuery) { + until = until[0]; + } + + for (; node; node = node[siblingName]) { + if (nodeType && node.nodeType !== nodeType) { + continue; + } + + if (until !== undefined) { + if (node === until) { + break; + } + + if (typeof until == 'string' && DomQuery(node).is(until)) { + break; + } + } + + result.push(node); + } + + return result; + } + + function firstSibling(node, siblingName, nodeType) { + for (node = node[siblingName]; node; node = node[siblingName]) { + if (node.nodeType == nodeType) { + return node; + } + } + + return null; + } + + each({ + /** + * Returns a new collection with the parent of each item in current collection matching the optional selector. + * + * @method parent + * @param {Element/tinymce.dom.DomQuery} node Node to match parents against. + * @return {tinymce.dom.DomQuery} New DomQuery instance with all matching parents. + */ + parent: function(node) { + var parent = node.parentNode; + + return parent && parent.nodeType !== 11 ? parent : null; + }, + + /** + * Returns a new collection with the all the parents of each item in current collection matching the optional selector. + * + * @method parents + * @param {Element/tinymce.dom.DomQuery} node Node to match parents against. + * @return {tinymce.dom.DomQuery} New DomQuery instance with all matching parents. + */ + parents: function(node) { + return dir(node, "parentNode"); + }, + + /** + * Returns a new collection with next sibling of each item in current collection matching the optional selector. + * + * @method next + * @param {Element/tinymce.dom.DomQuery} node Node to match the next element against. + * @return {tinymce.dom.DomQuery} New DomQuery instance with all matching elements. + */ + next: function(node) { + return firstSibling(node, 'nextSibling', 1); + }, + + /** + * Returns a new collection with previous sibling of each item in current collection matching the optional selector. + * + * @method prev + * @param {Element/tinymce.dom.DomQuery} node Node to match the previous element against. + * @return {tinymce.dom.DomQuery} New DomQuery instance with all matching elements. + */ + prev: function(node) { + return firstSibling(node, 'previousSibling', 1); + }, + + /** + * Returns all child elements matching the optional selector. + * + * @method children + * @param {Element/tinymce.dom.DomQuery} node Node to match the elements against. + * @return {tinymce.dom.DomQuery} New DomQuery instance with all matching elements. + */ + children: function(node) { + return sibling(node.firstChild, 'nextSibling', 1); + }, + + /** + * Returns all child nodes matching the optional selector. + * + * @method contents + * @param {Element/tinymce.dom.DomQuery} node Node to get the contents of. + * @return {tinymce.dom.DomQuery} New DomQuery instance with all matching elements. + */ + contents: function(node) { + return Tools.toArray((node.nodeName === "iframe" ? node.contentDocument || node.contentWindow.document : node).childNodes); + } + }, function(name, fn) { + DomQuery.fn[name] = function(selector) { + var self = this, result = []; + + self.each(function() { + var nodes = fn.call(result, this, selector, result); + + if (nodes) { + if (DomQuery.isArray(nodes)) { + result.push.apply(result, nodes); + } else { + result.push(nodes); + } + } + }); + + // If traversing on multiple elements we might get the same elements twice + if (this.length > 1) { + if (!skipUniques[name]) { + result = DomQuery.unique(result); + } + + if (name.indexOf('parents') === 0) { + result = result.reverse(); + } + } + + result = DomQuery(result); + + if (selector) { + return result.filter(selector); + } + + return result; + }; + }); + + each({ + /** + * Returns a new collection with the all the parents until the matching selector/element + * of each item in current collection matching the optional selector. + * + * @method parentsUntil + * @param {Element/tinymce.dom.DomQuery} node Node to find parent of. + * @param {String/Element/tinymce.dom.DomQuery} until Until the matching selector or element. + * @return {tinymce.dom.DomQuery} New DomQuery instance with all matching parents. + */ + parentsUntil: function(node, until) { + return dir(node, "parentNode", until); + }, + + /** + * Returns a new collection with all next siblings of each item in current collection matching the optional selector. + * + * @method nextUntil + * @param {Element/tinymce.dom.DomQuery} node Node to find next siblings on. + * @param {String/Element/tinymce.dom.DomQuery} until Until the matching selector or element. + * @return {tinymce.dom.DomQuery} New DomQuery instance with all matching elements. + */ + nextUntil: function(node, until) { + return sibling(node, 'nextSibling', 1, until).slice(1); + }, + + /** + * Returns a new collection with all previous siblings of each item in current collection matching the optional selector. + * + * @method prevUntil + * @param {Element/tinymce.dom.DomQuery} node Node to find previous siblings on. + * @param {String/Element/tinymce.dom.DomQuery} until Until the matching selector or element. + * @return {tinymce.dom.DomQuery} New DomQuery instance with all matching elements. + */ + prevUntil: function(node, until) { + return sibling(node, 'previousSibling', 1, until).slice(1); + } + }, function(name, fn) { + DomQuery.fn[name] = function(selector, filter) { + var self = this, result = []; + + self.each(function() { + var nodes = fn.call(result, this, selector, result); + + if (nodes) { + if (DomQuery.isArray(nodes)) { + result.push.apply(result, nodes); + } else { + result.push(nodes); + } + } + }); + + // If traversing on multiple elements we might get the same elements twice + if (this.length > 1) { + result = DomQuery.unique(result); + + if (name.indexOf('parents') === 0 || name === 'prevUntil') { + result = result.reverse(); + } + } + + result = DomQuery(result); + + if (filter) { + return result.filter(filter); + } + + return result; + }; + }); + + /** + * Returns true/false if the current set items matches the selector. + * + * @method is + * @param {String} selector Selector to match the elements against. + * @return {Boolean} True/false if the current set matches the selector. + */ + DomQuery.fn.is = function(selector) { + return !!selector && this.filter(selector).length > 0; + }; + + DomQuery.fn.init.prototype = DomQuery.fn; + + DomQuery.overrideDefaults = function(callback) { + var defaults; + + function sub(selector, context) { + defaults = defaults || callback(); + + if (arguments.length === 0) { + selector = defaults.element; + } + + if (!context) { + context = defaults.context; + } + + return new sub.fn.init(selector, context); + } + + DomQuery.extend(sub, this); + + return sub; + }; + + function appendHooks(targetHooks, prop, hooks) { + each(hooks, function(name, func) { + targetHooks[name] = targetHooks[name] || {}; + targetHooks[name][prop] = func; + }); + } + + if (Env.ie && Env.ie < 8) { + appendHooks(attrHooks, 'get', { + maxlength: function(elm) { + var value = elm.maxLength; + + if (value === 0x7fffffff) { + return undef; + } + + return value; + }, + + size: function(elm) { + var value = elm.size; + + if (value === 20) { + return undef; + } + + return value; + }, + + 'class': function(elm) { + return elm.className; + }, + + style: function(elm) { + var value = elm.style.cssText; + + if (value.length === 0) { + return undef; + } + + return value; + } + }); + + appendHooks(attrHooks, 'set', { + 'class': function(elm, value) { + elm.className = value; + }, + + style: function(elm, value) { + elm.style.cssText = value; + } + }); + } + + if (Env.ie && Env.ie < 9) { + /*jshint sub:true */ + /*eslint dot-notation: 0*/ + cssFix['float'] = 'styleFloat'; + + appendHooks(cssHooks, 'set', { + opacity: function(elm, value) { + var style = elm.style; + + if (value === null || value === '') { + style.removeAttribute('filter'); + } else { + style.zoom = 1; + style.filter = 'alpha(opacity=' + (value * 100) + ')'; + } + } + }); + } + + DomQuery.attrHooks = attrHooks; + DomQuery.cssHooks = cssHooks; + + return DomQuery; +}); + +// Included from: js/tinymce/classes/html/Styles.js + +/** + * Styles.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class is used to parse CSS styles it also compresses styles to reduce the output size. + * + * @example + * var Styles = new tinymce.html.Styles({ + * url_converter: function(url) { + * return url; + * } + * }); + * + * styles = Styles.parse('border: 1px solid red'); + * styles.color = 'red'; + * + * console.log(new tinymce.html.StyleSerializer().serialize(styles)); + * + * @class tinymce.html.Styles + * @version 3.4 + */ +define("tinymce/html/Styles", [], function() { + return function(settings, schema) { + /*jshint maxlen:255 */ + /*eslint max-len:0 */ + var rgbRegExp = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/gi, + urlOrStrRegExp = /(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi, + styleRegExp = /\s*([^:]+):\s*([^;]+);?/g, + trimRightRegExp = /\s+$/, + undef, i, encodingLookup = {}, encodingItems, validStyles, invalidStyles, invisibleChar = '\uFEFF'; + + settings = settings || {}; + + if (schema) { + validStyles = schema.getValidStyles(); + invalidStyles = schema.getInvalidStyles(); + } + + encodingItems = ('\\" \\\' \\; \\: ; : ' + invisibleChar).split(' '); + for (i = 0; i < encodingItems.length; i++) { + encodingLookup[encodingItems[i]] = invisibleChar + i; + encodingLookup[invisibleChar + i] = encodingItems[i]; + } + + function toHex(match, r, g, b) { + function hex(val) { + val = parseInt(val, 10).toString(16); + + return val.length > 1 ? val : '0' + val; // 0 -> 00 + } + + return '#' + hex(r) + hex(g) + hex(b); + } + + return { + /** + * Parses the specified RGB color value and returns a hex version of that color. + * + * @method toHex + * @param {String} color RGB string value like rgb(1,2,3) + * @return {String} Hex version of that RGB value like #FF00FF. + */ + toHex: function(color) { + return color.replace(rgbRegExp, toHex); + }, + + /** + * Parses the specified style value into an object collection. This parser will also + * merge and remove any redundant items that browsers might have added. It will also convert non hex + * colors to hex values. Urls inside the styles will also be converted to absolute/relative based on settings. + * + * @method parse + * @param {String} css Style value to parse for example: border:1px solid red;. + * @return {Object} Object representation of that style like {border: '1px solid red'} + */ + parse: function(css) { + var styles = {}, matches, name, value, isEncoded, urlConverter = settings.url_converter; + var urlConverterScope = settings.url_converter_scope || this; + + function compress(prefix, suffix, noJoin) { + var top, right, bottom, left; + + top = styles[prefix + '-top' + suffix]; + if (!top) { + return; + } + + right = styles[prefix + '-right' + suffix]; + if (!right) { + return; + } + + bottom = styles[prefix + '-bottom' + suffix]; + if (!bottom) { + return; + } + + left = styles[prefix + '-left' + suffix]; + if (!left) { + return; + } + + var box = [top, right, bottom, left]; + i = box.length - 1; + while (i--) { + if (box[i] !== box[i + 1]) { + break; + } + } + + if (i > -1 && noJoin) { + return; + } + + styles[prefix + suffix] = i == -1 ? box[0] : box.join(' '); + delete styles[prefix + '-top' + suffix]; + delete styles[prefix + '-right' + suffix]; + delete styles[prefix + '-bottom' + suffix]; + delete styles[prefix + '-left' + suffix]; + } + + /** + * Checks if the specific style can be compressed in other words if all border-width are equal. + */ + function canCompress(key) { + var value = styles[key], i; + + if (!value) { + return; + } + + value = value.split(' '); + i = value.length; + while (i--) { + if (value[i] !== value[0]) { + return false; + } + } + + styles[key] = value[0]; + + return true; + } + + /** + * Compresses multiple styles into one style. + */ + function compress2(target, a, b, c) { + if (!canCompress(a)) { + return; + } + + if (!canCompress(b)) { + return; + } + + if (!canCompress(c)) { + return; + } + + // Compress + styles[target] = styles[a] + ' ' + styles[b] + ' ' + styles[c]; + delete styles[a]; + delete styles[b]; + delete styles[c]; + } + + // Encodes the specified string by replacing all \" \' ; : with _<num> + function encode(str) { + isEncoded = true; + + return encodingLookup[str]; + } + + // Decodes the specified string by replacing all _<num> with it's original value \" \' etc + // It will also decode the \" \' if keep_slashes is set to fale or omitted + function decode(str, keep_slashes) { + if (isEncoded) { + str = str.replace(/\uFEFF[0-9]/g, function(str) { + return encodingLookup[str]; + }); + } + + if (!keep_slashes) { + str = str.replace(/\\([\'\";:])/g, "$1"); + } + + return str; + } + + function processUrl(match, url, url2, url3, str, str2) { + str = str || str2; + + if (str) { + str = decode(str); + + // Force strings into single quote format + return "'" + str.replace(/\'/g, "\\'") + "'"; + } + + url = decode(url || url2 || url3); + + if (!settings.allow_script_urls) { + var scriptUrl = url.replace(/[\s\r\n]+/, ''); + + if (/(java|vb)script:/i.test(scriptUrl)) { + return ""; + } + + if (!settings.allow_svg_data_urls && /^data:image\/svg/i.test(scriptUrl)) { + return ""; + } + } + + // Convert the URL to relative/absolute depending on config + if (urlConverter) { + url = urlConverter.call(urlConverterScope, url, 'style'); + } + + // Output new URL format + return "url('" + url.replace(/\'/g, "\\'") + "')"; + } + + if (css) { + css = css.replace(/[\u0000-\u001F]/g, ''); + + // Encode \" \' % and ; and : inside strings so they don't interfere with the style parsing + css = css.replace(/\\[\"\';:\uFEFF]/g, encode).replace(/\"[^\"]+\"|\'[^\']+\'/g, function(str) { + return str.replace(/[;:]/g, encode); + }); + + // Parse styles + while ((matches = styleRegExp.exec(css))) { + name = matches[1].replace(trimRightRegExp, '').toLowerCase(); + value = matches[2].replace(trimRightRegExp, ''); + + // Decode escaped sequences like \65 -> e + /*jshint loopfunc:true*/ + /*eslint no-loop-func:0 */ + value = value.replace(/\\[0-9a-f]+/g, function(e) { + return String.fromCharCode(parseInt(e.substr(1), 16)); + }); + + if (name && value.length > 0) { + // Don't allow behavior name or expression/comments within the values + if (!settings.allow_script_urls && (name == "behavior" || /expression\s*\(|\/\*|\*\//.test(value))) { + continue; + } + + // Opera will produce 700 instead of bold in their style values + if (name === 'font-weight' && value === '700') { + value = 'bold'; + } else if (name === 'color' || name === 'background-color') { // Lowercase colors like RED + value = value.toLowerCase(); + } + + // Convert RGB colors to HEX + value = value.replace(rgbRegExp, toHex); + + // Convert URLs and force them into url('value') format + value = value.replace(urlOrStrRegExp, processUrl); + styles[name] = isEncoded ? decode(value, true) : value; + } + + styleRegExp.lastIndex = matches.index + matches[0].length; + } + // Compress the styles to reduce it's size for example IE will expand styles + compress("border", "", true); + compress("border", "-width"); + compress("border", "-color"); + compress("border", "-style"); + compress("padding", ""); + compress("margin", ""); + compress2('border', 'border-width', 'border-style', 'border-color'); + + // Remove pointless border, IE produces these + if (styles.border === 'medium none') { + delete styles.border; + } + + // IE 11 will produce a border-image: none when getting the style attribute from <p style="border: 1px solid red"></p> + // So let us assume it shouldn't be there + if (styles['border-image'] === 'none') { + delete styles['border-image']; + } + } + + return styles; + }, + + /** + * Serializes the specified style object into a string. + * + * @method serialize + * @param {Object} styles Object to serialize as string for example: {border: '1px solid red'} + * @param {String} elementName Optional element name, if specified only the styles that matches the schema will be serialized. + * @return {String} String representation of the style object for example: border: 1px solid red. + */ + serialize: function(styles, elementName) { + var css = '', name, value; + + function serializeStyles(name) { + var styleList, i, l, value; + + styleList = validStyles[name]; + if (styleList) { + for (i = 0, l = styleList.length; i < l; i++) { + name = styleList[i]; + value = styles[name]; + + if (value !== undef && value.length > 0) { + css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';'; + } + } + } + } + + function isValid(name, elementName) { + var styleMap; + + styleMap = invalidStyles['*']; + if (styleMap && styleMap[name]) { + return false; + } + + styleMap = invalidStyles[elementName]; + if (styleMap && styleMap[name]) { + return false; + } + + return true; + } + + // Serialize styles according to schema + if (elementName && validStyles) { + // Serialize global styles and element specific styles + serializeStyles('*'); + serializeStyles(elementName); + } else { + // Output the styles in the order they are inside the object + for (name in styles) { + value = styles[name]; + + if (value !== undef && value.length > 0) { + if (!invalidStyles || isValid(name, elementName)) { + css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';'; + } + } + } + } + + return css; + } + }; + }; +}); + +// Included from: js/tinymce/classes/dom/TreeWalker.js + +/** + * TreeWalker.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * TreeWalker class enables you to walk the DOM in a linear manner. + * + * @class tinymce.dom.TreeWalker + * @example + * var walker = new tinymce.dom.TreeWalker(startNode); + * + * do { + * console.log(walker.current()); + * } while (walker.next()); + */ +define("tinymce/dom/TreeWalker", [], function() { + /** + * Constructs a new TreeWalker instance. + * + * @constructor + * @method TreeWalker + * @param {Node} startNode Node to start walking from. + * @param {node} rootNode Optional root node to never walk out of. + */ + return function(startNode, rootNode) { + var node = startNode; + + function findSibling(node, startName, siblingName, shallow) { + var sibling, parent; + + if (node) { + // Walk into nodes if it has a start + if (!shallow && node[startName]) { + return node[startName]; + } + + // Return the sibling if it has one + if (node != rootNode) { + sibling = node[siblingName]; + if (sibling) { + return sibling; + } + + // Walk up the parents to look for siblings + for (parent = node.parentNode; parent && parent != rootNode; parent = parent.parentNode) { + sibling = parent[siblingName]; + if (sibling) { + return sibling; + } + } + } + } + } + + function findPreviousNode(node, startName, siblingName, shallow) { + var sibling, parent, child; + + if (node) { + sibling = node[siblingName]; + if (rootNode && sibling === rootNode) { + return; + } + + if (sibling) { + if (!shallow) { + // Walk up the parents to look for siblings + for (child = sibling[startName]; child; child = child[startName]) { + if (!child[startName]) { + return child; + } + } + } + + return sibling; + } + + parent = node.parentNode; + if (parent && parent !== rootNode) { + return parent; + } + } + } + + /** + * Returns the current node. + * + * @method current + * @return {Node} Current node where the walker is. + */ + this.current = function() { + return node; + }; + + /** + * Walks to the next node in tree. + * + * @method next + * @return {Node} Current node where the walker is after moving to the next node. + */ + this.next = function(shallow) { + node = findSibling(node, 'firstChild', 'nextSibling', shallow); + return node; + }; + + /** + * Walks to the previous node in tree. + * + * @method prev + * @return {Node} Current node where the walker is after moving to the previous node. + */ + this.prev = function(shallow) { + node = findSibling(node, 'lastChild', 'previousSibling', shallow); + return node; + }; + + this.prev2 = function(shallow) { + node = findPreviousNode(node, 'lastChild', 'previousSibling', shallow); + return node; + }; + }; +}); + +// Included from: js/tinymce/classes/dom/Range.js + +/** + * Range.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Old IE Range. + * + * @private + * @class tinymce.dom.Range + */ +define("tinymce/dom/Range", [ + "tinymce/util/Tools" +], function(Tools) { + // Range constructor + function Range(dom) { + var self = this, + doc = dom.doc, + EXTRACT = 0, + CLONE = 1, + DELETE = 2, + TRUE = true, + FALSE = false, + START_OFFSET = 'startOffset', + START_CONTAINER = 'startContainer', + END_CONTAINER = 'endContainer', + END_OFFSET = 'endOffset', + extend = Tools.extend, + nodeIndex = dom.nodeIndex; + + function createDocumentFragment() { + return doc.createDocumentFragment(); + } + + function setStart(n, o) { + _setEndPoint(TRUE, n, o); + } + + function setEnd(n, o) { + _setEndPoint(FALSE, n, o); + } + + function setStartBefore(n) { + setStart(n.parentNode, nodeIndex(n)); + } + + function setStartAfter(n) { + setStart(n.parentNode, nodeIndex(n) + 1); + } + + function setEndBefore(n) { + setEnd(n.parentNode, nodeIndex(n)); + } + + function setEndAfter(n) { + setEnd(n.parentNode, nodeIndex(n) + 1); + } + + function collapse(ts) { + if (ts) { + self[END_CONTAINER] = self[START_CONTAINER]; + self[END_OFFSET] = self[START_OFFSET]; + } else { + self[START_CONTAINER] = self[END_CONTAINER]; + self[START_OFFSET] = self[END_OFFSET]; + } + + self.collapsed = TRUE; + } + + function selectNode(n) { + setStartBefore(n); + setEndAfter(n); + } + + function selectNodeContents(n) { + setStart(n, 0); + setEnd(n, n.nodeType === 1 ? n.childNodes.length : n.nodeValue.length); + } + + function compareBoundaryPoints(h, r) { + var sc = self[START_CONTAINER], so = self[START_OFFSET], ec = self[END_CONTAINER], eo = self[END_OFFSET], + rsc = r.startContainer, rso = r.startOffset, rec = r.endContainer, reo = r.endOffset; + + // Check START_TO_START + if (h === 0) { + return _compareBoundaryPoints(sc, so, rsc, rso); + } + + // Check START_TO_END + if (h === 1) { + return _compareBoundaryPoints(ec, eo, rsc, rso); + } + + // Check END_TO_END + if (h === 2) { + return _compareBoundaryPoints(ec, eo, rec, reo); + } + + // Check END_TO_START + if (h === 3) { + return _compareBoundaryPoints(sc, so, rec, reo); + } + } + + function deleteContents() { + _traverse(DELETE); + } + + function extractContents() { + return _traverse(EXTRACT); + } + + function cloneContents() { + return _traverse(CLONE); + } + + function insertNode(n) { + var startContainer = this[START_CONTAINER], + startOffset = this[START_OFFSET], nn, o; + + // Node is TEXT_NODE or CDATA + if ((startContainer.nodeType === 3 || startContainer.nodeType === 4) && startContainer.nodeValue) { + if (!startOffset) { + // At the start of text + startContainer.parentNode.insertBefore(n, startContainer); + } else if (startOffset >= startContainer.nodeValue.length) { + // At the end of text + dom.insertAfter(n, startContainer); + } else { + // Middle, need to split + nn = startContainer.splitText(startOffset); + startContainer.parentNode.insertBefore(n, nn); + } + } else { + // Insert element node + if (startContainer.childNodes.length > 0) { + o = startContainer.childNodes[startOffset]; + } + + if (o) { + startContainer.insertBefore(n, o); + } else { + if (startContainer.nodeType == 3) { + dom.insertAfter(n, startContainer); + } else { + startContainer.appendChild(n); + } + } + } + } + + function surroundContents(n) { + var f = self.extractContents(); + + self.insertNode(n); + n.appendChild(f); + self.selectNode(n); + } + + function cloneRange() { + return extend(new Range(dom), { + startContainer: self[START_CONTAINER], + startOffset: self[START_OFFSET], + endContainer: self[END_CONTAINER], + endOffset: self[END_OFFSET], + collapsed: self.collapsed, + commonAncestorContainer: self.commonAncestorContainer + }); + } + + // Private methods + + function _getSelectedNode(container, offset) { + var child; + + // TEXT_NODE + if (container.nodeType == 3) { + return container; + } + + if (offset < 0) { + return container; + } + + child = container.firstChild; + while (child && offset > 0) { + --offset; + child = child.nextSibling; + } + + if (child) { + return child; + } + + return container; + } + + function _isCollapsed() { + return (self[START_CONTAINER] == self[END_CONTAINER] && self[START_OFFSET] == self[END_OFFSET]); + } + + function _compareBoundaryPoints(containerA, offsetA, containerB, offsetB) { + var c, offsetC, n, cmnRoot, childA, childB; + + // In the first case the boundary-points have the same container. A is before B + // if its offset is less than the offset of B, A is equal to B if its offset is + // equal to the offset of B, and A is after B if its offset is greater than the + // offset of B. + if (containerA == containerB) { + if (offsetA == offsetB) { + return 0; // equal + } + + if (offsetA < offsetB) { + return -1; // before + } + + return 1; // after + } + + // In the second case a child node C of the container of A is an ancestor + // container of B. In this case, A is before B if the offset of A is less than or + // equal to the index of the child node C and A is after B otherwise. + c = containerB; + while (c && c.parentNode != containerA) { + c = c.parentNode; + } + + if (c) { + offsetC = 0; + n = containerA.firstChild; + + while (n != c && offsetC < offsetA) { + offsetC++; + n = n.nextSibling; + } + + if (offsetA <= offsetC) { + return -1; // before + } + + return 1; // after + } + + // In the third case a child node C of the container of B is an ancestor container + // of A. In this case, A is before B if the index of the child node C is less than + // the offset of B and A is after B otherwise. + c = containerA; + while (c && c.parentNode != containerB) { + c = c.parentNode; + } + + if (c) { + offsetC = 0; + n = containerB.firstChild; + + while (n != c && offsetC < offsetB) { + offsetC++; + n = n.nextSibling; + } + + if (offsetC < offsetB) { + return -1; // before + } + + return 1; // after + } + + // In the fourth case, none of three other cases hold: the containers of A and B + // are siblings or descendants of sibling nodes. In this case, A is before B if + // the container of A is before the container of B in a pre-order traversal of the + // Ranges' context tree and A is after B otherwise. + cmnRoot = dom.findCommonAncestor(containerA, containerB); + childA = containerA; + + while (childA && childA.parentNode != cmnRoot) { + childA = childA.parentNode; + } + + if (!childA) { + childA = cmnRoot; + } + + childB = containerB; + while (childB && childB.parentNode != cmnRoot) { + childB = childB.parentNode; + } + + if (!childB) { + childB = cmnRoot; + } + + if (childA == childB) { + return 0; // equal + } + + n = cmnRoot.firstChild; + while (n) { + if (n == childA) { + return -1; // before + } + + if (n == childB) { + return 1; // after + } + + n = n.nextSibling; + } + } + + function _setEndPoint(st, n, o) { + var ec, sc; + + if (st) { + self[START_CONTAINER] = n; + self[START_OFFSET] = o; + } else { + self[END_CONTAINER] = n; + self[END_OFFSET] = o; + } + + // If one boundary-point of a Range is set to have a root container + // other than the current one for the Range, the Range is collapsed to + // the new position. This enforces the restriction that both boundary- + // points of a Range must have the same root container. + ec = self[END_CONTAINER]; + while (ec.parentNode) { + ec = ec.parentNode; + } + + sc = self[START_CONTAINER]; + while (sc.parentNode) { + sc = sc.parentNode; + } + + if (sc == ec) { + // The start position of a Range is guaranteed to never be after the + // end position. To enforce this restriction, if the start is set to + // be at a position after the end, the Range is collapsed to that + // position. + if (_compareBoundaryPoints(self[START_CONTAINER], self[START_OFFSET], self[END_CONTAINER], self[END_OFFSET]) > 0) { + self.collapse(st); + } + } else { + self.collapse(st); + } + + self.collapsed = _isCollapsed(); + self.commonAncestorContainer = dom.findCommonAncestor(self[START_CONTAINER], self[END_CONTAINER]); + } + + function _traverse(how) { + var c, endContainerDepth = 0, startContainerDepth = 0, p, depthDiff, startNode, endNode, sp, ep; + + if (self[START_CONTAINER] == self[END_CONTAINER]) { + return _traverseSameContainer(how); + } + + for (c = self[END_CONTAINER], p = c.parentNode; p; c = p, p = p.parentNode) { + if (p == self[START_CONTAINER]) { + return _traverseCommonStartContainer(c, how); + } + + ++endContainerDepth; + } + + for (c = self[START_CONTAINER], p = c.parentNode; p; c = p, p = p.parentNode) { + if (p == self[END_CONTAINER]) { + return _traverseCommonEndContainer(c, how); + } + + ++startContainerDepth; + } + + depthDiff = startContainerDepth - endContainerDepth; + + startNode = self[START_CONTAINER]; + while (depthDiff > 0) { + startNode = startNode.parentNode; + depthDiff--; + } + + endNode = self[END_CONTAINER]; + while (depthDiff < 0) { + endNode = endNode.parentNode; + depthDiff++; + } + + // ascend the ancestor hierarchy until we have a common parent. + for (sp = startNode.parentNode, ep = endNode.parentNode; sp != ep; sp = sp.parentNode, ep = ep.parentNode) { + startNode = sp; + endNode = ep; + } + + return _traverseCommonAncestors(startNode, endNode, how); + } + + function _traverseSameContainer(how) { + var frag, s, sub, n, cnt, sibling, xferNode, start, len; + + if (how != DELETE) { + frag = createDocumentFragment(); + } + + // If selection is empty, just return the fragment + if (self[START_OFFSET] == self[END_OFFSET]) { + return frag; + } + + // Text node needs special case handling + if (self[START_CONTAINER].nodeType == 3) { // TEXT_NODE + // get the substring + s = self[START_CONTAINER].nodeValue; + sub = s.substring(self[START_OFFSET], self[END_OFFSET]); + + // set the original text node to its new value + if (how != CLONE) { + n = self[START_CONTAINER]; + start = self[START_OFFSET]; + len = self[END_OFFSET] - self[START_OFFSET]; + + if (start === 0 && len >= n.nodeValue.length - 1) { + n.parentNode.removeChild(n); + } else { + n.deleteData(start, len); + } + + // Nothing is partially selected, so collapse to start point + self.collapse(TRUE); + } + + if (how == DELETE) { + return; + } + + if (sub.length > 0) { + frag.appendChild(doc.createTextNode(sub)); + } + + return frag; + } + + // Copy nodes between the start/end offsets. + n = _getSelectedNode(self[START_CONTAINER], self[START_OFFSET]); + cnt = self[END_OFFSET] - self[START_OFFSET]; + + while (n && cnt > 0) { + sibling = n.nextSibling; + xferNode = _traverseFullySelected(n, how); + + if (frag) { + frag.appendChild(xferNode); + } + + --cnt; + n = sibling; + } + + // Nothing is partially selected, so collapse to start point + if (how != CLONE) { + self.collapse(TRUE); + } + + return frag; + } + + function _traverseCommonStartContainer(endAncestor, how) { + var frag, n, endIdx, cnt, sibling, xferNode; + + if (how != DELETE) { + frag = createDocumentFragment(); + } + + n = _traverseRightBoundary(endAncestor, how); + + if (frag) { + frag.appendChild(n); + } + + endIdx = nodeIndex(endAncestor); + cnt = endIdx - self[START_OFFSET]; + + if (cnt <= 0) { + // Collapse to just before the endAncestor, which + // is partially selected. + if (how != CLONE) { + self.setEndBefore(endAncestor); + self.collapse(FALSE); + } + + return frag; + } + + n = endAncestor.previousSibling; + while (cnt > 0) { + sibling = n.previousSibling; + xferNode = _traverseFullySelected(n, how); + + if (frag) { + frag.insertBefore(xferNode, frag.firstChild); + } + + --cnt; + n = sibling; + } + + // Collapse to just before the endAncestor, which + // is partially selected. + if (how != CLONE) { + self.setEndBefore(endAncestor); + self.collapse(FALSE); + } + + return frag; + } + + function _traverseCommonEndContainer(startAncestor, how) { + var frag, startIdx, n, cnt, sibling, xferNode; + + if (how != DELETE) { + frag = createDocumentFragment(); + } + + n = _traverseLeftBoundary(startAncestor, how); + if (frag) { + frag.appendChild(n); + } + + startIdx = nodeIndex(startAncestor); + ++startIdx; // Because we already traversed it + + cnt = self[END_OFFSET] - startIdx; + n = startAncestor.nextSibling; + while (n && cnt > 0) { + sibling = n.nextSibling; + xferNode = _traverseFullySelected(n, how); + + if (frag) { + frag.appendChild(xferNode); + } + + --cnt; + n = sibling; + } + + if (how != CLONE) { + self.setStartAfter(startAncestor); + self.collapse(TRUE); + } + + return frag; + } + + function _traverseCommonAncestors(startAncestor, endAncestor, how) { + var n, frag, startOffset, endOffset, cnt, sibling, nextSibling; + + if (how != DELETE) { + frag = createDocumentFragment(); + } + + n = _traverseLeftBoundary(startAncestor, how); + if (frag) { + frag.appendChild(n); + } + + startOffset = nodeIndex(startAncestor); + endOffset = nodeIndex(endAncestor); + ++startOffset; + + cnt = endOffset - startOffset; + sibling = startAncestor.nextSibling; + + while (cnt > 0) { + nextSibling = sibling.nextSibling; + n = _traverseFullySelected(sibling, how); + + if (frag) { + frag.appendChild(n); + } + + sibling = nextSibling; + --cnt; + } + + n = _traverseRightBoundary(endAncestor, how); + + if (frag) { + frag.appendChild(n); + } + + if (how != CLONE) { + self.setStartAfter(startAncestor); + self.collapse(TRUE); + } + + return frag; + } + + function _traverseRightBoundary(root, how) { + var next = _getSelectedNode(self[END_CONTAINER], self[END_OFFSET] - 1), parent, clonedParent; + var prevSibling, clonedChild, clonedGrandParent, isFullySelected = next != self[END_CONTAINER]; + + if (next == root) { + return _traverseNode(next, isFullySelected, FALSE, how); + } + + parent = next.parentNode; + clonedParent = _traverseNode(parent, FALSE, FALSE, how); + + while (parent) { + while (next) { + prevSibling = next.previousSibling; + clonedChild = _traverseNode(next, isFullySelected, FALSE, how); + + if (how != DELETE) { + clonedParent.insertBefore(clonedChild, clonedParent.firstChild); + } + + isFullySelected = TRUE; + next = prevSibling; + } + + if (parent == root) { + return clonedParent; + } + + next = parent.previousSibling; + parent = parent.parentNode; + + clonedGrandParent = _traverseNode(parent, FALSE, FALSE, how); + + if (how != DELETE) { + clonedGrandParent.appendChild(clonedParent); + } + + clonedParent = clonedGrandParent; + } + } + + function _traverseLeftBoundary(root, how) { + var next = _getSelectedNode(self[START_CONTAINER], self[START_OFFSET]), isFullySelected = next != self[START_CONTAINER]; + var parent, clonedParent, nextSibling, clonedChild, clonedGrandParent; + + if (next == root) { + return _traverseNode(next, isFullySelected, TRUE, how); + } + + parent = next.parentNode; + clonedParent = _traverseNode(parent, FALSE, TRUE, how); + + while (parent) { + while (next) { + nextSibling = next.nextSibling; + clonedChild = _traverseNode(next, isFullySelected, TRUE, how); + + if (how != DELETE) { + clonedParent.appendChild(clonedChild); + } + + isFullySelected = TRUE; + next = nextSibling; + } + + if (parent == root) { + return clonedParent; + } + + next = parent.nextSibling; + parent = parent.parentNode; + + clonedGrandParent = _traverseNode(parent, FALSE, TRUE, how); + + if (how != DELETE) { + clonedGrandParent.appendChild(clonedParent); + } + + clonedParent = clonedGrandParent; + } + } + + function _traverseNode(n, isFullySelected, isLeft, how) { + var txtValue, newNodeValue, oldNodeValue, offset, newNode; + + if (isFullySelected) { + return _traverseFullySelected(n, how); + } + + // TEXT_NODE + if (n.nodeType == 3) { + txtValue = n.nodeValue; + + if (isLeft) { + offset = self[START_OFFSET]; + newNodeValue = txtValue.substring(offset); + oldNodeValue = txtValue.substring(0, offset); + } else { + offset = self[END_OFFSET]; + newNodeValue = txtValue.substring(0, offset); + oldNodeValue = txtValue.substring(offset); + } + + if (how != CLONE) { + n.nodeValue = oldNodeValue; + } + + if (how == DELETE) { + return; + } + + newNode = dom.clone(n, FALSE); + newNode.nodeValue = newNodeValue; + + return newNode; + } + + if (how == DELETE) { + return; + } + + return dom.clone(n, FALSE); + } + + function _traverseFullySelected(n, how) { + if (how != DELETE) { + return how == CLONE ? dom.clone(n, TRUE) : n; + } + + n.parentNode.removeChild(n); + } + + function toStringIE() { + return dom.create('body', null, cloneContents()).outerText; + } + + extend(self, { + // Initial states + startContainer: doc, + startOffset: 0, + endContainer: doc, + endOffset: 0, + collapsed: TRUE, + commonAncestorContainer: doc, + + // Range constants + START_TO_START: 0, + START_TO_END: 1, + END_TO_END: 2, + END_TO_START: 3, + + // Public methods + setStart: setStart, + setEnd: setEnd, + setStartBefore: setStartBefore, + setStartAfter: setStartAfter, + setEndBefore: setEndBefore, + setEndAfter: setEndAfter, + collapse: collapse, + selectNode: selectNode, + selectNodeContents: selectNodeContents, + compareBoundaryPoints: compareBoundaryPoints, + deleteContents: deleteContents, + extractContents: extractContents, + cloneContents: cloneContents, + insertNode: insertNode, + surroundContents: surroundContents, + cloneRange: cloneRange, + toStringIE: toStringIE + }); + + return self; + } + + // Older IE versions doesn't let you override toString by it's constructor so we have to stick it in the prototype + Range.prototype.toString = function() { + return this.toStringIE(); + }; + + return Range; +}); + +// Included from: js/tinymce/classes/html/Entities.js + +/** + * Entities.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/*jshint bitwise:false */ +/*eslint no-bitwise:0 */ + +/** + * Entity encoder class. + * + * @class tinymce.html.Entities + * @static + * @version 3.4 + */ +define("tinymce/html/Entities", [ + "tinymce/util/Tools" +], function(Tools) { + var makeMap = Tools.makeMap; + + var namedEntities, baseEntities, reverseEntities, + attrsCharsRegExp = /[&<>\"\u0060\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, + textCharsRegExp = /[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, + rawCharsRegExp = /[<>&\"\']/g, + entityRegExp = /&#([a-z0-9]+);?|&([a-z0-9]+);/gi, + asciiMap = { + 128: "\u20AC", 130: "\u201A", 131: "\u0192", 132: "\u201E", 133: "\u2026", 134: "\u2020", + 135: "\u2021", 136: "\u02C6", 137: "\u2030", 138: "\u0160", 139: "\u2039", 140: "\u0152", + 142: "\u017D", 145: "\u2018", 146: "\u2019", 147: "\u201C", 148: "\u201D", 149: "\u2022", + 150: "\u2013", 151: "\u2014", 152: "\u02DC", 153: "\u2122", 154: "\u0161", 155: "\u203A", + 156: "\u0153", 158: "\u017E", 159: "\u0178" + }; + + // Raw entities + baseEntities = { + '\"': '"', // Needs to be escaped since the YUI compressor would otherwise break the code + "'": ''', + '<': '<', + '>': '>', + '&': '&', + '\u0060': '`' + }; + + // Reverse lookup table for raw entities + reverseEntities = { + '<': '<', + '>': '>', + '&': '&', + '"': '"', + ''': "'" + }; + + // Decodes text by using the browser + function nativeDecode(text) { + var elm; + + elm = document.createElement("div"); + elm.innerHTML = text; + + return elm.textContent || elm.innerText || text; + } + + // Build a two way lookup table for the entities + function buildEntitiesLookup(items, radix) { + var i, chr, entity, lookup = {}; + + if (items) { + items = items.split(','); + radix = radix || 10; + + // Build entities lookup table + for (i = 0; i < items.length; i += 2) { + chr = String.fromCharCode(parseInt(items[i], radix)); + + // Only add non base entities + if (!baseEntities[chr]) { + entity = '&' + items[i + 1] + ';'; + lookup[chr] = entity; + lookup[entity] = chr; + } + } + + return lookup; + } + } + + // Unpack entities lookup where the numbers are in radix 32 to reduce the size + namedEntities = buildEntitiesLookup( + '50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,' + + '5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,' + + '5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,' + + '5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,' + + '68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,' + + '6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,' + + '6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,' + + '75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,' + + '7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,' + + '7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,' + + 'sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,' + + 'st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,' + + 't9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,' + + 'tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,' + + 'u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,' + + '81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,' + + '8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,' + + '8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,' + + '8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,' + + '8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,' + + 'nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,' + + 'rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,' + + 'Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,' + + '80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,' + + '811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro', 32); + + var Entities = { + /** + * Encodes the specified string using raw entities. This means only the required XML base entities will be encoded. + * + * @method encodeRaw + * @param {String} text Text to encode. + * @param {Boolean} attr Optional flag to specify if the text is attribute contents. + * @return {String} Entity encoded text. + */ + encodeRaw: function(text, attr) { + return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function(chr) { + return baseEntities[chr] || chr; + }); + }, + + /** + * Encoded the specified text with both the attributes and text entities. This function will produce larger text contents + * since it doesn't know if the context is within a attribute or text node. This was added for compatibility + * and is exposed as the DOMUtils.encode function. + * + * @method encodeAllRaw + * @param {String} text Text to encode. + * @return {String} Entity encoded text. + */ + encodeAllRaw: function(text) { + return ('' + text).replace(rawCharsRegExp, function(chr) { + return baseEntities[chr] || chr; + }); + }, + + /** + * Encodes the specified string using numeric entities. The core entities will be + * encoded as named ones but all non lower ascii characters will be encoded into numeric entities. + * + * @method encodeNumeric + * @param {String} text Text to encode. + * @param {Boolean} attr Optional flag to specify if the text is attribute contents. + * @return {String} Entity encoded text. + */ + encodeNumeric: function(text, attr) { + return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function(chr) { + // Multi byte sequence convert it to a single entity + if (chr.length > 1) { + return '&#' + (((chr.charCodeAt(0) - 0xD800) * 0x400) + (chr.charCodeAt(1) - 0xDC00) + 0x10000) + ';'; + } + + return baseEntities[chr] || '&#' + chr.charCodeAt(0) + ';'; + }); + }, + + /** + * Encodes the specified string using named entities. The core entities will be encoded + * as named ones but all non lower ascii characters will be encoded into named entities. + * + * @method encodeNamed + * @param {String} text Text to encode. + * @param {Boolean} attr Optional flag to specify if the text is attribute contents. + * @param {Object} entities Optional parameter with entities to use. + * @return {String} Entity encoded text. + */ + encodeNamed: function(text, attr, entities) { + entities = entities || namedEntities; + + return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function(chr) { + return baseEntities[chr] || entities[chr] || chr; + }); + }, + + /** + * Returns an encode function based on the name(s) and it's optional entities. + * + * @method getEncodeFunc + * @param {String} name Comma separated list of encoders for example named,numeric. + * @param {String} entities Optional parameter with entities to use instead of the built in set. + * @return {function} Encode function to be used. + */ + getEncodeFunc: function(name, entities) { + entities = buildEntitiesLookup(entities) || namedEntities; + + function encodeNamedAndNumeric(text, attr) { + return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function(chr) { + return baseEntities[chr] || entities[chr] || '&#' + chr.charCodeAt(0) + ';' || chr; + }); + } + + function encodeCustomNamed(text, attr) { + return Entities.encodeNamed(text, attr, entities); + } + + // Replace + with , to be compatible with previous TinyMCE versions + name = makeMap(name.replace(/\+/g, ',')); + + // Named and numeric encoder + if (name.named && name.numeric) { + return encodeNamedAndNumeric; + } + + // Named encoder + if (name.named) { + // Custom names + if (entities) { + return encodeCustomNamed; + } + + return Entities.encodeNamed; + } + + // Numeric + if (name.numeric) { + return Entities.encodeNumeric; + } + + // Raw encoder + return Entities.encodeRaw; + }, + + /** + * Decodes the specified string, this will replace entities with raw UTF characters. + * + * @method decode + * @param {String} text Text to entity decode. + * @return {String} Entity decoded string. + */ + decode: function(text) { + return text.replace(entityRegExp, function(all, numeric) { + if (numeric) { + if (numeric.charAt(0).toLowerCase() === 'x') { + numeric = parseInt(numeric.substr(1), 16); + } else { + numeric = parseInt(numeric, 10); + } + + // Support upper UTF + if (numeric > 0xFFFF) { + numeric -= 0x10000; + + return String.fromCharCode(0xD800 + (numeric >> 10), 0xDC00 + (numeric & 0x3FF)); + } + + return asciiMap[numeric] || String.fromCharCode(numeric); + } + + return reverseEntities[all] || namedEntities[all] || nativeDecode(all); + }); + } + }; + + return Entities; +}); + +// Included from: js/tinymce/classes/dom/StyleSheetLoader.js + +/** + * StyleSheetLoader.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class handles loading of external stylesheets and fires events when these are loaded. + * + * @class tinymce.dom.StyleSheetLoader + * @private + */ +define("tinymce/dom/StyleSheetLoader", [ + "tinymce/util/Tools", + "tinymce/util/Delay" +], function(Tools, Delay) { + "use strict"; + + return function(document, settings) { + var idCount = 0, loadedStates = {}, maxLoadTime; + + settings = settings || {}; + maxLoadTime = settings.maxLoadTime || 5000; + + function appendToHead(node) { + document.getElementsByTagName('head')[0].appendChild(node); + } + + /** + * Loads the specified css style sheet file and call the loadedCallback once it's finished loading. + * + * @method load + * @param {String} url Url to be loaded. + * @param {Function} loadedCallback Callback to be executed when loaded. + * @param {Function} errorCallback Callback to be executed when failed loading. + */ + function load(url, loadedCallback, errorCallback) { + var link, style, startTime, state; + + function passed() { + var callbacks = state.passed, i = callbacks.length; + + while (i--) { + callbacks[i](); + } + + state.status = 2; + state.passed = []; + state.failed = []; + } + + function failed() { + var callbacks = state.failed, i = callbacks.length; + + while (i--) { + callbacks[i](); + } + + state.status = 3; + state.passed = []; + state.failed = []; + } + + // Sniffs for older WebKit versions that have the link.onload but a broken one + function isOldWebKit() { + var webKitChunks = navigator.userAgent.match(/WebKit\/(\d*)/); + return !!(webKitChunks && webKitChunks[1] < 536); + } + + // Calls the waitCallback until the test returns true or the timeout occurs + function wait(testCallback, waitCallback) { + if (!testCallback()) { + // Wait for timeout + if ((new Date().getTime()) - startTime < maxLoadTime) { + Delay.setTimeout(waitCallback); + } else { + failed(); + } + } + } + + // Workaround for WebKit that doesn't properly support the onload event for link elements + // Or WebKit that fires the onload event before the StyleSheet is added to the document + function waitForWebKitLinkLoaded() { + wait(function() { + var styleSheets = document.styleSheets, styleSheet, i = styleSheets.length, owner; + + while (i--) { + styleSheet = styleSheets[i]; + owner = styleSheet.ownerNode ? styleSheet.ownerNode : styleSheet.owningElement; + if (owner && owner.id === link.id) { + passed(); + return true; + } + } + }, waitForWebKitLinkLoaded); + } + + // Workaround for older Geckos that doesn't have any onload event for StyleSheets + function waitForGeckoLinkLoaded() { + wait(function() { + try { + // Accessing the cssRules will throw an exception until the CSS file is loaded + var cssRules = style.sheet.cssRules; + passed(); + return !!cssRules; + } catch (ex) { + // Ignore + } + }, waitForGeckoLinkLoaded); + } + + url = Tools._addCacheSuffix(url); + + if (!loadedStates[url]) { + state = { + passed: [], + failed: [] + }; + + loadedStates[url] = state; + } else { + state = loadedStates[url]; + } + + if (loadedCallback) { + state.passed.push(loadedCallback); + } + + if (errorCallback) { + state.failed.push(errorCallback); + } + + // Is loading wait for it to pass + if (state.status == 1) { + return; + } + + // Has finished loading and was success + if (state.status == 2) { + passed(); + return; + } + + // Has finished loading and was a failure + if (state.status == 3) { + failed(); + return; + } + + // Start loading + state.status = 1; + link = document.createElement('link'); + link.rel = 'stylesheet'; + link.type = 'text/css'; + link.id = 'u' + (idCount++); + link.async = false; + link.defer = false; + startTime = new Date().getTime(); + + // Feature detect onload on link element and sniff older webkits since it has an broken onload event + if ("onload" in link && !isOldWebKit()) { + link.onload = waitForWebKitLinkLoaded; + link.onerror = failed; + } else { + // Sniff for old Firefox that doesn't support the onload event on link elements + // TODO: Remove this in the future when everyone uses modern browsers + if (navigator.userAgent.indexOf("Firefox") > 0) { + style = document.createElement('style'); + style.textContent = '@import "' + url + '"'; + waitForGeckoLinkLoaded(); + appendToHead(style); + return; + } + + // Use the id owner on older webkits + waitForWebKitLinkLoaded(); + } + + appendToHead(link); + link.href = url; + } + + this.load = load; + }; +}); + +// Included from: js/tinymce/classes/dom/DOMUtils.js + +/** + * DOMUtils.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Utility class for various DOM manipulation and retrieval functions. + * + * @class tinymce.dom.DOMUtils + * @example + * // Add a class to an element by id in the page + * tinymce.DOM.addClass('someid', 'someclass'); + * + * // Add a class to an element by id inside the editor + * tinymce.activeEditor.dom.addClass('someid', 'someclass'); + */ +define("tinymce/dom/DOMUtils", [ + "tinymce/dom/Sizzle", + "tinymce/dom/DomQuery", + "tinymce/html/Styles", + "tinymce/dom/EventUtils", + "tinymce/dom/TreeWalker", + "tinymce/dom/Range", + "tinymce/html/Entities", + "tinymce/Env", + "tinymce/util/Tools", + "tinymce/dom/StyleSheetLoader" +], function(Sizzle, $, Styles, EventUtils, TreeWalker, Range, Entities, Env, Tools, StyleSheetLoader) { + // Shorten names + var each = Tools.each, is = Tools.is, grep = Tools.grep, trim = Tools.trim; + var isIE = Env.ie; + var simpleSelectorRe = /^([a-z0-9],?)+$/i; + var whiteSpaceRegExp = /^[ \t\r\n]*$/; + + function setupAttrHooks(domUtils, settings) { + var attrHooks = {}, keepValues = settings.keep_values, keepUrlHook; + + keepUrlHook = { + set: function($elm, value, name) { + if (settings.url_converter) { + value = settings.url_converter.call(settings.url_converter_scope || domUtils, value, name, $elm[0]); + } + + $elm.attr('data-mce-' + name, value).attr(name, value); + }, + + get: function($elm, name) { + return $elm.attr('data-mce-' + name) || $elm.attr(name); + } + }; + + attrHooks = { + style: { + set: function($elm, value) { + if (value !== null && typeof value === 'object') { + $elm.css(value); + return; + } + + if (keepValues) { + $elm.attr('data-mce-style', value); + } + + $elm.attr('style', value); + }, + + get: function($elm) { + var value = $elm.attr('data-mce-style') || $elm.attr('style'); + + value = domUtils.serializeStyle(domUtils.parseStyle(value), $elm[0].nodeName); + + return value; + } + } + }; + + if (keepValues) { + attrHooks.href = attrHooks.src = keepUrlHook; + } + + return attrHooks; + } + + function updateInternalStyleAttr(domUtils, $elm) { + var value = $elm.attr('style'); + + value = domUtils.serializeStyle(domUtils.parseStyle(value), $elm[0].nodeName); + + if (!value) { + value = null; + } + + $elm.attr('data-mce-style', value); + } + + function nodeIndex(node, normalized) { + var idx = 0, lastNodeType, nodeType; + + if (node) { + for (lastNodeType = node.nodeType, node = node.previousSibling; node; node = node.previousSibling) { + nodeType = node.nodeType; + + // Normalize text nodes + if (normalized && nodeType == 3) { + if (nodeType == lastNodeType || !node.nodeValue.length) { + continue; + } + } + idx++; + lastNodeType = nodeType; + } + } + + return idx; + } + + /** + * Constructs a new DOMUtils instance. Consult the Wiki for more details on settings etc for this class. + * + * @constructor + * @method DOMUtils + * @param {Document} doc Document reference to bind the utility class to. + * @param {settings} settings Optional settings collection. + */ + function DOMUtils(doc, settings) { + var self = this, blockElementsMap; + + self.doc = doc; + self.win = window; + self.files = {}; + self.counter = 0; + self.stdMode = !isIE || doc.documentMode >= 8; + self.boxModel = !isIE || doc.compatMode == "CSS1Compat" || self.stdMode; + self.styleSheetLoader = new StyleSheetLoader(doc); + self.boundEvents = []; + self.settings = settings = settings || {}; + self.schema = settings.schema; + self.styles = new Styles({ + url_converter: settings.url_converter, + url_converter_scope: settings.url_converter_scope + }, settings.schema); + + self.fixDoc(doc); + self.events = settings.ownEvents ? new EventUtils(settings.proxy) : EventUtils.Event; + self.attrHooks = setupAttrHooks(self, settings); + blockElementsMap = settings.schema ? settings.schema.getBlockElements() : {}; + self.$ = $.overrideDefaults(function() { + return { + context: doc, + element: self.getRoot() + }; + }); + + /** + * Returns true/false if the specified element is a block element or not. + * + * @method isBlock + * @param {Node/String} node Element/Node to check. + * @return {Boolean} True/False state if the node is a block element or not. + */ + self.isBlock = function(node) { + // Fix for #5446 + if (!node) { + return false; + } + + // This function is called in module pattern style since it might be executed with the wrong this scope + var type = node.nodeType; + + // If it's a node then check the type and use the nodeName + if (type) { + return !!(type === 1 && blockElementsMap[node.nodeName]); + } + + return !!blockElementsMap[node]; + }; + } + + DOMUtils.prototype = { + $$: function(elm) { + if (typeof elm == 'string') { + elm = this.get(elm); + } + + return this.$(elm); + }, + + root: null, + + fixDoc: function(doc) { + var settings = this.settings, name; + + if (isIE && settings.schema) { + // Add missing HTML 4/5 elements to IE + ('abbr article aside audio canvas ' + + 'details figcaption figure footer ' + + 'header hgroup mark menu meter nav ' + + 'output progress section summary ' + + 'time video').replace(/\w+/g, function(name) { + doc.createElement(name); + }); + + // Create all custom elements + for (name in settings.schema.getCustomElements()) { + doc.createElement(name); + } + } + }, + + clone: function(node, deep) { + var self = this, clone, doc; + + // TODO: Add feature detection here in the future + if (!isIE || node.nodeType !== 1 || deep) { + return node.cloneNode(deep); + } + + doc = self.doc; + + // Make a HTML5 safe shallow copy + if (!deep) { + clone = doc.createElement(node.nodeName); + + // Copy attribs + each(self.getAttribs(node), function(attr) { + self.setAttrib(clone, attr.nodeName, self.getAttrib(node, attr.nodeName)); + }); + + return clone; + } + + return clone.firstChild; + }, + + /** + * Returns the root node of the document. This is normally the body but might be a DIV. Parents like getParent will not + * go above the point of this root node. + * + * @method getRoot + * @return {Element} Root element for the utility class. + */ + getRoot: function() { + var self = this; + + return self.settings.root_element || self.doc.body; + }, + + /** + * Returns the viewport of the window. + * + * @method getViewPort + * @param {Window} win Optional window to get viewport of. + * @return {Object} Viewport object with fields x, y, w and h. + */ + getViewPort: function(win) { + var doc, rootElm; + + win = !win ? this.win : win; + doc = win.document; + rootElm = this.boxModel ? doc.documentElement : doc.body; + + // Returns viewport size excluding scrollbars + return { + x: win.pageXOffset || rootElm.scrollLeft, + y: win.pageYOffset || rootElm.scrollTop, + w: win.innerWidth || rootElm.clientWidth, + h: win.innerHeight || rootElm.clientHeight + }; + }, + + /** + * Returns the rectangle for a specific element. + * + * @method getRect + * @param {Element/String} elm Element object or element ID to get rectangle from. + * @return {object} Rectangle for specified element object with x, y, w, h fields. + */ + getRect: function(elm) { + var self = this, pos, size; + + elm = self.get(elm); + pos = self.getPos(elm); + size = self.getSize(elm); + + return { + x: pos.x, y: pos.y, + w: size.w, h: size.h + }; + }, + + /** + * Returns the size dimensions of the specified element. + * + * @method getSize + * @param {Element/String} elm Element object or element ID to get rectangle from. + * @return {object} Rectangle for specified element object with w, h fields. + */ + getSize: function(elm) { + var self = this, w, h; + + elm = self.get(elm); + w = self.getStyle(elm, 'width'); + h = self.getStyle(elm, 'height'); + + // Non pixel value, then force offset/clientWidth + if (w.indexOf('px') === -1) { + w = 0; + } + + // Non pixel value, then force offset/clientWidth + if (h.indexOf('px') === -1) { + h = 0; + } + + return { + w: parseInt(w, 10) || elm.offsetWidth || elm.clientWidth, + h: parseInt(h, 10) || elm.offsetHeight || elm.clientHeight + }; + }, + + /** + * Returns a node by the specified selector function. This function will + * loop through all parent nodes and call the specified function for each node. + * If the function then returns true indicating that it has found what it was looking for, the loop execution will then end + * and the node it found will be returned. + * + * @method getParent + * @param {Node/String} node DOM node to search parents on or ID string. + * @param {function} selector Selection function or CSS selector to execute on each node. + * @param {Node} root Optional root element, never go below this point. + * @return {Node} DOM Node or null if it wasn't found. + */ + getParent: function(node, selector, root) { + return this.getParents(node, selector, root, false); + }, + + /** + * Returns a node list of all parents matching the specified selector function or pattern. + * If the function then returns true indicating that it has found what it was looking for and that node will be collected. + * + * @method getParents + * @param {Node/String} node DOM node to search parents on or ID string. + * @param {function} selector Selection function to execute on each node or CSS pattern. + * @param {Node} root Optional root element, never go below this point. + * @return {Array} Array of nodes or null if it wasn't found. + */ + getParents: function(node, selector, root, collect) { + var self = this, selectorVal, result = []; + + node = self.get(node); + collect = collect === undefined; + + // Default root on inline mode + root = root || (self.getRoot().nodeName != 'BODY' ? self.getRoot().parentNode : null); + + // Wrap node name as func + if (is(selector, 'string')) { + selectorVal = selector; + + if (selector === '*') { + selector = function(node) { + return node.nodeType == 1; + }; + } else { + selector = function(node) { + return self.is(node, selectorVal); + }; + } + } + + while (node) { + if (node == root || !node.nodeType || node.nodeType === 9) { + break; + } + + if (!selector || selector(node)) { + if (collect) { + result.push(node); + } else { + return node; + } + } + + node = node.parentNode; + } + + return collect ? result : null; + }, + + /** + * Returns the specified element by ID or the input element if it isn't a string. + * + * @method get + * @param {String/Element} n Element id to look for or element to just pass though. + * @return {Element} Element matching the specified id or null if it wasn't found. + */ + get: function(elm) { + var name; + + if (elm && this.doc && typeof elm == 'string') { + name = elm; + elm = this.doc.getElementById(elm); + + // IE and Opera returns meta elements when they match the specified input ID, but getElementsByName seems to do the trick + if (elm && elm.id !== name) { + return this.doc.getElementsByName(name)[1]; + } + } + + return elm; + }, + + /** + * Returns the next node that matches selector or function + * + * @method getNext + * @param {Node} node Node to find siblings from. + * @param {String/function} selector Selector CSS expression or function. + * @return {Node} Next node item matching the selector or null if it wasn't found. + */ + getNext: function(node, selector) { + return this._findSib(node, selector, 'nextSibling'); + }, + + /** + * Returns the previous node that matches selector or function + * + * @method getPrev + * @param {Node} node Node to find siblings from. + * @param {String/function} selector Selector CSS expression or function. + * @return {Node} Previous node item matching the selector or null if it wasn't found. + */ + getPrev: function(node, selector) { + return this._findSib(node, selector, 'previousSibling'); + }, + + // #ifndef jquery + + /** + * Selects specific elements by a CSS level 3 pattern. For example "div#a1 p.test". + * This function is optimized for the most common patterns needed in TinyMCE but it also performs well enough + * on more complex patterns. + * + * @method select + * @param {String} selector CSS level 3 pattern to select/find elements by. + * @param {Object} scope Optional root element/scope element to search in. + * @return {Array} Array with all matched elements. + * @example + * // Adds a class to all paragraphs in the currently active editor + * tinymce.activeEditor.dom.addClass(tinymce.activeEditor.dom.select('p'), 'someclass'); + * + * // Adds a class to all spans that have the test class in the currently active editor + * tinymce.activeEditor.dom.addClass(tinymce.activeEditor.dom.select('span.test'), 'someclass') + */ + select: function(selector, scope) { + var self = this; + + /*eslint new-cap:0 */ + return Sizzle(selector, self.get(scope) || self.settings.root_element || self.doc, []); + }, + + /** + * Returns true/false if the specified element matches the specified css pattern. + * + * @method is + * @param {Node/NodeList} elm DOM node to match or an array of nodes to match. + * @param {String} selector CSS pattern to match the element against. + */ + is: function(elm, selector) { + var i; + + // If it isn't an array then try to do some simple selectors instead of Sizzle for to boost performance + if (elm.length === undefined) { + // Simple all selector + if (selector === '*') { + return elm.nodeType == 1; + } + + // Simple selector just elements + if (simpleSelectorRe.test(selector)) { + selector = selector.toLowerCase().split(/,/); + elm = elm.nodeName.toLowerCase(); + + for (i = selector.length - 1; i >= 0; i--) { + if (selector[i] == elm) { + return true; + } + } + + return false; + } + } + + // Is non element + if (elm.nodeType && elm.nodeType != 1) { + return false; + } + + var elms = elm.nodeType ? [elm] : elm; + + /*eslint new-cap:0 */ + return Sizzle(selector, elms[0].ownerDocument || elms[0], null, elms).length > 0; + }, + + // #endif + + /** + * Adds the specified element to another element or elements. + * + * @method add + * @param {String/Element/Array} parentElm Element id string, DOM node element or array of ids or elements to add to. + * @param {String/Element} name Name of new element to add or existing element to add. + * @param {Object} attrs Optional object collection with arguments to add to the new element(s). + * @param {String} html Optional inner HTML contents to add for each element. + * @param {Boolean} create Optional flag if the element should be created or added. + * @return {Element/Array} Element that got created, or an array of created elements if multiple input elements + * were passed in. + * @example + * // Adds a new paragraph to the end of the active editor + * tinymce.activeEditor.dom.add(tinymce.activeEditor.getBody(), 'p', {title: 'my title'}, 'Some content'); + */ + add: function(parentElm, name, attrs, html, create) { + var self = this; + + return this.run(parentElm, function(parentElm) { + var newElm; + + newElm = is(name, 'string') ? self.doc.createElement(name) : name; + self.setAttribs(newElm, attrs); + + if (html) { + if (html.nodeType) { + newElm.appendChild(html); + } else { + self.setHTML(newElm, html); + } + } + + return !create ? parentElm.appendChild(newElm) : newElm; + }); + }, + + /** + * Creates a new element. + * + * @method create + * @param {String} name Name of new element. + * @param {Object} attrs Optional object name/value collection with element attributes. + * @param {String} html Optional HTML string to set as inner HTML of the element. + * @return {Element} HTML DOM node element that got created. + * @example + * // Adds an element where the caret/selection is in the active editor + * var el = tinymce.activeEditor.dom.create('div', {id: 'test', 'class': 'myclass'}, 'some content'); + * tinymce.activeEditor.selection.setNode(el); + */ + create: function(name, attrs, html) { + return this.add(this.doc.createElement(name), name, attrs, html, 1); + }, + + /** + * Creates HTML string for element. The element will be closed unless an empty inner HTML string is passed in. + * + * @method createHTML + * @param {String} name Name of new element. + * @param {Object} attrs Optional object name/value collection with element attributes. + * @param {String} html Optional HTML string to set as inner HTML of the element. + * @return {String} String with new HTML element, for example: <a href="#">test</a>. + * @example + * // Creates a html chunk and inserts it at the current selection/caret location + * tinymce.activeEditor.selection.setContent(tinymce.activeEditor.dom.createHTML('a', {href: 'test.html'}, 'some line')); + */ + createHTML: function(name, attrs, html) { + var outHtml = '', key; + + outHtml += '<' + name; + + for (key in attrs) { + if (attrs.hasOwnProperty(key) && attrs[key] !== null && typeof attrs[key] != 'undefined') { + outHtml += ' ' + key + '="' + this.encode(attrs[key]) + '"'; + } + } + + // A call to tinymce.is doesn't work for some odd reason on IE9 possible bug inside their JS runtime + if (typeof html != "undefined") { + return outHtml + '>' + html + '</' + name + '>'; + } + + return outHtml + ' />'; + }, + + /** + * Creates a document fragment out of the specified HTML string. + * + * @method createFragment + * @param {String} html Html string to create fragment from. + * @return {DocumentFragment} Document fragment node. + */ + createFragment: function(html) { + var frag, node, doc = this.doc, container; + + container = doc.createElement("div"); + frag = doc.createDocumentFragment(); + + if (html) { + container.innerHTML = html; + } + + while ((node = container.firstChild)) { + frag.appendChild(node); + } + + return frag; + }, + + /** + * Removes/deletes the specified element(s) from the DOM. + * + * @method remove + * @param {String/Element/Array} node ID of element or DOM element object or array containing multiple elements/ids. + * @param {Boolean} keepChildren Optional state to keep children or not. If set to true all children will be + * placed at the location of the removed element. + * @return {Element/Array} HTML DOM element that got removed, or an array of removed elements if multiple input elements + * were passed in. + * @example + * // Removes all paragraphs in the active editor + * tinymce.activeEditor.dom.remove(tinymce.activeEditor.dom.select('p')); + * + * // Removes an element by id in the document + * tinymce.DOM.remove('mydiv'); + */ + remove: function(node, keepChildren) { + node = this.$$(node); + + if (keepChildren) { + node.each(function() { + var child; + + while ((child = this.firstChild)) { + if (child.nodeType == 3 && child.data.length === 0) { + this.removeChild(child); + } else { + this.parentNode.insertBefore(child, this); + } + } + }).remove(); + } else { + node.remove(); + } + + return node.length > 1 ? node.toArray() : node[0]; + }, + + /** + * Sets the CSS style value on a HTML element. The name can be a camelcase string + * or the CSS style name like background-color. + * + * @method setStyle + * @param {String/Element/Array} elm HTML element/Array of elements to set CSS style value on. + * @param {String} name Name of the style value to set. + * @param {String} value Value to set on the style. + * @example + * // Sets a style value on all paragraphs in the currently active editor + * tinymce.activeEditor.dom.setStyle(tinymce.activeEditor.dom.select('p'), 'background-color', 'red'); + * + * // Sets a style value to an element by id in the current document + * tinymce.DOM.setStyle('mydiv', 'background-color', 'red'); + */ + setStyle: function(elm, name, value) { + elm = this.$$(elm).css(name, value); + + if (this.settings.update_styles) { + updateInternalStyleAttr(this, elm); + } + }, + + /** + * Returns the current style or runtime/computed value of an element. + * + * @method getStyle + * @param {String/Element} elm HTML element or element id string to get style from. + * @param {String} name Style name to return. + * @param {Boolean} computed Computed style. + * @return {String} Current style or computed style value of an element. + */ + getStyle: function(elm, name, computed) { + elm = this.$$(elm); + + if (computed) { + return elm.css(name); + } + + // Camelcase it, if needed + name = name.replace(/-(\D)/g, function(a, b) { + return b.toUpperCase(); + }); + + if (name == 'float') { + name = Env.ie && Env.ie < 12 ? 'styleFloat' : 'cssFloat'; + } + + return elm[0] && elm[0].style ? elm[0].style[name] : undefined; + }, + + /** + * Sets multiple styles on the specified element(s). + * + * @method setStyles + * @param {Element/String/Array} elm DOM element, element id string or array of elements/ids to set styles on. + * @param {Object} styles Name/Value collection of style items to add to the element(s). + * @example + * // Sets styles on all paragraphs in the currently active editor + * tinymce.activeEditor.dom.setStyles(tinymce.activeEditor.dom.select('p'), {'background-color': 'red', 'color': 'green'}); + * + * // Sets styles to an element by id in the current document + * tinymce.DOM.setStyles('mydiv', {'background-color': 'red', 'color': 'green'}); + */ + setStyles: function(elm, styles) { + elm = this.$$(elm).css(styles); + + if (this.settings.update_styles) { + updateInternalStyleAttr(this, elm); + } + }, + + /** + * Removes all attributes from an element or elements. + * + * @method removeAllAttribs + * @param {Element/String/Array} e DOM element, element id string or array of elements/ids to remove attributes from. + */ + removeAllAttribs: function(e) { + return this.run(e, function(e) { + var i, attrs = e.attributes; + for (i = attrs.length - 1; i >= 0; i--) { + e.removeAttributeNode(attrs.item(i)); + } + }); + }, + + /** + * Sets the specified attribute of an element or elements. + * + * @method setAttrib + * @param {Element/String/Array} elm DOM element, element id string or array of elements/ids to set attribute on. + * @param {String} name Name of attribute to set. + * @param {String} value Value to set on the attribute - if this value is falsy like null, 0 or '' it will remove + * the attribute instead. + * @example + * // Sets class attribute on all paragraphs in the active editor + * tinymce.activeEditor.dom.setAttrib(tinymce.activeEditor.dom.select('p'), 'class', 'myclass'); + * + * // Sets class attribute on a specific element in the current page + * tinymce.dom.setAttrib('mydiv', 'class', 'myclass'); + */ + setAttrib: function(elm, name, value) { + var self = this, originalValue, hook, settings = self.settings; + + if (value === '') { + value = null; + } + + elm = self.$$(elm); + originalValue = elm.attr(name); + + if (!elm.length) { + return; + } + + hook = self.attrHooks[name]; + if (hook && hook.set) { + hook.set(elm, value, name); + } else { + elm.attr(name, value); + } + + if (originalValue != value && settings.onSetAttrib) { + settings.onSetAttrib({ + attrElm: elm, + attrName: name, + attrValue: value + }); + } + }, + + /** + * Sets two or more specified attributes of an element or elements. + * + * @method setAttribs + * @param {Element/String/Array} elm DOM element, element id string or array of elements/ids to set attributes on. + * @param {Object} attrs Name/Value collection of attribute items to add to the element(s). + * @example + * // Sets class and title attributes on all paragraphs in the active editor + * tinymce.activeEditor.dom.setAttribs(tinymce.activeEditor.dom.select('p'), {'class': 'myclass', title: 'some title'}); + * + * // Sets class and title attributes on a specific element in the current page + * tinymce.DOM.setAttribs('mydiv', {'class': 'myclass', title: 'some title'}); + */ + setAttribs: function(elm, attrs) { + var self = this; + + self.$$(elm).each(function(i, node) { + each(attrs, function(value, name) { + self.setAttrib(node, name, value); + }); + }); + }, + + /** + * Returns the specified attribute by name. + * + * @method getAttrib + * @param {String/Element} elm Element string id or DOM element to get attribute from. + * @param {String} name Name of attribute to get. + * @param {String} defaultVal Optional default value to return if the attribute didn't exist. + * @return {String} Attribute value string, default value or null if the attribute wasn't found. + */ + getAttrib: function(elm, name, defaultVal) { + var self = this, hook, value; + + elm = self.$$(elm); + + if (elm.length) { + hook = self.attrHooks[name]; + + if (hook && hook.get) { + value = hook.get(elm, name); + } else { + value = elm.attr(name); + } + } + + if (typeof value == 'undefined') { + value = defaultVal || ''; + } + + return value; + }, + + /** + * Returns the absolute x, y position of a node. The position will be returned in an object with x, y fields. + * + * @method getPos + * @param {Element/String} elm HTML element or element id to get x, y position from. + * @param {Element} rootElm Optional root element to stop calculations at. + * @return {object} Absolute position of the specified element object with x, y fields. + */ + getPos: function(elm, rootElm) { + var self = this, x = 0, y = 0, offsetParent, doc = self.doc, body = doc.body, pos; + + elm = self.get(elm); + rootElm = rootElm || body; + + if (elm) { + // Use getBoundingClientRect if it exists since it's faster than looping offset nodes + // Fallback to offsetParent calculations if the body isn't static better since it stops at the body root + if (rootElm === body && elm.getBoundingClientRect && $(body).css('position') === 'static') { + pos = elm.getBoundingClientRect(); + rootElm = self.boxModel ? doc.documentElement : body; + + // Add scroll offsets from documentElement or body since IE with the wrong box model will use d.body and so do WebKit + // Also remove the body/documentelement clientTop/clientLeft on IE 6, 7 since they offset the position + x = pos.left + (doc.documentElement.scrollLeft || body.scrollLeft) - rootElm.clientLeft; + y = pos.top + (doc.documentElement.scrollTop || body.scrollTop) - rootElm.clientTop; + + return {x: x, y: y}; + } + + offsetParent = elm; + while (offsetParent && offsetParent != rootElm && offsetParent.nodeType) { + x += offsetParent.offsetLeft || 0; + y += offsetParent.offsetTop || 0; + offsetParent = offsetParent.offsetParent; + } + + offsetParent = elm.parentNode; + while (offsetParent && offsetParent != rootElm && offsetParent.nodeType) { + x -= offsetParent.scrollLeft || 0; + y -= offsetParent.scrollTop || 0; + offsetParent = offsetParent.parentNode; + } + } + + return {x: x, y: y}; + }, + + /** + * Parses the specified style value into an object collection. This parser will also + * merge and remove any redundant items that browsers might have added. It will also convert non-hex + * colors to hex values. Urls inside the styles will also be converted to absolute/relative based on settings. + * + * @method parseStyle + * @param {String} cssText Style value to parse, for example: border:1px solid red;. + * @return {Object} Object representation of that style, for example: {border: '1px solid red'} + */ + parseStyle: function(cssText) { + return this.styles.parse(cssText); + }, + + /** + * Serializes the specified style object into a string. + * + * @method serializeStyle + * @param {Object} styles Object to serialize as string, for example: {border: '1px solid red'} + * @param {String} name Optional element name. + * @return {String} String representation of the style object, for example: border: 1px solid red. + */ + serializeStyle: function(styles, name) { + return this.styles.serialize(styles, name); + }, + + /** + * Adds a style element at the top of the document with the specified cssText content. + * + * @method addStyle + * @param {String} cssText CSS Text style to add to top of head of document. + */ + addStyle: function(cssText) { + var self = this, doc = self.doc, head, styleElm; + + // Prevent inline from loading the same styles twice + if (self !== DOMUtils.DOM && doc === document) { + var addedStyles = DOMUtils.DOM.addedStyles; + + addedStyles = addedStyles || []; + if (addedStyles[cssText]) { + return; + } + + addedStyles[cssText] = true; + DOMUtils.DOM.addedStyles = addedStyles; + } + + // Create style element if needed + styleElm = doc.getElementById('mceDefaultStyles'); + if (!styleElm) { + styleElm = doc.createElement('style'); + styleElm.id = 'mceDefaultStyles'; + styleElm.type = 'text/css'; + + head = doc.getElementsByTagName('head')[0]; + if (head.firstChild) { + head.insertBefore(styleElm, head.firstChild); + } else { + head.appendChild(styleElm); + } + } + + // Append style data to old or new style element + if (styleElm.styleSheet) { + styleElm.styleSheet.cssText += cssText; + } else { + styleElm.appendChild(doc.createTextNode(cssText)); + } + }, + + /** + * Imports/loads the specified CSS file into the document bound to the class. + * + * @method loadCSS + * @param {String} url URL to CSS file to load. + * @example + * // Loads a CSS file dynamically into the current document + * tinymce.DOM.loadCSS('somepath/some.css'); + * + * // Loads a CSS file into the currently active editor instance + * tinymce.activeEditor.dom.loadCSS('somepath/some.css'); + * + * // Loads a CSS file into an editor instance by id + * tinymce.get('someid').dom.loadCSS('somepath/some.css'); + * + * // Loads multiple CSS files into the current document + * tinymce.DOM.loadCSS('somepath/some.css,somepath/someother.css'); + */ + loadCSS: function(url) { + var self = this, doc = self.doc, head; + + // Prevent inline from loading the same CSS file twice + if (self !== DOMUtils.DOM && doc === document) { + DOMUtils.DOM.loadCSS(url); + return; + } + + if (!url) { + url = ''; + } + + head = doc.getElementsByTagName('head')[0]; + + each(url.split(','), function(url) { + var link; + + url = Tools._addCacheSuffix(url); + + if (self.files[url]) { + return; + } + + self.files[url] = true; + link = self.create('link', {rel: 'stylesheet', href: url}); + + // IE 8 has a bug where dynamically loading stylesheets would produce a 1 item remaining bug + // This fix seems to resolve that issue by recalcing the document once a stylesheet finishes loading + // It's ugly but it seems to work fine. + if (isIE && doc.documentMode && doc.recalc) { + link.onload = function() { + if (doc.recalc) { + doc.recalc(); + } + + link.onload = null; + }; + } + + head.appendChild(link); + }); + }, + + /** + * Adds a class to the specified element or elements. + * + * @method addClass + * @param {String/Element/Array} elm Element ID string or DOM element or array with elements or IDs. + * @param {String} cls Class name to add to each element. + * @return {String/Array} String with new class value or array with new class values for all elements. + * @example + * // Adds a class to all paragraphs in the active editor + * tinymce.activeEditor.dom.addClass(tinymce.activeEditor.dom.select('p'), 'myclass'); + * + * // Adds a class to a specific element in the current page + * tinymce.DOM.addClass('mydiv', 'myclass'); + */ + addClass: function(elm, cls) { + this.$$(elm).addClass(cls); + }, + + /** + * Removes a class from the specified element or elements. + * + * @method removeClass + * @param {String/Element/Array} elm Element ID string or DOM element or array with elements or IDs. + * @param {String} cls Class name to remove from each element. + * @return {String/Array} String of remaining class name(s), or an array of strings if multiple input elements + * were passed in. + * @example + * // Removes a class from all paragraphs in the active editor + * tinymce.activeEditor.dom.removeClass(tinymce.activeEditor.dom.select('p'), 'myclass'); + * + * // Removes a class from a specific element in the current page + * tinymce.DOM.removeClass('mydiv', 'myclass'); + */ + removeClass: function(elm, cls) { + this.toggleClass(elm, cls, false); + }, + + /** + * Returns true if the specified element has the specified class. + * + * @method hasClass + * @param {String/Element} elm HTML element or element id string to check CSS class on. + * @param {String} cls CSS class to check for. + * @return {Boolean} true/false if the specified element has the specified class. + */ + hasClass: function(elm, cls) { + return this.$$(elm).hasClass(cls); + }, + + /** + * Toggles the specified class on/off. + * + * @method toggleClass + * @param {Element} elm Element to toggle class on. + * @param {[type]} cls Class to toggle on/off. + * @param {[type]} state Optional state to set. + */ + toggleClass: function(elm, cls, state) { + this.$$(elm).toggleClass(cls, state).each(function() { + if (this.className === '') { + $(this).attr('class', null); + } + }); + }, + + /** + * Shows the specified element(s) by ID by setting the "display" style. + * + * @method show + * @param {String/Element/Array} elm ID of DOM element or DOM element or array with elements or IDs to show. + */ + show: function(elm) { + this.$$(elm).show(); + }, + + /** + * Hides the specified element(s) by ID by setting the "display" style. + * + * @method hide + * @param {String/Element/Array} elm ID of DOM element or DOM element or array with elements or IDs to hide. + * @example + * // Hides an element by id in the document + * tinymce.DOM.hide('myid'); + */ + hide: function(elm) { + this.$$(elm).hide(); + }, + + /** + * Returns true/false if the element is hidden or not by checking the "display" style. + * + * @method isHidden + * @param {String/Element} elm Id or element to check display state on. + * @return {Boolean} true/false if the element is hidden or not. + */ + isHidden: function(elm) { + return this.$$(elm).css('display') == 'none'; + }, + + /** + * Returns a unique id. This can be useful when generating elements on the fly. + * This method will not check if the element already exists. + * + * @method uniqueId + * @param {String} prefix Optional prefix to add in front of all ids - defaults to "mce_". + * @return {String} Unique id. + */ + uniqueId: function(prefix) { + return (!prefix ? 'mce_' : prefix) + (this.counter++); + }, + + /** + * Sets the specified HTML content inside the element or elements. The HTML will first be processed. This means + * URLs will get converted, hex color values fixed etc. Check processHTML for details. + * + * @method setHTML + * @param {Element/String/Array} elm DOM element, element id string or array of elements/ids to set HTML inside of. + * @param {String} html HTML content to set as inner HTML of the element. + * @example + * // Sets the inner HTML of all paragraphs in the active editor + * tinymce.activeEditor.dom.setHTML(tinymce.activeEditor.dom.select('p'), 'some inner html'); + * + * // Sets the inner HTML of an element by id in the document + * tinymce.DOM.setHTML('mydiv', 'some inner html'); + */ + setHTML: function(elm, html) { + elm = this.$$(elm); + + if (isIE) { + elm.each(function(i, target) { + if (target.canHaveHTML === false) { + return; + } + + // Remove all child nodes, IE keeps empty text nodes in DOM + while (target.firstChild) { + target.removeChild(target.firstChild); + } + + try { + // IE will remove comments from the beginning + // unless you padd the contents with something + target.innerHTML = '<br>' + html; + target.removeChild(target.firstChild); + } catch (ex) { + // IE sometimes produces an unknown runtime error on innerHTML if it's a div inside a p + $('<div>').html('<br>' + html).contents().slice(1).appendTo(target); + } + + return html; + }); + } else { + elm.html(html); + } + }, + + /** + * Returns the outer HTML of an element. + * + * @method getOuterHTML + * @param {String/Element} elm Element ID or element object to get outer HTML from. + * @return {String} Outer HTML string. + * @example + * tinymce.DOM.getOuterHTML(editorElement); + * tinymce.activeEditor.getOuterHTML(tinymce.activeEditor.getBody()); + */ + getOuterHTML: function(elm) { + elm = this.get(elm); + + // Older FF doesn't have outerHTML 3.6 is still used by some orgaizations + return elm.nodeType == 1 && "outerHTML" in elm ? elm.outerHTML : $('<div>').append($(elm).clone()).html(); + }, + + /** + * Sets the specified outer HTML on an element or elements. + * + * @method setOuterHTML + * @param {Element/String/Array} elm DOM element, element id string or array of elements/ids to set outer HTML on. + * @param {Object} html HTML code to set as outer value for the element. + * @example + * // Sets the outer HTML of all paragraphs in the active editor + * tinymce.activeEditor.dom.setOuterHTML(tinymce.activeEditor.dom.select('p'), '<div>some html</div>'); + * + * // Sets the outer HTML of an element by id in the document + * tinymce.DOM.setOuterHTML('mydiv', '<div>some html</div>'); + */ + setOuterHTML: function(elm, html) { + var self = this; + + self.$$(elm).each(function() { + try { + // Older FF doesn't have outerHTML 3.6 is still used by some organizations + if ("outerHTML" in this) { + this.outerHTML = html; + return; + } + } catch (ex) { + // Ignore + } + + // OuterHTML for IE it sometimes produces an "unknown runtime error" + self.remove($(this).html(html), true); + }); + }, + + /** + * Entity decodes a string. This method decodes any HTML entities, such as å. + * + * @method decode + * @param {String} s String to decode entities on. + * @return {String} Entity decoded string. + */ + decode: Entities.decode, + + /** + * Entity encodes a string. This method encodes the most common entities, such as <>"&. + * + * @method encode + * @param {String} text String to encode with entities. + * @return {String} Entity encoded string. + */ + encode: Entities.encodeAllRaw, + + /** + * Inserts an element after the reference element. + * + * @method insertAfter + * @param {Element} node Element to insert after the reference. + * @param {Element/String/Array} referenceNode Reference element, element id or array of elements to insert after. + * @return {Element/Array} Element that got added or an array with elements. + */ + insertAfter: function(node, referenceNode) { + referenceNode = this.get(referenceNode); + + return this.run(node, function(node) { + var parent, nextSibling; + + parent = referenceNode.parentNode; + nextSibling = referenceNode.nextSibling; + + if (nextSibling) { + parent.insertBefore(node, nextSibling); + } else { + parent.appendChild(node); + } + + return node; + }); + }, + + /** + * Replaces the specified element or elements with the new element specified. The new element will + * be cloned if multiple input elements are passed in. + * + * @method replace + * @param {Element} newElm New element to replace old ones with. + * @param {Element/String/Array} oldElm Element DOM node, element id or array of elements or ids to replace. + * @param {Boolean} keepChildren Optional keep children state, if set to true child nodes from the old object will be added + * to new ones. + */ + replace: function(newElm, oldElm, keepChildren) { + var self = this; + + return self.run(oldElm, function(oldElm) { + if (is(oldElm, 'array')) { + newElm = newElm.cloneNode(true); + } + + if (keepChildren) { + each(grep(oldElm.childNodes), function(node) { + newElm.appendChild(node); + }); + } + + return oldElm.parentNode.replaceChild(newElm, oldElm); + }); + }, + + /** + * Renames the specified element and keeps its attributes and children. + * + * @method rename + * @param {Element} elm Element to rename. + * @param {String} name Name of the new element. + * @return {Element} New element or the old element if it needed renaming. + */ + rename: function(elm, name) { + var self = this, newElm; + + if (elm.nodeName != name.toUpperCase()) { + // Rename block element + newElm = self.create(name); + + // Copy attribs to new block + each(self.getAttribs(elm), function(attrNode) { + self.setAttrib(newElm, attrNode.nodeName, self.getAttrib(elm, attrNode.nodeName)); + }); + + // Replace block + self.replace(newElm, elm, 1); + } + + return newElm || elm; + }, + + /** + * Find the common ancestor of two elements. This is a shorter method than using the DOM Range logic. + * + * @method findCommonAncestor + * @param {Element} a Element to find common ancestor of. + * @param {Element} b Element to find common ancestor of. + * @return {Element} Common ancestor element of the two input elements. + */ + findCommonAncestor: function(a, b) { + var ps = a, pe; + + while (ps) { + pe = b; + + while (pe && ps != pe) { + pe = pe.parentNode; + } + + if (ps == pe) { + break; + } + + ps = ps.parentNode; + } + + if (!ps && a.ownerDocument) { + return a.ownerDocument.documentElement; + } + + return ps; + }, + + /** + * Parses the specified RGB color value and returns a hex version of that color. + * + * @method toHex + * @param {String} rgbVal RGB string value like rgb(1,2,3) + * @return {String} Hex version of that RGB value like #FF00FF. + */ + toHex: function(rgbVal) { + return this.styles.toHex(Tools.trim(rgbVal)); + }, + + /** + * Executes the specified function on the element by id or dom element node or array of elements/id. + * + * @method run + * @param {String/Element/Array} elm ID or DOM element object or array with ids or elements. + * @param {function} func Function to execute for each item. + * @param {Object} scope Optional scope to execute the function in. + * @return {Object/Array} Single object, or an array of objects if multiple input elements were passed in. + */ + run: function(elm, func, scope) { + var self = this, result; + + if (typeof elm === 'string') { + elm = self.get(elm); + } + + if (!elm) { + return false; + } + + scope = scope || this; + if (!elm.nodeType && (elm.length || elm.length === 0)) { + result = []; + + each(elm, function(elm, i) { + if (elm) { + if (typeof elm == 'string') { + elm = self.get(elm); + } + + result.push(func.call(scope, elm, i)); + } + }); + + return result; + } + + return func.call(scope, elm); + }, + + /** + * Returns a NodeList with attributes for the element. + * + * @method getAttribs + * @param {HTMLElement/string} elm Element node or string id to get attributes from. + * @return {NodeList} NodeList with attributes. + */ + getAttribs: function(elm) { + var attrs; + + elm = this.get(elm); + + if (!elm) { + return []; + } + + if (isIE) { + attrs = []; + + // Object will throw exception in IE + if (elm.nodeName == 'OBJECT') { + return elm.attributes; + } + + // IE doesn't keep the selected attribute if you clone option elements + if (elm.nodeName === 'OPTION' && this.getAttrib(elm, 'selected')) { + attrs.push({specified: 1, nodeName: 'selected'}); + } + + // It's crazy that this is faster in IE but it's because it returns all attributes all the time + var attrRegExp = /<\/?[\w:\-]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=[\w\-]+|>/gi; + elm.cloneNode(false).outerHTML.replace(attrRegExp, '').replace(/[\w:\-]+/gi, function(a) { + attrs.push({specified: 1, nodeName: a}); + }); + + return attrs; + } + + return elm.attributes; + }, + + /** + * Returns true/false if the specified node is to be considered empty or not. + * + * @example + * tinymce.DOM.isEmpty(node, {img: true}); + * @method isEmpty + * @param {Object} elements Optional name/value object with elements that are automatically treated as non-empty elements. + * @return {Boolean} true/false if the node is empty or not. + */ + isEmpty: function(node, elements) { + var self = this, i, attributes, type, walker, name, brCount = 0; + + node = node.firstChild; + if (node) { + walker = new TreeWalker(node, node.parentNode); + elements = elements || (self.schema ? self.schema.getNonEmptyElements() : null); + + do { + type = node.nodeType; + + if (type === 1) { + // Ignore bogus elements + if (node.getAttribute('data-mce-bogus')) { + continue; + } + + // Keep empty elements like <img /> + name = node.nodeName.toLowerCase(); + if (elements && elements[name]) { + // Ignore single BR elements in blocks like <p><br /></p> or <p><span><br /></span></p> + if (name === 'br') { + brCount++; + continue; + } + + return false; + } + + // Keep elements with data-bookmark attributes or name attribute like <a name="1"></a> + attributes = self.getAttribs(node); + i = attributes.length; + while (i--) { + name = attributes[i].nodeName; + if (name === "name" || name === 'data-mce-bookmark') { + return false; + } + } + } + + // Keep comment nodes + if (type == 8) { + return false; + } + + // Keep non whitespace text nodes + if ((type === 3 && !whiteSpaceRegExp.test(node.nodeValue))) { + return false; + } + } while ((node = walker.next())); + } + + return brCount <= 1; + }, + + /** + * Creates a new DOM Range object. This will use the native DOM Range API if it's + * available. If it's not, it will fall back to the custom TinyMCE implementation. + * + * @method createRng + * @return {DOMRange} DOM Range object. + * @example + * var rng = tinymce.DOM.createRng(); + * alert(rng.startContainer + "," + rng.startOffset); + */ + createRng: function() { + var doc = this.doc; + + return doc.createRange ? doc.createRange() : new Range(this); + }, + + /** + * Returns the index of the specified node within its parent. + * + * @method nodeIndex + * @param {Node} node Node to look for. + * @param {boolean} normalized Optional true/false state if the index is what it would be after a normalization. + * @return {Number} Index of the specified node. + */ + nodeIndex: nodeIndex, + + /** + * Splits an element into two new elements and places the specified split + * element or elements between the new ones. For example splitting the paragraph at the bold element in + * this example <p>abc<b>abc</b>123</p> would produce <p>abc</p><b>abc</b><p>123</p>. + * + * @method split + * @param {Element} parentElm Parent element to split. + * @param {Element} splitElm Element to split at. + * @param {Element} replacementElm Optional replacement element to replace the split element with. + * @return {Element} Returns the split element or the replacement element if that is specified. + */ + split: function(parentElm, splitElm, replacementElm) { + var self = this, r = self.createRng(), bef, aft, pa; + + // W3C valid browsers tend to leave empty nodes to the left/right side of the contents - this makes sense + // but we don't want that in our code since it serves no purpose for the end user + // For example splitting this html at the bold element: + // <p>text 1<span><b>CHOP</b></span>text 2</p> + // would produce: + // <p>text 1<span></span></p><b>CHOP</b><p><span></span>text 2</p> + // this function will then trim off empty edges and produce: + // <p>text 1</p><b>CHOP</b><p>text 2</p> + function trimNode(node) { + var i, children = node.childNodes, type = node.nodeType; + + function surroundedBySpans(node) { + var previousIsSpan = node.previousSibling && node.previousSibling.nodeName == 'SPAN'; + var nextIsSpan = node.nextSibling && node.nextSibling.nodeName == 'SPAN'; + return previousIsSpan && nextIsSpan; + } + + if (type == 1 && node.getAttribute('data-mce-type') == 'bookmark') { + return; + } + + for (i = children.length - 1; i >= 0; i--) { + trimNode(children[i]); + } + + if (type != 9) { + // Keep non whitespace text nodes + if (type == 3 && node.nodeValue.length > 0) { + // If parent element isn't a block or there isn't any useful contents for example "<p> </p>" + // Also keep text nodes with only spaces if surrounded by spans. + // eg. "<p><span>a</span> <span>b</span></p>" should keep space between a and b + var trimmedLength = trim(node.nodeValue).length; + if (!self.isBlock(node.parentNode) || trimmedLength > 0 || trimmedLength === 0 && surroundedBySpans(node)) { + return; + } + } else if (type == 1) { + // If the only child is a bookmark then move it up + children = node.childNodes; + + // TODO fix this complex if + if (children.length == 1 && children[0] && children[0].nodeType == 1 && + children[0].getAttribute('data-mce-type') == 'bookmark') { + node.parentNode.insertBefore(children[0], node); + } + + // Keep non empty elements or img, hr etc + if (children.length || /^(br|hr|input|img)$/i.test(node.nodeName)) { + return; + } + } + + self.remove(node); + } + + return node; + } + + if (parentElm && splitElm) { + // Get before chunk + r.setStart(parentElm.parentNode, self.nodeIndex(parentElm)); + r.setEnd(splitElm.parentNode, self.nodeIndex(splitElm)); + bef = r.extractContents(); + + // Get after chunk + r = self.createRng(); + r.setStart(splitElm.parentNode, self.nodeIndex(splitElm) + 1); + r.setEnd(parentElm.parentNode, self.nodeIndex(parentElm) + 1); + aft = r.extractContents(); + + // Insert before chunk + pa = parentElm.parentNode; + pa.insertBefore(trimNode(bef), parentElm); + + // Insert middle chunk + if (replacementElm) { + pa.insertBefore(replacementElm, parentElm); + //pa.replaceChild(replacementElm, splitElm); + } else { + pa.insertBefore(splitElm, parentElm); + } + + // Insert after chunk + pa.insertBefore(trimNode(aft), parentElm); + self.remove(parentElm); + + return replacementElm || splitElm; + } + }, + + /** + * Adds an event handler to the specified object. + * + * @method bind + * @param {Element/Document/Window/Array} target Target element to bind events to. + * handler to or an array of elements/ids/documents. + * @param {String} name Name of event handler to add, for example: click. + * @param {function} func Function to execute when the event occurs. + * @param {Object} scope Optional scope to execute the function in. + * @return {function} Function callback handler the same as the one passed in. + */ + bind: function(target, name, func, scope) { + var self = this; + + if (Tools.isArray(target)) { + var i = target.length; + + while (i--) { + target[i] = self.bind(target[i], name, func, scope); + } + + return target; + } + + // Collect all window/document events bound by editor instance + if (self.settings.collect && (target === self.doc || target === self.win)) { + self.boundEvents.push([target, name, func, scope]); + } + + return self.events.bind(target, name, func, scope || self); + }, + + /** + * Removes the specified event handler by name and function from an element or collection of elements. + * + * @method unbind + * @param {Element/Document/Window/Array} target Target element to unbind events on. + * @param {String} name Event handler name, for example: "click" + * @param {function} func Function to remove. + * @return {bool/Array} Bool state of true if the handler was removed, or an array of states if multiple input elements + * were passed in. + */ + unbind: function(target, name, func) { + var self = this, i; + + if (Tools.isArray(target)) { + i = target.length; + + while (i--) { + target[i] = self.unbind(target[i], name, func); + } + + return target; + } + + // Remove any bound events matching the input + if (self.boundEvents && (target === self.doc || target === self.win)) { + i = self.boundEvents.length; + + while (i--) { + var item = self.boundEvents[i]; + + if (target == item[0] && (!name || name == item[1]) && (!func || func == item[2])) { + this.events.unbind(item[0], item[1], item[2]); + } + } + } + + return this.events.unbind(target, name, func); + }, + + /** + * Fires the specified event name with object on target. + * + * @method fire + * @param {Node/Document/Window} target Target element or object to fire event on. + * @param {String} name Name of the event to fire. + * @param {Object} evt Event object to send. + * @return {Event} Event object. + */ + fire: function(target, name, evt) { + return this.events.fire(target, name, evt); + }, + + // Returns the content editable state of a node + getContentEditable: function(node) { + var contentEditable; + + // Check type + if (!node || node.nodeType != 1) { + return null; + } + + // Check for fake content editable + contentEditable = node.getAttribute("data-mce-contenteditable"); + if (contentEditable && contentEditable !== "inherit") { + return contentEditable; + } + + // Check for real content editable + return node.contentEditable !== "inherit" ? node.contentEditable : null; + }, + + getContentEditableParent: function(node) { + var root = this.getRoot(), state = null; + + for (; node && node !== root; node = node.parentNode) { + state = this.getContentEditable(node); + + if (state !== null) { + break; + } + } + + return state; + }, + + /** + * Destroys all internal references to the DOM to solve IE leak issues. + * + * @method destroy + */ + destroy: function() { + var self = this; + + // Unbind all events bound to window/document by editor instance + if (self.boundEvents) { + var i = self.boundEvents.length; + + while (i--) { + var item = self.boundEvents[i]; + this.events.unbind(item[0], item[1], item[2]); + } + + self.boundEvents = null; + } + + // Restore sizzle document to window.document + // Since the current document might be removed producing "Permission denied" on IE see #6325 + if (Sizzle.setDocument) { + Sizzle.setDocument(); + } + + self.win = self.doc = self.root = self.events = self.frag = null; + }, + + isChildOf: function(node, parent) { + while (node) { + if (parent === node) { + return true; + } + + node = node.parentNode; + } + + return false; + }, + + // #ifdef debug + + dumpRng: function(r) { + return ( + 'startContainer: ' + r.startContainer.nodeName + + ', startOffset: ' + r.startOffset + + ', endContainer: ' + r.endContainer.nodeName + + ', endOffset: ' + r.endOffset + ); + }, + + // #endif + + _findSib: function(node, selector, name) { + var self = this, func = selector; + + if (node) { + // If expression make a function of it using is + if (typeof func == 'string') { + func = function(node) { + return self.is(node, selector); + }; + } + + // Loop all siblings + for (node = node[name]; node; node = node[name]) { + if (func(node)) { + return node; + } + } + } + + return null; + } + }; + + /** + * Instance of DOMUtils for the current document. + * + * @static + * @property DOM + * @type tinymce.dom.DOMUtils + * @example + * // Example of how to add a class to some element by id + * tinymce.DOM.addClass('someid', 'someclass'); + */ + DOMUtils.DOM = new DOMUtils(document); + DOMUtils.nodeIndex = nodeIndex; + + return DOMUtils; +}); + +// Included from: js/tinymce/classes/dom/ScriptLoader.js + +/** + * ScriptLoader.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/*globals console*/ + +/** + * This class handles asynchronous/synchronous loading of JavaScript files it will execute callbacks + * when various items gets loaded. This class is useful to load external JavaScript files. + * + * @class tinymce.dom.ScriptLoader + * @example + * // Load a script from a specific URL using the global script loader + * tinymce.ScriptLoader.load('somescript.js'); + * + * // Load a script using a unique instance of the script loader + * var scriptLoader = new tinymce.dom.ScriptLoader(); + * + * scriptLoader.load('somescript.js'); + * + * // Load multiple scripts + * var scriptLoader = new tinymce.dom.ScriptLoader(); + * + * scriptLoader.add('somescript1.js'); + * scriptLoader.add('somescript2.js'); + * scriptLoader.add('somescript3.js'); + * + * scriptLoader.loadQueue(function() { + * alert('All scripts are now loaded.'); + * }); + */ +define("tinymce/dom/ScriptLoader", [ + "tinymce/dom/DOMUtils", + "tinymce/util/Tools" +], function(DOMUtils, Tools) { + var DOM = DOMUtils.DOM; + var each = Tools.each, grep = Tools.grep; + + function ScriptLoader() { + var QUEUED = 0, + LOADING = 1, + LOADED = 2, + states = {}, + queue = [], + scriptLoadedCallbacks = {}, + queueLoadedCallbacks = [], + loading = 0, + undef; + + /** + * Loads a specific script directly without adding it to the load queue. + * + * @method load + * @param {String} url Absolute URL to script to add. + * @param {function} callback Optional callback function to execute ones this script gets loaded. + */ + function loadScript(url, callback) { + var dom = DOM, elm, id; + + // Execute callback when script is loaded + function done() { + dom.remove(id); + + if (elm) { + elm.onreadystatechange = elm.onload = elm = null; + } + + callback(); + } + + function error() { + /*eslint no-console:0 */ + + // Report the error so it's easier for people to spot loading errors + if (typeof console !== "undefined" && console.log) { + console.log("Failed to load: " + url); + } + + // We can't mark it as done if there is a load error since + // A) We don't want to produce 404 errors on the server and + // B) the onerror event won't fire on all browsers. + // done(); + } + + id = dom.uniqueId(); + + // Create new script element + elm = document.createElement('script'); + elm.id = id; + elm.type = 'text/javascript'; + elm.src = Tools._addCacheSuffix(url); + + // Seems that onreadystatechange works better on IE 10 onload seems to fire incorrectly + if ("onreadystatechange" in elm) { + elm.onreadystatechange = function() { + if (/loaded|complete/.test(elm.readyState)) { + done(); + } + }; + } else { + elm.onload = done; + } + + // Add onerror event will get fired on some browsers but not all of them + elm.onerror = error; + + // Add script to document + (document.getElementsByTagName('head')[0] || document.body).appendChild(elm); + } + + /** + * Returns true/false if a script has been loaded or not. + * + * @method isDone + * @param {String} url URL to check for. + * @return {Boolean} true/false if the URL is loaded. + */ + this.isDone = function(url) { + return states[url] == LOADED; + }; + + /** + * Marks a specific script to be loaded. This can be useful if a script got loaded outside + * the script loader or to skip it from loading some script. + * + * @method markDone + * @param {string} url Absolute URL to the script to mark as loaded. + */ + this.markDone = function(url) { + states[url] = LOADED; + }; + + /** + * Adds a specific script to the load queue of the script loader. + * + * @method add + * @param {String} url Absolute URL to script to add. + * @param {function} callback Optional callback function to execute ones this script gets loaded. + * @param {Object} scope Optional scope to execute callback in. + */ + this.add = this.load = function(url, callback, scope) { + var state = states[url]; + + // Add url to load queue + if (state == undef) { + queue.push(url); + states[url] = QUEUED; + } + + if (callback) { + // Store away callback for later execution + if (!scriptLoadedCallbacks[url]) { + scriptLoadedCallbacks[url] = []; + } + + scriptLoadedCallbacks[url].push({ + func: callback, + scope: scope || this + }); + } + }; + + this.remove = function(url) { + delete states[url]; + delete scriptLoadedCallbacks[url]; + }; + + /** + * Starts the loading of the queue. + * + * @method loadQueue + * @param {function} callback Optional callback to execute when all queued items are loaded. + * @param {Object} scope Optional scope to execute the callback in. + */ + this.loadQueue = function(callback, scope) { + this.loadScripts(queue, callback, scope); + }; + + /** + * Loads the specified queue of files and executes the callback ones they are loaded. + * This method is generally not used outside this class but it might be useful in some scenarios. + * + * @method loadScripts + * @param {Array} scripts Array of queue items to load. + * @param {function} callback Optional callback to execute ones all items are loaded. + * @param {Object} scope Optional scope to execute callback in. + */ + this.loadScripts = function(scripts, callback, scope) { + var loadScripts; + + function execScriptLoadedCallbacks(url) { + // Execute URL callback functions + each(scriptLoadedCallbacks[url], function(callback) { + callback.func.call(callback.scope); + }); + + scriptLoadedCallbacks[url] = undef; + } + + queueLoadedCallbacks.push({ + func: callback, + scope: scope || this + }); + + loadScripts = function() { + var loadingScripts = grep(scripts); + + // Current scripts has been handled + scripts.length = 0; + + // Load scripts that needs to be loaded + each(loadingScripts, function(url) { + // Script is already loaded then execute script callbacks directly + if (states[url] == LOADED) { + execScriptLoadedCallbacks(url); + return; + } + + // Is script not loading then start loading it + if (states[url] != LOADING) { + states[url] = LOADING; + loading++; + + loadScript(url, function() { + states[url] = LOADED; + loading--; + + execScriptLoadedCallbacks(url); + + // Load more scripts if they where added by the recently loaded script + loadScripts(); + }); + } + }); + + // No scripts are currently loading then execute all pending queue loaded callbacks + if (!loading) { + each(queueLoadedCallbacks, function(callback) { + callback.func.call(callback.scope); + }); + + queueLoadedCallbacks.length = 0; + } + }; + + loadScripts(); + }; + } + + ScriptLoader.ScriptLoader = new ScriptLoader(); + + return ScriptLoader; +}); + +// Included from: js/tinymce/classes/AddOnManager.js + +/** + * AddOnManager.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class handles the loading of themes/plugins or other add-ons and their language packs. + * + * @class tinymce.AddOnManager + */ +define("tinymce/AddOnManager", [ + "tinymce/dom/ScriptLoader", + "tinymce/util/Tools" +], function(ScriptLoader, Tools) { + var each = Tools.each; + + function AddOnManager() { + var self = this; + + self.items = []; + self.urls = {}; + self.lookup = {}; + } + + AddOnManager.prototype = { + /** + * Returns the specified add on by the short name. + * + * @method get + * @param {String} name Add-on to look for. + * @return {tinymce.Theme/tinymce.Plugin} Theme or plugin add-on instance or undefined. + */ + get: function(name) { + if (this.lookup[name]) { + return this.lookup[name].instance; + } + + return undefined; + }, + + dependencies: function(name) { + var result; + + if (this.lookup[name]) { + result = this.lookup[name].dependencies; + } + + return result || []; + }, + + /** + * Loads a language pack for the specified add-on. + * + * @method requireLangPack + * @param {String} name Short name of the add-on. + * @param {String} languages Optional comma or space separated list of languages to check if it matches the name. + */ + requireLangPack: function(name, languages) { + var language = AddOnManager.language; + + if (language && AddOnManager.languageLoad !== false) { + if (languages) { + languages = ',' + languages + ','; + + // Load short form sv.js or long form sv_SE.js + if (languages.indexOf(',' + language.substr(0, 2) + ',') != -1) { + language = language.substr(0, 2); + } else if (languages.indexOf(',' + language + ',') == -1) { + return; + } + } + + ScriptLoader.ScriptLoader.add(this.urls[name] + '/langs/' + language + '.js'); + } + }, + + /** + * Adds a instance of the add-on by it's short name. + * + * @method add + * @param {String} id Short name/id for the add-on. + * @param {tinymce.Theme/tinymce.Plugin} addOn Theme or plugin to add. + * @return {tinymce.Theme/tinymce.Plugin} The same theme or plugin instance that got passed in. + * @example + * // Create a simple plugin + * tinymce.create('tinymce.plugins.TestPlugin', { + * TestPlugin: function(ed, url) { + * ed.on('click', function(e) { + * ed.windowManager.alert('Hello World!'); + * }); + * } + * }); + * + * // Register plugin using the add method + * tinymce.PluginManager.add('test', tinymce.plugins.TestPlugin); + * + * // Initialize TinyMCE + * tinymce.init({ + * ... + * plugins: '-test' // Init the plugin but don't try to load it + * }); + */ + add: function(id, addOn, dependencies) { + this.items.push(addOn); + this.lookup[id] = {instance: addOn, dependencies: dependencies}; + + return addOn; + }, + + remove: function(name) { + delete this.urls[name]; + delete this.lookup[name]; + }, + + createUrl: function(baseUrl, dep) { + if (typeof dep === "object") { + return dep; + } + + return {prefix: baseUrl.prefix, resource: dep, suffix: baseUrl.suffix}; + }, + + /** + * Add a set of components that will make up the add-on. Using the url of the add-on name as the base url. + * This should be used in development mode. A new compressor/javascript munger process will ensure that the + * components are put together into the plugin.js file and compressed correctly. + * + * @method addComponents + * @param {String} pluginName name of the plugin to load scripts from (will be used to get the base url for the plugins). + * @param {Array} scripts Array containing the names of the scripts to load. + */ + addComponents: function(pluginName, scripts) { + var pluginUrl = this.urls[pluginName]; + + each(scripts, function(script) { + ScriptLoader.ScriptLoader.add(pluginUrl + "/" + script); + }); + }, + + /** + * Loads an add-on from a specific url. + * + * @method load + * @param {String} name Short name of the add-on that gets loaded. + * @param {String} addOnUrl URL to the add-on that will get loaded. + * @param {function} callback Optional callback to execute ones the add-on is loaded. + * @param {Object} scope Optional scope to execute the callback in. + * @example + * // Loads a plugin from an external URL + * tinymce.PluginManager.load('myplugin', '/some/dir/someplugin/plugin.js'); + * + * // Initialize TinyMCE + * tinymce.init({ + * ... + * plugins: '-myplugin' // Don't try to load it again + * }); + */ + load: function(name, addOnUrl, callback, scope) { + var self = this, url = addOnUrl; + + function loadDependencies() { + var dependencies = self.dependencies(name); + + each(dependencies, function(dep) { + var newUrl = self.createUrl(addOnUrl, dep); + + self.load(newUrl.resource, newUrl, undefined, undefined); + }); + + if (callback) { + if (scope) { + callback.call(scope); + } else { + callback.call(ScriptLoader); + } + } + } + + if (self.urls[name]) { + return; + } + + if (typeof addOnUrl === "object") { + url = addOnUrl.prefix + addOnUrl.resource + addOnUrl.suffix; + } + + if (url.indexOf('/') !== 0 && url.indexOf('://') == -1) { + url = AddOnManager.baseURL + '/' + url; + } + + self.urls[name] = url.substring(0, url.lastIndexOf('/')); + + if (self.lookup[name]) { + loadDependencies(); + } else { + ScriptLoader.ScriptLoader.add(url, loadDependencies, scope); + } + } + }; + + AddOnManager.PluginManager = new AddOnManager(); + AddOnManager.ThemeManager = new AddOnManager(); + + return AddOnManager; +}); + +/** + * TinyMCE theme class. + * + * @class tinymce.Theme + */ + +/** + * This method is responsible for rendering/generating the overall user interface with toolbars, buttons, iframe containers etc. + * + * @method renderUI + * @param {Object} obj Object parameter containing the targetNode DOM node that will be replaced visually with an editor instance. + * @return {Object} an object with items like iframeContainer, editorContainer, sizeContainer, deltaWidth, deltaHeight. + */ + +/** + * Plugin base class, this is a pseudo class that describes how a plugin is to be created for TinyMCE. The methods below are all optional. + * + * @class tinymce.Plugin + * @example + * tinymce.PluginManager.add('example', function(editor, url) { + * // Add a button that opens a window + * editor.addButton('example', { + * text: 'My button', + * icon: false, + * onclick: function() { + * // Open window + * editor.windowManager.open({ + * title: 'Example plugin', + * body: [ + * {type: 'textbox', name: 'title', label: 'Title'} + * ], + * onsubmit: function(e) { + * // Insert content when the window form is submitted + * editor.insertContent('Title: ' + e.data.title); + * } + * }); + * } + * }); + * + * // Adds a menu item to the tools menu + * editor.addMenuItem('example', { + * text: 'Example plugin', + * context: 'tools', + * onclick: function() { + * // Open window with a specific url + * editor.windowManager.open({ + * title: 'TinyMCE site', + * url: 'http://www.tinymce.com', + * width: 800, + * height: 600, + * buttons: [{ + * text: 'Close', + * onclick: 'close' + * }] + * }); + * } + * }); + * }); + */ + +// Included from: js/tinymce/classes/dom/NodeType.js + +/** + * NodeType.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Contains various node validation functions. + * + * @private + * @class tinymce.dom.NodeType + */ +define("tinymce/dom/NodeType", [], function() { + function isNodeType(type) { + return function(node) { + return !!node && node.nodeType == type; + }; + } + + var isElement = isNodeType(1); + + function matchNodeNames(names) { + names = names.toLowerCase().split(' '); + + return function(node) { + var i, name; + + if (node && node.nodeType) { + name = node.nodeName.toLowerCase(); + + for (i = 0; i < names.length; i++) { + if (name === names[i]) { + return true; + } + } + } + + return false; + }; + } + + function matchStyleValues(name, values) { + values = values.toLowerCase().split(' '); + + return function(node) { + var i, cssValue; + + if (isElement(node)) { + for (i = 0; i < values.length; i++) { + cssValue = getComputedStyle(node, null).getPropertyValue(name); + if (cssValue === values[i]) { + return true; + } + } + } + + return false; + }; + } + + function hasPropValue(propName, propValue) { + return function(node) { + return isElement(node) && node[propName] === propValue; + }; + } + + function hasAttributeValue(attrName, attrValue) { + return function(node) { + return isElement(node) && node.getAttribute(attrName) === attrValue; + }; + } + + function isBogus(node) { + return isElement(node) && node.hasAttribute('data-mce-bogus'); + } + + function hasContentEditableState(value) { + return function(node) { + if (isElement(node)) { + if (node.contentEditable === value) { + return true; + } + + if (node.getAttribute('data-mce-contenteditable') === value) { + return true; + } + } + + return false; + }; + } + + return { + isText: isNodeType(3), + isElement: isElement, + isComment: isNodeType(8), + isBr: matchNodeNames('br'), + isContentEditableTrue: hasContentEditableState('true'), + isContentEditableFalse: hasContentEditableState('false'), + matchNodeNames: matchNodeNames, + hasPropValue: hasPropValue, + hasAttributeValue: hasAttributeValue, + matchStyleValues: matchStyleValues, + isBogus: isBogus + }; +}); + +// Included from: js/tinymce/classes/text/Zwsp.js + +/** + * Zwsp.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * .... + * + * @private + * @class tinymce.text.Zwsp + * @example + * var isZwsp = Zwsp.isZwsp('\u200b'); + * var abc = Zwsp.trim('a\u200bc'); + */ +define("tinymce/text/Zwsp", [], function() { + var ZWSP = '\u200b'; + + function isZwsp(chr) { + return chr == ZWSP; + } + + function trim(str) { + return str.replace(new RegExp(ZWSP, 'g'), ''); + } + + return { + isZwsp: isZwsp, + ZWSP: ZWSP, + trim: trim + }; +}); + +// Included from: js/tinymce/classes/caret/CaretContainer.js + +/** + * CaretContainer.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This module handles caret containers. A caret container is a node that + * holds the caret for positional purposes. + * + * @private + * @class tinymce.caret.CaretContainer + */ +define("tinymce/caret/CaretContainer", [ + "tinymce/dom/NodeType", + "tinymce/text/Zwsp" +], function(NodeType, Zwsp) { + var isElement = NodeType.isElement, + isText = NodeType.isText; + + function isCaretContainerBlock(node) { + if (isText(node)) { + node = node.parentNode; + } + + return isElement(node) && node.hasAttribute('data-mce-caret'); + } + + function isCaretContainerInline(node) { + return isText(node) && Zwsp.isZwsp(node.data); + } + + function isCaretContainer(node) { + return isCaretContainerBlock(node) || isCaretContainerInline(node); + } + + function insertInline(node, before) { + var doc, sibling, textNode, parentNode; + + doc = node.ownerDocument; + textNode = doc.createTextNode(Zwsp.ZWSP); + parentNode = node.parentNode; + + if (!before) { + sibling = node.nextSibling; + if (isText(sibling)) { + if (isCaretContainer(sibling)) { + return sibling; + } + + if (startsWithCaretContainer(sibling)) { + sibling.splitText(1); + return sibling; + } + } + + if (node.nextSibling) { + parentNode.insertBefore(textNode, node.nextSibling); + } else { + parentNode.appendChild(textNode); + } + } else { + sibling = node.previousSibling; + if (isText(sibling)) { + if (isCaretContainer(sibling)) { + return sibling; + } + + if (endsWithCaretContainer(sibling)) { + return sibling.splitText(sibling.data.length - 1); + } + } + + parentNode.insertBefore(textNode, node); + } + + return textNode; + } + + function insertBlock(blockName, node, before) { + var doc, blockNode, parentNode; + + doc = node.ownerDocument; + blockNode = doc.createElement(blockName); + blockNode.setAttribute('data-mce-caret', before ? 'before' : 'after'); + blockNode.setAttribute('data-mce-bogus', 'all'); + blockNode.appendChild(doc.createTextNode('\u00a0')); + parentNode = node.parentNode; + + if (!before) { + if (node.nextSibling) { + parentNode.insertBefore(blockNode, node.nextSibling); + } else { + parentNode.appendChild(blockNode); + } + } else { + parentNode.insertBefore(blockNode, node); + } + + return blockNode; + } + + function remove(caretContainerNode) { + var text; + + if (isElement(caretContainerNode) && isCaretContainer(caretContainerNode)) { + if (caretContainerNode.innerHTML != ' ') { + caretContainerNode.removeAttribute('data-mce-caret'); + } else { + if (caretContainerNode.parentNode) { + caretContainerNode.parentNode.removeChild(caretContainerNode); + } + } + } + + if (isText(caretContainerNode)) { + text = Zwsp.trim(caretContainerNode.data); + + if (text.length === 0) { + if (caretContainerNode.parentNode) { + caretContainerNode.parentNode.removeChild(caretContainerNode); + } + } + + caretContainerNode.nodeValue = text; + } + } + + function startsWithCaretContainer(node) { + return isText(node) && node.data[0] == Zwsp.ZWSP; + } + + function endsWithCaretContainer(node) { + return isText(node) && node.data[node.data.length - 1] == Zwsp.ZWSP; + } + + return { + isCaretContainer: isCaretContainer, + isCaretContainerBlock: isCaretContainerBlock, + isCaretContainerInline: isCaretContainerInline, + insertInline: insertInline, + insertBlock: insertBlock, + remove: remove, + startsWithCaretContainer: startsWithCaretContainer, + endsWithCaretContainer: endsWithCaretContainer + }; +}); + +// Included from: js/tinymce/classes/dom/RangeUtils.js + +/** + * RangeUtils.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class contains a few utility methods for ranges. + * + * @class tinymce.dom.RangeUtils + */ +define("tinymce/dom/RangeUtils", [ + "tinymce/util/Tools", + "tinymce/dom/TreeWalker", + "tinymce/dom/NodeType", + "tinymce/caret/CaretContainer" +], function(Tools, TreeWalker, NodeType, CaretContainer) { + var each = Tools.each, + isContentEditableFalse = NodeType.isContentEditableFalse, + isCaretContainer = CaretContainer.isCaretContainer; + + function getEndChild(container, index) { + var childNodes = container.childNodes; + + index--; + + if (index > childNodes.length - 1) { + index = childNodes.length - 1; + } else if (index < 0) { + index = 0; + } + + return childNodes[index] || container; + } + + function RangeUtils(dom) { + /** + * Walks the specified range like object and executes the callback for each sibling collection it finds. + * + * @private + * @method walk + * @param {Object} rng Range like object. + * @param {function} callback Callback function to execute for each sibling collection. + */ + this.walk = function(rng, callback) { + var startContainer = rng.startContainer, + startOffset = rng.startOffset, + endContainer = rng.endContainer, + endOffset = rng.endOffset, + ancestor, startPoint, + endPoint, node, parent, siblings, nodes; + + // Handle table cell selection the table plugin enables + // you to fake select table cells and perform formatting actions on them + nodes = dom.select('td[data-mce-selected],th[data-mce-selected]'); + if (nodes.length > 0) { + each(nodes, function(node) { + callback([node]); + }); + + return; + } + + /** + * Excludes start/end text node if they are out side the range + * + * @private + * @param {Array} nodes Nodes to exclude items from. + * @return {Array} Array with nodes excluding the start/end container if needed. + */ + function exclude(nodes) { + var node; + + // First node is excluded + node = nodes[0]; + if (node.nodeType === 3 && node === startContainer && startOffset >= node.nodeValue.length) { + nodes.splice(0, 1); + } + + // Last node is excluded + node = nodes[nodes.length - 1]; + if (endOffset === 0 && nodes.length > 0 && node === endContainer && node.nodeType === 3) { + nodes.splice(nodes.length - 1, 1); + } + + return nodes; + } + + /** + * Collects siblings + * + * @private + * @param {Node} node Node to collect siblings from. + * @param {String} name Name of the sibling to check for. + * @param {Node} end_node + * @return {Array} Array of collected siblings. + */ + function collectSiblings(node, name, end_node) { + var siblings = []; + + for (; node && node != end_node; node = node[name]) { + siblings.push(node); + } + + return siblings; + } + + /** + * Find an end point this is the node just before the common ancestor root. + * + * @private + * @param {Node} node Node to start at. + * @param {Node} root Root/ancestor element to stop just before. + * @return {Node} Node just before the root element. + */ + function findEndPoint(node, root) { + do { + if (node.parentNode == root) { + return node; + } + + node = node.parentNode; + } while (node); + } + + function walkBoundary(start_node, end_node, next) { + var siblingName = next ? 'nextSibling' : 'previousSibling'; + + for (node = start_node, parent = node.parentNode; node && node != end_node; node = parent) { + parent = node.parentNode; + siblings = collectSiblings(node == start_node ? node : node[siblingName], siblingName); + + if (siblings.length) { + if (!next) { + siblings.reverse(); + } + + callback(exclude(siblings)); + } + } + } + + // If index based start position then resolve it + if (startContainer.nodeType == 1 && startContainer.hasChildNodes()) { + startContainer = startContainer.childNodes[startOffset]; + } + + // If index based end position then resolve it + if (endContainer.nodeType == 1 && endContainer.hasChildNodes()) { + endContainer = getEndChild(endContainer, endOffset); + } + + // Same container + if (startContainer == endContainer) { + return callback(exclude([startContainer])); + } + + // Find common ancestor and end points + ancestor = dom.findCommonAncestor(startContainer, endContainer); + + // Process left side + for (node = startContainer; node; node = node.parentNode) { + if (node === endContainer) { + return walkBoundary(startContainer, ancestor, true); + } + + if (node === ancestor) { + break; + } + } + + // Process right side + for (node = endContainer; node; node = node.parentNode) { + if (node === startContainer) { + return walkBoundary(endContainer, ancestor); + } + + if (node === ancestor) { + break; + } + } + + // Find start/end point + startPoint = findEndPoint(startContainer, ancestor) || startContainer; + endPoint = findEndPoint(endContainer, ancestor) || endContainer; + + // Walk left leaf + walkBoundary(startContainer, startPoint, true); + + // Walk the middle from start to end point + siblings = collectSiblings( + startPoint == startContainer ? startPoint : startPoint.nextSibling, + 'nextSibling', + endPoint == endContainer ? endPoint.nextSibling : endPoint + ); + + if (siblings.length) { + callback(exclude(siblings)); + } + + // Walk right leaf + walkBoundary(endContainer, endPoint); + }; + + /** + * Splits the specified range at it's start/end points. + * + * @private + * @param {Range/RangeObject} rng Range to split. + * @return {Object} Range position object. + */ + this.split = function(rng) { + var startContainer = rng.startContainer, + startOffset = rng.startOffset, + endContainer = rng.endContainer, + endOffset = rng.endOffset; + + function splitText(node, offset) { + return node.splitText(offset); + } + + // Handle single text node + if (startContainer == endContainer && startContainer.nodeType == 3) { + if (startOffset > 0 && startOffset < startContainer.nodeValue.length) { + endContainer = splitText(startContainer, startOffset); + startContainer = endContainer.previousSibling; + + if (endOffset > startOffset) { + endOffset = endOffset - startOffset; + startContainer = endContainer = splitText(endContainer, endOffset).previousSibling; + endOffset = endContainer.nodeValue.length; + startOffset = 0; + } else { + endOffset = 0; + } + } + } else { + // Split startContainer text node if needed + if (startContainer.nodeType == 3 && startOffset > 0 && startOffset < startContainer.nodeValue.length) { + startContainer = splitText(startContainer, startOffset); + startOffset = 0; + } + + // Split endContainer text node if needed + if (endContainer.nodeType == 3 && endOffset > 0 && endOffset < endContainer.nodeValue.length) { + endContainer = splitText(endContainer, endOffset).previousSibling; + endOffset = endContainer.nodeValue.length; + } + } + + return { + startContainer: startContainer, + startOffset: startOffset, + endContainer: endContainer, + endOffset: endOffset + }; + }; + + /** + * Normalizes the specified range by finding the closest best suitable caret location. + * + * @private + * @param {Range} rng Range to normalize. + * @return {Boolean} True/false if the specified range was normalized or not. + */ + this.normalize = function(rng) { + var normalized, collapsed; + + function normalizeEndPoint(start) { + var container, offset, walker, body = dom.getRoot(), node, nonEmptyElementsMap; + var directionLeft, isAfterNode; + + function isTableCell(node) { + return node && /^(TD|TH|CAPTION)$/.test(node.nodeName); + } + + function hasBrBeforeAfter(node, left) { + var walker = new TreeWalker(node, dom.getParent(node.parentNode, dom.isBlock) || body); + + while ((node = walker[left ? 'prev' : 'next']())) { + if (node.nodeName === "BR") { + return true; + } + } + } + + function hasContentEditableFalseParent(node) { + while (node && node != body) { + if (isContentEditableFalse(node)) { + return true; + } + + node = node.parentNode; + } + + return false; + } + + function isPrevNode(node, name) { + return node.previousSibling && node.previousSibling.nodeName == name; + } + + // Walks the dom left/right to find a suitable text node to move the endpoint into + // It will only walk within the current parent block or body and will stop if it hits a block or a BR/IMG + function findTextNodeRelative(left, startNode) { + var walker, lastInlineElement, parentBlockContainer; + + startNode = startNode || container; + parentBlockContainer = dom.getParent(startNode.parentNode, dom.isBlock) || body; + + // Lean left before the BR element if it's the only BR within a block element. Gecko bug: #6680 + // This: <p><br>|</p> becomes <p>|<br></p> + if (left && startNode.nodeName == 'BR' && isAfterNode && dom.isEmpty(parentBlockContainer)) { + container = startNode.parentNode; + offset = dom.nodeIndex(startNode); + normalized = true; + return; + } + + // Walk left until we hit a text node we can move to or a block/br/img + walker = new TreeWalker(startNode, parentBlockContainer); + while ((node = walker[left ? 'prev' : 'next']())) { + // Break if we hit a non content editable node + if (dom.getContentEditableParent(node) === "false" || isCaretContainer(node)) { + return; + } + + // Found text node that has a length + if (node.nodeType === 3 && node.nodeValue.length > 0) { + container = node; + offset = left ? node.nodeValue.length : 0; + normalized = true; + return; + } + + // Break if we find a block or a BR/IMG/INPUT etc + if (dom.isBlock(node) || nonEmptyElementsMap[node.nodeName.toLowerCase()]) { + return; + } + + lastInlineElement = node; + } + + // Only fetch the last inline element when in caret mode for now + if (collapsed && lastInlineElement) { + container = lastInlineElement; + normalized = true; + offset = 0; + } + } + + container = rng[(start ? 'start' : 'end') + 'Container']; + offset = rng[(start ? 'start' : 'end') + 'Offset']; + isAfterNode = container.nodeType == 1 && offset === container.childNodes.length; + nonEmptyElementsMap = dom.schema.getNonEmptyElements(); + directionLeft = start; + + if (isCaretContainer(container)) { + return; + } + + if (container.nodeType == 1 && offset > container.childNodes.length - 1) { + directionLeft = false; + } + + // If the container is a document move it to the body element + if (container.nodeType === 9) { + container = dom.getRoot(); + offset = 0; + } + + // If the container is body try move it into the closest text node or position + if (container === body) { + // If start is before/after a image, table etc + if (directionLeft) { + node = container.childNodes[offset > 0 ? offset - 1 : 0]; + if (node) { + if (isCaretContainer(node)) { + return; + } + + if (nonEmptyElementsMap[node.nodeName] || node.nodeName == "TABLE") { + return; + } + } + } + + // Resolve the index + if (container.hasChildNodes()) { + offset = Math.min(!directionLeft && offset > 0 ? offset - 1 : offset, container.childNodes.length - 1); + container = container.childNodes[offset]; + offset = 0; + + if (hasContentEditableFalseParent(container) || isCaretContainer(container)) { + return; + } + + // Don't walk into elements that doesn't have any child nodes like a IMG + if (container.hasChildNodes() && !/TABLE/.test(container.nodeName)) { + // Walk the DOM to find a text node to place the caret at or a BR + node = container; + walker = new TreeWalker(container, body); + + do { + if (isContentEditableFalse(node) || isCaretContainer(node)) { + normalized = false; + break; + } + + // Found a text node use that position + if (node.nodeType === 3 && node.nodeValue.length > 0) { + offset = directionLeft ? 0 : node.nodeValue.length; + container = node; + normalized = true; + break; + } + + // Found a BR/IMG element that we can place the caret before + if (nonEmptyElementsMap[node.nodeName.toLowerCase()] && !isTableCell(node)) { + offset = dom.nodeIndex(node); + container = node.parentNode; + + // Put caret after image when moving the end point + if (node.nodeName == "IMG" && !directionLeft) { + offset++; + } + + normalized = true; + break; + } + } while ((node = (directionLeft ? walker.next() : walker.prev()))); + } + } + } + + // Lean the caret to the left if possible + if (collapsed) { + // So this: <b>x</b><i>|x</i> + // Becomes: <b>x|</b><i>x</i> + // Seems that only gecko has issues with this + if (container.nodeType === 3 && offset === 0) { + findTextNodeRelative(true); + } + + // Lean left into empty inline elements when the caret is before a BR + // So this: <i><b></b><i>|<br></i> + // Becomes: <i><b>|</b><i><br></i> + // Seems that only gecko has issues with this. + // Special edge case for <p><a>x</a>|<br></p> since we don't want <p><a>x|</a><br></p> + if (container.nodeType === 1) { + node = container.childNodes[offset]; + + // Offset is after the containers last child + // then use the previous child for normalization + if (!node) { + node = container.childNodes[offset - 1]; + } + + if (node && node.nodeName === 'BR' && !isPrevNode(node, 'A') && + !hasBrBeforeAfter(node) && !hasBrBeforeAfter(node, true)) { + findTextNodeRelative(true, node); + } + } + } + + // Lean the start of the selection right if possible + // So this: x[<b>x]</b> + // Becomes: x<b>[x]</b> + if (directionLeft && !collapsed && container.nodeType === 3 && offset === container.nodeValue.length) { + findTextNodeRelative(false); + } + + // Set endpoint if it was normalized + if (normalized) { + rng['set' + (start ? 'Start' : 'End')](container, offset); + } + } + + collapsed = rng.collapsed; + + normalizeEndPoint(true); + + if (!collapsed) { + normalizeEndPoint(); + } + + // If it was collapsed then make sure it still is + if (normalized && collapsed) { + rng.collapse(true); + } + + return normalized; + }; + } + + /** + * Compares two ranges and checks if they are equal. + * + * @static + * @method compareRanges + * @param {DOMRange} rng1 First range to compare. + * @param {DOMRange} rng2 First range to compare. + * @return {Boolean} true/false if the ranges are equal. + */ + RangeUtils.compareRanges = function(rng1, rng2) { + if (rng1 && rng2) { + // Compare native IE ranges + if (rng1.item || rng1.duplicate) { + // Both are control ranges and the selected element matches + if (rng1.item && rng2.item && rng1.item(0) === rng2.item(0)) { + return true; + } + + // Both are text ranges and the range matches + if (rng1.isEqual && rng2.isEqual && rng2.isEqual(rng1)) { + return true; + } + } else { + // Compare w3c ranges + return rng1.startContainer == rng2.startContainer && rng1.startOffset == rng2.startOffset; + } + } + + return false; + }; + + /** + * Finds the closest selection rect tries to get the range from that. + */ + function findClosestIeRange(clientX, clientY, doc) { + var element, rng, rects; + + element = doc.elementFromPoint(clientX, clientY); + rng = doc.body.createTextRange(); + + if (!element || element.tagName == 'HTML') { + element = doc.body; + } + + rng.moveToElementText(element); + rects = Tools.toArray(rng.getClientRects()); + + rects = rects.sort(function(a, b) { + a = Math.abs(Math.max(a.top - clientY, a.bottom - clientY)); + b = Math.abs(Math.max(b.top - clientY, b.bottom - clientY)); + + return a - b; + }); + + if (rects.length > 0) { + clientY = (rects[0].bottom + rects[0].top) / 2; + + try { + rng.moveToPoint(clientX, clientY); + rng.collapse(true); + + return rng; + } catch (ex) { + // At least we tried + } + } + + return null; + } + + /** + * Gets the caret range for the given x/y location. + * + * @static + * @method getCaretRangeFromPoint + * @param {Number} clientX X coordinate for range + * @param {Number} clientY Y coordinate for range + * @param {Document} doc Document that x/y are relative to + * @returns {Range} caret range + */ + RangeUtils.getCaretRangeFromPoint = function(clientX, clientY, doc) { + var rng, point; + + if (doc.caretPositionFromPoint) { + point = doc.caretPositionFromPoint(clientX, clientY); + rng = doc.createRange(); + rng.setStart(point.offsetNode, point.offset); + rng.collapse(true); + } else if (doc.caretRangeFromPoint) { + rng = doc.caretRangeFromPoint(clientX, clientY); + } else if (doc.body.createTextRange) { + rng = doc.body.createTextRange(); + + try { + rng.moveToPoint(clientX, clientY); + rng.collapse(true); + } catch (ex) { + rng = findClosestIeRange(clientX, clientY, doc); + } + } + + return rng; + }; + + RangeUtils.getSelectedNode = function(range) { + var startContainer = range.startContainer, + startOffset = range.startOffset; + + if (startContainer.hasChildNodes() && range.endOffset == startOffset + 1) { + return startContainer.childNodes[startOffset]; + } + + return null; + }; + + RangeUtils.getNode = function(container, offset) { + if (container.nodeType == 1 && container.hasChildNodes()) { + if (offset >= container.childNodes.length) { + offset = container.childNodes.length - 1; + } + + container = container.childNodes[offset]; + } + + return container; + }; + + return RangeUtils; +}); + +// Included from: js/tinymce/classes/NodeChange.js + +/** + * NodeChange.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class handles the nodechange event dispatching both manual and through selection change events. + * + * @class tinymce.NodeChange + * @private + */ +define("tinymce/NodeChange", [ + "tinymce/dom/RangeUtils", + "tinymce/Env", + "tinymce/util/Delay" +], function(RangeUtils, Env, Delay) { + return function(editor) { + var lastRng, lastPath = []; + + /** + * Returns true/false if the current element path has been changed or not. + * + * @private + * @return {Boolean} True if the element path is the same false if it's not. + */ + function isSameElementPath(startElm) { + var i, currentPath; + + currentPath = editor.$(startElm).parentsUntil(editor.getBody()).add(startElm); + if (currentPath.length === lastPath.length) { + for (i = currentPath.length; i >= 0; i--) { + if (currentPath[i] !== lastPath[i]) { + break; + } + } + + if (i === -1) { + lastPath = currentPath; + return true; + } + } + + lastPath = currentPath; + + return false; + } + + // Gecko doesn't support the "selectionchange" event + if (!('onselectionchange' in editor.getDoc())) { + editor.on('NodeChange Click MouseUp KeyUp Focus', function(e) { + var nativeRng, fakeRng; + + // Since DOM Ranges mutate on modification + // of the DOM we need to clone it's contents + nativeRng = editor.selection.getRng(); + fakeRng = { + startContainer: nativeRng.startContainer, + startOffset: nativeRng.startOffset, + endContainer: nativeRng.endContainer, + endOffset: nativeRng.endOffset + }; + + // Always treat nodechange as a selectionchange since applying + // formatting to the current range wouldn't update the range but it's parent + if (e.type == 'nodechange' || !RangeUtils.compareRanges(fakeRng, lastRng)) { + editor.fire('SelectionChange'); + } + + lastRng = fakeRng; + }); + } + + // IE has a bug where it fires a selectionchange on right click that has a range at the start of the body + // When the contextmenu event fires the selection is located at the right location + editor.on('contextmenu', function() { + editor.fire('SelectionChange'); + }); + + // Selection change is delayed ~200ms on IE when you click inside the current range + editor.on('SelectionChange', function() { + var startElm = editor.selection.getStart(true); + + // IE 8 will fire a selectionchange event with an incorrect selection + // when focusing out of table cells. Click inside cell -> toolbar = Invalid SelectionChange event + if (!Env.range && editor.selection.isCollapsed()) { + return; + } + + if (!isSameElementPath(startElm) && editor.dom.isChildOf(startElm, editor.getBody())) { + editor.nodeChanged({selectionChange: true}); + } + }); + + // Fire an extra nodeChange on mouseup for compatibility reasons + editor.on('MouseUp', function(e) { + if (!e.isDefaultPrevented()) { + // Delay nodeChanged call for WebKit edge case issue where the range + // isn't updated until after you click outside a selected image + if (editor.selection.getNode().nodeName == 'IMG') { + Delay.setEditorTimeout(editor, function() { + editor.nodeChanged(); + }); + } else { + editor.nodeChanged(); + } + } + }); + + /** + * Dispatches out a onNodeChange event to all observers. This method should be called when you + * need to update the UI states or element path etc. + * + * @method nodeChanged + * @param {Object} args Optional args to pass to NodeChange event handlers. + */ + this.nodeChanged = function(args) { + var selection = editor.selection, node, parents, root; + + // Fix for bug #1896577 it seems that this can not be fired while the editor is loading + if (editor.initialized && selection && !editor.settings.disable_nodechange && !editor.readonly) { + // Get start node + root = editor.getBody(); + node = selection.getStart() || root; + + // Make sure the node is within the editor root or is the editor root + if (node.ownerDocument != editor.getDoc() || !editor.dom.isChildOf(node, root)) { + node = root; + } + + // Edge case for <p>|<img></p> + if (node.nodeName == 'IMG' && selection.isCollapsed()) { + node = node.parentNode; + } + + // Get parents and add them to object + parents = []; + editor.dom.getParent(node, function(node) { + if (node === root) { + return true; + } + + parents.push(node); + }); + + args = args || {}; + args.element = node; + args.parents = parents; + + editor.fire('NodeChange', args); + } + }; + }; +}); + +// Included from: js/tinymce/classes/html/Node.js + +/** + * Node.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class is a minimalistic implementation of a DOM like node used by the DomParser class. + * + * @example + * var node = new tinymce.html.Node('strong', 1); + * someRoot.append(node); + * + * @class tinymce.html.Node + * @version 3.4 + */ +define("tinymce/html/Node", [], function() { + var whiteSpaceRegExp = /^[ \t\r\n]*$/, typeLookup = { + '#text': 3, + '#comment': 8, + '#cdata': 4, + '#pi': 7, + '#doctype': 10, + '#document-fragment': 11 + }; + + // Walks the tree left/right + function walk(node, root_node, prev) { + var sibling, parent, startName = prev ? 'lastChild' : 'firstChild', siblingName = prev ? 'prev' : 'next'; + + // Walk into nodes if it has a start + if (node[startName]) { + return node[startName]; + } + + // Return the sibling if it has one + if (node !== root_node) { + sibling = node[siblingName]; + + if (sibling) { + return sibling; + } + + // Walk up the parents to look for siblings + for (parent = node.parent; parent && parent !== root_node; parent = parent.parent) { + sibling = parent[siblingName]; + + if (sibling) { + return sibling; + } + } + } + } + + /** + * Constructs a new Node instance. + * + * @constructor + * @method Node + * @param {String} name Name of the node type. + * @param {Number} type Numeric type representing the node. + */ + function Node(name, type) { + this.name = name; + this.type = type; + + if (type === 1) { + this.attributes = []; + this.attributes.map = {}; + } + } + + Node.prototype = { + /** + * Replaces the current node with the specified one. + * + * @example + * someNode.replace(someNewNode); + * + * @method replace + * @param {tinymce.html.Node} node Node to replace the current node with. + * @return {tinymce.html.Node} The old node that got replaced. + */ + replace: function(node) { + var self = this; + + if (node.parent) { + node.remove(); + } + + self.insert(node, self); + self.remove(); + + return self; + }, + + /** + * Gets/sets or removes an attribute by name. + * + * @example + * someNode.attr("name", "value"); // Sets an attribute + * console.log(someNode.attr("name")); // Gets an attribute + * someNode.attr("name", null); // Removes an attribute + * + * @method attr + * @param {String} name Attribute name to set or get. + * @param {String} value Optional value to set. + * @return {String/tinymce.html.Node} String or undefined on a get operation or the current node on a set operation. + */ + attr: function(name, value) { + var self = this, attrs, i, undef; + + if (typeof name !== "string") { + for (i in name) { + self.attr(i, name[i]); + } + + return self; + } + + if ((attrs = self.attributes)) { + if (value !== undef) { + // Remove attribute + if (value === null) { + if (name in attrs.map) { + delete attrs.map[name]; + + i = attrs.length; + while (i--) { + if (attrs[i].name === name) { + attrs = attrs.splice(i, 1); + return self; + } + } + } + + return self; + } + + // Set attribute + if (name in attrs.map) { + // Set attribute + i = attrs.length; + while (i--) { + if (attrs[i].name === name) { + attrs[i].value = value; + break; + } + } + } else { + attrs.push({name: name, value: value}); + } + + attrs.map[name] = value; + + return self; + } + + return attrs.map[name]; + } + }, + + /** + * Does a shallow clones the node into a new node. It will also exclude id attributes since + * there should only be one id per document. + * + * @example + * var clonedNode = node.clone(); + * + * @method clone + * @return {tinymce.html.Node} New copy of the original node. + */ + clone: function() { + var self = this, clone = new Node(self.name, self.type), i, l, selfAttrs, selfAttr, cloneAttrs; + + // Clone element attributes + if ((selfAttrs = self.attributes)) { + cloneAttrs = []; + cloneAttrs.map = {}; + + for (i = 0, l = selfAttrs.length; i < l; i++) { + selfAttr = selfAttrs[i]; + + // Clone everything except id + if (selfAttr.name !== 'id') { + cloneAttrs[cloneAttrs.length] = {name: selfAttr.name, value: selfAttr.value}; + cloneAttrs.map[selfAttr.name] = selfAttr.value; + } + } + + clone.attributes = cloneAttrs; + } + + clone.value = self.value; + clone.shortEnded = self.shortEnded; + + return clone; + }, + + /** + * Wraps the node in in another node. + * + * @example + * node.wrap(wrapperNode); + * + * @method wrap + */ + wrap: function(wrapper) { + var self = this; + + self.parent.insert(wrapper, self); + wrapper.append(self); + + return self; + }, + + /** + * Unwraps the node in other words it removes the node but keeps the children. + * + * @example + * node.unwrap(); + * + * @method unwrap + */ + unwrap: function() { + var self = this, node, next; + + for (node = self.firstChild; node;) { + next = node.next; + self.insert(node, self, true); + node = next; + } + + self.remove(); + }, + + /** + * Removes the node from it's parent. + * + * @example + * node.remove(); + * + * @method remove + * @return {tinymce.html.Node} Current node that got removed. + */ + remove: function() { + var self = this, parent = self.parent, next = self.next, prev = self.prev; + + if (parent) { + if (parent.firstChild === self) { + parent.firstChild = next; + + if (next) { + next.prev = null; + } + } else { + prev.next = next; + } + + if (parent.lastChild === self) { + parent.lastChild = prev; + + if (prev) { + prev.next = null; + } + } else { + next.prev = prev; + } + + self.parent = self.next = self.prev = null; + } + + return self; + }, + + /** + * Appends a new node as a child of the current node. + * + * @example + * node.append(someNode); + * + * @method append + * @param {tinymce.html.Node} node Node to append as a child of the current one. + * @return {tinymce.html.Node} The node that got appended. + */ + append: function(node) { + var self = this, last; + + if (node.parent) { + node.remove(); + } + + last = self.lastChild; + if (last) { + last.next = node; + node.prev = last; + self.lastChild = node; + } else { + self.lastChild = self.firstChild = node; + } + + node.parent = self; + + return node; + }, + + /** + * Inserts a node at a specific position as a child of the current node. + * + * @example + * parentNode.insert(newChildNode, oldChildNode); + * + * @method insert + * @param {tinymce.html.Node} node Node to insert as a child of the current node. + * @param {tinymce.html.Node} ref_node Reference node to set node before/after. + * @param {Boolean} before Optional state to insert the node before the reference node. + * @return {tinymce.html.Node} The node that got inserted. + */ + insert: function(node, ref_node, before) { + var parent; + + if (node.parent) { + node.remove(); + } + + parent = ref_node.parent || this; + + if (before) { + if (ref_node === parent.firstChild) { + parent.firstChild = node; + } else { + ref_node.prev.next = node; + } + + node.prev = ref_node.prev; + node.next = ref_node; + ref_node.prev = node; + } else { + if (ref_node === parent.lastChild) { + parent.lastChild = node; + } else { + ref_node.next.prev = node; + } + + node.next = ref_node.next; + node.prev = ref_node; + ref_node.next = node; + } + + node.parent = parent; + + return node; + }, + + /** + * Get all children by name. + * + * @method getAll + * @param {String} name Name of the child nodes to collect. + * @return {Array} Array with child nodes matchin the specified name. + */ + getAll: function(name) { + var self = this, node, collection = []; + + for (node = self.firstChild; node; node = walk(node, self)) { + if (node.name === name) { + collection.push(node); + } + } + + return collection; + }, + + /** + * Removes all children of the current node. + * + * @method empty + * @return {tinymce.html.Node} The current node that got cleared. + */ + empty: function() { + var self = this, nodes, i, node; + + // Remove all children + if (self.firstChild) { + nodes = []; + + // Collect the children + for (node = self.firstChild; node; node = walk(node, self)) { + nodes.push(node); + } + + // Remove the children + i = nodes.length; + while (i--) { + node = nodes[i]; + node.parent = node.firstChild = node.lastChild = node.next = node.prev = null; + } + } + + self.firstChild = self.lastChild = null; + + return self; + }, + + /** + * Returns true/false if the node is to be considered empty or not. + * + * @example + * node.isEmpty({img: true}); + * @method isEmpty + * @param {Object} elements Name/value object with elements that are automatically treated as non empty elements. + * @return {Boolean} true/false if the node is empty or not. + */ + isEmpty: function(elements) { + var self = this, node = self.firstChild, i, name; + + if (node) { + do { + if (node.type === 1) { + // Ignore bogus elements + if (node.attributes.map['data-mce-bogus']) { + continue; + } + + // Keep empty elements like <img /> + if (elements[node.name]) { + return false; + } + + // Keep bookmark nodes and name attribute like <a name="1"></a> + i = node.attributes.length; + while (i--) { + name = node.attributes[i].name; + if (name === "name" || name.indexOf('data-mce-bookmark') === 0) { + return false; + } + } + } + + // Keep comments + if (node.type === 8) { + return false; + } + + // Keep non whitespace text nodes + if ((node.type === 3 && !whiteSpaceRegExp.test(node.value))) { + return false; + } + } while ((node = walk(node, self))); + } + + return true; + }, + + /** + * Walks to the next or previous node and returns that node or null if it wasn't found. + * + * @method walk + * @param {Boolean} prev Optional previous node state defaults to false. + * @return {tinymce.html.Node} Node that is next to or previous of the current node. + */ + walk: function(prev) { + return walk(this, null, prev); + } + }; + + /** + * Creates a node of a specific type. + * + * @static + * @method create + * @param {String} name Name of the node type to create for example "b" or "#text". + * @param {Object} attrs Name/value collection of attributes that will be applied to elements. + */ + Node.create = function(name, attrs) { + var node, attrName; + + // Create node + node = new Node(name, typeLookup[name] || 1); + + // Add attributes if needed + if (attrs) { + for (attrName in attrs) { + node.attr(attrName, attrs[attrName]); + } + } + + return node; + }; + + return Node; +}); + +// Included from: js/tinymce/classes/html/Schema.js + +/** + * Schema.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Schema validator class. + * + * @class tinymce.html.Schema + * @example + * if (tinymce.activeEditor.schema.isValidChild('p', 'span')) + * alert('span is valid child of p.'); + * + * if (tinymce.activeEditor.schema.getElementRule('p')) + * alert('P is a valid element.'); + * + * @class tinymce.html.Schema + * @version 3.4 + */ +define("tinymce/html/Schema", [ + "tinymce/util/Tools" +], function(Tools) { + var mapCache = {}, dummyObj = {}; + var makeMap = Tools.makeMap, each = Tools.each, extend = Tools.extend, explode = Tools.explode, inArray = Tools.inArray; + + function split(items, delim) { + return items ? items.split(delim || ' ') : []; + } + + /** + * Builds a schema lookup table + * + * @private + * @param {String} type html4, html5 or html5-strict schema type. + * @return {Object} Schema lookup table. + */ + function compileSchema(type) { + var schema = {}, globalAttributes, blockContent; + var phrasingContent, flowContent, html4BlockContent, html4PhrasingContent; + + function add(name, attributes, children) { + var ni, i, attributesOrder, args = arguments; + + function arrayToMap(array, obj) { + var map = {}, i, l; + + for (i = 0, l = array.length; i < l; i++) { + map[array[i]] = obj || {}; + } + + return map; + } + + children = children || []; + attributes = attributes || ""; + + if (typeof children === "string") { + children = split(children); + } + + // Split string children + for (i = 3; i < args.length; i++) { + if (typeof args[i] === "string") { + args[i] = split(args[i]); + } + + children.push.apply(children, args[i]); + } + + name = split(name); + ni = name.length; + while (ni--) { + attributesOrder = [].concat(globalAttributes, split(attributes)); + schema[name[ni]] = { + attributes: arrayToMap(attributesOrder), + attributesOrder: attributesOrder, + children: arrayToMap(children, dummyObj) + }; + } + } + + function addAttrs(name, attributes) { + var ni, schemaItem, i, l; + + name = split(name); + ni = name.length; + attributes = split(attributes); + while (ni--) { + schemaItem = schema[name[ni]]; + for (i = 0, l = attributes.length; i < l; i++) { + schemaItem.attributes[attributes[i]] = {}; + schemaItem.attributesOrder.push(attributes[i]); + } + } + } + + // Use cached schema + if (mapCache[type]) { + return mapCache[type]; + } + + // Attributes present on all elements + globalAttributes = split("id accesskey class dir lang style tabindex title"); + + // Event attributes can be opt-in/opt-out + /*eventAttributes = split("onabort onblur oncancel oncanplay oncanplaythrough onchange onclick onclose oncontextmenu oncuechange " + + "ondblclick ondrag ondragend ondragenter ondragleave ondragover ondragstart ondrop ondurationchange onemptied onended " + + "onerror onfocus oninput oninvalid onkeydown onkeypress onkeyup onload onloadeddata onloadedmetadata onloadstart " + + "onmousedown onmousemove onmouseout onmouseover onmouseup onmousewheel onpause onplay onplaying onprogress onratechange " + + "onreset onscroll onseeked onseeking onseeking onselect onshow onstalled onsubmit onsuspend ontimeupdate onvolumechange " + + "onwaiting" + );*/ + + // Block content elements + blockContent = split( + "address blockquote div dl fieldset form h1 h2 h3 h4 h5 h6 hr menu ol p pre table ul" + ); + + // Phrasing content elements from the HTML5 spec (inline) + phrasingContent = split( + "a abbr b bdo br button cite code del dfn em embed i iframe img input ins kbd " + + "label map noscript object q s samp script select small span strong sub sup " + + "textarea u var #text #comment" + ); + + // Add HTML5 items to globalAttributes, blockContent, phrasingContent + if (type != "html4") { + globalAttributes.push.apply(globalAttributes, split("contenteditable contextmenu draggable dropzone " + + "hidden spellcheck translate")); + blockContent.push.apply(blockContent, split("article aside details dialog figure header footer hgroup section nav")); + phrasingContent.push.apply(phrasingContent, split("audio canvas command datalist mark meter output picture " + + "progress time wbr video ruby bdi keygen")); + } + + // Add HTML4 elements unless it's html5-strict + if (type != "html5-strict") { + globalAttributes.push("xml:lang"); + + html4PhrasingContent = split("acronym applet basefont big font strike tt"); + phrasingContent.push.apply(phrasingContent, html4PhrasingContent); + + each(html4PhrasingContent, function(name) { + add(name, "", phrasingContent); + }); + + html4BlockContent = split("center dir isindex noframes"); + blockContent.push.apply(blockContent, html4BlockContent); + + // Flow content elements from the HTML5 spec (block+inline) + flowContent = [].concat(blockContent, phrasingContent); + + each(html4BlockContent, function(name) { + add(name, "", flowContent); + }); + } + + // Flow content elements from the HTML5 spec (block+inline) + flowContent = flowContent || [].concat(blockContent, phrasingContent); + + // HTML4 base schema TODO: Move HTML5 specific attributes to HTML5 specific if statement + // Schema items <element name>, <specific attributes>, <children ..> + add("html", "manifest", "head body"); + add("head", "", "base command link meta noscript script style title"); + add("title hr noscript br"); + add("base", "href target"); + add("link", "href rel media hreflang type sizes hreflang"); + add("meta", "name http-equiv content charset"); + add("style", "media type scoped"); + add("script", "src async defer type charset"); + add("body", "onafterprint onbeforeprint onbeforeunload onblur onerror onfocus " + + "onhashchange onload onmessage onoffline ononline onpagehide onpageshow " + + "onpopstate onresize onscroll onstorage onunload", flowContent); + add("address dt dd div caption", "", flowContent); + add("h1 h2 h3 h4 h5 h6 pre p abbr code var samp kbd sub sup i b u bdo span legend em strong small s cite dfn", "", phrasingContent); + add("blockquote", "cite", flowContent); + add("ol", "reversed start type", "li"); + add("ul", "", "li"); + add("li", "value", flowContent); + add("dl", "", "dt dd"); + add("a", "href target rel media hreflang type", phrasingContent); + add("q", "cite", phrasingContent); + add("ins del", "cite datetime", flowContent); + add("img", "src sizes srcset alt usemap ismap width height"); + add("iframe", "src name width height", flowContent); + add("embed", "src type width height"); + add("object", "data type typemustmatch name usemap form width height", flowContent, "param"); + add("param", "name value"); + add("map", "name", flowContent, "area"); + add("area", "alt coords shape href target rel media hreflang type"); + add("table", "border", "caption colgroup thead tfoot tbody tr" + (type == "html4" ? " col" : "")); + add("colgroup", "span", "col"); + add("col", "span"); + add("tbody thead tfoot", "", "tr"); + add("tr", "", "td th"); + add("td", "colspan rowspan headers", flowContent); + add("th", "colspan rowspan headers scope abbr", flowContent); + add("form", "accept-charset action autocomplete enctype method name novalidate target", flowContent); + add("fieldset", "disabled form name", flowContent, "legend"); + add("label", "form for", phrasingContent); + add("input", "accept alt autocomplete checked dirname disabled form formaction formenctype formmethod formnovalidate " + + "formtarget height list max maxlength min multiple name pattern readonly required size src step type value width" + ); + add("button", "disabled form formaction formenctype formmethod formnovalidate formtarget name type value", + type == "html4" ? flowContent : phrasingContent); + add("select", "disabled form multiple name required size", "option optgroup"); + add("optgroup", "disabled label", "option"); + add("option", "disabled label selected value"); + add("textarea", "cols dirname disabled form maxlength name readonly required rows wrap"); + add("menu", "type label", flowContent, "li"); + add("noscript", "", flowContent); + + // Extend with HTML5 elements + if (type != "html4") { + add("wbr"); + add("ruby", "", phrasingContent, "rt rp"); + add("figcaption", "", flowContent); + add("mark rt rp summary bdi", "", phrasingContent); + add("canvas", "width height", flowContent); + add("video", "src crossorigin poster preload autoplay mediagroup loop " + + "muted controls width height buffered", flowContent, "track source"); + add("audio", "src crossorigin preload autoplay mediagroup loop muted controls buffered volume", flowContent, "track source"); + add("picture", "", "img source"); + add("source", "src srcset type media sizes"); + add("track", "kind src srclang label default"); + add("datalist", "", phrasingContent, "option"); + add("article section nav aside header footer", "", flowContent); + add("hgroup", "", "h1 h2 h3 h4 h5 h6"); + add("figure", "", flowContent, "figcaption"); + add("time", "datetime", phrasingContent); + add("dialog", "open", flowContent); + add("command", "type label icon disabled checked radiogroup command"); + add("output", "for form name", phrasingContent); + add("progress", "value max", phrasingContent); + add("meter", "value min max low high optimum", phrasingContent); + add("details", "open", flowContent, "summary"); + add("keygen", "autofocus challenge disabled form keytype name"); + } + + // Extend with HTML4 attributes unless it's html5-strict + if (type != "html5-strict") { + addAttrs("script", "language xml:space"); + addAttrs("style", "xml:space"); + addAttrs("object", "declare classid code codebase codetype archive standby align border hspace vspace"); + addAttrs("embed", "align name hspace vspace"); + addAttrs("param", "valuetype type"); + addAttrs("a", "charset name rev shape coords"); + addAttrs("br", "clear"); + addAttrs("applet", "codebase archive code object alt name width height align hspace vspace"); + addAttrs("img", "name longdesc align border hspace vspace"); + addAttrs("iframe", "longdesc frameborder marginwidth marginheight scrolling align"); + addAttrs("font basefont", "size color face"); + addAttrs("input", "usemap align"); + addAttrs("select", "onchange"); + addAttrs("textarea"); + addAttrs("h1 h2 h3 h4 h5 h6 div p legend caption", "align"); + addAttrs("ul", "type compact"); + addAttrs("li", "type"); + addAttrs("ol dl menu dir", "compact"); + addAttrs("pre", "width xml:space"); + addAttrs("hr", "align noshade size width"); + addAttrs("isindex", "prompt"); + addAttrs("table", "summary width frame rules cellspacing cellpadding align bgcolor"); + addAttrs("col", "width align char charoff valign"); + addAttrs("colgroup", "width align char charoff valign"); + addAttrs("thead", "align char charoff valign"); + addAttrs("tr", "align char charoff valign bgcolor"); + addAttrs("th", "axis align char charoff valign nowrap bgcolor width height"); + addAttrs("form", "accept"); + addAttrs("td", "abbr axis scope align char charoff valign nowrap bgcolor width height"); + addAttrs("tfoot", "align char charoff valign"); + addAttrs("tbody", "align char charoff valign"); + addAttrs("area", "nohref"); + addAttrs("body", "background bgcolor text link vlink alink"); + } + + // Extend with HTML5 attributes unless it's html4 + if (type != "html4") { + addAttrs("input button select textarea", "autofocus"); + addAttrs("input textarea", "placeholder"); + addAttrs("a", "download"); + addAttrs("link script img", "crossorigin"); + addAttrs("iframe", "sandbox seamless allowfullscreen"); // Excluded: srcdoc + } + + // Special: iframe, ruby, video, audio, label + + // Delete children of the same name from it's parent + // For example: form can't have a child of the name form + each(split('a form meter progress dfn'), function(name) { + if (schema[name]) { + delete schema[name].children[name]; + } + }); + + // Delete header, footer, sectioning and heading content descendants + /*each('dt th address', function(name) { + delete schema[name].children[name]; + });*/ + + // Caption can't have tables + delete schema.caption.children.table; + + // Delete scripts by default due to possible XSS + delete schema.script; + + // TODO: LI:s can only have value if parent is OL + + // TODO: Handle transparent elements + // a ins del canvas map + + mapCache[type] = schema; + + return schema; + } + + function compileElementMap(value, mode) { + var styles; + + if (value) { + styles = {}; + + if (typeof value == 'string') { + value = { + '*': value + }; + } + + // Convert styles into a rule list + each(value, function(value, key) { + styles[key] = styles[key.toUpperCase()] = mode == 'map' ? makeMap(value, /[, ]/) : explode(value, /[, ]/); + }); + } + + return styles; + } + + /** + * Constructs a new Schema instance. + * + * @constructor + * @method Schema + * @param {Object} settings Name/value settings object. + */ + return function(settings) { + var self = this, elements = {}, children = {}, patternElements = [], validStyles, invalidStyles, schemaItems; + var whiteSpaceElementsMap, selfClosingElementsMap, shortEndedElementsMap, boolAttrMap, validClasses; + var blockElementsMap, nonEmptyElementsMap, moveCaretBeforeOnEnterElementsMap, textBlockElementsMap, textInlineElementsMap; + var customElementsMap = {}, specialElements = {}; + + // Creates an lookup table map object for the specified option or the default value + function createLookupTable(option, default_value, extendWith) { + var value = settings[option]; + + if (!value) { + // Get cached default map or make it if needed + value = mapCache[option]; + + if (!value) { + value = makeMap(default_value, ' ', makeMap(default_value.toUpperCase(), ' ')); + value = extend(value, extendWith); + + mapCache[option] = value; + } + } else { + // Create custom map + value = makeMap(value, /[, ]/, makeMap(value.toUpperCase(), /[, ]/)); + } + + return value; + } + + settings = settings || {}; + schemaItems = compileSchema(settings.schema); + + // Allow all elements and attributes if verify_html is set to false + if (settings.verify_html === false) { + settings.valid_elements = '*[*]'; + } + + validStyles = compileElementMap(settings.valid_styles); + invalidStyles = compileElementMap(settings.invalid_styles, 'map'); + validClasses = compileElementMap(settings.valid_classes, 'map'); + + // Setup map objects + whiteSpaceElementsMap = createLookupTable('whitespace_elements', 'pre script noscript style textarea video audio iframe object'); + selfClosingElementsMap = createLookupTable('self_closing_elements', 'colgroup dd dt li option p td tfoot th thead tr'); + shortEndedElementsMap = createLookupTable('short_ended_elements', 'area base basefont br col frame hr img input isindex link ' + + 'meta param embed source wbr track'); + boolAttrMap = createLookupTable('boolean_attributes', 'checked compact declare defer disabled ismap multiple nohref noresize ' + + 'noshade nowrap readonly selected autoplay loop controls'); + nonEmptyElementsMap = createLookupTable('non_empty_elements', 'td th iframe video audio object script', shortEndedElementsMap); + moveCaretBeforeOnEnterElementsMap = createLookupTable('move_caret_before_on_enter_elements', 'table', nonEmptyElementsMap); + textBlockElementsMap = createLookupTable('text_block_elements', 'h1 h2 h3 h4 h5 h6 p div address pre form ' + + 'blockquote center dir fieldset header footer article section hgroup aside nav figure'); + blockElementsMap = createLookupTable('block_elements', 'hr table tbody thead tfoot ' + + 'th tr td li ol ul caption dl dt dd noscript menu isindex option ' + + 'datalist select optgroup figcaption', textBlockElementsMap); + textInlineElementsMap = createLookupTable('text_inline_elements', 'span strong b em i font strike u var cite ' + + 'dfn code mark q sup sub samp'); + + each((settings.special || 'script noscript style textarea').split(' '), function(name) { + specialElements[name] = new RegExp('<\/' + name + '[^>]*>', 'gi'); + }); + + // Converts a wildcard expression string to a regexp for example *a will become /.*a/. + function patternToRegExp(str) { + return new RegExp('^' + str.replace(/([?+*])/g, '.$1') + '$'); + } + + // Parses the specified valid_elements string and adds to the current rules + // This function is a bit hard to read since it's heavily optimized for speed + function addValidElements(validElements) { + var ei, el, ai, al, matches, element, attr, attrData, elementName, attrName, attrType, attributes, attributesOrder, + prefix, outputName, globalAttributes, globalAttributesOrder, key, value, + elementRuleRegExp = /^([#+\-])?([^\[!\/]+)(?:\/([^\[!]+))?(?:(!?)\[([^\]]+)\])?$/, + attrRuleRegExp = /^([!\-])?(\w+::\w+|[^=:<]+)?(?:([=:<])(.*))?$/, + hasPatternsRegExp = /[*?+]/; + + if (validElements) { + // Split valid elements into an array with rules + validElements = split(validElements, ','); + + if (elements['@']) { + globalAttributes = elements['@'].attributes; + globalAttributesOrder = elements['@'].attributesOrder; + } + + // Loop all rules + for (ei = 0, el = validElements.length; ei < el; ei++) { + // Parse element rule + matches = elementRuleRegExp.exec(validElements[ei]); + if (matches) { + // Setup local names for matches + prefix = matches[1]; + elementName = matches[2]; + outputName = matches[3]; + attrData = matches[5]; + + // Create new attributes and attributesOrder + attributes = {}; + attributesOrder = []; + + // Create the new element + element = { + attributes: attributes, + attributesOrder: attributesOrder + }; + + // Padd empty elements prefix + if (prefix === '#') { + element.paddEmpty = true; + } + + // Remove empty elements prefix + if (prefix === '-') { + element.removeEmpty = true; + } + + if (matches[4] === '!') { + element.removeEmptyAttrs = true; + } + + // Copy attributes from global rule into current rule + if (globalAttributes) { + for (key in globalAttributes) { + attributes[key] = globalAttributes[key]; + } + + attributesOrder.push.apply(attributesOrder, globalAttributesOrder); + } + + // Attributes defined + if (attrData) { + attrData = split(attrData, '|'); + for (ai = 0, al = attrData.length; ai < al; ai++) { + matches = attrRuleRegExp.exec(attrData[ai]); + if (matches) { + attr = {}; + attrType = matches[1]; + attrName = matches[2].replace(/::/g, ':'); + prefix = matches[3]; + value = matches[4]; + + // Required + if (attrType === '!') { + element.attributesRequired = element.attributesRequired || []; + element.attributesRequired.push(attrName); + attr.required = true; + } + + // Denied from global + if (attrType === '-') { + delete attributes[attrName]; + attributesOrder.splice(inArray(attributesOrder, attrName), 1); + continue; + } + + // Default value + if (prefix) { + // Default value + if (prefix === '=') { + element.attributesDefault = element.attributesDefault || []; + element.attributesDefault.push({name: attrName, value: value}); + attr.defaultValue = value; + } + + // Forced value + if (prefix === ':') { + element.attributesForced = element.attributesForced || []; + element.attributesForced.push({name: attrName, value: value}); + attr.forcedValue = value; + } + + // Required values + if (prefix === '<') { + attr.validValues = makeMap(value, '?'); + } + } + + // Check for attribute patterns + if (hasPatternsRegExp.test(attrName)) { + element.attributePatterns = element.attributePatterns || []; + attr.pattern = patternToRegExp(attrName); + element.attributePatterns.push(attr); + } else { + // Add attribute to order list if it doesn't already exist + if (!attributes[attrName]) { + attributesOrder.push(attrName); + } + + attributes[attrName] = attr; + } + } + } + } + + // Global rule, store away these for later usage + if (!globalAttributes && elementName == '@') { + globalAttributes = attributes; + globalAttributesOrder = attributesOrder; + } + + // Handle substitute elements such as b/strong + if (outputName) { + element.outputName = elementName; + elements[outputName] = element; + } + + // Add pattern or exact element + if (hasPatternsRegExp.test(elementName)) { + element.pattern = patternToRegExp(elementName); + patternElements.push(element); + } else { + elements[elementName] = element; + } + } + } + } + } + + function setValidElements(validElements) { + elements = {}; + patternElements = []; + + addValidElements(validElements); + + each(schemaItems, function(element, name) { + children[name] = element.children; + }); + } + + // Adds custom non HTML elements to the schema + function addCustomElements(customElements) { + var customElementRegExp = /^(~)?(.+)$/; + + if (customElements) { + // Flush cached items since we are altering the default maps + mapCache.text_block_elements = mapCache.block_elements = null; + + each(split(customElements, ','), function(rule) { + var matches = customElementRegExp.exec(rule), + inline = matches[1] === '~', + cloneName = inline ? 'span' : 'div', + name = matches[2]; + + children[name] = children[cloneName]; + customElementsMap[name] = cloneName; + + // If it's not marked as inline then add it to valid block elements + if (!inline) { + blockElementsMap[name.toUpperCase()] = {}; + blockElementsMap[name] = {}; + } + + // Add elements clone if needed + if (!elements[name]) { + var customRule = elements[cloneName]; + + customRule = extend({}, customRule); + delete customRule.removeEmptyAttrs; + delete customRule.removeEmpty; + + elements[name] = customRule; + } + + // Add custom elements at span/div positions + each(children, function(element, elmName) { + if (element[cloneName]) { + children[elmName] = element = extend({}, children[elmName]); + element[name] = element[cloneName]; + } + }); + }); + } + } + + // Adds valid children to the schema object + function addValidChildren(validChildren) { + var childRuleRegExp = /^([+\-]?)(\w+)\[([^\]]+)\]$/; + + // Invalidate the schema cache if the schema is mutated + mapCache[settings.schema] = null; + + if (validChildren) { + each(split(validChildren, ','), function(rule) { + var matches = childRuleRegExp.exec(rule), parent, prefix; + + if (matches) { + prefix = matches[1]; + + // Add/remove items from default + if (prefix) { + parent = children[matches[2]]; + } else { + parent = children[matches[2]] = {'#comment': {}}; + } + + parent = children[matches[2]]; + + each(split(matches[3], '|'), function(child) { + if (prefix === '-') { + delete parent[child]; + } else { + parent[child] = {}; + } + }); + } + }); + } + } + + function getElementRule(name) { + var element = elements[name], i; + + // Exact match found + if (element) { + return element; + } + + // No exact match then try the patterns + i = patternElements.length; + while (i--) { + element = patternElements[i]; + + if (element.pattern.test(name)) { + return element; + } + } + } + + if (!settings.valid_elements) { + // No valid elements defined then clone the elements from the schema spec + each(schemaItems, function(element, name) { + elements[name] = { + attributes: element.attributes, + attributesOrder: element.attributesOrder + }; + + children[name] = element.children; + }); + + // Switch these on HTML4 + if (settings.schema != "html5") { + each(split('strong/b em/i'), function(item) { + item = split(item, '/'); + elements[item[1]].outputName = item[0]; + }); + } + + // Add default alt attribute for images, removed since alt="" is treated as presentational. + // elements.img.attributesDefault = [{name: 'alt', value: ''}]; + + // Remove these if they are empty by default + each(split('ol ul sub sup blockquote span font a table tbody tr strong em b i'), function(name) { + if (elements[name]) { + elements[name].removeEmpty = true; + } + }); + + // Padd these by default + each(split('p h1 h2 h3 h4 h5 h6 th td pre div address caption'), function(name) { + elements[name].paddEmpty = true; + }); + + // Remove these if they have no attributes + each(split('span'), function(name) { + elements[name].removeEmptyAttrs = true; + }); + + // Remove these by default + // TODO: Reenable in 4.1 + /*each(split('script style'), function(name) { + delete elements[name]; + });*/ + } else { + setValidElements(settings.valid_elements); + } + + addCustomElements(settings.custom_elements); + addValidChildren(settings.valid_children); + addValidElements(settings.extended_valid_elements); + + // Todo: Remove this when we fix list handling to be valid + addValidChildren('+ol[ul|ol],+ul[ul|ol]'); + + // Delete invalid elements + if (settings.invalid_elements) { + each(explode(settings.invalid_elements), function(item) { + if (elements[item]) { + delete elements[item]; + } + }); + } + + // If the user didn't allow span only allow internal spans + if (!getElementRule('span')) { + addValidElements('span[!data-mce-type|*]'); + } + + /** + * Name/value map object with valid parents and children to those parents. + * + * @example + * children = { + * div:{p:{}, h1:{}} + * }; + * @field children + * @type Object + */ + self.children = children; + + /** + * Name/value map object with valid styles for each element. + * + * @method getValidStyles + * @type Object + */ + self.getValidStyles = function() { + return validStyles; + }; + + /** + * Name/value map object with valid styles for each element. + * + * @method getInvalidStyles + * @type Object + */ + self.getInvalidStyles = function() { + return invalidStyles; + }; + + /** + * Name/value map object with valid classes for each element. + * + * @method getValidClasses + * @type Object + */ + self.getValidClasses = function() { + return validClasses; + }; + + /** + * Returns a map with boolean attributes. + * + * @method getBoolAttrs + * @return {Object} Name/value lookup map for boolean attributes. + */ + self.getBoolAttrs = function() { + return boolAttrMap; + }; + + /** + * Returns a map with block elements. + * + * @method getBlockElements + * @return {Object} Name/value lookup map for block elements. + */ + self.getBlockElements = function() { + return blockElementsMap; + }; + + /** + * Returns a map with text block elements. Such as: p,h1-h6,div,address + * + * @method getTextBlockElements + * @return {Object} Name/value lookup map for block elements. + */ + self.getTextBlockElements = function() { + return textBlockElementsMap; + }; + + /** + * Returns a map of inline text format nodes for example strong/span or ins. + * + * @method getTextInlineElements + * @return {Object} Name/value lookup map for text format elements. + */ + self.getTextInlineElements = function() { + return textInlineElementsMap; + }; + + /** + * Returns a map with short ended elements such as BR or IMG. + * + * @method getShortEndedElements + * @return {Object} Name/value lookup map for short ended elements. + */ + self.getShortEndedElements = function() { + return shortEndedElementsMap; + }; + + /** + * Returns a map with self closing tags such as <li>. + * + * @method getSelfClosingElements + * @return {Object} Name/value lookup map for self closing tags elements. + */ + self.getSelfClosingElements = function() { + return selfClosingElementsMap; + }; + + /** + * Returns a map with elements that should be treated as contents regardless if it has text + * content in them or not such as TD, VIDEO or IMG. + * + * @method getNonEmptyElements + * @return {Object} Name/value lookup map for non empty elements. + */ + self.getNonEmptyElements = function() { + return nonEmptyElementsMap; + }; + + /** + * Returns a map with elements that the caret should be moved in front of after enter is + * pressed + * + * @method getMoveCaretBeforeOnEnterElements + * @return {Object} Name/value lookup map for elements to place the caret in front of. + */ + self.getMoveCaretBeforeOnEnterElements = function() { + return moveCaretBeforeOnEnterElementsMap; + }; + + /** + * Returns a map with elements where white space is to be preserved like PRE or SCRIPT. + * + * @method getWhiteSpaceElements + * @return {Object} Name/value lookup map for white space elements. + */ + self.getWhiteSpaceElements = function() { + return whiteSpaceElementsMap; + }; + + /** + * Returns a map with special elements. These are elements that needs to be parsed + * in a special way such as script, style, textarea etc. The map object values + * are regexps used to find the end of the element. + * + * @method getSpecialElements + * @return {Object} Name/value lookup map for special elements. + */ + self.getSpecialElements = function() { + return specialElements; + }; + + /** + * Returns true/false if the specified element and it's child is valid or not + * according to the schema. + * + * @method isValidChild + * @param {String} name Element name to check for. + * @param {String} child Element child to verify. + * @return {Boolean} True/false if the element is a valid child of the specified parent. + */ + self.isValidChild = function(name, child) { + var parent = children[name]; + + return !!(parent && parent[child]); + }; + + /** + * Returns true/false if the specified element name and optional attribute is + * valid according to the schema. + * + * @method isValid + * @param {String} name Name of element to check. + * @param {String} attr Optional attribute name to check for. + * @return {Boolean} True/false if the element and attribute is valid. + */ + self.isValid = function(name, attr) { + var attrPatterns, i, rule = getElementRule(name); + + // Check if it's a valid element + if (rule) { + if (attr) { + // Check if attribute name exists + if (rule.attributes[attr]) { + return true; + } + + // Check if attribute matches a regexp pattern + attrPatterns = rule.attributePatterns; + if (attrPatterns) { + i = attrPatterns.length; + while (i--) { + if (attrPatterns[i].pattern.test(name)) { + return true; + } + } + } + } else { + return true; + } + } + + // No match + return false; + }; + + /** + * Returns true/false if the specified element is valid or not + * according to the schema. + * + * @method getElementRule + * @param {String} name Element name to check for. + * @return {Object} Element object or undefined if the element isn't valid. + */ + self.getElementRule = getElementRule; + + /** + * Returns an map object of all custom elements. + * + * @method getCustomElements + * @return {Object} Name/value map object of all custom elements. + */ + self.getCustomElements = function() { + return customElementsMap; + }; + + /** + * Parses a valid elements string and adds it to the schema. The valid elements + * format is for example "element[attr=default|otherattr]". + * Existing rules will be replaced with the ones specified, so this extends the schema. + * + * @method addValidElements + * @param {String} valid_elements String in the valid elements format to be parsed. + */ + self.addValidElements = addValidElements; + + /** + * Parses a valid elements string and sets it to the schema. The valid elements + * format is for example "element[attr=default|otherattr]". + * Existing rules will be replaced with the ones specified, so this extends the schema. + * + * @method setValidElements + * @param {String} valid_elements String in the valid elements format to be parsed. + */ + self.setValidElements = setValidElements; + + /** + * Adds custom non HTML elements to the schema. + * + * @method addCustomElements + * @param {String} custom_elements Comma separated list of custom elements to add. + */ + self.addCustomElements = addCustomElements; + + /** + * Parses a valid children string and adds them to the schema structure. The valid children + * format is for example: "element[child1|child2]". + * + * @method addValidChildren + * @param {String} valid_children Valid children elements string to parse + */ + self.addValidChildren = addValidChildren; + + self.elements = elements; + }; +}); + +// Included from: js/tinymce/classes/html/SaxParser.js + +/** + * SaxParser.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/*eslint max-depth:[2, 9] */ + +/** + * This class parses HTML code using pure JavaScript and executes various events for each item it finds. It will + * always execute the events in the right order for tag soup code like <b><p></b></p>. It will also remove elements + * and attributes that doesn't fit the schema if the validate setting is enabled. + * + * @example + * var parser = new tinymce.html.SaxParser({ + * validate: true, + * + * comment: function(text) { + * console.log('Comment:', text); + * }, + * + * cdata: function(text) { + * console.log('CDATA:', text); + * }, + * + * text: function(text, raw) { + * console.log('Text:', text, 'Raw:', raw); + * }, + * + * start: function(name, attrs, empty) { + * console.log('Start:', name, attrs, empty); + * }, + * + * end: function(name) { + * console.log('End:', name); + * }, + * + * pi: function(name, text) { + * console.log('PI:', name, text); + * }, + * + * doctype: function(text) { + * console.log('DocType:', text); + * } + * }, schema); + * @class tinymce.html.SaxParser + * @version 3.4 + */ +define("tinymce/html/SaxParser", [ + "tinymce/html/Schema", + "tinymce/html/Entities", + "tinymce/util/Tools" +], function(Schema, Entities, Tools) { + var each = Tools.each; + + /** + * Returns the index of the end tag for a specific start tag. This can be + * used to skip all children of a parent element from being processed. + * + * @private + * @method findEndTag + * @param {tinymce.html.Schema} schema Schema instance to use to match short ended elements. + * @param {String} html HTML string to find the end tag in. + * @param {Number} startIndex Indext to start searching at should be after the start tag. + * @return {Number} Index of the end tag. + */ + function findEndTag(schema, html, startIndex) { + var count = 1, index, matches, tokenRegExp, shortEndedElements; + + shortEndedElements = schema.getShortEndedElements(); + tokenRegExp = /<([!?\/])?([A-Za-z0-9\-_\:\.]+)((?:\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\/|\s+)>/g; + tokenRegExp.lastIndex = index = startIndex; + + while ((matches = tokenRegExp.exec(html))) { + index = tokenRegExp.lastIndex; + + if (matches[1] === '/') { // End element + count--; + } else if (!matches[1]) { // Start element + if (matches[2] in shortEndedElements) { + continue; + } + + count++; + } + + if (count === 0) { + break; + } + } + + return index; + } + + /** + * Constructs a new SaxParser instance. + * + * @constructor + * @method SaxParser + * @param {Object} settings Name/value collection of settings. comment, cdata, text, start and end are callbacks. + * @param {tinymce.html.Schema} schema HTML Schema class to use when parsing. + */ + function SaxParser(settings, schema) { + var self = this; + + function noop() {} + + settings = settings || {}; + self.schema = schema = schema || new Schema(); + + if (settings.fix_self_closing !== false) { + settings.fix_self_closing = true; + } + + // Add handler functions from settings and setup default handlers + each('comment cdata text start end pi doctype'.split(' '), function(name) { + if (name) { + self[name] = settings[name] || noop; + } + }); + + /** + * Parses the specified HTML string and executes the callbacks for each item it finds. + * + * @example + * new SaxParser({...}).parse('<b>text</b>'); + * @method parse + * @param {String} html Html string to sax parse. + */ + self.parse = function(html) { + var self = this, matches, index = 0, value, endRegExp, stack = [], attrList, i, text, name; + var isInternalElement, removeInternalElements, shortEndedElements, fillAttrsMap, isShortEnded; + var validate, elementRule, isValidElement, attr, attribsValue, validAttributesMap, validAttributePatterns; + var attributesRequired, attributesDefault, attributesForced; + var anyAttributesRequired, selfClosing, tokenRegExp, attrRegExp, specialElements, attrValue, idCount = 0; + var decode = Entities.decode, fixSelfClosing, filteredUrlAttrs = Tools.makeMap('src,href,data,background,formaction,poster'); + var scriptUriRegExp = /((java|vb)script|mhtml):/i, dataUriRegExp = /^data:/i; + + function processEndTag(name) { + var pos, i; + + // Find position of parent of the same type + pos = stack.length; + while (pos--) { + if (stack[pos].name === name) { + break; + } + } + + // Found parent + if (pos >= 0) { + // Close all the open elements + for (i = stack.length - 1; i >= pos; i--) { + name = stack[i]; + + if (name.valid) { + self.end(name.name); + } + } + + // Remove the open elements from the stack + stack.length = pos; + } + } + + function parseAttribute(match, name, value, val2, val3) { + var attrRule, i, trimRegExp = /[\s\u0000-\u001F]+/g; + + name = name.toLowerCase(); + value = name in fillAttrsMap ? name : decode(value || val2 || val3 || ''); // Handle boolean attribute than value attribute + + // Validate name and value pass through all data- attributes + if (validate && !isInternalElement && name.indexOf('data-') !== 0) { + attrRule = validAttributesMap[name]; + + // Find rule by pattern matching + if (!attrRule && validAttributePatterns) { + i = validAttributePatterns.length; + while (i--) { + attrRule = validAttributePatterns[i]; + if (attrRule.pattern.test(name)) { + break; + } + } + + // No rule matched + if (i === -1) { + attrRule = null; + } + } + + // No attribute rule found + if (!attrRule) { + return; + } + + // Validate value + if (attrRule.validValues && !(value in attrRule.validValues)) { + return; + } + } + + // Block any javascript: urls or non image data uris + if (filteredUrlAttrs[name] && !settings.allow_script_urls) { + var uri = value.replace(trimRegExp, ''); + + try { + // Might throw malformed URI sequence + uri = decodeURIComponent(uri); + } catch (ex) { + // Fallback to non UTF-8 decoder + uri = unescape(uri); + } + + if (scriptUriRegExp.test(uri)) { + return; + } + + if (!settings.allow_html_data_urls && dataUriRegExp.test(uri) && !/^data:image\//i.test(uri)) { + return; + } + } + + // Add attribute to list and map + attrList.map[name] = value; + attrList.push({ + name: name, + value: value + }); + } + + // Precompile RegExps and map objects + tokenRegExp = new RegExp('<(?:' + + '(?:!--([\\w\\W]*?)-->)|' + // Comment + '(?:!\\[CDATA\\[([\\w\\W]*?)\\]\\]>)|' + // CDATA + '(?:!DOCTYPE([\\w\\W]*?)>)|' + // DOCTYPE + '(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|' + // PI + '(?:\\/([^>]+)>)|' + // End element + '(?:([A-Za-z0-9\\-_\\:\\.]+)((?:\\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\\/|\\s+)>)' + // Start element + ')', 'g'); + + attrRegExp = /([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:[^\"])*)\")|(?:\'((?:[^\'])*)\')|([^>\s]+)))?/g; + + // Setup lookup tables for empty elements and boolean attributes + shortEndedElements = schema.getShortEndedElements(); + selfClosing = settings.self_closing_elements || schema.getSelfClosingElements(); + fillAttrsMap = schema.getBoolAttrs(); + validate = settings.validate; + removeInternalElements = settings.remove_internals; + fixSelfClosing = settings.fix_self_closing; + specialElements = schema.getSpecialElements(); + + while ((matches = tokenRegExp.exec(html))) { + // Text + if (index < matches.index) { + self.text(decode(html.substr(index, matches.index - index))); + } + + if ((value = matches[6])) { // End element + value = value.toLowerCase(); + + // IE will add a ":" in front of elements it doesn't understand like custom elements or HTML5 elements + if (value.charAt(0) === ':') { + value = value.substr(1); + } + + processEndTag(value); + } else if ((value = matches[7])) { // Start element + value = value.toLowerCase(); + + // IE will add a ":" in front of elements it doesn't understand like custom elements or HTML5 elements + if (value.charAt(0) === ':') { + value = value.substr(1); + } + + isShortEnded = value in shortEndedElements; + + // Is self closing tag for example an <li> after an open <li> + if (fixSelfClosing && selfClosing[value] && stack.length > 0 && stack[stack.length - 1].name === value) { + processEndTag(value); + } + + // Validate element + if (!validate || (elementRule = schema.getElementRule(value))) { + isValidElement = true; + + // Grab attributes map and patters when validation is enabled + if (validate) { + validAttributesMap = elementRule.attributes; + validAttributePatterns = elementRule.attributePatterns; + } + + // Parse attributes + if ((attribsValue = matches[8])) { + isInternalElement = attribsValue.indexOf('data-mce-type') !== -1; // Check if the element is an internal element + + // If the element has internal attributes then remove it if we are told to do so + if (isInternalElement && removeInternalElements) { + isValidElement = false; + } + + attrList = []; + attrList.map = {}; + + attribsValue.replace(attrRegExp, parseAttribute); + } else { + attrList = []; + attrList.map = {}; + } + + // Process attributes if validation is enabled + if (validate && !isInternalElement) { + attributesRequired = elementRule.attributesRequired; + attributesDefault = elementRule.attributesDefault; + attributesForced = elementRule.attributesForced; + anyAttributesRequired = elementRule.removeEmptyAttrs; + + // Check if any attribute exists + if (anyAttributesRequired && !attrList.length) { + isValidElement = false; + } + + // Handle forced attributes + if (attributesForced) { + i = attributesForced.length; + while (i--) { + attr = attributesForced[i]; + name = attr.name; + attrValue = attr.value; + + if (attrValue === '{$uid}') { + attrValue = 'mce_' + idCount++; + } + + attrList.map[name] = attrValue; + attrList.push({name: name, value: attrValue}); + } + } + + // Handle default attributes + if (attributesDefault) { + i = attributesDefault.length; + while (i--) { + attr = attributesDefault[i]; + name = attr.name; + + if (!(name in attrList.map)) { + attrValue = attr.value; + + if (attrValue === '{$uid}') { + attrValue = 'mce_' + idCount++; + } + + attrList.map[name] = attrValue; + attrList.push({name: name, value: attrValue}); + } + } + } + + // Handle required attributes + if (attributesRequired) { + i = attributesRequired.length; + while (i--) { + if (attributesRequired[i] in attrList.map) { + break; + } + } + + // None of the required attributes where found + if (i === -1) { + isValidElement = false; + } + } + + // Invalidate element if it's marked as bogus + if ((attr = attrList.map['data-mce-bogus'])) { + if (attr === 'all') { + index = findEndTag(schema, html, tokenRegExp.lastIndex); + tokenRegExp.lastIndex = index; + continue; + } + + isValidElement = false; + } + } + + if (isValidElement) { + self.start(value, attrList, isShortEnded); + } + } else { + isValidElement = false; + } + + // Treat script, noscript and style a bit different since they may include code that looks like elements + if ((endRegExp = specialElements[value])) { + endRegExp.lastIndex = index = matches.index + matches[0].length; + + if ((matches = endRegExp.exec(html))) { + if (isValidElement) { + text = html.substr(index, matches.index - index); + } + + index = matches.index + matches[0].length; + } else { + text = html.substr(index); + index = html.length; + } + + if (isValidElement) { + if (text.length > 0) { + self.text(text, true); + } + + self.end(value); + } + + tokenRegExp.lastIndex = index; + continue; + } + + // Push value on to stack + if (!isShortEnded) { + if (!attribsValue || attribsValue.indexOf('/') != attribsValue.length - 1) { + stack.push({name: value, valid: isValidElement}); + } else if (isValidElement) { + self.end(value); + } + } + } else if ((value = matches[1])) { // Comment + // Padd comment value to avoid browsers from parsing invalid comments as HTML + if (value.charAt(0) === '>') { + value = ' ' + value; + } + + if (!settings.allow_conditional_comments && value.substr(0, 3) === '[if') { + value = ' ' + value; + } + + self.comment(value); + } else if ((value = matches[2])) { // CDATA + self.cdata(value); + } else if ((value = matches[3])) { // DOCTYPE + self.doctype(value); + } else if ((value = matches[4])) { // PI + self.pi(value, matches[5]); + } + + index = matches.index + matches[0].length; + } + + // Text + if (index < html.length) { + self.text(decode(html.substr(index))); + } + + // Close any open elements + for (i = stack.length - 1; i >= 0; i--) { + value = stack[i]; + + if (value.valid) { + self.end(value.name); + } + } + }; + } + + SaxParser.findEndTag = findEndTag; + + return SaxParser; +}); + +// Included from: js/tinymce/classes/html/DomParser.js + +/** + * DomParser.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class parses HTML code into a DOM like structure of nodes it will remove redundant whitespace and make + * sure that the node tree is valid according to the specified schema. + * So for example: <p>a<p>b</p>c</p> will become <p>a</p><p>b</p><p>c</p> + * + * @example + * var parser = new tinymce.html.DomParser({validate: true}, schema); + * var rootNode = parser.parse('<h1>content</h1>'); + * + * @class tinymce.html.DomParser + * @version 3.4 + */ +define("tinymce/html/DomParser", [ + "tinymce/html/Node", + "tinymce/html/Schema", + "tinymce/html/SaxParser", + "tinymce/util/Tools" +], function(Node, Schema, SaxParser, Tools) { + var makeMap = Tools.makeMap, each = Tools.each, explode = Tools.explode, extend = Tools.extend; + + /** + * Constructs a new DomParser instance. + * + * @constructor + * @method DomParser + * @param {Object} settings Name/value collection of settings. comment, cdata, text, start and end are callbacks. + * @param {tinymce.html.Schema} schema HTML Schema class to use when parsing. + */ + return function(settings, schema) { + var self = this, nodeFilters = {}, attributeFilters = [], matchedNodes = {}, matchedAttributes = {}; + + settings = settings || {}; + settings.validate = "validate" in settings ? settings.validate : true; + settings.root_name = settings.root_name || 'body'; + self.schema = schema = schema || new Schema(); + + function fixInvalidChildren(nodes) { + var ni, node, parent, parents, newParent, currentNode, tempNode, childNode, i; + var nonEmptyElements, nonSplitableElements, textBlockElements, specialElements, sibling, nextNode; + + nonSplitableElements = makeMap('tr,td,th,tbody,thead,tfoot,table'); + nonEmptyElements = schema.getNonEmptyElements(); + textBlockElements = schema.getTextBlockElements(); + specialElements = schema.getSpecialElements(); + + for (ni = 0; ni < nodes.length; ni++) { + node = nodes[ni]; + + // Already removed or fixed + if (!node.parent || node.fixed) { + continue; + } + + // If the invalid element is a text block and the text block is within a parent LI element + // Then unwrap the first text block and convert other sibling text blocks to LI elements similar to Word/Open Office + if (textBlockElements[node.name] && node.parent.name == 'li') { + // Move sibling text blocks after LI element + sibling = node.next; + while (sibling) { + if (textBlockElements[sibling.name]) { + sibling.name = 'li'; + sibling.fixed = true; + node.parent.insert(sibling, node.parent); + } else { + break; + } + + sibling = sibling.next; + } + + // Unwrap current text block + node.unwrap(node); + continue; + } + + // Get list of all parent nodes until we find a valid parent to stick the child into + parents = [node]; + for (parent = node.parent; parent && !schema.isValidChild(parent.name, node.name) && + !nonSplitableElements[parent.name]; parent = parent.parent) { + parents.push(parent); + } + + // Found a suitable parent + if (parent && parents.length > 1) { + // Reverse the array since it makes looping easier + parents.reverse(); + + // Clone the related parent and insert that after the moved node + newParent = currentNode = self.filterNode(parents[0].clone()); + + // Start cloning and moving children on the left side of the target node + for (i = 0; i < parents.length - 1; i++) { + if (schema.isValidChild(currentNode.name, parents[i].name)) { + tempNode = self.filterNode(parents[i].clone()); + currentNode.append(tempNode); + } else { + tempNode = currentNode; + } + + for (childNode = parents[i].firstChild; childNode && childNode != parents[i + 1];) { + nextNode = childNode.next; + tempNode.append(childNode); + childNode = nextNode; + } + + currentNode = tempNode; + } + + if (!newParent.isEmpty(nonEmptyElements)) { + parent.insert(newParent, parents[0], true); + parent.insert(node, newParent); + } else { + parent.insert(node, parents[0], true); + } + + // Check if the element is empty by looking through it's contents and special treatment for <p><br /></p> + parent = parents[0]; + if (parent.isEmpty(nonEmptyElements) || parent.firstChild === parent.lastChild && parent.firstChild.name === 'br') { + parent.empty().remove(); + } + } else if (node.parent) { + // If it's an LI try to find a UL/OL for it or wrap it + if (node.name === 'li') { + sibling = node.prev; + if (sibling && (sibling.name === 'ul' || sibling.name === 'ul')) { + sibling.append(node); + continue; + } + + sibling = node.next; + if (sibling && (sibling.name === 'ul' || sibling.name === 'ul')) { + sibling.insert(node, sibling.firstChild, true); + continue; + } + + node.wrap(self.filterNode(new Node('ul', 1))); + continue; + } + + // Try wrapping the element in a DIV + if (schema.isValidChild(node.parent.name, 'div') && schema.isValidChild('div', node.name)) { + node.wrap(self.filterNode(new Node('div', 1))); + } else { + // We failed wrapping it, then remove or unwrap it + if (specialElements[node.name]) { + node.empty().remove(); + } else { + node.unwrap(); + } + } + } + } + } + + /** + * Runs the specified node though the element and attributes filters. + * + * @method filterNode + * @param {tinymce.html.Node} Node the node to run filters on. + * @return {tinymce.html.Node} The passed in node. + */ + self.filterNode = function(node) { + var i, name, list; + + // Run element filters + if (name in nodeFilters) { + list = matchedNodes[name]; + + if (list) { + list.push(node); + } else { + matchedNodes[name] = [node]; + } + } + + // Run attribute filters + i = attributeFilters.length; + while (i--) { + name = attributeFilters[i].name; + + if (name in node.attributes.map) { + list = matchedAttributes[name]; + + if (list) { + list.push(node); + } else { + matchedAttributes[name] = [node]; + } + } + } + + return node; + }; + + /** + * Adds a node filter function to the parser, the parser will collect the specified nodes by name + * and then execute the callback ones it has finished parsing the document. + * + * @example + * parser.addNodeFilter('p,h1', function(nodes, name) { + * for (var i = 0; i < nodes.length; i++) { + * console.log(nodes[i].name); + * } + * }); + * @method addNodeFilter + * @method {String} name Comma separated list of nodes to collect. + * @param {function} callback Callback function to execute once it has collected nodes. + */ + self.addNodeFilter = function(name, callback) { + each(explode(name), function(name) { + var list = nodeFilters[name]; + + if (!list) { + nodeFilters[name] = list = []; + } + + list.push(callback); + }); + }; + + /** + * Adds a attribute filter function to the parser, the parser will collect nodes that has the specified attributes + * and then execute the callback ones it has finished parsing the document. + * + * @example + * parser.addAttributeFilter('src,href', function(nodes, name) { + * for (var i = 0; i < nodes.length; i++) { + * console.log(nodes[i].name); + * } + * }); + * @method addAttributeFilter + * @method {String} name Comma separated list of nodes to collect. + * @param {function} callback Callback function to execute once it has collected nodes. + */ + self.addAttributeFilter = function(name, callback) { + each(explode(name), function(name) { + var i; + + for (i = 0; i < attributeFilters.length; i++) { + if (attributeFilters[i].name === name) { + attributeFilters[i].callbacks.push(callback); + return; + } + } + + attributeFilters.push({name: name, callbacks: [callback]}); + }); + }; + + /** + * Parses the specified HTML string into a DOM like node tree and returns the result. + * + * @example + * var rootNode = new DomParser({...}).parse('<b>text</b>'); + * @method parse + * @param {String} html Html string to sax parse. + * @param {Object} args Optional args object that gets passed to all filter functions. + * @return {tinymce.html.Node} Root node containing the tree. + */ + self.parse = function(html, args) { + var parser, rootNode, node, nodes, i, l, fi, fl, list, name, validate; + var blockElements, startWhiteSpaceRegExp, invalidChildren = [], isInWhiteSpacePreservedElement; + var endWhiteSpaceRegExp, allWhiteSpaceRegExp, isAllWhiteSpaceRegExp, whiteSpaceElements; + var children, nonEmptyElements, rootBlockName; + + args = args || {}; + matchedNodes = {}; + matchedAttributes = {}; + blockElements = extend(makeMap('script,style,head,html,body,title,meta,param'), schema.getBlockElements()); + nonEmptyElements = schema.getNonEmptyElements(); + children = schema.children; + validate = settings.validate; + rootBlockName = "forced_root_block" in args ? args.forced_root_block : settings.forced_root_block; + + whiteSpaceElements = schema.getWhiteSpaceElements(); + startWhiteSpaceRegExp = /^[ \t\r\n]+/; + endWhiteSpaceRegExp = /[ \t\r\n]+$/; + allWhiteSpaceRegExp = /[ \t\r\n]+/g; + isAllWhiteSpaceRegExp = /^[ \t\r\n]+$/; + + function addRootBlocks() { + var node = rootNode.firstChild, next, rootBlockNode; + + // Removes whitespace at beginning and end of block so: + // <p> x </p> -> <p>x</p> + function trim(rootBlockNode) { + if (rootBlockNode) { + node = rootBlockNode.firstChild; + if (node && node.type == 3) { + node.value = node.value.replace(startWhiteSpaceRegExp, ''); + } + + node = rootBlockNode.lastChild; + if (node && node.type == 3) { + node.value = node.value.replace(endWhiteSpaceRegExp, ''); + } + } + } + + // Check if rootBlock is valid within rootNode for example if P is valid in H1 if H1 is the contentEditabe root + if (!schema.isValidChild(rootNode.name, rootBlockName.toLowerCase())) { + return; + } + + while (node) { + next = node.next; + + if (node.type == 3 || (node.type == 1 && node.name !== 'p' && + !blockElements[node.name] && !node.attr('data-mce-type'))) { + if (!rootBlockNode) { + // Create a new root block element + rootBlockNode = createNode(rootBlockName, 1); + rootBlockNode.attr(settings.forced_root_block_attrs); + rootNode.insert(rootBlockNode, node); + rootBlockNode.append(node); + } else { + rootBlockNode.append(node); + } + } else { + trim(rootBlockNode); + rootBlockNode = null; + } + + node = next; + } + + trim(rootBlockNode); + } + + function createNode(name, type) { + var node = new Node(name, type), list; + + if (name in nodeFilters) { + list = matchedNodes[name]; + + if (list) { + list.push(node); + } else { + matchedNodes[name] = [node]; + } + } + + return node; + } + + function removeWhitespaceBefore(node) { + var textNode, textNodeNext, textVal, sibling, blockElements = schema.getBlockElements(); + + for (textNode = node.prev; textNode && textNode.type === 3;) { + textVal = textNode.value.replace(endWhiteSpaceRegExp, ''); + + // Found a text node with non whitespace then trim that and break + if (textVal.length > 0) { + textNode.value = textVal; + return; + } + + textNodeNext = textNode.next; + + // Fix for bug #7543 where bogus nodes would produce empty + // text nodes and these would be removed if a nested list was before it + if (textNodeNext) { + if (textNodeNext.type == 3 && textNodeNext.value.length) { + textNode = textNode.prev; + continue; + } + + if (!blockElements[textNodeNext.name] && textNodeNext.name != 'script' && textNodeNext.name != 'style') { + textNode = textNode.prev; + continue; + } + } + + sibling = textNode.prev; + textNode.remove(); + textNode = sibling; + } + } + + function cloneAndExcludeBlocks(input) { + var name, output = {}; + + for (name in input) { + if (name !== 'li' && name != 'p') { + output[name] = input[name]; + } + } + + return output; + } + + parser = new SaxParser({ + validate: validate, + allow_script_urls: settings.allow_script_urls, + allow_conditional_comments: settings.allow_conditional_comments, + + // Exclude P and LI from DOM parsing since it's treated better by the DOM parser + self_closing_elements: cloneAndExcludeBlocks(schema.getSelfClosingElements()), + + cdata: function(text) { + node.append(createNode('#cdata', 4)).value = text; + }, + + text: function(text, raw) { + var textNode; + + // Trim all redundant whitespace on non white space elements + if (!isInWhiteSpacePreservedElement) { + text = text.replace(allWhiteSpaceRegExp, ' '); + + if (node.lastChild && blockElements[node.lastChild.name]) { + text = text.replace(startWhiteSpaceRegExp, ''); + } + } + + // Do we need to create the node + if (text.length !== 0) { + textNode = createNode('#text', 3); + textNode.raw = !!raw; + node.append(textNode).value = text; + } + }, + + comment: function(text) { + node.append(createNode('#comment', 8)).value = text; + }, + + pi: function(name, text) { + node.append(createNode(name, 7)).value = text; + removeWhitespaceBefore(node); + }, + + doctype: function(text) { + var newNode; + + newNode = node.append(createNode('#doctype', 10)); + newNode.value = text; + removeWhitespaceBefore(node); + }, + + start: function(name, attrs, empty) { + var newNode, attrFiltersLen, elementRule, attrName, parent; + + elementRule = validate ? schema.getElementRule(name) : {}; + if (elementRule) { + newNode = createNode(elementRule.outputName || name, 1); + newNode.attributes = attrs; + newNode.shortEnded = empty; + + node.append(newNode); + + // Check if node is valid child of the parent node is the child is + // unknown we don't collect it since it's probably a custom element + parent = children[node.name]; + if (parent && children[newNode.name] && !parent[newNode.name]) { + invalidChildren.push(newNode); + } + + attrFiltersLen = attributeFilters.length; + while (attrFiltersLen--) { + attrName = attributeFilters[attrFiltersLen].name; + + if (attrName in attrs.map) { + list = matchedAttributes[attrName]; + + if (list) { + list.push(newNode); + } else { + matchedAttributes[attrName] = [newNode]; + } + } + } + + // Trim whitespace before block + if (blockElements[name]) { + removeWhitespaceBefore(newNode); + } + + // Change current node if the element wasn't empty i.e not <br /> or <img /> + if (!empty) { + node = newNode; + } + + // Check if we are inside a whitespace preserved element + if (!isInWhiteSpacePreservedElement && whiteSpaceElements[name]) { + isInWhiteSpacePreservedElement = true; + } + } + }, + + end: function(name) { + var textNode, elementRule, text, sibling, tempNode; + + elementRule = validate ? schema.getElementRule(name) : {}; + if (elementRule) { + if (blockElements[name]) { + if (!isInWhiteSpacePreservedElement) { + // Trim whitespace of the first node in a block + textNode = node.firstChild; + if (textNode && textNode.type === 3) { + text = textNode.value.replace(startWhiteSpaceRegExp, ''); + + // Any characters left after trim or should we remove it + if (text.length > 0) { + textNode.value = text; + textNode = textNode.next; + } else { + sibling = textNode.next; + textNode.remove(); + textNode = sibling; + + // Remove any pure whitespace siblings + while (textNode && textNode.type === 3) { + text = textNode.value; + sibling = textNode.next; + + if (text.length === 0 || isAllWhiteSpaceRegExp.test(text)) { + textNode.remove(); + textNode = sibling; + } + + textNode = sibling; + } + } + } + + // Trim whitespace of the last node in a block + textNode = node.lastChild; + if (textNode && textNode.type === 3) { + text = textNode.value.replace(endWhiteSpaceRegExp, ''); + + // Any characters left after trim or should we remove it + if (text.length > 0) { + textNode.value = text; + textNode = textNode.prev; + } else { + sibling = textNode.prev; + textNode.remove(); + textNode = sibling; + + // Remove any pure whitespace siblings + while (textNode && textNode.type === 3) { + text = textNode.value; + sibling = textNode.prev; + + if (text.length === 0 || isAllWhiteSpaceRegExp.test(text)) { + textNode.remove(); + textNode = sibling; + } + + textNode = sibling; + } + } + } + } + + // Trim start white space + // Removed due to: #5424 + /*textNode = node.prev; + if (textNode && textNode.type === 3) { + text = textNode.value.replace(startWhiteSpaceRegExp, ''); + + if (text.length > 0) + textNode.value = text; + else + textNode.remove(); + }*/ + } + + // Check if we exited a whitespace preserved element + if (isInWhiteSpacePreservedElement && whiteSpaceElements[name]) { + isInWhiteSpacePreservedElement = false; + } + + // Handle empty nodes + if (elementRule.removeEmpty || elementRule.paddEmpty) { + if (node.isEmpty(nonEmptyElements)) { + if (elementRule.paddEmpty) { + node.empty().append(new Node('#text', '3')).value = '\u00a0'; + } else { + // Leave nodes that have a name like <a name="name"> + if (!node.attributes.map.name && !node.attributes.map.id) { + tempNode = node.parent; + + if (blockElements[node.name]) { + node.empty().remove(); + } else { + node.unwrap(); + } + + node = tempNode; + return; + } + } + } + } + + node = node.parent; + } + } + }, schema); + + rootNode = node = new Node(args.context || settings.root_name, 11); + + parser.parse(html); + + // Fix invalid children or report invalid children in a contextual parsing + if (validate && invalidChildren.length) { + if (!args.context) { + fixInvalidChildren(invalidChildren); + } else { + args.invalid = true; + } + } + + // Wrap nodes in the root into block elements if the root is body + if (rootBlockName && (rootNode.name == 'body' || args.isRootContent)) { + addRootBlocks(); + } + + // Run filters only when the contents is valid + if (!args.invalid) { + // Run node filters + for (name in matchedNodes) { + list = nodeFilters[name]; + nodes = matchedNodes[name]; + + // Remove already removed children + fi = nodes.length; + while (fi--) { + if (!nodes[fi].parent) { + nodes.splice(fi, 1); + } + } + + for (i = 0, l = list.length; i < l; i++) { + list[i](nodes, name, args); + } + } + + // Run attribute filters + for (i = 0, l = attributeFilters.length; i < l; i++) { + list = attributeFilters[i]; + + if (list.name in matchedAttributes) { + nodes = matchedAttributes[list.name]; + + // Remove already removed children + fi = nodes.length; + while (fi--) { + if (!nodes[fi].parent) { + nodes.splice(fi, 1); + } + } + + for (fi = 0, fl = list.callbacks.length; fi < fl; fi++) { + list.callbacks[fi](nodes, list.name, args); + } + } + } + } + + return rootNode; + }; + + // Remove <br> at end of block elements Gecko and WebKit injects BR elements to + // make it possible to place the caret inside empty blocks. This logic tries to remove + // these elements and keep br elements that where intended to be there intact + if (settings.remove_trailing_brs) { + self.addNodeFilter('br', function(nodes) { + var i, l = nodes.length, node, blockElements = extend({}, schema.getBlockElements()); + var nonEmptyElements = schema.getNonEmptyElements(), parent, lastParent, prev, prevName; + var elementRule, textNode; + + // Remove brs from body element as well + blockElements.body = 1; + + // Must loop forwards since it will otherwise remove all brs in <p>a<br><br><br></p> + for (i = 0; i < l; i++) { + node = nodes[i]; + parent = node.parent; + + if (blockElements[node.parent.name] && node === parent.lastChild) { + // Loop all nodes to the left of the current node and check for other BR elements + // excluding bookmarks since they are invisible + prev = node.prev; + while (prev) { + prevName = prev.name; + + // Ignore bookmarks + if (prevName !== "span" || prev.attr('data-mce-type') !== 'bookmark') { + // Found a non BR element + if (prevName !== "br") { + break; + } + + // Found another br it's a <br><br> structure then don't remove anything + if (prevName === 'br') { + node = null; + break; + } + } + + prev = prev.prev; + } + + if (node) { + node.remove(); + + // Is the parent to be considered empty after we removed the BR + if (parent.isEmpty(nonEmptyElements)) { + elementRule = schema.getElementRule(parent.name); + + // Remove or padd the element depending on schema rule + if (elementRule) { + if (elementRule.removeEmpty) { + parent.remove(); + } else if (elementRule.paddEmpty) { + parent.empty().append(new Node('#text', 3)).value = '\u00a0'; + } + } + } + } + } else { + // Replaces BR elements inside inline elements like <p><b><i><br></i></b></p> + // so they become <p><b><i> </i></b></p> + lastParent = node; + while (parent && parent.firstChild === lastParent && parent.lastChild === lastParent) { + lastParent = parent; + + if (blockElements[parent.name]) { + break; + } + + parent = parent.parent; + } + + if (lastParent === parent) { + textNode = new Node('#text', 3); + textNode.value = '\u00a0'; + node.replace(textNode); + } + } + } + }); + } + + // Force anchor names closed, unless the setting "allow_html_in_named_anchor" is explicitly included. + if (!settings.allow_html_in_named_anchor) { + self.addAttributeFilter('id,name', function(nodes) { + var i = nodes.length, sibling, prevSibling, parent, node; + + while (i--) { + node = nodes[i]; + if (node.name === 'a' && node.firstChild && !node.attr('href')) { + parent = node.parent; + + // Move children after current node + sibling = node.lastChild; + do { + prevSibling = sibling.prev; + parent.insert(sibling, node); + sibling = prevSibling; + } while (sibling); + } + } + }); + } + + if (settings.validate && schema.getValidClasses()) { + self.addAttributeFilter('class', function(nodes) { + var i = nodes.length, node, classList, ci, className, classValue; + var validClasses = schema.getValidClasses(), validClassesMap, valid; + + while (i--) { + node = nodes[i]; + classList = node.attr('class').split(' '); + classValue = ''; + + for (ci = 0; ci < classList.length; ci++) { + className = classList[ci]; + valid = false; + + validClassesMap = validClasses['*']; + if (validClassesMap && validClassesMap[className]) { + valid = true; + } + + validClassesMap = validClasses[node.name]; + if (!valid && validClassesMap && validClassesMap[className]) { + valid = true; + } + + if (valid) { + if (classValue) { + classValue += ' '; + } + + classValue += className; + } + } + + if (!classValue.length) { + classValue = null; + } + + node.attr('class', classValue); + } + }); + } + }; +}); + +// Included from: js/tinymce/classes/html/Writer.js + +/** + * Writer.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class is used to write HTML tags out it can be used with the Serializer or the SaxParser. + * + * @class tinymce.html.Writer + * @example + * var writer = new tinymce.html.Writer({indent: true}); + * var parser = new tinymce.html.SaxParser(writer).parse('<p><br></p>'); + * console.log(writer.getContent()); + * + * @class tinymce.html.Writer + * @version 3.4 + */ +define("tinymce/html/Writer", [ + "tinymce/html/Entities", + "tinymce/util/Tools" +], function(Entities, Tools) { + var makeMap = Tools.makeMap; + + /** + * Constructs a new Writer instance. + * + * @constructor + * @method Writer + * @param {Object} settings Name/value settings object. + */ + return function(settings) { + var html = [], indent, indentBefore, indentAfter, encode, htmlOutput; + + settings = settings || {}; + indent = settings.indent; + indentBefore = makeMap(settings.indent_before || ''); + indentAfter = makeMap(settings.indent_after || ''); + encode = Entities.getEncodeFunc(settings.entity_encoding || 'raw', settings.entities); + htmlOutput = settings.element_format == "html"; + + return { + /** + * Writes the a start element such as <p id="a">. + * + * @method start + * @param {String} name Name of the element. + * @param {Array} attrs Optional attribute array or undefined if it hasn't any. + * @param {Boolean} empty Optional empty state if the tag should end like <br />. + */ + start: function(name, attrs, empty) { + var i, l, attr, value; + + if (indent && indentBefore[name] && html.length > 0) { + value = html[html.length - 1]; + + if (value.length > 0 && value !== '\n') { + html.push('\n'); + } + } + + html.push('<', name); + + if (attrs) { + for (i = 0, l = attrs.length; i < l; i++) { + attr = attrs[i]; + html.push(' ', attr.name, '="', encode(attr.value, true), '"'); + } + } + + if (!empty || htmlOutput) { + html[html.length] = '>'; + } else { + html[html.length] = ' />'; + } + + if (empty && indent && indentAfter[name] && html.length > 0) { + value = html[html.length - 1]; + + if (value.length > 0 && value !== '\n') { + html.push('\n'); + } + } + }, + + /** + * Writes the a end element such as </p>. + * + * @method end + * @param {String} name Name of the element. + */ + end: function(name) { + var value; + + /*if (indent && indentBefore[name] && html.length > 0) { + value = html[html.length - 1]; + + if (value.length > 0 && value !== '\n') + html.push('\n'); + }*/ + + html.push('</', name, '>'); + + if (indent && indentAfter[name] && html.length > 0) { + value = html[html.length - 1]; + + if (value.length > 0 && value !== '\n') { + html.push('\n'); + } + } + }, + + /** + * Writes a text node. + * + * @method text + * @param {String} text String to write out. + * @param {Boolean} raw Optional raw state if true the contents wont get encoded. + */ + text: function(text, raw) { + if (text.length > 0) { + html[html.length] = raw ? text : encode(text); + } + }, + + /** + * Writes a cdata node such as <![CDATA[data]]>. + * + * @method cdata + * @param {String} text String to write out inside the cdata. + */ + cdata: function(text) { + html.push('<![CDATA[', text, ']]>'); + }, + + /** + * Writes a comment node such as <!-- Comment -->. + * + * @method cdata + * @param {String} text String to write out inside the comment. + */ + comment: function(text) { + html.push('<!--', text, '-->'); + }, + + /** + * Writes a PI node such as <?xml attr="value" ?>. + * + * @method pi + * @param {String} name Name of the pi. + * @param {String} text String to write out inside the pi. + */ + pi: function(name, text) { + if (text) { + html.push('<?', name, ' ', encode(text), '?>'); + } else { + html.push('<?', name, '?>'); + } + + if (indent) { + html.push('\n'); + } + }, + + /** + * Writes a doctype node such as <!DOCTYPE data>. + * + * @method doctype + * @param {String} text String to write out inside the doctype. + */ + doctype: function(text) { + html.push('<!DOCTYPE', text, '>', indent ? '\n' : ''); + }, + + /** + * Resets the internal buffer if one wants to reuse the writer. + * + * @method reset + */ + reset: function() { + html.length = 0; + }, + + /** + * Returns the contents that got serialized. + * + * @method getContent + * @return {String} HTML contents that got written down. + */ + getContent: function() { + return html.join('').replace(/\n$/, ''); + } + }; + }; +}); + +// Included from: js/tinymce/classes/html/Serializer.js + +/** + * Serializer.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class is used to serialize down the DOM tree into a string using a Writer instance. + * + * + * @example + * new tinymce.html.Serializer().serialize(new tinymce.html.DomParser().parse('<p>text</p>')); + * @class tinymce.html.Serializer + * @version 3.4 + */ +define("tinymce/html/Serializer", [ + "tinymce/html/Writer", + "tinymce/html/Schema" +], function(Writer, Schema) { + /** + * Constructs a new Serializer instance. + * + * @constructor + * @method Serializer + * @param {Object} settings Name/value settings object. + * @param {tinymce.html.Schema} schema Schema instance to use. + */ + return function(settings, schema) { + var self = this, writer = new Writer(settings); + + settings = settings || {}; + settings.validate = "validate" in settings ? settings.validate : true; + + self.schema = schema = schema || new Schema(); + self.writer = writer; + + /** + * Serializes the specified node into a string. + * + * @example + * new tinymce.html.Serializer().serialize(new tinymce.html.DomParser().parse('<p>text</p>')); + * @method serialize + * @param {tinymce.html.Node} node Node instance to serialize. + * @return {String} String with HTML based on DOM tree. + */ + self.serialize = function(node) { + var handlers, validate; + + validate = settings.validate; + + handlers = { + // #text + 3: function(node) { + writer.text(node.value, node.raw); + }, + + // #comment + 8: function(node) { + writer.comment(node.value); + }, + + // Processing instruction + 7: function(node) { + writer.pi(node.name, node.value); + }, + + // Doctype + 10: function(node) { + writer.doctype(node.value); + }, + + // CDATA + 4: function(node) { + writer.cdata(node.value); + }, + + // Document fragment + 11: function(node) { + if ((node = node.firstChild)) { + do { + walk(node); + } while ((node = node.next)); + } + } + }; + + writer.reset(); + + function walk(node) { + var handler = handlers[node.type], name, isEmpty, attrs, attrName, attrValue, sortedAttrs, i, l, elementRule; + + if (!handler) { + name = node.name; + isEmpty = node.shortEnded; + attrs = node.attributes; + + // Sort attributes + if (validate && attrs && attrs.length > 1) { + sortedAttrs = []; + sortedAttrs.map = {}; + + elementRule = schema.getElementRule(node.name); + if (elementRule) { + for (i = 0, l = elementRule.attributesOrder.length; i < l; i++) { + attrName = elementRule.attributesOrder[i]; + + if (attrName in attrs.map) { + attrValue = attrs.map[attrName]; + sortedAttrs.map[attrName] = attrValue; + sortedAttrs.push({name: attrName, value: attrValue}); + } + } + + for (i = 0, l = attrs.length; i < l; i++) { + attrName = attrs[i].name; + + if (!(attrName in sortedAttrs.map)) { + attrValue = attrs.map[attrName]; + sortedAttrs.map[attrName] = attrValue; + sortedAttrs.push({name: attrName, value: attrValue}); + } + } + + attrs = sortedAttrs; + } + } + + writer.start(node.name, attrs, isEmpty); + + if (!isEmpty) { + if ((node = node.firstChild)) { + do { + walk(node); + } while ((node = node.next)); + } + + writer.end(name); + } + } else { + handler(node); + } + } + + // Serialize element and treat all non elements as fragments + if (node.type == 1 && !settings.inner) { + walk(node); + } else { + handlers[11](node); + } + + return writer.getContent(); + }; + }; +}); + +// Included from: js/tinymce/classes/dom/Serializer.js + +/** + * Serializer.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class is used to serialize DOM trees into a string. Consult the TinyMCE Wiki API for + * more details and examples on how to use this class. + * + * @class tinymce.dom.Serializer + */ +define("tinymce/dom/Serializer", [ + "tinymce/dom/DOMUtils", + "tinymce/html/DomParser", + "tinymce/html/SaxParser", + "tinymce/html/Entities", + "tinymce/html/Serializer", + "tinymce/html/Node", + "tinymce/html/Schema", + "tinymce/Env", + "tinymce/util/Tools", + "tinymce/text/Zwsp" +], function(DOMUtils, DomParser, SaxParser, Entities, Serializer, Node, Schema, Env, Tools, Zwsp) { + var each = Tools.each, trim = Tools.trim; + var DOM = DOMUtils.DOM, tempAttrs = ["data-mce-selected"]; + + /** + * IE 11 has a fantastic bug where it will produce two trailing BR elements to iframe bodies when + * the iframe is hidden by display: none on a parent container. The DOM is actually out of sync + * with innerHTML in this case. It's like IE adds shadow DOM BR elements that appears on innerHTML + * but not as the lastChild of the body. So this fix simply removes the last two + * BR elements at the end of the document. + * + * Example of what happens: <body>text</body> becomes <body>text<br><br></body> + */ + function trimTrailingBr(rootNode) { + var brNode1, brNode2; + + function isBr(node) { + return node && node.name === 'br'; + } + + brNode1 = rootNode.lastChild; + if (isBr(brNode1)) { + brNode2 = brNode1.prev; + + if (isBr(brNode2)) { + brNode1.remove(); + brNode2.remove(); + } + } + } + + /** + * Constructs a new DOM serializer class. + * + * @constructor + * @method Serializer + * @param {Object} settings Serializer settings object. + * @param {tinymce.Editor} editor Optional editor to bind events to and get schema/dom from. + */ + return function(settings, editor) { + var dom, schema, htmlParser; + + if (editor) { + dom = editor.dom; + schema = editor.schema; + } + + function trimHtml(html) { + var trimContentRegExp = new RegExp([ + '<span[^>]+data-mce-bogus[^>]+>[\u200B\uFEFF]+<\\/span>', // Trim bogus spans like caret containers + '\\s?(' + tempAttrs.join('|') + ')="[^"]+"' // Trim temporaty data-mce prefixed attributes like data-mce-selected + ].join('|'), 'gi'); + + html = Zwsp.trim(html.replace(trimContentRegExp, '')); + + return html; + } + + /** + * Returns a trimmed version of the editor contents to be used for the undo level. This + * will remove any data-mce-bogus="all" marked elements since these are used for UI it will also + * remove the data-mce-selected attributes used for selection of objects and caret containers. + * It will keep all data-mce-bogus="1" elements since these can be used to place the caret etc and will + * be removed by the serialization logic when you save. + * + * @private + * @return {String} HTML contents of the editor excluding some internal bogus elements. + */ + function getTrimmedContent() { + var content = editor.getBody().innerHTML; + var bogusAllRegExp = /<(\w+) [^>]*data-mce-bogus="all"[^>]*>/g; + var endTagIndex, index, matchLength, matches, shortEndedElements, schema = editor.schema; + + content = trimHtml(content); + shortEndedElements = schema.getShortEndedElements(); + + // Remove all bogus elements marked with "all" + while ((matches = bogusAllRegExp.exec(content))) { + index = bogusAllRegExp.lastIndex; + matchLength = matches[0].length; + + if (shortEndedElements[matches[1]]) { + endTagIndex = index; + } else { + endTagIndex = SaxParser.findEndTag(schema, content, index); + } + + content = content.substring(0, index - matchLength) + content.substring(endTagIndex); + bogusAllRegExp.lastIndex = index - matchLength; + } + + return trim(content); + } + + function addTempAttr(name) { + if (Tools.inArray(tempAttrs, name) === -1) { + htmlParser.addAttributeFilter(name, function(nodes, name) { + var i = nodes.length; + + while (i--) { + nodes[i].attr(name, null); + } + }); + + tempAttrs.push(name); + } + } + + // Default DOM and Schema if they are undefined + dom = dom || DOM; + schema = schema || new Schema(settings); + settings.entity_encoding = settings.entity_encoding || 'named'; + settings.remove_trailing_brs = "remove_trailing_brs" in settings ? settings.remove_trailing_brs : true; + + htmlParser = new DomParser(settings, schema); + + // Convert tabindex back to elements when serializing contents + htmlParser.addAttributeFilter('data-mce-tabindex', function(nodes, name) { + var i = nodes.length, node; + + while (i--) { + node = nodes[i]; + node.attr('tabindex', node.attributes.map['data-mce-tabindex']); + node.attr(name, null); + } + }); + + // Convert move data-mce-src, data-mce-href and data-mce-style into nodes or process them if needed + htmlParser.addAttributeFilter('src,href,style', function(nodes, name) { + var i = nodes.length, node, value, internalName = 'data-mce-' + name; + var urlConverter = settings.url_converter, urlConverterScope = settings.url_converter_scope, undef; + + while (i--) { + node = nodes[i]; + + value = node.attributes.map[internalName]; + if (value !== undef) { + // Set external name to internal value and remove internal + node.attr(name, value.length > 0 ? value : null); + node.attr(internalName, null); + } else { + // No internal attribute found then convert the value we have in the DOM + value = node.attributes.map[name]; + + if (name === "style") { + value = dom.serializeStyle(dom.parseStyle(value), node.name); + } else if (urlConverter) { + value = urlConverter.call(urlConverterScope, value, name, node.name); + } + + node.attr(name, value.length > 0 ? value : null); + } + } + }); + + // Remove internal classes mceItem<..> or mceSelected + htmlParser.addAttributeFilter('class', function(nodes) { + var i = nodes.length, node, value; + + while (i--) { + node = nodes[i]; + value = node.attr('class'); + + if (value) { + value = node.attr('class').replace(/(?:^|\s)mce-item-\w+(?!\S)/g, ''); + node.attr('class', value.length > 0 ? value : null); + } + } + }); + + // Remove bookmark elements + htmlParser.addAttributeFilter('data-mce-type', function(nodes, name, args) { + var i = nodes.length, node; + + while (i--) { + node = nodes[i]; + + if (node.attributes.map['data-mce-type'] === 'bookmark' && !args.cleanup) { + node.remove(); + } + } + }); + + htmlParser.addNodeFilter('noscript', function(nodes) { + var i = nodes.length, node; + + while (i--) { + node = nodes[i].firstChild; + + if (node) { + node.value = Entities.decode(node.value); + } + } + }); + + // Force script into CDATA sections and remove the mce- prefix also add comments around styles + htmlParser.addNodeFilter('script,style', function(nodes, name) { + var i = nodes.length, node, value, type; + + function trim(value) { + /*jshint maxlen:255 */ + /*eslint max-len:0 */ + return value.replace(/(<!--\[CDATA\[|\]\]-->)/g, '\n') + .replace(/^[\r\n]*|[\r\n]*$/g, '') + .replace(/^\s*((<!--)?(\s*\/\/)?\s*<!\[CDATA\[|(<!--\s*)?\/\*\s*<!\[CDATA\[\s*\*\/|(\/\/)?\s*<!--|\/\*\s*<!--\s*\*\/)\s*[\r\n]*/gi, '') + .replace(/\s*(\/\*\s*\]\]>\s*\*\/(-->)?|\s*\/\/\s*\]\]>(-->)?|\/\/\s*(-->)?|\]\]>|\/\*\s*-->\s*\*\/|\s*-->\s*)\s*$/g, ''); + } + + while (i--) { + node = nodes[i]; + value = node.firstChild ? node.firstChild.value : ''; + + if (name === "script") { + // Remove mce- prefix from script elements and remove default type since the user specified + // a script element without type attribute + type = node.attr('type'); + if (type) { + node.attr('type', type == 'mce-no/type' ? null : type.replace(/^mce\-/, '')); + } + + if (value.length > 0) { + node.firstChild.value = '// <![CDATA[\n' + trim(value) + '\n// ]]>'; + } + } else { + if (value.length > 0) { + node.firstChild.value = '<!--\n' + trim(value) + '\n-->'; + } + } + } + }); + + // Convert comments to cdata and handle protected comments + htmlParser.addNodeFilter('#comment', function(nodes) { + var i = nodes.length, node; + + while (i--) { + node = nodes[i]; + + if (node.value.indexOf('[CDATA[') === 0) { + node.name = '#cdata'; + node.type = 4; + node.value = node.value.replace(/^\[CDATA\[|\]\]$/g, ''); + } else if (node.value.indexOf('mce:protected ') === 0) { + node.name = "#text"; + node.type = 3; + node.raw = true; + node.value = unescape(node.value).substr(14); + } + } + }); + + htmlParser.addNodeFilter('xml:namespace,input', function(nodes, name) { + var i = nodes.length, node; + + while (i--) { + node = nodes[i]; + if (node.type === 7) { + node.remove(); + } else if (node.type === 1) { + if (name === "input" && !("type" in node.attributes.map)) { + node.attr('type', 'text'); + } + } + } + }); + + // Fix list elements, TODO: Replace this later + if (settings.fix_list_elements) { + htmlParser.addNodeFilter('ul,ol', function(nodes) { + var i = nodes.length, node, parentNode; + + while (i--) { + node = nodes[i]; + parentNode = node.parent; + + if (parentNode.name === 'ul' || parentNode.name === 'ol') { + if (node.prev && node.prev.name === 'li') { + node.prev.append(node); + } + } + } + }); + } + + // Remove internal data attributes + htmlParser.addAttributeFilter( + 'data-mce-src,data-mce-href,data-mce-style,' + + 'data-mce-selected,data-mce-expando,' + + 'data-mce-type,data-mce-resize', + + function(nodes, name) { + var i = nodes.length; + + while (i--) { + nodes[i].attr(name, null); + } + } + ); + + // Return public methods + return { + /** + * Schema instance that was used to when the Serializer was constructed. + * + * @field {tinymce.html.Schema} schema + */ + schema: schema, + + /** + * Adds a node filter function to the parser used by the serializer, the parser will collect the specified nodes by name + * and then execute the callback ones it has finished parsing the document. + * + * @example + * parser.addNodeFilter('p,h1', function(nodes, name) { + * for (var i = 0; i < nodes.length; i++) { + * console.log(nodes[i].name); + * } + * }); + * @method addNodeFilter + * @method {String} name Comma separated list of nodes to collect. + * @param {function} callback Callback function to execute once it has collected nodes. + */ + addNodeFilter: htmlParser.addNodeFilter, + + /** + * Adds a attribute filter function to the parser used by the serializer, the parser will + * collect nodes that has the specified attributes + * and then execute the callback ones it has finished parsing the document. + * + * @example + * parser.addAttributeFilter('src,href', function(nodes, name) { + * for (var i = 0; i < nodes.length; i++) { + * console.log(nodes[i].name); + * } + * }); + * @method addAttributeFilter + * @method {String} name Comma separated list of nodes to collect. + * @param {function} callback Callback function to execute once it has collected nodes. + */ + addAttributeFilter: htmlParser.addAttributeFilter, + + /** + * Serializes the specified browser DOM node into a HTML string. + * + * @method serialize + * @param {DOMNode} node DOM node to serialize. + * @param {Object} args Arguments option that gets passed to event handlers. + */ + serialize: function(node, args) { + var self = this, impl, doc, oldDoc, htmlSerializer, content, rootNode; + + // Explorer won't clone contents of script and style and the + // selected index of select elements are cleared on a clone operation. + if (Env.ie && dom.select('script,style,select,map').length > 0) { + content = node.innerHTML; + node = node.cloneNode(false); + dom.setHTML(node, content); + } else { + node = node.cloneNode(true); + } + + // Nodes needs to be attached to something in WebKit/Opera + // This fix will make DOM ranges and make Sizzle happy! + impl = node.ownerDocument.implementation; + if (impl.createHTMLDocument) { + // Create an empty HTML document + doc = impl.createHTMLDocument(""); + + // Add the element or it's children if it's a body element to the new document + each(node.nodeName == 'BODY' ? node.childNodes : [node], function(node) { + doc.body.appendChild(doc.importNode(node, true)); + }); + + // Grab first child or body element for serialization + if (node.nodeName != 'BODY') { + node = doc.body.firstChild; + } else { + node = doc.body; + } + + // set the new document in DOMUtils so createElement etc works + oldDoc = dom.doc; + dom.doc = doc; + } + + args = args || {}; + args.format = args.format || 'html'; + + // Don't wrap content if we want selected html + if (args.selection) { + args.forced_root_block = ''; + } + + // Pre process + if (!args.no_events) { + args.node = node; + self.onPreProcess(args); + } + + // Parse HTML + rootNode = htmlParser.parse(trim(args.getInner ? node.innerHTML : dom.getOuterHTML(node)), args); + trimTrailingBr(rootNode); + + // Serialize HTML + htmlSerializer = new Serializer(settings, schema); + args.content = htmlSerializer.serialize(rootNode); + + // Replace all BOM characters for now until we can find a better solution + if (!args.cleanup) { + args.content = Zwsp.trim(args.content); + args.content = args.content.replace(/\uFEFF/g, ''); + } + + // Post process + if (!args.no_events) { + self.onPostProcess(args); + } + + // Restore the old document if it was changed + if (oldDoc) { + dom.doc = oldDoc; + } + + args.node = null; + + return args.content; + }, + + /** + * Adds valid elements rules to the serializers schema instance this enables you to specify things + * like what elements should be outputted and what attributes specific elements might have. + * Consult the Wiki for more details on this format. + * + * @method addRules + * @param {String} rules Valid elements rules string to add to schema. + */ + addRules: function(rules) { + schema.addValidElements(rules); + }, + + /** + * Sets the valid elements rules to the serializers schema instance this enables you to specify things + * like what elements should be outputted and what attributes specific elements might have. + * Consult the Wiki for more details on this format. + * + * @method setRules + * @param {String} rules Valid elements rules string. + */ + setRules: function(rules) { + schema.setValidElements(rules); + }, + + onPreProcess: function(args) { + if (editor) { + editor.fire('PreProcess', args); + } + }, + + onPostProcess: function(args) { + if (editor) { + editor.fire('PostProcess', args); + } + }, + + /** + * Adds a temporary internal attribute these attributes will get removed on undo and + * when getting contents out of the editor. + * + * @method addTempAttr + * @param {String} name string + */ + addTempAttr: addTempAttr, + + // Internal + trimHtml: trimHtml, + getTrimmedContent: getTrimmedContent + }; + }; +}); + +// Included from: js/tinymce/classes/dom/TridentSelection.js + +/** + * TridentSelection.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Selection class for old explorer versions. This one fakes the + * native selection object available on modern browsers. + * + * @private + * @class tinymce.dom.TridentSelection + */ +define("tinymce/dom/TridentSelection", [], function() { + function Selection(selection) { + var self = this, dom = selection.dom, FALSE = false; + + function getPosition(rng, start) { + var checkRng, startIndex = 0, endIndex, inside, + children, child, offset, index, position = -1, parent; + + // Setup test range, collapse it and get the parent + checkRng = rng.duplicate(); + checkRng.collapse(start); + parent = checkRng.parentElement(); + + // Check if the selection is within the right document + if (parent.ownerDocument !== selection.dom.doc) { + return; + } + + // IE will report non editable elements as it's parent so look for an editable one + while (parent.contentEditable === "false") { + parent = parent.parentNode; + } + + // If parent doesn't have any children then return that we are inside the element + if (!parent.hasChildNodes()) { + return {node: parent, inside: 1}; + } + + // Setup node list and endIndex + children = parent.children; + endIndex = children.length - 1; + + // Perform a binary search for the position + while (startIndex <= endIndex) { + index = Math.floor((startIndex + endIndex) / 2); + + // Move selection to node and compare the ranges + child = children[index]; + checkRng.moveToElementText(child); + position = checkRng.compareEndPoints(start ? 'StartToStart' : 'EndToEnd', rng); + + // Before/after or an exact match + if (position > 0) { + endIndex = index - 1; + } else if (position < 0) { + startIndex = index + 1; + } else { + return {node: child}; + } + } + + // Check if child position is before or we didn't find a position + if (position < 0) { + // No element child was found use the parent element and the offset inside that + if (!child) { + checkRng.moveToElementText(parent); + checkRng.collapse(true); + child = parent; + inside = true; + } else { + checkRng.collapse(false); + } + + // Walk character by character in text node until we hit the selected range endpoint, + // hit the end of document or parent isn't the right one + // We need to walk char by char since rng.text or rng.htmlText will trim line endings + offset = 0; + while (checkRng.compareEndPoints(start ? 'StartToStart' : 'StartToEnd', rng) !== 0) { + if (checkRng.move('character', 1) === 0 || parent != checkRng.parentElement()) { + break; + } + + offset++; + } + } else { + // Child position is after the selection endpoint + checkRng.collapse(true); + + // Walk character by character in text node until we hit the selected range endpoint, hit + // the end of document or parent isn't the right one + offset = 0; + while (checkRng.compareEndPoints(start ? 'StartToStart' : 'StartToEnd', rng) !== 0) { + if (checkRng.move('character', -1) === 0 || parent != checkRng.parentElement()) { + break; + } + + offset++; + } + } + + return {node: child, position: position, offset: offset, inside: inside}; + } + + // Returns a W3C DOM compatible range object by using the IE Range API + function getRange() { + var ieRange = selection.getRng(), domRange = dom.createRng(), element, collapsed, tmpRange, element2, bookmark; + + // If selection is outside the current document just return an empty range + element = ieRange.item ? ieRange.item(0) : ieRange.parentElement(); + if (element.ownerDocument != dom.doc) { + return domRange; + } + + collapsed = selection.isCollapsed(); + + // Handle control selection + if (ieRange.item) { + domRange.setStart(element.parentNode, dom.nodeIndex(element)); + domRange.setEnd(domRange.startContainer, domRange.startOffset + 1); + + return domRange; + } + + function findEndPoint(start) { + var endPoint = getPosition(ieRange, start), container, offset, textNodeOffset = 0, sibling, undef, nodeValue; + + container = endPoint.node; + offset = endPoint.offset; + + if (endPoint.inside && !container.hasChildNodes()) { + domRange[start ? 'setStart' : 'setEnd'](container, 0); + return; + } + + if (offset === undef) { + domRange[start ? 'setStartBefore' : 'setEndAfter'](container); + return; + } + + if (endPoint.position < 0) { + sibling = endPoint.inside ? container.firstChild : container.nextSibling; + + if (!sibling) { + domRange[start ? 'setStartAfter' : 'setEndAfter'](container); + return; + } + + if (!offset) { + if (sibling.nodeType == 3) { + domRange[start ? 'setStart' : 'setEnd'](sibling, 0); + } else { + domRange[start ? 'setStartBefore' : 'setEndBefore'](sibling); + } + + return; + } + + // Find the text node and offset + while (sibling) { + if (sibling.nodeType == 3) { + nodeValue = sibling.nodeValue; + textNodeOffset += nodeValue.length; + + // We are at or passed the position we where looking for + if (textNodeOffset >= offset) { + container = sibling; + textNodeOffset -= offset; + textNodeOffset = nodeValue.length - textNodeOffset; + break; + } + } + + sibling = sibling.nextSibling; + } + } else { + // Find the text node and offset + sibling = container.previousSibling; + + if (!sibling) { + return domRange[start ? 'setStartBefore' : 'setEndBefore'](container); + } + + // If there isn't any text to loop then use the first position + if (!offset) { + if (container.nodeType == 3) { + domRange[start ? 'setStart' : 'setEnd'](sibling, container.nodeValue.length); + } else { + domRange[start ? 'setStartAfter' : 'setEndAfter'](sibling); + } + + return; + } + + while (sibling) { + if (sibling.nodeType == 3) { + textNodeOffset += sibling.nodeValue.length; + + // We are at or passed the position we where looking for + if (textNodeOffset >= offset) { + container = sibling; + textNodeOffset -= offset; + break; + } + } + + sibling = sibling.previousSibling; + } + } + + domRange[start ? 'setStart' : 'setEnd'](container, textNodeOffset); + } + + try { + // Find start point + findEndPoint(true); + + // Find end point if needed + if (!collapsed) { + findEndPoint(); + } + } catch (ex) { + // IE has a nasty bug where text nodes might throw "invalid argument" when you + // access the nodeValue or other properties of text nodes. This seems to happen when + // text nodes are split into two nodes by a delete/backspace call. + // So let us detect and try to fix it. + if (ex.number == -2147024809) { + // Get the current selection + bookmark = self.getBookmark(2); + + // Get start element + tmpRange = ieRange.duplicate(); + tmpRange.collapse(true); + element = tmpRange.parentElement(); + + // Get end element + if (!collapsed) { + tmpRange = ieRange.duplicate(); + tmpRange.collapse(false); + element2 = tmpRange.parentElement(); + element2.innerHTML = element2.innerHTML; + } + + // Remove the broken elements + element.innerHTML = element.innerHTML; + + // Restore the selection + self.moveToBookmark(bookmark); + + // Since the range has moved we need to re-get it + ieRange = selection.getRng(); + + // Find start point + findEndPoint(true); + + // Find end point if needed + if (!collapsed) { + findEndPoint(); + } + } else { + throw ex; // Throw other errors + } + } + + return domRange; + } + + this.getBookmark = function(type) { + var rng = selection.getRng(), bookmark = {}; + + function getIndexes(node) { + var parent, root, children, i, indexes = []; + + parent = node.parentNode; + root = dom.getRoot().parentNode; + + while (parent != root && parent.nodeType !== 9) { + children = parent.children; + + i = children.length; + while (i--) { + if (node === children[i]) { + indexes.push(i); + break; + } + } + + node = parent; + parent = parent.parentNode; + } + + return indexes; + } + + function getBookmarkEndPoint(start) { + var position; + + position = getPosition(rng, start); + if (position) { + return { + position: position.position, + offset: position.offset, + indexes: getIndexes(position.node), + inside: position.inside + }; + } + } + + // Non ubstructive bookmark + if (type === 2) { + // Handle text selection + if (!rng.item) { + bookmark.start = getBookmarkEndPoint(true); + + if (!selection.isCollapsed()) { + bookmark.end = getBookmarkEndPoint(); + } + } else { + bookmark.start = {ctrl: true, indexes: getIndexes(rng.item(0))}; + } + } + + return bookmark; + }; + + this.moveToBookmark = function(bookmark) { + var rng, body = dom.doc.body; + + function resolveIndexes(indexes) { + var node, i, idx, children; + + node = dom.getRoot(); + for (i = indexes.length - 1; i >= 0; i--) { + children = node.children; + idx = indexes[i]; + + if (idx <= children.length - 1) { + node = children[idx]; + } + } + + return node; + } + + function setBookmarkEndPoint(start) { + var endPoint = bookmark[start ? 'start' : 'end'], moveLeft, moveRng, undef, offset; + + if (endPoint) { + moveLeft = endPoint.position > 0; + + moveRng = body.createTextRange(); + moveRng.moveToElementText(resolveIndexes(endPoint.indexes)); + + offset = endPoint.offset; + if (offset !== undef) { + moveRng.collapse(endPoint.inside || moveLeft); + moveRng.moveStart('character', moveLeft ? -offset : offset); + } else { + moveRng.collapse(start); + } + + rng.setEndPoint(start ? 'StartToStart' : 'EndToStart', moveRng); + + if (start) { + rng.collapse(true); + } + } + } + + if (bookmark.start) { + if (bookmark.start.ctrl) { + rng = body.createControlRange(); + rng.addElement(resolveIndexes(bookmark.start.indexes)); + rng.select(); + } else { + rng = body.createTextRange(); + setBookmarkEndPoint(true); + setBookmarkEndPoint(); + rng.select(); + } + } + }; + + this.addRange = function(rng) { + var ieRng, ctrlRng, startContainer, startOffset, endContainer, endOffset, sibling, + doc = selection.dom.doc, body = doc.body, nativeRng, ctrlElm; + + function setEndPoint(start) { + var container, offset, marker, tmpRng, nodes; + + marker = dom.create('a'); + container = start ? startContainer : endContainer; + offset = start ? startOffset : endOffset; + tmpRng = ieRng.duplicate(); + + if (container == doc || container == doc.documentElement) { + container = body; + offset = 0; + } + + if (container.nodeType == 3) { + container.parentNode.insertBefore(marker, container); + tmpRng.moveToElementText(marker); + tmpRng.moveStart('character', offset); + dom.remove(marker); + ieRng.setEndPoint(start ? 'StartToStart' : 'EndToEnd', tmpRng); + } else { + nodes = container.childNodes; + + if (nodes.length) { + if (offset >= nodes.length) { + dom.insertAfter(marker, nodes[nodes.length - 1]); + } else { + container.insertBefore(marker, nodes[offset]); + } + + tmpRng.moveToElementText(marker); + } else if (container.canHaveHTML) { + // Empty node selection for example <div>|</div> + // Setting innerHTML with a span marker then remove that marker seems to keep empty block elements open + container.innerHTML = '<span></span>'; + marker = container.firstChild; + tmpRng.moveToElementText(marker); + tmpRng.collapse(FALSE); // Collapse false works better than true for some odd reason + } + + ieRng.setEndPoint(start ? 'StartToStart' : 'EndToEnd', tmpRng); + dom.remove(marker); + } + } + + // Setup some shorter versions + startContainer = rng.startContainer; + startOffset = rng.startOffset; + endContainer = rng.endContainer; + endOffset = rng.endOffset; + ieRng = body.createTextRange(); + + // If single element selection then try making a control selection out of it + if (startContainer == endContainer && startContainer.nodeType == 1) { + // Trick to place the caret inside an empty block element like <p></p> + if (startOffset == endOffset && !startContainer.hasChildNodes()) { + if (startContainer.canHaveHTML) { + // Check if previous sibling is an empty block if it is then we need to render it + // IE would otherwise move the caret into the sibling instead of the empty startContainer see: #5236 + // Example this: <p></p><p>|</p> would become this: <p>|</p><p></p> + sibling = startContainer.previousSibling; + if (sibling && !sibling.hasChildNodes() && dom.isBlock(sibling)) { + sibling.innerHTML = ''; + } else { + sibling = null; + } + + startContainer.innerHTML = '<span></span><span></span>'; + ieRng.moveToElementText(startContainer.lastChild); + ieRng.select(); + dom.doc.selection.clear(); + startContainer.innerHTML = ''; + + if (sibling) { + sibling.innerHTML = ''; + } + return; + } + + startOffset = dom.nodeIndex(startContainer); + startContainer = startContainer.parentNode; + } + + if (startOffset == endOffset - 1) { + try { + ctrlElm = startContainer.childNodes[startOffset]; + ctrlRng = body.createControlRange(); + ctrlRng.addElement(ctrlElm); + ctrlRng.select(); + + // Check if the range produced is on the correct element and is a control range + // On IE 8 it will select the parent contentEditable container if you select an inner element see: #5398 + nativeRng = selection.getRng(); + if (nativeRng.item && ctrlElm === nativeRng.item(0)) { + return; + } + } catch (ex) { + // Ignore + } + } + } + + // Set start/end point of selection + setEndPoint(true); + setEndPoint(); + + // Select the new range and scroll it into view + ieRng.select(); + }; + + // Expose range method + this.getRangeAt = getRange; + } + + return Selection; +}); + +// Included from: js/tinymce/classes/util/VK.js + +/** + * VK.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This file exposes a set of the common KeyCodes for use. Please grow it as needed. + */ +define("tinymce/util/VK", [ + "tinymce/Env" +], function(Env) { + return { + BACKSPACE: 8, + DELETE: 46, + DOWN: 40, + ENTER: 13, + LEFT: 37, + RIGHT: 39, + SPACEBAR: 32, + TAB: 9, + UP: 38, + + modifierPressed: function(e) { + return e.shiftKey || e.ctrlKey || e.altKey || this.metaKeyPressed(e); + }, + + metaKeyPressed: function(e) { + // Check if ctrl or meta key is pressed. Edge case for AltGr on Windows where it produces ctrlKey+altKey states + return (Env.mac ? e.metaKey : e.ctrlKey && !e.altKey); + } + }; +}); + +// Included from: js/tinymce/classes/dom/ControlSelection.js + +/** + * ControlSelection.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class handles control selection of elements. Controls are elements + * that can be resized and needs to be selected as a whole. It adds custom resize handles + * to all browser engines that support properly disabling the built in resize logic. + * + * @class tinymce.dom.ControlSelection + */ +define("tinymce/dom/ControlSelection", [ + "tinymce/util/VK", + "tinymce/util/Tools", + "tinymce/util/Delay", + "tinymce/Env", + "tinymce/dom/NodeType" +], function(VK, Tools, Delay, Env, NodeType) { + var isContentEditableFalse = NodeType.isContentEditableFalse; + + return function(selection, editor) { + var dom = editor.dom, each = Tools.each; + var selectedElm, selectedElmGhost, resizeHelper, resizeHandles, selectedHandle, lastMouseDownEvent; + var startX, startY, selectedElmX, selectedElmY, startW, startH, ratio, resizeStarted; + var width, height, editableDoc = editor.getDoc(), rootDocument = document, isIE = Env.ie && Env.ie < 11; + var abs = Math.abs, round = Math.round, rootElement = editor.getBody(), startScrollWidth, startScrollHeight; + + // Details about each resize handle how to scale etc + resizeHandles = { + // Name: x multiplier, y multiplier, delta size x, delta size y + /*n: [0.5, 0, 0, -1], + e: [1, 0.5, 1, 0], + s: [0.5, 1, 0, 1], + w: [0, 0.5, -1, 0],*/ + nw: [0, 0, -1, -1], + ne: [1, 0, 1, -1], + se: [1, 1, 1, 1], + sw: [0, 1, -1, 1] + }; + + // Add CSS for resize handles, cloned element and selected + var rootClass = '.mce-content-body'; + editor.contentStyles.push( + rootClass + ' div.mce-resizehandle {' + + 'position: absolute;' + + 'border: 1px solid black;' + + 'box-sizing: box-sizing;' + + 'background: #FFF;' + + 'width: 7px;' + + 'height: 7px;' + + 'z-index: 10000' + + '}' + + rootClass + ' .mce-resizehandle:hover {' + + 'background: #000' + + '}' + + rootClass + ' img[data-mce-selected],' + rootClass + ' hr[data-mce-selected] {' + + 'outline: 1px solid black;' + + 'resize: none' + // Have been talks about implementing this in browsers + '}' + + rootClass + ' .mce-clonedresizable {' + + 'position: absolute;' + + (Env.gecko ? '' : 'outline: 1px dashed black;') + // Gecko produces trails while resizing + 'opacity: .5;' + + 'filter: alpha(opacity=50);' + + 'z-index: 10000' + + '}' + + rootClass + ' .mce-resize-helper {' + + 'background: #555;' + + 'background: rgba(0,0,0,0.75);' + + 'border-radius: 3px;' + + 'border: 1px;' + + 'color: white;' + + 'display: none;' + + 'font-family: sans-serif;' + + 'font-size: 12px;' + + 'white-space: nowrap;' + + 'line-height: 14px;' + + 'margin: 5px 10px;' + + 'padding: 5px;' + + 'position: absolute;' + + 'z-index: 10001' + + '}' + ); + + function isResizable(elm) { + var selector = editor.settings.object_resizing; + + if (selector === false || Env.iOS) { + return false; + } + + if (typeof selector != 'string') { + selector = 'table,img,div'; + } + + if (elm.getAttribute('data-mce-resize') === 'false') { + return false; + } + + if (elm == editor.getBody()) { + return false; + } + + return editor.dom.is(elm, selector); + } + + function resizeGhostElement(e) { + var deltaX, deltaY, proportional; + var resizeHelperX, resizeHelperY; + + // Calc new width/height + deltaX = e.screenX - startX; + deltaY = e.screenY - startY; + + // Calc new size + width = deltaX * selectedHandle[2] + startW; + height = deltaY * selectedHandle[3] + startH; + + // Never scale down lower than 5 pixels + width = width < 5 ? 5 : width; + height = height < 5 ? 5 : height; + + if (selectedElm.nodeName == "IMG" && editor.settings.resize_img_proportional !== false) { + proportional = !VK.modifierPressed(e); + } else { + proportional = VK.modifierPressed(e) || (selectedElm.nodeName == "IMG" && selectedHandle[2] * selectedHandle[3] !== 0); + } + + // Constrain proportions + if (proportional) { + if (abs(deltaX) > abs(deltaY)) { + height = round(width * ratio); + width = round(height / ratio); + } else { + width = round(height / ratio); + height = round(width * ratio); + } + } + + // Update ghost size + dom.setStyles(selectedElmGhost, { + width: width, + height: height + }); + + // Update resize helper position + resizeHelperX = selectedHandle.startPos.x + deltaX; + resizeHelperY = selectedHandle.startPos.y + deltaY; + resizeHelperX = resizeHelperX > 0 ? resizeHelperX : 0; + resizeHelperY = resizeHelperY > 0 ? resizeHelperY : 0; + + dom.setStyles(resizeHelper, { + left: resizeHelperX, + top: resizeHelperY, + display: 'block' + }); + + resizeHelper.innerHTML = width + ' × ' + height; + + // Update ghost X position if needed + if (selectedHandle[2] < 0 && selectedElmGhost.clientWidth <= width) { + dom.setStyle(selectedElmGhost, 'left', selectedElmX + (startW - width)); + } + + // Update ghost Y position if needed + if (selectedHandle[3] < 0 && selectedElmGhost.clientHeight <= height) { + dom.setStyle(selectedElmGhost, 'top', selectedElmY + (startH - height)); + } + + // Calculate how must overflow we got + deltaX = rootElement.scrollWidth - startScrollWidth; + deltaY = rootElement.scrollHeight - startScrollHeight; + + // Re-position the resize helper based on the overflow + if (deltaX + deltaY !== 0) { + dom.setStyles(resizeHelper, { + left: resizeHelperX - deltaX, + top: resizeHelperY - deltaY + }); + } + + if (!resizeStarted) { + editor.fire('ObjectResizeStart', {target: selectedElm, width: startW, height: startH}); + resizeStarted = true; + } + } + + function endGhostResize() { + resizeStarted = false; + + function setSizeProp(name, value) { + if (value) { + // Resize by using style or attribute + if (selectedElm.style[name] || !editor.schema.isValid(selectedElm.nodeName.toLowerCase(), name)) { + dom.setStyle(selectedElm, name, value); + } else { + dom.setAttrib(selectedElm, name, value); + } + } + } + + // Set width/height properties + setSizeProp('width', width); + setSizeProp('height', height); + + dom.unbind(editableDoc, 'mousemove', resizeGhostElement); + dom.unbind(editableDoc, 'mouseup', endGhostResize); + + if (rootDocument != editableDoc) { + dom.unbind(rootDocument, 'mousemove', resizeGhostElement); + dom.unbind(rootDocument, 'mouseup', endGhostResize); + } + + // Remove ghost/helper and update resize handle positions + dom.remove(selectedElmGhost); + dom.remove(resizeHelper); + + if (!isIE || selectedElm.nodeName == "TABLE") { + showResizeRect(selectedElm); + } + + editor.fire('ObjectResized', {target: selectedElm, width: width, height: height}); + dom.setAttrib(selectedElm, 'style', dom.getAttrib(selectedElm, 'style')); + editor.nodeChanged(); + } + + function showResizeRect(targetElm, mouseDownHandleName, mouseDownEvent) { + var position, targetWidth, targetHeight, e, rect; + + hideResizeRect(); + unbindResizeHandleEvents(); + + // Get position and size of target + position = dom.getPos(targetElm, rootElement); + selectedElmX = position.x; + selectedElmY = position.y; + rect = targetElm.getBoundingClientRect(); // Fix for Gecko offsetHeight for table with caption + targetWidth = rect.width || (rect.right - rect.left); + targetHeight = rect.height || (rect.bottom - rect.top); + + // Reset width/height if user selects a new image/table + if (selectedElm != targetElm) { + detachResizeStartListener(); + selectedElm = targetElm; + width = height = 0; + } + + // Makes it possible to disable resizing + e = editor.fire('ObjectSelected', {target: targetElm}); + + if (isResizable(targetElm) && !e.isDefaultPrevented()) { + each(resizeHandles, function(handle, name) { + var handleElm; + + function startDrag(e) { + startX = e.screenX; + startY = e.screenY; + startW = selectedElm.clientWidth; + startH = selectedElm.clientHeight; + ratio = startH / startW; + selectedHandle = handle; + + handle.startPos = { + x: targetWidth * handle[0] + selectedElmX, + y: targetHeight * handle[1] + selectedElmY + }; + + startScrollWidth = rootElement.scrollWidth; + startScrollHeight = rootElement.scrollHeight; + + selectedElmGhost = selectedElm.cloneNode(true); + dom.addClass(selectedElmGhost, 'mce-clonedresizable'); + dom.setAttrib(selectedElmGhost, 'data-mce-bogus', 'all'); + selectedElmGhost.contentEditable = false; // Hides IE move layer cursor + selectedElmGhost.unSelectabe = true; + dom.setStyles(selectedElmGhost, { + left: selectedElmX, + top: selectedElmY, + margin: 0 + }); + + selectedElmGhost.removeAttribute('data-mce-selected'); + rootElement.appendChild(selectedElmGhost); + + dom.bind(editableDoc, 'mousemove', resizeGhostElement); + dom.bind(editableDoc, 'mouseup', endGhostResize); + + if (rootDocument != editableDoc) { + dom.bind(rootDocument, 'mousemove', resizeGhostElement); + dom.bind(rootDocument, 'mouseup', endGhostResize); + } + + resizeHelper = dom.add(rootElement, 'div', { + 'class': 'mce-resize-helper', + 'data-mce-bogus': 'all' + }, startW + ' × ' + startH); + } + + if (mouseDownHandleName) { + // Drag started by IE native resizestart + if (name == mouseDownHandleName) { + startDrag(mouseDownEvent); + } + + return; + } + + // Get existing or render resize handle + handleElm = dom.get('mceResizeHandle' + name); + if (handleElm) { + dom.remove(handleElm); + } + + handleElm = dom.add(rootElement, 'div', { + id: 'mceResizeHandle' + name, + 'data-mce-bogus': 'all', + 'class': 'mce-resizehandle', + unselectable: true, + style: 'cursor:' + name + '-resize; margin:0; padding:0' + }); + + // Hides IE move layer cursor + // If we set it on Chrome we get this wounderful bug: #6725 + if (Env.ie) { + handleElm.contentEditable = false; + } + + dom.bind(handleElm, 'mousedown', function(e) { + e.stopImmediatePropagation(); + e.preventDefault(); + startDrag(e); + }); + + handle.elm = handleElm; + + // Position element + dom.setStyles(handleElm, { + left: (targetWidth * handle[0] + selectedElmX) - (handleElm.offsetWidth / 2), + top: (targetHeight * handle[1] + selectedElmY) - (handleElm.offsetHeight / 2) + }); + }); + } else { + hideResizeRect(); + } + + selectedElm.setAttribute('data-mce-selected', '1'); + } + + function hideResizeRect() { + var name, handleElm; + + unbindResizeHandleEvents(); + + if (selectedElm) { + selectedElm.removeAttribute('data-mce-selected'); + } + + for (name in resizeHandles) { + handleElm = dom.get('mceResizeHandle' + name); + if (handleElm) { + dom.unbind(handleElm); + dom.remove(handleElm); + } + } + } + + function updateResizeRect(e) { + var startElm, controlElm; + + function isChildOrEqual(node, parent) { + if (node) { + do { + if (node === parent) { + return true; + } + } while ((node = node.parentNode)); + } + } + + // Ignore all events while resizing or if the editor instance was removed + if (resizeStarted || editor.removed) { + return; + } + + // Remove data-mce-selected from all elements since they might have been copied using Ctrl+c/v + each(dom.select('img[data-mce-selected],hr[data-mce-selected]'), function(img) { + img.removeAttribute('data-mce-selected'); + }); + + controlElm = e.type == 'mousedown' ? e.target : selection.getNode(); + controlElm = dom.$(controlElm).closest(isIE ? 'table' : 'table,img,hr')[0]; + + if (isChildOrEqual(controlElm, rootElement)) { + disableGeckoResize(); + startElm = selection.getStart(true); + + if (isChildOrEqual(startElm, controlElm) && isChildOrEqual(selection.getEnd(true), controlElm)) { + if (!isIE || (controlElm != startElm && startElm.nodeName !== 'IMG')) { + showResizeRect(controlElm); + return; + } + } + } + + hideResizeRect(); + } + + function attachEvent(elm, name, func) { + if (elm && elm.attachEvent) { + elm.attachEvent('on' + name, func); + } + } + + function detachEvent(elm, name, func) { + if (elm && elm.detachEvent) { + elm.detachEvent('on' + name, func); + } + } + + function resizeNativeStart(e) { + var target = e.srcElement, pos, name, corner, cornerX, cornerY, relativeX, relativeY; + + pos = target.getBoundingClientRect(); + relativeX = lastMouseDownEvent.clientX - pos.left; + relativeY = lastMouseDownEvent.clientY - pos.top; + + // Figure out what corner we are draging on + for (name in resizeHandles) { + corner = resizeHandles[name]; + + cornerX = target.offsetWidth * corner[0]; + cornerY = target.offsetHeight * corner[1]; + + if (abs(cornerX - relativeX) < 8 && abs(cornerY - relativeY) < 8) { + selectedHandle = corner; + break; + } + } + + // Remove native selection and let the magic begin + resizeStarted = true; + editor.fire('ObjectResizeStart', { + target: selectedElm, + width: selectedElm.clientWidth, + height: selectedElm.clientHeight + }); + editor.getDoc().selection.empty(); + showResizeRect(target, name, lastMouseDownEvent); + } + + function preventDefault(e) { + if (e.preventDefault) { + e.preventDefault(); + } else { + e.returnValue = false; // IE + } + } + + function nativeControlSelect(e) { + var target = e.srcElement; + + if (isContentEditableFalse(target)) { + preventDefault(e); + return; + } + + if (target != selectedElm) { + editor.fire('ObjectSelected', {target: target}); + detachResizeStartListener(); + + if (target.id.indexOf('mceResizeHandle') === 0) { + e.returnValue = false; + return; + } + + if (target.nodeName == 'IMG' || target.nodeName == 'TABLE') { + hideResizeRect(); + selectedElm = target; + attachEvent(target, 'resizestart', resizeNativeStart); + } + } + } + + function detachResizeStartListener() { + detachEvent(selectedElm, 'resizestart', resizeNativeStart); + } + + function unbindResizeHandleEvents() { + for (var name in resizeHandles) { + var handle = resizeHandles[name]; + + if (handle.elm) { + dom.unbind(handle.elm); + delete handle.elm; + } + } + } + + function disableGeckoResize() { + try { + // Disable object resizing on Gecko + editor.getDoc().execCommand('enableObjectResizing', false, false); + } catch (ex) { + // Ignore + } + } + + function controlSelect(elm) { + var ctrlRng; + + if (!isIE) { + return; + } + + ctrlRng = editableDoc.body.createControlRange(); + + try { + ctrlRng.addElement(elm); + ctrlRng.select(); + return true; + } catch (ex) { + // Ignore since the element can't be control selected for example a P tag + } + } + + editor.on('init', function() { + if (isIE) { + // Hide the resize rect on resize and reselect the image + editor.on('ObjectResized', function(e) { + if (e.target.nodeName != 'TABLE') { + hideResizeRect(); + controlSelect(e.target); + } + }); + + attachEvent(rootElement, 'controlselect', nativeControlSelect); + + editor.on('mousedown', function(e) { + lastMouseDownEvent = e; + }); + } else { + disableGeckoResize(); + + // Sniff sniff, hard to feature detect this stuff + if (Env.ie >= 11) { + // Needs to be mousedown for drag/drop to work on IE 11 + // Needs to be click on Edge to properly select images + editor.on('mousedown click', function(e) { + var nodeName = e.target.nodeName; + + if (!resizeStarted && /^(TABLE|IMG|HR)$/.test(nodeName)) { + editor.selection.select(e.target, nodeName == 'TABLE'); + + // Only fire once since nodeChange is expensive + if (e.type == 'mousedown') { + editor.nodeChanged(); + } + } + }); + + editor.dom.bind(rootElement, 'mscontrolselect', function(e) { + function delayedSelect(node) { + Delay.setEditorTimeout(editor, function() { + editor.selection.select(node); + }); + } + + if (isContentEditableFalse(e.target)) { + e.preventDefault(); + delayedSelect(e.target); + return; + } + + if (/^(TABLE|IMG|HR)$/.test(e.target.nodeName)) { + e.preventDefault(); + + // This moves the selection from being a control selection to a text like selection like in WebKit #6753 + // TODO: Fix this the day IE works like other browsers without this nasty native ugly control selections. + if (e.target.tagName == 'IMG') { + delayedSelect(e.target); + } + } + }); + } + } + + var throttledUpdateResizeRect = Delay.throttle(function(e) { + if (!editor.composing) { + updateResizeRect(e); + } + }); + + editor.on('nodechange ResizeEditor ResizeWindow drop', throttledUpdateResizeRect); + + // Update resize rect while typing in a table + editor.on('keyup compositionend', function(e) { + // Don't update the resize rect while composing since it blows away the IME see: #2710 + if (selectedElm && selectedElm.nodeName == "TABLE") { + throttledUpdateResizeRect(e); + } + }); + + editor.on('hide blur', hideResizeRect); + + // Hide rect on focusout since it would float on top of windows otherwise + //editor.on('focusout', hideResizeRect); + }); + + editor.on('remove', unbindResizeHandleEvents); + + function destroy() { + selectedElm = selectedElmGhost = null; + + if (isIE) { + detachResizeStartListener(); + detachEvent(rootElement, 'controlselect', nativeControlSelect); + } + } + + return { + isResizable: isResizable, + showResizeRect: showResizeRect, + hideResizeRect: hideResizeRect, + updateResizeRect: updateResizeRect, + controlSelect: controlSelect, + destroy: destroy + }; + }; +}); + +// Included from: js/tinymce/classes/util/Fun.js + +/** + * Fun.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Functional utility class. + * + * @private + * @class tinymce.util.Fun + */ +define("tinymce/util/Fun", [], function() { + var slice = [].slice; + + function constant(value) { + return function() { + return value; + }; + } + + function negate(predicate) { + return function(x) { + return !predicate(x); + }; + } + + function compose(f, g) { + return function(x) { + return f(g(x)); + }; + } + + function or() { + var args = slice.call(arguments); + + return function(x) { + for (var i = 0; i < args.length; i++) { + if (args[i](x)) { + return true; + } + } + + return false; + }; + } + + function and() { + var args = slice.call(arguments); + + return function(x) { + for (var i = 0; i < args.length; i++) { + if (!args[i](x)) { + return false; + } + } + + return true; + }; + } + + function curry(fn) { + var args = slice.call(arguments); + + if (args.length - 1 >= fn.length) { + return fn.apply(this, args.slice(1)); + } + + return function() { + var tempArgs = args.concat([].slice.call(arguments)); + return curry.apply(this, tempArgs); + }; + } + + return { + constant: constant, + negate: negate, + and: and, + or: or, + curry: curry, + compose: compose + }; +}); + +// Included from: js/tinymce/classes/caret/CaretCandidate.js + +/** + * CaretCandidate.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This module contains logic for handling caret candidates. A caret candidate is + * for example text nodes, images, input elements, cE=false elements etc. + * + * @private + * @class tinymce.caret.CaretCandidate + */ +define("tinymce/caret/CaretCandidate", [ + "tinymce/dom/NodeType", + "tinymce/util/Arr", + "tinymce/caret/CaretContainer" +], function(NodeType, Arr, CaretContainer) { + var isContentEditableTrue = NodeType.isContentEditableTrue, + isContentEditableFalse = NodeType.isContentEditableFalse, + isBr = NodeType.isBr, + isText = NodeType.isText, + isInvalidTextElement = NodeType.matchNodeNames('script style textarea'), + isAtomicInline = NodeType.matchNodeNames('img input textarea hr iframe video audio object'), + isTable = NodeType.matchNodeNames('table'), + isCaretContainer = CaretContainer.isCaretContainer; + + function isCaretCandidate(node) { + if (isCaretContainer(node)) { + return false; + } + + if (isText(node)) { + if (isInvalidTextElement(node.parentNode)) { + return false; + } + + return true; + } + + return isAtomicInline(node) || isBr(node) || isTable(node) || isContentEditableFalse(node); + } + + function isInEditable(node, rootNode) { + for (node = node.parentNode; node && node != rootNode; node = node.parentNode) { + if (isContentEditableFalse(node)) { + return false; + } + + if (isContentEditableTrue(node)) { + return true; + } + } + + return true; + } + + function isAtomicContentEditableFalse(node) { + if (!isContentEditableFalse(node)) { + return false; + } + + return Arr.reduce(node.getElementsByTagName('*'), function(result, elm) { + return result || isContentEditableTrue(elm); + }, false) !== true; + } + + function isAtomic(node) { + return isAtomicInline(node) || isAtomicContentEditableFalse(node); + } + + function isEditableCaretCandidate(node, rootNode) { + return isCaretCandidate(node) && isInEditable(node, rootNode); + } + + return { + isCaretCandidate: isCaretCandidate, + isInEditable: isInEditable, + isAtomic: isAtomic, + isEditableCaretCandidate: isEditableCaretCandidate + }; +}); + +// Included from: js/tinymce/classes/geom/ClientRect.js + +/** + * ClientRect.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Utility functions for working with client rects. + * + * @private + * @class tinymce.geom.ClientRect + */ +define("tinymce/geom/ClientRect", [], function() { + var round = Math.round; + + function clone(rect) { + if (!rect) { + return {left: 0, top: 0, bottom: 0, right: 0, width: 0, height: 0}; + } + + return { + left: round(rect.left), + top: round(rect.top), + bottom: round(rect.bottom), + right: round(rect.right), + width: round(rect.width), + height: round(rect.height) + }; + } + + function collapse(clientRect, toStart) { + clientRect = clone(clientRect); + + if (toStart) { + clientRect.right = clientRect.left; + } else { + clientRect.left = clientRect.left + clientRect.width; + clientRect.right = clientRect.left; + } + + clientRect.width = 0; + + return clientRect; + } + + function isEqual(rect1, rect2) { + return ( + rect1.left === rect2.left && + rect1.top === rect2.top && + rect1.bottom === rect2.bottom && + rect1.right === rect2.right + ); + } + + function isValidOverflow(overflowY, clientRect1, clientRect2) { + return overflowY >= 0 && overflowY <= Math.min(clientRect1.height, clientRect2.height) / 2; + + } + + function isAbove(clientRect1, clientRect2) { + if (clientRect1.bottom < clientRect2.top) { + return true; + } + + if (clientRect1.top > clientRect2.bottom) { + return false; + } + + return isValidOverflow(clientRect2.top - clientRect1.bottom, clientRect1, clientRect2); + } + + function isBelow(clientRect1, clientRect2) { + if (clientRect1.top > clientRect2.bottom) { + return true; + } + + if (clientRect1.bottom < clientRect2.top) { + return false; + } + + return isValidOverflow(clientRect2.bottom - clientRect1.top, clientRect1, clientRect2); + } + + function isLeft(clientRect1, clientRect2) { + return clientRect1.left < clientRect2.left; + } + + function isRight(clientRect1, clientRect2) { + return clientRect1.right > clientRect2.right; + } + + function compare(clientRect1, clientRect2) { + if (isAbove(clientRect1, clientRect2)) { + return -1; + } + + if (isBelow(clientRect1, clientRect2)) { + return 1; + } + + if (isLeft(clientRect1, clientRect2)) { + return -1; + } + + if (isRight(clientRect1, clientRect2)) { + return 1; + } + + return 0; + } + + function containsXY(clientRect, clientX, clientY) { + return ( + clientX >= clientRect.left && + clientX <= clientRect.right && + clientY >= clientRect.top && + clientY <= clientRect.bottom + ); + } + + return { + clone: clone, + collapse: collapse, + isEqual: isEqual, + isAbove: isAbove, + isBelow: isBelow, + isLeft: isLeft, + isRight: isRight, + compare: compare, + containsXY: containsXY + }; +}); + +// Included from: js/tinymce/classes/text/ExtendingChar.js + +/** + * ExtendingChar.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class contains logic for detecting extending characters. + * + * @private + * @class tinymce.text.ExtendingChar + * @example + * var isExtending = ExtendingChar.isExtendingChar('a'); + */ +define("tinymce/text/ExtendingChar", [], function() { + // Generated from: http://www.unicode.org/Public/UNIDATA/DerivedCoreProperties.txt + // Only includes the characters in that fit into UCS-2 16 bit + var extendingChars = new RegExp( + "[\u0300-\u036F\u0483-\u0487\u0488-\u0489\u0591-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u061A" + + "\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0" + + "\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E3-\u0902\u093A\u093C" + + "\u0941-\u0948\u094D\u0951-\u0957\u0962-\u0963\u0981\u09BC\u09BE\u09C1-\u09C4\u09CD\u09D7\u09E2-\u09E3" + + "\u0A01-\u0A02\u0A3C\u0A41-\u0A42\u0A47-\u0A48\u0A4B-\u0A4D\u0A51\u0A70-\u0A71\u0A75\u0A81-\u0A82\u0ABC" + + "\u0AC1-\u0AC5\u0AC7-\u0AC8\u0ACD\u0AE2-\u0AE3\u0B01\u0B3C\u0B3E\u0B3F\u0B41-\u0B44\u0B4D\u0B56\u0B57" + + "\u0B62-\u0B63\u0B82\u0BBE\u0BC0\u0BCD\u0BD7\u0C00\u0C3E-\u0C40\u0C46-\u0C48\u0C4A-\u0C4D\u0C55-\u0C56" + + "\u0C62-\u0C63\u0C81\u0CBC\u0CBF\u0CC2\u0CC6\u0CCC-\u0CCD\u0CD5-\u0CD6\u0CE2-\u0CE3\u0D01\u0D3E\u0D41-\u0D44" + + "\u0D4D\u0D57\u0D62-\u0D63\u0DCA\u0DCF\u0DD2-\u0DD4\u0DD6\u0DDF\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9" + + "\u0EBB-\u0EBC\u0EC8-\u0ECD\u0F18-\u0F19\u0F35\u0F37\u0F39\u0F71-\u0F7E\u0F80-\u0F84\u0F86-\u0F87\u0F8D-\u0F97" + + "\u0F99-\u0FBC\u0FC6\u102D-\u1030\u1032-\u1037\u1039-\u103A\u103D-\u103E\u1058-\u1059\u105E-\u1060\u1071-\u1074" + + "\u1082\u1085-\u1086\u108D\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752-\u1753\u1772-\u1773\u17B4-\u17B5" + + "\u17B7-\u17BD\u17C6\u17C9-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u1922\u1927-\u1928\u1932\u1939-\u193B\u1A17-\u1A18" + + "\u1A1B\u1A56\u1A58-\u1A5E\u1A60\u1A62\u1A65-\u1A6C\u1A73-\u1A7C\u1A7F\u1AB0-\u1ABD\u1ABE\u1B00-\u1B03\u1B34" + + "\u1B36-\u1B3A\u1B3C\u1B42\u1B6B-\u1B73\u1B80-\u1B81\u1BA2-\u1BA5\u1BA8-\u1BA9\u1BAB-\u1BAD\u1BE6\u1BE8-\u1BE9" + + "\u1BED\u1BEF-\u1BF1\u1C2C-\u1C33\u1C36-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE0\u1CE2-\u1CE8\u1CED\u1CF4\u1CF8-\u1CF9" + + "\u1DC0-\u1DF5\u1DFC-\u1DFF\u200C-\u200D\u20D0-\u20DC\u20DD-\u20E0\u20E1\u20E2-\u20E4\u20E5-\u20F0\u2CEF-\u2CF1" + + "\u2D7F\u2DE0-\u2DFF\u302A-\u302D\u302E-\u302F\u3099-\u309A\uA66F\uA670-\uA672\uA674-\uA67D\uA69E-\uA69F\uA6F0-\uA6F1" + + "\uA802\uA806\uA80B\uA825-\uA826\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA951\uA980-\uA982\uA9B3\uA9B6-\uA9B9\uA9BC" + + "\uA9E5\uAA29-\uAA2E\uAA31-\uAA32\uAA35-\uAA36\uAA43\uAA4C\uAA7C\uAAB0\uAAB2-\uAAB4\uAAB7-\uAAB8\uAABE-\uAABF\uAAC1" + + "\uAAEC-\uAAED\uAAF6\uABE5\uABE8\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F\uFF9E-\uFF9F]" + ); + + function isExtendingChar(ch) { + return typeof ch == "string" && ch.charCodeAt(0) >= 768 && extendingChars.test(ch); + } + + return { + isExtendingChar: isExtendingChar + }; +}); + +// Included from: js/tinymce/classes/caret/CaretPosition.js + +/** + * CaretPosition.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This module contains logic for creating caret positions within a document a caretposition + * is similar to a DOMRange object but it doesn't have two endpoints and is also more lightweight + * since it's now updated live when the DOM changes. + * + * @private + * @class tinymce.caret.CaretPosition + * @example + * var caretPos1 = new CaretPosition(container, offset); + * var caretPos2 = CaretPosition.fromRangeStart(someRange); + */ +define("tinymce/caret/CaretPosition", [ + "tinymce/util/Fun", + "tinymce/dom/NodeType", + "tinymce/dom/DOMUtils", + "tinymce/dom/RangeUtils", + "tinymce/caret/CaretCandidate", + "tinymce/geom/ClientRect", + "tinymce/text/ExtendingChar" +], function(Fun, NodeType, DOMUtils, RangeUtils, CaretCandidate, ClientRect, ExtendingChar) { + var isElement = NodeType.isElement, + isCaretCandidate = CaretCandidate.isCaretCandidate, + isBlock = NodeType.matchStyleValues('display', 'block table'), + isFloated = NodeType.matchStyleValues('float', 'left right'), + isValidElementCaretCandidate = Fun.and(isElement, isCaretCandidate, Fun.negate(isFloated)), + isNotPre = Fun.negate(NodeType.matchStyleValues('white-space', 'pre pre-line pre-wrap')), + isText = NodeType.isText, + isBr = NodeType.isBr, + nodeIndex = DOMUtils.nodeIndex, + resolveIndex = RangeUtils.getNode; + + function isWhiteSpace(chr) { + return chr && /[\r\n\t ]/.test(chr); + } + + function isHiddenWhiteSpaceRange(range) { + var container = range.startContainer, + offset = range.startOffset, + text; + + if (isWhiteSpace(range.toString()) && isNotPre(container.parentNode)) { + text = container.data; + + if (isWhiteSpace(text[offset - 1]) || isWhiteSpace(text[offset + 1])) { + return true; + } + } + + return false; + } + + function getCaretPositionClientRects(caretPosition) { + var clientRects = [], beforeNode, node; + + // Hack for older WebKit versions that doesn't + // support getBoundingClientRect on BR elements + function getBrClientRect(brNode) { + var doc = brNode.ownerDocument, + rng = doc.createRange(), + nbsp = doc.createTextNode('\u00a0'), + parentNode = brNode.parentNode, + clientRect; + + parentNode.insertBefore(nbsp, brNode); + rng.setStart(nbsp, 0); + rng.setEnd(nbsp, 1); + clientRect = ClientRect.clone(rng.getBoundingClientRect()); + parentNode.removeChild(nbsp); + + return clientRect; + } + + function getBoundingClientRect(item) { + var clientRect, clientRects; + + clientRects = item.getClientRects(); + if (clientRects.length > 0) { + clientRect = ClientRect.clone(clientRects[0]); + } else { + clientRect = ClientRect.clone(item.getBoundingClientRect()); + } + + if (isBr(item) && clientRect.left === 0) { + return getBrClientRect(item); + } + + return clientRect; + } + + function collapseAndInflateWidth(clientRect, toStart) { + clientRect = ClientRect.collapse(clientRect, toStart); + clientRect.width = 1; + clientRect.right = clientRect.left + 1; + + return clientRect; + } + + function addUniqueAndValidRect(clientRect) { + if (clientRect.height === 0) { + return; + } + + if (clientRects.length > 0) { + if (ClientRect.isEqual(clientRect, clientRects[clientRects.length - 1])) { + return; + } + } + + clientRects.push(clientRect); + } + + function addCharacterOffset(container, offset) { + var range = container.ownerDocument.createRange(); + + if (offset < container.data.length) { + if (ExtendingChar.isExtendingChar(container.data[offset])) { + return clientRects; + } + + // WebKit returns two client rects for a position after an extending + // character a\uxxx|b so expand on "b" and collapse to start of "b" box + if (ExtendingChar.isExtendingChar(container.data[offset - 1])) { + range.setStart(container, offset); + range.setEnd(container, offset + 1); + + if (!isHiddenWhiteSpaceRange(range)) { + addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(range), false)); + return clientRects; + } + } + } + + if (offset > 0) { + range.setStart(container, offset - 1); + range.setEnd(container, offset); + + if (!isHiddenWhiteSpaceRange(range)) { + addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(range), false)); + } + } + + if (offset < container.data.length) { + range.setStart(container, offset); + range.setEnd(container, offset + 1); + + if (!isHiddenWhiteSpaceRange(range)) { + addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(range), true)); + } + } + } + + if (isText(caretPosition.container())) { + addCharacterOffset(caretPosition.container(), caretPosition.offset()); + return clientRects; + } + + if (isElement(caretPosition.container())) { + if (caretPosition.isAtEnd()) { + node = resolveIndex(caretPosition.container(), caretPosition.offset()); + if (isText(node)) { + addCharacterOffset(node, node.data.length); + } + + if (isValidElementCaretCandidate(node) && !isBr(node)) { + addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(node), false)); + } + } else { + node = resolveIndex(caretPosition.container(), caretPosition.offset()); + if (isText(node)) { + addCharacterOffset(node, 0); + } + + if (isValidElementCaretCandidate(node) && caretPosition.isAtEnd()) { + addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(node), false)); + return clientRects; + } + + beforeNode = resolveIndex(caretPosition.container(), caretPosition.offset() - 1); + if (isValidElementCaretCandidate(beforeNode) && !isBr(beforeNode)) { + if (isBlock(beforeNode) || isBlock(node) || !isValidElementCaretCandidate(node)) { + addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(beforeNode), false)); + } + } + + if (isValidElementCaretCandidate(node)) { + addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(node), true)); + } + } + } + + return clientRects; + } + + /** + * Represents a location within the document by a container and an offset. + * + * @constructor + * @param {Node} container Container node. + * @param {Number} offset Offset within that container node. + * @param {Array} clientRects Optional client rects array for the position. + */ + function CaretPosition(container, offset, clientRects) { + function isAtStart() { + if (isText(container)) { + return offset === 0; + } + + return offset === 0; + } + + function isAtEnd() { + if (isText(container)) { + return offset >= container.data.length; + } + + return offset >= container.childNodes.length; + } + + function toRange() { + var range; + + range = container.ownerDocument.createRange(); + range.setStart(container, offset); + range.setEnd(container, offset); + + return range; + } + + function getClientRects() { + if (!clientRects) { + clientRects = getCaretPositionClientRects(new CaretPosition(container, offset)); + } + + return clientRects; + } + + function isVisible() { + return getClientRects().length > 0; + } + + function isEqual(caretPosition) { + return caretPosition && container === caretPosition.container() && offset === caretPosition.offset(); + } + + function getNode(before) { + return resolveIndex(container, before ? offset - 1 : offset); + } + + return { + /** + * Returns the container node. + * + * @method container + * @return {Node} Container node. + */ + container: Fun.constant(container), + + /** + * Returns the offset within the container node. + * + * @method offset + * @return {Number} Offset within the container node. + */ + offset: Fun.constant(offset), + + /** + * Returns a range out of a the caret position. + * + * @method toRange + * @return {DOMRange} range for the caret position. + */ + toRange: toRange, + + /** + * Returns the client rects for the caret position. Might be multiple rects between + * block elements. + * + * @method getClientRects + * @return {Array} Array of client rects. + */ + getClientRects: getClientRects, + + /** + * Returns true if the caret location is visible/displayed on screen. + * + * @method isVisible + * @return {Boolean} true/false if the position is visible or not. + */ + isVisible: isVisible, + + /** + * Returns true if the caret location is at the beginning of text node or container. + * + * @method isVisible + * @return {Boolean} true/false if the position is at the beginning. + */ + isAtStart: isAtStart, + + /** + * Returns true if the caret location is at the end of text node or container. + * + * @method isVisible + * @return {Boolean} true/false if the position is at the end. + */ + isAtEnd: isAtEnd, + + /** + * Compares the caret position to another caret position. This will only compare the + * container and offset not it's visual position. + * + * @method isEqual + * @param {tinymce.caret.CaretPosition} caretPosition Caret position to compare with. + * @return {Boolean} true if the caret positions are equal. + */ + isEqual: isEqual, + + /** + * Returns the closest resolved node from a node index. That means if you have an offset after the + * last node in a container it will return that last node. + * + * @method getNode + * @return {Node} Node that is closest to the index. + */ + getNode: getNode + }; + } + + /** + * Creates a caret position from the start of a range. + * + * @method fromRangeStart + * @param {DOMRange} range DOM Range to create caret position from. + * @return {tinymce.caret.CaretPosition} Caret position from the start of DOM range. + */ + CaretPosition.fromRangeStart = function(range) { + return new CaretPosition(range.startContainer, range.startOffset); + }; + + /** + * Creates a caret position from the end of a range. + * + * @method fromRangeEnd + * @param {DOMRange} range DOM Range to create caret position from. + * @return {tinymce.caret.CaretPosition} Caret position from the end of DOM range. + */ + CaretPosition.fromRangeEnd = function(range) { + return new CaretPosition(range.endContainer, range.endOffset); + }; + + /** + * Creates a caret position from a node and places the offset after it. + * + * @method after + * @param {Node} node Node to get caret position from. + * @return {tinymce.caret.CaretPosition} Caret position from the node. + */ + CaretPosition.after = function(node) { + return new CaretPosition(node.parentNode, nodeIndex(node) + 1); + }; + + /** + * Creates a caret position from a node and places the offset before it. + * + * @method before + * @param {Node} node Node to get caret position from. + * @return {tinymce.caret.CaretPosition} Caret position from the node. + */ + CaretPosition.before = function(node) { + return new CaretPosition(node.parentNode, nodeIndex(node)); + }; + + return CaretPosition; +}); + +// Included from: js/tinymce/classes/caret/CaretBookmark.js + +/** + * CaretBookmark.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This module creates or resolves xpath like string representation of a CaretPositions. + * + * The format is a / separated list of chunks with: + * <element|text()>[index|after|before] + * + * For example: + * p[0]/b[0]/text()[0],1 = <p><b>a|c</b></p> + * p[0]/img[0],before = <p>|<img></p> + * p[0]/img[0],after = <p><img>|</p> + * + * @private + * @static + * @class tinymce.caret.CaretBookmark + * @example + * var bookmark = CaretBookmark.create(rootElm, CaretPosition.before(rootElm.firstChild)); + * var caretPosition = CaretBookmark.resolve(bookmark); + */ +define('tinymce/caret/CaretBookmark', [ + 'tinymce/dom/NodeType', + 'tinymce/dom/DOMUtils', + 'tinymce/util/Fun', + 'tinymce/util/Arr', + 'tinymce/caret/CaretPosition' +], function(NodeType, DomUtils, Fun, Arr, CaretPosition) { + var isText = NodeType.isText, + isBogus = NodeType.isBogus, + nodeIndex = DomUtils.nodeIndex; + + function normalizedParent(node) { + var parentNode = node.parentNode; + + if (isBogus(parentNode)) { + return normalizedParent(parentNode); + } + + return parentNode; + } + + function getChildNodes(node) { + if (!node) { + return []; + } + + return Arr.reduce(node.childNodes, function(result, node) { + if (isBogus(node) && node.nodeName != 'BR') { + result = result.concat(getChildNodes(node)); + } else { + result.push(node); + } + + return result; + }, []); + } + + function normalizedTextOffset(textNode, offset) { + while ((textNode = textNode.previousSibling)) { + if (!isText(textNode)) { + break; + } + + offset += textNode.data.length; + } + + return offset; + } + + function equal(targetValue) { + return function(value) { + return targetValue === value; + }; + } + + function normalizedNodeIndex(node) { + var nodes, index, numTextFragments; + + nodes = getChildNodes(normalizedParent(node)); + index = Arr.findIndex(nodes, equal(node), node); + nodes = nodes.slice(0, index + 1); + numTextFragments = Arr.reduce(nodes, function(result, node, i) { + if (isText(node) && isText(nodes[i - 1])) { + result++; + } + + return result; + }, 0); + + nodes = Arr.filter(nodes, NodeType.matchNodeNames(node.nodeName)); + index = Arr.findIndex(nodes, equal(node), node); + + return index - numTextFragments; + } + + function createPathItem(node) { + var name; + + if (isText(node)) { + name = 'text()'; + } else { + name = node.nodeName.toLowerCase(); + } + + return name + '[' + normalizedNodeIndex(node) + ']'; + } + + function parentsUntil(rootNode, node, predicate) { + var parents = []; + + for (node = node.parentNode; node != rootNode; node = node.parentNode) { + if (predicate && predicate(node)) { + break; + } + + parents.push(node); + } + + return parents; + } + + function create(rootNode, caretPosition) { + var container, offset, path = [], + outputOffset, childNodes, parents; + + container = caretPosition.container(); + offset = caretPosition.offset(); + + if (isText(container)) { + outputOffset = normalizedTextOffset(container, offset); + } else { + childNodes = container.childNodes; + if (offset >= childNodes.length) { + outputOffset = 'after'; + offset = childNodes.length - 1; + } else { + outputOffset = 'before'; + } + + container = childNodes[offset]; + } + + path.push(createPathItem(container)); + parents = parentsUntil(rootNode, container); + parents = Arr.filter(parents, Fun.negate(NodeType.isBogus)); + path = path.concat(Arr.map(parents, function(node) { + return createPathItem(node); + })); + + return path.reverse().join('/') + ',' + outputOffset; + } + + function resolvePathItem(node, name, index) { + var nodes = getChildNodes(node); + + nodes = Arr.filter(nodes, function(node, index) { + return !isText(node) || !isText(nodes[index - 1]); + }); + + nodes = Arr.filter(nodes, NodeType.matchNodeNames(name)); + return nodes[index]; + } + + function findTextPosition(container, offset) { + var node = container, targetOffset = 0, dataLen; + + while (isText(node)) { + dataLen = node.data.length; + + if (offset >= targetOffset && offset <= targetOffset + dataLen) { + container = node; + offset = offset - targetOffset; + break; + } + + if (!isText(node.nextSibling)) { + container = node; + offset = dataLen; + break; + } + + targetOffset += dataLen; + node = node.nextSibling; + } + + if (offset > container.data.length) { + offset = container.data.length; + } + + return new CaretPosition(container, offset); + } + + function resolve(rootNode, path) { + var parts, container, offset; + + if (!path) { + return null; + } + + parts = path.split(','); + path = parts[0].split('/'); + offset = parts.length > 1 ? parts[1] : 'before'; + + container = Arr.reduce(path, function(result, value) { + value = /([\w\-\(\)]+)\[([0-9]+)\]/.exec(value); + if (!value) { + return null; + } + + if (value[1] === 'text()') { + value[1] = '#text'; + } + + return resolvePathItem(result, value[1], parseInt(value[2], 10)); + }, rootNode); + + if (!container) { + return null; + } + + if (!isText(container)) { + if (offset === 'after') { + offset = nodeIndex(container) + 1; + } else { + offset = nodeIndex(container); + } + + return new CaretPosition(container.parentNode, offset); + } + + return findTextPosition(container, parseInt(offset, 10)); + } + + return { + /** + * Create a xpath bookmark location for the specified caret position. + * + * @method create + * @param {Node} rootNode Root node to create bookmark within. + * @param {tinymce.caret.CaretPosition} caretPosition Caret position within the root node. + * @return {String} String xpath like location of caret position. + */ + create: create, + + /** + * Resolves a xpath like bookmark location to the a caret position. + * + * @method resolve + * @param {Node} rootNode Root node to resolve xpath bookmark within. + * @param {String} bookmark Bookmark string to resolve. + * @return {tinymce.caret.CaretPosition} Caret position resolved from xpath like bookmark. + */ + resolve: resolve + }; +}); + +// Included from: js/tinymce/classes/dom/BookmarkManager.js + +/** + * BookmarkManager.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class handles selection bookmarks. + * + * @class tinymce.dom.BookmarkManager + */ +define("tinymce/dom/BookmarkManager", [ + "tinymce/Env", + "tinymce/util/Tools", + "tinymce/caret/CaretContainer", + "tinymce/caret/CaretBookmark", + "tinymce/caret/CaretPosition", + "tinymce/dom/NodeType" +], function(Env, Tools, CaretContainer, CaretBookmark, CaretPosition, NodeType) { + var isContentEditableFalse = NodeType.isContentEditableFalse; + + /** + * Constructs a new BookmarkManager instance for a specific selection instance. + * + * @constructor + * @method BookmarkManager + * @param {tinymce.dom.Selection} selection Selection instance to handle bookmarks for. + */ + function BookmarkManager(selection) { + var dom = selection.dom; + + /** + * Returns a bookmark location for the current selection. This bookmark object + * can then be used to restore the selection after some content modification to the document. + * + * @method getBookmark + * @param {Number} type Optional state if the bookmark should be simple or not. Default is complex. + * @param {Boolean} normalized Optional state that enables you to get a position that it would be after normalization. + * @return {Object} Bookmark object, use moveToBookmark with this object to restore the selection. + * @example + * // Stores a bookmark of the current selection + * var bm = tinymce.activeEditor.selection.getBookmark(); + * + * tinymce.activeEditor.setContent(tinymce.activeEditor.getContent() + 'Some new content'); + * + * // Restore the selection bookmark + * tinymce.activeEditor.selection.moveToBookmark(bm); + */ + this.getBookmark = function(type, normalized) { + var rng, rng2, id, collapsed, name, element, chr = '', styles; + + function findIndex(name, element) { + var count = 0; + + Tools.each(dom.select(name), function(node) { + if (node.getAttribute('data-mce-bogus') === 'all') { + return; + } + + if (node == element) { + return false; + } + + count++; + }); + + return count; + } + + function normalizeTableCellSelection(rng) { + function moveEndPoint(start) { + var container, offset, childNodes, prefix = start ? 'start' : 'end'; + + container = rng[prefix + 'Container']; + offset = rng[prefix + 'Offset']; + + if (container.nodeType == 1 && container.nodeName == "TR") { + childNodes = container.childNodes; + container = childNodes[Math.min(start ? offset : offset - 1, childNodes.length - 1)]; + if (container) { + offset = start ? 0 : container.childNodes.length; + rng['set' + (start ? 'Start' : 'End')](container, offset); + } + } + } + + moveEndPoint(true); + moveEndPoint(); + + return rng; + } + + function getLocation(rng) { + var root = dom.getRoot(), bookmark = {}; + + function getPoint(rng, start) { + var container = rng[start ? 'startContainer' : 'endContainer'], + offset = rng[start ? 'startOffset' : 'endOffset'], point = [], node, childNodes, after = 0; + + if (container.nodeType == 3) { + if (normalized) { + for (node = container.previousSibling; node && node.nodeType == 3; node = node.previousSibling) { + offset += node.nodeValue.length; + } + } + + point.push(offset); + } else { + childNodes = container.childNodes; + + if (offset >= childNodes.length && childNodes.length) { + after = 1; + offset = Math.max(0, childNodes.length - 1); + } + + point.push(dom.nodeIndex(childNodes[offset], normalized) + after); + } + + for (; container && container != root; container = container.parentNode) { + point.push(dom.nodeIndex(container, normalized)); + } + + return point; + } + + bookmark.start = getPoint(rng, true); + + if (!selection.isCollapsed()) { + bookmark.end = getPoint(rng); + } + + return bookmark; + } + + function findAdjacentContentEditableFalseElm(rng) { + function findSibling(node) { + var sibling; + + if (CaretContainer.isCaretContainer(node)) { + if (NodeType.isText(node) && CaretContainer.isCaretContainerBlock(node)) { + node = node.parentNode; + } + + sibling = node.previousSibling; + if (isContentEditableFalse(sibling)) { + return sibling; + } + + sibling = node.nextSibling; + if (isContentEditableFalse(sibling)) { + return sibling; + } + } + } + + return findSibling(rng.startContainer) || findSibling(rng.endContainer); + } + + if (type == 2) { + element = selection.getNode(); + name = element ? element.nodeName : null; + rng = selection.getRng(); + + if (isContentEditableFalse(element) || name == 'IMG') { + return {name: name, index: findIndex(name, element)}; + } + + if (selection.tridentSel) { + return selection.tridentSel.getBookmark(type); + } + + element = findAdjacentContentEditableFalseElm(rng); + if (element) { + name = element.tagName; + return {name: name, index: findIndex(name, element)}; + } + + return getLocation(rng); + } + + if (type == 3) { + rng = selection.getRng(); + + return { + start: CaretBookmark.create(dom.getRoot(), CaretPosition.fromRangeStart(rng)), + end: CaretBookmark.create(dom.getRoot(), CaretPosition.fromRangeEnd(rng)) + }; + } + + // Handle simple range + if (type) { + return {rng: selection.getRng()}; + } + + rng = selection.getRng(); + id = dom.uniqueId(); + collapsed = selection.isCollapsed(); + styles = 'overflow:hidden;line-height:0px'; + + // Explorer method + if (rng.duplicate || rng.item) { + // Text selection + if (!rng.item) { + rng2 = rng.duplicate(); + + try { + // Insert start marker + rng.collapse(); + rng.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_start" style="' + styles + '">' + chr + '</span>'); + + // Insert end marker + if (!collapsed) { + rng2.collapse(false); + + // Detect the empty space after block elements in IE and move the + // end back one character <p></p>] becomes <p>]</p> + rng.moveToElementText(rng2.parentElement()); + if (rng.compareEndPoints('StartToEnd', rng2) === 0) { + rng2.move('character', -1); + } + + rng2.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_end" style="' + styles + '">' + chr + '</span>'); + } + } catch (ex) { + // IE might throw unspecified error so lets ignore it + return null; + } + } else { + // Control selection + element = rng.item(0); + name = element.nodeName; + + return {name: name, index: findIndex(name, element)}; + } + } else { + element = selection.getNode(); + name = element.nodeName; + if (name == 'IMG') { + return {name: name, index: findIndex(name, element)}; + } + + // W3C method + rng2 = normalizeTableCellSelection(rng.cloneRange()); + + // Insert end marker + if (!collapsed) { + rng2.collapse(false); + rng2.insertNode(dom.create('span', {'data-mce-type': "bookmark", id: id + '_end', style: styles}, chr)); + } + + rng = normalizeTableCellSelection(rng); + rng.collapse(true); + rng.insertNode(dom.create('span', {'data-mce-type': "bookmark", id: id + '_start', style: styles}, chr)); + } + + selection.moveToBookmark({id: id, keep: 1}); + + return {id: id}; + }; + + /** + * Restores the selection to the specified bookmark. + * + * @method moveToBookmark + * @param {Object} bookmark Bookmark to restore selection from. + * @return {Boolean} true/false if it was successful or not. + * @example + * // Stores a bookmark of the current selection + * var bm = tinymce.activeEditor.selection.getBookmark(); + * + * tinymce.activeEditor.setContent(tinymce.activeEditor.getContent() + 'Some new content'); + * + * // Restore the selection bookmark + * tinymce.activeEditor.selection.moveToBookmark(bm); + */ + this.moveToBookmark = function(bookmark) { + var rng, root, startContainer, endContainer, startOffset, endOffset; + + function setEndPoint(start) { + var point = bookmark[start ? 'start' : 'end'], i, node, offset, children; + + if (point) { + offset = point[0]; + + // Find container node + for (node = root, i = point.length - 1; i >= 1; i--) { + children = node.childNodes; + + if (point[i] > children.length - 1) { + return; + } + + node = children[point[i]]; + } + + // Move text offset to best suitable location + if (node.nodeType === 3) { + offset = Math.min(point[0], node.nodeValue.length); + } + + // Move element offset to best suitable location + if (node.nodeType === 1) { + offset = Math.min(point[0], node.childNodes.length); + } + + // Set offset within container node + if (start) { + rng.setStart(node, offset); + } else { + rng.setEnd(node, offset); + } + } + + return true; + } + + function restoreEndPoint(suffix) { + var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev, keep = bookmark.keep; + + if (marker) { + node = marker.parentNode; + + if (suffix == 'start') { + if (!keep) { + idx = dom.nodeIndex(marker); + } else { + node = marker.firstChild; + idx = 1; + } + + startContainer = endContainer = node; + startOffset = endOffset = idx; + } else { + if (!keep) { + idx = dom.nodeIndex(marker); + } else { + node = marker.firstChild; + idx = 1; + } + + endContainer = node; + endOffset = idx; + } + + if (!keep) { + prev = marker.previousSibling; + next = marker.nextSibling; + + // Remove all marker text nodes + Tools.each(Tools.grep(marker.childNodes), function(node) { + if (node.nodeType == 3) { + node.nodeValue = node.nodeValue.replace(/\uFEFF/g, ''); + } + }); + + // Remove marker but keep children if for example contents where inserted into the marker + // Also remove duplicated instances of the marker for example by a + // split operation or by WebKit auto split on paste feature + while ((marker = dom.get(bookmark.id + '_' + suffix))) { + dom.remove(marker, 1); + } + + // If siblings are text nodes then merge them unless it's Opera since it some how removes the node + // and we are sniffing since adding a lot of detection code for a browser with 3% of the market + // isn't worth the effort. Sorry, Opera but it's just a fact + if (prev && next && prev.nodeType == next.nodeType && prev.nodeType == 3 && !Env.opera) { + idx = prev.nodeValue.length; + prev.appendData(next.nodeValue); + dom.remove(next); + + if (suffix == 'start') { + startContainer = endContainer = prev; + startOffset = endOffset = idx; + } else { + endContainer = prev; + endOffset = idx; + } + } + } + } + } + + function addBogus(node) { + // Adds a bogus BR element for empty block elements + if (dom.isBlock(node) && !node.innerHTML && !Env.ie) { + node.innerHTML = '<br data-mce-bogus="1" />'; + } + + return node; + } + + function resolveCaretPositionBookmark() { + var rng, pos; + + rng = dom.createRng(); + pos = CaretBookmark.resolve(dom.getRoot(), bookmark.start); + rng.setStart(pos.container(), pos.offset()); + + pos = CaretBookmark.resolve(dom.getRoot(), bookmark.end); + rng.setEnd(pos.container(), pos.offset()); + + return rng; + } + + if (bookmark) { + if (Tools.isArray(bookmark.start)) { + rng = dom.createRng(); + root = dom.getRoot(); + + if (selection.tridentSel) { + return selection.tridentSel.moveToBookmark(bookmark); + } + + if (setEndPoint(true) && setEndPoint()) { + selection.setRng(rng); + } + } else if (typeof bookmark.start == 'string') { + selection.setRng(resolveCaretPositionBookmark(bookmark)); + } else if (bookmark.id) { + // Restore start/end points + restoreEndPoint('start'); + restoreEndPoint('end'); + + if (startContainer) { + rng = dom.createRng(); + rng.setStart(addBogus(startContainer), startOffset); + rng.setEnd(addBogus(endContainer), endOffset); + selection.setRng(rng); + } + } else if (bookmark.name) { + selection.select(dom.select(bookmark.name)[bookmark.index]); + } else if (bookmark.rng) { + selection.setRng(bookmark.rng); + } + } + }; + } + + /** + * Returns true/false if the specified node is a bookmark node or not. + * + * @static + * @method isBookmarkNode + * @param {DOMNode} node DOM Node to check if it's a bookmark node or not. + * @return {Boolean} true/false if the node is a bookmark node or not. + */ + BookmarkManager.isBookmarkNode = function(node) { + return node && node.tagName === 'SPAN' && node.getAttribute('data-mce-type') === 'bookmark'; + }; + + return BookmarkManager; +}); + +// Included from: js/tinymce/classes/dom/Selection.js + +/** + * Selection.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class handles text and control selection it's an crossbrowser utility class. + * Consult the TinyMCE Wiki API for more details and examples on how to use this class. + * + * @class tinymce.dom.Selection + * @example + * // Getting the currently selected node for the active editor + * alert(tinymce.activeEditor.selection.getNode().nodeName); + */ +define("tinymce/dom/Selection", [ + "tinymce/dom/TreeWalker", + "tinymce/dom/TridentSelection", + "tinymce/dom/ControlSelection", + "tinymce/dom/RangeUtils", + "tinymce/dom/BookmarkManager", + "tinymce/dom/NodeType", + "tinymce/Env", + "tinymce/util/Tools" +], function(TreeWalker, TridentSelection, ControlSelection, RangeUtils, BookmarkManager, NodeType, Env, Tools) { + var each = Tools.each, trim = Tools.trim; + var isIE = Env.ie; + + /** + * Constructs a new selection instance. + * + * @constructor + * @method Selection + * @param {tinymce.dom.DOMUtils} dom DOMUtils object reference. + * @param {Window} win Window to bind the selection object to. + * @param {tinymce.Editor} editor Editor instance of the selection. + * @param {tinymce.dom.Serializer} serializer DOM serialization class to use for getContent. + */ + function Selection(dom, win, serializer, editor) { + var self = this; + + self.dom = dom; + self.win = win; + self.serializer = serializer; + self.editor = editor; + self.bookmarkManager = new BookmarkManager(self); + self.controlSelection = new ControlSelection(self, editor); + + // No W3C Range support + if (!self.win.getSelection) { + self.tridentSel = new TridentSelection(self); + } + } + + Selection.prototype = { + /** + * Move the selection cursor range to the specified node and offset. + * If there is no node specified it will move it to the first suitable location within the body. + * + * @method setCursorLocation + * @param {Node} node Optional node to put the cursor in. + * @param {Number} offset Optional offset from the start of the node to put the cursor at. + */ + setCursorLocation: function(node, offset) { + var self = this, rng = self.dom.createRng(); + + if (!node) { + self._moveEndPoint(rng, self.editor.getBody(), true); + self.setRng(rng); + } else { + rng.setStart(node, offset); + rng.setEnd(node, offset); + self.setRng(rng); + self.collapse(false); + } + }, + + /** + * Returns the selected contents using the DOM serializer passed in to this class. + * + * @method getContent + * @param {Object} args Optional settings class with for example output format text or html. + * @return {String} Selected contents in for example HTML format. + * @example + * // Alerts the currently selected contents + * alert(tinymce.activeEditor.selection.getContent()); + * + * // Alerts the currently selected contents as plain text + * alert(tinymce.activeEditor.selection.getContent({format: 'text'})); + */ + getContent: function(args) { + var self = this, rng = self.getRng(), tmpElm = self.dom.create("body"); + var se = self.getSel(), whiteSpaceBefore, whiteSpaceAfter, fragment; + + args = args || {}; + whiteSpaceBefore = whiteSpaceAfter = ''; + args.get = true; + args.format = args.format || 'html'; + args.selection = true; + self.editor.fire('BeforeGetContent', args); + + if (args.format == 'text') { + return self.isCollapsed() ? '' : (rng.text || (se.toString ? se.toString() : '')); + } + + if (rng.cloneContents) { + fragment = rng.cloneContents(); + + if (fragment) { + tmpElm.appendChild(fragment); + } + } else if (rng.item !== undefined || rng.htmlText !== undefined) { + // IE will produce invalid markup if elements are present that + // it doesn't understand like custom elements or HTML5 elements. + // Adding a BR in front of the contents and then remoiving it seems to fix it though. + tmpElm.innerHTML = '<br>' + (rng.item ? rng.item(0).outerHTML : rng.htmlText); + tmpElm.removeChild(tmpElm.firstChild); + } else { + tmpElm.innerHTML = rng.toString(); + } + + // Keep whitespace before and after + if (/^\s/.test(tmpElm.innerHTML)) { + whiteSpaceBefore = ' '; + } + + if (/\s+$/.test(tmpElm.innerHTML)) { + whiteSpaceAfter = ' '; + } + + args.getInner = true; + + args.content = self.isCollapsed() ? '' : whiteSpaceBefore + self.serializer.serialize(tmpElm, args) + whiteSpaceAfter; + self.editor.fire('GetContent', args); + + return args.content; + }, + + /** + * Sets the current selection to the specified content. If any contents is selected it will be replaced + * with the contents passed in to this function. If there is no selection the contents will be inserted + * where the caret is placed in the editor/page. + * + * @method setContent + * @param {String} content HTML contents to set could also be other formats depending on settings. + * @param {Object} args Optional settings object with for example data format. + * @example + * // Inserts some HTML contents at the current selection + * tinymce.activeEditor.selection.setContent('<strong>Some contents</strong>'); + */ + setContent: function(content, args) { + var self = this, rng = self.getRng(), caretNode, doc = self.win.document, frag, temp; + + args = args || {format: 'html'}; + args.set = true; + args.selection = true; + args.content = content; + + // Dispatch before set content event + if (!args.no_events) { + self.editor.fire('BeforeSetContent', args); + } + + content = args.content; + + if (rng.insertNode) { + // Make caret marker since insertNode places the caret in the beginning of text after insert + content += '<span id="__caret">_</span>'; + + // Delete and insert new node + if (rng.startContainer == doc && rng.endContainer == doc) { + // WebKit will fail if the body is empty since the range is then invalid and it can't insert contents + doc.body.innerHTML = content; + } else { + rng.deleteContents(); + + if (doc.body.childNodes.length === 0) { + doc.body.innerHTML = content; + } else { + // createContextualFragment doesn't exists in IE 9 DOMRanges + if (rng.createContextualFragment) { + rng.insertNode(rng.createContextualFragment(content)); + } else { + // Fake createContextualFragment call in IE 9 + frag = doc.createDocumentFragment(); + temp = doc.createElement('div'); + + frag.appendChild(temp); + temp.outerHTML = content; + + rng.insertNode(frag); + } + } + } + + // Move to caret marker + caretNode = self.dom.get('__caret'); + + // Make sure we wrap it compleatly, Opera fails with a simple select call + rng = doc.createRange(); + rng.setStartBefore(caretNode); + rng.setEndBefore(caretNode); + self.setRng(rng); + + // Remove the caret position + self.dom.remove('__caret'); + + try { + self.setRng(rng); + } catch (ex) { + // Might fail on Opera for some odd reason + } + } else { + if (rng.item) { + // Delete content and get caret text selection + doc.execCommand('Delete', false, null); + rng = self.getRng(); + } + + // Explorer removes spaces from the beginning of pasted contents + if (/^\s+/.test(content)) { + rng.pasteHTML('<span id="__mce_tmp">_</span>' + content); + self.dom.remove('__mce_tmp'); + } else { + rng.pasteHTML(content); + } + } + + // Dispatch set content event + if (!args.no_events) { + self.editor.fire('SetContent', args); + } + }, + + /** + * Returns the start element of a selection range. If the start is in a text + * node the parent element will be returned. + * + * @method getStart + * @param {Boolean} real Optional state to get the real parent when the selection is collapsed not the closest element. + * @return {Element} Start element of selection range. + */ + getStart: function(real) { + var self = this, rng = self.getRng(), startElement, parentElement, checkRng, node; + + if (rng.duplicate || rng.item) { + // Control selection, return first item + if (rng.item) { + return rng.item(0); + } + + // Get start element + checkRng = rng.duplicate(); + checkRng.collapse(1); + startElement = checkRng.parentElement(); + if (startElement.ownerDocument !== self.dom.doc) { + startElement = self.dom.getRoot(); + } + + // Check if range parent is inside the start element, then return the inner parent element + // This will fix issues when a single element is selected, IE would otherwise return the wrong start element + parentElement = node = rng.parentElement(); + while ((node = node.parentNode)) { + if (node == startElement) { + startElement = parentElement; + break; + } + } + + return startElement; + } + + startElement = rng.startContainer; + + if (startElement.nodeType == 1 && startElement.hasChildNodes()) { + if (!real || !rng.collapsed) { + startElement = startElement.childNodes[Math.min(startElement.childNodes.length - 1, rng.startOffset)]; + } + } + + if (startElement && startElement.nodeType == 3) { + return startElement.parentNode; + } + + return startElement; + }, + + /** + * Returns the end element of a selection range. If the end is in a text + * node the parent element will be returned. + * + * @method getEnd + * @param {Boolean} real Optional state to get the real parent when the selection is collapsed not the closest element. + * @return {Element} End element of selection range. + */ + getEnd: function(real) { + var self = this, rng = self.getRng(), endElement, endOffset; + + if (rng.duplicate || rng.item) { + if (rng.item) { + return rng.item(0); + } + + rng = rng.duplicate(); + rng.collapse(0); + endElement = rng.parentElement(); + if (endElement.ownerDocument !== self.dom.doc) { + endElement = self.dom.getRoot(); + } + + if (endElement && endElement.nodeName == 'BODY') { + return endElement.lastChild || endElement; + } + + return endElement; + } + + endElement = rng.endContainer; + endOffset = rng.endOffset; + + if (endElement.nodeType == 1 && endElement.hasChildNodes()) { + if (!real || !rng.collapsed) { + endElement = endElement.childNodes[endOffset > 0 ? endOffset - 1 : endOffset]; + } + } + + if (endElement && endElement.nodeType == 3) { + return endElement.parentNode; + } + + return endElement; + }, + + /** + * Returns a bookmark location for the current selection. This bookmark object + * can then be used to restore the selection after some content modification to the document. + * + * @method getBookmark + * @param {Number} type Optional state if the bookmark should be simple or not. Default is complex. + * @param {Boolean} normalized Optional state that enables you to get a position that it would be after normalization. + * @return {Object} Bookmark object, use moveToBookmark with this object to restore the selection. + * @example + * // Stores a bookmark of the current selection + * var bm = tinymce.activeEditor.selection.getBookmark(); + * + * tinymce.activeEditor.setContent(tinymce.activeEditor.getContent() + 'Some new content'); + * + * // Restore the selection bookmark + * tinymce.activeEditor.selection.moveToBookmark(bm); + */ + getBookmark: function(type, normalized) { + return this.bookmarkManager.getBookmark(type, normalized); + }, + + /** + * Restores the selection to the specified bookmark. + * + * @method moveToBookmark + * @param {Object} bookmark Bookmark to restore selection from. + * @return {Boolean} true/false if it was successful or not. + * @example + * // Stores a bookmark of the current selection + * var bm = tinymce.activeEditor.selection.getBookmark(); + * + * tinymce.activeEditor.setContent(tinymce.activeEditor.getContent() + 'Some new content'); + * + * // Restore the selection bookmark + * tinymce.activeEditor.selection.moveToBookmark(bm); + */ + moveToBookmark: function(bookmark) { + return this.bookmarkManager.moveToBookmark(bookmark); + }, + + /** + * Selects the specified element. This will place the start and end of the selection range around the element. + * + * @method select + * @param {Element} node HTML DOM element to select. + * @param {Boolean} content Optional bool state if the contents should be selected or not on non IE browser. + * @return {Element} Selected element the same element as the one that got passed in. + * @example + * // Select the first paragraph in the active editor + * tinymce.activeEditor.selection.select(tinymce.activeEditor.dom.select('p')[0]); + */ + select: function(node, content) { + var self = this, dom = self.dom, rng = dom.createRng(), idx; + + // Clear stored range set by FocusManager + self.lastFocusBookmark = null; + + if (node) { + if (!content && self.controlSelection.controlSelect(node)) { + return; + } + + idx = dom.nodeIndex(node); + rng.setStart(node.parentNode, idx); + rng.setEnd(node.parentNode, idx + 1); + + // Find first/last text node or BR element + if (content) { + self._moveEndPoint(rng, node, true); + self._moveEndPoint(rng, node); + } + + self.setRng(rng); + } + + return node; + }, + + /** + * Returns true/false if the selection range is collapsed or not. Collapsed means if it's a caret or a larger selection. + * + * @method isCollapsed + * @return {Boolean} true/false state if the selection range is collapsed or not. + * Collapsed means if it's a caret or a larger selection. + */ + isCollapsed: function() { + var self = this, rng = self.getRng(), sel = self.getSel(); + + if (!rng || rng.item) { + return false; + } + + if (rng.compareEndPoints) { + return rng.compareEndPoints('StartToEnd', rng) === 0; + } + + return !sel || rng.collapsed; + }, + + /** + * Collapse the selection to start or end of range. + * + * @method collapse + * @param {Boolean} toStart Optional boolean state if to collapse to end or not. Defaults to false. + */ + collapse: function(toStart) { + var self = this, rng = self.getRng(), node; + + // Control range on IE + if (rng.item) { + node = rng.item(0); + rng = self.win.document.body.createTextRange(); + rng.moveToElementText(node); + } + + rng.collapse(!!toStart); + self.setRng(rng); + }, + + /** + * Returns the browsers internal selection object. + * + * @method getSel + * @return {Selection} Internal browser selection object. + */ + getSel: function() { + var win = this.win; + + return win.getSelection ? win.getSelection() : win.document.selection; + }, + + /** + * Returns the browsers internal range object. + * + * @method getRng + * @param {Boolean} w3c Forces a compatible W3C range on IE. + * @return {Range} Internal browser range object. + * @see http://www.quirksmode.org/dom/range_intro.html + * @see http://www.dotvoid.com/2001/03/using-the-range-object-in-mozilla/ + */ + getRng: function(w3c) { + var self = this, selection, rng, elm, doc, ieRng, evt; + + function tryCompareBoundaryPoints(how, sourceRange, destinationRange) { + try { + return sourceRange.compareBoundaryPoints(how, destinationRange); + } catch (ex) { + // Gecko throws wrong document exception if the range points + // to nodes that where removed from the dom #6690 + // Browsers should mutate existing DOMRange instances so that they always point + // to something in the document this is not the case in Gecko works fine in IE/WebKit/Blink + // For performance reasons just return -1 + return -1; + } + } + + if (!self.win) { + return null; + } + + doc = self.win.document; + + // Use last rng passed from FocusManager if it's available this enables + // calls to editor.selection.getStart() to work when caret focus is lost on IE + if (!w3c && self.lastFocusBookmark) { + var bookmark = self.lastFocusBookmark; + + // Convert bookmark to range IE 11 fix + if (bookmark.startContainer) { + rng = doc.createRange(); + rng.setStart(bookmark.startContainer, bookmark.startOffset); + rng.setEnd(bookmark.endContainer, bookmark.endOffset); + } else { + rng = bookmark; + } + + return rng; + } + + // Found tridentSel object then we need to use that one + if (w3c && self.tridentSel) { + return self.tridentSel.getRangeAt(0); + } + + try { + if ((selection = self.getSel())) { + if (selection.rangeCount > 0) { + rng = selection.getRangeAt(0); + } else { + rng = selection.createRange ? selection.createRange() : doc.createRange(); + } + } + } catch (ex) { + // IE throws unspecified error here if TinyMCE is placed in a frame/iframe + } + + evt = self.editor.fire('GetSelectionRange', {range: rng}); + if (evt.range !== rng) { + return evt.range; + } + + // We have W3C ranges and it's IE then fake control selection since IE9 doesn't handle that correctly yet + // IE 11 doesn't support the selection object so we check for that as well + if (isIE && rng && rng.setStart && doc.selection) { + try { + // IE will sometimes throw an exception here + ieRng = doc.selection.createRange(); + } catch (ex) { + // Ignore + } + + if (ieRng && ieRng.item) { + elm = ieRng.item(0); + rng = doc.createRange(); + rng.setStartBefore(elm); + rng.setEndAfter(elm); + } + } + + // No range found then create an empty one + // This can occur when the editor is placed in a hidden container element on Gecko + // Or on IE when there was an exception + if (!rng) { + rng = doc.createRange ? doc.createRange() : doc.body.createTextRange(); + } + + // If range is at start of document then move it to start of body + if (rng.setStart && rng.startContainer.nodeType === 9 && rng.collapsed) { + elm = self.dom.getRoot(); + rng.setStart(elm, 0); + rng.setEnd(elm, 0); + } + + if (self.selectedRange && self.explicitRange) { + if (tryCompareBoundaryPoints(rng.START_TO_START, rng, self.selectedRange) === 0 && + tryCompareBoundaryPoints(rng.END_TO_END, rng, self.selectedRange) === 0) { + // Safari, Opera and Chrome only ever select text which causes the range to change. + // This lets us use the originally set range if the selection hasn't been changed by the user. + rng = self.explicitRange; + } else { + self.selectedRange = null; + self.explicitRange = null; + } + } + + return rng; + }, + + /** + * Changes the selection to the specified DOM range. + * + * @method setRng + * @param {Range} rng Range to select. + * @param {Boolean} forward Optional boolean if the selection is forwards or backwards. + */ + setRng: function(rng, forward) { + var self = this, sel, node, evt; + + if (!rng) { + return; + } + + // Is IE specific range + if (rng.select) { + self.explicitRange = null; + + try { + rng.select(); + } catch (ex) { + // Needed for some odd IE bug #1843306 + } + + return; + } + + if (!self.tridentSel) { + sel = self.getSel(); + + evt = self.editor.fire('SetSelectionRange', {range: rng}); + rng = evt.range; + + if (sel) { + self.explicitRange = rng; + + try { + sel.removeAllRanges(); + sel.addRange(rng); + } catch (ex) { + // IE might throw errors here if the editor is within a hidden container and selection is changed + } + + // Forward is set to false and we have an extend function + if (forward === false && sel.extend) { + sel.collapse(rng.endContainer, rng.endOffset); + sel.extend(rng.startContainer, rng.startOffset); + } + + // adding range isn't always successful so we need to check range count otherwise an exception can occur + self.selectedRange = sel.rangeCount > 0 ? sel.getRangeAt(0) : null; + } + + // WebKit egde case selecting images works better using setBaseAndExtent + if (!rng.collapsed && rng.startContainer == rng.endContainer && sel.setBaseAndExtent && !Env.ie) { + if (rng.endOffset - rng.startOffset < 2) { + if (rng.startContainer.hasChildNodes()) { + node = rng.startContainer.childNodes[rng.startOffset]; + if (node && node.tagName == 'IMG') { + self.getSel().setBaseAndExtent(node, 0, node, 1); + } + } + } + } + } else { + // Is W3C Range fake range on IE + if (rng.cloneRange) { + try { + self.tridentSel.addRange(rng); + } catch (ex) { + //IE9 throws an error here if called before selection is placed in the editor + } + } + } + }, + + /** + * Sets the current selection to the specified DOM element. + * + * @method setNode + * @param {Element} elm Element to set as the contents of the selection. + * @return {Element} Returns the element that got passed in. + * @example + * // Inserts a DOM node at current selection/caret location + * tinymce.activeEditor.selection.setNode(tinymce.activeEditor.dom.create('img', {src: 'some.gif', title: 'some title'})); + */ + setNode: function(elm) { + var self = this; + + self.setContent(self.dom.getOuterHTML(elm)); + + return elm; + }, + + /** + * Returns the currently selected element or the common ancestor element for both start and end of the selection. + * + * @method getNode + * @return {Element} Currently selected element or common ancestor element. + * @example + * // Alerts the currently selected elements node name + * alert(tinymce.activeEditor.selection.getNode().nodeName); + */ + getNode: function() { + var self = this, rng = self.getRng(), elm; + var startContainer, endContainer, startOffset, endOffset, root = self.dom.getRoot(); + + function skipEmptyTextNodes(node, forwards) { + var orig = node; + + while (node && node.nodeType === 3 && node.length === 0) { + node = forwards ? node.nextSibling : node.previousSibling; + } + + return node || orig; + } + + // Range maybe lost after the editor is made visible again + if (!rng) { + return root; + } + + startContainer = rng.startContainer; + endContainer = rng.endContainer; + startOffset = rng.startOffset; + endOffset = rng.endOffset; + + if (rng.setStart) { + elm = rng.commonAncestorContainer; + + // Handle selection a image or other control like element such as anchors + if (!rng.collapsed) { + if (startContainer == endContainer) { + if (endOffset - startOffset < 2) { + if (startContainer.hasChildNodes()) { + elm = startContainer.childNodes[startOffset]; + } + } + } + + // If the anchor node is a element instead of a text node then return this element + //if (tinymce.isWebKit && sel.anchorNode && sel.anchorNode.nodeType == 1) + // return sel.anchorNode.childNodes[sel.anchorOffset]; + + // Handle cases where the selection is immediately wrapped around a node and return that node instead of it's parent. + // This happens when you double click an underlined word in FireFox. + if (startContainer.nodeType === 3 && endContainer.nodeType === 3) { + if (startContainer.length === startOffset) { + startContainer = skipEmptyTextNodes(startContainer.nextSibling, true); + } else { + startContainer = startContainer.parentNode; + } + + if (endOffset === 0) { + endContainer = skipEmptyTextNodes(endContainer.previousSibling, false); + } else { + endContainer = endContainer.parentNode; + } + + if (startContainer && startContainer === endContainer) { + return startContainer; + } + } + } + + if (elm && elm.nodeType == 3) { + return elm.parentNode; + } + + return elm; + } + + elm = rng.item ? rng.item(0) : rng.parentElement(); + + // IE 7 might return elements outside the iframe + if (elm.ownerDocument !== self.win.document) { + elm = root; + } + + return elm; + }, + + getSelectedBlocks: function(startElm, endElm) { + var self = this, dom = self.dom, node, root, selectedBlocks = []; + + root = dom.getRoot(); + startElm = dom.getParent(startElm || self.getStart(), dom.isBlock); + endElm = dom.getParent(endElm || self.getEnd(), dom.isBlock); + + if (startElm && startElm != root) { + selectedBlocks.push(startElm); + } + + if (startElm && endElm && startElm != endElm) { + node = startElm; + + var walker = new TreeWalker(startElm, root); + while ((node = walker.next()) && node != endElm) { + if (dom.isBlock(node)) { + selectedBlocks.push(node); + } + } + } + + if (endElm && startElm != endElm && endElm != root) { + selectedBlocks.push(endElm); + } + + return selectedBlocks; + }, + + isForward: function() { + var dom = this.dom, sel = this.getSel(), anchorRange, focusRange; + + // No support for selection direction then always return true + if (!sel || !sel.anchorNode || !sel.focusNode) { + return true; + } + + anchorRange = dom.createRng(); + anchorRange.setStart(sel.anchorNode, sel.anchorOffset); + anchorRange.collapse(true); + + focusRange = dom.createRng(); + focusRange.setStart(sel.focusNode, sel.focusOffset); + focusRange.collapse(true); + + return anchorRange.compareBoundaryPoints(anchorRange.START_TO_START, focusRange) <= 0; + }, + + normalize: function() { + var self = this, rng = self.getRng(); + + if (Env.range && new RangeUtils(self.dom).normalize(rng)) { + self.setRng(rng, self.isForward()); + } + + return rng; + }, + + /** + * Executes callback when the current selection starts/stops matching the specified selector. The current + * state will be passed to the callback as it's first argument. + * + * @method selectorChanged + * @param {String} selector CSS selector to check for. + * @param {function} callback Callback with state and args when the selector is matches or not. + */ + selectorChanged: function(selector, callback) { + var self = this, currentSelectors; + + if (!self.selectorChangedData) { + self.selectorChangedData = {}; + currentSelectors = {}; + + self.editor.on('NodeChange', function(e) { + var node = e.element, dom = self.dom, parents = dom.getParents(node, null, dom.getRoot()), matchedSelectors = {}; + + // Check for new matching selectors + each(self.selectorChangedData, function(callbacks, selector) { + each(parents, function(node) { + if (dom.is(node, selector)) { + if (!currentSelectors[selector]) { + // Execute callbacks + each(callbacks, function(callback) { + callback(true, {node: node, selector: selector, parents: parents}); + }); + + currentSelectors[selector] = callbacks; + } + + matchedSelectors[selector] = callbacks; + return false; + } + }); + }); + + // Check if current selectors still match + each(currentSelectors, function(callbacks, selector) { + if (!matchedSelectors[selector]) { + delete currentSelectors[selector]; + + each(callbacks, function(callback) { + callback(false, {node: node, selector: selector, parents: parents}); + }); + } + }); + }); + } + + // Add selector listeners + if (!self.selectorChangedData[selector]) { + self.selectorChangedData[selector] = []; + } + + self.selectorChangedData[selector].push(callback); + + return self; + }, + + getScrollContainer: function() { + var scrollContainer, node = this.dom.getRoot(); + + while (node && node.nodeName != 'BODY') { + if (node.scrollHeight > node.clientHeight) { + scrollContainer = node; + break; + } + + node = node.parentNode; + } + + return scrollContainer; + }, + + scrollIntoView: function(elm, alignToTop) { + var y, viewPort, self = this, dom = self.dom, root = dom.getRoot(), viewPortY, viewPortH, offsetY = 0; + + function getPos(elm) { + var x = 0, y = 0; + + var offsetParent = elm; + while (offsetParent && offsetParent.nodeType) { + x += offsetParent.offsetLeft || 0; + y += offsetParent.offsetTop || 0; + offsetParent = offsetParent.offsetParent; + } + + return {x: x, y: y}; + } + + if (!NodeType.isElement(elm)) { + return; + } + + if (alignToTop === false) { + offsetY = elm.offsetHeight; + } + + if (root.nodeName != 'BODY') { + var scrollContainer = self.getScrollContainer(); + if (scrollContainer) { + y = getPos(elm).y - getPos(scrollContainer).y + offsetY; + viewPortH = scrollContainer.clientHeight; + viewPortY = scrollContainer.scrollTop; + if (y < viewPortY || y + 25 > viewPortY + viewPortH) { + scrollContainer.scrollTop = y < viewPortY ? y : y - viewPortH + 25; + } + + return; + } + } + + viewPort = dom.getViewPort(self.editor.getWin()); + y = dom.getPos(elm).y + offsetY; + viewPortY = viewPort.y; + viewPortH = viewPort.h; + if (y < viewPort.y || y + 25 > viewPortY + viewPortH) { + self.editor.getWin().scrollTo(0, y < viewPortY ? y : y - viewPortH + 25); + } + }, + + placeCaretAt: function(clientX, clientY) { + this.setRng(RangeUtils.getCaretRangeFromPoint(clientX, clientY, this.editor.getDoc())); + }, + + _moveEndPoint: function(rng, node, start) { + var root = node, walker = new TreeWalker(node, root); + var nonEmptyElementsMap = this.dom.schema.getNonEmptyElements(); + + do { + // Text node + if (node.nodeType == 3 && trim(node.nodeValue).length !== 0) { + if (start) { + rng.setStart(node, 0); + } else { + rng.setEnd(node, node.nodeValue.length); + } + + return; + } + + // BR/IMG/INPUT elements but not table cells + if (nonEmptyElementsMap[node.nodeName] && !/^(TD|TH)$/.test(node.nodeName)) { + if (start) { + rng.setStartBefore(node); + } else { + if (node.nodeName == 'BR') { + rng.setEndBefore(node); + } else { + rng.setEndAfter(node); + } + } + + return; + } + + // Found empty text block old IE can place the selection inside those + if (Env.ie && Env.ie < 11 && this.dom.isBlock(node) && this.dom.isEmpty(node)) { + if (start) { + rng.setStart(node, 0); + } else { + rng.setEnd(node, 0); + } + + return; + } + } while ((node = (start ? walker.next() : walker.prev()))); + + // Failed to find any text node or other suitable location then move to the root of body + if (root.nodeName == 'BODY') { + if (start) { + rng.setStart(root, 0); + } else { + rng.setEnd(root, root.childNodes.length); + } + } + }, + + destroy: function() { + this.win = null; + this.controlSelection.destroy(); + } + }; + + return Selection; +}); + +// Included from: js/tinymce/classes/dom/ElementUtils.js + +/** + * ElementUtils.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Utility class for various element specific functions. + * + * @private + * @class tinymce.dom.ElementUtils + */ +define("tinymce/dom/ElementUtils", [ + "tinymce/dom/BookmarkManager", + "tinymce/util/Tools" +], function(BookmarkManager, Tools) { + var each = Tools.each; + + function ElementUtils(dom) { + /** + * Compares two nodes and checks if it's attributes and styles matches. + * This doesn't compare classes as items since their order is significant. + * + * @method compare + * @param {Node} node1 First node to compare with. + * @param {Node} node2 Second node to compare with. + * @return {boolean} True/false if the nodes are the same or not. + */ + this.compare = function(node1, node2) { + // Not the same name + if (node1.nodeName != node2.nodeName) { + return false; + } + + /** + * Returns all the nodes attributes excluding internal ones, styles and classes. + * + * @private + * @param {Node} node Node to get attributes from. + * @return {Object} Name/value object with attributes and attribute values. + */ + function getAttribs(node) { + var attribs = {}; + + each(dom.getAttribs(node), function(attr) { + var name = attr.nodeName.toLowerCase(); + + // Don't compare internal attributes or style + if (name.indexOf('_') !== 0 && name !== 'style' && name !== 'data-mce-style' && name != 'data-mce-fragment') { + attribs[name] = dom.getAttrib(node, name); + } + }); + + return attribs; + } + + /** + * Compares two objects checks if it's key + value exists in the other one. + * + * @private + * @param {Object} obj1 First object to compare. + * @param {Object} obj2 Second object to compare. + * @return {boolean} True/false if the objects matches or not. + */ + function compareObjects(obj1, obj2) { + var value, name; + + for (name in obj1) { + // Obj1 has item obj2 doesn't have + if (obj1.hasOwnProperty(name)) { + value = obj2[name]; + + // Obj2 doesn't have obj1 item + if (typeof value == "undefined") { + return false; + } + + // Obj2 item has a different value + if (obj1[name] != value) { + return false; + } + + // Delete similar value + delete obj2[name]; + } + } + + // Check if obj 2 has something obj 1 doesn't have + for (name in obj2) { + // Obj2 has item obj1 doesn't have + if (obj2.hasOwnProperty(name)) { + return false; + } + } + + return true; + } + + // Attribs are not the same + if (!compareObjects(getAttribs(node1), getAttribs(node2))) { + return false; + } + + // Styles are not the same + if (!compareObjects(dom.parseStyle(dom.getAttrib(node1, 'style')), dom.parseStyle(dom.getAttrib(node2, 'style')))) { + return false; + } + + return !BookmarkManager.isBookmarkNode(node1) && !BookmarkManager.isBookmarkNode(node2); + }; + } + + return ElementUtils; +}); + +// Included from: js/tinymce/classes/fmt/Preview.js + +/** + * Preview.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Internal class for generating previews styles for formats. + * + * Example: + * Preview.getCssText(editor, 'bold'); + * + * @private + * @class tinymce.fmt.Preview + */ +define("tinymce/fmt/Preview", [ + "tinymce/util/Tools" +], function(Tools) { + var each = Tools.each; + + function getCssText(editor, format) { + var name, previewElm, dom = editor.dom; + var previewCss = '', parentFontSize, previewStyles; + + previewStyles = editor.settings.preview_styles; + + // No preview forced + if (previewStyles === false) { + return ''; + } + + // Default preview + if (!previewStyles) { + previewStyles = 'font-family font-size font-weight font-style text-decoration ' + + 'text-transform color background-color border border-radius outline text-shadow'; + } + + // Removes any variables since these can't be previewed + function removeVars(val) { + return val.replace(/%(\w+)/g, ''); + } + + // Create block/inline element to use for preview + if (typeof format == "string") { + format = editor.formatter.get(format); + if (!format) { + return; + } + + format = format[0]; + } + + name = format.block || format.inline || 'span'; + previewElm = dom.create(name); + + // Add format styles to preview element + each(format.styles, function(value, name) { + value = removeVars(value); + + if (value) { + dom.setStyle(previewElm, name, value); + } + }); + + // Add attributes to preview element + each(format.attributes, function(value, name) { + value = removeVars(value); + + if (value) { + dom.setAttrib(previewElm, name, value); + } + }); + + // Add classes to preview element + each(format.classes, function(value) { + value = removeVars(value); + + if (!dom.hasClass(previewElm, value)) { + dom.addClass(previewElm, value); + } + }); + + editor.fire('PreviewFormats'); + + // Add the previewElm outside the visual area + dom.setStyles(previewElm, {position: 'absolute', left: -0xFFFF}); + editor.getBody().appendChild(previewElm); + + // Get parent container font size so we can compute px values out of em/% for older IE:s + parentFontSize = dom.getStyle(editor.getBody(), 'fontSize', true); + parentFontSize = /px$/.test(parentFontSize) ? parseInt(parentFontSize, 10) : 0; + + each(previewStyles.split(' '), function(name) { + var value = dom.getStyle(previewElm, name, true); + + // If background is transparent then check if the body has a background color we can use + if (name == 'background-color' && /transparent|rgba\s*\([^)]+,\s*0\)/.test(value)) { + value = dom.getStyle(editor.getBody(), name, true); + + // Ignore white since it's the default color, not the nicest fix + // TODO: Fix this by detecting runtime style + if (dom.toHex(value).toLowerCase() == '#ffffff') { + return; + } + } + + if (name == 'color') { + // Ignore black since it's the default color, not the nicest fix + // TODO: Fix this by detecting runtime style + if (dom.toHex(value).toLowerCase() == '#000000') { + return; + } + } + + // Old IE won't calculate the font size so we need to do that manually + if (name == 'font-size') { + if (/em|%$/.test(value)) { + if (parentFontSize === 0) { + return; + } + + // Convert font size from em/% to px + value = parseFloat(value, 10) / (/%$/.test(value) ? 100 : 1); + value = (value * parentFontSize) + 'px'; + } + } + + if (name == "border" && value) { + previewCss += 'padding:0 2px;'; + } + + previewCss += name + ':' + value + ';'; + }); + + editor.fire('AfterPreviewFormats'); + + //previewCss += 'line-height:normal'; + + dom.remove(previewElm); + + return previewCss; + } + + return { + getCssText: getCssText + }; +}); + +// Included from: js/tinymce/classes/fmt/Hooks.js + +/** + * Hooks.js + * + * Released under LGPL License. + * Copyright (c) 1999-2016 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Internal class for overriding formatting. + * + * @private + * @class tinymce.fmt.Hooks + */ +define("tinymce/fmt/Hooks", [ + "tinymce/util/Arr", + "tinymce/dom/NodeType", + "tinymce/dom/DomQuery" +], function(Arr, NodeType, $) { + var postProcessHooks = [], filter = Arr.filter, each = Arr.each; + + function addPostProcessHook(name, hook) { + var hooks = postProcessHooks[name]; + + if (!hooks) { + postProcessHooks[name] = hooks = []; + } + + postProcessHooks[name].push(hook); + } + + function postProcess(name, editor) { + each(postProcessHooks[name], function(hook) { + hook(editor); + }); + } + + addPostProcessHook("pre", function(editor) { + var rng = editor.selection.getRng(), isPre, blocks; + + function hasPreSibling(pre) { + return isPre(pre.previousSibling) && Arr.indexOf(blocks, pre.previousSibling) != -1; + } + + function joinPre(pre1, pre2) { + $(pre2).remove(); + $(pre1).append('<br><br>').append(pre2.childNodes); + } + + isPre = NodeType.matchNodeNames('pre'); + + if (!rng.collapsed) { + blocks = editor.selection.getSelectedBlocks(); + + each(filter(filter(blocks, isPre), hasPreSibling), function(pre) { + joinPre(pre.previousSibling, pre); + }); + } + }); + + return { + postProcess: postProcess + }; +}); + +// Included from: js/tinymce/classes/Formatter.js + +/** + * Formatter.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Text formatter engine class. This class is used to apply formats like bold, italic, font size + * etc to the current selection or specific nodes. This engine was built to replace the browser's + * default formatting logic for execCommand due to its inconsistent and buggy behavior. + * + * @class tinymce.Formatter + * @example + * tinymce.activeEditor.formatter.register('mycustomformat', { + * inline: 'span', + * styles: {color: '#ff0000'} + * }); + * + * tinymce.activeEditor.formatter.apply('mycustomformat'); + */ +define("tinymce/Formatter", [ + "tinymce/dom/TreeWalker", + "tinymce/dom/RangeUtils", + "tinymce/dom/BookmarkManager", + "tinymce/dom/ElementUtils", + "tinymce/util/Tools", + "tinymce/fmt/Preview", + "tinymce/fmt/Hooks" +], function(TreeWalker, RangeUtils, BookmarkManager, ElementUtils, Tools, Preview, Hooks) { + /** + * Constructs a new formatter instance. + * + * @constructor Formatter + * @param {tinymce.Editor} ed Editor instance to construct the formatter engine to. + */ + return function(ed) { + var formats = {}, + dom = ed.dom, + selection = ed.selection, + rangeUtils = new RangeUtils(dom), + isValid = ed.schema.isValidChild, + isBlock = dom.isBlock, + forcedRootBlock = ed.settings.forced_root_block, + nodeIndex = dom.nodeIndex, + INVISIBLE_CHAR = '\uFEFF', + MCE_ATTR_RE = /^(src|href|style)$/, + FALSE = false, + TRUE = true, + formatChangeData, + undef, + getContentEditable = dom.getContentEditable, + disableCaretContainer, + markCaretContainersBogus, + isBookmarkNode = BookmarkManager.isBookmarkNode; + + var each = Tools.each, + grep = Tools.grep, + walk = Tools.walk, + extend = Tools.extend; + + function isTextBlock(name) { + if (name.nodeType) { + name = name.nodeName; + } + + return !!ed.schema.getTextBlockElements()[name.toLowerCase()]; + } + + function isTableCell(node) { + return /^(TH|TD)$/.test(node.nodeName); + } + + function isInlineBlock(node) { + return node && /^(IMG)$/.test(node.nodeName); + } + + function getParents(node, selector) { + return dom.getParents(node, selector, dom.getRoot()); + } + + function isCaretNode(node) { + return node.nodeType === 1 && node.id === '_mce_caret'; + } + + function defaultFormats() { + register({ + valigntop: [ + {selector: 'td,th', styles: {'verticalAlign': 'top'}} + ], + + valignmiddle: [ + {selector: 'td,th', styles: {'verticalAlign': 'middle'}} + ], + + valignbottom: [ + {selector: 'td,th', styles: {'verticalAlign': 'bottom'}} + ], + + alignleft: [ + {selector: 'figure.image', collapsed: false, classes: 'align-left', ceFalseOverride: true}, + { + selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li', + styles: { + textAlign: 'left' + }, + inherit: false, + defaultBlock: 'div' + }, + {selector: 'img,table', collapsed: false, styles: {'float': 'left'}} + ], + + aligncenter: [ + { + selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li', + styles: { + textAlign: 'center' + }, + inherit: false, + defaultBlock: 'div' + }, + {selector: 'figure.image', collapsed: false, classes: 'align-center', ceFalseOverride: true}, + {selector: 'img', collapsed: false, styles: {display: 'block', marginLeft: 'auto', marginRight: 'auto'}}, + {selector: 'table', collapsed: false, styles: {marginLeft: 'auto', marginRight: 'auto'}} + ], + + alignright: [ + {selector: 'figure.image', collapsed: false, classes: 'align-right', ceFalseOverride: true}, + { + selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li', + styles: { + textAlign: 'right' + }, + inherit: false, + defaultBlock: 'div' + }, + {selector: 'img,table', collapsed: false, styles: {'float': 'right'}} + ], + + alignjustify: [ + { + selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li', + styles: { + textAlign: 'justify' + }, + inherit: false, + defaultBlock: 'div' + } + ], + + bold: [ + {inline: 'strong', remove: 'all'}, + {inline: 'span', styles: {fontWeight: 'bold'}}, + {inline: 'b', remove: 'all'} + ], + + italic: [ + {inline: 'em', remove: 'all'}, + {inline: 'span', styles: {fontStyle: 'italic'}}, + {inline: 'i', remove: 'all'} + ], + + underline: [ + {inline: 'span', styles: {textDecoration: 'underline'}, exact: true}, + {inline: 'u', remove: 'all'} + ], + + strikethrough: [ + {inline: 'span', styles: {textDecoration: 'line-through'}, exact: true}, + {inline: 'strike', remove: 'all'} + ], + + forecolor: {inline: 'span', styles: {color: '%value'}, links: true, remove_similar: true}, + hilitecolor: {inline: 'span', styles: {backgroundColor: '%value'}, links: true, remove_similar: true}, + fontname: {inline: 'span', styles: {fontFamily: '%value'}}, + fontsize: {inline: 'span', styles: {fontSize: '%value'}}, + fontsize_class: {inline: 'span', attributes: {'class': '%value'}}, + blockquote: {block: 'blockquote', wrapper: 1, remove: 'all'}, + subscript: {inline: 'sub'}, + superscript: {inline: 'sup'}, + code: {inline: 'code'}, + + link: {inline: 'a', selector: 'a', remove: 'all', split: true, deep: true, + onmatch: function() { + return true; + }, + + onformat: function(elm, fmt, vars) { + each(vars, function(value, key) { + dom.setAttrib(elm, key, value); + }); + } + }, + + removeformat: [ + { + selector: 'b,strong,em,i,font,u,strike,sub,sup,dfn,code,samp,kbd,var,cite,mark,q,del,ins', + remove: 'all', + split: true, + expand: false, + block_expand: true, + deep: true + }, + {selector: 'span', attributes: ['style', 'class'], remove: 'empty', split: true, expand: false, deep: true}, + {selector: '*', attributes: ['style', 'class'], split: false, expand: false, deep: true} + ] + }); + + // Register default block formats + each('p h1 h2 h3 h4 h5 h6 div address pre div dt dd samp'.split(/\s/), function(name) { + register(name, {block: name, remove: 'all'}); + }); + + // Register user defined formats + register(ed.settings.formats); + } + + function addKeyboardShortcuts() { + // Add some inline shortcuts + ed.addShortcut('meta+b', 'bold_desc', 'Bold'); + ed.addShortcut('meta+i', 'italic_desc', 'Italic'); + ed.addShortcut('meta+u', 'underline_desc', 'Underline'); + + // BlockFormat shortcuts keys + for (var i = 1; i <= 6; i++) { + ed.addShortcut('access+' + i, '', ['FormatBlock', false, 'h' + i]); + } + + ed.addShortcut('access+7', '', ['FormatBlock', false, 'p']); + ed.addShortcut('access+8', '', ['FormatBlock', false, 'div']); + ed.addShortcut('access+9', '', ['FormatBlock', false, 'address']); + } + + // Public functions + + /** + * Returns the format by name or all formats if no name is specified. + * + * @method get + * @param {String} name Optional name to retrieve by. + * @return {Array/Object} Array/Object with all registered formats or a specific format. + */ + function get(name) { + return name ? formats[name] : formats; + } + + /** + * Registers a specific format by name. + * + * @method register + * @param {Object/String} name Name of the format for example "bold". + * @param {Object/Array} format Optional format object or array of format variants + * can only be omitted if the first arg is an object. + */ + function register(name, format) { + if (name) { + if (typeof name !== 'string') { + each(name, function(format, name) { + register(name, format); + }); + } else { + // Force format into array and add it to internal collection + format = format.length ? format : [format]; + + each(format, function(format) { + // Set deep to false by default on selector formats this to avoid removing + // alignment on images inside paragraphs when alignment is changed on paragraphs + if (format.deep === undef) { + format.deep = !format.selector; + } + + // Default to true + if (format.split === undef) { + format.split = !format.selector || format.inline; + } + + // Default to true + if (format.remove === undef && format.selector && !format.inline) { + format.remove = 'none'; + } + + // Mark format as a mixed format inline + block level + if (format.selector && format.inline) { + format.mixed = true; + format.block_expand = true; + } + + // Split classes if needed + if (typeof format.classes === 'string') { + format.classes = format.classes.split(/\s+/); + } + }); + + formats[name] = format; + } + } + } + + /** + * Unregister a specific format by name. + * + * @method unregister + * @param {String} name Name of the format for example "bold". + */ + function unregister(name) { + if (name && formats[name]) { + delete formats[name]; + } + + return formats; + } + + function matchesUnInheritedFormatSelector(node, name) { + var formatList = get(name); + + if (formatList) { + for (var i = 0; i < formatList.length; i++) { + if (formatList[i].inherit === false && dom.is(node, formatList[i].selector)) { + return true; + } + } + } + + return false; + } + + function getTextDecoration(node) { + var decoration; + + ed.dom.getParent(node, function(n) { + decoration = ed.dom.getStyle(n, 'text-decoration'); + return decoration && decoration !== 'none'; + }); + + return decoration; + } + + function processUnderlineAndColor(node) { + var textDecoration; + if (node.nodeType === 1 && node.parentNode && node.parentNode.nodeType === 1) { + textDecoration = getTextDecoration(node.parentNode); + if (ed.dom.getStyle(node, 'color') && textDecoration) { + ed.dom.setStyle(node, 'text-decoration', textDecoration); + } else if (ed.dom.getStyle(node, 'text-decoration') === textDecoration) { + ed.dom.setStyle(node, 'text-decoration', null); + } + } + } + + /** + * Applies the specified format to the current selection or specified node. + * + * @method apply + * @param {String} name Name of format to apply. + * @param {Object} vars Optional list of variables to replace within format before applying it. + * @param {Node} node Optional node to apply the format to defaults to current selection. + */ + function apply(name, vars, node) { + var formatList = get(name), format = formatList[0], bookmark, rng, isCollapsed = !node && selection.isCollapsed(); + + function setElementFormat(elm, fmt) { + fmt = fmt || format; + + if (elm) { + if (fmt.onformat) { + fmt.onformat(elm, fmt, vars, node); + } + + each(fmt.styles, function(value, name) { + dom.setStyle(elm, name, replaceVars(value, vars)); + }); + + // Needed for the WebKit span spam bug + // TODO: Remove this once WebKit/Blink fixes this + if (fmt.styles) { + var styleVal = dom.getAttrib(elm, 'style'); + + if (styleVal) { + elm.setAttribute('data-mce-style', styleVal); + } + } + + each(fmt.attributes, function(value, name) { + dom.setAttrib(elm, name, replaceVars(value, vars)); + }); + + each(fmt.classes, function(value) { + value = replaceVars(value, vars); + + if (!dom.hasClass(elm, value)) { + dom.addClass(elm, value); + } + }); + } + } + + // This converts: <p>[a</p><p>]b</p> -> <p>[a]</p><p>b</p> + function adjustSelectionToVisibleSelection() { + function findSelectionEnd(start, end) { + var walker = new TreeWalker(end); + for (node = walker.prev2(); node; node = walker.prev2()) { + if (node.nodeType == 3 && node.data.length > 0) { + return node; + } + + if (node.childNodes.length > 1 || node == start || node.tagName == 'BR') { + return node; + } + } + } + + // Adjust selection so that a end container with a end offset of zero is not included in the selection + // as this isn't visible to the user. + var rng = ed.selection.getRng(); + var start = rng.startContainer; + var end = rng.endContainer; + + if (start != end && rng.endOffset === 0) { + var newEnd = findSelectionEnd(start, end); + var endOffset = newEnd.nodeType == 3 ? newEnd.data.length : newEnd.childNodes.length; + + rng.setEnd(newEnd, endOffset); + } + + return rng; + } + + function applyRngStyle(rng, bookmark, node_specific) { + var newWrappers = [], wrapName, wrapElm, contentEditable = true; + + // Setup wrapper element + wrapName = format.inline || format.block; + wrapElm = dom.create(wrapName); + setElementFormat(wrapElm); + + rangeUtils.walk(rng, function(nodes) { + var currentWrapElm; + + /** + * Process a list of nodes wrap them. + */ + function process(node) { + var nodeName, parentName, found, hasContentEditableState, lastContentEditable; + + lastContentEditable = contentEditable; + nodeName = node.nodeName.toLowerCase(); + parentName = node.parentNode.nodeName.toLowerCase(); + + // Node has a contentEditable value + if (node.nodeType === 1 && getContentEditable(node)) { + lastContentEditable = contentEditable; + contentEditable = getContentEditable(node) === "true"; + hasContentEditableState = true; // We don't want to wrap the container only it's children + } + + // Stop wrapping on br elements + if (isEq(nodeName, 'br')) { + currentWrapElm = 0; + + // Remove any br elements when we wrap things + if (format.block) { + dom.remove(node); + } + + return; + } + + // If node is wrapper type + if (format.wrapper && matchNode(node, name, vars)) { + currentWrapElm = 0; + return; + } + + // Can we rename the block + // TODO: Break this if up, too complex + if (contentEditable && !hasContentEditableState && format.block && + !format.wrapper && isTextBlock(nodeName) && isValid(parentName, wrapName)) { + node = dom.rename(node, wrapName); + setElementFormat(node); + newWrappers.push(node); + currentWrapElm = 0; + return; + } + + // Handle selector patterns + if (format.selector) { + // Look for matching formats + each(formatList, function(format) { + // Check collapsed state if it exists + if ('collapsed' in format && format.collapsed !== isCollapsed) { + return; + } + + if (dom.is(node, format.selector) && !isCaretNode(node)) { + setElementFormat(node, format); + found = true; + return false; + } + }); + + // Continue processing if a selector match wasn't found and a inline element is defined + if (!format.inline || found) { + currentWrapElm = 0; + return; + } + } + + // Is it valid to wrap this item + // TODO: Break this if up, too complex + if (contentEditable && !hasContentEditableState && isValid(wrapName, nodeName) && isValid(parentName, wrapName) && + !(!node_specific && node.nodeType === 3 && + node.nodeValue.length === 1 && + node.nodeValue.charCodeAt(0) === 65279) && + !isCaretNode(node) && + (!format.inline || !isBlock(node))) { + // Start wrapping + if (!currentWrapElm) { + // Wrap the node + currentWrapElm = dom.clone(wrapElm, FALSE); + node.parentNode.insertBefore(currentWrapElm, node); + newWrappers.push(currentWrapElm); + } + + currentWrapElm.appendChild(node); + } else { + // Start a new wrapper for possible children + currentWrapElm = 0; + + each(grep(node.childNodes), process); + + if (hasContentEditableState) { + contentEditable = lastContentEditable; // Restore last contentEditable state from stack + } + + // End the last wrapper + currentWrapElm = 0; + } + } + + // Process siblings from range + each(nodes, process); + }); + + // Apply formats to links as well to get the color of the underline to change as well + if (format.links === true) { + each(newWrappers, function(node) { + function process(node) { + if (node.nodeName === 'A') { + setElementFormat(node, format); + } + + each(grep(node.childNodes), process); + } + + process(node); + }); + } + + // Cleanup + each(newWrappers, function(node) { + var childCount; + + function getChildCount(node) { + var count = 0; + + each(node.childNodes, function(node) { + if (!isWhiteSpaceNode(node) && !isBookmarkNode(node)) { + count++; + } + }); + + return count; + } + + function mergeStyles(node) { + var child, clone; + + each(node.childNodes, function(node) { + if (node.nodeType == 1 && !isBookmarkNode(node) && !isCaretNode(node)) { + child = node; + return FALSE; // break loop + } + }); + + // If child was found and of the same type as the current node + if (child && !isBookmarkNode(child) && matchName(child, format)) { + clone = dom.clone(child, FALSE); + setElementFormat(clone); + + dom.replace(clone, node, TRUE); + dom.remove(child, 1); + } + + return clone || node; + } + + childCount = getChildCount(node); + + // Remove empty nodes but only if there is multiple wrappers and they are not block + // elements so never remove single <h1></h1> since that would remove the + // current empty block element where the caret is at + if ((newWrappers.length > 1 || !isBlock(node)) && childCount === 0) { + dom.remove(node, 1); + return; + } + + if (format.inline || format.wrapper) { + // Merges the current node with it's children of similar type to reduce the number of elements + if (!format.exact && childCount === 1) { + node = mergeStyles(node); + } + + // Remove/merge children + each(formatList, function(format) { + // Merge all children of similar type will move styles from child to parent + // this: <span style="color:red"><b><span style="color:red; font-size:10px">text</span></b></span> + // will become: <span style="color:red"><b><span style="font-size:10px">text</span></b></span> + each(dom.select(format.inline, node), function(child) { + if (isBookmarkNode(child)) { + return; + } + + removeFormat(format, vars, child, format.exact ? child : null); + }); + }); + + // Remove child if direct parent is of same type + if (matchNode(node.parentNode, name, vars)) { + dom.remove(node, 1); + node = 0; + return TRUE; + } + + // Look for parent with similar style format + if (format.merge_with_parents) { + dom.getParent(node.parentNode, function(parent) { + if (matchNode(parent, name, vars)) { + dom.remove(node, 1); + node = 0; + return TRUE; + } + }); + } + + // Merge next and previous siblings if they are similar <b>text</b><b>text</b> becomes <b>texttext</b> + if (node && format.merge_siblings !== false) { + node = mergeSiblings(getNonWhiteSpaceSibling(node), node); + node = mergeSiblings(node, getNonWhiteSpaceSibling(node, TRUE)); + } + } + }); + } + + if (getContentEditable(selection.getNode()) === "false") { + node = selection.getNode(); + for (var i = 0, l = formatList.length; i < l; i++) { + if (formatList[i].ceFalseOverride && dom.is(node, formatList[i].selector)) { + setElementFormat(node, formatList[i]); + return; + } + } + + return; + } + + if (format) { + if (node) { + if (node.nodeType) { + rng = dom.createRng(); + rng.setStartBefore(node); + rng.setEndAfter(node); + applyRngStyle(expandRng(rng, formatList), null, true); + } else { + applyRngStyle(node, null, true); + } + } else { + if (!isCollapsed || !format.inline || dom.select('td[data-mce-selected],th[data-mce-selected]').length) { + // Obtain selection node before selection is unselected by applyRngStyle() + var curSelNode = ed.selection.getNode(); + + // If the formats have a default block and we can't find a parent block then + // start wrapping it with a DIV this is for forced_root_blocks: false + // It's kind of a hack but people should be using the default block type P since all desktop editors work that way + if (!forcedRootBlock && formatList[0].defaultBlock && !dom.getParent(curSelNode, dom.isBlock)) { + apply(formatList[0].defaultBlock); + } + + // Apply formatting to selection + ed.selection.setRng(adjustSelectionToVisibleSelection()); + bookmark = selection.getBookmark(); + applyRngStyle(expandRng(selection.getRng(TRUE), formatList), bookmark); + + // Colored nodes should be underlined so that the color of the underline matches the text color. + if (format.styles && (format.styles.color || format.styles.textDecoration)) { + walk(curSelNode, processUnderlineAndColor, 'childNodes'); + processUnderlineAndColor(curSelNode); + } + + selection.moveToBookmark(bookmark); + moveStart(selection.getRng(TRUE)); + ed.nodeChanged(); + } else { + performCaretAction('apply', name, vars); + } + } + + Hooks.postProcess(name, ed); + } + } + + /** + * Removes the specified format from the current selection or specified node. + * + * @method remove + * @param {String} name Name of format to remove. + * @param {Object} vars Optional list of variables to replace within format before removing it. + * @param {Node/Range} node Optional node or DOM range to remove the format from defaults to current selection. + */ + function remove(name, vars, node, similar) { + var formatList = get(name), format = formatList[0], bookmark, rng, contentEditable = true; + + // Merges the styles for each node + function process(node) { + var children, i, l, lastContentEditable, hasContentEditableState; + + // Node has a contentEditable value + if (node.nodeType === 1 && getContentEditable(node)) { + lastContentEditable = contentEditable; + contentEditable = getContentEditable(node) === "true"; + hasContentEditableState = true; // We don't want to wrap the container only it's children + } + + // Grab the children first since the nodelist might be changed + children = grep(node.childNodes); + + // Process current node + if (contentEditable && !hasContentEditableState) { + for (i = 0, l = formatList.length; i < l; i++) { + if (removeFormat(formatList[i], vars, node, node)) { + break; + } + } + } + + // Process the children + if (format.deep) { + if (children.length) { + for (i = 0, l = children.length; i < l; i++) { + process(children[i]); + } + + if (hasContentEditableState) { + contentEditable = lastContentEditable; // Restore last contentEditable state from stack + } + } + } + } + + function findFormatRoot(container) { + var formatRoot; + + // Find format root + each(getParents(container.parentNode).reverse(), function(parent) { + var format; + + // Find format root element + if (!formatRoot && parent.id != '_start' && parent.id != '_end') { + // Is the node matching the format we are looking for + format = matchNode(parent, name, vars, similar); + if (format && format.split !== false) { + formatRoot = parent; + } + } + }); + + return formatRoot; + } + + function wrapAndSplit(formatRoot, container, target, split) { + var parent, clone, lastClone, firstClone, i, formatRootParent; + + // Format root found then clone formats and split it + if (formatRoot) { + formatRootParent = formatRoot.parentNode; + + for (parent = container.parentNode; parent && parent != formatRootParent; parent = parent.parentNode) { + clone = dom.clone(parent, FALSE); + + for (i = 0; i < formatList.length; i++) { + if (removeFormat(formatList[i], vars, clone, clone)) { + clone = 0; + break; + } + } + + // Build wrapper node + if (clone) { + if (lastClone) { + clone.appendChild(lastClone); + } + + if (!firstClone) { + firstClone = clone; + } + + lastClone = clone; + } + } + + // Never split block elements if the format is mixed + if (split && (!format.mixed || !isBlock(formatRoot))) { + container = dom.split(formatRoot, container); + } + + // Wrap container in cloned formats + if (lastClone) { + target.parentNode.insertBefore(lastClone, target); + firstClone.appendChild(target); + } + } + + return container; + } + + function splitToFormatRoot(container) { + return wrapAndSplit(findFormatRoot(container), container, container, true); + } + + function unwrap(start) { + var node = dom.get(start ? '_start' : '_end'), + out = node[start ? 'firstChild' : 'lastChild']; + + // If the end is placed within the start the result will be removed + // So this checks if the out node is a bookmark node if it is it + // checks for another more suitable node + if (isBookmarkNode(out)) { + out = out[start ? 'firstChild' : 'lastChild']; + } + + // Since dom.remove removes empty text nodes then we need to try to find a better node + if (out.nodeType == 3 && out.data.length === 0) { + out = start ? node.previousSibling || node.nextSibling : node.nextSibling || node.previousSibling; + } + + dom.remove(node, true); + + return out; + } + + function removeRngStyle(rng) { + var startContainer, endContainer; + var commonAncestorContainer = rng.commonAncestorContainer; + + rng = expandRng(rng, formatList, TRUE); + + if (format.split) { + startContainer = getContainer(rng, TRUE); + endContainer = getContainer(rng); + + if (startContainer != endContainer) { + // WebKit will render the table incorrectly if we wrap a TH or TD in a SPAN + // so let's see if we can use the first child instead + // This will happen if you triple click a table cell and use remove formatting + if (/^(TR|TH|TD)$/.test(startContainer.nodeName) && startContainer.firstChild) { + if (startContainer.nodeName == "TR") { + startContainer = startContainer.firstChild.firstChild || startContainer; + } else { + startContainer = startContainer.firstChild || startContainer; + } + } + + // Try to adjust endContainer as well if cells on the same row were selected - bug #6410 + if (commonAncestorContainer && + /^T(HEAD|BODY|FOOT|R)$/.test(commonAncestorContainer.nodeName) && + isTableCell(endContainer) && endContainer.firstChild) { + endContainer = endContainer.firstChild || endContainer; + } + + if (dom.isChildOf(startContainer, endContainer) && !isBlock(endContainer) && + !isTableCell(startContainer) && !isTableCell(endContainer)) { + startContainer = wrap(startContainer, 'span', {id: '_start', 'data-mce-type': 'bookmark'}); + splitToFormatRoot(startContainer); + startContainer = unwrap(TRUE); + return; + } + + // Wrap start/end nodes in span element since these might be cloned/moved + startContainer = wrap(startContainer, 'span', {id: '_start', 'data-mce-type': 'bookmark'}); + endContainer = wrap(endContainer, 'span', {id: '_end', 'data-mce-type': 'bookmark'}); + + // Split start/end + splitToFormatRoot(startContainer); + splitToFormatRoot(endContainer); + + // Unwrap start/end to get real elements again + startContainer = unwrap(TRUE); + endContainer = unwrap(); + } else { + startContainer = endContainer = splitToFormatRoot(startContainer); + } + + // Update range positions since they might have changed after the split operations + rng.startContainer = startContainer.parentNode ? startContainer.parentNode : startContainer; + rng.startOffset = nodeIndex(startContainer); + rng.endContainer = endContainer.parentNode ? endContainer.parentNode : endContainer; + rng.endOffset = nodeIndex(endContainer) + 1; + } + + // Remove items between start/end + rangeUtils.walk(rng, function(nodes) { + each(nodes, function(node) { + process(node); + + // Remove parent span if it only contains text-decoration: underline, yet a parent node is also underlined. + if (node.nodeType === 1 && ed.dom.getStyle(node, 'text-decoration') === 'underline' && + node.parentNode && getTextDecoration(node.parentNode) === 'underline') { + removeFormat({ + 'deep': false, + 'exact': true, + 'inline': 'span', + 'styles': { + 'textDecoration': 'underline' + } + }, null, node); + } + }); + }); + } + + // Handle node + if (node) { + if (node.nodeType) { + rng = dom.createRng(); + rng.setStartBefore(node); + rng.setEndAfter(node); + removeRngStyle(rng); + } else { + removeRngStyle(node); + } + + return; + } + + if (getContentEditable(selection.getNode()) === "false") { + node = selection.getNode(); + for (var i = 0, l = formatList.length; i < l; i++) { + if (formatList[i].ceFalseOverride) { + if (removeFormat(formatList[i], vars, node, node)) { + break; + } + } + } + + return; + } + + if (!selection.isCollapsed() || !format.inline || dom.select('td[data-mce-selected],th[data-mce-selected]').length) { + bookmark = selection.getBookmark(); + removeRngStyle(selection.getRng(TRUE)); + selection.moveToBookmark(bookmark); + + // Check if start element still has formatting then we are at: "<b>text|</b>text" + // and need to move the start into the next text node + if (format.inline && match(name, vars, selection.getStart())) { + moveStart(selection.getRng(true)); + } + + ed.nodeChanged(); + } else { + performCaretAction('remove', name, vars, similar); + } + } + + /** + * Toggles the specified format on/off. + * + * @method toggle + * @param {String} name Name of format to apply/remove. + * @param {Object} vars Optional list of variables to replace within format before applying/removing it. + * @param {Node} node Optional node to apply the format to or remove from. Defaults to current selection. + */ + function toggle(name, vars, node) { + var fmt = get(name); + + if (match(name, vars, node) && (!('toggle' in fmt[0]) || fmt[0].toggle)) { + remove(name, vars, node); + } else { + apply(name, vars, node); + } + } + + /** + * Return true/false if the specified node has the specified format. + * + * @method matchNode + * @param {Node} node Node to check the format on. + * @param {String} name Format name to check. + * @param {Object} vars Optional list of variables to replace before checking it. + * @param {Boolean} similar Match format that has similar properties. + * @return {Object} Returns the format object it matches or undefined if it doesn't match. + */ + function matchNode(node, name, vars, similar) { + var formatList = get(name), format, i, classes; + + function matchItems(node, format, item_name) { + var key, value, items = format[item_name], i; + + // Custom match + if (format.onmatch) { + return format.onmatch(node, format, item_name); + } + + // Check all items + if (items) { + // Non indexed object + if (items.length === undef) { + for (key in items) { + if (items.hasOwnProperty(key)) { + if (item_name === 'attributes') { + value = dom.getAttrib(node, key); + } else { + value = getStyle(node, key); + } + + if (similar && !value && !format.exact) { + return; + } + + if ((!similar || format.exact) && !isEq(value, normalizeStyleValue(replaceVars(items[key], vars), key))) { + return; + } + } + } + } else { + // Only one match needed for indexed arrays + for (i = 0; i < items.length; i++) { + if (item_name === 'attributes' ? dom.getAttrib(node, items[i]) : getStyle(node, items[i])) { + return format; + } + } + } + } + + return format; + } + + if (formatList && node) { + // Check each format in list + for (i = 0; i < formatList.length; i++) { + format = formatList[i]; + + // Name name, attributes, styles and classes + if (matchName(node, format) && matchItems(node, format, 'attributes') && matchItems(node, format, 'styles')) { + // Match classes + if ((classes = format.classes)) { + for (i = 0; i < classes.length; i++) { + if (!dom.hasClass(node, classes[i])) { + return; + } + } + } + + return format; + } + } + } + } + + /** + * Matches the current selection or specified node against the specified format name. + * + * @method match + * @param {String} name Name of format to match. + * @param {Object} vars Optional list of variables to replace before checking it. + * @param {Node} node Optional node to check. + * @return {boolean} true/false if the specified selection/node matches the format. + */ + function match(name, vars, node) { + var startNode; + + function matchParents(node) { + var root = dom.getRoot(); + + if (node === root) { + return false; + } + + // Find first node with similar format settings + node = dom.getParent(node, function(node) { + if (matchesUnInheritedFormatSelector(node, name)) { + return true; + } + + return node.parentNode === root || !!matchNode(node, name, vars, true); + }); + + // Do an exact check on the similar format element + return matchNode(node, name, vars); + } + + // Check specified node + if (node) { + return matchParents(node); + } + + // Check selected node + node = selection.getNode(); + if (matchParents(node)) { + return TRUE; + } + + // Check start node if it's different + startNode = selection.getStart(); + if (startNode != node) { + if (matchParents(startNode)) { + return TRUE; + } + } + + return FALSE; + } + + /** + * Matches the current selection against the array of formats and returns a new array with matching formats. + * + * @method matchAll + * @param {Array} names Name of format to match. + * @param {Object} vars Optional list of variables to replace before checking it. + * @return {Array} Array with matched formats. + */ + function matchAll(names, vars) { + var startElement, matchedFormatNames = [], checkedMap = {}; + + // Check start of selection for formats + startElement = selection.getStart(); + dom.getParent(startElement, function(node) { + var i, name; + + for (i = 0; i < names.length; i++) { + name = names[i]; + + if (!checkedMap[name] && matchNode(node, name, vars)) { + checkedMap[name] = true; + matchedFormatNames.push(name); + } + } + }, dom.getRoot()); + + return matchedFormatNames; + } + + /** + * Returns true/false if the specified format can be applied to the current selection or not. It + * will currently only check the state for selector formats, it returns true on all other format types. + * + * @method canApply + * @param {String} name Name of format to check. + * @return {boolean} true/false if the specified format can be applied to the current selection/node. + */ + function canApply(name) { + var formatList = get(name), startNode, parents, i, x, selector; + + if (formatList) { + startNode = selection.getStart(); + parents = getParents(startNode); + + for (x = formatList.length - 1; x >= 0; x--) { + selector = formatList[x].selector; + + // Format is not selector based then always return TRUE + // Is it has a defaultBlock then it's likely it can be applied for example align on a non block element line + if (!selector || formatList[x].defaultBlock) { + return TRUE; + } + + for (i = parents.length - 1; i >= 0; i--) { + if (dom.is(parents[i], selector)) { + return TRUE; + } + } + } + } + + return FALSE; + } + + /** + * Executes the specified callback when the current selection matches the formats or not. + * + * @method formatChanged + * @param {String} formats Comma separated list of formats to check for. + * @param {function} callback Callback with state and args when the format is changed/toggled on/off. + * @param {Boolean} similar True/false state if the match should handle similar or exact formats. + */ + function formatChanged(formats, callback, similar) { + var currentFormats; + + // Setup format node change logic + if (!formatChangeData) { + formatChangeData = {}; + currentFormats = {}; + + ed.on('NodeChange', function(e) { + var parents = getParents(e.element), matchedFormats = {}; + + // Ignore bogus nodes like the <a> tag created by moveStart() + parents = Tools.grep(parents, function(node) { + return node.nodeType == 1 && !node.getAttribute('data-mce-bogus'); + }); + + // Check for new formats + each(formatChangeData, function(callbacks, format) { + each(parents, function(node) { + if (matchNode(node, format, {}, callbacks.similar)) { + if (!currentFormats[format]) { + // Execute callbacks + each(callbacks, function(callback) { + callback(true, {node: node, format: format, parents: parents}); + }); + + currentFormats[format] = callbacks; + } + + matchedFormats[format] = callbacks; + return false; + } + + if (matchesUnInheritedFormatSelector(node, format)) { + return false; + } + }); + }); + + // Check if current formats still match + each(currentFormats, function(callbacks, format) { + if (!matchedFormats[format]) { + delete currentFormats[format]; + + each(callbacks, function(callback) { + callback(false, {node: e.element, format: format, parents: parents}); + }); + } + }); + }); + } + + // Add format listeners + each(formats.split(','), function(format) { + if (!formatChangeData[format]) { + formatChangeData[format] = []; + formatChangeData[format].similar = similar; + } + + formatChangeData[format].push(callback); + }); + + return this; + } + + /** + * Returns a preview css text for the specified format. + * + * @method getCssText + * @param {String/Object} format Format to generate preview css text for. + * @return {String} Css text for the specified format. + * @example + * var cssText1 = editor.formatter.getCssText('bold'); + * var cssText2 = editor.formatter.getCssText({inline: 'b'}); + */ + function getCssText(format) { + return Preview.getCssText(ed, format); + } + + // Expose to public + extend(this, { + get: get, + register: register, + unregister: unregister, + apply: apply, + remove: remove, + toggle: toggle, + match: match, + matchAll: matchAll, + matchNode: matchNode, + canApply: canApply, + formatChanged: formatChanged, + getCssText: getCssText + }); + + // Initialize + defaultFormats(); + addKeyboardShortcuts(); + ed.on('BeforeGetContent', function(e) { + if (markCaretContainersBogus && e.format != 'raw') { + markCaretContainersBogus(); + } + }); + ed.on('mouseup keydown', function(e) { + if (disableCaretContainer) { + disableCaretContainer(e); + } + }); + + // Private functions + + /** + * Checks if the specified nodes name matches the format inline/block or selector. + * + * @private + * @param {Node} node Node to match against the specified format. + * @param {Object} format Format object o match with. + * @return {boolean} true/false if the format matches. + */ + function matchName(node, format) { + // Check for inline match + if (isEq(node, format.inline)) { + return TRUE; + } + + // Check for block match + if (isEq(node, format.block)) { + return TRUE; + } + + // Check for selector match + if (format.selector) { + return node.nodeType == 1 && dom.is(node, format.selector); + } + } + + /** + * Compares two string/nodes regardless of their case. + * + * @private + * @param {String/Node} str1 Node or string to compare. + * @param {String/Node} str2 Node or string to compare. + * @return {boolean} True/false if they match. + */ + function isEq(str1, str2) { + str1 = str1 || ''; + str2 = str2 || ''; + + str1 = '' + (str1.nodeName || str1); + str2 = '' + (str2.nodeName || str2); + + return str1.toLowerCase() == str2.toLowerCase(); + } + + /** + * Returns the style by name on the specified node. This method modifies the style + * contents to make it more easy to match. This will resolve a few browser issues. + * + * @private + * @param {Node} node to get style from. + * @param {String} name Style name to get. + * @return {String} Style item value. + */ + function getStyle(node, name) { + return normalizeStyleValue(dom.getStyle(node, name), name); + } + + /** + * Normalize style value by name. This method modifies the style contents + * to make it more easy to match. This will resolve a few browser issues. + * + * @private + * @param {String} value Value to get style from. + * @param {String} name Style name to get. + * @return {String} Style item value. + */ + function normalizeStyleValue(value, name) { + // Force the format to hex + if (name == 'color' || name == 'backgroundColor') { + value = dom.toHex(value); + } + + // Opera will return bold as 700 + if (name == 'fontWeight' && value == 700) { + value = 'bold'; + } + + // Normalize fontFamily so "'Font name', Font" becomes: "Font name,Font" + if (name == 'fontFamily') { + value = value.replace(/[\'\"]/g, '').replace(/,\s+/g, ','); + } + + return '' + value; + } + + /** + * Replaces variables in the value. The variable format is %var. + * + * @private + * @param {String} value Value to replace variables in. + * @param {Object} vars Name/value array with variables to replace. + * @return {String} New value with replaced variables. + */ + function replaceVars(value, vars) { + if (typeof value != "string") { + value = value(vars); + } else if (vars) { + value = value.replace(/%(\w+)/g, function(str, name) { + return vars[name] || str; + }); + } + + return value; + } + + function isWhiteSpaceNode(node) { + return node && node.nodeType === 3 && /^([\t \r\n]+|)$/.test(node.nodeValue); + } + + function wrap(node, name, attrs) { + var wrapper = dom.create(name, attrs); + + node.parentNode.insertBefore(wrapper, node); + wrapper.appendChild(node); + + return wrapper; + } + + /** + * Expands the specified range like object to depending on format. + * + * For example on block formats it will move the start/end position + * to the beginning of the current block. + * + * @private + * @param {Object} rng Range like object. + * @param {Array} format Array with formats to expand by. + * @param {Boolean} remove + * @return {Object} Expanded range like object. + */ + function expandRng(rng, format, remove) { + var lastIdx, leaf, endPoint, + startContainer = rng.startContainer, + startOffset = rng.startOffset, + endContainer = rng.endContainer, + endOffset = rng.endOffset; + + // This function walks up the tree if there is no siblings before/after the node + function findParentContainer(start) { + var container, parent, sibling, siblingName, root; + + container = parent = start ? startContainer : endContainer; + siblingName = start ? 'previousSibling' : 'nextSibling'; + root = dom.getRoot(); + + function isBogusBr(node) { + return node.nodeName == "BR" && node.getAttribute('data-mce-bogus') && !node.nextSibling; + } + + // If it's a text node and the offset is inside the text + if (container.nodeType == 3 && !isWhiteSpaceNode(container)) { + if (start ? startOffset > 0 : endOffset < container.nodeValue.length) { + return container; + } + } + + /*eslint no-constant-condition:0 */ + while (true) { + // Stop expanding on block elements + if (!format[0].block_expand && isBlock(parent)) { + return parent; + } + + // Walk left/right + for (sibling = parent[siblingName]; sibling; sibling = sibling[siblingName]) { + if (!isBookmarkNode(sibling) && !isWhiteSpaceNode(sibling) && !isBogusBr(sibling)) { + return parent; + } + } + + // Check if we can move up are we at root level or body level + if (parent == root || parent.parentNode == root) { + container = parent; + break; + } + + parent = parent.parentNode; + } + + return container; + } + + // This function walks down the tree to find the leaf at the selection. + // The offset is also returned as if node initially a leaf, the offset may be in the middle of the text node. + function findLeaf(node, offset) { + if (offset === undef) { + offset = node.nodeType === 3 ? node.length : node.childNodes.length; + } + + while (node && node.hasChildNodes()) { + node = node.childNodes[offset]; + if (node) { + offset = node.nodeType === 3 ? node.length : node.childNodes.length; + } + } + return {node: node, offset: offset}; + } + + // If index based start position then resolve it + if (startContainer.nodeType == 1 && startContainer.hasChildNodes()) { + lastIdx = startContainer.childNodes.length - 1; + startContainer = startContainer.childNodes[startOffset > lastIdx ? lastIdx : startOffset]; + + if (startContainer.nodeType == 3) { + startOffset = 0; + } + } + + // If index based end position then resolve it + if (endContainer.nodeType == 1 && endContainer.hasChildNodes()) { + lastIdx = endContainer.childNodes.length - 1; + endContainer = endContainer.childNodes[endOffset > lastIdx ? lastIdx : endOffset - 1]; + + if (endContainer.nodeType == 3) { + endOffset = endContainer.nodeValue.length; + } + } + + // Expands the node to the closes contentEditable false element if it exists + function findParentContentEditable(node) { + var parent = node; + + while (parent) { + if (parent.nodeType === 1 && getContentEditable(parent)) { + return getContentEditable(parent) === "false" ? parent : node; + } + + parent = parent.parentNode; + } + + return node; + } + + function findWordEndPoint(container, offset, start) { + var walker, node, pos, lastTextNode; + + function findSpace(node, offset) { + var pos, pos2, str = node.nodeValue; + + if (typeof offset == "undefined") { + offset = start ? str.length : 0; + } + + if (start) { + pos = str.lastIndexOf(' ', offset); + pos2 = str.lastIndexOf('\u00a0', offset); + pos = pos > pos2 ? pos : pos2; + + // Include the space on remove to avoid tag soup + if (pos !== -1 && !remove) { + pos++; + } + } else { + pos = str.indexOf(' ', offset); + pos2 = str.indexOf('\u00a0', offset); + pos = pos !== -1 && (pos2 === -1 || pos < pos2) ? pos : pos2; + } + + return pos; + } + + if (container.nodeType === 3) { + pos = findSpace(container, offset); + + if (pos !== -1) { + return {container: container, offset: pos}; + } + + lastTextNode = container; + } + + // Walk the nodes inside the block + walker = new TreeWalker(container, dom.getParent(container, isBlock) || ed.getBody()); + while ((node = walker[start ? 'prev' : 'next']())) { + if (node.nodeType === 3) { + lastTextNode = node; + pos = findSpace(node); + + if (pos !== -1) { + return {container: node, offset: pos}; + } + } else if (isBlock(node)) { + break; + } + } + + if (lastTextNode) { + if (start) { + offset = 0; + } else { + offset = lastTextNode.length; + } + + return {container: lastTextNode, offset: offset}; + } + } + + function findSelectorEndPoint(container, sibling_name) { + var parents, i, y, curFormat; + + if (container.nodeType == 3 && container.nodeValue.length === 0 && container[sibling_name]) { + container = container[sibling_name]; + } + + parents = getParents(container); + for (i = 0; i < parents.length; i++) { + for (y = 0; y < format.length; y++) { + curFormat = format[y]; + + // If collapsed state is set then skip formats that doesn't match that + if ("collapsed" in curFormat && curFormat.collapsed !== rng.collapsed) { + continue; + } + + if (dom.is(parents[i], curFormat.selector)) { + return parents[i]; + } + } + } + + return container; + } + + function findBlockEndPoint(container, sibling_name) { + var node, root = dom.getRoot(); + + // Expand to block of similar type + if (!format[0].wrapper) { + node = dom.getParent(container, format[0].block, root); + } + + // Expand to first wrappable block element or any block element + if (!node) { + node = dom.getParent(container.nodeType == 3 ? container.parentNode : container, function(node) { + // Fixes #6183 where it would expand to editable parent element in inline mode + return node != root && isTextBlock(node); + }); + } + + // Exclude inner lists from wrapping + if (node && format[0].wrapper) { + node = getParents(node, 'ul,ol').reverse()[0] || node; + } + + // Didn't find a block element look for first/last wrappable element + if (!node) { + node = container; + + while (node[sibling_name] && !isBlock(node[sibling_name])) { + node = node[sibling_name]; + + // Break on BR but include it will be removed later on + // we can't remove it now since we need to check if it can be wrapped + if (isEq(node, 'br')) { + break; + } + } + } + + return node || container; + } + + // Expand to closest contentEditable element + startContainer = findParentContentEditable(startContainer); + endContainer = findParentContentEditable(endContainer); + + // Exclude bookmark nodes if possible + if (isBookmarkNode(startContainer.parentNode) || isBookmarkNode(startContainer)) { + startContainer = isBookmarkNode(startContainer) ? startContainer : startContainer.parentNode; + startContainer = startContainer.nextSibling || startContainer; + + if (startContainer.nodeType == 3) { + startOffset = 0; + } + } + + if (isBookmarkNode(endContainer.parentNode) || isBookmarkNode(endContainer)) { + endContainer = isBookmarkNode(endContainer) ? endContainer : endContainer.parentNode; + endContainer = endContainer.previousSibling || endContainer; + + if (endContainer.nodeType == 3) { + endOffset = endContainer.length; + } + } + + if (format[0].inline) { + if (rng.collapsed) { + // Expand left to closest word boundary + endPoint = findWordEndPoint(startContainer, startOffset, true); + if (endPoint) { + startContainer = endPoint.container; + startOffset = endPoint.offset; + } + + // Expand right to closest word boundary + endPoint = findWordEndPoint(endContainer, endOffset); + if (endPoint) { + endContainer = endPoint.container; + endOffset = endPoint.offset; + } + } + + // Avoid applying formatting to a trailing space. + leaf = findLeaf(endContainer, endOffset); + if (leaf.node) { + while (leaf.node && leaf.offset === 0 && leaf.node.previousSibling) { + leaf = findLeaf(leaf.node.previousSibling); + } + + if (leaf.node && leaf.offset > 0 && leaf.node.nodeType === 3 && + leaf.node.nodeValue.charAt(leaf.offset - 1) === ' ') { + + if (leaf.offset > 1) { + endContainer = leaf.node; + endContainer.splitText(leaf.offset - 1); + } + } + } + } + + // Move start/end point up the tree if the leaves are sharp and if we are in different containers + // Example * becomes !: !<p><b><i>*text</i><i>text*</i></b></p>! + // This will reduce the number of wrapper elements that needs to be created + // Move start point up the tree + if (format[0].inline || format[0].block_expand) { + if (!format[0].inline || (startContainer.nodeType != 3 || startOffset === 0)) { + startContainer = findParentContainer(true); + } + + if (!format[0].inline || (endContainer.nodeType != 3 || endOffset === endContainer.nodeValue.length)) { + endContainer = findParentContainer(); + } + } + + // Expand start/end container to matching selector + if (format[0].selector && format[0].expand !== FALSE && !format[0].inline) { + // Find new startContainer/endContainer if there is better one + startContainer = findSelectorEndPoint(startContainer, 'previousSibling'); + endContainer = findSelectorEndPoint(endContainer, 'nextSibling'); + } + + // Expand start/end container to matching block element or text node + if (format[0].block || format[0].selector) { + // Find new startContainer/endContainer if there is better one + startContainer = findBlockEndPoint(startContainer, 'previousSibling'); + endContainer = findBlockEndPoint(endContainer, 'nextSibling'); + + // Non block element then try to expand up the leaf + if (format[0].block) { + if (!isBlock(startContainer)) { + startContainer = findParentContainer(true); + } + + if (!isBlock(endContainer)) { + endContainer = findParentContainer(); + } + } + } + + // Setup index for startContainer + if (startContainer.nodeType == 1) { + startOffset = nodeIndex(startContainer); + startContainer = startContainer.parentNode; + } + + // Setup index for endContainer + if (endContainer.nodeType == 1) { + endOffset = nodeIndex(endContainer) + 1; + endContainer = endContainer.parentNode; + } + + // Return new range like object + return { + startContainer: startContainer, + startOffset: startOffset, + endContainer: endContainer, + endOffset: endOffset + }; + } + + function isColorFormatAndAnchor(node, format) { + return format.links && node.tagName == 'A'; + } + + /** + * Removes the specified format for the specified node. It will also remove the node if it doesn't have + * any attributes if the format specifies it to do so. + * + * @private + * @param {Object} format Format object with items to remove from node. + * @param {Object} vars Name/value object with variables to apply to format. + * @param {Node} node Node to remove the format styles on. + * @param {Node} compare_node Optional compare node, if specified the styles will be compared to that node. + * @return {Boolean} True/false if the node was removed or not. + */ + function removeFormat(format, vars, node, compare_node) { + var i, attrs, stylesModified; + + // Check if node matches format + if (!matchName(node, format) && !isColorFormatAndAnchor(node, format)) { + return FALSE; + } + + // Should we compare with format attribs and styles + if (format.remove != 'all') { + // Remove styles + each(format.styles, function(value, name) { + value = normalizeStyleValue(replaceVars(value, vars), name); + + // Indexed array + if (typeof name === 'number') { + name = value; + compare_node = 0; + } + + if (format.remove_similar || (!compare_node || isEq(getStyle(compare_node, name), value))) { + dom.setStyle(node, name, ''); + } + + stylesModified = 1; + }); + + // Remove style attribute if it's empty + if (stylesModified && dom.getAttrib(node, 'style') === '') { + node.removeAttribute('style'); + node.removeAttribute('data-mce-style'); + } + + // Remove attributes + each(format.attributes, function(value, name) { + var valueOut; + + value = replaceVars(value, vars); + + // Indexed array + if (typeof name === 'number') { + name = value; + compare_node = 0; + } + + if (!compare_node || isEq(dom.getAttrib(compare_node, name), value)) { + // Keep internal classes + if (name == 'class') { + value = dom.getAttrib(node, name); + if (value) { + // Build new class value where everything is removed except the internal prefixed classes + valueOut = ''; + each(value.split(/\s+/), function(cls) { + if (/mce\-\w+/.test(cls)) { + valueOut += (valueOut ? ' ' : '') + cls; + } + }); + + // We got some internal classes left + if (valueOut) { + dom.setAttrib(node, name, valueOut); + return; + } + } + } + + // IE6 has a bug where the attribute doesn't get removed correctly + if (name == "class") { + node.removeAttribute('className'); + } + + // Remove mce prefixed attributes + if (MCE_ATTR_RE.test(name)) { + node.removeAttribute('data-mce-' + name); + } + + node.removeAttribute(name); + } + }); + + // Remove classes + each(format.classes, function(value) { + value = replaceVars(value, vars); + + if (!compare_node || dom.hasClass(compare_node, value)) { + dom.removeClass(node, value); + } + }); + + // Check for non internal attributes + attrs = dom.getAttribs(node); + for (i = 0; i < attrs.length; i++) { + if (attrs[i].nodeName.indexOf('_') !== 0) { + return FALSE; + } + } + } + + // Remove the inline child if it's empty for example <b> or <span> + if (format.remove != 'none') { + removeNode(node, format); + return TRUE; + } + } + + /** + * Removes the node and wrap it's children in paragraphs before doing so or + * appends BR elements to the beginning/end of the block element if forcedRootBlocks is disabled. + * + * If the div in the node below gets removed: + * text<div>text</div>text + * + * Output becomes: + * text<div><br />text<br /></div>text + * + * So when the div is removed the result is: + * text<br />text<br />text + * + * @private + * @param {Node} node Node to remove + apply BR/P elements to. + * @param {Object} format Format rule. + * @return {Node} Input node. + */ + function removeNode(node, format) { + var parentNode = node.parentNode, rootBlockElm; + + function find(node, next, inc) { + node = getNonWhiteSpaceSibling(node, next, inc); + + return !node || (node.nodeName == 'BR' || isBlock(node)); + } + + if (format.block) { + if (!forcedRootBlock) { + // Append BR elements if needed before we remove the block + if (isBlock(node) && !isBlock(parentNode)) { + if (!find(node, FALSE) && !find(node.firstChild, TRUE, 1)) { + node.insertBefore(dom.create('br'), node.firstChild); + } + + if (!find(node, TRUE) && !find(node.lastChild, FALSE, 1)) { + node.appendChild(dom.create('br')); + } + } + } else { + // Wrap the block in a forcedRootBlock if we are at the root of document + if (parentNode == dom.getRoot()) { + if (!format.list_block || !isEq(node, format.list_block)) { + each(grep(node.childNodes), function(node) { + if (isValid(forcedRootBlock, node.nodeName.toLowerCase())) { + if (!rootBlockElm) { + rootBlockElm = wrap(node, forcedRootBlock); + dom.setAttribs(rootBlockElm, ed.settings.forced_root_block_attrs); + } else { + rootBlockElm.appendChild(node); + } + } else { + rootBlockElm = 0; + } + }); + } + } + } + } + + // Never remove nodes that isn't the specified inline element if a selector is specified too + if (format.selector && format.inline && !isEq(format.inline, node)) { + return; + } + + dom.remove(node, 1); + } + + /** + * Returns the next/previous non whitespace node. + * + * @private + * @param {Node} node Node to start at. + * @param {boolean} next (Optional) Include next or previous node defaults to previous. + * @param {boolean} inc (Optional) Include the current node in checking. Defaults to false. + * @return {Node} Next or previous node or undefined if it wasn't found. + */ + function getNonWhiteSpaceSibling(node, next, inc) { + if (node) { + next = next ? 'nextSibling' : 'previousSibling'; + + for (node = inc ? node : node[next]; node; node = node[next]) { + if (node.nodeType == 1 || !isWhiteSpaceNode(node)) { + return node; + } + } + } + } + + /** + * Merges the next/previous sibling element if they match. + * + * @private + * @param {Node} prev Previous node to compare/merge. + * @param {Node} next Next node to compare/merge. + * @return {Node} Next node if we didn't merge and prev node if we did. + */ + function mergeSiblings(prev, next) { + var sibling, tmpSibling, elementUtils = new ElementUtils(dom); + + function findElementSibling(node, sibling_name) { + for (sibling = node; sibling; sibling = sibling[sibling_name]) { + if (sibling.nodeType == 3 && sibling.nodeValue.length !== 0) { + return node; + } + + if (sibling.nodeType == 1 && !isBookmarkNode(sibling)) { + return sibling; + } + } + + return node; + } + + // Check if next/prev exists and that they are elements + if (prev && next) { + // If previous sibling is empty then jump over it + prev = findElementSibling(prev, 'previousSibling'); + next = findElementSibling(next, 'nextSibling'); + + // Compare next and previous nodes + if (elementUtils.compare(prev, next)) { + // Append nodes between + for (sibling = prev.nextSibling; sibling && sibling != next;) { + tmpSibling = sibling; + sibling = sibling.nextSibling; + prev.appendChild(tmpSibling); + } + + // Remove next node + dom.remove(next); + + // Move children into prev node + each(grep(next.childNodes), function(node) { + prev.appendChild(node); + }); + + return prev; + } + } + + return next; + } + + function getContainer(rng, start) { + var container, offset, lastIdx; + + container = rng[start ? 'startContainer' : 'endContainer']; + offset = rng[start ? 'startOffset' : 'endOffset']; + + if (container.nodeType == 1) { + lastIdx = container.childNodes.length - 1; + + if (!start && offset) { + offset--; + } + + container = container.childNodes[offset > lastIdx ? lastIdx : offset]; + } + + // If start text node is excluded then walk to the next node + if (container.nodeType === 3 && start && offset >= container.nodeValue.length) { + container = new TreeWalker(container, ed.getBody()).next() || container; + } + + // If end text node is excluded then walk to the previous node + if (container.nodeType === 3 && !start && offset === 0) { + container = new TreeWalker(container, ed.getBody()).prev() || container; + } + + return container; + } + + function performCaretAction(type, name, vars, similar) { + var caretContainerId = '_mce_caret', debug = ed.settings.caret_debug; + + // Creates a caret container bogus element + function createCaretContainer(fill) { + var caretContainer = dom.create('span', {id: caretContainerId, 'data-mce-bogus': true, style: debug ? 'color:red' : ''}); + + if (fill) { + caretContainer.appendChild(ed.getDoc().createTextNode(INVISIBLE_CHAR)); + } + + return caretContainer; + } + + function isCaretContainerEmpty(node, nodes) { + while (node) { + if ((node.nodeType === 3 && node.nodeValue !== INVISIBLE_CHAR) || node.childNodes.length > 1) { + return false; + } + + // Collect nodes + if (nodes && node.nodeType === 1) { + nodes.push(node); + } + + node = node.firstChild; + } + + return true; + } + + // Returns any parent caret container element + function getParentCaretContainer(node) { + while (node) { + if (node.id === caretContainerId) { + return node; + } + + node = node.parentNode; + } + } + + // Finds the first text node in the specified node + function findFirstTextNode(node) { + var walker; + + if (node) { + walker = new TreeWalker(node, node); + + for (node = walker.current(); node; node = walker.next()) { + if (node.nodeType === 3) { + return node; + } + } + } + } + + // Removes the caret container for the specified node or all on the current document + function removeCaretContainer(node, move_caret) { + var child, rng; + + if (!node) { + node = getParentCaretContainer(selection.getStart()); + + if (!node) { + while ((node = dom.get(caretContainerId))) { + removeCaretContainer(node, false); + } + } + } else { + rng = selection.getRng(true); + + if (isCaretContainerEmpty(node)) { + if (move_caret !== false) { + rng.setStartBefore(node); + rng.setEndBefore(node); + } + + dom.remove(node); + } else { + child = findFirstTextNode(node); + + if (child.nodeValue.charAt(0) === INVISIBLE_CHAR) { + child.deleteData(0, 1); + + // Fix for bug #6976 + if (rng.startContainer == child && rng.startOffset > 0) { + rng.setStart(child, rng.startOffset - 1); + } + + if (rng.endContainer == child && rng.endOffset > 0) { + rng.setEnd(child, rng.endOffset - 1); + } + } + + dom.remove(node, 1); + } + + selection.setRng(rng); + } + } + + // Applies formatting to the caret position + function applyCaretFormat() { + var rng, caretContainer, textNode, offset, bookmark, container, text; + + rng = selection.getRng(true); + offset = rng.startOffset; + container = rng.startContainer; + text = container.nodeValue; + + caretContainer = getParentCaretContainer(selection.getStart()); + if (caretContainer) { + textNode = findFirstTextNode(caretContainer); + } + + // Expand to word is caret is in the middle of a text node and the char before/after is a alpha numeric character + if (text && offset > 0 && offset < text.length && /\w/.test(text.charAt(offset)) && /\w/.test(text.charAt(offset - 1))) { + // Get bookmark of caret position + bookmark = selection.getBookmark(); + + // Collapse bookmark range (WebKit) + rng.collapse(true); + + // Expand the range to the closest word and split it at those points + rng = expandRng(rng, get(name)); + rng = rangeUtils.split(rng); + + // Apply the format to the range + apply(name, vars, rng); + + // Move selection back to caret position + selection.moveToBookmark(bookmark); + } else { + if (!caretContainer || textNode.nodeValue !== INVISIBLE_CHAR) { + caretContainer = createCaretContainer(true); + textNode = caretContainer.firstChild; + + rng.insertNode(caretContainer); + offset = 1; + + apply(name, vars, caretContainer); + } else { + apply(name, vars, caretContainer); + } + + // Move selection to text node + selection.setCursorLocation(textNode, offset); + } + } + + function removeCaretFormat() { + var rng = selection.getRng(true), container, offset, bookmark, + hasContentAfter, node, formatNode, parents = [], i, caretContainer; + + container = rng.startContainer; + offset = rng.startOffset; + node = container; + + if (container.nodeType == 3) { + if (offset != container.nodeValue.length) { + hasContentAfter = true; + } + + node = node.parentNode; + } + + while (node) { + if (matchNode(node, name, vars, similar)) { + formatNode = node; + break; + } + + if (node.nextSibling) { + hasContentAfter = true; + } + + parents.push(node); + node = node.parentNode; + } + + // Node doesn't have the specified format + if (!formatNode) { + return; + } + + // Is there contents after the caret then remove the format on the element + if (hasContentAfter) { + // Get bookmark of caret position + bookmark = selection.getBookmark(); + + // Collapse bookmark range (WebKit) + rng.collapse(true); + + // Expand the range to the closest word and split it at those points + rng = expandRng(rng, get(name), true); + rng = rangeUtils.split(rng); + + // Remove the format from the range + remove(name, vars, rng); + + // Move selection back to caret position + selection.moveToBookmark(bookmark); + } else { + caretContainer = createCaretContainer(); + + node = caretContainer; + for (i = parents.length - 1; i >= 0; i--) { + node.appendChild(dom.clone(parents[i], false)); + node = node.firstChild; + } + + // Insert invisible character into inner most format element + node.appendChild(dom.doc.createTextNode(INVISIBLE_CHAR)); + node = node.firstChild; + + var block = dom.getParent(formatNode, isTextBlock); + + if (block && dom.isEmpty(block)) { + // Replace formatNode with caretContainer when removing format from empty block like <p><b>|</b></p> + formatNode.parentNode.replaceChild(caretContainer, formatNode); + } else { + // Insert caret container after the formatted node + dom.insertAfter(caretContainer, formatNode); + } + + // Move selection to text node + selection.setCursorLocation(node, 1); + + // If the formatNode is empty, we can remove it safely. + if (dom.isEmpty(formatNode)) { + dom.remove(formatNode); + } + } + } + + // Checks if the parent caret container node isn't empty if that is the case it + // will remove the bogus state on all children that isn't empty + function unmarkBogusCaretParents() { + var caretContainer; + + caretContainer = getParentCaretContainer(selection.getStart()); + if (caretContainer && !dom.isEmpty(caretContainer)) { + walk(caretContainer, function(node) { + if (node.nodeType == 1 && node.id !== caretContainerId && !dom.isEmpty(node)) { + dom.setAttrib(node, 'data-mce-bogus', null); + } + }, 'childNodes'); + } + } + + // Only bind the caret events once + if (!ed._hasCaretEvents) { + // Mark current caret container elements as bogus when getting the contents so we don't end up with empty elements + markCaretContainersBogus = function() { + var nodes = [], i; + + if (isCaretContainerEmpty(getParentCaretContainer(selection.getStart()), nodes)) { + // Mark children + i = nodes.length; + while (i--) { + dom.setAttrib(nodes[i], 'data-mce-bogus', '1'); + } + } + }; + + disableCaretContainer = function(e) { + var keyCode = e.keyCode; + + removeCaretContainer(); + + // Remove caret container if it's empty + if (keyCode == 8 && selection.isCollapsed() && selection.getStart().innerHTML == INVISIBLE_CHAR) { + removeCaretContainer(getParentCaretContainer(selection.getStart())); + } + + // Remove caret container on keydown and it's left/right arrow keys + if (keyCode == 37 || keyCode == 39) { + removeCaretContainer(getParentCaretContainer(selection.getStart())); + } + + unmarkBogusCaretParents(); + }; + + // Remove bogus state if they got filled by contents using editor.selection.setContent + ed.on('SetContent', function(e) { + if (e.selection) { + unmarkBogusCaretParents(); + } + }); + ed._hasCaretEvents = true; + } + + // Do apply or remove caret format + if (type == "apply") { + applyCaretFormat(); + } else { + removeCaretFormat(); + } + } + + /** + * Moves the start to the first suitable text node. + */ + function moveStart(rng) { + var container = rng.startContainer, + offset = rng.startOffset, isAtEndOfText, + walker, node, nodes, tmpNode; + + if (rng.startContainer == rng.endContainer) { + if (isInlineBlock(rng.startContainer.childNodes[rng.startOffset])) { + return; + } + } + + // Convert text node into index if possible + if (container.nodeType == 3 && offset >= container.nodeValue.length) { + // Get the parent container location and walk from there + offset = nodeIndex(container); + container = container.parentNode; + isAtEndOfText = true; + } + + // Move startContainer/startOffset in to a suitable node + if (container.nodeType == 1) { + nodes = container.childNodes; + container = nodes[Math.min(offset, nodes.length - 1)]; + walker = new TreeWalker(container, dom.getParent(container, dom.isBlock)); + + // If offset is at end of the parent node walk to the next one + if (offset > nodes.length - 1 || isAtEndOfText) { + walker.next(); + } + + for (node = walker.current(); node; node = walker.next()) { + if (node.nodeType == 3 && !isWhiteSpaceNode(node)) { + // IE has a "neat" feature where it moves the start node into the closest element + // we can avoid this by inserting an element before it and then remove it after we set the selection + tmpNode = dom.create('a', {'data-mce-bogus': 'all'}, INVISIBLE_CHAR); + node.parentNode.insertBefore(tmpNode, node); + + // Set selection and remove tmpNode + rng.setStart(node, 0); + selection.setRng(rng); + dom.remove(tmpNode); + + return; + } + } + } + } + }; +}); + +// Included from: js/tinymce/classes/UndoManager.js + +/** + * UndoManager.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class handles the undo/redo history levels for the editor. Since the built-in undo/redo has major drawbacks a custom one was needed. + * + * @class tinymce.UndoManager + */ +define("tinymce/UndoManager", [ + "tinymce/util/VK", + "tinymce/Env" +], function(VK, Env) { + return function(editor) { + var self = this, index = 0, data = [], beforeBookmark, isFirstTypedCharacter, locks = 0; + + function getContent() { + return editor.serializer.getTrimmedContent(); + } + + function setDirty(state) { + editor.setDirty(state); + } + + function addNonTypingUndoLevel(e) { + self.typing = false; + self.add({}, e); + } + + // Add initial undo level when the editor is initialized + editor.on('init', function() { + self.add(); + }); + + // Get position before an execCommand is processed + editor.on('BeforeExecCommand', function(e) { + var cmd = e.command; + + if (cmd != 'Undo' && cmd != 'Redo' && cmd != 'mceRepaint') { + self.beforeChange(); + } + }); + + // Add undo level after an execCommand call was made + editor.on('ExecCommand', function(e) { + var cmd = e.command; + + if (cmd != 'Undo' && cmd != 'Redo' && cmd != 'mceRepaint') { + addNonTypingUndoLevel(e); + } + }); + + editor.on('ObjectResizeStart Cut', function() { + self.beforeChange(); + }); + + editor.on('SaveContent ObjectResized blur', addNonTypingUndoLevel); + editor.on('DragEnd', addNonTypingUndoLevel); + + editor.on('KeyUp', function(e) { + var keyCode = e.keyCode; + + // If key is prevented then don't add undo level + // This would happen on keyboard shortcuts for example + if (e.isDefaultPrevented()) { + return; + } + + if ((keyCode >= 33 && keyCode <= 36) || (keyCode >= 37 && keyCode <= 40) || keyCode == 45 || keyCode == 13 || e.ctrlKey) { + addNonTypingUndoLevel(); + editor.nodeChanged(); + } + + if (keyCode == 46 || keyCode == 8 || (Env.mac && (keyCode == 91 || keyCode == 93))) { + editor.nodeChanged(); + } + + // Fire a TypingUndo event on the first character entered + if (isFirstTypedCharacter && self.typing) { + // Make it dirty if the content was changed after typing the first character + if (!editor.isDirty()) { + setDirty(data[0] && getContent() != data[0].content); + + // Fire initial change event + if (editor.isDirty()) { + editor.fire('change', {level: data[0], lastLevel: null}); + } + } + + editor.fire('TypingUndo'); + isFirstTypedCharacter = false; + editor.nodeChanged(); + } + }); + + editor.on('KeyDown', function(e) { + var keyCode = e.keyCode; + + // If key is prevented then don't add undo level + // This would happen on keyboard shortcuts for example + if (e.isDefaultPrevented()) { + return; + } + + // Is character position keys left,right,up,down,home,end,pgdown,pgup,enter + if ((keyCode >= 33 && keyCode <= 36) || (keyCode >= 37 && keyCode <= 40) || keyCode == 45) { + if (self.typing) { + addNonTypingUndoLevel(e); + } + + return; + } + + // If key isn't Ctrl+Alt/AltGr + var modKey = (e.ctrlKey && !e.altKey) || e.metaKey; + if ((keyCode < 16 || keyCode > 20) && keyCode != 224 && keyCode != 91 && !self.typing && !modKey) { + self.beforeChange(); + self.typing = true; + self.add({}, e); + isFirstTypedCharacter = true; + } + }); + + editor.on('MouseDown', function(e) { + if (self.typing) { + addNonTypingUndoLevel(e); + } + }); + + // Add keyboard shortcuts for undo/redo keys + editor.addShortcut('meta+z', '', 'Undo'); + editor.addShortcut('meta+y,meta+shift+z', '', 'Redo'); + + editor.on('AddUndo Undo Redo ClearUndos', function(e) { + if (!e.isDefaultPrevented()) { + editor.nodeChanged(); + } + }); + + /*eslint consistent-this:0 */ + self = { + // Explode for debugging reasons + data: data, + + /** + * State if the user is currently typing or not. This will add a typing operation into one undo + * level instead of one new level for each keystroke. + * + * @field {Boolean} typing + */ + typing: false, + + /** + * Stores away a bookmark to be used when performing an undo action so that the selection is before + * the change has been made. + * + * @method beforeChange + */ + beforeChange: function() { + if (!locks) { + beforeBookmark = editor.selection.getBookmark(2, true); + } + }, + + /** + * Adds a new undo level/snapshot to the undo list. + * + * @method add + * @param {Object} level Optional undo level object to add. + * @param {DOMEvent} event Optional event responsible for the creation of the undo level. + * @return {Object} Undo level that got added or null it a level wasn't needed. + */ + add: function(level, event) { + var i, settings = editor.settings, lastLevel; + + level = level || {}; + level.content = getContent(); + + if (locks || editor.removed) { + return null; + } + + lastLevel = data[index]; + if (editor.fire('BeforeAddUndo', {level: level, lastLevel: lastLevel, originalEvent: event}).isDefaultPrevented()) { + return null; + } + + // Add undo level if needed + if (lastLevel && lastLevel.content == level.content) { + return null; + } + + // Set before bookmark on previous level + if (data[index]) { + data[index].beforeBookmark = beforeBookmark; + } + + // Time to compress + if (settings.custom_undo_redo_levels) { + if (data.length > settings.custom_undo_redo_levels) { + for (i = 0; i < data.length - 1; i++) { + data[i] = data[i + 1]; + } + + data.length--; + index = data.length; + } + } + + // Get a non intrusive normalized bookmark + level.bookmark = editor.selection.getBookmark(2, true); + + // Crop array if needed + if (index < data.length - 1) { + data.length = index + 1; + } + + data.push(level); + index = data.length - 1; + + var args = {level: level, lastLevel: lastLevel, originalEvent: event}; + + editor.fire('AddUndo', args); + + if (index > 0) { + setDirty(true); + editor.fire('change', args); + } + + return level; + }, + + /** + * Undoes the last action. + * + * @method undo + * @return {Object} Undo level or null if no undo was performed. + */ + undo: function() { + var level; + + if (self.typing) { + self.add(); + self.typing = false; + } + + if (index > 0) { + level = data[--index]; + + editor.setContent(level.content, {format: 'raw'}); + editor.selection.moveToBookmark(level.beforeBookmark); + setDirty(true); + + editor.fire('undo', {level: level}); + } + + return level; + }, + + /** + * Redoes the last action. + * + * @method redo + * @return {Object} Redo level or null if no redo was performed. + */ + redo: function() { + var level; + + if (index < data.length - 1) { + level = data[++index]; + + editor.setContent(level.content, {format: 'raw'}); + editor.selection.moveToBookmark(level.bookmark); + setDirty(true); + + editor.fire('redo', {level: level}); + } + + return level; + }, + + /** + * Removes all undo levels. + * + * @method clear + */ + clear: function() { + data = []; + index = 0; + self.typing = false; + editor.fire('ClearUndos'); + }, + + /** + * Returns true/false if the undo manager has any undo levels. + * + * @method hasUndo + * @return {Boolean} true/false if the undo manager has any undo levels. + */ + hasUndo: function() { + // Has undo levels or typing and content isn't the same as the initial level + return index > 0 || (self.typing && data[0] && getContent() != data[0].content); + }, + + /** + * Returns true/false if the undo manager has any redo levels. + * + * @method hasRedo + * @return {Boolean} true/false if the undo manager has any redo levels. + */ + hasRedo: function() { + return index < data.length - 1 && !this.typing; + }, + + /** + * Executes the specified function in an undo translation. The selection + * before the modification will be stored to the undo stack and if the DOM changes + * it will add a new undo level. Any methods within the translation that adds undo levels will + * be ignored. So a translation can include calls to execCommand or editor.insertContent. + * + * @method transact + * @param {function} callback Function to execute dom manipulation logic in. + */ + transact: function(callback) { + self.beforeChange(); + + try { + locks++; + callback(); + } finally { + locks--; + } + + self.add(); + } + }; + + return self; + }; +}); + +// Included from: js/tinymce/classes/EnterKey.js + +/** + * EnterKey.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Contains logic for handling the enter key to split/generate block elements. + * + * @private + * @class tinymce.EnterKey + */ +define("tinymce/EnterKey", [ + "tinymce/dom/TreeWalker", + "tinymce/dom/RangeUtils", + "tinymce/Env" +], function(TreeWalker, RangeUtils, Env) { + var isIE = Env.ie && Env.ie < 11; + + return function(editor) { + var dom = editor.dom, selection = editor.selection, settings = editor.settings; + var undoManager = editor.undoManager, schema = editor.schema, nonEmptyElementsMap = schema.getNonEmptyElements(), + moveCaretBeforeOnEnterElementsMap = schema.getMoveCaretBeforeOnEnterElements(); + + function handleEnterKey(evt) { + var rng, tmpRng, editableRoot, container, offset, parentBlock, documentMode, shiftKey, + newBlock, fragment, containerBlock, parentBlockName, containerBlockName, newBlockName, isAfterLastNodeInContainer; + + // Returns true if the block can be split into two blocks or not + function canSplitBlock(node) { + return node && + dom.isBlock(node) && + !/^(TD|TH|CAPTION|FORM)$/.test(node.nodeName) && + !/^(fixed|absolute)/i.test(node.style.position) && + dom.getContentEditable(node) !== "true"; + } + + function isTableCell(node) { + return node && /^(TD|TH|CAPTION)$/.test(node.nodeName); + } + + // Renders empty block on IE + function renderBlockOnIE(block) { + var oldRng; + + if (dom.isBlock(block)) { + oldRng = selection.getRng(); + block.appendChild(dom.create('span', null, '\u00a0')); + selection.select(block); + block.lastChild.outerHTML = ''; + selection.setRng(oldRng); + } + } + + // Remove the first empty inline element of the block so this: <p><b><em></em></b>x</p> becomes this: <p>x</p> + function trimInlineElementsOnLeftSideOfBlock(block) { + var node = block, firstChilds = [], i; + + if (!node) { + return; + } + + // Find inner most first child ex: <p><i><b>*</b></i></p> + while ((node = node.firstChild)) { + if (dom.isBlock(node)) { + return; + } + + if (node.nodeType == 1 && !nonEmptyElementsMap[node.nodeName.toLowerCase()]) { + firstChilds.push(node); + } + } + + i = firstChilds.length; + while (i--) { + node = firstChilds[i]; + if (!node.hasChildNodes() || (node.firstChild == node.lastChild && node.firstChild.nodeValue === '')) { + dom.remove(node); + } else { + // Remove <a> </a> see #5381 + if (node.nodeName == "A" && (node.innerText || node.textContent) === ' ') { + dom.remove(node); + } + } + } + } + + // Moves the caret to a suitable position within the root for example in the first non + // pure whitespace text node or before an image + function moveToCaretPosition(root) { + var walker, node, rng, lastNode = root, tempElm; + function firstNonWhiteSpaceNodeSibling(node) { + while (node) { + if (node.nodeType == 1 || (node.nodeType == 3 && node.data && /[\r\n\s]/.test(node.data))) { + return node; + } + + node = node.nextSibling; + } + } + + if (!root) { + return; + } + + // Old IE versions doesn't properly render blocks with br elements in them + // For example <p><br></p> wont be rendered correctly in a contentEditable area + // until you remove the br producing <p></p> + if (Env.ie && Env.ie < 9 && parentBlock && parentBlock.firstChild) { + if (parentBlock.firstChild == parentBlock.lastChild && parentBlock.firstChild.tagName == 'BR') { + dom.remove(parentBlock.firstChild); + } + } + + if (/^(LI|DT|DD)$/.test(root.nodeName)) { + var firstChild = firstNonWhiteSpaceNodeSibling(root.firstChild); + + if (firstChild && /^(UL|OL|DL)$/.test(firstChild.nodeName)) { + root.insertBefore(dom.doc.createTextNode('\u00a0'), root.firstChild); + } + } + + rng = dom.createRng(); + + // Normalize whitespace to remove empty text nodes. Fix for: #6904 + // Gecko will be able to place the caret in empty text nodes but it won't render propery + // Older IE versions will sometimes crash so for now ignore all IE versions + if (!Env.ie) { + root.normalize(); + } + + if (root.hasChildNodes()) { + walker = new TreeWalker(root, root); + + while ((node = walker.current())) { + if (node.nodeType == 3) { + rng.setStart(node, 0); + rng.setEnd(node, 0); + break; + } + + if (moveCaretBeforeOnEnterElementsMap[node.nodeName.toLowerCase()]) { + rng.setStartBefore(node); + rng.setEndBefore(node); + break; + } + + lastNode = node; + node = walker.next(); + } + + if (!node) { + rng.setStart(lastNode, 0); + rng.setEnd(lastNode, 0); + } + } else { + if (root.nodeName == 'BR') { + if (root.nextSibling && dom.isBlock(root.nextSibling)) { + // Trick on older IE versions to render the caret before the BR between two lists + if (!documentMode || documentMode < 9) { + tempElm = dom.create('br'); + root.parentNode.insertBefore(tempElm, root); + } + + rng.setStartBefore(root); + rng.setEndBefore(root); + } else { + rng.setStartAfter(root); + rng.setEndAfter(root); + } + } else { + rng.setStart(root, 0); + rng.setEnd(root, 0); + } + } + + selection.setRng(rng); + + // Remove tempElm created for old IE:s + dom.remove(tempElm); + selection.scrollIntoView(root); + } + + function setForcedBlockAttrs(node) { + var forcedRootBlockName = settings.forced_root_block; + + if (forcedRootBlockName && forcedRootBlockName.toLowerCase() === node.tagName.toLowerCase()) { + dom.setAttribs(node, settings.forced_root_block_attrs); + } + } + + function emptyBlock(elm) { + // BR is needed in empty blocks on non IE browsers + elm.innerHTML = !isIE ? '<br data-mce-bogus="1">' : ''; + } + + // Creates a new block element by cloning the current one or creating a new one if the name is specified + // This function will also copy any text formatting from the parent block and add it to the new one + function createNewBlock(name) { + var node = container, block, clonedNode, caretNode, textInlineElements = schema.getTextInlineElements(); + + if (name || parentBlockName == "TABLE") { + block = dom.create(name || newBlockName); + setForcedBlockAttrs(block); + } else { + block = parentBlock.cloneNode(false); + } + + caretNode = block; + + // Clone any parent styles + if (settings.keep_styles !== false) { + do { + if (textInlineElements[node.nodeName]) { + // Never clone a caret containers + if (node.id == '_mce_caret') { + continue; + } + + clonedNode = node.cloneNode(false); + dom.setAttrib(clonedNode, 'id', ''); // Remove ID since it needs to be document unique + + if (block.hasChildNodes()) { + clonedNode.appendChild(block.firstChild); + block.appendChild(clonedNode); + } else { + caretNode = clonedNode; + block.appendChild(clonedNode); + } + } + } while ((node = node.parentNode) && node != editableRoot); + } + + // BR is needed in empty blocks on non IE browsers + if (!isIE) { + caretNode.innerHTML = '<br data-mce-bogus="1">'; + } + + return block; + } + + // Returns true/false if the caret is at the start/end of the parent block element + function isCaretAtStartOrEndOfBlock(start) { + var walker, node, name; + + // Caret is in the middle of a text node like "a|b" + if (container.nodeType == 3 && (start ? offset > 0 : offset < container.nodeValue.length)) { + return false; + } + + // If after the last element in block node edge case for #5091 + if (container.parentNode == parentBlock && isAfterLastNodeInContainer && !start) { + return true; + } + + // If the caret if before the first element in parentBlock + if (start && container.nodeType == 1 && container == parentBlock.firstChild) { + return true; + } + + // Caret can be before/after a table + if (container.nodeName === "TABLE" || (container.previousSibling && container.previousSibling.nodeName == "TABLE")) { + return (isAfterLastNodeInContainer && !start) || (!isAfterLastNodeInContainer && start); + } + + // Walk the DOM and look for text nodes or non empty elements + walker = new TreeWalker(container, parentBlock); + + // If caret is in beginning or end of a text block then jump to the next/previous node + if (container.nodeType == 3) { + if (start && offset === 0) { + walker.prev(); + } else if (!start && offset == container.nodeValue.length) { + walker.next(); + } + } + + while ((node = walker.current())) { + if (node.nodeType === 1) { + // Ignore bogus elements + if (!node.getAttribute('data-mce-bogus')) { + // Keep empty elements like <img /> <input /> but not trailing br:s like <p>text|<br></p> + name = node.nodeName.toLowerCase(); + if (nonEmptyElementsMap[name] && name !== 'br') { + return false; + } + } + } else if (node.nodeType === 3 && !/^[ \t\r\n]*$/.test(node.nodeValue)) { + return false; + } + + if (start) { + walker.prev(); + } else { + walker.next(); + } + } + + return true; + } + + // Wraps any text nodes or inline elements in the specified forced root block name + function wrapSelfAndSiblingsInDefaultBlock(container, offset) { + var newBlock, parentBlock, startNode, node, next, rootBlockName, blockName = newBlockName || 'P'; + + // Not in a block element or in a table cell or caption + parentBlock = dom.getParent(container, dom.isBlock); + if (!parentBlock || !canSplitBlock(parentBlock)) { + parentBlock = parentBlock || editableRoot; + + if (parentBlock == editor.getBody() || isTableCell(parentBlock)) { + rootBlockName = parentBlock.nodeName.toLowerCase(); + } else { + rootBlockName = parentBlock.parentNode.nodeName.toLowerCase(); + } + + if (!parentBlock.hasChildNodes()) { + newBlock = dom.create(blockName); + setForcedBlockAttrs(newBlock); + parentBlock.appendChild(newBlock); + rng.setStart(newBlock, 0); + rng.setEnd(newBlock, 0); + return newBlock; + } + + // Find parent that is the first child of parentBlock + node = container; + while (node.parentNode != parentBlock) { + node = node.parentNode; + } + + // Loop left to find start node start wrapping at + while (node && !dom.isBlock(node)) { + startNode = node; + node = node.previousSibling; + } + + if (startNode && schema.isValidChild(rootBlockName, blockName.toLowerCase())) { + newBlock = dom.create(blockName); + setForcedBlockAttrs(newBlock); + startNode.parentNode.insertBefore(newBlock, startNode); + + // Start wrapping until we hit a block + node = startNode; + while (node && !dom.isBlock(node)) { + next = node.nextSibling; + newBlock.appendChild(node); + node = next; + } + + // Restore range to it's past location + rng.setStart(container, offset); + rng.setEnd(container, offset); + } + } + + return container; + } + + // Inserts a block or br before/after or in the middle of a split list of the LI is empty + function handleEmptyListItem() { + function isFirstOrLastLi(first) { + var node = containerBlock[first ? 'firstChild' : 'lastChild']; + + // Find first/last element since there might be whitespace there + while (node) { + if (node.nodeType == 1) { + break; + } + + node = node[first ? 'nextSibling' : 'previousSibling']; + } + + return node === parentBlock; + } + + function getContainerBlock() { + var containerBlockParent = containerBlock.parentNode; + + if (/^(LI|DT|DD)$/.test(containerBlockParent.nodeName)) { + return containerBlockParent; + } + + return containerBlock; + } + + if (containerBlock == editor.getBody()) { + return; + } + + // Check if we are in an nested list + var containerBlockParentName = containerBlock.parentNode.nodeName; + if (/^(OL|UL|LI)$/.test(containerBlockParentName)) { + newBlockName = 'LI'; + } + + newBlock = newBlockName ? createNewBlock(newBlockName) : dom.create('BR'); + + if (isFirstOrLastLi(true) && isFirstOrLastLi()) { + if (containerBlockParentName == 'LI') { + // Nested list is inside a LI + dom.insertAfter(newBlock, getContainerBlock()); + } else { + // Is first and last list item then replace the OL/UL with a text block + dom.replace(newBlock, containerBlock); + } + } else if (isFirstOrLastLi(true)) { + if (containerBlockParentName == 'LI') { + // List nested in an LI then move the list to a new sibling LI + dom.insertAfter(newBlock, getContainerBlock()); + newBlock.appendChild(dom.doc.createTextNode(' ')); // Needed for IE so the caret can be placed + newBlock.appendChild(containerBlock); + } else { + // First LI in list then remove LI and add text block before list + containerBlock.parentNode.insertBefore(newBlock, containerBlock); + } + } else if (isFirstOrLastLi()) { + // Last LI in list then remove LI and add text block after list + dom.insertAfter(newBlock, getContainerBlock()); + renderBlockOnIE(newBlock); + } else { + // Middle LI in list the split the list and insert a text block in the middle + // Extract after fragment and insert it after the current block + containerBlock = getContainerBlock(); + tmpRng = rng.cloneRange(); + tmpRng.setStartAfter(parentBlock); + tmpRng.setEndAfter(containerBlock); + fragment = tmpRng.extractContents(); + + if (newBlockName == 'LI' && fragment.firstChild.nodeName == 'LI') { + newBlock = fragment.firstChild; + dom.insertAfter(fragment, containerBlock); + } else { + dom.insertAfter(fragment, containerBlock); + dom.insertAfter(newBlock, containerBlock); + } + } + + dom.remove(parentBlock); + moveToCaretPosition(newBlock); + undoManager.add(); + } + + // Inserts a BR element if the forced_root_block option is set to false or empty string + function insertBr() { + editor.execCommand("InsertLineBreak", false, evt); + } + + // Trims any linebreaks at the beginning of node user for example when pressing enter in a PRE element + function trimLeadingLineBreaks(node) { + do { + if (node.nodeType === 3) { + node.nodeValue = node.nodeValue.replace(/^[\r\n]+/, ''); + } + + node = node.firstChild; + } while (node); + } + + function getEditableRoot(node) { + var root = dom.getRoot(), parent, editableRoot; + + // Get all parents until we hit a non editable parent or the root + parent = node; + while (parent !== root && dom.getContentEditable(parent) !== "false") { + if (dom.getContentEditable(parent) === "true") { + editableRoot = parent; + } + + parent = parent.parentNode; + } + + return parent !== root ? editableRoot : root; + } + + // Adds a BR at the end of blocks that only contains an IMG or INPUT since + // these might be floated and then they won't expand the block + function addBrToBlockIfNeeded(block) { + var lastChild; + + // IE will render the blocks correctly other browsers needs a BR + if (!isIE) { + block.normalize(); // Remove empty text nodes that got left behind by the extract + + // Check if the block is empty or contains a floated last child + lastChild = block.lastChild; + if (!lastChild || (/^(left|right)$/gi.test(dom.getStyle(lastChild, 'float', true)))) { + dom.add(block, 'br'); + } + } + } + + function insertNewBlockAfter() { + // If the caret is at the end of a header we produce a P tag after it similar to Word unless we are in a hgroup + if (/^(H[1-6]|PRE|FIGURE)$/.test(parentBlockName) && containerBlockName != 'HGROUP') { + newBlock = createNewBlock(newBlockName); + } else { + newBlock = createNewBlock(); + } + + // Split the current container block element if enter is pressed inside an empty inner block element + if (settings.end_container_on_empty_block && canSplitBlock(containerBlock) && dom.isEmpty(parentBlock)) { + // Split container block for example a BLOCKQUOTE at the current blockParent location for example a P + newBlock = dom.split(containerBlock, parentBlock); + } else { + dom.insertAfter(newBlock, parentBlock); + } + + moveToCaretPosition(newBlock); + } + + rng = selection.getRng(true); + + // Event is blocked by some other handler for example the lists plugin + if (evt.isDefaultPrevented()) { + return; + } + + // Delete any selected contents + if (!rng.collapsed) { + editor.execCommand('Delete'); + return; + } + + // Setup range items and newBlockName + new RangeUtils(dom).normalize(rng); + container = rng.startContainer; + offset = rng.startOffset; + newBlockName = (settings.force_p_newlines ? 'p' : '') || settings.forced_root_block; + newBlockName = newBlockName ? newBlockName.toUpperCase() : ''; + documentMode = dom.doc.documentMode; + shiftKey = evt.shiftKey; + + // Resolve node index + if (container.nodeType == 1 && container.hasChildNodes()) { + isAfterLastNodeInContainer = offset > container.childNodes.length - 1; + + container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container; + if (isAfterLastNodeInContainer && container.nodeType == 3) { + offset = container.nodeValue.length; + } else { + offset = 0; + } + } + + // Get editable root node, normally the body element but sometimes a div or span + editableRoot = getEditableRoot(container); + + // If there is no editable root then enter is done inside a contentEditable false element + if (!editableRoot) { + return; + } + + undoManager.beforeChange(); + + // If editable root isn't block nor the root of the editor + if (!dom.isBlock(editableRoot) && editableRoot != dom.getRoot()) { + if (!newBlockName || shiftKey) { + insertBr(); + } + + return; + } + + // Wrap the current node and it's sibling in a default block if it's needed. + // for example this <td>text|<b>text2</b></td> will become this <td><p>text|<b>text2</p></b></td> + // This won't happen if root blocks are disabled or the shiftKey is pressed + if ((newBlockName && !shiftKey) || (!newBlockName && shiftKey)) { + container = wrapSelfAndSiblingsInDefaultBlock(container, offset); + } + + // Find parent block and setup empty block paddings + parentBlock = dom.getParent(container, dom.isBlock); + containerBlock = parentBlock ? dom.getParent(parentBlock.parentNode, dom.isBlock) : null; + + // Setup block names + parentBlockName = parentBlock ? parentBlock.nodeName.toUpperCase() : ''; // IE < 9 & HTML5 + containerBlockName = containerBlock ? containerBlock.nodeName.toUpperCase() : ''; // IE < 9 & HTML5 + + // Enter inside block contained within a LI then split or insert before/after LI + if (containerBlockName == 'LI' && !evt.ctrlKey) { + parentBlock = containerBlock; + parentBlockName = containerBlockName; + } + + // Handle enter in list item + if (/^(LI|DT|DD)$/.test(parentBlockName)) { + if (!newBlockName && shiftKey) { + insertBr(); + return; + } + + // Handle enter inside an empty list item + if (dom.isEmpty(parentBlock)) { + handleEmptyListItem(); + return; + } + } + + // Don't split PRE tags but insert a BR instead easier when writing code samples etc + if (parentBlockName == 'PRE' && settings.br_in_pre !== false) { + if (!shiftKey) { + insertBr(); + return; + } + } else { + // If no root block is configured then insert a BR by default or if the shiftKey is pressed + if ((!newBlockName && !shiftKey && parentBlockName != 'LI') || (newBlockName && shiftKey)) { + insertBr(); + return; + } + } + + // If parent block is root then never insert new blocks + if (newBlockName && parentBlock === editor.getBody()) { + return; + } + + // Default block name if it's not configured + newBlockName = newBlockName || 'P'; + + // Insert new block before/after the parent block depending on caret location + if (isCaretAtStartOrEndOfBlock()) { + insertNewBlockAfter(); + } else if (isCaretAtStartOrEndOfBlock(true)) { + // Insert new block before + newBlock = parentBlock.parentNode.insertBefore(createNewBlock(), parentBlock); + renderBlockOnIE(newBlock); + moveToCaretPosition(parentBlock); + } else { + // Extract after fragment and insert it after the current block + tmpRng = rng.cloneRange(); + tmpRng.setEndAfter(parentBlock); + fragment = tmpRng.extractContents(); + trimLeadingLineBreaks(fragment); + newBlock = fragment.firstChild; + dom.insertAfter(fragment, parentBlock); + trimInlineElementsOnLeftSideOfBlock(newBlock); + addBrToBlockIfNeeded(parentBlock); + + if (dom.isEmpty(parentBlock)) { + emptyBlock(parentBlock); + } + + newBlock.normalize(); + + // New block might become empty if it's <p><b>a |</b></p> + if (dom.isEmpty(newBlock)) { + dom.remove(newBlock); + insertNewBlockAfter(); + } else { + moveToCaretPosition(newBlock); + } + } + + dom.setAttrib(newBlock, 'id', ''); // Remove ID since it needs to be document unique + + // Allow custom handling of new blocks + editor.fire('NewBlock', {newBlock: newBlock}); + + undoManager.add(); + } + + editor.on('keydown', function(evt) { + if (evt.keyCode == 13) { + if (handleEnterKey(evt) !== false) { + evt.preventDefault(); + } + } + }); + }; +}); + +// Included from: js/tinymce/classes/ForceBlocks.js + +/** + * ForceBlocks.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Makes sure that everything gets wrapped in paragraphs. + * + * @private + * @class tinymce.ForceBlocks + */ +define("tinymce/ForceBlocks", [], function() { + return function(editor) { + var settings = editor.settings, dom = editor.dom, selection = editor.selection; + var schema = editor.schema, blockElements = schema.getBlockElements(); + + function addRootBlocks() { + var node = selection.getStart(), rootNode = editor.getBody(), rng; + var startContainer, startOffset, endContainer, endOffset, rootBlockNode; + var tempNode, offset = -0xFFFFFF, wrapped, restoreSelection; + var tmpRng, rootNodeName, forcedRootBlock; + + forcedRootBlock = settings.forced_root_block; + + if (!node || node.nodeType !== 1 || !forcedRootBlock) { + return; + } + + // Check if node is wrapped in block + while (node && node != rootNode) { + if (blockElements[node.nodeName]) { + return; + } + + node = node.parentNode; + } + + // Get current selection + rng = selection.getRng(); + if (rng.setStart) { + startContainer = rng.startContainer; + startOffset = rng.startOffset; + endContainer = rng.endContainer; + endOffset = rng.endOffset; + + try { + restoreSelection = editor.getDoc().activeElement === rootNode; + } catch (ex) { + // IE throws unspecified error here sometimes + } + } else { + // Force control range into text range + if (rng.item) { + node = rng.item(0); + rng = editor.getDoc().body.createTextRange(); + rng.moveToElementText(node); + } + + restoreSelection = rng.parentElement().ownerDocument === editor.getDoc(); + tmpRng = rng.duplicate(); + tmpRng.collapse(true); + startOffset = tmpRng.move('character', offset) * -1; + + if (!tmpRng.collapsed) { + tmpRng = rng.duplicate(); + tmpRng.collapse(false); + endOffset = (tmpRng.move('character', offset) * -1) - startOffset; + } + } + + // Wrap non block elements and text nodes + node = rootNode.firstChild; + rootNodeName = rootNode.nodeName.toLowerCase(); + while (node) { + // TODO: Break this up, too complex + if (((node.nodeType === 3 || (node.nodeType == 1 && !blockElements[node.nodeName]))) && + schema.isValidChild(rootNodeName, forcedRootBlock.toLowerCase())) { + // Remove empty text nodes + if (node.nodeType === 3 && node.nodeValue.length === 0) { + tempNode = node; + node = node.nextSibling; + dom.remove(tempNode); + continue; + } + + if (!rootBlockNode) { + rootBlockNode = dom.create(forcedRootBlock, editor.settings.forced_root_block_attrs); + node.parentNode.insertBefore(rootBlockNode, node); + wrapped = true; + } + + tempNode = node; + node = node.nextSibling; + rootBlockNode.appendChild(tempNode); + } else { + rootBlockNode = null; + node = node.nextSibling; + } + } + + if (wrapped && restoreSelection) { + if (rng.setStart) { + rng.setStart(startContainer, startOffset); + rng.setEnd(endContainer, endOffset); + selection.setRng(rng); + } else { + // Only select if the previous selection was inside the document to prevent auto focus in quirks mode + try { + rng = editor.getDoc().body.createTextRange(); + rng.moveToElementText(rootNode); + rng.collapse(true); + rng.moveStart('character', startOffset); + + if (endOffset > 0) { + rng.moveEnd('character', endOffset); + } + + rng.select(); + } catch (ex) { + // Ignore + } + } + + editor.nodeChanged(); + } + } + + // Force root blocks + if (settings.forced_root_block) { + editor.on('NodeChange', addRootBlocks); + } + }; +}); + +// Included from: js/tinymce/classes/caret/CaretUtils.js + +/** + * CaretUtils.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Utility functions shared by the caret logic. + * + * @private + * @class tinymce.caret.CaretUtils + */ +define("tinymce/caret/CaretUtils", [ + "tinymce/util/Fun", + "tinymce/dom/TreeWalker", + "tinymce/dom/NodeType", + "tinymce/caret/CaretPosition", + "tinymce/caret/CaretContainer", + "tinymce/caret/CaretCandidate" +], function(Fun, TreeWalker, NodeType, CaretPosition, CaretContainer, CaretCandidate) { + var isContentEditableTrue = NodeType.isContentEditableTrue, + isContentEditableFalse = NodeType.isContentEditableFalse, + isBlockLike = NodeType.matchStyleValues('display', 'block table table-cell table-caption'), + isCaretContainer = CaretContainer.isCaretContainer, + curry = Fun.curry, + isElement = NodeType.isElement, + isCaretCandidate = CaretCandidate.isCaretCandidate; + + function isForwards(direction) { + return direction > 0; + } + + function isBackwards(direction) { + return direction < 0; + } + + function findNode(node, direction, predicateFn, rootNode, shallow) { + var walker = new TreeWalker(node, rootNode); + + if (isBackwards(direction)) { + if (isContentEditableFalse(node)) { + node = walker.prev(true); + if (predicateFn(node)) { + return node; + } + } + + while ((node = walker.prev(shallow))) { + if (predicateFn(node)) { + return node; + } + } + } + + if (isForwards(direction)) { + if (isContentEditableFalse(node)) { + node = walker.next(true); + if (predicateFn(node)) { + return node; + } + } + + while ((node = walker.next(shallow))) { + if (predicateFn(node)) { + return node; + } + } + } + + return null; + } + + function getEditingHost(node, rootNode) { + for (node = node.parentNode; node && node != rootNode; node = node.parentNode) { + if (isContentEditableTrue(node)) { + return node; + } + } + + return rootNode; + } + + function getParentBlock(node, rootNode) { + while (node && node != rootNode) { + if (isBlockLike(node)) { + return node; + } + + node = node.parentNode; + } + + return null; + } + + function isInSameBlock(caretPosition1, caretPosition2, rootNode) { + return getParentBlock(caretPosition1.container(), rootNode) == getParentBlock(caretPosition2.container(), rootNode); + } + + function isInSameEditingHost(caretPosition1, caretPosition2, rootNode) { + return getEditingHost(caretPosition1.container(), rootNode) == getEditingHost(caretPosition2.container(), rootNode); + } + + function getChildNodeAtRelativeOffset(relativeOffset, caretPosition) { + var container, offset; + + if (!caretPosition) { + return null; + } + + container = caretPosition.container(); + offset = caretPosition.offset(); + + if (!isElement(container)) { + return null; + } + + return container.childNodes[offset + relativeOffset]; + } + + function beforeAfter(before, node) { + var range = node.ownerDocument.createRange(); + + if (before) { + range.setStartBefore(node); + range.setEndBefore(node); + } else { + range.setStartAfter(node); + range.setEndAfter(node); + } + + return range; + } + + function isNodesInSameBlock(rootNode, node1, node2) { + return getParentBlock(node1, rootNode) == getParentBlock(node2, rootNode); + } + + function lean(left, rootNode, node) { + var sibling, siblingName; + + if (left) { + siblingName = 'previousSibling'; + } else { + siblingName = 'nextSibling'; + } + + while (node && node != rootNode) { + sibling = node[siblingName]; + + if (isCaretContainer(sibling)) { + sibling = sibling[siblingName]; + } + + if (isContentEditableFalse(sibling)) { + if (isNodesInSameBlock(rootNode, sibling, node)) { + return sibling; + } + + break; + } + + if (isCaretCandidate(sibling)) { + break; + } + + node = node.parentNode; + } + + return null; + } + + var before = curry(beforeAfter, true); + var after = curry(beforeAfter, false); + + function normalizeRange(direction, rootNode, range) { + var node, container, offset, location; + var leanLeft = curry(lean, true, rootNode); + var leanRight = curry(lean, false, rootNode); + + container = range.startContainer; + offset = range.startOffset; + + if (CaretContainer.isCaretContainerBlock(container)) { + if (!isElement(container)) { + container = container.parentNode; + } + + location = container.getAttribute('data-mce-caret'); + + if (location == 'before') { + node = container.nextSibling; + if (isContentEditableFalse(node)) { + return before(node); + } + } + + if (location == 'after') { + node = container.previousSibling; + if (isContentEditableFalse(node)) { + return after(node); + } + } + } + + if (!range.collapsed) { + return range; + } + + if (NodeType.isText(container)) { + if (isCaretContainer(container)) { + if (direction === 1) { + node = leanRight(container); + if (node) { + return before(node); + } + + node = leanLeft(container); + if (node) { + return after(node); + } + } + + if (direction === -1) { + node = leanLeft(container); + if (node) { + return after(node); + } + + node = leanRight(container); + if (node) { + return before(node); + } + } + + return range; + } + + if (CaretContainer.endsWithCaretContainer(container) && offset >= container.data.length - 1) { + if (direction === 1) { + node = leanRight(container); + if (node) { + return before(node); + } + } + + return range; + } + + if (CaretContainer.startsWithCaretContainer(container) && offset <= 1) { + if (direction === -1) { + node = leanLeft(container); + if (node) { + return after(node); + } + } + + return range; + } + + if (offset === container.data.length) { + node = leanRight(container); + if (node) { + return before(node); + } + + return range; + } + + if (offset === 0) { + node = leanLeft(container); + if (node) { + return after(node); + } + + return range; + } + } + + return range; + } + + function isNextToContentEditableFalse(relativeOffset, caretPosition) { + return isContentEditableFalse(getChildNodeAtRelativeOffset(relativeOffset, caretPosition)); + } + + return { + isForwards: isForwards, + isBackwards: isBackwards, + findNode: findNode, + getEditingHost: getEditingHost, + getParentBlock: getParentBlock, + isInSameBlock: isInSameBlock, + isInSameEditingHost: isInSameEditingHost, + isBeforeContentEditableFalse: curry(isNextToContentEditableFalse, 0), + isAfterContentEditableFalse: curry(isNextToContentEditableFalse, -1), + normalizeRange: normalizeRange + }; +}); + +// Included from: js/tinymce/classes/caret/CaretWalker.js + +/** + * CaretWalker.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This module contains logic for moving around a virtual caret in logical order within a DOM element. + * + * It ignores the most obvious invalid caret locations such as within a script element or within a + * contentEditable=false element but it will return locations that isn't possible to render visually. + * + * @private + * @class tinymce.caret.CaretWalker + * @example + * var caretWalker = new CaretWalker(rootElm); + * + * var prevLogicalCaretPosition = caretWalker.prev(CaretPosition.fromRangeStart(range)); + * var nextLogicalCaretPosition = caretWalker.next(CaretPosition.fromRangeEnd(range)); + */ +define("tinymce/caret/CaretWalker", [ + "tinymce/dom/NodeType", + "tinymce/caret/CaretCandidate", + "tinymce/caret/CaretPosition", + "tinymce/caret/CaretUtils", + "tinymce/util/Arr", + "tinymce/util/Fun" +], function(NodeType, CaretCandidate, CaretPosition, CaretUtils, Arr, Fun) { + var isContentEditableFalse = NodeType.isContentEditableFalse, + isText = NodeType.isText, + isElement = NodeType.isElement, + isBr = NodeType.isBr, + isForwards = CaretUtils.isForwards, + isBackwards = CaretUtils.isBackwards, + isCaretCandidate = CaretCandidate.isCaretCandidate, + isAtomic = CaretCandidate.isAtomic, + isEditableCaretCandidate = CaretCandidate.isEditableCaretCandidate; + + function getParents(node, rootNode) { + var parents = []; + + while (node && node != rootNode) { + parents.push(node); + node = node.parentNode; + } + + return parents; + } + + function nodeAtIndex(container, offset) { + if (container.hasChildNodes() && offset < container.childNodes.length) { + return container.childNodes[offset]; + } + + return null; + } + + function getCaretCandidatePosition(direction, node) { + if (isForwards(direction)) { + if (isCaretCandidate(node.previousSibling) && !isText(node.previousSibling)) { + return CaretPosition.before(node); + } + + if (isText(node)) { + return CaretPosition(node, 0); + } + } + + if (isBackwards(direction)) { + if (isCaretCandidate(node.nextSibling) && !isText(node.nextSibling)) { + return CaretPosition.after(node); + } + + if (isText(node)) { + return CaretPosition(node, node.data.length); + } + } + + if (isBackwards(direction)) { + if (isBr(node)) { + return CaretPosition.before(node); + } + + return CaretPosition.after(node); + } + + return CaretPosition.before(node); + } + + // Jumps over BR elements <p>|<br></p><p>a</p> -> <p><br></p><p>|a</p> + function isBrBeforeBlock(node, rootNode) { + var next; + + if (!NodeType.isBr(node)) { + return false; + } + + next = findCaretPosition(1, CaretPosition.after(node), rootNode); + if (!next) { + return false; + } + + return !CaretUtils.isInSameBlock(CaretPosition.before(node), CaretPosition.before(next), rootNode); + } + + function findCaretPosition(direction, startCaretPosition, rootNode) { + var container, offset, node, nextNode, innerNode, + rootContentEditableFalseElm, caretPosition; + + if (!isElement(rootNode) || !startCaretPosition) { + return null; + } + + caretPosition = startCaretPosition; + container = caretPosition.container(); + offset = caretPosition.offset(); + + if (isText(container)) { + if (isBackwards(direction) && offset > 0) { + return CaretPosition(container, --offset); + } + + if (isForwards(direction) && offset < container.length) { + return CaretPosition(container, ++offset); + } + + node = container; + } else { + if (isBackwards(direction) && offset > 0) { + nextNode = nodeAtIndex(container, offset - 1); + if (isCaretCandidate(nextNode)) { + if (!isAtomic(nextNode)) { + innerNode = CaretUtils.findNode(nextNode, direction, isEditableCaretCandidate, nextNode); + if (innerNode) { + if (isText(innerNode)) { + return CaretPosition(innerNode, innerNode.data.length); + } + + return CaretPosition.after(innerNode); + } + } + + if (isText(nextNode)) { + return CaretPosition(nextNode, nextNode.data.length); + } + + return CaretPosition.before(nextNode); + } + } + + if (isForwards(direction) && offset < container.childNodes.length) { + nextNode = nodeAtIndex(container, offset); + if (isCaretCandidate(nextNode)) { + if (isBrBeforeBlock(nextNode, rootNode)) { + return findCaretPosition(direction, CaretPosition.after(nextNode), rootNode); + } + + if (!isAtomic(nextNode)) { + innerNode = CaretUtils.findNode(nextNode, direction, isEditableCaretCandidate, nextNode); + if (innerNode) { + if (isText(innerNode)) { + return CaretPosition(innerNode, 0); + } + + return CaretPosition.before(innerNode); + } + } + + if (isText(nextNode)) { + return CaretPosition(nextNode, 0); + } + + return CaretPosition.after(nextNode); + } + } + + node = caretPosition.getNode(); + } + + if ((isForwards(direction) && caretPosition.isAtEnd()) || (isBackwards(direction) && caretPosition.isAtStart())) { + node = CaretUtils.findNode(node, direction, Fun.constant(true), rootNode, true); + if (isEditableCaretCandidate(node)) { + return getCaretCandidatePosition(direction, node); + } + } + + nextNode = CaretUtils.findNode(node, direction, isEditableCaretCandidate, rootNode); + + rootContentEditableFalseElm = Arr.last(Arr.filter(getParents(container, rootNode), isContentEditableFalse)); + if (rootContentEditableFalseElm && (!nextNode || !rootContentEditableFalseElm.contains(nextNode))) { + if (isForwards(direction)) { + caretPosition = CaretPosition.after(rootContentEditableFalseElm); + } else { + caretPosition = CaretPosition.before(rootContentEditableFalseElm); + } + + return caretPosition; + } + + if (nextNode) { + return getCaretCandidatePosition(direction, nextNode); + } + + return null; + } + + return function(rootNode) { + return { + /** + * Returns the next logical caret position from the specificed input + * caretPoisiton or null if there isn't any more positions left for example + * at the end specified root element. + * + * @method next + * @param {tinymce.caret.CaretPosition} caretPosition Caret position to start from. + * @return {tinymce.caret.CaretPosition} CaretPosition or null if no position was found. + */ + next: function(caretPosition) { + return findCaretPosition(1, caretPosition, rootNode); + }, + + /** + * Returns the previous logical caret position from the specificed input + * caretPoisiton or null if there isn't any more positions left for example + * at the end specified root element. + * + * @method prev + * @param {tinymce.caret.CaretPosition} caretPosition Caret position to start from. + * @return {tinymce.caret.CaretPosition} CaretPosition or null if no position was found. + */ + prev: function(caretPosition) { + return findCaretPosition(-1, caretPosition, rootNode); + } + }; + }; +}); + +// Included from: js/tinymce/classes/InsertList.js + +/** + * InsertList.js + * + * Released under LGPL License. + * Copyright (c) 1999-2016 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Handles inserts of lists into the editor instance. + * + * @class tinymce.InsertList + * @private + */ +define("tinymce/InsertList", [ + "tinymce/util/Tools", + "tinymce/caret/CaretWalker", + "tinymce/caret/CaretPosition" +], function(Tools, CaretWalker, CaretPosition) { + var isListFragment = function(fragment) { + var firstChild = fragment.firstChild; + var lastChild = fragment.lastChild; + + // Skip meta since it's likely <meta><ul>..</ul> + if (firstChild && firstChild.name === 'meta') { + firstChild = firstChild.next; + } + + // Skip mce_marker since it's likely <ul>..</ul><span id="mce_marker"></span> + if (lastChild && lastChild.attr('id') === 'mce_marker') { + lastChild = lastChild.prev; + } + + if (!firstChild || firstChild !== lastChild) { + return false; + } + + return firstChild.name === 'ul' || firstChild.name === 'ol'; + }; + + var cleanupDomFragment = function (domFragment) { + var firstChild = domFragment.firstChild; + var lastChild = domFragment.lastChild; + + // TODO: remove the meta tag from paste logic + if (firstChild && firstChild.nodeName === 'META') { + firstChild.parentNode.removeChild(firstChild); + } + + if (lastChild && lastChild.id === 'mce_marker') { + lastChild.parentNode.removeChild(lastChild); + } + + return domFragment; + }; + + var toDomFragment = function(dom, serializer, fragment) { + var html = serializer.serialize(fragment); + var domFragment = dom.createFragment(html); + + return cleanupDomFragment(domFragment); + }; + + var listItems = function(elm) { + return Tools.grep(elm.childNodes, function(child) { + return child.nodeName === 'LI'; + }); + }; + + var isEmpty = function (elm) { + return !elm.firstChild; + }; + + var trimListItems = function(elms) { + return elms.length > 0 && isEmpty(elms[elms.length - 1]) ? elms.slice(0, -1) : elms; + }; + + var getParentLi = function(dom, node) { + var parentBlock = dom.getParent(node, dom.isBlock); + return parentBlock && parentBlock.nodeName === 'LI' ? parentBlock : null; + }; + + var isParentBlockLi = function(dom, node) { + return !!getParentLi(dom, node); + }; + + var getSplit = function(parentNode, rng) { + var beforeRng = rng.cloneRange(); + var afterRng = rng.cloneRange(); + + beforeRng.setStartBefore(parentNode); + afterRng.setEndAfter(parentNode); + + return [ + beforeRng.cloneContents(), + afterRng.cloneContents() + ]; + }; + + var findFirstIn = function(node, rootNode) { + var caretPos = CaretPosition.before(node); + var caretWalker = new CaretWalker(rootNode); + var newCaretPos = caretWalker.next(caretPos); + + return newCaretPos ? newCaretPos.toRange() : null; + }; + + var findLastOf = function(node, rootNode) { + var caretPos = CaretPosition.after(node); + var caretWalker = new CaretWalker(rootNode); + var newCaretPos = caretWalker.prev(caretPos); + + return newCaretPos ? newCaretPos.toRange() : null; + }; + + var insertMiddle = function(target, elms, rootNode, rng) { + var parts = getSplit(target, rng); + var parentElm = target.parentNode; + + parentElm.insertBefore(parts[0], target); + Tools.each(elms, function(li) { + parentElm.insertBefore(li, target); + }); + parentElm.insertBefore(parts[1], target); + parentElm.removeChild(target); + + return findLastOf(elms[elms.length - 1], rootNode); + }; + + var insertBefore = function(target, elms, rootNode) { + var parentElm = target.parentNode; + + Tools.each(elms, function(elm) { + parentElm.insertBefore(elm, target); + }); + + return findFirstIn(target, rootNode); + }; + + var insertAfter = function(target, elms, rootNode, dom) { + dom.insertAfter(elms.reverse(), target); + return findLastOf(elms[0], rootNode); + }; + + var insertAtCaret = function(serializer, dom, rng, fragment) { + var domFragment = toDomFragment(dom, serializer, fragment); + var liTarget = getParentLi(dom, rng.startContainer); + var liElms = trimListItems(listItems(domFragment.firstChild)); + var BEGINNING = 1, END = 2; + var rootNode = dom.getRoot(); + + var isAt = function(location) { + var caretPos = CaretPosition.fromRangeStart(rng); + var caretWalker = new CaretWalker(dom.getRoot()); + var newPos = location === BEGINNING ? caretWalker.prev(caretPos) : caretWalker.next(caretPos); + + return newPos ? getParentLi(dom, newPos.getNode()) !== liTarget : true; + }; + + if (isAt(BEGINNING)) { + return insertBefore(liTarget, liElms, rootNode); + } else if (isAt(END)) { + return insertAfter(liTarget, liElms, rootNode, dom); + } + + return insertMiddle(liTarget, liElms, rootNode, rng); + }; + + return { + isListFragment: isListFragment, + insertAtCaret: insertAtCaret, + isParentBlockLi: isParentBlockLi, + trimListItems: trimListItems, + listItems: listItems + }; +}); + +// Included from: js/tinymce/classes/InsertContent.js + +/** + * InsertContent.js + * + * Released under LGPL License. + * Copyright (c) 1999-2016 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Handles inserts of contents into the editor instance. + * + * @class tinymce.InsertContent + * @private + */ +define("tinymce/InsertContent", [ + "tinymce/Env", + "tinymce/util/Tools", + "tinymce/html/Serializer", + "tinymce/caret/CaretWalker", + "tinymce/caret/CaretPosition", + "tinymce/dom/ElementUtils", + "tinymce/dom/NodeType", + "tinymce/InsertList" +], function(Env, Tools, Serializer, CaretWalker, CaretPosition, ElementUtils, NodeType, InsertList) { + var isTableCell = NodeType.matchNodeNames('td th'); + + var insertAtCaret = function(editor, value) { + var parser, serializer, parentNode, rootNode, fragment, args; + var marker, rng, node, node2, bookmarkHtml, merge, data; + var textInlineElements = editor.schema.getTextInlineElements(); + var selection = editor.selection, dom = editor.dom; + + function trimOrPaddLeftRight(html) { + var rng, container, offset; + + rng = selection.getRng(true); + container = rng.startContainer; + offset = rng.startOffset; + + function hasSiblingText(siblingName) { + return container[siblingName] && container[siblingName].nodeType == 3; + } + + if (container.nodeType == 3) { + if (offset > 0) { + html = html.replace(/^ /, ' '); + } else if (!hasSiblingText('previousSibling')) { + html = html.replace(/^ /, ' '); + } + + if (offset < container.length) { + html = html.replace(/ (<br>|)$/, ' '); + } else if (!hasSiblingText('nextSibling')) { + html = html.replace(/( | )(<br>|)$/, ' '); + } + } + + return html; + } + + // Removes from a [b] c -> a c -> a c + function trimNbspAfterDeleteAndPaddValue() { + var rng, container, offset; + + rng = selection.getRng(true); + container = rng.startContainer; + offset = rng.startOffset; + + if (container.nodeType == 3 && rng.collapsed) { + if (container.data[offset] === '\u00a0') { + container.deleteData(offset, 1); + + if (!/[\u00a0| ]$/.test(value)) { + value += ' '; + } + } else if (container.data[offset - 1] === '\u00a0') { + container.deleteData(offset - 1, 1); + + if (!/[\u00a0| ]$/.test(value)) { + value = ' ' + value; + } + } + } + } + + function markInlineFormatElements(fragment) { + if (merge) { + for (node = fragment.firstChild; node; node = node.walk(true)) { + if (textInlineElements[node.name]) { + node.attr('data-mce-new', "true"); + } + } + } + } + + function reduceInlineTextElements() { + if (merge) { + var root = editor.getBody(), elementUtils = new ElementUtils(dom); + + Tools.each(dom.select('*[data-mce-new]'), function(node) { + node.removeAttribute('data-mce-new'); + + for (var testNode = node.parentNode; testNode && testNode != root; testNode = testNode.parentNode) { + if (elementUtils.compare(testNode, node)) { + dom.remove(node, true); + } + } + }); + } + } + + function markFragmentElements(fragment) { + var node = fragment; + + while ((node = node.walk())) { + if (node.type === 1) { + node.attr('data-mce-fragment', '1'); + } + } + } + + function umarkFragmentElements(elm) { + Tools.each(elm.getElementsByTagName('*'), function(elm) { + elm.removeAttribute('data-mce-fragment'); + }); + } + + function isPartOfFragment(node) { + return !!node.getAttribute('data-mce-fragment'); + } + + function canHaveChildren(node) { + return node && !editor.schema.getShortEndedElements()[node.nodeName]; + } + + function moveSelectionToMarker(marker) { + var parentEditableFalseElm, parentBlock, nextRng; + + function getContentEditableFalseParent(node) { + var root = editor.getBody(); + + for (; node && node !== root; node = node.parentNode) { + if (editor.dom.getContentEditable(node) === 'false') { + return node; + } + } + + return null; + } + + if (!marker) { + return; + } + + selection.scrollIntoView(marker); + + // If marker is in cE=false then move selection to that element instead + parentEditableFalseElm = getContentEditableFalseParent(marker); + if (parentEditableFalseElm) { + dom.remove(marker); + selection.select(parentEditableFalseElm); + return; + } + + // Move selection before marker and remove it + rng = dom.createRng(); + + // If previous sibling is a text node set the selection to the end of that node + node = marker.previousSibling; + if (node && node.nodeType == 3) { + rng.setStart(node, node.nodeValue.length); + + // TODO: Why can't we normalize on IE + if (!Env.ie) { + node2 = marker.nextSibling; + if (node2 && node2.nodeType == 3) { + node.appendData(node2.data); + node2.parentNode.removeChild(node2); + } + } + } else { + // If the previous sibling isn't a text node or doesn't exist set the selection before the marker node + rng.setStartBefore(marker); + rng.setEndBefore(marker); + } + + function findNextCaretRng(rng) { + var caretPos = CaretPosition.fromRangeStart(rng); + var caretWalker = new CaretWalker(editor.getBody()); + + caretPos = caretWalker.next(caretPos); + if (caretPos) { + return caretPos.toRange(); + } + } + + // Remove the marker node and set the new range + parentBlock = dom.getParent(marker, dom.isBlock); + dom.remove(marker); + + if (parentBlock && dom.isEmpty(parentBlock)) { + editor.$(parentBlock).empty(); + + rng.setStart(parentBlock, 0); + rng.setEnd(parentBlock, 0); + + if (!isTableCell(parentBlock) && !isPartOfFragment(parentBlock) && (nextRng = findNextCaretRng(rng))) { + rng = nextRng; + dom.remove(parentBlock); + } else { + dom.add(parentBlock, dom.create('br', {'data-mce-bogus': '1'})); + } + } + + selection.setRng(rng); + } + + if (typeof value != 'string') { + merge = value.merge; + data = value.data; + value = value.content; + } + + // Check for whitespace before/after value + if (/^ | $/.test(value)) { + value = trimOrPaddLeftRight(value); + } + + // Setup parser and serializer + parser = editor.parser; + serializer = new Serializer({ + validate: editor.settings.validate + }, editor.schema); + bookmarkHtml = '<span id="mce_marker" data-mce-type="bookmark">​</span>'; + + // Run beforeSetContent handlers on the HTML to be inserted + args = {content: value, format: 'html', selection: true}; + editor.fire('BeforeSetContent', args); + value = args.content; + + // Add caret at end of contents if it's missing + if (value.indexOf('{$caret}') == -1) { + value += '{$caret}'; + } + + // Replace the caret marker with a span bookmark element + value = value.replace(/\{\$caret\}/, bookmarkHtml); + + // If selection is at <body>|<p></p> then move it into <body><p>|</p> + rng = selection.getRng(); + var caretElement = rng.startContainer || (rng.parentElement ? rng.parentElement() : null); + var body = editor.getBody(); + if (caretElement === body && selection.isCollapsed()) { + if (dom.isBlock(body.firstChild) && canHaveChildren(body.firstChild) && dom.isEmpty(body.firstChild)) { + rng = dom.createRng(); + rng.setStart(body.firstChild, 0); + rng.setEnd(body.firstChild, 0); + selection.setRng(rng); + } + } + + // Insert node maker where we will insert the new HTML and get it's parent + if (!selection.isCollapsed()) { + // Fix for #2595 seems that delete removes one extra character on + // WebKit for some odd reason if you double click select a word + editor.selection.setRng(editor.selection.getRng()); + editor.getDoc().execCommand('Delete', false, null); + trimNbspAfterDeleteAndPaddValue(); + } + + parentNode = selection.getNode(); + + // Parse the fragment within the context of the parent node + var parserArgs = {context: parentNode.nodeName.toLowerCase(), data: data}; + fragment = parser.parse(value, parserArgs); + + // Custom handling of lists + if (InsertList.isListFragment(fragment) && InsertList.isParentBlockLi(dom, parentNode)) { + rng = InsertList.insertAtCaret(serializer, dom, editor.selection.getRng(), fragment); + editor.selection.setRng(rng); + editor.fire('SetContent', args); + return; + } + + markFragmentElements(fragment); + markInlineFormatElements(fragment); + + // Move the caret to a more suitable location + node = fragment.lastChild; + if (node.attr('id') == 'mce_marker') { + marker = node; + + for (node = node.prev; node; node = node.walk(true)) { + if (node.type == 3 || !dom.isBlock(node.name)) { + if (editor.schema.isValidChild(node.parent.name, 'span')) { + node.parent.insert(marker, node, node.name === 'br'); + } + break; + } + } + } + + editor._selectionOverrides.showBlockCaretContainer(parentNode); + + // If parser says valid we can insert the contents into that parent + if (!parserArgs.invalid) { + value = serializer.serialize(fragment); + + // Check if parent is empty or only has one BR element then set the innerHTML of that parent + node = parentNode.firstChild; + node2 = parentNode.lastChild; + if (!node || (node === node2 && node.nodeName === 'BR')) { + dom.setHTML(parentNode, value); + } else { + selection.setContent(value); + } + } else { + // If the fragment was invalid within that context then we need + // to parse and process the parent it's inserted into + + // Insert bookmark node and get the parent + selection.setContent(bookmarkHtml); + parentNode = selection.getNode(); + rootNode = editor.getBody(); + + // Opera will return the document node when selection is in root + if (parentNode.nodeType == 9) { + parentNode = node = rootNode; + } else { + node = parentNode; + } + + // Find the ancestor just before the root element + while (node !== rootNode) { + parentNode = node; + node = node.parentNode; + } + + // Get the outer/inner HTML depending on if we are in the root and parser and serialize that + value = parentNode == rootNode ? rootNode.innerHTML : dom.getOuterHTML(parentNode); + value = serializer.serialize( + parser.parse( + // Need to replace by using a function since $ in the contents would otherwise be a problem + value.replace(/<span (id="mce_marker"|id=mce_marker).+?<\/span>/i, function() { + return serializer.serialize(fragment); + }) + ) + ); + + // Set the inner/outer HTML depending on if we are in the root or not + if (parentNode == rootNode) { + dom.setHTML(rootNode, value); + } else { + dom.setOuterHTML(parentNode, value); + } + } + + reduceInlineTextElements(); + moveSelectionToMarker(dom.get('mce_marker')); + umarkFragmentElements(editor.getBody()); + editor.fire('SetContent', args); + editor.addVisual(); + }; + + return { + insertAtCaret: insertAtCaret + }; +}); + +// Included from: js/tinymce/classes/EditorCommands.js + +/** + * EditorCommands.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class enables you to add custom editor commands and it contains + * overrides for native browser commands to address various bugs and issues. + * + * @class tinymce.EditorCommands + */ +define("tinymce/EditorCommands", [ + "tinymce/Env", + "tinymce/util/Tools", + "tinymce/dom/RangeUtils", + "tinymce/dom/TreeWalker", + "tinymce/InsertContent" +], function(Env, Tools, RangeUtils, TreeWalker, InsertContent) { + // Added for compression purposes + var each = Tools.each, extend = Tools.extend; + var map = Tools.map, inArray = Tools.inArray, explode = Tools.explode; + var isOldIE = Env.ie && Env.ie < 11; + var TRUE = true, FALSE = false; + + return function(editor) { + var dom, selection, formatter, + commands = {state: {}, exec: {}, value: {}}, + settings = editor.settings, + bookmark; + + editor.on('PreInit', function() { + dom = editor.dom; + selection = editor.selection; + settings = editor.settings; + formatter = editor.formatter; + }); + + /** + * Executes the specified command. + * + * @method execCommand + * @param {String} command Command to execute. + * @param {Boolean} ui Optional user interface state. + * @param {Object} value Optional value for command. + * @param {Object} args Optional extra arguments to the execCommand. + * @return {Boolean} true/false if the command was found or not. + */ + function execCommand(command, ui, value, args) { + var func, customCommand, state = 0; + + if (!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint)$/.test(command) && (!args || !args.skip_focus)) { + editor.focus(); + } + + args = editor.fire('BeforeExecCommand', {command: command, ui: ui, value: value}); + if (args.isDefaultPrevented()) { + return false; + } + + customCommand = command.toLowerCase(); + if ((func = commands.exec[customCommand])) { + func(customCommand, ui, value); + editor.fire('ExecCommand', {command: command, ui: ui, value: value}); + return true; + } + + // Plugin commands + each(editor.plugins, function(p) { + if (p.execCommand && p.execCommand(command, ui, value)) { + editor.fire('ExecCommand', {command: command, ui: ui, value: value}); + state = true; + return false; + } + }); + + if (state) { + return state; + } + + // Theme commands + if (editor.theme && editor.theme.execCommand && editor.theme.execCommand(command, ui, value)) { + editor.fire('ExecCommand', {command: command, ui: ui, value: value}); + return true; + } + + // Browser commands + try { + state = editor.getDoc().execCommand(command, ui, value); + } catch (ex) { + // Ignore old IE errors + } + + if (state) { + editor.fire('ExecCommand', {command: command, ui: ui, value: value}); + return true; + } + + return false; + } + + /** + * Queries the current state for a command for example if the current selection is "bold". + * + * @method queryCommandState + * @param {String} command Command to check the state of. + * @return {Boolean/Number} true/false if the selected contents is bold or not, -1 if it's not found. + */ + function queryCommandState(command) { + var func; + + // Is hidden then return undefined + if (editor.quirks.isHidden()) { + return; + } + + command = command.toLowerCase(); + if ((func = commands.state[command])) { + return func(command); + } + + // Browser commands + try { + return editor.getDoc().queryCommandState(command); + } catch (ex) { + // Fails sometimes see bug: 1896577 + } + + return false; + } + + /** + * Queries the command value for example the current fontsize. + * + * @method queryCommandValue + * @param {String} command Command to check the value of. + * @return {Object} Command value of false if it's not found. + */ + function queryCommandValue(command) { + var func; + + // Is hidden then return undefined + if (editor.quirks.isHidden()) { + return; + } + + command = command.toLowerCase(); + if ((func = commands.value[command])) { + return func(command); + } + + // Browser commands + try { + return editor.getDoc().queryCommandValue(command); + } catch (ex) { + // Fails sometimes see bug: 1896577 + } + } + + /** + * Adds commands to the command collection. + * + * @method addCommands + * @param {Object} command_list Name/value collection with commands to add, the names can also be comma separated. + * @param {String} type Optional type to add, defaults to exec. Can be value or state as well. + */ + function addCommands(command_list, type) { + type = type || 'exec'; + + each(command_list, function(callback, command) { + each(command.toLowerCase().split(','), function(command) { + commands[type][command] = callback; + }); + }); + } + + function addCommand(command, callback, scope) { + command = command.toLowerCase(); + commands.exec[command] = function(command, ui, value, args) { + return callback.call(scope || editor, ui, value, args); + }; + } + + /** + * Returns true/false if the command is supported or not. + * + * @method queryCommandSupported + * @param {String} command Command that we check support for. + * @return {Boolean} true/false if the command is supported or not. + */ + function queryCommandSupported(command) { + command = command.toLowerCase(); + + if (commands.exec[command]) { + return true; + } + + // Browser commands + try { + return editor.getDoc().queryCommandSupported(command); + } catch (ex) { + // Fails sometimes see bug: 1896577 + } + + return false; + } + + function addQueryStateHandler(command, callback, scope) { + command = command.toLowerCase(); + commands.state[command] = function() { + return callback.call(scope || editor); + }; + } + + function addQueryValueHandler(command, callback, scope) { + command = command.toLowerCase(); + commands.value[command] = function() { + return callback.call(scope || editor); + }; + } + + function hasCustomCommand(command) { + command = command.toLowerCase(); + return !!commands.exec[command]; + } + + // Expose public methods + extend(this, { + execCommand: execCommand, + queryCommandState: queryCommandState, + queryCommandValue: queryCommandValue, + queryCommandSupported: queryCommandSupported, + addCommands: addCommands, + addCommand: addCommand, + addQueryStateHandler: addQueryStateHandler, + addQueryValueHandler: addQueryValueHandler, + hasCustomCommand: hasCustomCommand + }); + + // Private methods + + function execNativeCommand(command, ui, value) { + if (ui === undefined) { + ui = FALSE; + } + + if (value === undefined) { + value = null; + } + + return editor.getDoc().execCommand(command, ui, value); + } + + function isFormatMatch(name) { + return formatter.match(name); + } + + function toggleFormat(name, value) { + formatter.toggle(name, value ? {value: value} : undefined); + editor.nodeChanged(); + } + + function storeSelection(type) { + bookmark = selection.getBookmark(type); + } + + function restoreSelection() { + selection.moveToBookmark(bookmark); + } + + // Add execCommand overrides + addCommands({ + // Ignore these, added for compatibility + 'mceResetDesignMode,mceBeginUndoLevel': function() {}, + + // Add undo manager logic + 'mceEndUndoLevel,mceAddUndoLevel': function() { + editor.undoManager.add(); + }, + + 'Cut,Copy,Paste': function(command) { + var doc = editor.getDoc(), failed; + + // Try executing the native command + try { + execNativeCommand(command); + } catch (ex) { + // Command failed + failed = TRUE; + } + + // Chrome reports the paste command as supported however older IE:s will return false for cut/paste + if (command === 'paste' && !doc.queryCommandEnabled(command)) { + failed = true; + } + + // Present alert message about clipboard access not being available + if (failed || !doc.queryCommandSupported(command)) { + var msg = editor.translate( + "Your browser doesn't support direct access to the clipboard. " + + "Please use the Ctrl+X/C/V keyboard shortcuts instead." + ); + + if (Env.mac) { + msg = msg.replace(/Ctrl\+/g, '\u2318+'); + } + + editor.notificationManager.open({text: msg, type: 'error'}); + } + }, + + // Override unlink command + unlink: function() { + if (selection.isCollapsed()) { + var elm = selection.getNode(); + if (elm.tagName == 'A') { + editor.dom.remove(elm, true); + } + + return; + } + + formatter.remove("link"); + }, + + // Override justify commands to use the text formatter engine + 'JustifyLeft,JustifyCenter,JustifyRight,JustifyFull,JustifyNone': function(command) { + var align = command.substring(7); + + if (align == 'full') { + align = 'justify'; + } + + // Remove all other alignments first + each('left,center,right,justify'.split(','), function(name) { + if (align != name) { + formatter.remove('align' + name); + } + }); + + if (align != 'none') { + toggleFormat('align' + align); + } + }, + + // Override list commands to fix WebKit bug + 'InsertUnorderedList,InsertOrderedList': function(command) { + var listElm, listParent; + + execNativeCommand(command); + + // WebKit produces lists within block elements so we need to split them + // we will replace the native list creation logic to custom logic later on + // TODO: Remove this when the list creation logic is removed + listElm = dom.getParent(selection.getNode(), 'ol,ul'); + if (listElm) { + listParent = listElm.parentNode; + + // If list is within a text block then split that block + if (/^(H[1-6]|P|ADDRESS|PRE)$/.test(listParent.nodeName)) { + storeSelection(); + dom.split(listParent, listElm); + restoreSelection(); + } + } + }, + + // Override commands to use the text formatter engine + 'Bold,Italic,Underline,Strikethrough,Superscript,Subscript': function(command) { + toggleFormat(command); + }, + + // Override commands to use the text formatter engine + 'ForeColor,HiliteColor,FontName': function(command, ui, value) { + toggleFormat(command, value); + }, + + FontSize: function(command, ui, value) { + var fontClasses, fontSizes; + + // Convert font size 1-7 to styles + if (value >= 1 && value <= 7) { + fontSizes = explode(settings.font_size_style_values); + fontClasses = explode(settings.font_size_classes); + + if (fontClasses) { + value = fontClasses[value - 1] || value; + } else { + value = fontSizes[value - 1] || value; + } + } + + toggleFormat(command, value); + }, + + RemoveFormat: function(command) { + formatter.remove(command); + }, + + mceBlockQuote: function() { + toggleFormat('blockquote'); + }, + + FormatBlock: function(command, ui, value) { + return toggleFormat(value || 'p'); + }, + + mceCleanup: function() { + var bookmark = selection.getBookmark(); + + editor.setContent(editor.getContent({cleanup: TRUE}), {cleanup: TRUE}); + + selection.moveToBookmark(bookmark); + }, + + mceRemoveNode: function(command, ui, value) { + var node = value || selection.getNode(); + + // Make sure that the body node isn't removed + if (node != editor.getBody()) { + storeSelection(); + editor.dom.remove(node, TRUE); + restoreSelection(); + } + }, + + mceSelectNodeDepth: function(command, ui, value) { + var counter = 0; + + dom.getParent(selection.getNode(), function(node) { + if (node.nodeType == 1 && counter++ == value) { + selection.select(node); + return FALSE; + } + }, editor.getBody()); + }, + + mceSelectNode: function(command, ui, value) { + selection.select(value); + }, + + mceInsertContent: function(command, ui, value) { + InsertContent.insertAtCaret(editor, value); + }, + + mceInsertRawHTML: function(command, ui, value) { + selection.setContent('tiny_mce_marker'); + editor.setContent( + editor.getContent().replace(/tiny_mce_marker/g, function() { + return value; + }) + ); + }, + + mceToggleFormat: function(command, ui, value) { + toggleFormat(value); + }, + + mceSetContent: function(command, ui, value) { + editor.setContent(value); + }, + + 'Indent,Outdent': function(command) { + var intentValue, indentUnit, value; + + // Setup indent level + intentValue = settings.indentation; + indentUnit = /[a-z%]+$/i.exec(intentValue); + intentValue = parseInt(intentValue, 10); + + if (!queryCommandState('InsertUnorderedList') && !queryCommandState('InsertOrderedList')) { + // If forced_root_blocks is set to false we don't have a block to indent so lets create a div + if (!settings.forced_root_block && !dom.getParent(selection.getNode(), dom.isBlock)) { + formatter.apply('div'); + } + + each(selection.getSelectedBlocks(), function(element) { + if (dom.getContentEditable(element) === "false") { + return; + } + + if (element.nodeName != "LI") { + var indentStyleName = editor.getParam('indent_use_margin', false) ? 'margin' : 'padding'; + + indentStyleName += dom.getStyle(element, 'direction', true) == 'rtl' ? 'Right' : 'Left'; + + if (command == 'outdent') { + value = Math.max(0, parseInt(element.style[indentStyleName] || 0, 10) - intentValue); + dom.setStyle(element, indentStyleName, value ? value + indentUnit : ''); + } else { + value = (parseInt(element.style[indentStyleName] || 0, 10) + intentValue) + indentUnit; + dom.setStyle(element, indentStyleName, value); + } + } + }); + } else { + execNativeCommand(command); + } + }, + + mceRepaint: function() { + }, + + InsertHorizontalRule: function() { + editor.execCommand('mceInsertContent', false, '<hr />'); + }, + + mceToggleVisualAid: function() { + editor.hasVisual = !editor.hasVisual; + editor.addVisual(); + }, + + mceReplaceContent: function(command, ui, value) { + editor.execCommand('mceInsertContent', false, value.replace(/\{\$selection\}/g, selection.getContent({format: 'text'}))); + }, + + mceInsertLink: function(command, ui, value) { + var anchor; + + if (typeof value == 'string') { + value = {href: value}; + } + + anchor = dom.getParent(selection.getNode(), 'a'); + + // Spaces are never valid in URLs and it's a very common mistake for people to make so we fix it here. + value.href = value.href.replace(' ', '%20'); + + // Remove existing links if there could be child links or that the href isn't specified + if (!anchor || !value.href) { + formatter.remove('link'); + } + + // Apply new link to selection + if (value.href) { + formatter.apply('link', value, anchor); + } + }, + + selectAll: function() { + var root = dom.getRoot(), rng; + + if (selection.getRng().setStart) { + rng = dom.createRng(); + rng.setStart(root, 0); + rng.setEnd(root, root.childNodes.length); + selection.setRng(rng); + } else { + // IE will render it's own root level block elements and sometimes + // even put font elements in them when the user starts typing. So we need to + // move the selection to a more suitable element from this: + // <body>|<p></p></body> to this: <body><p>|</p></body> + rng = selection.getRng(); + if (!rng.item) { + rng.moveToElementText(root); + rng.select(); + } + } + }, + + "delete": function() { + execNativeCommand("Delete"); + + // Check if body is empty after the delete call if so then set the contents + // to an empty string and move the caret to any block produced by that operation + // this fixes the issue with root blocks not being properly produced after a delete call on IE + var body = editor.getBody(); + + if (dom.isEmpty(body)) { + editor.setContent(''); + + if (body.firstChild && dom.isBlock(body.firstChild)) { + editor.selection.setCursorLocation(body.firstChild, 0); + } else { + editor.selection.setCursorLocation(body, 0); + } + } + }, + + mceNewDocument: function() { + editor.setContent(''); + }, + + InsertLineBreak: function(command, ui, value) { + // We load the current event in from EnterKey.js when appropriate to heed + // certain event-specific variations such as ctrl-enter in a list + var evt = value; + var brElm, extraBr, marker; + var rng = selection.getRng(true); + new RangeUtils(dom).normalize(rng); + + var offset = rng.startOffset; + var container = rng.startContainer; + + // Resolve node index + if (container.nodeType == 1 && container.hasChildNodes()) { + var isAfterLastNodeInContainer = offset > container.childNodes.length - 1; + + container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container; + if (isAfterLastNodeInContainer && container.nodeType == 3) { + offset = container.nodeValue.length; + } else { + offset = 0; + } + } + + var parentBlock = dom.getParent(container, dom.isBlock); + var parentBlockName = parentBlock ? parentBlock.nodeName.toUpperCase() : ''; // IE < 9 & HTML5 + var containerBlock = parentBlock ? dom.getParent(parentBlock.parentNode, dom.isBlock) : null; + var containerBlockName = containerBlock ? containerBlock.nodeName.toUpperCase() : ''; // IE < 9 & HTML5 + + // Enter inside block contained within a LI then split or insert before/after LI + var isControlKey = evt && evt.ctrlKey; + if (containerBlockName == 'LI' && !isControlKey) { + parentBlock = containerBlock; + parentBlockName = containerBlockName; + } + + // Walks the parent block to the right and look for BR elements + function hasRightSideContent() { + var walker = new TreeWalker(container, parentBlock), node; + var nonEmptyElementsMap = editor.schema.getNonEmptyElements(); + + while ((node = walker.next())) { + if (nonEmptyElementsMap[node.nodeName.toLowerCase()] || node.length > 0) { + return true; + } + } + } + + if (container && container.nodeType == 3 && offset >= container.nodeValue.length) { + // Insert extra BR element at the end block elements + if (!isOldIE && !hasRightSideContent()) { + brElm = dom.create('br'); + rng.insertNode(brElm); + rng.setStartAfter(brElm); + rng.setEndAfter(brElm); + extraBr = true; + } + } + + brElm = dom.create('br'); + rng.insertNode(brElm); + + // Rendering modes below IE8 doesn't display BR elements in PRE unless we have a \n before it + var documentMode = dom.doc.documentMode; + if (isOldIE && parentBlockName == 'PRE' && (!documentMode || documentMode < 8)) { + brElm.parentNode.insertBefore(dom.doc.createTextNode('\r'), brElm); + } + + // Insert temp marker and scroll to that + marker = dom.create('span', {}, ' '); + brElm.parentNode.insertBefore(marker, brElm); + selection.scrollIntoView(marker); + dom.remove(marker); + + if (!extraBr) { + rng.setStartAfter(brElm); + rng.setEndAfter(brElm); + } else { + rng.setStartBefore(brElm); + rng.setEndBefore(brElm); + } + + selection.setRng(rng); + editor.undoManager.add(); + + return TRUE; + } + }); + + // Add queryCommandState overrides + addCommands({ + // Override justify commands + 'JustifyLeft,JustifyCenter,JustifyRight,JustifyFull': function(command) { + var name = 'align' + command.substring(7); + var nodes = selection.isCollapsed() ? [dom.getParent(selection.getNode(), dom.isBlock)] : selection.getSelectedBlocks(); + var matches = map(nodes, function(node) { + return !!formatter.matchNode(node, name); + }); + return inArray(matches, TRUE) !== -1; + }, + + 'Bold,Italic,Underline,Strikethrough,Superscript,Subscript': function(command) { + return isFormatMatch(command); + }, + + mceBlockQuote: function() { + return isFormatMatch('blockquote'); + }, + + Outdent: function() { + var node; + + if (settings.inline_styles) { + if ((node = dom.getParent(selection.getStart(), dom.isBlock)) && parseInt(node.style.paddingLeft, 10) > 0) { + return TRUE; + } + + if ((node = dom.getParent(selection.getEnd(), dom.isBlock)) && parseInt(node.style.paddingLeft, 10) > 0) { + return TRUE; + } + } + + return ( + queryCommandState('InsertUnorderedList') || + queryCommandState('InsertOrderedList') || + (!settings.inline_styles && !!dom.getParent(selection.getNode(), 'BLOCKQUOTE')) + ); + }, + + 'InsertUnorderedList,InsertOrderedList': function(command) { + var list = dom.getParent(selection.getNode(), 'ul,ol'); + + return list && + ( + command === 'insertunorderedlist' && list.tagName === 'UL' || + command === 'insertorderedlist' && list.tagName === 'OL' + ); + } + }, 'state'); + + // Add queryCommandValue overrides + addCommands({ + 'FontSize,FontName': function(command) { + var value = 0, parent; + + if ((parent = dom.getParent(selection.getNode(), 'span'))) { + if (command == 'fontsize') { + value = parent.style.fontSize; + } else { + value = parent.style.fontFamily.replace(/, /g, ',').replace(/[\'\"]/g, '').toLowerCase(); + } + } + + return value; + } + }, 'value'); + + // Add undo manager logic + addCommands({ + Undo: function() { + editor.undoManager.undo(); + }, + + Redo: function() { + editor.undoManager.redo(); + } + }); + }; +}); + +// Included from: js/tinymce/classes/util/URI.js + +/** + * URI.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class handles parsing, modification and serialization of URI/URL strings. + * @class tinymce.util.URI + */ +define("tinymce/util/URI", [ + "tinymce/util/Tools" +], function(Tools) { + var each = Tools.each, trim = Tools.trim; + var queryParts = "source protocol authority userInfo user password host port relative path directory file query anchor".split(' '); + var DEFAULT_PORTS = { + 'ftp': 21, + 'http': 80, + 'https': 443, + 'mailto': 25 + }; + + /** + * Constructs a new URI instance. + * + * @constructor + * @method URI + * @param {String} url URI string to parse. + * @param {Object} settings Optional settings object. + */ + function URI(url, settings) { + var self = this, baseUri, base_url; + + url = trim(url); + settings = self.settings = settings || {}; + baseUri = settings.base_uri; + + // Strange app protocol that isn't http/https or local anchor + // For example: mailto,skype,tel etc. + if (/^([\w\-]+):([^\/]{2})/i.test(url) || /^\s*#/.test(url)) { + self.source = url; + return; + } + + var isProtocolRelative = url.indexOf('//') === 0; + + // Absolute path with no host, fake host and protocol + if (url.indexOf('/') === 0 && !isProtocolRelative) { + url = (baseUri ? baseUri.protocol || 'http' : 'http') + '://mce_host' + url; + } + + // Relative path http:// or protocol relative //path + if (!/^[\w\-]*:?\/\//.test(url)) { + base_url = settings.base_uri ? settings.base_uri.path : new URI(location.href).directory; + if (settings.base_uri.protocol === "") { + url = '//mce_host' + self.toAbsPath(base_url, url); + } else { + url = /([^#?]*)([#?]?.*)/.exec(url); + url = ((baseUri && baseUri.protocol) || 'http') + '://mce_host' + self.toAbsPath(base_url, url[1]) + url[2]; + } + } + + // Parse URL (Credits goes to Steave, http://blog.stevenlevithan.com/archives/parseuri) + url = url.replace(/@@/g, '(mce_at)'); // Zope 3 workaround, they use @@something + + /*jshint maxlen: 255 */ + /*eslint max-len: 0 */ + url = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(url); + + each(queryParts, function(v, i) { + var part = url[i]; + + // Zope 3 workaround, they use @@something + if (part) { + part = part.replace(/\(mce_at\)/g, '@@'); + } + + self[v] = part; + }); + + if (baseUri) { + if (!self.protocol) { + self.protocol = baseUri.protocol; + } + + if (!self.userInfo) { + self.userInfo = baseUri.userInfo; + } + + if (!self.port && self.host === 'mce_host') { + self.port = baseUri.port; + } + + if (!self.host || self.host === 'mce_host') { + self.host = baseUri.host; + } + + self.source = ''; + } + + if (isProtocolRelative) { + self.protocol = ''; + } + + //t.path = t.path || '/'; + } + + URI.prototype = { + /** + * Sets the internal path part of the URI. + * + * @method setPath + * @param {string} path Path string to set. + */ + setPath: function(path) { + var self = this; + + path = /^(.*?)\/?(\w+)?$/.exec(path); + + // Update path parts + self.path = path[0]; + self.directory = path[1]; + self.file = path[2]; + + // Rebuild source + self.source = ''; + self.getURI(); + }, + + /** + * Converts the specified URI into a relative URI based on the current URI instance location. + * + * @method toRelative + * @param {String} uri URI to convert into a relative path/URI. + * @return {String} Relative URI from the point specified in the current URI instance. + * @example + * // Converts an absolute URL to an relative URL url will be somedir/somefile.htm + * var url = new tinymce.util.URI('http://www.site.com/dir/').toRelative('http://www.site.com/dir/somedir/somefile.htm'); + */ + toRelative: function(uri) { + var self = this, output; + + if (uri === "./") { + return uri; + } + + uri = new URI(uri, {base_uri: self}); + + // Not on same domain/port or protocol + if ((uri.host != 'mce_host' && self.host != uri.host && uri.host) || self.port != uri.port || + (self.protocol != uri.protocol && uri.protocol !== "")) { + return uri.getURI(); + } + + var tu = self.getURI(), uu = uri.getURI(); + + // Allow usage of the base_uri when relative_urls = true + if (tu == uu || (tu.charAt(tu.length - 1) == "/" && tu.substr(0, tu.length - 1) == uu)) { + return tu; + } + + output = self.toRelPath(self.path, uri.path); + + // Add query + if (uri.query) { + output += '?' + uri.query; + } + + // Add anchor + if (uri.anchor) { + output += '#' + uri.anchor; + } + + return output; + }, + + /** + * Converts the specified URI into a absolute URI based on the current URI instance location. + * + * @method toAbsolute + * @param {String} uri URI to convert into a relative path/URI. + * @param {Boolean} noHost No host and protocol prefix. + * @return {String} Absolute URI from the point specified in the current URI instance. + * @example + * // Converts an relative URL to an absolute URL url will be http://www.site.com/dir/somedir/somefile.htm + * var url = new tinymce.util.URI('http://www.site.com/dir/').toAbsolute('somedir/somefile.htm'); + */ + toAbsolute: function(uri, noHost) { + uri = new URI(uri, {base_uri: this}); + + return uri.getURI(noHost && this.isSameOrigin(uri)); + }, + + /** + * Determine whether the given URI has the same origin as this URI. Based on RFC-6454. + * Supports default ports for protocols listed in DEFAULT_PORTS. Unsupported protocols will fail safe: they + * won't match, if the port specifications differ. + * + * @method isSameOrigin + * @param {tinymce.util.URI} uri Uri instance to compare. + * @returns {Boolean} True if the origins are the same. + */ + isSameOrigin: function(uri) { + if (this.host == uri.host && this.protocol == uri.protocol) { + if (this.port == uri.port) { + return true; + } + + var defaultPort = DEFAULT_PORTS[this.protocol]; + if (defaultPort && ((this.port || defaultPort) == (uri.port || defaultPort))) { + return true; + } + } + + return false; + }, + + /** + * Converts a absolute path into a relative path. + * + * @method toRelPath + * @param {String} base Base point to convert the path from. + * @param {String} path Absolute path to convert into a relative path. + */ + toRelPath: function(base, path) { + var items, breakPoint = 0, out = '', i, l; + + // Split the paths + base = base.substring(0, base.lastIndexOf('/')); + base = base.split('/'); + items = path.split('/'); + + if (base.length >= items.length) { + for (i = 0, l = base.length; i < l; i++) { + if (i >= items.length || base[i] != items[i]) { + breakPoint = i + 1; + break; + } + } + } + + if (base.length < items.length) { + for (i = 0, l = items.length; i < l; i++) { + if (i >= base.length || base[i] != items[i]) { + breakPoint = i + 1; + break; + } + } + } + + if (breakPoint === 1) { + return path; + } + + for (i = 0, l = base.length - (breakPoint - 1); i < l; i++) { + out += "../"; + } + + for (i = breakPoint - 1, l = items.length; i < l; i++) { + if (i != breakPoint - 1) { + out += "/" + items[i]; + } else { + out += items[i]; + } + } + + return out; + }, + + /** + * Converts a relative path into a absolute path. + * + * @method toAbsPath + * @param {String} base Base point to convert the path from. + * @param {String} path Relative path to convert into an absolute path. + */ + toAbsPath: function(base, path) { + var i, nb = 0, o = [], tr, outPath; + + // Split paths + tr = /\/$/.test(path) ? '/' : ''; + base = base.split('/'); + path = path.split('/'); + + // Remove empty chunks + each(base, function(k) { + if (k) { + o.push(k); + } + }); + + base = o; + + // Merge relURLParts chunks + for (i = path.length - 1, o = []; i >= 0; i--) { + // Ignore empty or . + if (path[i].length === 0 || path[i] === ".") { + continue; + } + + // Is parent + if (path[i] === '..') { + nb++; + continue; + } + + // Move up + if (nb > 0) { + nb--; + continue; + } + + o.push(path[i]); + } + + i = base.length - nb; + + // If /a/b/c or / + if (i <= 0) { + outPath = o.reverse().join('/'); + } else { + outPath = base.slice(0, i).join('/') + '/' + o.reverse().join('/'); + } + + // Add front / if it's needed + if (outPath.indexOf('/') !== 0) { + outPath = '/' + outPath; + } + + // Add traling / if it's needed + if (tr && outPath.lastIndexOf('/') !== outPath.length - 1) { + outPath += tr; + } + + return outPath; + }, + + /** + * Returns the full URI of the internal structure. + * + * @method getURI + * @param {Boolean} noProtoHost Optional no host and protocol part. Defaults to false. + */ + getURI: function(noProtoHost) { + var s, self = this; + + // Rebuild source + if (!self.source || noProtoHost) { + s = ''; + + if (!noProtoHost) { + if (self.protocol) { + s += self.protocol + '://'; + } else { + s += '//'; + } + + if (self.userInfo) { + s += self.userInfo + '@'; + } + + if (self.host) { + s += self.host; + } + + if (self.port) { + s += ':' + self.port; + } + } + + if (self.path) { + s += self.path; + } + + if (self.query) { + s += '?' + self.query; + } + + if (self.anchor) { + s += '#' + self.anchor; + } + + self.source = s; + } + + return self.source; + } + }; + + URI.parseDataUri = function(uri) { + var type, matches; + + uri = decodeURIComponent(uri).split(','); + + matches = /data:([^;]+)/.exec(uri[0]); + if (matches) { + type = matches[1]; + } + + return { + type: type, + data: uri[1] + }; + }; + + URI.getDocumentBaseUrl = function(loc) { + var baseUrl; + + // Pass applewebdata:// and other non web protocols though + if (loc.protocol.indexOf('http') !== 0 && loc.protocol !== 'file:') { + baseUrl = loc.href; + } else { + baseUrl = loc.protocol + '//' + loc.host + loc.pathname; + } + + if (/^[^:]+:\/\/\/?[^\/]+\//.test(baseUrl)) { + baseUrl = baseUrl.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, ''); + + if (!/[\/\\]$/.test(baseUrl)) { + baseUrl += '/'; + } + } + + return baseUrl; + }; + + return URI; +}); + +// Included from: js/tinymce/classes/util/Class.js + +/** + * Class.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This utilitiy class is used for easier inheritance. + * + * Features: + * * Exposed super functions: this._super(); + * * Mixins + * * Dummy functions + * * Property functions: var value = object.value(); and object.value(newValue); + * * Static functions + * * Defaults settings + */ +define("tinymce/util/Class", [ + "tinymce/util/Tools" +], function(Tools) { + var each = Tools.each, extend = Tools.extend; + + var extendClass, initializing; + + function Class() { + } + + // Provides classical inheritance, based on code made by John Resig + Class.extend = extendClass = function(prop) { + var self = this, _super = self.prototype, prototype, name, member; + + // The dummy class constructor + function Class() { + var i, mixins, mixin, self = this; + + // All construction is actually done in the init method + if (!initializing) { + // Run class constuctor + if (self.init) { + self.init.apply(self, arguments); + } + + // Run mixin constructors + mixins = self.Mixins; + if (mixins) { + i = mixins.length; + while (i--) { + mixin = mixins[i]; + if (mixin.init) { + mixin.init.apply(self, arguments); + } + } + } + } + } + + // Dummy function, needs to be extended in order to provide functionality + function dummy() { + return this; + } + + // Creates a overloaded method for the class + // this enables you to use this._super(); to call the super function + function createMethod(name, fn) { + return function() { + var self = this, tmp = self._super, ret; + + self._super = _super[name]; + ret = fn.apply(self, arguments); + self._super = tmp; + + return ret; + }; + } + + // Instantiate a base class (but only create the instance, + // don't run the init constructor) + initializing = true; + + /*eslint new-cap:0 */ + prototype = new self(); + initializing = false; + + // Add mixins + if (prop.Mixins) { + each(prop.Mixins, function(mixin) { + for (var name in mixin) { + if (name !== "init") { + prop[name] = mixin[name]; + } + } + }); + + if (_super.Mixins) { + prop.Mixins = _super.Mixins.concat(prop.Mixins); + } + } + + // Generate dummy methods + if (prop.Methods) { + each(prop.Methods.split(','), function(name) { + prop[name] = dummy; + }); + } + + // Generate property methods + if (prop.Properties) { + each(prop.Properties.split(','), function(name) { + var fieldName = '_' + name; + + prop[name] = function(value) { + var self = this, undef; + + // Set value + if (value !== undef) { + self[fieldName] = value; + + return self; + } + + // Get value + return self[fieldName]; + }; + }); + } + + // Static functions + if (prop.Statics) { + each(prop.Statics, function(func, name) { + Class[name] = func; + }); + } + + // Default settings + if (prop.Defaults && _super.Defaults) { + prop.Defaults = extend({}, _super.Defaults, prop.Defaults); + } + + // Copy the properties over onto the new prototype + for (name in prop) { + member = prop[name]; + + if (typeof member == "function" && _super[name]) { + prototype[name] = createMethod(name, member); + } else { + prototype[name] = member; + } + } + + // Populate our constructed prototype object + Class.prototype = prototype; + + // Enforce the constructor to be what we expect + Class.constructor = Class; + + // And make this class extendible + Class.extend = extendClass; + + return Class; + }; + + return Class; +}); + +// Included from: js/tinymce/classes/util/EventDispatcher.js + +/** + * EventDispatcher.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class lets you add/remove and fire events by name on the specified scope. This makes + * it easy to add event listener logic to any class. + * + * @class tinymce.util.EventDispatcher + * @example + * var eventDispatcher = new EventDispatcher(); + * + * eventDispatcher.on('click', function() {console.log('data');}); + * eventDispatcher.fire('click', {data: 123}); + */ +define("tinymce/util/EventDispatcher", [ + "tinymce/util/Tools" +], function(Tools) { + var nativeEvents = Tools.makeMap( + "focus blur focusin focusout click dblclick mousedown mouseup mousemove mouseover beforepaste paste cut copy selectionchange " + + "mouseout mouseenter mouseleave wheel keydown keypress keyup input contextmenu dragstart dragend dragover " + + "draggesture dragdrop drop drag submit " + + "compositionstart compositionend compositionupdate touchstart touchend", + ' ' + ); + + function Dispatcher(settings) { + var self = this, scope, bindings = {}, toggleEvent; + + function returnFalse() { + return false; + } + + function returnTrue() { + return true; + } + + settings = settings || {}; + scope = settings.scope || self; + toggleEvent = settings.toggleEvent || returnFalse; + + /** + * Fires the specified event by name. + * + * @method fire + * @param {String} name Name of the event to fire. + * @param {Object?} args Event arguments. + * @return {Object} Event args instance passed in. + * @example + * instance.fire('event', {...}); + */ + function fire(name, args) { + var handlers, i, l, callback; + + name = name.toLowerCase(); + args = args || {}; + args.type = name; + + // Setup target is there isn't one + if (!args.target) { + args.target = scope; + } + + // Add event delegation methods if they are missing + if (!args.preventDefault) { + // Add preventDefault method + args.preventDefault = function() { + args.isDefaultPrevented = returnTrue; + }; + + // Add stopPropagation + args.stopPropagation = function() { + args.isPropagationStopped = returnTrue; + }; + + // Add stopImmediatePropagation + args.stopImmediatePropagation = function() { + args.isImmediatePropagationStopped = returnTrue; + }; + + // Add event delegation states + args.isDefaultPrevented = returnFalse; + args.isPropagationStopped = returnFalse; + args.isImmediatePropagationStopped = returnFalse; + } + + if (settings.beforeFire) { + settings.beforeFire(args); + } + + handlers = bindings[name]; + if (handlers) { + for (i = 0, l = handlers.length; i < l; i++) { + callback = handlers[i]; + + // Unbind handlers marked with "once" + if (callback.once) { + off(name, callback.func); + } + + // Stop immediate propagation if needed + if (args.isImmediatePropagationStopped()) { + args.stopPropagation(); + return args; + } + + // If callback returns false then prevent default and stop all propagation + if (callback.func.call(scope, args) === false) { + args.preventDefault(); + return args; + } + } + } + + return args; + } + + /** + * Binds an event listener to a specific event by name. + * + * @method on + * @param {String} name Event name or space separated list of events to bind. + * @param {callback} callback Callback to be executed when the event occurs. + * @param {Boolean} first Optional flag if the event should be prepended. Use this with care. + * @return {Object} Current class instance. + * @example + * instance.on('event', function(e) { + * // Callback logic + * }); + */ + function on(name, callback, prepend, extra) { + var handlers, names, i; + + if (callback === false) { + callback = returnFalse; + } + + if (callback) { + callback = { + func: callback + }; + + if (extra) { + Tools.extend(callback, extra); + } + + names = name.toLowerCase().split(' '); + i = names.length; + while (i--) { + name = names[i]; + handlers = bindings[name]; + if (!handlers) { + handlers = bindings[name] = []; + toggleEvent(name, true); + } + + if (prepend) { + handlers.unshift(callback); + } else { + handlers.push(callback); + } + } + } + + return self; + } + + /** + * Unbinds an event listener to a specific event by name. + * + * @method off + * @param {String?} name Name of the event to unbind. + * @param {callback?} callback Callback to unbind. + * @return {Object} Current class instance. + * @example + * // Unbind specific callback + * instance.off('event', handler); + * + * // Unbind all listeners by name + * instance.off('event'); + * + * // Unbind all events + * instance.off(); + */ + function off(name, callback) { + var i, handlers, bindingName, names, hi; + + if (name) { + names = name.toLowerCase().split(' '); + i = names.length; + while (i--) { + name = names[i]; + handlers = bindings[name]; + + // Unbind all handlers + if (!name) { + for (bindingName in bindings) { + toggleEvent(bindingName, false); + delete bindings[bindingName]; + } + + return self; + } + + if (handlers) { + // Unbind all by name + if (!callback) { + handlers.length = 0; + } else { + // Unbind specific ones + hi = handlers.length; + while (hi--) { + if (handlers[hi].func === callback) { + handlers = handlers.slice(0, hi).concat(handlers.slice(hi + 1)); + bindings[name] = handlers; + } + } + } + + if (!handlers.length) { + toggleEvent(name, false); + delete bindings[name]; + } + } + } + } else { + for (name in bindings) { + toggleEvent(name, false); + } + + bindings = {}; + } + + return self; + } + + /** + * Binds an event listener to a specific event by name + * and automatically unbind the event once the callback fires. + * + * @method once + * @param {String} name Event name or space separated list of events to bind. + * @param {callback} callback Callback to be executed when the event occurs. + * @param {Boolean} first Optional flag if the event should be prepended. Use this with care. + * @return {Object} Current class instance. + * @example + * instance.once('event', function(e) { + * // Callback logic + * }); + */ + function once(name, callback, prepend) { + return on(name, callback, prepend, {once: true}); + } + + /** + * Returns true/false if the dispatcher has a event of the specified name. + * + * @method has + * @param {String} name Name of the event to check for. + * @return {Boolean} true/false if the event exists or not. + */ + function has(name) { + name = name.toLowerCase(); + return !(!bindings[name] || bindings[name].length === 0); + } + + // Expose + self.fire = fire; + self.on = on; + self.off = off; + self.once = once; + self.has = has; + } + + /** + * Returns true/false if the specified event name is a native browser event or not. + * + * @method isNative + * @param {String} name Name to check if it's native. + * @return {Boolean} true/false if the event is native or not. + * @static + */ + Dispatcher.isNative = function(name) { + return !!nativeEvents[name.toLowerCase()]; + }; + + return Dispatcher; +}); + +// Included from: js/tinymce/classes/data/Binding.js + +/** + * Binding.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class gets dynamically extended to provide a binding between two models. This makes it possible to + * sync the state of two properties in two models by a layer of abstraction. + * + * @private + * @class tinymce.data.Binding + */ +define("tinymce/data/Binding", [], function() { + /** + * Constructs a new bidning. + * + * @constructor + * @method Binding + * @param {Object} settings Settings to the binding. + */ + function Binding(settings) { + this.create = settings.create; + } + + /** + * Creates a binding for a property on a model. + * + * @method create + * @param {tinymce.data.ObservableObject} model Model to create binding to. + * @param {String} name Name of property to bind. + * @return {tinymce.data.Binding} Binding instance. + */ + Binding.create = function(model, name) { + return new Binding({ + create: function(otherModel, otherName) { + var bindings; + + function fromSelfToOther(e) { + otherModel.set(otherName, e.value); + } + + function fromOtherToSelf(e) { + model.set(name, e.value); + } + + otherModel.on('change:' + otherName, fromOtherToSelf); + model.on('change:' + name, fromSelfToOther); + + // Keep track of the bindings + bindings = otherModel._bindings; + + if (!bindings) { + bindings = otherModel._bindings = []; + + otherModel.on('destroy', function() { + var i = bindings.length; + + while (i--) { + bindings[i](); + } + }); + } + + bindings.push(function() { + model.off('change:' + name, fromSelfToOther); + }); + + return model.get(name); + } + }); + }; + + return Binding; +}); + +// Included from: js/tinymce/classes/util/Observable.js + +/** + * Observable.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This mixin will add event binding logic to classes. + * + * @mixin tinymce.util.Observable + */ +define("tinymce/util/Observable", [ + "tinymce/util/EventDispatcher" +], function(EventDispatcher) { + function getEventDispatcher(obj) { + if (!obj._eventDispatcher) { + obj._eventDispatcher = new EventDispatcher({ + scope: obj, + toggleEvent: function(name, state) { + if (EventDispatcher.isNative(name) && obj.toggleNativeEvent) { + obj.toggleNativeEvent(name, state); + } + } + }); + } + + return obj._eventDispatcher; + } + + return { + /** + * Fires the specified event by name. + * + * @method fire + * @param {String} name Name of the event to fire. + * @param {Object?} args Event arguments. + * @param {Boolean?} bubble True/false if the event is to be bubbled. + * @return {Object} Event args instance passed in. + * @example + * instance.fire('event', {...}); + */ + fire: function(name, args, bubble) { + var self = this; + + // Prevent all events except the remove event after the instance has been removed + if (self.removed && name !== "remove") { + return args; + } + + args = getEventDispatcher(self).fire(name, args, bubble); + + // Bubble event up to parents + if (bubble !== false && self.parent) { + var parent = self.parent(); + while (parent && !args.isPropagationStopped()) { + parent.fire(name, args, false); + parent = parent.parent(); + } + } + + return args; + }, + + /** + * Binds an event listener to a specific event by name. + * + * @method on + * @param {String} name Event name or space separated list of events to bind. + * @param {callback} callback Callback to be executed when the event occurs. + * @param {Boolean} first Optional flag if the event should be prepended. Use this with care. + * @return {Object} Current class instance. + * @example + * instance.on('event', function(e) { + * // Callback logic + * }); + */ + on: function(name, callback, prepend) { + return getEventDispatcher(this).on(name, callback, prepend); + }, + + /** + * Unbinds an event listener to a specific event by name. + * + * @method off + * @param {String?} name Name of the event to unbind. + * @param {callback?} callback Callback to unbind. + * @return {Object} Current class instance. + * @example + * // Unbind specific callback + * instance.off('event', handler); + * + * // Unbind all listeners by name + * instance.off('event'); + * + * // Unbind all events + * instance.off(); + */ + off: function(name, callback) { + return getEventDispatcher(this).off(name, callback); + }, + + /** + * Bind the event callback and once it fires the callback is removed. + * + * @method once + * @param {String} name Name of the event to bind. + * @param {callback} callback Callback to bind only once. + * @return {Object} Current class instance. + */ + once: function(name, callback) { + return getEventDispatcher(this).once(name, callback); + }, + + /** + * Returns true/false if the object has a event of the specified name. + * + * @method hasEventListeners + * @param {String} name Name of the event to check for. + * @return {Boolean} true/false if the event exists or not. + */ + hasEventListeners: function(name) { + return getEventDispatcher(this).has(name); + } + }; +}); + +// Included from: js/tinymce/classes/data/ObservableObject.js + +/** + * ObservableObject.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class is a object that is observable when properties changes a change event gets emitted. + * + * @private + * @class tinymce.data.ObservableObject + */ +define("tinymce/data/ObservableObject", [ + "tinymce/data/Binding", + "tinymce/util/Observable", + "tinymce/util/Class", + "tinymce/util/Tools" +], function(Binding, Observable, Class, Tools) { + function isNode(node) { + return node.nodeType > 0; + } + + // Todo: Maybe this should be shallow compare since it might be huge object references + function isEqual(a, b) { + var k, checked; + + // Strict equals + if (a === b) { + return true; + } + + // Compare null + if (a === null || b === null) { + return a === b; + } + + // Compare number, boolean, string, undefined + if (typeof a !== "object" || typeof b !== "object") { + return a === b; + } + + // Compare arrays + if (Tools.isArray(b)) { + if (a.length !== b.length) { + return false; + } + + k = a.length; + while (k--) { + if (!isEqual(a[k], b[k])) { + return false; + } + } + } + + // Shallow compare nodes + if (isNode(a) || isNode(b)) { + return a === b; + } + + // Compare objects + checked = {}; + for (k in b) { + if (!isEqual(a[k], b[k])) { + return false; + } + + checked[k] = true; + } + + for (k in a) { + if (!checked[k] && !isEqual(a[k], b[k])) { + return false; + } + } + + return true; + } + + return Class.extend({ + Mixins: [Observable], + + /** + * Constructs a new observable object instance. + * + * @constructor + * @param {Object} data Initial data for the object. + */ + init: function(data) { + var name, value; + + data = data || {}; + + for (name in data) { + value = data[name]; + + if (value instanceof Binding) { + data[name] = value.create(this, name); + } + } + + this.data = data; + }, + + /** + * Sets a property on the value this will call + * observers if the value is a change from the current value. + * + * @method set + * @param {String/object} name Name of the property to set or a object of items to set. + * @param {Object} value Value to set for the property. + * @return {tinymce.data.ObservableObject} Observable object instance. + */ + set: function(name, value) { + var key, args, oldValue = this.data[name]; + + if (value instanceof Binding) { + value = value.create(this, name); + } + + if (typeof name === "object") { + for (key in name) { + this.set(key, name[key]); + } + + return this; + } + + if (!isEqual(oldValue, value)) { + this.data[name] = value; + + args = { + target: this, + name: name, + value: value, + oldValue: oldValue + }; + + this.fire('change:' + name, args); + this.fire('change', args); + } + + return this; + }, + + /** + * Gets a property by name. + * + * @method get + * @param {String} name Name of the property to get. + * @return {Object} Object value of propery. + */ + get: function(name) { + return this.data[name]; + }, + + /** + * Returns true/false if the specified property exists. + * + * @method has + * @param {String} name Name of the property to check for. + * @return {Boolean} true/false if the item exists. + */ + has: function(name) { + return name in this.data; + }, + + /** + * Returns a dynamic property binding for the specified property name. This makes + * it possible to sync the state of two properties in two ObservableObject instances. + * + * @method bind + * @param {String} name Name of the property to sync with the property it's inserted to. + * @return {tinymce.data.Binding} Data binding instance. + */ + bind: function(name) { + return Binding.create(this, name); + }, + + /** + * Destroys the observable object and fires the "destroy" + * event and clean up any internal resources. + * + * @method destroy + */ + destroy: function() { + this.fire('destroy'); + } + }); +}); + +// Included from: js/tinymce/classes/ui/Selector.js + +/** + * Selector.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/*eslint no-nested-ternary:0 */ + +/** + * Selector engine, enables you to select controls by using CSS like expressions. + * We currently only support basic CSS expressions to reduce the size of the core + * and the ones we support should be enough for most cases. + * + * @example + * Supported expressions: + * element + * element#name + * element.class + * element[attr] + * element[attr*=value] + * element[attr~=value] + * element[attr!=value] + * element[attr^=value] + * element[attr$=value] + * element:<state> + * element:not(<expression>) + * element:first + * element:last + * element:odd + * element:even + * element element + * element > element + * + * @class tinymce.ui.Selector + */ +define("tinymce/ui/Selector", [ + "tinymce/util/Class" +], function(Class) { + "use strict"; + + /** + * Produces an array with a unique set of objects. It will not compare the values + * but the references of the objects. + * + * @private + * @method unqiue + * @param {Array} array Array to make into an array with unique items. + * @return {Array} Array with unique items. + */ + function unique(array) { + var uniqueItems = [], i = array.length, item; + + while (i--) { + item = array[i]; + + if (!item.__checked) { + uniqueItems.push(item); + item.__checked = 1; + } + } + + i = uniqueItems.length; + while (i--) { + delete uniqueItems[i].__checked; + } + + return uniqueItems; + } + + var expression = /^([\w\\*]+)?(?:#([\w\-\\]+))?(?:\.([\w\\\.]+))?(?:\[\@?([\w\\]+)([\^\$\*!~]?=)([\w\\]+)\])?(?:\:(.+))?/i; + + /*jshint maxlen:255 */ + /*eslint max-len:0 */ + var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, + whiteSpace = /^\s*|\s*$/g, + Collection; + + var Selector = Class.extend({ + /** + * Constructs a new Selector instance. + * + * @constructor + * @method init + * @param {String} selector CSS like selector expression. + */ + init: function(selector) { + var match = this.match; + + function compileNameFilter(name) { + if (name) { + name = name.toLowerCase(); + + return function(item) { + return name === '*' || item.type === name; + }; + } + } + + function compileIdFilter(id) { + if (id) { + return function(item) { + return item._name === id; + }; + } + } + + function compileClassesFilter(classes) { + if (classes) { + classes = classes.split('.'); + + return function(item) { + var i = classes.length; + + while (i--) { + if (!item.classes.contains(classes[i])) { + return false; + } + } + + return true; + }; + } + } + + function compileAttrFilter(name, cmp, check) { + if (name) { + return function(item) { + var value = item[name] ? item[name]() : ''; + + return !cmp ? !!check : + cmp === "=" ? value === check : + cmp === "*=" ? value.indexOf(check) >= 0 : + cmp === "~=" ? (" " + value + " ").indexOf(" " + check + " ") >= 0 : + cmp === "!=" ? value != check : + cmp === "^=" ? value.indexOf(check) === 0 : + cmp === "$=" ? value.substr(value.length - check.length) === check : + false; + }; + } + } + + function compilePsuedoFilter(name) { + var notSelectors; + + if (name) { + name = /(?:not\((.+)\))|(.+)/i.exec(name); + + if (!name[1]) { + name = name[2]; + + return function(item, index, length) { + return name === 'first' ? index === 0 : + name === 'last' ? index === length - 1 : + name === 'even' ? index % 2 === 0 : + name === 'odd' ? index % 2 === 1 : + item[name] ? item[name]() : + false; + }; + } + + // Compile not expression + notSelectors = parseChunks(name[1], []); + + return function(item) { + return !match(item, notSelectors); + }; + } + } + + function compile(selector, filters, direct) { + var parts; + + function add(filter) { + if (filter) { + filters.push(filter); + } + } + + // Parse expression into parts + parts = expression.exec(selector.replace(whiteSpace, '')); + + add(compileNameFilter(parts[1])); + add(compileIdFilter(parts[2])); + add(compileClassesFilter(parts[3])); + add(compileAttrFilter(parts[4], parts[5], parts[6])); + add(compilePsuedoFilter(parts[7])); + + // Mark the filter with pseudo for performance + filters.pseudo = !!parts[7]; + filters.direct = direct; + + return filters; + } + + // Parser logic based on Sizzle by John Resig + function parseChunks(selector, selectors) { + var parts = [], extra, matches, i; + + do { + chunker.exec(""); + matches = chunker.exec(selector); + + if (matches) { + selector = matches[3]; + parts.push(matches[1]); + + if (matches[2]) { + extra = matches[3]; + break; + } + } + } while (matches); + + if (extra) { + parseChunks(extra, selectors); + } + + selector = []; + for (i = 0; i < parts.length; i++) { + if (parts[i] != '>') { + selector.push(compile(parts[i], [], parts[i - 1] === '>')); + } + } + + selectors.push(selector); + + return selectors; + } + + this._selectors = parseChunks(selector, []); + }, + + /** + * Returns true/false if the selector matches the specified control. + * + * @method match + * @param {tinymce.ui.Control} control Control to match against the selector. + * @param {Array} selectors Optional array of selectors, mostly used internally. + * @return {Boolean} true/false state if the control matches or not. + */ + match: function(control, selectors) { + var i, l, si, sl, selector, fi, fl, filters, index, length, siblings, count, item; + + selectors = selectors || this._selectors; + for (i = 0, l = selectors.length; i < l; i++) { + selector = selectors[i]; + sl = selector.length; + item = control; + count = 0; + + for (si = sl - 1; si >= 0; si--) { + filters = selector[si]; + + while (item) { + // Find the index and length since a pseudo filter like :first needs it + if (filters.pseudo) { + siblings = item.parent().items(); + index = length = siblings.length; + while (index--) { + if (siblings[index] === item) { + break; + } + } + } + + for (fi = 0, fl = filters.length; fi < fl; fi++) { + if (!filters[fi](item, index, length)) { + fi = fl + 1; + break; + } + } + + if (fi === fl) { + count++; + break; + } else { + // If it didn't match the right most expression then + // break since it's no point looking at the parents + if (si === sl - 1) { + break; + } + } + + item = item.parent(); + } + } + + // If we found all selectors then return true otherwise continue looking + if (count === sl) { + return true; + } + } + + return false; + }, + + /** + * Returns a tinymce.ui.Collection with matches of the specified selector inside the specified container. + * + * @method find + * @param {tinymce.ui.Control} container Container to look for items in. + * @return {tinymce.ui.Collection} Collection with matched elements. + */ + find: function(container) { + var matches = [], i, l, selectors = this._selectors; + + function collect(items, selector, index) { + var i, l, fi, fl, item, filters = selector[index]; + + for (i = 0, l = items.length; i < l; i++) { + item = items[i]; + + // Run each filter against the item + for (fi = 0, fl = filters.length; fi < fl; fi++) { + if (!filters[fi](item, i, l)) { + fi = fl + 1; + break; + } + } + + // All filters matched the item + if (fi === fl) { + // Matched item is on the last expression like: panel toolbar [button] + if (index == selector.length - 1) { + matches.push(item); + } else { + // Collect next expression type + if (item.items) { + collect(item.items(), selector, index + 1); + } + } + } else if (filters.direct) { + return; + } + + // Collect child items + if (item.items) { + collect(item.items(), selector, index); + } + } + } + + if (container.items) { + for (i = 0, l = selectors.length; i < l; i++) { + collect(container.items(), selectors[i], 0); + } + + // Unique the matches if needed + if (l > 1) { + matches = unique(matches); + } + } + + // Fix for circular reference + if (!Collection) { + // TODO: Fix me! + Collection = Selector.Collection; + } + + return new Collection(matches); + } + }); + + return Selector; +}); + +// Included from: js/tinymce/classes/ui/Collection.js + +/** + * Collection.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Control collection, this class contains control instances and it enables you to + * perform actions on all the contained items. This is very similar to how jQuery works. + * + * @example + * someCollection.show().disabled(true); + * + * @class tinymce.ui.Collection + */ +define("tinymce/ui/Collection", [ + "tinymce/util/Tools", + "tinymce/ui/Selector", + "tinymce/util/Class" +], function(Tools, Selector, Class) { + "use strict"; + + var Collection, proto, push = Array.prototype.push, slice = Array.prototype.slice; + + proto = { + /** + * Current number of contained control instances. + * + * @field length + * @type Number + */ + length: 0, + + /** + * Constructor for the collection. + * + * @constructor + * @method init + * @param {Array} items Optional array with items to add. + */ + init: function(items) { + if (items) { + this.add(items); + } + }, + + /** + * Adds new items to the control collection. + * + * @method add + * @param {Array} items Array if items to add to collection. + * @return {tinymce.ui.Collection} Current collection instance. + */ + add: function(items) { + var self = this; + + // Force single item into array + if (!Tools.isArray(items)) { + if (items instanceof Collection) { + self.add(items.toArray()); + } else { + push.call(self, items); + } + } else { + push.apply(self, items); + } + + return self; + }, + + /** + * Sets the contents of the collection. This will remove any existing items + * and replace them with the ones specified in the input array. + * + * @method set + * @param {Array} items Array with items to set into the Collection. + * @return {tinymce.ui.Collection} Collection instance. + */ + set: function(items) { + var self = this, len = self.length, i; + + self.length = 0; + self.add(items); + + // Remove old entries + for (i = self.length; i < len; i++) { + delete self[i]; + } + + return self; + }, + + /** + * Filters the collection item based on the specified selector expression or selector function. + * + * @method filter + * @param {String} selector Selector expression to filter items by. + * @return {tinymce.ui.Collection} Collection containing the filtered items. + */ + filter: function(selector) { + var self = this, i, l, matches = [], item, match; + + // Compile string into selector expression + if (typeof selector === "string") { + selector = new Selector(selector); + + match = function(item) { + return selector.match(item); + }; + } else { + // Use selector as matching function + match = selector; + } + + for (i = 0, l = self.length; i < l; i++) { + item = self[i]; + + if (match(item)) { + matches.push(item); + } + } + + return new Collection(matches); + }, + + /** + * Slices the items within the collection. + * + * @method slice + * @param {Number} index Index to slice at. + * @param {Number} len Optional length to slice. + * @return {tinymce.ui.Collection} Current collection. + */ + slice: function() { + return new Collection(slice.apply(this, arguments)); + }, + + /** + * Makes the current collection equal to the specified index. + * + * @method eq + * @param {Number} index Index of the item to set the collection to. + * @return {tinymce.ui.Collection} Current collection. + */ + eq: function(index) { + return index === -1 ? this.slice(index) : this.slice(index, +index + 1); + }, + + /** + * Executes the specified callback on each item in collection. + * + * @method each + * @param {function} callback Callback to execute for each item in collection. + * @return {tinymce.ui.Collection} Current collection instance. + */ + each: function(callback) { + Tools.each(this, callback); + + return this; + }, + + /** + * Returns an JavaScript array object of the contents inside the collection. + * + * @method toArray + * @return {Array} Array with all items from collection. + */ + toArray: function() { + return Tools.toArray(this); + }, + + /** + * Finds the index of the specified control or return -1 if it isn't in the collection. + * + * @method indexOf + * @param {Control} ctrl Control instance to look for. + * @return {Number} Index of the specified control or -1. + */ + indexOf: function(ctrl) { + var self = this, i = self.length; + + while (i--) { + if (self[i] === ctrl) { + break; + } + } + + return i; + }, + + /** + * Returns a new collection of the contents in reverse order. + * + * @method reverse + * @return {tinymce.ui.Collection} Collection instance with reversed items. + */ + reverse: function() { + return new Collection(Tools.toArray(this).reverse()); + }, + + /** + * Returns true/false if the class exists or not. + * + * @method hasClass + * @param {String} cls Class to check for. + * @return {Boolean} true/false state if the class exists or not. + */ + hasClass: function(cls) { + return this[0] ? this[0].classes.contains(cls) : false; + }, + + /** + * Sets/gets the specific property on the items in the collection. The same as executing control.<property>(<value>); + * + * @method prop + * @param {String} name Property name to get/set. + * @param {Object} value Optional object value to set. + * @return {tinymce.ui.Collection} Current collection instance or value of the first item on a get operation. + */ + prop: function(name, value) { + var self = this, undef, item; + + if (value !== undef) { + self.each(function(item) { + if (item[name]) { + item[name](value); + } + }); + + return self; + } + + item = self[0]; + + if (item && item[name]) { + return item[name](); + } + }, + + /** + * Executes the specific function name with optional arguments an all items in collection if it exists. + * + * @example collection.exec("myMethod", arg1, arg2, arg3); + * @method exec + * @param {String} name Name of the function to execute. + * @param {Object} ... Multiple arguments to pass to each function. + * @return {tinymce.ui.Collection} Current collection. + */ + exec: function(name) { + var self = this, args = Tools.toArray(arguments).slice(1); + + self.each(function(item) { + if (item[name]) { + item[name].apply(item, args); + } + }); + + return self; + }, + + /** + * Remove all items from collection and DOM. + * + * @method remove + * @return {tinymce.ui.Collection} Current collection. + */ + remove: function() { + var i = this.length; + + while (i--) { + this[i].remove(); + } + + return this; + }, + + /** + * Adds a class to all items in the collection. + * + * @method addClass + * @param {String} cls Class to add to each item. + * @return {tinymce.ui.Collection} Current collection instance. + */ + addClass: function(cls) { + return this.each(function(item) { + item.classes.add(cls); + }); + }, + + /** + * Removes the specified class from all items in collection. + * + * @method removeClass + * @param {String} cls Class to remove from each item. + * @return {tinymce.ui.Collection} Current collection instance. + */ + removeClass: function(cls) { + return this.each(function(item) { + item.classes.remove(cls); + }); + } + + /** + * Fires the specified event by name and arguments on the control. This will execute all + * bound event handlers. + * + * @method fire + * @param {String} name Name of the event to fire. + * @param {Object} args Optional arguments to pass to the event. + * @return {tinymce.ui.Collection} Current collection instance. + */ + // fire: function(event, args) {}, -- Generated by code below + + /** + * Binds a callback to the specified event. This event can both be + * native browser events like "click" or custom ones like PostRender. + * + * The callback function will have two parameters the first one being the control that received the event + * the second one will be the event object either the browsers native event object or a custom JS object. + * + * @method on + * @param {String} name Name of the event to bind. For example "click". + * @param {String/function} callback Callback function to execute ones the event occurs. + * @return {tinymce.ui.Collection} Current collection instance. + */ + // on: function(name, callback) {}, -- Generated by code below + + /** + * Unbinds the specified event and optionally a specific callback. If you omit the name + * parameter all event handlers will be removed. If you omit the callback all event handles + * by the specified name will be removed. + * + * @method off + * @param {String} name Optional name for the event to unbind. + * @param {function} callback Optional callback function to unbind. + * @return {tinymce.ui.Collection} Current collection instance. + */ + // off: function(name, callback) {}, -- Generated by code below + + /** + * Shows the items in the current collection. + * + * @method show + * @return {tinymce.ui.Collection} Current collection instance. + */ + // show: function() {}, -- Generated by code below + + /** + * Hides the items in the current collection. + * + * @method hide + * @return {tinymce.ui.Collection} Current collection instance. + */ + // hide: function() {}, -- Generated by code below + + /** + * Sets/gets the text contents of the items in the current collection. + * + * @method text + * @return {tinymce.ui.Collection} Current collection instance or text value of the first item on a get operation. + */ + // text: function(value) {}, -- Generated by code below + + /** + * Sets/gets the name contents of the items in the current collection. + * + * @method name + * @return {tinymce.ui.Collection} Current collection instance or name value of the first item on a get operation. + */ + // name: function(value) {}, -- Generated by code below + + /** + * Sets/gets the disabled state on the items in the current collection. + * + * @method disabled + * @return {tinymce.ui.Collection} Current collection instance or disabled state of the first item on a get operation. + */ + // disabled: function(state) {}, -- Generated by code below + + /** + * Sets/gets the active state on the items in the current collection. + * + * @method active + * @return {tinymce.ui.Collection} Current collection instance or active state of the first item on a get operation. + */ + // active: function(state) {}, -- Generated by code below + + /** + * Sets/gets the selected state on the items in the current collection. + * + * @method selected + * @return {tinymce.ui.Collection} Current collection instance or selected state of the first item on a get operation. + */ + // selected: function(state) {}, -- Generated by code below + + /** + * Sets/gets the selected state on the items in the current collection. + * + * @method visible + * @return {tinymce.ui.Collection} Current collection instance or visible state of the first item on a get operation. + */ + // visible: function(state) {}, -- Generated by code below + }; + + // Extend tinymce.ui.Collection prototype with some generated control specific methods + Tools.each('fire on off show hide append prepend before after reflow'.split(' '), function(name) { + proto[name] = function() { + var args = Tools.toArray(arguments); + + this.each(function(ctrl) { + if (name in ctrl) { + ctrl[name].apply(ctrl, args); + } + }); + + return this; + }; + }); + + // Extend tinymce.ui.Collection prototype with some property methods + Tools.each('text name disabled active selected checked visible parent value data'.split(' '), function(name) { + proto[name] = function(value) { + return this.prop(name, value); + }; + }); + + // Create class based on the new prototype + Collection = Class.extend(proto); + + // Stick Collection into Selector to prevent circual references + Selector.Collection = Collection; + + return Collection; +}); + +// Included from: js/tinymce/classes/ui/DomUtils.js + +/** + * DomUtils.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Private UI DomUtils proxy. + * + * @private + * @class tinymce.ui.DomUtils + */ +define("tinymce/ui/DomUtils", [ + "tinymce/util/Tools", + "tinymce/dom/DOMUtils" +], function(Tools, DOMUtils) { + "use strict"; + + var count = 0; + + return { + id: function() { + return 'mceu_' + (count++); + }, + + create: function(name, attrs, children) { + var elm = document.createElement(name); + + DOMUtils.DOM.setAttribs(elm, attrs); + + if (typeof children === 'string') { + elm.innerHTML = children; + } else { + Tools.each(children, function(child) { + if (child.nodeType) { + elm.appendChild(child); + } + }); + } + + return elm; + }, + + createFragment: function(html) { + return DOMUtils.DOM.createFragment(html); + }, + + getWindowSize: function() { + return DOMUtils.DOM.getViewPort(); + }, + + getSize: function(elm) { + var width, height; + + if (elm.getBoundingClientRect) { + var rect = elm.getBoundingClientRect(); + + width = Math.max(rect.width || (rect.right - rect.left), elm.offsetWidth); + height = Math.max(rect.height || (rect.bottom - rect.bottom), elm.offsetHeight); + } else { + width = elm.offsetWidth; + height = elm.offsetHeight; + } + + return {width: width, height: height}; + }, + + getPos: function(elm, root) { + return DOMUtils.DOM.getPos(elm, root); + }, + + getViewPort: function(win) { + return DOMUtils.DOM.getViewPort(win); + }, + + get: function(id) { + return document.getElementById(id); + }, + + addClass: function(elm, cls) { + return DOMUtils.DOM.addClass(elm, cls); + }, + + removeClass: function(elm, cls) { + return DOMUtils.DOM.removeClass(elm, cls); + }, + + hasClass: function(elm, cls) { + return DOMUtils.DOM.hasClass(elm, cls); + }, + + toggleClass: function(elm, cls, state) { + return DOMUtils.DOM.toggleClass(elm, cls, state); + }, + + css: function(elm, name, value) { + return DOMUtils.DOM.setStyle(elm, name, value); + }, + + getRuntimeStyle: function(elm, name) { + return DOMUtils.DOM.getStyle(elm, name, true); + }, + + on: function(target, name, callback, scope) { + return DOMUtils.DOM.bind(target, name, callback, scope); + }, + + off: function(target, name, callback) { + return DOMUtils.DOM.unbind(target, name, callback); + }, + + fire: function(target, name, args) { + return DOMUtils.DOM.fire(target, name, args); + }, + + innerHtml: function(elm, html) { + // Workaround for <div> in <p> bug on IE 8 #6178 + DOMUtils.DOM.setHTML(elm, html); + } + }; +}); + +// Included from: js/tinymce/classes/ui/BoxUtils.js + +/** + * BoxUtils.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Utility class for box parsing and measuring. + * + * @private + * @class tinymce.ui.BoxUtils + */ +define("tinymce/ui/BoxUtils", [ +], function() { + "use strict"; + + return { + /** + * Parses the specified box value. A box value contains 1-4 properties in clockwise order. + * + * @method parseBox + * @param {String/Number} value Box value "0 1 2 3" or "0" etc. + * @return {Object} Object with top/right/bottom/left properties. + * @private + */ + parseBox: function(value) { + var len, radix = 10; + + if (!value) { + return; + } + + if (typeof value === "number") { + value = value || 0; + + return { + top: value, + left: value, + bottom: value, + right: value + }; + } + + value = value.split(' '); + len = value.length; + + if (len === 1) { + value[1] = value[2] = value[3] = value[0]; + } else if (len === 2) { + value[2] = value[0]; + value[3] = value[1]; + } else if (len === 3) { + value[3] = value[1]; + } + + return { + top: parseInt(value[0], radix) || 0, + right: parseInt(value[1], radix) || 0, + bottom: parseInt(value[2], radix) || 0, + left: parseInt(value[3], radix) || 0 + }; + }, + + measureBox: function(elm, prefix) { + function getStyle(name) { + var defaultView = document.defaultView; + + if (defaultView) { + // Remove camelcase + name = name.replace(/[A-Z]/g, function(a) { + return '-' + a; + }); + + return defaultView.getComputedStyle(elm, null).getPropertyValue(name); + } + + return elm.currentStyle[name]; + } + + function getSide(name) { + var val = parseFloat(getStyle(name), 10); + + return isNaN(val) ? 0 : val; + } + + return { + top: getSide(prefix + "TopWidth"), + right: getSide(prefix + "RightWidth"), + bottom: getSide(prefix + "BottomWidth"), + left: getSide(prefix + "LeftWidth") + }; + } + }; +}); + +// Included from: js/tinymce/classes/ui/ClassList.js + +/** + * ClassList.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Handles adding and removal of classes. + * + * @private + * @class tinymce.ui.ClassList + */ +define("tinymce/ui/ClassList", [ + "tinymce/util/Tools" +], function(Tools) { + "use strict"; + + function noop() { + } + + /** + * Constructs a new class list the specified onchange + * callback will be executed when the class list gets modifed. + * + * @constructor ClassList + * @param {function} onchange Onchange callback to be executed. + */ + function ClassList(onchange) { + this.cls = []; + this.cls._map = {}; + this.onchange = onchange || noop; + this.prefix = ''; + } + + Tools.extend(ClassList.prototype, { + /** + * Adds a new class to the class list. + * + * @method add + * @param {String} cls Class to be added. + * @return {tinymce.ui.ClassList} Current class list instance. + */ + add: function(cls) { + if (cls && !this.contains(cls)) { + this.cls._map[cls] = true; + this.cls.push(cls); + this._change(); + } + + return this; + }, + + /** + * Removes the specified class from the class list. + * + * @method remove + * @param {String} cls Class to be removed. + * @return {tinymce.ui.ClassList} Current class list instance. + */ + remove: function(cls) { + if (this.contains(cls)) { + for (var i = 0; i < this.cls.length; i++) { + if (this.cls[i] === cls) { + break; + } + } + + this.cls.splice(i, 1); + delete this.cls._map[cls]; + this._change(); + } + + return this; + }, + + /** + * Toggles a class in the class list. + * + * @method toggle + * @param {String} cls Class to be added/removed. + * @param {Boolean} state Optional state if it should be added/removed. + * @return {tinymce.ui.ClassList} Current class list instance. + */ + toggle: function(cls, state) { + var curState = this.contains(cls); + + if (curState !== state) { + if (curState) { + this.remove(cls); + } else { + this.add(cls); + } + + this._change(); + } + + return this; + }, + + /** + * Returns true if the class list has the specified class. + * + * @method contains + * @param {String} cls Class to look for. + * @return {Boolean} true/false if the class exists or not. + */ + contains: function(cls) { + return !!this.cls._map[cls]; + }, + + /** + * Returns a space separated list of classes. + * + * @method toString + * @return {String} Space separated list of classes. + */ + + _change: function() { + delete this.clsValue; + this.onchange.call(this); + } + }); + + // IE 8 compatibility + ClassList.prototype.toString = function() { + var value; + + if (this.clsValue) { + return this.clsValue; + } + + value = ''; + for (var i = 0; i < this.cls.length; i++) { + if (i > 0) { + value += ' '; + } + + value += this.prefix + this.cls[i]; + } + + return value; + }; + + return ClassList; +}); + +// Included from: js/tinymce/classes/ui/ReflowQueue.js + +/** + * ReflowQueue.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class will automatically reflow controls on the next animation frame within a few milliseconds on older browsers. + * If the user manually reflows then the automatic reflow will be cancelled. This class is used internally when various control states + * changes that triggers a reflow. + * + * @class tinymce.ui.ReflowQueue + * @static + */ +define("tinymce/ui/ReflowQueue", [ + "tinymce/util/Delay" +], function(Delay) { + var dirtyCtrls = {}, animationFrameRequested; + + return { + /** + * Adds a control to the next automatic reflow call. This is the control that had a state + * change for example if the control was hidden/shown. + * + * @method add + * @param {tinymce.ui.Control} ctrl Control to add to queue. + */ + add: function(ctrl) { + var parent = ctrl.parent(); + + if (parent) { + if (!parent._layout || parent._layout.isNative()) { + return; + } + + if (!dirtyCtrls[parent._id]) { + dirtyCtrls[parent._id] = parent; + } + + if (!animationFrameRequested) { + animationFrameRequested = true; + + Delay.requestAnimationFrame(function() { + var id, ctrl; + + animationFrameRequested = false; + + for (id in dirtyCtrls) { + ctrl = dirtyCtrls[id]; + + if (ctrl.state.get('rendered')) { + ctrl.reflow(); + } + } + + dirtyCtrls = {}; + }, document.body); + } + } + }, + + /** + * Removes the specified control from the automatic reflow. This will happen when for example the user + * manually triggers a reflow. + * + * @method remove + * @param {tinymce.ui.Control} ctrl Control to remove from queue. + */ + remove: function(ctrl) { + if (dirtyCtrls[ctrl._id]) { + delete dirtyCtrls[ctrl._id]; + } + } + }; +}); + +// Included from: js/tinymce/classes/ui/Control.js + +/** + * Control.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/*eslint consistent-this:0 */ + +/** + * This is the base class for all controls and containers. All UI control instances inherit + * from this one as it has the base logic needed by all of them. + * + * @class tinymce.ui.Control + */ +define("tinymce/ui/Control", [ + "tinymce/util/Class", + "tinymce/util/Tools", + "tinymce/util/EventDispatcher", + "tinymce/data/ObservableObject", + "tinymce/ui/Collection", + "tinymce/ui/DomUtils", + "tinymce/dom/DomQuery", + "tinymce/ui/BoxUtils", + "tinymce/ui/ClassList", + "tinymce/ui/ReflowQueue" +], function(Class, Tools, EventDispatcher, ObservableObject, Collection, DomUtils, $, BoxUtils, ClassList, ReflowQueue) { + "use strict"; + + var hasMouseWheelEventSupport = "onmousewheel" in document; + var hasWheelEventSupport = false; + var classPrefix = "mce-"; + var Control, idCounter = 0; + + var proto = { + Statics: { + classPrefix: classPrefix + }, + + isRtl: function() { + return Control.rtl; + }, + + /** + * Class/id prefix to use for all controls. + * + * @final + * @field {String} classPrefix + */ + classPrefix: classPrefix, + + /** + * Constructs a new control instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + * @setting {String} style Style CSS properties to add. + * @setting {String} border Border box values example: 1 1 1 1 + * @setting {String} padding Padding box values example: 1 1 1 1 + * @setting {String} margin Margin box values example: 1 1 1 1 + * @setting {Number} minWidth Minimal width for the control. + * @setting {Number} minHeight Minimal height for the control. + * @setting {String} classes Space separated list of classes to add. + * @setting {String} role WAI-ARIA role to use for control. + * @setting {Boolean} hidden Is the control hidden by default. + * @setting {Boolean} disabled Is the control disabled by default. + * @setting {String} name Name of the control instance. + */ + init: function(settings) { + var self = this, classes, defaultClasses; + + function applyClasses(classes) { + var i; + + classes = classes.split(' '); + for (i = 0; i < classes.length; i++) { + self.classes.add(classes[i]); + } + } + + self.settings = settings = Tools.extend({}, self.Defaults, settings); + + // Initial states + self._id = settings.id || ('mceu_' + (idCounter++)); + self._aria = {role: settings.role}; + self._elmCache = {}; + self.$ = $; + + self.state = new ObservableObject({ + visible: true, + active: false, + disabled: false, + value: '' + }); + + self.data = new ObservableObject(settings.data); + + self.classes = new ClassList(function() { + if (self.state.get('rendered')) { + self.getEl().className = this.toString(); + } + }); + self.classes.prefix = self.classPrefix; + + // Setup classes + classes = settings.classes; + if (classes) { + if (self.Defaults) { + defaultClasses = self.Defaults.classes; + + if (defaultClasses && classes != defaultClasses) { + applyClasses(defaultClasses); + } + } + + applyClasses(classes); + } + + Tools.each('title text name visible disabled active value'.split(' '), function(name) { + if (name in settings) { + self[name](settings[name]); + } + }); + + self.on('click', function() { + if (self.disabled()) { + return false; + } + }); + + /** + * Name/value object with settings for the current control. + * + * @field {Object} settings + */ + self.settings = settings; + + self.borderBox = BoxUtils.parseBox(settings.border); + self.paddingBox = BoxUtils.parseBox(settings.padding); + self.marginBox = BoxUtils.parseBox(settings.margin); + + if (settings.hidden) { + self.hide(); + } + }, + + // Will generate getter/setter methods for these properties + Properties: 'parent,name', + + /** + * Returns the root element to render controls into. + * + * @method getContainerElm + * @return {Element} HTML DOM element to render into. + */ + getContainerElm: function() { + return document.body; + }, + + /** + * Returns a control instance for the current DOM element. + * + * @method getParentCtrl + * @param {Element} elm HTML dom element to get parent control from. + * @return {tinymce.ui.Control} Control instance or undefined. + */ + getParentCtrl: function(elm) { + var ctrl, lookup = this.getRoot().controlIdLookup; + + while (elm && lookup) { + ctrl = lookup[elm.id]; + if (ctrl) { + break; + } + + elm = elm.parentNode; + } + + return ctrl; + }, + + /** + * Initializes the current controls layout rect. + * This will be executed by the layout managers to determine the + * default minWidth/minHeight etc. + * + * @method initLayoutRect + * @return {Object} Layout rect instance. + */ + initLayoutRect: function() { + var self = this, settings = self.settings, borderBox, layoutRect; + var elm = self.getEl(), width, height, minWidth, minHeight, autoResize; + var startMinWidth, startMinHeight, initialSize; + + // Measure the current element + borderBox = self.borderBox = self.borderBox || BoxUtils.measureBox(elm, 'border'); + self.paddingBox = self.paddingBox || BoxUtils.measureBox(elm, 'padding'); + self.marginBox = self.marginBox || BoxUtils.measureBox(elm, 'margin'); + initialSize = DomUtils.getSize(elm); + + // Setup minWidth/minHeight and width/height + startMinWidth = settings.minWidth; + startMinHeight = settings.minHeight; + minWidth = startMinWidth || initialSize.width; + minHeight = startMinHeight || initialSize.height; + width = settings.width; + height = settings.height; + autoResize = settings.autoResize; + autoResize = typeof autoResize != "undefined" ? autoResize : !width && !height; + + width = width || minWidth; + height = height || minHeight; + + var deltaW = borderBox.left + borderBox.right; + var deltaH = borderBox.top + borderBox.bottom; + + var maxW = settings.maxWidth || 0xFFFF; + var maxH = settings.maxHeight || 0xFFFF; + + // Setup initial layout rect + self._layoutRect = layoutRect = { + x: settings.x || 0, + y: settings.y || 0, + w: width, + h: height, + deltaW: deltaW, + deltaH: deltaH, + contentW: width - deltaW, + contentH: height - deltaH, + innerW: width - deltaW, + innerH: height - deltaH, + startMinWidth: startMinWidth || 0, + startMinHeight: startMinHeight || 0, + minW: Math.min(minWidth, maxW), + minH: Math.min(minHeight, maxH), + maxW: maxW, + maxH: maxH, + autoResize: autoResize, + scrollW: 0 + }; + + self._lastLayoutRect = {}; + + return layoutRect; + }, + + /** + * Getter/setter for the current layout rect. + * + * @method layoutRect + * @param {Object} [newRect] Optional new layout rect. + * @return {tinymce.ui.Control/Object} Current control or rect object. + */ + layoutRect: function(newRect) { + var self = this, curRect = self._layoutRect, lastLayoutRect, size, deltaWidth, deltaHeight, undef, repaintControls; + + // Initialize default layout rect + if (!curRect) { + curRect = self.initLayoutRect(); + } + + // Set new rect values + if (newRect) { + // Calc deltas between inner and outer sizes + deltaWidth = curRect.deltaW; + deltaHeight = curRect.deltaH; + + // Set x position + if (newRect.x !== undef) { + curRect.x = newRect.x; + } + + // Set y position + if (newRect.y !== undef) { + curRect.y = newRect.y; + } + + // Set minW + if (newRect.minW !== undef) { + curRect.minW = newRect.minW; + } + + // Set minH + if (newRect.minH !== undef) { + curRect.minH = newRect.minH; + } + + // Set new width and calculate inner width + size = newRect.w; + if (size !== undef) { + size = size < curRect.minW ? curRect.minW : size; + size = size > curRect.maxW ? curRect.maxW : size; + curRect.w = size; + curRect.innerW = size - deltaWidth; + } + + // Set new height and calculate inner height + size = newRect.h; + if (size !== undef) { + size = size < curRect.minH ? curRect.minH : size; + size = size > curRect.maxH ? curRect.maxH : size; + curRect.h = size; + curRect.innerH = size - deltaHeight; + } + + // Set new inner width and calculate width + size = newRect.innerW; + if (size !== undef) { + size = size < curRect.minW - deltaWidth ? curRect.minW - deltaWidth : size; + size = size > curRect.maxW - deltaWidth ? curRect.maxW - deltaWidth : size; + curRect.innerW = size; + curRect.w = size + deltaWidth; + } + + // Set new height and calculate inner height + size = newRect.innerH; + if (size !== undef) { + size = size < curRect.minH - deltaHeight ? curRect.minH - deltaHeight : size; + size = size > curRect.maxH - deltaHeight ? curRect.maxH - deltaHeight : size; + curRect.innerH = size; + curRect.h = size + deltaHeight; + } + + // Set new contentW + if (newRect.contentW !== undef) { + curRect.contentW = newRect.contentW; + } + + // Set new contentH + if (newRect.contentH !== undef) { + curRect.contentH = newRect.contentH; + } + + // Compare last layout rect with the current one to see if we need to repaint or not + lastLayoutRect = self._lastLayoutRect; + if (lastLayoutRect.x !== curRect.x || lastLayoutRect.y !== curRect.y || + lastLayoutRect.w !== curRect.w || lastLayoutRect.h !== curRect.h) { + repaintControls = Control.repaintControls; + + if (repaintControls) { + if (repaintControls.map && !repaintControls.map[self._id]) { + repaintControls.push(self); + repaintControls.map[self._id] = true; + } + } + + lastLayoutRect.x = curRect.x; + lastLayoutRect.y = curRect.y; + lastLayoutRect.w = curRect.w; + lastLayoutRect.h = curRect.h; + } + + return self; + } + + return curRect; + }, + + /** + * Repaints the control after a layout operation. + * + * @method repaint + */ + repaint: function() { + var self = this, style, bodyStyle, bodyElm, rect, borderBox; + var borderW, borderH, lastRepaintRect, round, value; + + // Use Math.round on all values on IE < 9 + round = !document.createRange ? Math.round : function(value) { + return value; + }; + + style = self.getEl().style; + rect = self._layoutRect; + lastRepaintRect = self._lastRepaintRect || {}; + + borderBox = self.borderBox; + borderW = borderBox.left + borderBox.right; + borderH = borderBox.top + borderBox.bottom; + + if (rect.x !== lastRepaintRect.x) { + style.left = round(rect.x) + 'px'; + lastRepaintRect.x = rect.x; + } + + if (rect.y !== lastRepaintRect.y) { + style.top = round(rect.y) + 'px'; + lastRepaintRect.y = rect.y; + } + + if (rect.w !== lastRepaintRect.w) { + value = round(rect.w - borderW); + style.width = (value >= 0 ? value : 0) + 'px'; + lastRepaintRect.w = rect.w; + } + + if (rect.h !== lastRepaintRect.h) { + value = round(rect.h - borderH); + style.height = (value >= 0 ? value : 0) + 'px'; + lastRepaintRect.h = rect.h; + } + + // Update body if needed + if (self._hasBody && rect.innerW !== lastRepaintRect.innerW) { + value = round(rect.innerW); + + bodyElm = self.getEl('body'); + if (bodyElm) { + bodyStyle = bodyElm.style; + bodyStyle.width = (value >= 0 ? value : 0) + 'px'; + } + + lastRepaintRect.innerW = rect.innerW; + } + + if (self._hasBody && rect.innerH !== lastRepaintRect.innerH) { + value = round(rect.innerH); + + bodyElm = bodyElm || self.getEl('body'); + if (bodyElm) { + bodyStyle = bodyStyle || bodyElm.style; + bodyStyle.height = (value >= 0 ? value : 0) + 'px'; + } + + lastRepaintRect.innerH = rect.innerH; + } + + self._lastRepaintRect = lastRepaintRect; + self.fire('repaint', {}, false); + }, + + /** + * Updates the controls layout rect by re-measuing it. + */ + updateLayoutRect: function() { + var self = this; + + self.parent()._lastRect = null; + + DomUtils.css(self.getEl(), {width: '', height: ''}); + + self._layoutRect = self._lastRepaintRect = self._lastLayoutRect = null; + self.initLayoutRect(); + }, + + /** + * Binds a callback to the specified event. This event can both be + * native browser events like "click" or custom ones like PostRender. + * + * The callback function will be passed a DOM event like object that enables yout do stop propagation. + * + * @method on + * @param {String} name Name of the event to bind. For example "click". + * @param {String/function} callback Callback function to execute ones the event occurs. + * @return {tinymce.ui.Control} Current control object. + */ + on: function(name, callback) { + var self = this; + + function resolveCallbackName(name) { + var callback, scope; + + if (typeof name != 'string') { + return name; + } + + return function(e) { + if (!callback) { + self.parentsAndSelf().each(function(ctrl) { + var callbacks = ctrl.settings.callbacks; + + if (callbacks && (callback = callbacks[name])) { + scope = ctrl; + return false; + } + }); + } + + if (!callback) { + e.action = name; + this.fire('execute', e); + return; + } + + return callback.call(scope, e); + }; + } + + getEventDispatcher(self).on(name, resolveCallbackName(callback)); + + return self; + }, + + /** + * Unbinds the specified event and optionally a specific callback. If you omit the name + * parameter all event handlers will be removed. If you omit the callback all event handles + * by the specified name will be removed. + * + * @method off + * @param {String} [name] Name for the event to unbind. + * @param {function} [callback] Callback function to unbind. + * @return {tinymce.ui.Control} Current control object. + */ + off: function(name, callback) { + getEventDispatcher(this).off(name, callback); + return this; + }, + + /** + * Fires the specified event by name and arguments on the control. This will execute all + * bound event handlers. + * + * @method fire + * @param {String} name Name of the event to fire. + * @param {Object} [args] Arguments to pass to the event. + * @param {Boolean} [bubble] Value to control bubbling. Defaults to true. + * @return {Object} Current arguments object. + */ + fire: function(name, args, bubble) { + var self = this; + + args = args || {}; + + if (!args.control) { + args.control = self; + } + + args = getEventDispatcher(self).fire(name, args); + + // Bubble event up to parents + if (bubble !== false && self.parent) { + var parent = self.parent(); + while (parent && !args.isPropagationStopped()) { + parent.fire(name, args, false); + parent = parent.parent(); + } + } + + return args; + }, + + /** + * Returns true/false if the specified event has any listeners. + * + * @method hasEventListeners + * @param {String} name Name of the event to check for. + * @return {Boolean} True/false state if the event has listeners. + */ + hasEventListeners: function(name) { + return getEventDispatcher(this).has(name); + }, + + /** + * Returns a control collection with all parent controls. + * + * @method parents + * @param {String} selector Optional selector expression to find parents. + * @return {tinymce.ui.Collection} Collection with all parent controls. + */ + parents: function(selector) { + var self = this, ctrl, parents = new Collection(); + + // Add each parent to collection + for (ctrl = self.parent(); ctrl; ctrl = ctrl.parent()) { + parents.add(ctrl); + } + + // Filter away everything that doesn't match the selector + if (selector) { + parents = parents.filter(selector); + } + + return parents; + }, + + /** + * Returns the current control and it's parents. + * + * @method parentsAndSelf + * @param {String} selector Optional selector expression to find parents. + * @return {tinymce.ui.Collection} Collection with all parent controls. + */ + parentsAndSelf: function(selector) { + return new Collection(this).add(this.parents(selector)); + }, + + /** + * Returns the control next to the current control. + * + * @method next + * @return {tinymce.ui.Control} Next control instance. + */ + next: function() { + var parentControls = this.parent().items(); + + return parentControls[parentControls.indexOf(this) + 1]; + }, + + /** + * Returns the control previous to the current control. + * + * @method prev + * @return {tinymce.ui.Control} Previous control instance. + */ + prev: function() { + var parentControls = this.parent().items(); + + return parentControls[parentControls.indexOf(this) - 1]; + }, + + /** + * Sets the inner HTML of the control element. + * + * @method innerHtml + * @param {String} html Html string to set as inner html. + * @return {tinymce.ui.Control} Current control object. + */ + innerHtml: function(html) { + this.$el.html(html); + return this; + }, + + /** + * Returns the control DOM element or sub element. + * + * @method getEl + * @param {String} [suffix] Suffix to get element by. + * @return {Element} HTML DOM element for the current control or it's children. + */ + getEl: function(suffix) { + var id = suffix ? this._id + '-' + suffix : this._id; + + if (!this._elmCache[id]) { + this._elmCache[id] = $('#' + id)[0]; + } + + return this._elmCache[id]; + }, + + /** + * Sets the visible state to true. + * + * @method show + * @return {tinymce.ui.Control} Current control instance. + */ + show: function() { + return this.visible(true); + }, + + /** + * Sets the visible state to false. + * + * @method hide + * @return {tinymce.ui.Control} Current control instance. + */ + hide: function() { + return this.visible(false); + }, + + /** + * Focuses the current control. + * + * @method focus + * @return {tinymce.ui.Control} Current control instance. + */ + focus: function() { + try { + this.getEl().focus(); + } catch (ex) { + // Ignore IE error + } + + return this; + }, + + /** + * Blurs the current control. + * + * @method blur + * @return {tinymce.ui.Control} Current control instance. + */ + blur: function() { + this.getEl().blur(); + + return this; + }, + + /** + * Sets the specified aria property. + * + * @method aria + * @param {String} name Name of the aria property to set. + * @param {String} value Value of the aria property. + * @return {tinymce.ui.Control} Current control instance. + */ + aria: function(name, value) { + var self = this, elm = self.getEl(self.ariaTarget); + + if (typeof value === "undefined") { + return self._aria[name]; + } + + self._aria[name] = value; + + if (self.state.get('rendered')) { + elm.setAttribute(name == 'role' ? name : 'aria-' + name, value); + } + + return self; + }, + + /** + * Encodes the specified string with HTML entities. It will also + * translate the string to different languages. + * + * @method encode + * @param {String/Object/Array} text Text to entity encode. + * @param {Boolean} [translate=true] False if the contents shouldn't be translated. + * @return {String} Encoded and possible traslated string. + */ + encode: function(text, translate) { + if (translate !== false) { + text = this.translate(text); + } + + return (text || '').replace(/[&<>"]/g, function(match) { + return '&#' + match.charCodeAt(0) + ';'; + }); + }, + + /** + * Returns the translated string. + * + * @method translate + * @param {String} text Text to translate. + * @return {String} Translated string or the same as the input. + */ + translate: function(text) { + return Control.translate ? Control.translate(text) : text; + }, + + /** + * Adds items before the current control. + * + * @method before + * @param {Array/tinymce.ui.Collection} items Array of items to prepend before this control. + * @return {tinymce.ui.Control} Current control instance. + */ + before: function(items) { + var self = this, parent = self.parent(); + + if (parent) { + parent.insert(items, parent.items().indexOf(self), true); + } + + return self; + }, + + /** + * Adds items after the current control. + * + * @method after + * @param {Array/tinymce.ui.Collection} items Array of items to append after this control. + * @return {tinymce.ui.Control} Current control instance. + */ + after: function(items) { + var self = this, parent = self.parent(); + + if (parent) { + parent.insert(items, parent.items().indexOf(self)); + } + + return self; + }, + + /** + * Removes the current control from DOM and from UI collections. + * + * @method remove + * @return {tinymce.ui.Control} Current control instance. + */ + remove: function() { + var self = this, elm = self.getEl(), parent = self.parent(), newItems, i; + + if (self.items) { + var controls = self.items().toArray(); + i = controls.length; + while (i--) { + controls[i].remove(); + } + } + + if (parent && parent.items) { + newItems = []; + + parent.items().each(function(item) { + if (item !== self) { + newItems.push(item); + } + }); + + parent.items().set(newItems); + parent._lastRect = null; + } + + if (self._eventsRoot && self._eventsRoot == self) { + $(elm).off(); + } + + var lookup = self.getRoot().controlIdLookup; + if (lookup) { + delete lookup[self._id]; + } + + if (elm && elm.parentNode) { + elm.parentNode.removeChild(elm); + } + + self.state.set('rendered', false); + self.state.destroy(); + + self.fire('remove'); + + return self; + }, + + /** + * Renders the control before the specified element. + * + * @method renderBefore + * @param {Element} elm Element to render before. + * @return {tinymce.ui.Control} Current control instance. + */ + renderBefore: function(elm) { + $(elm).before(this.renderHtml()); + this.postRender(); + return this; + }, + + /** + * Renders the control to the specified element. + * + * @method renderBefore + * @param {Element} elm Element to render to. + * @return {tinymce.ui.Control} Current control instance. + */ + renderTo: function(elm) { + $(elm || this.getContainerElm()).append(this.renderHtml()); + this.postRender(); + return this; + }, + + preRender: function() { + }, + + render: function() { + }, + + renderHtml: function() { + return '<div id="' + this._id + '" class="' + this.classes + '"></div>'; + }, + + /** + * Post render method. Called after the control has been rendered to the target. + * + * @method postRender + * @return {tinymce.ui.Control} Current control instance. + */ + postRender: function() { + var self = this, settings = self.settings, elm, box, parent, name, parentEventsRoot; + + self.$el = $(self.getEl()); + self.state.set('rendered', true); + + // Bind on<event> settings + for (name in settings) { + if (name.indexOf("on") === 0) { + self.on(name.substr(2), settings[name]); + } + } + + if (self._eventsRoot) { + for (parent = self.parent(); !parentEventsRoot && parent; parent = parent.parent()) { + parentEventsRoot = parent._eventsRoot; + } + + if (parentEventsRoot) { + for (name in parentEventsRoot._nativeEvents) { + self._nativeEvents[name] = true; + } + } + } + + bindPendingEvents(self); + + if (settings.style) { + elm = self.getEl(); + if (elm) { + elm.setAttribute('style', settings.style); + elm.style.cssText = settings.style; + } + } + + if (self.settings.border) { + box = self.borderBox; + self.$el.css({ + 'border-top-width': box.top, + 'border-right-width': box.right, + 'border-bottom-width': box.bottom, + 'border-left-width': box.left + }); + } + + // Add instance to lookup + var root = self.getRoot(); + if (!root.controlIdLookup) { + root.controlIdLookup = {}; + } + + root.controlIdLookup[self._id] = self; + + for (var key in self._aria) { + self.aria(key, self._aria[key]); + } + + if (self.state.get('visible') === false) { + self.getEl().style.display = 'none'; + } + + self.bindStates(); + + self.state.on('change:visible', function(e) { + var state = e.value, parentCtrl; + + if (self.state.get('rendered')) { + self.getEl().style.display = state === false ? 'none' : ''; + + // Need to force a reflow here on IE 8 + self.getEl().getBoundingClientRect(); + } + + // Parent container needs to reflow + parentCtrl = self.parent(); + if (parentCtrl) { + parentCtrl._lastRect = null; + } + + self.fire(state ? 'show' : 'hide'); + + ReflowQueue.add(self); + }); + + self.fire('postrender', {}, false); + }, + + bindStates: function() { + }, + + /** + * Scrolls the current control into view. + * + * @method scrollIntoView + * @param {String} align Alignment in view top|center|bottom. + * @return {tinymce.ui.Control} Current control instance. + */ + scrollIntoView: function(align) { + function getOffset(elm, rootElm) { + var x, y, parent = elm; + + x = y = 0; + while (parent && parent != rootElm && parent.nodeType) { + x += parent.offsetLeft || 0; + y += parent.offsetTop || 0; + parent = parent.offsetParent; + } + + return {x: x, y: y}; + } + + var elm = this.getEl(), parentElm = elm.parentNode; + var x, y, width, height, parentWidth, parentHeight; + var pos = getOffset(elm, parentElm); + + x = pos.x; + y = pos.y; + width = elm.offsetWidth; + height = elm.offsetHeight; + parentWidth = parentElm.clientWidth; + parentHeight = parentElm.clientHeight; + + if (align == "end") { + x -= parentWidth - width; + y -= parentHeight - height; + } else if (align == "center") { + x -= (parentWidth / 2) - (width / 2); + y -= (parentHeight / 2) - (height / 2); + } + + parentElm.scrollLeft = x; + parentElm.scrollTop = y; + + return this; + }, + + getRoot: function() { + var ctrl = this, rootControl, parents = []; + + while (ctrl) { + if (ctrl.rootControl) { + rootControl = ctrl.rootControl; + break; + } + + parents.push(ctrl); + rootControl = ctrl; + ctrl = ctrl.parent(); + } + + if (!rootControl) { + rootControl = this; + } + + var i = parents.length; + while (i--) { + parents[i].rootControl = rootControl; + } + + return rootControl; + }, + + /** + * Reflows the current control and it's parents. + * This should be used after you for example append children to the current control so + * that the layout managers know that they need to reposition everything. + * + * @example + * container.append({type: 'button', text: 'My button'}).reflow(); + * + * @method reflow + * @return {tinymce.ui.Control} Current control instance. + */ + reflow: function() { + ReflowQueue.remove(this); + + var parent = this.parent(); + if (parent._layout && !parent._layout.isNative()) { + parent.reflow(); + } + + return this; + } + + /** + * Sets/gets the parent container for the control. + * + * @method parent + * @param {tinymce.ui.Container} parent Optional parent to set. + * @return {tinymce.ui.Control} Parent control or the current control on a set action. + */ + // parent: function(parent) {} -- Generated + + /** + * Sets/gets the text for the control. + * + * @method text + * @param {String} value Value to set to control. + * @return {String/tinymce.ui.Control} Current control on a set operation or current value on a get. + */ + // text: function(value) {} -- Generated + + /** + * Sets/gets the disabled state on the control. + * + * @method disabled + * @param {Boolean} state Value to set to control. + * @return {Boolean/tinymce.ui.Control} Current control on a set operation or current state on a get. + */ + // disabled: function(state) {} -- Generated + + /** + * Sets/gets the active for the control. + * + * @method active + * @param {Boolean} state Value to set to control. + * @return {Boolean/tinymce.ui.Control} Current control on a set operation or current state on a get. + */ + // active: function(state) {} -- Generated + + /** + * Sets/gets the name for the control. + * + * @method name + * @param {String} value Value to set to control. + * @return {String/tinymce.ui.Control} Current control on a set operation or current value on a get. + */ + // name: function(value) {} -- Generated + + /** + * Sets/gets the title for the control. + * + * @method title + * @param {String} value Value to set to control. + * @return {String/tinymce.ui.Control} Current control on a set operation or current value on a get. + */ + // title: function(value) {} -- Generated + + /** + * Sets/gets the visible for the control. + * + * @method visible + * @param {Boolean} state Value to set to control. + * @return {Boolean/tinymce.ui.Control} Current control on a set operation or current state on a get. + */ + // visible: function(value) {} -- Generated + }; + + /** + * Setup state properties. + */ + Tools.each('text title visible disabled active value'.split(' '), function(name) { + proto[name] = function(value) { + if (arguments.length === 0) { + return this.state.get(name); + } + + if (typeof value != "undefined") { + this.state.set(name, value); + } + + return this; + }; + }); + + Control = Class.extend(proto); + + function getEventDispatcher(obj) { + if (!obj._eventDispatcher) { + obj._eventDispatcher = new EventDispatcher({ + scope: obj, + toggleEvent: function(name, state) { + if (state && EventDispatcher.isNative(name)) { + if (!obj._nativeEvents) { + obj._nativeEvents = {}; + } + + obj._nativeEvents[name] = true; + + if (obj.state.get('rendered')) { + bindPendingEvents(obj); + } + } + } + }); + } + + return obj._eventDispatcher; + } + + function bindPendingEvents(eventCtrl) { + var i, l, parents, eventRootCtrl, nativeEvents, name; + + function delegate(e) { + var control = eventCtrl.getParentCtrl(e.target); + + if (control) { + control.fire(e.type, e); + } + } + + function mouseLeaveHandler() { + var ctrl = eventRootCtrl._lastHoverCtrl; + + if (ctrl) { + ctrl.fire("mouseleave", {target: ctrl.getEl()}); + + ctrl.parents().each(function(ctrl) { + ctrl.fire("mouseleave", {target: ctrl.getEl()}); + }); + + eventRootCtrl._lastHoverCtrl = null; + } + } + + function mouseEnterHandler(e) { + var ctrl = eventCtrl.getParentCtrl(e.target), lastCtrl = eventRootCtrl._lastHoverCtrl, idx = 0, i, parents, lastParents; + + // Over on a new control + if (ctrl !== lastCtrl) { + eventRootCtrl._lastHoverCtrl = ctrl; + + parents = ctrl.parents().toArray().reverse(); + parents.push(ctrl); + + if (lastCtrl) { + lastParents = lastCtrl.parents().toArray().reverse(); + lastParents.push(lastCtrl); + + for (idx = 0; idx < lastParents.length; idx++) { + if (parents[idx] !== lastParents[idx]) { + break; + } + } + + for (i = lastParents.length - 1; i >= idx; i--) { + lastCtrl = lastParents[i]; + lastCtrl.fire("mouseleave", { + target: lastCtrl.getEl() + }); + } + } + + for (i = idx; i < parents.length; i++) { + ctrl = parents[i]; + ctrl.fire("mouseenter", { + target: ctrl.getEl() + }); + } + } + } + + function fixWheelEvent(e) { + e.preventDefault(); + + if (e.type == "mousewheel") { + e.deltaY = -1 / 40 * e.wheelDelta; + + if (e.wheelDeltaX) { + e.deltaX = -1 / 40 * e.wheelDeltaX; + } + } else { + e.deltaX = 0; + e.deltaY = e.detail; + } + + e = eventCtrl.fire("wheel", e); + } + + nativeEvents = eventCtrl._nativeEvents; + if (nativeEvents) { + // Find event root element if it exists + parents = eventCtrl.parents().toArray(); + parents.unshift(eventCtrl); + for (i = 0, l = parents.length; !eventRootCtrl && i < l; i++) { + eventRootCtrl = parents[i]._eventsRoot; + } + + // Event root wasn't found the use the root control + if (!eventRootCtrl) { + eventRootCtrl = parents[parents.length - 1] || eventCtrl; + } + + // Set the eventsRoot property on children that didn't have it + eventCtrl._eventsRoot = eventRootCtrl; + for (l = i, i = 0; i < l; i++) { + parents[i]._eventsRoot = eventRootCtrl; + } + + var eventRootDelegates = eventRootCtrl._delegates; + if (!eventRootDelegates) { + eventRootDelegates = eventRootCtrl._delegates = {}; + } + + // Bind native event delegates + for (name in nativeEvents) { + if (!nativeEvents) { + return false; + } + + if (name === "wheel" && !hasWheelEventSupport) { + if (hasMouseWheelEventSupport) { + $(eventCtrl.getEl()).on("mousewheel", fixWheelEvent); + } else { + $(eventCtrl.getEl()).on("DOMMouseScroll", fixWheelEvent); + } + + continue; + } + + // Special treatment for mousenter/mouseleave since these doesn't bubble + if (name === "mouseenter" || name === "mouseleave") { + // Fake mousenter/mouseleave + if (!eventRootCtrl._hasMouseEnter) { + $(eventRootCtrl.getEl()).on("mouseleave", mouseLeaveHandler).on("mouseover", mouseEnterHandler); + eventRootCtrl._hasMouseEnter = 1; + } + } else if (!eventRootDelegates[name]) { + $(eventRootCtrl.getEl()).on(name, delegate); + eventRootDelegates[name] = true; + } + + // Remove the event once it's bound + nativeEvents[name] = false; + } + } + } + + return Control; +}); + +// Included from: js/tinymce/classes/ui/Factory.js + +/** + * Factory.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/*global tinymce:true */ + +/** + * This class is a factory for control instances. This enables you + * to create instances of controls without having to require the UI controls directly. + * + * It also allow you to override or add new control types. + * + * @class tinymce.ui.Factory + */ +define("tinymce/ui/Factory", [], function() { + "use strict"; + + var types = {}, namespaceInit; + + return { + /** + * Adds a new control instance type to the factory. + * + * @method add + * @param {String} type Type name for example "button". + * @param {function} typeClass Class type function. + */ + add: function(type, typeClass) { + types[type.toLowerCase()] = typeClass; + }, + + /** + * Returns true/false if the specified type exists or not. + * + * @method has + * @param {String} type Type to look for. + * @return {Boolean} true/false if the control by name exists. + */ + has: function(type) { + return !!types[type.toLowerCase()]; + }, + + /** + * Creates a new control instance based on the settings provided. The instance created will be + * based on the specified type property it can also create whole structures of components out of + * the specified JSON object. + * + * @example + * tinymce.ui.Factory.create({ + * type: 'button', + * text: 'Hello world!' + * }); + * + * @method create + * @param {Object/String} settings Name/Value object with items used to create the type. + * @return {tinymce.ui.Control} Control instance based on the specified type. + */ + create: function(type, settings) { + var ControlType, name, namespace; + + // Build type lookup + if (!namespaceInit) { + namespace = tinymce.ui; + + for (name in namespace) { + types[name.toLowerCase()] = namespace[name]; + } + + namespaceInit = true; + } + + // If string is specified then use it as the type + if (typeof type == 'string') { + settings = settings || {}; + settings.type = type; + } else { + settings = type; + type = settings.type; + } + + // Find control type + type = type.toLowerCase(); + ControlType = types[type]; + + // #if debug + + if (!ControlType) { + throw new Error("Could not find control by type: " + type); + } + + // #endif + + ControlType = new ControlType(settings); + ControlType.type = type; // Set the type on the instance, this will be used by the Selector engine + + return ControlType; + } + }; +}); + +// Included from: js/tinymce/classes/ui/KeyboardNavigation.js + +/** + * KeyboardNavigation.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class handles keyboard navigation of controls and elements. + * + * @class tinymce.ui.KeyboardNavigation + */ +define("tinymce/ui/KeyboardNavigation", [ +], function() { + "use strict"; + + /** + * This class handles all keyboard navigation for WAI-ARIA support. Each root container + * gets an instance of this class. + * + * @constructor + */ + return function(settings) { + var root = settings.root, focusedElement, focusedControl; + + function isElement(node) { + return node && node.nodeType === 1; + } + + try { + focusedElement = document.activeElement; + } catch (ex) { + // IE sometimes fails to return a proper element + focusedElement = document.body; + } + + focusedControl = root.getParentCtrl(focusedElement); + + /** + * Returns the currently focused elements wai aria role of the currently + * focused element or specified element. + * + * @private + * @param {Element} elm Optional element to get role from. + * @return {String} Role of specified element. + */ + function getRole(elm) { + elm = elm || focusedElement; + + if (isElement(elm)) { + return elm.getAttribute('role'); + } + + return null; + } + + /** + * Returns the wai role of the parent element of the currently + * focused element or specified element. + * + * @private + * @param {Element} elm Optional element to get parent role from. + * @return {String} Role of the first parent that has a role. + */ + function getParentRole(elm) { + var role, parent = elm || focusedElement; + + while ((parent = parent.parentNode)) { + if ((role = getRole(parent))) { + return role; + } + } + } + + /** + * Returns a wai aria property by name for example aria-selected. + * + * @private + * @param {String} name Name of the aria property to get for example "disabled". + * @return {String} Aria property value. + */ + function getAriaProp(name) { + var elm = focusedElement; + + if (isElement(elm)) { + return elm.getAttribute('aria-' + name); + } + } + + /** + * Is the element a text input element or not. + * + * @private + * @param {Element} elm Element to check if it's an text input element or not. + * @return {Boolean} True/false if the element is a text element or not. + */ + function isTextInputElement(elm) { + var tagName = elm.tagName.toUpperCase(); + + // Notice: since type can be "email" etc we don't check the type + // So all input elements gets treated as text input elements + return tagName == "INPUT" || tagName == "TEXTAREA" || tagName == "SELECT"; + } + + /** + * Returns true/false if the specified element can be focused or not. + * + * @private + * @param {Element} elm DOM element to check if it can be focused or not. + * @return {Boolean} True/false if the element can have focus. + */ + function canFocus(elm) { + if (isTextInputElement(elm) && !elm.hidden) { + return true; + } + + if (/^(button|menuitem|checkbox|tab|menuitemcheckbox|option|gridcell|slider)$/.test(getRole(elm))) { + return true; + } + + return false; + } + + /** + * Returns an array of focusable visible elements within the specified container element. + * + * @private + * @param {Element} elm DOM element to find focusable elements within. + * @return {Array} Array of focusable elements. + */ + function getFocusElements(elm) { + var elements = []; + + function collect(elm) { + if (elm.nodeType != 1 || elm.style.display == 'none') { + return; + } + + if (canFocus(elm)) { + elements.push(elm); + } + + for (var i = 0; i < elm.childNodes.length; i++) { + collect(elm.childNodes[i]); + } + } + + collect(elm || root.getEl()); + + return elements; + } + + /** + * Returns the navigation root control for the specified control. The navigation root + * is the control that the keyboard navigation gets scoped to for example a menubar or toolbar group. + * It will look for parents of the specified target control or the currently focused control if this option is omitted. + * + * @private + * @param {tinymce.ui.Control} targetControl Optional target control to find root of. + * @return {tinymce.ui.Control} Navigation root control. + */ + function getNavigationRoot(targetControl) { + var navigationRoot, controls; + + targetControl = targetControl || focusedControl; + controls = targetControl.parents().toArray(); + controls.unshift(targetControl); + + for (var i = 0; i < controls.length; i++) { + navigationRoot = controls[i]; + + if (navigationRoot.settings.ariaRoot) { + break; + } + } + + return navigationRoot; + } + + /** + * Focuses the first item in the specified targetControl element or the last aria index if the + * navigation root has the ariaRemember option enabled. + * + * @private + * @param {tinymce.ui.Control} targetControl Target control to focus the first item in. + */ + function focusFirst(targetControl) { + var navigationRoot = getNavigationRoot(targetControl); + var focusElements = getFocusElements(navigationRoot.getEl()); + + if (navigationRoot.settings.ariaRemember && "lastAriaIndex" in navigationRoot) { + moveFocusToIndex(navigationRoot.lastAriaIndex, focusElements); + } else { + moveFocusToIndex(0, focusElements); + } + } + + /** + * Moves the focus to the specified index within the elements list. + * This will scope the index to the size of the element list if it changed. + * + * @private + * @param {Number} idx Specified index to move to. + * @param {Array} elements Array with dom elements to move focus within. + * @return {Number} Input index or a changed index if it was out of range. + */ + function moveFocusToIndex(idx, elements) { + if (idx < 0) { + idx = elements.length - 1; + } else if (idx >= elements.length) { + idx = 0; + } + + if (elements[idx]) { + elements[idx].focus(); + } + + return idx; + } + + /** + * Moves the focus forwards or backwards. + * + * @private + * @param {Number} dir Direction to move in positive means forward, negative means backwards. + * @param {Array} elements Optional array of elements to move within defaults to the current navigation roots elements. + */ + function moveFocus(dir, elements) { + var idx = -1, navigationRoot = getNavigationRoot(); + + elements = elements || getFocusElements(navigationRoot.getEl()); + + for (var i = 0; i < elements.length; i++) { + if (elements[i] === focusedElement) { + idx = i; + } + } + + idx += dir; + navigationRoot.lastAriaIndex = moveFocusToIndex(idx, elements); + } + + /** + * Moves the focus to the left this is called by the left key. + * + * @private + */ + function left() { + var parentRole = getParentRole(); + + if (parentRole == "tablist") { + moveFocus(-1, getFocusElements(focusedElement.parentNode)); + } else if (focusedControl.parent().submenu) { + cancel(); + } else { + moveFocus(-1); + } + } + + /** + * Moves the focus to the right this is called by the right key. + * + * @private + */ + function right() { + var role = getRole(), parentRole = getParentRole(); + + if (parentRole == "tablist") { + moveFocus(1, getFocusElements(focusedElement.parentNode)); + } else if (role == "menuitem" && parentRole == "menu" && getAriaProp('haspopup')) { + enter(); + } else { + moveFocus(1); + } + } + + /** + * Moves the focus to the up this is called by the up key. + * + * @private + */ + function up() { + moveFocus(-1); + } + + /** + * Moves the focus to the up this is called by the down key. + * + * @private + */ + function down() { + var role = getRole(), parentRole = getParentRole(); + + if (role == "menuitem" && parentRole == "menubar") { + enter(); + } else if (role == "button" && getAriaProp('haspopup')) { + enter({key: 'down'}); + } else { + moveFocus(1); + } + } + + /** + * Moves the focus to the next item or previous item depending on shift key. + * + * @private + * @param {DOMEvent} e DOM event object. + */ + function tab(e) { + var parentRole = getParentRole(); + + if (parentRole == "tablist") { + var elm = getFocusElements(focusedControl.getEl('body'))[0]; + + if (elm) { + elm.focus(); + } + } else { + moveFocus(e.shiftKey ? -1 : 1); + } + } + + /** + * Calls the cancel event on the currently focused control. This is normally done using the Esc key. + * + * @private + */ + function cancel() { + focusedControl.fire('cancel'); + } + + /** + * Calls the click event on the currently focused control. This is normally done using the Enter/Space keys. + * + * @private + * @param {Object} aria Optional aria data to pass along with the enter event. + */ + function enter(aria) { + aria = aria || {}; + focusedControl.fire('click', {target: focusedElement, aria: aria}); + } + + root.on('keydown', function(e) { + function handleNonTabOrEscEvent(e, handler) { + // Ignore non tab keys for text elements + if (isTextInputElement(focusedElement)) { + return; + } + + if (getRole(focusedElement) === 'slider') { + return; + } + + if (handler(e) !== false) { + e.preventDefault(); + } + } + + if (e.isDefaultPrevented()) { + return; + } + + switch (e.keyCode) { + case 37: // DOM_VK_LEFT + handleNonTabOrEscEvent(e, left); + break; + + case 39: // DOM_VK_RIGHT + handleNonTabOrEscEvent(e, right); + break; + + case 38: // DOM_VK_UP + handleNonTabOrEscEvent(e, up); + break; + + case 40: // DOM_VK_DOWN + handleNonTabOrEscEvent(e, down); + break; + + case 27: // DOM_VK_ESCAPE + cancel(); + break; + + case 14: // DOM_VK_ENTER + case 13: // DOM_VK_RETURN + case 32: // DOM_VK_SPACE + handleNonTabOrEscEvent(e, enter); + break; + + case 9: // DOM_VK_TAB + if (tab(e) !== false) { + e.preventDefault(); + } + break; + } + }); + + root.on('focusin', function(e) { + focusedElement = e.target; + focusedControl = e.control; + }); + + return { + focusFirst: focusFirst + }; + }; +}); + +// Included from: js/tinymce/classes/ui/Container.js + +/** + * Container.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Container control. This is extended by all controls that can have + * children such as panels etc. You can also use this class directly as an + * generic container instance. The container doesn't have any specific role or style. + * + * @-x-less Container.less + * @class tinymce.ui.Container + * @extends tinymce.ui.Control + */ +define("tinymce/ui/Container", [ + "tinymce/ui/Control", + "tinymce/ui/Collection", + "tinymce/ui/Selector", + "tinymce/ui/Factory", + "tinymce/ui/KeyboardNavigation", + "tinymce/util/Tools", + "tinymce/dom/DomQuery", + "tinymce/ui/ClassList", + "tinymce/ui/ReflowQueue" +], function(Control, Collection, Selector, Factory, KeyboardNavigation, Tools, $, ClassList, ReflowQueue) { + "use strict"; + + var selectorCache = {}; + + return Control.extend({ + /** + * Constructs a new control instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + * @setting {Array} items Items to add to container in JSON format or control instances. + * @setting {String} layout Layout manager by name to use. + * @setting {Object} defaults Default settings to apply to all items. + */ + init: function(settings) { + var self = this; + + self._super(settings); + settings = self.settings; + + if (settings.fixed) { + self.state.set('fixed', true); + } + + self._items = new Collection(); + + if (self.isRtl()) { + self.classes.add('rtl'); + } + + self.bodyClasses = new ClassList(function() { + if (self.state.get('rendered')) { + self.getEl('body').className = this.toString(); + } + }); + self.bodyClasses.prefix = self.classPrefix; + + self.classes.add('container'); + self.bodyClasses.add('container-body'); + + if (settings.containerCls) { + self.classes.add(settings.containerCls); + } + + self._layout = Factory.create((settings.layout || '') + 'layout'); + + if (self.settings.items) { + self.add(self.settings.items); + } else { + self.add(self.render()); + } + + // TODO: Fix this! + self._hasBody = true; + }, + + /** + * Returns a collection of child items that the container currently have. + * + * @method items + * @return {tinymce.ui.Collection} Control collection direct child controls. + */ + items: function() { + return this._items; + }, + + /** + * Find child controls by selector. + * + * @method find + * @param {String} selector Selector CSS pattern to find children by. + * @return {tinymce.ui.Collection} Control collection with child controls. + */ + find: function(selector) { + selector = selectorCache[selector] = selectorCache[selector] || new Selector(selector); + + return selector.find(this); + }, + + /** + * Adds one or many items to the current container. This will create instances of + * the object representations if needed. + * + * @method add + * @param {Array/Object/tinymce.ui.Control} items Array or item that will be added to the container. + * @return {tinymce.ui.Collection} Current collection control. + */ + add: function(items) { + var self = this; + + self.items().add(self.create(items)).parent(self); + + return self; + }, + + /** + * Focuses the current container instance. This will look + * for the first control in the container and focus that. + * + * @method focus + * @param {Boolean} keyboard Optional true/false if the focus was a keyboard focus or not. + * @return {tinymce.ui.Collection} Current instance. + */ + focus: function(keyboard) { + var self = this, focusCtrl, keyboardNav, items; + + if (keyboard) { + keyboardNav = self.keyboardNav || self.parents().eq(-1)[0].keyboardNav; + + if (keyboardNav) { + keyboardNav.focusFirst(self); + return; + } + } + + items = self.find('*'); + + // TODO: Figure out a better way to auto focus alert dialog buttons + if (self.statusbar) { + items.add(self.statusbar.items()); + } + + items.each(function(ctrl) { + if (ctrl.settings.autofocus) { + focusCtrl = null; + return false; + } + + if (ctrl.canFocus) { + focusCtrl = focusCtrl || ctrl; + } + }); + + if (focusCtrl) { + focusCtrl.focus(); + } + + return self; + }, + + /** + * Replaces the specified child control with a new control. + * + * @method replace + * @param {tinymce.ui.Control} oldItem Old item to be replaced. + * @param {tinymce.ui.Control} newItem New item to be inserted. + */ + replace: function(oldItem, newItem) { + var ctrlElm, items = this.items(), i = items.length; + + // Replace the item in collection + while (i--) { + if (items[i] === oldItem) { + items[i] = newItem; + break; + } + } + + if (i >= 0) { + // Remove new item from DOM + ctrlElm = newItem.getEl(); + if (ctrlElm) { + ctrlElm.parentNode.removeChild(ctrlElm); + } + + // Remove old item from DOM + ctrlElm = oldItem.getEl(); + if (ctrlElm) { + ctrlElm.parentNode.removeChild(ctrlElm); + } + } + + // Adopt the item + newItem.parent(this); + }, + + /** + * Creates the specified items. If any of the items is plain JSON style objects + * it will convert these into real tinymce.ui.Control instances. + * + * @method create + * @param {Array} items Array of items to convert into control instances. + * @return {Array} Array with control instances. + */ + create: function(items) { + var self = this, settings, ctrlItems = []; + + // Non array structure, then force it into an array + if (!Tools.isArray(items)) { + items = [items]; + } + + // Add default type to each child control + Tools.each(items, function(item) { + if (item) { + // Construct item if needed + if (!(item instanceof Control)) { + // Name only then convert it to an object + if (typeof item == "string") { + item = {type: item}; + } + + // Create control instance based on input settings and default settings + settings = Tools.extend({}, self.settings.defaults, item); + item.type = settings.type = settings.type || item.type || self.settings.defaultType || + (settings.defaults ? settings.defaults.type : null); + item = Factory.create(settings); + } + + ctrlItems.push(item); + } + }); + + return ctrlItems; + }, + + /** + * Renders new control instances. + * + * @private + */ + renderNew: function() { + var self = this; + + // Render any new items + self.items().each(function(ctrl, index) { + var containerElm; + + ctrl.parent(self); + + if (!ctrl.state.get('rendered')) { + containerElm = self.getEl('body'); + + // Insert or append the item + if (containerElm.hasChildNodes() && index <= containerElm.childNodes.length - 1) { + $(containerElm.childNodes[index]).before(ctrl.renderHtml()); + } else { + $(containerElm).append(ctrl.renderHtml()); + } + + ctrl.postRender(); + ReflowQueue.add(ctrl); + } + }); + + self._layout.applyClasses(self.items().filter(':visible')); + self._lastRect = null; + + return self; + }, + + /** + * Appends new instances to the current container. + * + * @method append + * @param {Array/tinymce.ui.Collection} items Array if controls to append. + * @return {tinymce.ui.Container} Current container instance. + */ + append: function(items) { + return this.add(items).renderNew(); + }, + + /** + * Prepends new instances to the current container. + * + * @method prepend + * @param {Array/tinymce.ui.Collection} items Array if controls to prepend. + * @return {tinymce.ui.Container} Current container instance. + */ + prepend: function(items) { + var self = this; + + self.items().set(self.create(items).concat(self.items().toArray())); + + return self.renderNew(); + }, + + /** + * Inserts an control at a specific index. + * + * @method insert + * @param {Array/tinymce.ui.Collection} items Array if controls to insert. + * @param {Number} index Index to insert controls at. + * @param {Boolean} [before=false] Inserts controls before the index. + */ + insert: function(items, index, before) { + var self = this, curItems, beforeItems, afterItems; + + items = self.create(items); + curItems = self.items(); + + if (!before && index < curItems.length - 1) { + index += 1; + } + + if (index >= 0 && index < curItems.length) { + beforeItems = curItems.slice(0, index).toArray(); + afterItems = curItems.slice(index).toArray(); + curItems.set(beforeItems.concat(items, afterItems)); + } + + return self.renderNew(); + }, + + /** + * Populates the form fields from the specified JSON data object. + * + * Control items in the form that matches the data will have it's value set. + * + * @method fromJSON + * @param {Object} data JSON data object to set control values by. + * @return {tinymce.ui.Container} Current form instance. + */ + fromJSON: function(data) { + var self = this; + + for (var name in data) { + self.find('#' + name).value(data[name]); + } + + return self; + }, + + /** + * Serializes the form into a JSON object by getting all items + * that has a name and a value. + * + * @method toJSON + * @return {Object} JSON object with form data. + */ + toJSON: function() { + var self = this, data = {}; + + self.find('*').each(function(ctrl) { + var name = ctrl.name(), value = ctrl.value(); + + if (name && typeof value != "undefined") { + data[name] = value; + } + }); + + return data; + }, + + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this, layout = self._layout, role = this.settings.role; + + self.preRender(); + layout.preRender(self); + + return ( + '<div id="' + self._id + '" class="' + self.classes + '"' + (role ? ' role="' + this.settings.role + '"' : '') + '>' + + '<div id="' + self._id + '-body" class="' + self.bodyClasses + '">' + + (self.settings.html || '') + layout.renderHtml(self) + + '</div>' + + '</div>' + ); + }, + + /** + * Post render method. Called after the control has been rendered to the target. + * + * @method postRender + * @return {tinymce.ui.Container} Current combobox instance. + */ + postRender: function() { + var self = this, box; + + self.items().exec('postRender'); + self._super(); + + self._layout.postRender(self); + self.state.set('rendered', true); + + if (self.settings.style) { + self.$el.css(self.settings.style); + } + + if (self.settings.border) { + box = self.borderBox; + self.$el.css({ + 'border-top-width': box.top, + 'border-right-width': box.right, + 'border-bottom-width': box.bottom, + 'border-left-width': box.left + }); + } + + if (!self.parent()) { + self.keyboardNav = new KeyboardNavigation({ + root: self + }); + } + + return self; + }, + + /** + * Initializes the current controls layout rect. + * This will be executed by the layout managers to determine the + * default minWidth/minHeight etc. + * + * @method initLayoutRect + * @return {Object} Layout rect instance. + */ + initLayoutRect: function() { + var self = this, layoutRect = self._super(); + + // Recalc container size by asking layout manager + self._layout.recalc(self); + + return layoutRect; + }, + + /** + * Recalculates the positions of the controls in the current container. + * This is invoked by the reflow method and shouldn't be called directly. + * + * @method recalc + */ + recalc: function() { + var self = this, rect = self._layoutRect, lastRect = self._lastRect; + + if (!lastRect || lastRect.w != rect.w || lastRect.h != rect.h) { + self._layout.recalc(self); + rect = self.layoutRect(); + self._lastRect = {x: rect.x, y: rect.y, w: rect.w, h: rect.h}; + return true; + } + }, + + /** + * Reflows the current container and it's children and possible parents. + * This should be used after you for example append children to the current control so + * that the layout managers know that they need to reposition everything. + * + * @example + * container.append({type: 'button', text: 'My button'}).reflow(); + * + * @method reflow + * @return {tinymce.ui.Container} Current container instance. + */ + reflow: function() { + var i; + + ReflowQueue.remove(this); + + if (this.visible()) { + Control.repaintControls = []; + Control.repaintControls.map = {}; + + this.recalc(); + i = Control.repaintControls.length; + + while (i--) { + Control.repaintControls[i].repaint(); + } + + // TODO: Fix me! + if (this.settings.layout !== "flow" && this.settings.layout !== "stack") { + this.repaint(); + } + + Control.repaintControls = []; + } + + return this; + } + }); +}); + +// Included from: js/tinymce/classes/ui/DragHelper.js + +/** + * DragHelper.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Drag/drop helper class. + * + * @example + * var dragHelper = new tinymce.ui.DragHelper('mydiv', { + * start: function(evt) { + * }, + * + * drag: function(evt) { + * }, + * + * end: function(evt) { + * } + * }); + * + * @class tinymce.ui.DragHelper + */ +define("tinymce/ui/DragHelper", [ + "tinymce/dom/DomQuery" +], function($) { + "use strict"; + + function getDocumentSize(doc) { + var documentElement, body, scrollWidth, clientWidth; + var offsetWidth, scrollHeight, clientHeight, offsetHeight, max = Math.max; + + documentElement = doc.documentElement; + body = doc.body; + + scrollWidth = max(documentElement.scrollWidth, body.scrollWidth); + clientWidth = max(documentElement.clientWidth, body.clientWidth); + offsetWidth = max(documentElement.offsetWidth, body.offsetWidth); + + scrollHeight = max(documentElement.scrollHeight, body.scrollHeight); + clientHeight = max(documentElement.clientHeight, body.clientHeight); + offsetHeight = max(documentElement.offsetHeight, body.offsetHeight); + + return { + width: scrollWidth < offsetWidth ? clientWidth : scrollWidth, + height: scrollHeight < offsetHeight ? clientHeight : scrollHeight + }; + } + + function updateWithTouchData(e) { + var keys, i; + + if (e.changedTouches) { + keys = "screenX screenY pageX pageY clientX clientY".split(' '); + for (i = 0; i < keys.length; i++) { + e[keys[i]] = e.changedTouches[0][keys[i]]; + } + } + } + + return function(id, settings) { + var $eventOverlay, doc = settings.document || document, downButton, start, stop, drag, startX, startY; + + settings = settings || {}; + + function getHandleElm() { + return doc.getElementById(settings.handle || id); + } + + start = function(e) { + var docSize = getDocumentSize(doc), handleElm, cursor; + + updateWithTouchData(e); + + e.preventDefault(); + downButton = e.button; + handleElm = getHandleElm(); + startX = e.screenX; + startY = e.screenY; + + // Grab cursor from handle so we can place it on overlay + if (window.getComputedStyle) { + cursor = window.getComputedStyle(handleElm, null).getPropertyValue("cursor"); + } else { + cursor = handleElm.runtimeStyle.cursor; + } + + $eventOverlay = $('<div>').css({ + position: "absolute", + top: 0, left: 0, + width: docSize.width, + height: docSize.height, + zIndex: 0x7FFFFFFF, + opacity: 0.0001, + cursor: cursor + }).appendTo(doc.body); + + $(doc).on('mousemove touchmove', drag).on('mouseup touchend', stop); + + settings.start(e); + }; + + drag = function(e) { + updateWithTouchData(e); + + if (e.button !== downButton) { + return stop(e); + } + + e.deltaX = e.screenX - startX; + e.deltaY = e.screenY - startY; + + e.preventDefault(); + settings.drag(e); + }; + + stop = function(e) { + updateWithTouchData(e); + + $(doc).off('mousemove touchmove', drag).off('mouseup touchend', stop); + + $eventOverlay.remove(); + + if (settings.stop) { + settings.stop(e); + } + }; + + /** + * Destroys the drag/drop helper instance. + * + * @method destroy + */ + this.destroy = function() { + $(getHandleElm()).off(); + }; + + $(getHandleElm()).on('mousedown touchstart', start); + }; +}); + +// Included from: js/tinymce/classes/ui/Scrollable.js + +/** + * Scrollable.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This mixin makes controls scrollable using custom scrollbars. + * + * @-x-less Scrollable.less + * @mixin tinymce.ui.Scrollable + */ +define("tinymce/ui/Scrollable", [ + "tinymce/dom/DomQuery", + "tinymce/ui/DragHelper" +], function($, DragHelper) { + "use strict"; + + return { + init: function() { + var self = this; + self.on('repaint', self.renderScroll); + }, + + renderScroll: function() { + var self = this, margin = 2; + + function repaintScroll() { + var hasScrollH, hasScrollV, bodyElm; + + function repaintAxis(axisName, posName, sizeName, contentSizeName, hasScroll, ax) { + var containerElm, scrollBarElm, scrollThumbElm; + var containerSize, scrollSize, ratio, rect; + var posNameLower, sizeNameLower; + + scrollBarElm = self.getEl('scroll' + axisName); + if (scrollBarElm) { + posNameLower = posName.toLowerCase(); + sizeNameLower = sizeName.toLowerCase(); + + $(self.getEl('absend')).css(posNameLower, self.layoutRect()[contentSizeName] - 1); + + if (!hasScroll) { + $(scrollBarElm).css('display', 'none'); + return; + } + + $(scrollBarElm).css('display', 'block'); + containerElm = self.getEl('body'); + scrollThumbElm = self.getEl('scroll' + axisName + "t"); + containerSize = containerElm["client" + sizeName] - (margin * 2); + containerSize -= hasScrollH && hasScrollV ? scrollBarElm["client" + ax] : 0; + scrollSize = containerElm["scroll" + sizeName]; + ratio = containerSize / scrollSize; + + rect = {}; + rect[posNameLower] = containerElm["offset" + posName] + margin; + rect[sizeNameLower] = containerSize; + $(scrollBarElm).css(rect); + + rect = {}; + rect[posNameLower] = containerElm["scroll" + posName] * ratio; + rect[sizeNameLower] = containerSize * ratio; + $(scrollThumbElm).css(rect); + } + } + + bodyElm = self.getEl('body'); + hasScrollH = bodyElm.scrollWidth > bodyElm.clientWidth; + hasScrollV = bodyElm.scrollHeight > bodyElm.clientHeight; + + repaintAxis("h", "Left", "Width", "contentW", hasScrollH, "Height"); + repaintAxis("v", "Top", "Height", "contentH", hasScrollV, "Width"); + } + + function addScroll() { + function addScrollAxis(axisName, posName, sizeName, deltaPosName, ax) { + var scrollStart, axisId = self._id + '-scroll' + axisName, prefix = self.classPrefix; + + $(self.getEl()).append( + '<div id="' + axisId + '" class="' + prefix + 'scrollbar ' + prefix + 'scrollbar-' + axisName + '">' + + '<div id="' + axisId + 't" class="' + prefix + 'scrollbar-thumb"></div>' + + '</div>' + ); + + self.draghelper = new DragHelper(axisId + 't', { + start: function() { + scrollStart = self.getEl('body')["scroll" + posName]; + $('#' + axisId).addClass(prefix + 'active'); + }, + + drag: function(e) { + var ratio, hasScrollH, hasScrollV, containerSize, layoutRect = self.layoutRect(); + + hasScrollH = layoutRect.contentW > layoutRect.innerW; + hasScrollV = layoutRect.contentH > layoutRect.innerH; + containerSize = self.getEl('body')["client" + sizeName] - (margin * 2); + containerSize -= hasScrollH && hasScrollV ? self.getEl('scroll' + axisName)["client" + ax] : 0; + + ratio = containerSize / self.getEl('body')["scroll" + sizeName]; + self.getEl('body')["scroll" + posName] = scrollStart + (e["delta" + deltaPosName] / ratio); + }, + + stop: function() { + $('#' + axisId).removeClass(prefix + 'active'); + } + }); + } + + self.classes.add('scroll'); + + addScrollAxis("v", "Top", "Height", "Y", "Width"); + addScrollAxis("h", "Left", "Width", "X", "Height"); + } + + if (self.settings.autoScroll) { + if (!self._hasScroll) { + self._hasScroll = true; + addScroll(); + + self.on('wheel', function(e) { + var bodyEl = self.getEl('body'); + + bodyEl.scrollLeft += (e.deltaX || 0) * 10; + bodyEl.scrollTop += e.deltaY * 10; + + repaintScroll(); + }); + + $(self.getEl('body')).on("scroll", repaintScroll); + } + + repaintScroll(); + } + } + }; +}); + +// Included from: js/tinymce/classes/ui/Panel.js + +/** + * Panel.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Creates a new panel. + * + * @-x-less Panel.less + * @class tinymce.ui.Panel + * @extends tinymce.ui.Container + * @mixes tinymce.ui.Scrollable + */ +define("tinymce/ui/Panel", [ + "tinymce/ui/Container", + "tinymce/ui/Scrollable" +], function(Container, Scrollable) { + "use strict"; + + return Container.extend({ + Defaults: { + layout: 'fit', + containerCls: 'panel' + }, + + Mixins: [Scrollable], + + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this, layout = self._layout, innerHtml = self.settings.html; + + self.preRender(); + layout.preRender(self); + + if (typeof innerHtml == "undefined") { + innerHtml = ( + '<div id="' + self._id + '-body" class="' + self.bodyClasses + '">' + + layout.renderHtml(self) + + '</div>' + ); + } else { + if (typeof innerHtml == 'function') { + innerHtml = innerHtml.call(self); + } + + self._hasBody = false; + } + + return ( + '<div id="' + self._id + '" class="' + self.classes + '" hidefocus="1" tabindex="-1" role="group">' + + (self._preBodyHtml || '') + + innerHtml + + '</div>' + ); + } + }); +}); + +// Included from: js/tinymce/classes/ui/Movable.js + +/** + * Movable.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Movable mixin. Makes controls movable absolute and relative to other elements. + * + * @mixin tinymce.ui.Movable + */ +define("tinymce/ui/Movable", [ + "tinymce/ui/DomUtils" +], function(DomUtils) { + "use strict"; + + function calculateRelativePosition(ctrl, targetElm, rel) { + var ctrlElm, pos, x, y, selfW, selfH, targetW, targetH, viewport, size; + + viewport = DomUtils.getViewPort(); + + // Get pos of target + pos = DomUtils.getPos(targetElm); + x = pos.x; + y = pos.y; + + if (ctrl.state.get('fixed') && DomUtils.getRuntimeStyle(document.body, 'position') == 'static') { + x -= viewport.x; + y -= viewport.y; + } + + // Get size of self + ctrlElm = ctrl.getEl(); + size = DomUtils.getSize(ctrlElm); + selfW = size.width; + selfH = size.height; + + // Get size of target + size = DomUtils.getSize(targetElm); + targetW = size.width; + targetH = size.height; + + // Parse align string + rel = (rel || '').split(''); + + // Target corners + if (rel[0] === 'b') { + y += targetH; + } + + if (rel[1] === 'r') { + x += targetW; + } + + if (rel[0] === 'c') { + y += Math.round(targetH / 2); + } + + if (rel[1] === 'c') { + x += Math.round(targetW / 2); + } + + // Self corners + if (rel[3] === 'b') { + y -= selfH; + } + + if (rel[4] === 'r') { + x -= selfW; + } + + if (rel[3] === 'c') { + y -= Math.round(selfH / 2); + } + + if (rel[4] === 'c') { + x -= Math.round(selfW / 2); + } + + return { + x: x, + y: y, + w: selfW, + h: selfH + }; + } + + return { + /** + * Tests various positions to get the most suitable one. + * + * @method testMoveRel + * @param {DOMElement} elm Element to position against. + * @param {Array} rels Array with relative positions. + * @return {String} Best suitable relative position. + */ + testMoveRel: function(elm, rels) { + var viewPortRect = DomUtils.getViewPort(); + + for (var i = 0; i < rels.length; i++) { + var pos = calculateRelativePosition(this, elm, rels[i]); + + if (this.state.get('fixed')) { + if (pos.x > 0 && pos.x + pos.w < viewPortRect.w && pos.y > 0 && pos.y + pos.h < viewPortRect.h) { + return rels[i]; + } + } else { + if (pos.x > viewPortRect.x && pos.x + pos.w < viewPortRect.w + viewPortRect.x && + pos.y > viewPortRect.y && pos.y + pos.h < viewPortRect.h + viewPortRect.y) { + return rels[i]; + } + } + } + + return rels[0]; + }, + + /** + * Move relative to the specified element. + * + * @method moveRel + * @param {Element} elm Element to move relative to. + * @param {String} rel Relative mode. For example: br-tl. + * @return {tinymce.ui.Control} Current control instance. + */ + moveRel: function(elm, rel) { + if (typeof rel != 'string') { + rel = this.testMoveRel(elm, rel); + } + + var pos = calculateRelativePosition(this, elm, rel); + return this.moveTo(pos.x, pos.y); + }, + + /** + * Move by a relative x, y values. + * + * @method moveBy + * @param {Number} dx Relative x position. + * @param {Number} dy Relative y position. + * @return {tinymce.ui.Control} Current control instance. + */ + moveBy: function(dx, dy) { + var self = this, rect = self.layoutRect(); + + self.moveTo(rect.x + dx, rect.y + dy); + + return self; + }, + + /** + * Move to absolute position. + * + * @method moveTo + * @param {Number} x Absolute x position. + * @param {Number} y Absolute y position. + * @return {tinymce.ui.Control} Current control instance. + */ + moveTo: function(x, y) { + var self = this; + + // TODO: Move this to some global class + function constrain(value, max, size) { + if (value < 0) { + return 0; + } + + if (value + size > max) { + value = max - size; + return value < 0 ? 0 : value; + } + + return value; + } + + if (self.settings.constrainToViewport) { + var viewPortRect = DomUtils.getViewPort(window); + var layoutRect = self.layoutRect(); + + x = constrain(x, viewPortRect.w + viewPortRect.x, layoutRect.w); + y = constrain(y, viewPortRect.h + viewPortRect.y, layoutRect.h); + } + + if (self.state.get('rendered')) { + self.layoutRect({x: x, y: y}).repaint(); + } else { + self.settings.x = x; + self.settings.y = y; + } + + self.fire('move', {x: x, y: y}); + + return self; + } + }; +}); + +// Included from: js/tinymce/classes/ui/Resizable.js + +/** + * Resizable.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Resizable mixin. Enables controls to be resized. + * + * @mixin tinymce.ui.Resizable + */ +define("tinymce/ui/Resizable", [ + "tinymce/ui/DomUtils" +], function(DomUtils) { + "use strict"; + + return { + /** + * Resizes the control to contents. + * + * @method resizeToContent + */ + resizeToContent: function() { + this._layoutRect.autoResize = true; + this._lastRect = null; + this.reflow(); + }, + + /** + * Resizes the control to a specific width/height. + * + * @method resizeTo + * @param {Number} w Control width. + * @param {Number} h Control height. + * @return {tinymce.ui.Control} Current control instance. + */ + resizeTo: function(w, h) { + // TODO: Fix hack + if (w <= 1 || h <= 1) { + var rect = DomUtils.getWindowSize(); + + w = w <= 1 ? w * rect.w : w; + h = h <= 1 ? h * rect.h : h; + } + + this._layoutRect.autoResize = false; + return this.layoutRect({minW: w, minH: h, w: w, h: h}).reflow(); + }, + + /** + * Resizes the control to a specific relative width/height. + * + * @method resizeBy + * @param {Number} dw Relative control width. + * @param {Number} dh Relative control height. + * @return {tinymce.ui.Control} Current control instance. + */ + resizeBy: function(dw, dh) { + var self = this, rect = self.layoutRect(); + + return self.resizeTo(rect.w + dw, rect.h + dh); + } + }; +}); + +// Included from: js/tinymce/classes/ui/FloatPanel.js + +/** + * FloatPanel.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class creates a floating panel. + * + * @-x-less FloatPanel.less + * @class tinymce.ui.FloatPanel + * @extends tinymce.ui.Panel + * @mixes tinymce.ui.Movable + * @mixes tinymce.ui.Resizable + */ +define("tinymce/ui/FloatPanel", [ + "tinymce/ui/Panel", + "tinymce/ui/Movable", + "tinymce/ui/Resizable", + "tinymce/ui/DomUtils", + "tinymce/dom/DomQuery", + "tinymce/util/Delay" +], function(Panel, Movable, Resizable, DomUtils, $, Delay) { + "use strict"; + + var documentClickHandler, documentScrollHandler, windowResizeHandler, visiblePanels = []; + var zOrder = [], hasModal; + + function isChildOf(ctrl, parent) { + while (ctrl) { + if (ctrl == parent) { + return true; + } + + ctrl = ctrl.parent(); + } + } + + function skipOrHidePanels(e) { + // Hide any float panel when a click/focus out is out side that float panel and the + // float panels direct parent for example a click on a menu button + var i = visiblePanels.length; + + while (i--) { + var panel = visiblePanels[i], clickCtrl = panel.getParentCtrl(e.target); + + if (panel.settings.autohide) { + if (clickCtrl) { + if (isChildOf(clickCtrl, panel) || panel.parent() === clickCtrl) { + continue; + } + } + + e = panel.fire('autohide', {target: e.target}); + if (!e.isDefaultPrevented()) { + panel.hide(); + } + } + } + } + + function bindDocumentClickHandler() { + + if (!documentClickHandler) { + documentClickHandler = function(e) { + // Gecko fires click event and in the wrong order on Mac so lets normalize + if (e.button == 2) { + return; + } + + skipOrHidePanels(e); + }; + + $(document).on('click touchstart', documentClickHandler); + } + } + + function bindDocumentScrollHandler() { + if (!documentScrollHandler) { + documentScrollHandler = function() { + var i; + + i = visiblePanels.length; + while (i--) { + repositionPanel(visiblePanels[i]); + } + }; + + $(window).on('scroll', documentScrollHandler); + } + } + + function bindWindowResizeHandler() { + if (!windowResizeHandler) { + var docElm = document.documentElement, clientWidth = docElm.clientWidth, clientHeight = docElm.clientHeight; + + windowResizeHandler = function() { + // Workaround for #7065 IE 7 fires resize events event though the window wasn't resized + if (!document.all || clientWidth != docElm.clientWidth || clientHeight != docElm.clientHeight) { + clientWidth = docElm.clientWidth; + clientHeight = docElm.clientHeight; + FloatPanel.hideAll(); + } + }; + + $(window).on('resize', windowResizeHandler); + } + } + + /** + * Repositions the panel to the top of page if the panel is outside of the visual viewport. It will + * also reposition all child panels of the current panel. + */ + function repositionPanel(panel) { + var scrollY = DomUtils.getViewPort().y; + + function toggleFixedChildPanels(fixed, deltaY) { + var parent; + + for (var i = 0; i < visiblePanels.length; i++) { + if (visiblePanels[i] != panel) { + parent = visiblePanels[i].parent(); + + while (parent && (parent = parent.parent())) { + if (parent == panel) { + visiblePanels[i].fixed(fixed).moveBy(0, deltaY).repaint(); + } + } + } + } + } + + if (panel.settings.autofix) { + if (!panel.state.get('fixed')) { + panel._autoFixY = panel.layoutRect().y; + + if (panel._autoFixY < scrollY) { + panel.fixed(true).layoutRect({y: 0}).repaint(); + toggleFixedChildPanels(true, scrollY - panel._autoFixY); + } + } else { + if (panel._autoFixY > scrollY) { + panel.fixed(false).layoutRect({y: panel._autoFixY}).repaint(); + toggleFixedChildPanels(false, panel._autoFixY - scrollY); + } + } + } + } + + function addRemove(add, ctrl) { + var i, zIndex = FloatPanel.zIndex || 0xFFFF, topModal; + + if (add) { + zOrder.push(ctrl); + } else { + i = zOrder.length; + + while (i--) { + if (zOrder[i] === ctrl) { + zOrder.splice(i, 1); + } + } + } + + if (zOrder.length) { + for (i = 0; i < zOrder.length; i++) { + if (zOrder[i].modal) { + zIndex++; + topModal = zOrder[i]; + } + + zOrder[i].getEl().style.zIndex = zIndex; + zOrder[i].zIndex = zIndex; + zIndex++; + } + } + + var modalBlockEl = $('#' + ctrl.classPrefix + 'modal-block', ctrl.getContainerElm())[0]; + + if (topModal) { + $(modalBlockEl).css('z-index', topModal.zIndex - 1); + } else if (modalBlockEl) { + modalBlockEl.parentNode.removeChild(modalBlockEl); + hasModal = false; + } + + FloatPanel.currentZIndex = zIndex; + } + + var FloatPanel = Panel.extend({ + Mixins: [Movable, Resizable], + + /** + * Constructs a new control instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + * @setting {Boolean} autohide Automatically hide the panel. + */ + init: function(settings) { + var self = this; + + self._super(settings); + self._eventsRoot = self; + + self.classes.add('floatpanel'); + + // Hide floatpanes on click out side the root button + if (settings.autohide) { + bindDocumentClickHandler(); + bindWindowResizeHandler(); + visiblePanels.push(self); + } + + if (settings.autofix) { + bindDocumentScrollHandler(); + + self.on('move', function() { + repositionPanel(this); + }); + } + + self.on('postrender show', function(e) { + if (e.control == self) { + var $modalBlockEl, prefix = self.classPrefix; + + if (self.modal && !hasModal) { + $modalBlockEl = $('#' + prefix + 'modal-block', self.getContainerElm()); + if (!$modalBlockEl[0]) { + $modalBlockEl = $( + '<div id="' + prefix + 'modal-block" class="' + prefix + 'reset ' + prefix + 'fade"></div>' + ).appendTo(self.getContainerElm()); + } + + Delay.setTimeout(function() { + $modalBlockEl.addClass(prefix + 'in'); + $(self.getEl()).addClass(prefix + 'in'); + }); + + hasModal = true; + } + + addRemove(true, self); + } + }); + + self.on('show', function() { + self.parents().each(function(ctrl) { + if (ctrl.state.get('fixed')) { + self.fixed(true); + return false; + } + }); + }); + + if (settings.popover) { + self._preBodyHtml = '<div class="' + self.classPrefix + 'arrow"></div>'; + self.classes.add('popover').add('bottom').add(self.isRtl() ? 'end' : 'start'); + } + + self.aria('label', settings.ariaLabel); + self.aria('labelledby', self._id); + self.aria('describedby', self.describedBy || self._id + '-none'); + }, + + fixed: function(state) { + var self = this; + + if (self.state.get('fixed') != state) { + if (self.state.get('rendered')) { + var viewport = DomUtils.getViewPort(); + + if (state) { + self.layoutRect().y -= viewport.y; + } else { + self.layoutRect().y += viewport.y; + } + } + + self.classes.toggle('fixed', state); + self.state.set('fixed', state); + } + + return self; + }, + + /** + * Shows the current float panel. + * + * @method show + * @return {tinymce.ui.FloatPanel} Current floatpanel instance. + */ + show: function() { + var self = this, i, state = self._super(); + + i = visiblePanels.length; + while (i--) { + if (visiblePanels[i] === self) { + break; + } + } + + if (i === -1) { + visiblePanels.push(self); + } + + return state; + }, + + /** + * Hides the current float panel. + * + * @method hide + * @return {tinymce.ui.FloatPanel} Current floatpanel instance. + */ + hide: function() { + removeVisiblePanel(this); + addRemove(false, this); + + return this._super(); + }, + + /** + * Hide all visible float panels with he autohide setting enabled. This is for + * manually hiding floating menus or panels. + * + * @method hideAll + */ + hideAll: function() { + FloatPanel.hideAll(); + }, + + /** + * Closes the float panel. This will remove the float panel from page and fire the close event. + * + * @method close + */ + close: function() { + var self = this; + + if (!self.fire('close').isDefaultPrevented()) { + self.remove(); + addRemove(false, self); + } + + return self; + }, + + /** + * Removes the float panel from page. + * + * @method remove + */ + remove: function() { + removeVisiblePanel(this); + this._super(); + }, + + postRender: function() { + var self = this; + + if (self.settings.bodyRole) { + this.getEl('body').setAttribute('role', self.settings.bodyRole); + } + + return self._super(); + } + }); + + /** + * Hide all visible float panels with he autohide setting enabled. This is for + * manually hiding floating menus or panels. + * + * @static + * @method hideAll + */ + FloatPanel.hideAll = function() { + var i = visiblePanels.length; + + while (i--) { + var panel = visiblePanels[i]; + + if (panel && panel.settings.autohide) { + panel.hide(); + visiblePanels.splice(i, 1); + } + } + }; + + function removeVisiblePanel(panel) { + var i; + + i = visiblePanels.length; + while (i--) { + if (visiblePanels[i] === panel) { + visiblePanels.splice(i, 1); + } + } + + i = zOrder.length; + while (i--) { + if (zOrder[i] === panel) { + zOrder.splice(i, 1); + } + } + } + + return FloatPanel; +}); + +// Included from: js/tinymce/classes/ui/Window.js + +/** + * Window.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Creates a new window. + * + * @-x-less Window.less + * @class tinymce.ui.Window + * @extends tinymce.ui.FloatPanel + */ +define("tinymce/ui/Window", [ + "tinymce/ui/FloatPanel", + "tinymce/ui/Panel", + "tinymce/ui/DomUtils", + "tinymce/dom/DomQuery", + "tinymce/ui/DragHelper", + "tinymce/ui/BoxUtils", + "tinymce/Env", + "tinymce/util/Delay" +], function(FloatPanel, Panel, DomUtils, $, DragHelper, BoxUtils, Env, Delay) { + "use strict"; + + var windows = [], oldMetaValue = ''; + + function toggleFullScreenState(state) { + var noScaleMetaValue = 'width=device-width,initial-scale=1.0,user-scalable=0,minimum-scale=1.0,maximum-scale=1.0', + viewport = $("meta[name=viewport]")[0], + contentValue; + + if (Env.overrideViewPort === false) { + return; + } + + if (!viewport) { + viewport = document.createElement('meta'); + viewport.setAttribute('name', 'viewport'); + document.getElementsByTagName('head')[0].appendChild(viewport); + } + + contentValue = viewport.getAttribute('content'); + if (contentValue && typeof oldMetaValue != 'undefined') { + oldMetaValue = contentValue; + } + + viewport.setAttribute('content', state ? noScaleMetaValue : oldMetaValue); + } + + function toggleBodyFullScreenClasses(classPrefix) { + for (var i = 0; i < windows.length; i++) { + if (windows[i]._fullscreen) { + return; + } + } + + $([document.documentElement, document.body]).removeClass(classPrefix + 'fullscreen'); + } + + function handleWindowResize() { + if (!Env.desktop) { + var lastSize = { + w: window.innerWidth, + h: window.innerHeight + }; + + Delay.setInterval(function() { + var w = window.innerWidth, + h = window.innerHeight; + + if (lastSize.w != w || lastSize.h != h) { + lastSize = { + w: w, + h: h + }; + + $(window).trigger('resize'); + } + }, 100); + } + + function reposition() { + var i, rect = DomUtils.getWindowSize(), layoutRect; + + for (i = 0; i < windows.length; i++) { + layoutRect = windows[i].layoutRect(); + + windows[i].moveTo( + windows[i].settings.x || Math.max(0, rect.w / 2 - layoutRect.w / 2), + windows[i].settings.y || Math.max(0, rect.h / 2 - layoutRect.h / 2) + ); + } + } + + $(window).on('resize', reposition); + } + + var Window = FloatPanel.extend({ + modal: true, + + Defaults: { + border: 1, + layout: 'flex', + containerCls: 'panel', + role: 'dialog', + callbacks: { + submit: function() { + this.fire('submit', {data: this.toJSON()}); + }, + + close: function() { + this.close(); + } + } + }, + + /** + * Constructs a instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + */ + init: function(settings) { + var self = this; + + self._super(settings); + + if (self.isRtl()) { + self.classes.add('rtl'); + } + + self.classes.add('window'); + self.bodyClasses.add('window-body'); + self.state.set('fixed', true); + + // Create statusbar + if (settings.buttons) { + self.statusbar = new Panel({ + layout: 'flex', + border: '1 0 0 0', + spacing: 3, + padding: 10, + align: 'center', + pack: self.isRtl() ? 'start' : 'end', + defaults: { + type: 'button' + }, + items: settings.buttons + }); + + self.statusbar.classes.add('foot'); + self.statusbar.parent(self); + } + + self.on('click', function(e) { + var closeClass = self.classPrefix + 'close'; + + if (DomUtils.hasClass(e.target, closeClass) || DomUtils.hasClass(e.target.parentNode, closeClass)) { + self.close(); + } + }); + + self.on('cancel', function() { + self.close(); + }); + + self.aria('describedby', self.describedBy || self._id + '-none'); + self.aria('label', settings.title); + self._fullscreen = false; + }, + + /** + * Recalculates the positions of the controls in the current container. + * This is invoked by the reflow method and shouldn't be called directly. + * + * @method recalc + */ + recalc: function() { + var self = this, statusbar = self.statusbar, layoutRect, width, x, needsRecalc; + + if (self._fullscreen) { + self.layoutRect(DomUtils.getWindowSize()); + self.layoutRect().contentH = self.layoutRect().innerH; + } + + self._super(); + + layoutRect = self.layoutRect(); + + // Resize window based on title width + if (self.settings.title && !self._fullscreen) { + width = layoutRect.headerW; + if (width > layoutRect.w) { + x = layoutRect.x - Math.max(0, width / 2); + self.layoutRect({w: width, x: x}); + needsRecalc = true; + } + } + + // Resize window based on statusbar width + if (statusbar) { + statusbar.layoutRect({w: self.layoutRect().innerW}).recalc(); + + width = statusbar.layoutRect().minW + layoutRect.deltaW; + if (width > layoutRect.w) { + x = layoutRect.x - Math.max(0, width - layoutRect.w); + self.layoutRect({w: width, x: x}); + needsRecalc = true; + } + } + + // Recalc body and disable auto resize + if (needsRecalc) { + self.recalc(); + } + }, + + /** + * Initializes the current controls layout rect. + * This will be executed by the layout managers to determine the + * default minWidth/minHeight etc. + * + * @method initLayoutRect + * @return {Object} Layout rect instance. + */ + initLayoutRect: function() { + var self = this, layoutRect = self._super(), deltaH = 0, headEl; + + // Reserve vertical space for title + if (self.settings.title && !self._fullscreen) { + headEl = self.getEl('head'); + + var size = DomUtils.getSize(headEl); + + layoutRect.headerW = size.width; + layoutRect.headerH = size.height; + + deltaH += layoutRect.headerH; + } + + // Reserve vertical space for statusbar + if (self.statusbar) { + deltaH += self.statusbar.layoutRect().h; + } + + layoutRect.deltaH += deltaH; + layoutRect.minH += deltaH; + //layoutRect.innerH -= deltaH; + layoutRect.h += deltaH; + + var rect = DomUtils.getWindowSize(); + + layoutRect.x = self.settings.x || Math.max(0, rect.w / 2 - layoutRect.w / 2); + layoutRect.y = self.settings.y || Math.max(0, rect.h / 2 - layoutRect.h / 2); + + return layoutRect; + }, + + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this, layout = self._layout, id = self._id, prefix = self.classPrefix; + var settings = self.settings, headerHtml = '', footerHtml = '', html = settings.html; + + self.preRender(); + layout.preRender(self); + + if (settings.title) { + headerHtml = ( + '<div id="' + id + '-head" class="' + prefix + 'window-head">' + + '<div id="' + id + '-title" class="' + prefix + 'title">' + self.encode(settings.title) + '</div>' + + '<div id="' + id + '-dragh" class="' + prefix + 'dragh"></div>' + + '<button type="button" class="' + prefix + 'close" aria-hidden="true">' + + '<i class="mce-ico mce-i-remove"></i>' + + '</button>' + + '</div>' + ); + } + + if (settings.url) { + html = '<iframe src="' + settings.url + '" tabindex="-1"></iframe>'; + } + + if (typeof html == "undefined") { + html = layout.renderHtml(self); + } + + if (self.statusbar) { + footerHtml = self.statusbar.renderHtml(); + } + + return ( + '<div id="' + id + '" class="' + self.classes + '" hidefocus="1">' + + '<div class="' + self.classPrefix + 'reset" role="application">' + + headerHtml + + '<div id="' + id + '-body" class="' + self.bodyClasses + '">' + + html + + '</div>' + + footerHtml + + '</div>' + + '</div>' + ); + }, + + /** + * Switches the window fullscreen mode. + * + * @method fullscreen + * @param {Boolean} state True/false state. + * @return {tinymce.ui.Window} Current window instance. + */ + fullscreen: function(state) { + var self = this, documentElement = document.documentElement, slowRendering, prefix = self.classPrefix, layoutRect; + + if (state != self._fullscreen) { + $(window).on('resize', function() { + var time; + + if (self._fullscreen) { + // Time the layout time if it's to slow use a timeout to not hog the CPU + if (!slowRendering) { + time = new Date().getTime(); + + var rect = DomUtils.getWindowSize(); + self.moveTo(0, 0).resizeTo(rect.w, rect.h); + + if ((new Date().getTime()) - time > 50) { + slowRendering = true; + } + } else { + if (!self._timer) { + self._timer = Delay.setTimeout(function() { + var rect = DomUtils.getWindowSize(); + self.moveTo(0, 0).resizeTo(rect.w, rect.h); + + self._timer = 0; + }, 50); + } + } + } + }); + + layoutRect = self.layoutRect(); + self._fullscreen = state; + + if (!state) { + self.borderBox = BoxUtils.parseBox(self.settings.border); + self.getEl('head').style.display = ''; + layoutRect.deltaH += layoutRect.headerH; + $([documentElement, document.body]).removeClass(prefix + 'fullscreen'); + self.classes.remove('fullscreen'); + self.moveTo(self._initial.x, self._initial.y).resizeTo(self._initial.w, self._initial.h); + } else { + self._initial = {x: layoutRect.x, y: layoutRect.y, w: layoutRect.w, h: layoutRect.h}; + + self.borderBox = BoxUtils.parseBox('0'); + self.getEl('head').style.display = 'none'; + layoutRect.deltaH -= layoutRect.headerH + 2; + $([documentElement, document.body]).addClass(prefix + 'fullscreen'); + self.classes.add('fullscreen'); + + var rect = DomUtils.getWindowSize(); + self.moveTo(0, 0).resizeTo(rect.w, rect.h); + } + } + + return self.reflow(); + }, + + /** + * Called after the control has been rendered. + * + * @method postRender + */ + postRender: function() { + var self = this, startPos; + + setTimeout(function() { + self.classes.add('in'); + self.fire('open'); + }, 0); + + self._super(); + + if (self.statusbar) { + self.statusbar.postRender(); + } + + self.focus(); + + this.dragHelper = new DragHelper(self._id + '-dragh', { + start: function() { + startPos = { + x: self.layoutRect().x, + y: self.layoutRect().y + }; + }, + + drag: function(e) { + self.moveTo(startPos.x + e.deltaX, startPos.y + e.deltaY); + } + }); + + self.on('submit', function(e) { + if (!e.isDefaultPrevented()) { + self.close(); + } + }); + + windows.push(self); + toggleFullScreenState(true); + }, + + /** + * Fires a submit event with the serialized form. + * + * @method submit + * @return {Object} Event arguments object. + */ + submit: function() { + return this.fire('submit', {data: this.toJSON()}); + }, + + /** + * Removes the current control from DOM and from UI collections. + * + * @method remove + * @return {tinymce.ui.Control} Current control instance. + */ + remove: function() { + var self = this, i; + + self.dragHelper.destroy(); + self._super(); + + if (self.statusbar) { + this.statusbar.remove(); + } + + i = windows.length; + while (i--) { + if (windows[i] === self) { + windows.splice(i, 1); + } + } + + toggleFullScreenState(windows.length > 0); + toggleBodyFullScreenClasses(self.classPrefix); + }, + + /** + * Returns the contentWindow object of the iframe if it exists. + * + * @method getContentWindow + * @return {Window} window object or null. + */ + getContentWindow: function() { + var ifr = this.getEl().getElementsByTagName('iframe')[0]; + return ifr ? ifr.contentWindow : null; + } + }); + + handleWindowResize(); + + return Window; +}); + +// Included from: js/tinymce/classes/ui/MessageBox.js + +/** + * MessageBox.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class is used to create MessageBoxes like alerts/confirms etc. + * + * @class tinymce.ui.MessageBox + * @extends tinymce.ui.FloatPanel + */ +define("tinymce/ui/MessageBox", [ + "tinymce/ui/Window" +], function(Window) { + "use strict"; + + var MessageBox = Window.extend({ + /** + * Constructs a instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + */ + init: function(settings) { + settings = { + border: 1, + padding: 20, + layout: 'flex', + pack: "center", + align: "center", + containerCls: 'panel', + autoScroll: true, + buttons: {type: "button", text: "Ok", action: "ok"}, + items: { + type: "label", + multiline: true, + maxWidth: 500, + maxHeight: 200 + } + }; + + this._super(settings); + }, + + Statics: { + /** + * Ok buttons constant. + * + * @static + * @final + * @field {Number} OK + */ + OK: 1, + + /** + * Ok/cancel buttons constant. + * + * @static + * @final + * @field {Number} OK_CANCEL + */ + OK_CANCEL: 2, + + /** + * yes/no buttons constant. + * + * @static + * @final + * @field {Number} YES_NO + */ + YES_NO: 3, + + /** + * yes/no/cancel buttons constant. + * + * @static + * @final + * @field {Number} YES_NO_CANCEL + */ + YES_NO_CANCEL: 4, + + /** + * Constructs a new message box and renders it to the body element. + * + * @static + * @method msgBox + * @param {Object} settings Name/value object with settings. + */ + msgBox: function(settings) { + var buttons, callback = settings.callback || function() {}; + + function createButton(text, status, primary) { + return { + type: "button", + text: text, + subtype: primary ? 'primary' : '', + onClick: function(e) { + e.control.parents()[1].close(); + callback(status); + } + }; + } + + switch (settings.buttons) { + case MessageBox.OK_CANCEL: + buttons = [ + createButton('Ok', true, true), + createButton('Cancel', false) + ]; + break; + + case MessageBox.YES_NO: + case MessageBox.YES_NO_CANCEL: + buttons = [ + createButton('Yes', 1, true), + createButton('No', 0) + ]; + + if (settings.buttons == MessageBox.YES_NO_CANCEL) { + buttons.push(createButton('Cancel', -1)); + } + break; + + default: + buttons = [ + createButton('Ok', true, true) + ]; + break; + } + + return new Window({ + padding: 20, + x: settings.x, + y: settings.y, + minWidth: 300, + minHeight: 100, + layout: "flex", + pack: "center", + align: "center", + buttons: buttons, + title: settings.title, + role: 'alertdialog', + items: { + type: "label", + multiline: true, + maxWidth: 500, + maxHeight: 200, + text: settings.text + }, + onPostRender: function() { + this.aria('describedby', this.items()[0]._id); + }, + onClose: settings.onClose, + onCancel: function() { + callback(false); + } + }).renderTo(document.body).reflow(); + }, + + /** + * Creates a new alert dialog. + * + * @method alert + * @param {Object} settings Settings for the alert dialog. + * @param {function} [callback] Callback to execute when the user makes a choice. + */ + alert: function(settings, callback) { + if (typeof settings == "string") { + settings = {text: settings}; + } + + settings.callback = callback; + return MessageBox.msgBox(settings); + }, + + /** + * Creates a new confirm dialog. + * + * @method confirm + * @param {Object} settings Settings for the confirm dialog. + * @param {function} [callback] Callback to execute when the user makes a choice. + */ + confirm: function(settings, callback) { + if (typeof settings == "string") { + settings = {text: settings}; + } + + settings.callback = callback; + settings.buttons = MessageBox.OK_CANCEL; + + return MessageBox.msgBox(settings); + } + } + }); + + return MessageBox; +}); + +// Included from: js/tinymce/classes/WindowManager.js + +/** + * WindowManager.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class handles the creation of native windows and dialogs. This class can be extended to provide for example inline dialogs. + * + * @class tinymce.WindowManager + * @example + * // Opens a new dialog with the file.htm file and the size 320x240 + * // It also adds a custom parameter this can be retrieved by using tinyMCEPopup.getWindowArg inside the dialog. + * tinymce.activeEditor.windowManager.open({ + * url: 'file.htm', + * width: 320, + * height: 240 + * }, { + * custom_param: 1 + * }); + * + * // Displays an alert box using the active editors window manager instance + * tinymce.activeEditor.windowManager.alert('Hello world!'); + * + * // Displays an confirm box and an alert message will be displayed depending on what you choose in the confirm + * tinymce.activeEditor.windowManager.confirm("Do you want to do something", function(s) { + * if (s) + * tinymce.activeEditor.windowManager.alert("Ok"); + * else + * tinymce.activeEditor.windowManager.alert("Cancel"); + * }); + */ +define("tinymce/WindowManager", [ + "tinymce/ui/Window", + "tinymce/ui/MessageBox" +], function(Window, MessageBox) { + return function(editor) { + var self = this, windows = []; + + function getTopMostWindow() { + if (windows.length) { + return windows[windows.length - 1]; + } + } + + function fireOpenEvent(win) { + editor.fire('OpenWindow', { + win: win + }); + } + + function fireCloseEvent(win) { + editor.fire('CloseWindow', { + win: win + }); + } + + self.windows = windows; + + editor.on('remove', function() { + var i = windows.length; + + while (i--) { + windows[i].close(); + } + }); + + /** + * Opens a new window. + * + * @method open + * @param {Object} args Optional name/value settings collection contains things like width/height/url etc. + * @param {Object} params Options like title, file, width, height etc. + * @option {String} title Window title. + * @option {String} file URL of the file to open in the window. + * @option {Number} width Width in pixels. + * @option {Number} height Height in pixels. + * @option {Boolean} autoScroll Specifies whether the popup window can have scrollbars if required (i.e. content + * larger than the popup size specified). + */ + self.open = function(args, params) { + var win; + + editor.editorManager.setActive(editor); + + args.title = args.title || ' '; + + // Handle URL + args.url = args.url || args.file; // Legacy + if (args.url) { + args.width = parseInt(args.width || 320, 10); + args.height = parseInt(args.height || 240, 10); + } + + // Handle body + if (args.body) { + args.items = { + defaults: args.defaults, + type: args.bodyType || 'form', + items: args.body, + data: args.data, + callbacks: args.commands + }; + } + + if (!args.url && !args.buttons) { + args.buttons = [ + {text: 'Ok', subtype: 'primary', onclick: function() { + win.find('form')[0].submit(); + }}, + + {text: 'Cancel', onclick: function() { + win.close(); + }} + ]; + } + + win = new Window(args); + windows.push(win); + + win.on('close', function() { + var i = windows.length; + + while (i--) { + if (windows[i] === win) { + windows.splice(i, 1); + } + } + + if (!windows.length) { + editor.focus(); + } + + fireCloseEvent(win); + }); + + // Handle data + if (args.data) { + win.on('postRender', function() { + this.find('*').each(function(ctrl) { + var name = ctrl.name(); + + if (name in args.data) { + ctrl.value(args.data[name]); + } + }); + }); + } + + // store args and parameters + win.features = args || {}; + win.params = params || {}; + + // Takes a snapshot in the FocusManager of the selection before focus is lost to dialog + if (windows.length === 1) { + editor.nodeChanged(); + } + + win = win.renderTo().reflow(); + + fireOpenEvent(win); + + return win; + }; + + /** + * Creates a alert dialog. Please don't use the blocking behavior of this + * native version use the callback method instead then it can be extended. + * + * @method alert + * @param {String} message Text to display in the new alert dialog. + * @param {function} callback Callback function to be executed after the user has selected ok. + * @param {Object} scope Optional scope to execute the callback in. + * @example + * // Displays an alert box using the active editors window manager instance + * tinymce.activeEditor.windowManager.alert('Hello world!'); + */ + self.alert = function(message, callback, scope) { + var win; + + win = MessageBox.alert(message, function() { + if (callback) { + callback.call(scope || this); + } else { + editor.focus(); + } + }); + + win.on('close', function() { + fireCloseEvent(win); + }); + + fireOpenEvent(win); + }; + + /** + * Creates a confirm dialog. Please don't use the blocking behavior of this + * native version use the callback method instead then it can be extended. + * + * @method confirm + * @param {String} message Text to display in the new confirm dialog. + * @param {function} callback Callback function to be executed after the user has selected ok or cancel. + * @param {Object} scope Optional scope to execute the callback in. + * @example + * // Displays an confirm box and an alert message will be displayed depending on what you choose in the confirm + * tinymce.activeEditor.windowManager.confirm("Do you want to do something", function(s) { + * if (s) + * tinymce.activeEditor.windowManager.alert("Ok"); + * else + * tinymce.activeEditor.windowManager.alert("Cancel"); + * }); + */ + self.confirm = function(message, callback, scope) { + var win; + + win = MessageBox.confirm(message, function(state) { + callback.call(scope || this, state); + }); + + win.on('close', function() { + fireCloseEvent(win); + }); + + fireOpenEvent(win); + }; + + /** + * Closes the top most window. + * + * @method close + */ + self.close = function() { + if (getTopMostWindow()) { + getTopMostWindow().close(); + } + }; + + /** + * Returns the params of the last window open call. This can be used in iframe based + * dialog to get params passed from the tinymce plugin. + * + * @example + * var dialogArguments = top.tinymce.activeEditor.windowManager.getParams(); + * + * @method getParams + * @return {Object} Name/value object with parameters passed from windowManager.open call. + */ + self.getParams = function() { + return getTopMostWindow() ? getTopMostWindow().params : null; + }; + + /** + * Sets the params of the last opened window. + * + * @method setParams + * @param {Object} params Params object to set for the last opened window. + */ + self.setParams = function(params) { + if (getTopMostWindow()) { + getTopMostWindow().params = params; + } + }; + + /** + * Returns the currently opened window objects. + * + * @method getWindows + * @return {Array} Array of the currently opened windows. + */ + self.getWindows = function() { + return windows; + }; + }; +}); + +// Included from: js/tinymce/classes/ui/Tooltip.js + +/** + * Tooltip.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Creates a tooltip instance. + * + * @-x-less ToolTip.less + * @class tinymce.ui.ToolTip + * @extends tinymce.ui.Control + * @mixes tinymce.ui.Movable + */ +define("tinymce/ui/Tooltip", [ + "tinymce/ui/Control", + "tinymce/ui/Movable" +], function(Control, Movable) { + return Control.extend({ + Mixins: [Movable], + + Defaults: { + classes: 'widget tooltip tooltip-n' + }, + + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this, prefix = self.classPrefix; + + return ( + '<div id="' + self._id + '" class="' + self.classes + '" role="presentation">' + + '<div class="' + prefix + 'tooltip-arrow"></div>' + + '<div class="' + prefix + 'tooltip-inner">' + self.encode(self.state.get('text')) + '</div>' + + '</div>' + ); + }, + + bindStates: function() { + var self = this; + + self.state.on('change:text', function(e) { + self.getEl().lastChild.innerHTML = self.encode(e.value); + }); + + return self._super(); + }, + + /** + * Repaints the control after a layout operation. + * + * @method repaint + */ + repaint: function() { + var self = this, style, rect; + + style = self.getEl().style; + rect = self._layoutRect; + + style.left = rect.x + 'px'; + style.top = rect.y + 'px'; + style.zIndex = 0xFFFF + 0xFFFF; + } + }); +}); + +// Included from: js/tinymce/classes/ui/Widget.js + +/** + * Widget.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Widget base class a widget is a control that has a tooltip and some basic states. + * + * @class tinymce.ui.Widget + * @extends tinymce.ui.Control + */ +define("tinymce/ui/Widget", [ + "tinymce/ui/Control", + "tinymce/ui/Tooltip" +], function(Control, Tooltip) { + "use strict"; + + var tooltip; + + var Widget = Control.extend({ + /** + * Constructs a instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + * @setting {String} tooltip Tooltip text to display when hovering. + * @setting {Boolean} autofocus True if the control should be focused when rendered. + * @setting {String} text Text to display inside widget. + */ + init: function(settings) { + var self = this; + + self._super(settings); + settings = self.settings; + self.canFocus = true; + + if (settings.tooltip && Widget.tooltips !== false) { + self.on('mouseenter', function(e) { + var tooltip = self.tooltip().moveTo(-0xFFFF); + + if (e.control == self) { + var rel = tooltip.text(settings.tooltip).show().testMoveRel(self.getEl(), ['bc-tc', 'bc-tl', 'bc-tr']); + + tooltip.classes.toggle('tooltip-n', rel == 'bc-tc'); + tooltip.classes.toggle('tooltip-nw', rel == 'bc-tl'); + tooltip.classes.toggle('tooltip-ne', rel == 'bc-tr'); + + tooltip.moveRel(self.getEl(), rel); + } else { + tooltip.hide(); + } + }); + + self.on('mouseleave mousedown click', function() { + self.tooltip().hide(); + }); + } + + self.aria('label', settings.ariaLabel || settings.tooltip); + }, + + /** + * Returns the current tooltip instance. + * + * @method tooltip + * @return {tinymce.ui.Tooltip} Tooltip instance. + */ + tooltip: function() { + if (!tooltip) { + tooltip = new Tooltip({type: 'tooltip'}); + tooltip.renderTo(); + } + + return tooltip; + }, + + /** + * Called after the control has been rendered. + * + * @method postRender + */ + postRender: function() { + var self = this, settings = self.settings; + + self._super(); + + if (!self.parent() && (settings.width || settings.height)) { + self.initLayoutRect(); + self.repaint(); + } + + if (settings.autofocus) { + self.focus(); + } + }, + + bindStates: function() { + var self = this; + + function disable(state) { + self.aria('disabled', state); + self.classes.toggle('disabled', state); + } + + function active(state) { + self.aria('pressed', state); + self.classes.toggle('active', state); + } + + self.state.on('change:disabled', function(e) { + disable(e.value); + }); + + self.state.on('change:active', function(e) { + active(e.value); + }); + + if (self.state.get('disabled')) { + disable(true); + } + + if (self.state.get('active')) { + active(true); + } + + return self._super(); + }, + + /** + * Removes the current control from DOM and from UI collections. + * + * @method remove + * @return {tinymce.ui.Control} Current control instance. + */ + remove: function() { + this._super(); + + if (tooltip) { + tooltip.remove(); + tooltip = null; + } + } + }); + + return Widget; +}); + +// Included from: js/tinymce/classes/ui/Progress.js + +/** + * Progress.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Progress control. + * + * @-x-less Progress.less + * @class tinymce.ui.Progress + * @extends tinymce.ui.Control + */ +define("tinymce/ui/Progress", [ + "tinymce/ui/Widget" +], function(Widget) { + "use strict"; + + return Widget.extend({ + Defaults: { + value: 0 + }, + + init: function(settings) { + var self = this; + + self._super(settings); + self.classes.add('progress'); + + if (!self.settings.filter) { + self.settings.filter = function(value) { + return Math.round(value); + }; + } + }, + + renderHtml: function() { + var self = this, id = self._id, prefix = this.classPrefix; + + return ( + '<div id="' + id + '" class="' + self.classes + '">' + + '<div class="' + prefix + 'bar-container">' + + '<div class="' + prefix + 'bar"></div>' + + '</div>' + + '<div class="' + prefix + 'text">0%</div>' + + '</div>' + ); + }, + + postRender: function() { + var self = this; + + self._super(); + self.value(self.settings.value); + + return self; + }, + + bindStates: function() { + var self = this; + + function setValue(value) { + value = self.settings.filter(value); + self.getEl().lastChild.innerHTML = value + '%'; + self.getEl().firstChild.firstChild.style.width = value + '%'; + } + + self.state.on('change:value', function(e) { + setValue(e.value); + }); + + setValue(self.state.get('value')); + + return self._super(); + } + }); +}); + +// Included from: js/tinymce/classes/ui/Notification.js + +/** + * Notification.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Creates a notification instance. + * + * @-x-less Notification.less + * @class tinymce.ui.Notification + * @extends tinymce.ui.Container + * @mixes tinymce.ui.Movable + */ +define("tinymce/ui/Notification", [ + "tinymce/ui/Control", + "tinymce/ui/Movable", + "tinymce/ui/Progress", + "tinymce/util/Delay" +], function(Control, Movable, Progress, Delay) { + return Control.extend({ + Mixins: [Movable], + + Defaults: { + classes: 'widget notification' + }, + + init: function(settings) { + var self = this; + + self._super(settings); + + if (settings.text) { + self.text(settings.text); + } + + if (settings.icon) { + self.icon = settings.icon; + } + + if (settings.color) { + self.color = settings.color; + } + + if (settings.type) { + self.classes.add('notification-' + settings.type); + } + + if (settings.timeout && (settings.timeout < 0 || settings.timeout > 0) && !settings.closeButton) { + self.closeButton = false; + } else { + self.classes.add('has-close'); + self.closeButton = true; + } + + if (settings.progressBar) { + self.progressBar = new Progress(); + } + + self.on('click', function(e) { + if (e.target.className.indexOf(self.classPrefix + 'close') != -1) { + self.close(); + } + }); + }, + + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this, prefix = self.classPrefix, icon = '', closeButton = '', progressBar = '', notificationStyle = ''; + + if (self.icon) { + icon = '<i class="' + prefix + 'ico' + ' ' + prefix + 'i-' + self.icon + '"></i>'; + } + + if (self.color) { + notificationStyle = ' style="background-color: ' + self.color + '"'; + } + + if (self.closeButton) { + closeButton = '<button type="button" class="' + prefix + 'close" aria-hidden="true">\u00d7</button>'; + } + + if (self.progressBar) { + progressBar = self.progressBar.renderHtml(); + } + + return ( + '<div id="' + self._id + '" class="' + self.classes + '"' + notificationStyle + ' role="presentation">' + + icon + + '<div class="' + prefix + 'notification-inner">' + self.state.get('text') + '</div>' + + progressBar + + closeButton + + '</div>' + ); + }, + + postRender: function() { + var self = this; + + Delay.setTimeout(function() { + self.$el.addClass(self.classPrefix + 'in'); + }); + + return self._super(); + }, + + bindStates: function() { + var self = this; + + self.state.on('change:text', function(e) { + self.getEl().childNodes[1].innerHTML = e.value; + }); + if (self.progressBar) { + self.progressBar.bindStates(); + } + return self._super(); + }, + + close: function() { + var self = this; + + if (!self.fire('close').isDefaultPrevented()) { + self.remove(); + } + + return self; + }, + + /** + * Repaints the control after a layout operation. + * + * @method repaint + */ + repaint: function() { + var self = this, style, rect; + + style = self.getEl().style; + rect = self._layoutRect; + + style.left = rect.x + 'px'; + style.top = rect.y + 'px'; + style.zIndex = 0xFFFF + 0xFFFF; + } + }); +}); + +// Included from: js/tinymce/classes/NotificationManager.js + +/** + * NotificationManager.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class handles the creation of TinyMCE's notifications. + * + * @class tinymce.notificationManager + * @example + * // Opens a new notification of type "error" with text "An error occurred." + * tinymce.activeEditor.notificationManager.open({ + * text: 'An error occurred.', + * type: 'error' + * }); + */ +define("tinymce/NotificationManager", [ + "tinymce/ui/Notification", + "tinymce/util/Delay" +], function(Notification, Delay) { + return function(editor) { + var self = this, notifications = []; + + function getLastNotification() { + if (notifications.length) { + return notifications[notifications.length - 1]; + } + } + + self.notifications = notifications; + + function resizeWindowEvent() { + Delay.requestAnimationFrame(function() { + prePositionNotifications(); + positionNotifications(); + }); + } + + // Since the viewport will change based on the present notifications, we need to move them all to the + // top left of the viewport to give an accurate size measurement so we can position them later. + function prePositionNotifications() { + for (var i = 0; i < notifications.length; i++) { + notifications[i].moveTo(0, 0); + } + } + + function positionNotifications() { + if (notifications.length > 0) { + var firstItem = notifications.slice(0, 1)[0]; + var container = editor.inline ? editor.getElement() : editor.getContentAreaContainer(); + firstItem.moveRel(container, 'tc-tc'); + if (notifications.length > 1) { + for (var i = 1; i < notifications.length; i++) { + notifications[i].moveRel(notifications[i - 1].getEl(), 'bc-tc'); + } + } + } + } + + editor.on('remove', function() { + var i = notifications.length; + + while (i--) { + notifications[i].close(); + } + }); + + editor.on('ResizeEditor', positionNotifications); + editor.on('ResizeWindow', resizeWindowEvent); + + /** + * Opens a new notification. + * + * @method open + * @param {Object} args Optional name/value settings collection contains things like timeout/color/message etc. + */ + self.open = function(args) { + var notif; + + editor.editorManager.setActive(editor); + + notif = new Notification(args); + notifications.push(notif); + + //If we have a timeout value + if (args.timeout > 0) { + notif.timer = setTimeout(function() { + notif.close(); + }, args.timeout); + } + + notif.on('close', function() { + var i = notifications.length; + + if (notif.timer) { + editor.getWin().clearTimeout(notif.timer); + } + + while (i--) { + if (notifications[i] === notif) { + notifications.splice(i, 1); + } + } + + positionNotifications(); + }); + + notif.renderTo(); + + positionNotifications(); + + return notif; + }; + + /** + * Closes the top most notification. + * + * @method close + */ + self.close = function() { + if (getLastNotification()) { + getLastNotification().close(); + } + }; + + /** + * Returns the currently opened notification objects. + * + * @method getNotifications + * @return {Array} Array of the currently opened notifications. + */ + self.getNotifications = function() { + return notifications; + }; + + editor.on('SkinLoaded', function() { + var serviceMessage = editor.settings.service_message; + + if (serviceMessage) { + editor.notificationManager.open({ + text: serviceMessage, + type: 'warning', + timeout: 0, + icon: '' + }); + } + }); + + //self.positionNotifications = positionNotifications; + }; +}); + +// Included from: js/tinymce/classes/dom/NodePath.js + +/** + * NodePath.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Handles paths of nodes within an element. + * + * @private + * @class tinymce.dom.NodePath + */ +define("tinymce/dom/NodePath", [ + "tinymce/dom/DOMUtils" +], function(DOMUtils) { + function create(rootNode, targetNode, normalized) { + var path = []; + + for (; targetNode && targetNode != rootNode; targetNode = targetNode.parentNode) { + path.push(DOMUtils.nodeIndex(targetNode, normalized)); + } + + return path; + } + + function resolve(rootNode, path) { + var i, node, children; + + for (node = rootNode, i = path.length - 1; i >= 0; i--) { + children = node.childNodes; + + if (path[i] > children.length - 1) { + return null; + } + + node = children[path[i]]; + } + + return node; + } + + return { + create: create, + resolve: resolve + }; +}); + +// Included from: js/tinymce/classes/util/Quirks.js + +/** + * Quirks.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + * + * @ignore-file + */ + +/** + * This file includes fixes for various browser quirks it's made to make it easy to add/remove browser specific fixes. + * + * @private + * @class tinymce.util.Quirks + */ +define("tinymce/util/Quirks", [ + "tinymce/util/VK", + "tinymce/dom/RangeUtils", + "tinymce/dom/TreeWalker", + "tinymce/dom/NodePath", + "tinymce/html/Node", + "tinymce/html/Entities", + "tinymce/Env", + "tinymce/util/Tools", + "tinymce/util/Delay", + "tinymce/caret/CaretContainer" +], function(VK, RangeUtils, TreeWalker, NodePath, Node, Entities, Env, Tools, Delay, CaretContainer) { + return function(editor) { + var each = Tools.each, $ = editor.$; + var BACKSPACE = VK.BACKSPACE, DELETE = VK.DELETE, dom = editor.dom, selection = editor.selection, + settings = editor.settings, parser = editor.parser, serializer = editor.serializer; + var isGecko = Env.gecko, isIE = Env.ie, isWebKit = Env.webkit; + var mceInternalUrlPrefix = 'data:text/mce-internal,'; + var mceInternalDataType = isIE ? 'Text' : 'URL'; + + /** + * Executes a command with a specific state this can be to enable/disable browser editing features. + */ + function setEditorCommandState(cmd, state) { + try { + editor.getDoc().execCommand(cmd, false, state); + } catch (ex) { + // Ignore + } + } + + /** + * Returns current IE document mode. + */ + function getDocumentMode() { + var documentMode = editor.getDoc().documentMode; + + return documentMode ? documentMode : 6; + } + + /** + * Returns true/false if the event is prevented or not. + * + * @private + * @param {Event} e Event object. + * @return {Boolean} true/false if the event is prevented or not. + */ + function isDefaultPrevented(e) { + return e.isDefaultPrevented(); + } + + /** + * Sets Text/URL data on the event's dataTransfer object to a special data:text/mce-internal url. + * This is to workaround the inability to set custom contentType on IE and Safari. + * The editor's selected content is encoded into this url so drag and drop between editors will work. + * + * @private + * @param {DragEvent} e Event object + */ + function setMceInternalContent(e) { + var selectionHtml, internalContent; + + if (e.dataTransfer) { + if (editor.selection.isCollapsed() && e.target.tagName == 'IMG') { + selection.select(e.target); + } + + selectionHtml = editor.selection.getContent(); + + // Safari/IE doesn't support custom dataTransfer items so we can only use URL and Text + if (selectionHtml.length > 0) { + internalContent = mceInternalUrlPrefix + escape(editor.id) + ',' + escape(selectionHtml); + e.dataTransfer.setData(mceInternalDataType, internalContent); + } + } + } + + /** + * Gets content of special data:text/mce-internal url on the event's dataTransfer object. + * This is to workaround the inability to set custom contentType on IE and Safari. + * The editor's selected content is encoded into this url so drag and drop between editors will work. + * + * @private + * @param {DragEvent} e Event object + * @returns {String} mce-internal content + */ + function getMceInternalContent(e) { + var internalContent; + + if (e.dataTransfer) { + internalContent = e.dataTransfer.getData(mceInternalDataType); + + if (internalContent && internalContent.indexOf(mceInternalUrlPrefix) >= 0) { + internalContent = internalContent.substr(mceInternalUrlPrefix.length).split(','); + + return { + id: unescape(internalContent[0]), + html: unescape(internalContent[1]) + }; + } + } + + return null; + } + + /** + * Inserts contents using the paste clipboard command if it's available if it isn't it will fallback + * to the core command. + * + * @private + * @param {String} content Content to insert at selection. + */ + function insertClipboardContents(content) { + if (editor.queryCommandSupported('mceInsertClipboardContent')) { + editor.execCommand('mceInsertClipboardContent', false, {content: content}); + } else { + editor.execCommand('mceInsertContent', false, content); + } + } + + /** + * Fixes a WebKit bug when deleting contents using backspace or delete key. + * WebKit will produce a span element if you delete across two block elements. + * + * Example: + * <h1>a</h1><p>|b</p> + * + * Will produce this on backspace: + * <h1>a<span style="<all runtime styles>">b</span></p> + * + * This fixes the backspace to produce: + * <h1>a|b</p> + * + * See bug: https://bugs.webkit.org/show_bug.cgi?id=45784 + * + * This fixes the following delete scenarios: + * 1. Delete by pressing backspace key. + * 2. Delete by pressing delete key. + * 3. Delete by pressing backspace key with ctrl/cmd (Word delete). + * 4. Delete by pressing delete key with ctrl/cmd (Word delete). + * 5. Delete by drag/dropping contents inside the editor. + * 6. Delete by using Cut Ctrl+X/Cmd+X. + * 7. Delete by selecting contents and writing a character. + * + * This code is a ugly hack since writing full custom delete logic for just this bug + * fix seemed like a huge task. I hope we can remove this before the year 2030. + */ + function cleanupStylesWhenDeleting() { + var doc = editor.getDoc(), dom = editor.dom, selection = editor.selection; + var MutationObserver = window.MutationObserver, olderWebKit, dragStartRng; + + // Add mini polyfill for older WebKits + // TODO: Remove this when old Safari versions gets updated + if (!MutationObserver) { + olderWebKit = true; + + MutationObserver = function() { + var records = [], target; + + function nodeInsert(e) { + var target = e.relatedNode || e.target; + records.push({target: target, addedNodes: [target]}); + } + + function attrModified(e) { + var target = e.relatedNode || e.target; + records.push({target: target, attributeName: e.attrName}); + } + + this.observe = function(node) { + target = node; + target.addEventListener('DOMSubtreeModified', nodeInsert, false); + target.addEventListener('DOMNodeInsertedIntoDocument', nodeInsert, false); + target.addEventListener('DOMNodeInserted', nodeInsert, false); + target.addEventListener('DOMAttrModified', attrModified, false); + }; + + this.disconnect = function() { + target.removeEventListener('DOMSubtreeModified', nodeInsert, false); + target.removeEventListener('DOMNodeInsertedIntoDocument', nodeInsert, false); + target.removeEventListener('DOMNodeInserted', nodeInsert, false); + target.removeEventListener('DOMAttrModified', attrModified, false); + }; + + this.takeRecords = function() { + return records; + }; + }; + } + + function isTrailingBr(node) { + var blockElements = dom.schema.getBlockElements(), rootNode = editor.getBody(); + + if (node.nodeName != 'BR') { + return false; + } + + for (; node != rootNode && !blockElements[node.nodeName]; node = node.parentNode) { + if (node.nextSibling) { + return false; + } + } + + return true; + } + + function isSiblingsIgnoreWhiteSpace(node1, node2) { + var node; + + for (node = node1.nextSibling; node && node != node2; node = node.nextSibling) { + if (node.nodeType == 3 && $.trim(node.data).length === 0) { + continue; + } + + if (node !== node2) { + return false; + } + } + + return node === node2; + } + + function findCaretNode(node, forward, startNode) { + var walker, current, nonEmptyElements; + + nonEmptyElements = dom.schema.getNonEmptyElements(); + + walker = new TreeWalker(startNode || node, node); + + while ((current = walker[forward ? 'next' : 'prev']())) { + if (nonEmptyElements[current.nodeName] && !isTrailingBr(current)) { + return current; + } + + if (current.nodeType == 3 && current.data.length > 0) { + return current; + } + } + } + + function deleteRangeBetweenTextBlocks(rng) { + var startBlock, endBlock, caretNodeBefore, caretNodeAfter, textBlockElements; + + if (rng.collapsed) { + return; + } + + startBlock = dom.getParent(RangeUtils.getNode(rng.startContainer, rng.startOffset), dom.isBlock); + endBlock = dom.getParent(RangeUtils.getNode(rng.endContainer, rng.endOffset), dom.isBlock); + textBlockElements = editor.schema.getTextBlockElements(); + + if (startBlock == endBlock) { + return; + } + + if (!textBlockElements[startBlock.nodeName] || !textBlockElements[endBlock.nodeName]) { + return; + } + + if (dom.getContentEditable(startBlock) === "false" || dom.getContentEditable(endBlock) === "false") { + return; + } + + rng.deleteContents(); + + caretNodeBefore = findCaretNode(startBlock, false); + caretNodeAfter = findCaretNode(endBlock, true); + + if (!dom.isEmpty(endBlock)) { + $(startBlock).append(endBlock.childNodes); + } + + $(endBlock).remove(); + + if (caretNodeBefore) { + if (caretNodeBefore.nodeType == 1) { + if (caretNodeBefore.nodeName == "BR") { + rng.setStartBefore(caretNodeBefore); + rng.setEndBefore(caretNodeBefore); + } else { + rng.setStartAfter(caretNodeBefore); + rng.setEndAfter(caretNodeBefore); + } + } else { + rng.setStart(caretNodeBefore, caretNodeBefore.data.length); + rng.setEnd(caretNodeBefore, caretNodeBefore.data.length); + } + } else if (caretNodeAfter) { + if (caretNodeAfter.nodeType == 1) { + rng.setStartBefore(caretNodeAfter); + rng.setEndBefore(caretNodeAfter); + } else { + rng.setStart(caretNodeAfter, 0); + rng.setEnd(caretNodeAfter, 0); + } + } + + selection.setRng(rng); + + return true; + } + + function expandBetweenBlocks(rng, isForward) { + var caretNode, targetCaretNode, textBlock, targetTextBlock, container, offset; + + if (!rng.collapsed) { + return rng; + } + + container = rng.startContainer; + offset = rng.startOffset; + + if (container.nodeType == 3) { + if (isForward) { + if (offset < container.data.length) { + return rng; + } + } else { + if (offset > 0) { + return rng; + } + } + } + + caretNode = RangeUtils.getNode(rng.startContainer, rng.startOffset); + textBlock = dom.getParent(caretNode, dom.isBlock); + targetCaretNode = findCaretNode(editor.getBody(), isForward, caretNode); + targetTextBlock = dom.getParent(targetCaretNode, dom.isBlock); + + if (!caretNode || !targetCaretNode) { + return rng; + } + + if (targetTextBlock && textBlock != targetTextBlock) { + if (!isForward) { + if (!isSiblingsIgnoreWhiteSpace(targetTextBlock, textBlock)) { + return rng; + } + + if (targetCaretNode.nodeType == 1) { + if (targetCaretNode.nodeName == "BR") { + rng.setStartBefore(targetCaretNode); + } else { + rng.setStartAfter(targetCaretNode); + } + } else { + rng.setStart(targetCaretNode, targetCaretNode.data.length); + } + + if (caretNode.nodeType == 1) { + rng.setEnd(caretNode, 0); + } else { + rng.setEndBefore(caretNode); + } + } else { + if (!isSiblingsIgnoreWhiteSpace(textBlock, targetTextBlock)) { + return rng; + } + + if (caretNode.nodeType == 1) { + if (caretNode.nodeName == "BR") { + rng.setStartBefore(caretNode); + } else { + rng.setStartAfter(caretNode); + } + } else { + rng.setStart(caretNode, caretNode.data.length); + } + + if (targetCaretNode.nodeType == 1) { + rng.setEnd(targetCaretNode, 0); + } else { + rng.setEndBefore(targetCaretNode); + } + } + } + + return rng; + } + + function handleTextBlockMergeDelete(isForward) { + var rng = selection.getRng(); + + rng = expandBetweenBlocks(rng, isForward); + + if (deleteRangeBetweenTextBlocks(rng)) { + return true; + } + } + + /** + * This retains the formatting if the last character is to be deleted. + * + * Backspace on this: <p><b><i>a|</i></b></p> would become <p>|</p> in WebKit. + * With this patch: <p><b><i>|<br></i></b></p> + */ + function handleLastBlockCharacterDelete(isForward, rng) { + var path, blockElm, newBlockElm, clonedBlockElm, sibling, + container, offset, br, currentFormatNodes; + + function cloneTextBlockWithFormats(blockElm, node) { + currentFormatNodes = $(node).parents().filter(function(idx, node) { + return !!editor.schema.getTextInlineElements()[node.nodeName]; + }); + + newBlockElm = blockElm.cloneNode(false); + + currentFormatNodes = Tools.map(currentFormatNodes, function(formatNode) { + formatNode = formatNode.cloneNode(false); + + if (newBlockElm.hasChildNodes()) { + formatNode.appendChild(newBlockElm.firstChild); + newBlockElm.appendChild(formatNode); + } else { + newBlockElm.appendChild(formatNode); + } + + newBlockElm.appendChild(formatNode); + + return formatNode; + }); + + if (currentFormatNodes.length) { + br = dom.create('br'); + currentFormatNodes[0].appendChild(br); + dom.replace(newBlockElm, blockElm); + + rng.setStartBefore(br); + rng.setEndBefore(br); + editor.selection.setRng(rng); + + return br; + } + + return null; + } + + function isTextBlock(node) { + return node && editor.schema.getTextBlockElements()[node.tagName]; + } + + if (!rng.collapsed) { + return; + } + + container = rng.startContainer; + offset = rng.startOffset; + blockElm = dom.getParent(container, dom.isBlock); + if (!isTextBlock(blockElm)) { + return; + } + + if (container.nodeType == 1) { + container = container.childNodes[offset]; + if (container && container.tagName != 'BR') { + return; + } + + if (isForward) { + sibling = blockElm.nextSibling; + } else { + sibling = blockElm.previousSibling; + } + + if (dom.isEmpty(blockElm) && isTextBlock(sibling) && dom.isEmpty(sibling)) { + if (cloneTextBlockWithFormats(blockElm, container)) { + dom.remove(sibling); + return true; + } + } + } else if (container.nodeType == 3) { + path = NodePath.create(blockElm, container); + clonedBlockElm = blockElm.cloneNode(true); + container = NodePath.resolve(clonedBlockElm, path); + + if (isForward) { + if (offset >= container.data.length) { + return; + } + + container.deleteData(offset, 1); + } else { + if (offset <= 0) { + return; + } + + container.deleteData(offset - 1, 1); + } + + if (dom.isEmpty(clonedBlockElm)) { + return cloneTextBlockWithFormats(blockElm, container); + } + } + } + + function customDelete(isForward) { + var mutationObserver, rng, caretElement; + + if (handleTextBlockMergeDelete(isForward)) { + return; + } + + Tools.each(editor.getBody().getElementsByTagName('*'), function(elm) { + // Mark existing spans + if (elm.tagName == 'SPAN') { + elm.setAttribute('mce-data-marked', 1); + } + + // Make sure all elements has a data-mce-style attribute + if (!elm.hasAttribute('data-mce-style') && elm.hasAttribute('style')) { + editor.dom.setAttrib(elm, 'style', editor.dom.getAttrib(elm, 'style')); + } + }); + + // Observe added nodes and style attribute changes + mutationObserver = new MutationObserver(function() {}); + mutationObserver.observe(editor.getDoc(), { + childList: true, + attributes: true, + subtree: true, + attributeFilter: ['style'] + }); + + editor.getDoc().execCommand(isForward ? 'ForwardDelete' : 'Delete', false, null); + + rng = editor.selection.getRng(); + caretElement = rng.startContainer.parentNode; + + Tools.each(mutationObserver.takeRecords(), function(record) { + if (!dom.isChildOf(record.target, editor.getBody())) { + return; + } + + // Restore style attribute to previous value + if (record.attributeName == "style") { + var oldValue = record.target.getAttribute('data-mce-style'); + + if (oldValue) { + record.target.setAttribute("style", oldValue); + } else { + record.target.removeAttribute("style"); + } + } + + // Remove all spans that aren't marked and retain selection + Tools.each(record.addedNodes, function(node) { + if (node.nodeName == "SPAN" && !node.getAttribute('mce-data-marked')) { + var offset, container; + + if (node == caretElement) { + offset = rng.startOffset; + container = node.firstChild; + } + + dom.remove(node, true); + + if (container) { + rng.setStart(container, offset); + rng.setEnd(container, offset); + editor.selection.setRng(rng); + } + } + }); + }); + + mutationObserver.disconnect(); + + // Remove any left over marks + Tools.each(editor.dom.select('span[mce-data-marked]'), function(span) { + span.removeAttribute('mce-data-marked'); + }); + } + + editor.on('keydown', function(e) { + var isForward = e.keyCode == DELETE, isMetaOrCtrl = e.ctrlKey || e.metaKey; + + if (!isDefaultPrevented(e) && (isForward || e.keyCode == BACKSPACE)) { + var rng = editor.selection.getRng(), container = rng.startContainer, offset = rng.startOffset; + + // Shift+Delete is cut + if (isForward && e.shiftKey) { + return; + } + + if (handleLastBlockCharacterDelete(isForward, rng)) { + e.preventDefault(); + return; + } + + // Ignore non meta delete in the where there is text before/after the caret + if (!isMetaOrCtrl && rng.collapsed && container.nodeType == 3) { + if (isForward ? offset < container.data.length : offset > 0) { + return; + } + } + + e.preventDefault(); + + if (isMetaOrCtrl) { + editor.selection.getSel().modify("extend", isForward ? "forward" : "backward", e.metaKey ? "lineboundary" : "word"); + } + + customDelete(isForward); + } + }); + + // Handle case where text is deleted by typing over + editor.on('keypress', function(e) { + if (!isDefaultPrevented(e) && !selection.isCollapsed() && e.charCode > 31 && !VK.metaKeyPressed(e)) { + var rng, currentFormatNodes, fragmentNode, blockParent, caretNode, charText; + + rng = editor.selection.getRng(); + charText = String.fromCharCode(e.charCode); + e.preventDefault(); + + // Keep track of current format nodes + currentFormatNodes = $(rng.startContainer).parents().filter(function(idx, node) { + return !!editor.schema.getTextInlineElements()[node.nodeName]; + }); + + customDelete(true); + + // Check if the browser removed them + currentFormatNodes = currentFormatNodes.filter(function(idx, node) { + return !$.contains(editor.getBody(), node); + }); + + // Then re-add them + if (currentFormatNodes.length) { + fragmentNode = dom.createFragment(); + + currentFormatNodes.each(function(idx, formatNode) { + formatNode = formatNode.cloneNode(false); + + if (fragmentNode.hasChildNodes()) { + formatNode.appendChild(fragmentNode.firstChild); + fragmentNode.appendChild(formatNode); + } else { + caretNode = formatNode; + fragmentNode.appendChild(formatNode); + } + + fragmentNode.appendChild(formatNode); + }); + + caretNode.appendChild(editor.getDoc().createTextNode(charText)); + + // Prevent edge case where older WebKit would add an extra BR element + blockParent = dom.getParent(rng.startContainer, dom.isBlock); + if (dom.isEmpty(blockParent)) { + $(blockParent).empty().append(fragmentNode); + } else { + rng.insertNode(fragmentNode); + } + + rng.setStart(caretNode.firstChild, 1); + rng.setEnd(caretNode.firstChild, 1); + editor.selection.setRng(rng); + } else { + editor.selection.setContent(charText); + } + } + }); + + editor.addCommand('Delete', function() { + customDelete(); + }); + + editor.addCommand('ForwardDelete', function() { + customDelete(true); + }); + + // Older WebKits doesn't properly handle the clipboard so we can't add the rest + if (olderWebKit) { + return; + } + + editor.on('dragstart', function(e) { + dragStartRng = selection.getRng(); + setMceInternalContent(e); + }); + + editor.on('drop', function(e) { + if (!isDefaultPrevented(e)) { + var internalContent = getMceInternalContent(e); + + if (internalContent) { + e.preventDefault(); + + // Safari has a weird issue where drag/dropping images sometimes + // produces a green plus icon. When this happens the caretRangeFromPoint + // will return "null" even though the x, y coordinate is correct. + // But if we detach the insert from the drop event we will get a proper range + Delay.setEditorTimeout(editor, function() { + var pointRng = RangeUtils.getCaretRangeFromPoint(e.x, e.y, doc); + + if (dragStartRng) { + selection.setRng(dragStartRng); + dragStartRng = null; + } + + customDelete(); + selection.setRng(pointRng); + insertClipboardContents(internalContent.html); + }); + } + } + }); + + editor.on('cut', function(e) { + if (!isDefaultPrevented(e) && e.clipboardData && !editor.selection.isCollapsed()) { + e.preventDefault(); + e.clipboardData.clearData(); + e.clipboardData.setData('text/html', editor.selection.getContent()); + e.clipboardData.setData('text/plain', editor.selection.getContent({format: 'text'})); + + // Needed delay for https://code.google.com/p/chromium/issues/detail?id=363288#c3 + // Nested delete/forwardDelete not allowed on execCommand("cut") + // This is ugly but not sure how to work around it otherwise + Delay.setEditorTimeout(editor, function() { + customDelete(true); + }); + } + }); + } + + /** + * Makes sure that the editor body becomes empty when backspace or delete is pressed in empty editors. + * + * For example: + * <p><b>|</b></p> + * + * Or: + * <h1>|</h1> + * + * Or: + * [<h1></h1>] + */ + function emptyEditorWhenDeleting() { + function serializeRng(rng) { + var body = dom.create("body"); + var contents = rng.cloneContents(); + body.appendChild(contents); + return selection.serializer.serialize(body, {format: 'html'}); + } + + function allContentsSelected(rng) { + if (!rng.setStart) { + if (rng.item) { + return false; + } + + var bodyRng = rng.duplicate(); + bodyRng.moveToElementText(editor.getBody()); + return RangeUtils.compareRanges(rng, bodyRng); + } + + var selection = serializeRng(rng); + + var allRng = dom.createRng(); + allRng.selectNode(editor.getBody()); + + var allSelection = serializeRng(allRng); + return selection === allSelection; + } + + editor.on('keydown', function(e) { + var keyCode = e.keyCode, isCollapsed, body; + + // Empty the editor if it's needed for example backspace at <p><b>|</b></p> + if (!isDefaultPrevented(e) && (keyCode == DELETE || keyCode == BACKSPACE)) { + isCollapsed = editor.selection.isCollapsed(); + body = editor.getBody(); + + // Selection is collapsed but the editor isn't empty + if (isCollapsed && !dom.isEmpty(body)) { + return; + } + + // Selection isn't collapsed but not all the contents is selected + if (!isCollapsed && !allContentsSelected(editor.selection.getRng())) { + return; + } + + // Manually empty the editor + e.preventDefault(); + editor.setContent(''); + + if (body.firstChild && dom.isBlock(body.firstChild)) { + editor.selection.setCursorLocation(body.firstChild, 0); + } else { + editor.selection.setCursorLocation(body, 0); + } + + editor.nodeChanged(); + } + }); + } + + /** + * WebKit doesn't select all the nodes in the body when you press Ctrl+A. + * IE selects more than the contents <body>[<p>a</p>]</body> instead of <body><p>[a]</p]</body> see bug #6438 + * This selects the whole body so that backspace/delete logic will delete everything + */ + function selectAll() { + editor.shortcuts.add('meta+a', null, 'SelectAll'); + } + + /** + * WebKit has a weird issue where it some times fails to properly convert keypresses to input method keystrokes. + * The IME on Mac doesn't initialize when it doesn't fire a proper focus event. + * + * This seems to happen when the user manages to click the documentElement element then the window doesn't get proper focus until + * you enter a character into the editor. + * + * It also happens when the first focus in made to the body. + * + * See: https://bugs.webkit.org/show_bug.cgi?id=83566 + */ + function inputMethodFocus() { + if (!editor.settings.content_editable) { + // Case 1 IME doesn't initialize if you focus the document + // Disabled since it was interferring with the cE=false logic + // Also coultn't reproduce the issue on Safari 9 + /*dom.bind(editor.getDoc(), 'focusin', function() { + selection.setRng(selection.getRng()); + });*/ + + // Case 2 IME doesn't initialize if you click the documentElement it also doesn't properly fire the focusin event + // Needs to be both down/up due to weird rendering bug on Chrome Windows + dom.bind(editor.getDoc(), 'mousedown mouseup', function(e) { + var rng; + + if (e.target == editor.getDoc().documentElement) { + rng = selection.getRng(); + editor.getBody().focus(); + + if (e.type == 'mousedown') { + if (CaretContainer.isCaretContainer(rng.startContainer)) { + return; + } + + // Edge case for mousedown, drag select and mousedown again within selection on Chrome Windows to render caret + selection.placeCaretAt(e.clientX, e.clientY); + } else { + selection.setRng(rng); + } + } + }); + } + } + + /** + * Backspacing in FireFox/IE from a paragraph into a horizontal rule results in a floating text node because the + * browser just deletes the paragraph - the browser fails to merge the text node with a horizontal rule so it is + * left there. TinyMCE sees a floating text node and wraps it in a paragraph on the key up event (ForceBlocks.js + * addRootBlocks), meaning the action does nothing. With this code, FireFox/IE matche the behaviour of other + * browsers. + * + * It also fixes a bug on Firefox where it's impossible to delete HR elements. + */ + function removeHrOnBackspace() { + editor.on('keydown', function(e) { + if (!isDefaultPrevented(e) && e.keyCode === BACKSPACE) { + // Check if there is any HR elements this is faster since getRng on IE 7 & 8 is slow + if (!editor.getBody().getElementsByTagName('hr').length) { + return; + } + + if (selection.isCollapsed() && selection.getRng(true).startOffset === 0) { + var node = selection.getNode(); + var previousSibling = node.previousSibling; + + if (node.nodeName == 'HR') { + dom.remove(node); + e.preventDefault(); + return; + } + + if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === "hr") { + dom.remove(previousSibling); + e.preventDefault(); + } + } + } + }); + } + + /** + * Firefox 3.x has an issue where the body element won't get proper focus if you click out + * side it's rectangle. + */ + function focusBody() { + // Fix for a focus bug in FF 3.x where the body element + // wouldn't get proper focus if the user clicked on the HTML element + if (!window.Range.prototype.getClientRects) { // Detect getClientRects got introduced in FF 4 + editor.on('mousedown', function(e) { + if (!isDefaultPrevented(e) && e.target.nodeName === "HTML") { + var body = editor.getBody(); + + // Blur the body it's focused but not correctly focused + body.blur(); + + // Refocus the body after a little while + Delay.setEditorTimeout(editor, function() { + body.focus(); + }); + } + }); + } + } + + /** + * WebKit has a bug where it isn't possible to select image, hr or anchor elements + * by clicking on them so we need to fake that. + */ + function selectControlElements() { + editor.on('click', function(e) { + var target = e.target; + + // Workaround for bug, http://bugs.webkit.org/show_bug.cgi?id=12250 + // WebKit can't even do simple things like selecting an image + // Needs to be the setBaseAndExtend or it will fail to select floated images + if (/^(IMG|HR)$/.test(target.nodeName) && dom.getContentEditableParent(target) !== "false") { + e.preventDefault(); + selection.getSel().setBaseAndExtent(target, 0, target, 1); + editor.nodeChanged(); + } + + if (target.nodeName == 'A' && dom.hasClass(target, 'mce-item-anchor')) { + e.preventDefault(); + selection.select(target); + } + }); + } + + /** + * Fixes a Gecko bug where the style attribute gets added to the wrong element when deleting between two block elements. + * + * Fixes do backspace/delete on this: + * <p>bla[ck</p><p style="color:red">r]ed</p> + * + * Would become: + * <p>bla|ed</p> + * + * Instead of: + * <p style="color:red">bla|ed</p> + */ + function removeStylesWhenDeletingAcrossBlockElements() { + function getAttributeApplyFunction() { + var template = dom.getAttribs(selection.getStart().cloneNode(false)); + + return function() { + var target = selection.getStart(); + + if (target !== editor.getBody()) { + dom.setAttrib(target, "style", null); + + each(template, function(attr) { + target.setAttributeNode(attr.cloneNode(true)); + }); + } + }; + } + + function isSelectionAcrossElements() { + return !selection.isCollapsed() && + dom.getParent(selection.getStart(), dom.isBlock) != dom.getParent(selection.getEnd(), dom.isBlock); + } + + editor.on('keypress', function(e) { + var applyAttributes; + + if (!isDefaultPrevented(e) && (e.keyCode == 8 || e.keyCode == 46) && isSelectionAcrossElements()) { + applyAttributes = getAttributeApplyFunction(); + editor.getDoc().execCommand('delete', false, null); + applyAttributes(); + e.preventDefault(); + return false; + } + }); + + dom.bind(editor.getDoc(), 'cut', function(e) { + var applyAttributes; + + if (!isDefaultPrevented(e) && isSelectionAcrossElements()) { + applyAttributes = getAttributeApplyFunction(); + + Delay.setEditorTimeout(editor, function() { + applyAttributes(); + }); + } + }); + } + + /** + * Screen readers on IE needs to have the role application set on the body. + */ + function ensureBodyHasRoleApplication() { + document.body.setAttribute("role", "application"); + } + + /** + * Backspacing into a table behaves differently depending upon browser type. + * Therefore, disable Backspace when cursor immediately follows a table. + */ + function disableBackspaceIntoATable() { + editor.on('keydown', function(e) { + if (!isDefaultPrevented(e) && e.keyCode === BACKSPACE) { + if (selection.isCollapsed() && selection.getRng(true).startOffset === 0) { + var previousSibling = selection.getNode().previousSibling; + if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === "table") { + e.preventDefault(); + return false; + } + } + } + }); + } + + /** + * Old IE versions can't properly render BR elements in PRE tags white in contentEditable mode. So this + * logic adds a \n before the BR so that it will get rendered. + */ + function addNewLinesBeforeBrInPre() { + // IE8+ rendering mode does the right thing with BR in PRE + if (getDocumentMode() > 7) { + return; + } + + // Enable display: none in area and add a specific class that hides all BR elements in PRE to + // avoid the caret from getting stuck at the BR elements while pressing the right arrow key + setEditorCommandState('RespectVisibilityInDesign', true); + editor.contentStyles.push('.mceHideBrInPre pre br {display: none}'); + dom.addClass(editor.getBody(), 'mceHideBrInPre'); + + // Adds a \n before all BR elements in PRE to get them visual + parser.addNodeFilter('pre', function(nodes) { + var i = nodes.length, brNodes, j, brElm, sibling; + + while (i--) { + brNodes = nodes[i].getAll('br'); + j = brNodes.length; + while (j--) { + brElm = brNodes[j]; + + // Add \n before BR in PRE elements on older IE:s so the new lines get rendered + sibling = brElm.prev; + if (sibling && sibling.type === 3 && sibling.value.charAt(sibling.value - 1) != '\n') { + sibling.value += '\n'; + } else { + brElm.parent.insert(new Node('#text', 3), brElm, true).value = '\n'; + } + } + } + }); + + // Removes any \n before BR elements in PRE since other browsers and in contentEditable=false mode they will be visible + serializer.addNodeFilter('pre', function(nodes) { + var i = nodes.length, brNodes, j, brElm, sibling; + + while (i--) { + brNodes = nodes[i].getAll('br'); + j = brNodes.length; + while (j--) { + brElm = brNodes[j]; + sibling = brElm.prev; + if (sibling && sibling.type == 3) { + sibling.value = sibling.value.replace(/\r?\n$/, ''); + } + } + } + }); + } + + /** + * Moves style width/height to attribute width/height when the user resizes an image on IE. + */ + function removePreSerializedStylesWhenSelectingControls() { + dom.bind(editor.getBody(), 'mouseup', function() { + var value, node = selection.getNode(); + + // Moved styles to attributes on IMG eements + if (node.nodeName == 'IMG') { + // Convert style width to width attribute + if ((value = dom.getStyle(node, 'width'))) { + dom.setAttrib(node, 'width', value.replace(/[^0-9%]+/g, '')); + dom.setStyle(node, 'width', ''); + } + + // Convert style height to height attribute + if ((value = dom.getStyle(node, 'height'))) { + dom.setAttrib(node, 'height', value.replace(/[^0-9%]+/g, '')); + dom.setStyle(node, 'height', ''); + } + } + }); + } + + /** + * Removes a blockquote when backspace is pressed at the beginning of it. + * + * For example: + * <blockquote><p>|x</p></blockquote> + * + * Becomes: + * <p>|x</p> + */ + function removeBlockQuoteOnBackSpace() { + // Add block quote deletion handler + editor.on('keydown', function(e) { + var rng, container, offset, root, parent; + + if (isDefaultPrevented(e) || e.keyCode != VK.BACKSPACE) { + return; + } + + rng = selection.getRng(); + container = rng.startContainer; + offset = rng.startOffset; + root = dom.getRoot(); + parent = container; + + if (!rng.collapsed || offset !== 0) { + return; + } + + while (parent && parent.parentNode && parent.parentNode.firstChild == parent && parent.parentNode != root) { + parent = parent.parentNode; + } + + // Is the cursor at the beginning of a blockquote? + if (parent.tagName === 'BLOCKQUOTE') { + // Remove the blockquote + editor.formatter.toggle('blockquote', null, parent); + + // Move the caret to the beginning of container + rng = dom.createRng(); + rng.setStart(container, 0); + rng.setEnd(container, 0); + selection.setRng(rng); + } + }); + } + + /** + * Sets various Gecko editing options on mouse down and before a execCommand to disable inline table editing that is broken etc. + */ + function setGeckoEditingOptions() { + function setOpts() { + refreshContentEditable(); + + setEditorCommandState("StyleWithCSS", false); + setEditorCommandState("enableInlineTableEditing", false); + + if (!settings.object_resizing) { + setEditorCommandState("enableObjectResizing", false); + } + } + + if (!settings.readonly) { + editor.on('BeforeExecCommand MouseDown', setOpts); + } + } + + /** + * Fixes a gecko link bug, when a link is placed at the end of block elements there is + * no way to move the caret behind the link. This fix adds a bogus br element after the link. + * + * For example this: + * <p><b><a href="#">x</a></b></p> + * + * Becomes this: + * <p><b><a href="#">x</a></b><br></p> + */ + function addBrAfterLastLinks() { + function fixLinks() { + each(dom.select('a'), function(node) { + var parentNode = node.parentNode, root = dom.getRoot(); + + if (parentNode.lastChild === node) { + while (parentNode && !dom.isBlock(parentNode)) { + if (parentNode.parentNode.lastChild !== parentNode || parentNode === root) { + return; + } + + parentNode = parentNode.parentNode; + } + + dom.add(parentNode, 'br', {'data-mce-bogus': 1}); + } + }); + } + + editor.on('SetContent ExecCommand', function(e) { + if (e.type == "setcontent" || e.command === 'mceInsertLink') { + fixLinks(); + } + }); + } + + /** + * WebKit will produce DIV elements here and there by default. But since TinyMCE uses paragraphs by + * default we want to change that behavior. + */ + function setDefaultBlockType() { + if (settings.forced_root_block) { + editor.on('init', function() { + setEditorCommandState('DefaultParagraphSeparator', settings.forced_root_block); + }); + } + } + + /** + * Deletes the selected image on IE instead of navigating to previous page. + */ + function deleteControlItemOnBackSpace() { + editor.on('keydown', function(e) { + var rng; + + if (!isDefaultPrevented(e) && e.keyCode == BACKSPACE) { + rng = editor.getDoc().selection.createRange(); + if (rng && rng.item) { + e.preventDefault(); + editor.undoManager.beforeChange(); + dom.remove(rng.item(0)); + editor.undoManager.add(); + } + } + }); + } + + /** + * IE10 doesn't properly render block elements with the right height until you add contents to them. + * This fixes that by adding a padding-right to all empty text block elements. + * See: https://connect.microsoft.com/IE/feedback/details/743881 + */ + function renderEmptyBlocksFix() { + var emptyBlocksCSS; + + // IE10+ + if (getDocumentMode() >= 10) { + emptyBlocksCSS = ''; + each('p div h1 h2 h3 h4 h5 h6'.split(' '), function(name, i) { + emptyBlocksCSS += (i > 0 ? ',' : '') + name + ':empty'; + }); + + editor.contentStyles.push(emptyBlocksCSS + '{padding-right: 1px !important}'); + } + } + + /** + * Old IE versions can't retain contents within noscript elements so this logic will store the contents + * as a attribute and the insert that value as it's raw text when the DOM is serialized. + */ + function keepNoScriptContents() { + if (getDocumentMode() < 9) { + parser.addNodeFilter('noscript', function(nodes) { + var i = nodes.length, node, textNode; + + while (i--) { + node = nodes[i]; + textNode = node.firstChild; + + if (textNode) { + node.attr('data-mce-innertext', textNode.value); + } + } + }); + + serializer.addNodeFilter('noscript', function(nodes) { + var i = nodes.length, node, textNode, value; + + while (i--) { + node = nodes[i]; + textNode = nodes[i].firstChild; + + if (textNode) { + textNode.value = Entities.decode(textNode.value); + } else { + // Old IE can't retain noscript value so an attribute is used to store it + value = node.attributes.map['data-mce-innertext']; + if (value) { + node.attr('data-mce-innertext', null); + textNode = new Node('#text', 3); + textNode.value = value; + textNode.raw = true; + node.append(textNode); + } + } + } + }); + } + } + + /** + * IE has an issue where you can't select/move the caret by clicking outside the body if the document is in standards mode. + */ + function fixCaretSelectionOfDocumentElementOnIe() { + var doc = dom.doc, body = doc.body, started, startRng, htmlElm; + + // Return range from point or null if it failed + function rngFromPoint(x, y) { + var rng = body.createTextRange(); + + try { + rng.moveToPoint(x, y); + } catch (ex) { + // IE sometimes throws and exception, so lets just ignore it + rng = null; + } + + return rng; + } + + // Fires while the selection is changing + function selectionChange(e) { + var pointRng; + + // Check if the button is down or not + if (e.button) { + // Create range from mouse position + pointRng = rngFromPoint(e.x, e.y); + + if (pointRng) { + // Check if pointRange is before/after selection then change the endPoint + if (pointRng.compareEndPoints('StartToStart', startRng) > 0) { + pointRng.setEndPoint('StartToStart', startRng); + } else { + pointRng.setEndPoint('EndToEnd', startRng); + } + + pointRng.select(); + } + } else { + endSelection(); + } + } + + // Removes listeners + function endSelection() { + var rng = doc.selection.createRange(); + + // If the range is collapsed then use the last start range + if (startRng && !rng.item && rng.compareEndPoints('StartToEnd', rng) === 0) { + startRng.select(); + } + + dom.unbind(doc, 'mouseup', endSelection); + dom.unbind(doc, 'mousemove', selectionChange); + startRng = started = 0; + } + + // Make HTML element unselectable since we are going to handle selection by hand + doc.documentElement.unselectable = true; + + // Detect when user selects outside BODY + dom.bind(doc, 'mousedown contextmenu', function(e) { + if (e.target.nodeName === 'HTML') { + if (started) { + endSelection(); + } + + // Detect vertical scrollbar, since IE will fire a mousedown on the scrollbar and have target set as HTML + htmlElm = doc.documentElement; + if (htmlElm.scrollHeight > htmlElm.clientHeight) { + return; + } + + started = 1; + // Setup start position + startRng = rngFromPoint(e.x, e.y); + if (startRng) { + // Listen for selection change events + dom.bind(doc, 'mouseup', endSelection); + dom.bind(doc, 'mousemove', selectionChange); + + dom.getRoot().focus(); + startRng.select(); + } + } + }); + } + + /** + * Fixes selection issues where the caret can be placed between two inline elements like <b>a</b>|<b>b</b> + * this fix will lean the caret right into the closest inline element. + */ + function normalizeSelection() { + // Normalize selection for example <b>a</b><i>|a</i> becomes <b>a|</b><i>a</i> except for Ctrl+A since it selects everything + editor.on('keyup focusin mouseup', function(e) { + if (e.keyCode != 65 || !VK.metaKeyPressed(e)) { + selection.normalize(); + } + }, true); + } + + /** + * Forces Gecko to render a broken image icon if it fails to load an image. + */ + function showBrokenImageIcon() { + editor.contentStyles.push( + 'img:-moz-broken {' + + '-moz-force-broken-image-icon:1;' + + 'min-width:24px;' + + 'min-height:24px' + + '}' + ); + } + + /** + * iOS has a bug where it's impossible to type if the document has a touchstart event + * bound and the user touches the document while having the on screen keyboard visible. + * + * The touch event moves the focus to the parent document while having the caret inside the iframe + * this fix moves the focus back into the iframe document. + */ + function restoreFocusOnKeyDown() { + if (!editor.inline) { + editor.on('keydown', function() { + if (document.activeElement == document.body) { + editor.getWin().focus(); + } + }); + } + } + + /** + * IE 11 has an annoying issue where you can't move focus into the editor + * by clicking on the white area HTML element. We used to be able to to fix this with + * the fixCaretSelectionOfDocumentElementOnIe fix. But since M$ removed the selection + * object it's not possible anymore. So we need to hack in a ungly CSS to force the + * body to be at least 150px. If the user clicks the HTML element out side this 150px region + * we simply move the focus into the first paragraph. Not ideal since you loose the + * positioning of the caret but goot enough for most cases. + */ + function bodyHeight() { + if (!editor.inline) { + editor.contentStyles.push('body {min-height: 150px}'); + editor.on('click', function(e) { + var rng; + + if (e.target.nodeName == 'HTML') { + // Edge seems to only need focus if we set the range + // the caret will become invisible and moved out of the iframe!! + if (Env.ie > 11) { + editor.getBody().focus(); + return; + } + + // Need to store away non collapsed ranges since the focus call will mess that up see #7382 + rng = editor.selection.getRng(); + editor.getBody().focus(); + editor.selection.setRng(rng); + editor.selection.normalize(); + editor.nodeChanged(); + } + }); + } + } + + /** + * Firefox on Mac OS will move the browser back to the previous page if you press CMD+Left arrow. + * You might then loose all your work so we need to block that behavior and replace it with our own. + */ + function blockCmdArrowNavigation() { + if (Env.mac) { + editor.on('keydown', function(e) { + if (VK.metaKeyPressed(e) && !e.shiftKey && (e.keyCode == 37 || e.keyCode == 39)) { + e.preventDefault(); + editor.selection.getSel().modify('move', e.keyCode == 37 ? 'backward' : 'forward', 'lineboundary'); + } + }); + } + } + + /** + * Disables the autolinking in IE 9+ this is then re-enabled by the autolink plugin. + */ + function disableAutoUrlDetect() { + setEditorCommandState("AutoUrlDetect", false); + } + + /** + * iOS 7.1 introduced two new bugs: + * 1) It's possible to open links within a contentEditable area by clicking on them. + * 2) If you hold down the finger it will display the link/image touch callout menu. + */ + function tapLinksAndImages() { + editor.on('click', function(e) { + var elm = e.target; + + do { + if (elm.tagName === 'A') { + e.preventDefault(); + return; + } + } while ((elm = elm.parentNode)); + }); + + editor.contentStyles.push('.mce-content-body {-webkit-touch-callout: none}'); + } + + /** + * iOS Safari and possible other browsers have a bug where it won't fire + * a click event when a contentEditable is focused. This function fakes click events + * by using touchstart/touchend and measuring the time and distance travelled. + */ + /* + function touchClickEvent() { + editor.on('touchstart', function(e) { + var elm, time, startTouch, changedTouches; + + elm = e.target; + time = new Date().getTime(); + changedTouches = e.changedTouches; + + if (!changedTouches || changedTouches.length > 1) { + return; + } + + startTouch = changedTouches[0]; + + editor.once('touchend', function(e) { + var endTouch = e.changedTouches[0], args; + + if (new Date().getTime() - time > 500) { + return; + } + + if (Math.abs(startTouch.clientX - endTouch.clientX) > 5) { + return; + } + + if (Math.abs(startTouch.clientY - endTouch.clientY) > 5) { + return; + } + + args = { + target: elm + }; + + each('pageX pageY clientX clientY screenX screenY'.split(' '), function(key) { + args[key] = endTouch[key]; + }); + + args = editor.fire('click', args); + + if (!args.isDefaultPrevented()) { + // iOS WebKit can't place the caret properly once + // you bind touch events so we need to do this manually + // TODO: Expand to the closest word? Touble tap still works. + editor.selection.placeCaretAt(endTouch.clientX, endTouch.clientY); + editor.nodeChanged(); + } + }); + }); + } + */ + + /** + * WebKit has a bug where it will allow forms to be submitted if they are inside a contentEditable element. + * For example this: <form><button></form> + */ + function blockFormSubmitInsideEditor() { + editor.on('init', function() { + editor.dom.bind(editor.getBody(), 'submit', function(e) { + e.preventDefault(); + }); + }); + } + + /** + * Sometimes WebKit/Blink generates BR elements with the Apple-interchange-newline class. + * + * Scenario: + * 1) Create a table 2x2. + * 2) Select and copy cells A2-B2. + * 3) Paste and it will add BR element to table cell. + */ + function removeAppleInterchangeBrs() { + parser.addNodeFilter('br', function(nodes) { + var i = nodes.length; + + while (i--) { + if (nodes[i].attr('class') == 'Apple-interchange-newline') { + nodes[i].remove(); + } + } + }); + } + + /** + * IE cannot set custom contentType's on drag events, and also does not properly drag/drop between + * editors. This uses a special data:text/mce-internal URL to pass data when drag/drop between editors. + */ + function ieInternalDragAndDrop() { + editor.on('dragstart', function(e) { + setMceInternalContent(e); + }); + + editor.on('drop', function(e) { + if (!isDefaultPrevented(e)) { + var internalContent = getMceInternalContent(e); + + if (internalContent && internalContent.id != editor.id) { + e.preventDefault(); + + var rng = RangeUtils.getCaretRangeFromPoint(e.x, e.y, editor.getDoc()); + selection.setRng(rng); + insertClipboardContents(internalContent.html); + } + } + }); + } + + function refreshContentEditable() { + var body, parent; + + // Check if the editor was hidden and the re-initialize contentEditable mode by removing and adding the body again + if (isHidden()) { + body = editor.getBody(); + parent = body.parentNode; + + parent.removeChild(body); + parent.appendChild(body); + + body.focus(); + } + } + + function isHidden() { + var sel; + + if (!isGecko) { + return 0; + } + + // Weird, wheres that cursor selection? + sel = editor.selection.getSel(); + return (!sel || !sel.rangeCount || sel.rangeCount === 0); + } + + // All browsers + removeBlockQuoteOnBackSpace(); + emptyEditorWhenDeleting(); + + // Windows phone will return a range like [body, 0] on mousedown so + // it will always normalize to the wrong location + if (!Env.windowsPhone) { + normalizeSelection(); + } + + // WebKit + if (isWebKit) { + cleanupStylesWhenDeleting(); + inputMethodFocus(); + selectControlElements(); + setDefaultBlockType(); + blockFormSubmitInsideEditor(); + disableBackspaceIntoATable(); + removeAppleInterchangeBrs(); + //touchClickEvent(); + + // iOS + if (Env.iOS) { + restoreFocusOnKeyDown(); + bodyHeight(); + tapLinksAndImages(); + } else { + selectAll(); + } + } + + // IE + if (isIE && Env.ie < 11) { + removeHrOnBackspace(); + ensureBodyHasRoleApplication(); + addNewLinesBeforeBrInPre(); + removePreSerializedStylesWhenSelectingControls(); + deleteControlItemOnBackSpace(); + renderEmptyBlocksFix(); + keepNoScriptContents(); + fixCaretSelectionOfDocumentElementOnIe(); + } + + if (Env.ie >= 11) { + bodyHeight(); + disableBackspaceIntoATable(); + } + + if (Env.ie) { + selectAll(); + disableAutoUrlDetect(); + ieInternalDragAndDrop(); + } + + // Gecko + if (isGecko) { + removeHrOnBackspace(); + focusBody(); + removeStylesWhenDeletingAcrossBlockElements(); + setGeckoEditingOptions(); + addBrAfterLastLinks(); + showBrokenImageIcon(); + blockCmdArrowNavigation(); + disableBackspaceIntoATable(); + } + + return { + refreshContentEditable: refreshContentEditable, + isHidden: isHidden + }; + }; +}); + +// Included from: js/tinymce/classes/EditorObservable.js + +/** + * EditorObservable.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This mixin contains the event logic for the tinymce.Editor class. + * + * @mixin tinymce.EditorObservable + * @extends tinymce.util.Observable + */ +define("tinymce/EditorObservable", [ + "tinymce/util/Observable", + "tinymce/dom/DOMUtils", + "tinymce/util/Tools" +], function(Observable, DOMUtils, Tools) { + var DOM = DOMUtils.DOM, customEventRootDelegates; + + /** + * Returns the event target so for the specified event. Some events fire + * only on document, some fire on documentElement etc. This also handles the + * custom event root setting where it returns that element instead of the body. + * + * @private + * @param {tinymce.Editor} editor Editor instance to get event target from. + * @param {String} eventName Name of the event for example "click". + * @return {Element/Document} HTML Element or document target to bind on. + */ + function getEventTarget(editor, eventName) { + if (eventName == 'selectionchange') { + return editor.getDoc(); + } + + // Need to bind mousedown/mouseup etc to document not body in iframe mode + // Since the user might click on the HTML element not the BODY + if (!editor.inline && /^mouse|click|contextmenu|drop|dragover|dragend/.test(eventName)) { + return editor.getDoc().documentElement; + } + + // Bind to event root instead of body if it's defined + if (editor.settings.event_root) { + if (!editor.eventRoot) { + editor.eventRoot = DOM.select(editor.settings.event_root)[0]; + } + + return editor.eventRoot; + } + + return editor.getBody(); + } + + /** + * Binds a event delegate for the specified name this delegate will fire + * the event to the editor dispatcher. + * + * @private + * @param {tinymce.Editor} editor Editor instance to get event target from. + * @param {String} eventName Name of the event for example "click". + */ + function bindEventDelegate(editor, eventName) { + var eventRootElm = getEventTarget(editor, eventName), delegate; + + function isListening(editor) { + return !editor.hidden && !editor.readonly; + } + + if (!editor.delegates) { + editor.delegates = {}; + } + + if (editor.delegates[eventName]) { + return; + } + + if (editor.settings.event_root) { + if (!customEventRootDelegates) { + customEventRootDelegates = {}; + editor.editorManager.on('removeEditor', function() { + var name; + + if (!editor.editorManager.activeEditor) { + if (customEventRootDelegates) { + for (name in customEventRootDelegates) { + editor.dom.unbind(getEventTarget(editor, name)); + } + + customEventRootDelegates = null; + } + } + }); + } + + if (customEventRootDelegates[eventName]) { + return; + } + + delegate = function(e) { + var target = e.target, editors = editor.editorManager.editors, i = editors.length; + + while (i--) { + var body = editors[i].getBody(); + + if (body === target || DOM.isChildOf(target, body)) { + if (isListening(editors[i])) { + editors[i].fire(eventName, e); + } + } + } + }; + + customEventRootDelegates[eventName] = delegate; + DOM.bind(eventRootElm, eventName, delegate); + } else { + delegate = function(e) { + if (isListening(editor)) { + editor.fire(eventName, e); + } + }; + + DOM.bind(eventRootElm, eventName, delegate); + editor.delegates[eventName] = delegate; + } + } + + var EditorObservable = { + /** + * Bind any pending event delegates. This gets executed after the target body/document is created. + * + * @private + */ + bindPendingEventDelegates: function() { + var self = this; + + Tools.each(self._pendingNativeEvents, function(name) { + bindEventDelegate(self, name); + }); + }, + + /** + * Toggles a native event on/off this is called by the EventDispatcher when + * the first native event handler is added and when the last native event handler is removed. + * + * @private + */ + toggleNativeEvent: function(name, state) { + var self = this; + + // Never bind focus/blur since the FocusManager fakes those + if (name == "focus" || name == "blur") { + return; + } + + if (state) { + if (self.initialized) { + bindEventDelegate(self, name); + } else { + if (!self._pendingNativeEvents) { + self._pendingNativeEvents = [name]; + } else { + self._pendingNativeEvents.push(name); + } + } + } else if (self.initialized) { + self.dom.unbind(getEventTarget(self, name), name, self.delegates[name]); + delete self.delegates[name]; + } + }, + + /** + * Unbinds all native event handlers that means delegates, custom events bound using the Events API etc. + * + * @private + */ + unbindAllNativeEvents: function() { + var self = this, name; + + if (self.delegates) { + for (name in self.delegates) { + self.dom.unbind(getEventTarget(self, name), name, self.delegates[name]); + } + + delete self.delegates; + } + + if (!self.inline) { + self.getBody().onload = null; + self.dom.unbind(self.getWin()); + self.dom.unbind(self.getDoc()); + } + + self.dom.unbind(self.getBody()); + self.dom.unbind(self.getContainer()); + } + }; + + EditorObservable = Tools.extend({}, Observable, EditorObservable); + + return EditorObservable; +}); + +// Included from: js/tinymce/classes/Mode.js + +/** + * Mode.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Mode switcher logic. + * + * @private + * @class tinymce.Mode + */ +define("tinymce/Mode", [], function() { + function setEditorCommandState(editor, cmd, state) { + try { + editor.getDoc().execCommand(cmd, false, state); + } catch (ex) { + // Ignore + } + } + + function clickBlocker(editor) { + var target, handler; + + target = editor.getBody(); + + handler = function(e) { + if (editor.dom.getParents(e.target, 'a').length > 0) { + e.preventDefault(); + } + }; + + editor.dom.bind(target, 'click', handler); + + return { + unbind: function() { + editor.dom.unbind(target, 'click', handler); + } + }; + } + + function toggleReadOnly(editor, state) { + if (editor._clickBlocker) { + editor._clickBlocker.unbind(); + editor._clickBlocker = null; + } + + if (state) { + editor._clickBlocker = clickBlocker(editor); + editor.selection.controlSelection.hideResizeRect(); + editor.readonly = true; + editor.getBody().contentEditable = false; + } else { + editor.readonly = false; + editor.getBody().contentEditable = true; + setEditorCommandState(editor, "StyleWithCSS", false); + setEditorCommandState(editor, "enableInlineTableEditing", false); + setEditorCommandState(editor, "enableObjectResizing", false); + editor.focus(); + editor.nodeChanged(); + } + } + + function setMode(editor, mode) { + var currentMode = editor.readonly ? 'readonly' : 'design'; + + if (mode == currentMode) { + return; + } + + if (editor.initialized) { + toggleReadOnly(editor, mode == 'readonly'); + } else { + editor.on('init', function() { + toggleReadOnly(editor, mode == 'readonly'); + }); + } + + // Event is NOT preventable + editor.fire('SwitchMode', {mode: mode}); + } + + return { + setMode: setMode + }; +}); + +// Included from: js/tinymce/classes/Shortcuts.js + +/** + * Shortcuts.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Contains all logic for handling of keyboard shortcuts. + * + * @class tinymce.Shortcuts + * @example + * editor.shortcuts.add('ctrl+a', function() {}); + * editor.shortcuts.add('meta+a', function() {}); // "meta" maps to Command on Mac and Ctrl on PC + * editor.shortcuts.add('ctrl+alt+a', function() {}); + * editor.shortcuts.add('access+a', function() {}); // "access" maps to ctrl+alt on Mac and shift+alt on PC + */ +define("tinymce/Shortcuts", [ + "tinymce/util/Tools", + "tinymce/Env" +], function(Tools, Env) { + var each = Tools.each, explode = Tools.explode; + + var keyCodeLookup = { + "f9": 120, + "f10": 121, + "f11": 122 + }; + + var modifierNames = Tools.makeMap('alt,ctrl,shift,meta,access'); + + return function(editor) { + var self = this, shortcuts = {}, pendingPatterns = []; + + function parseShortcut(pattern) { + var id, key, shortcut = {}; + + // Parse modifiers and keys ctrl+alt+b for example + each(explode(pattern, '+'), function(value) { + if (value in modifierNames) { + shortcut[value] = true; + } else { + // Allow numeric keycodes like ctrl+219 for ctrl+[ + if (/^[0-9]{2,}$/.test(value)) { + shortcut.keyCode = parseInt(value, 10); + } else { + shortcut.charCode = value.charCodeAt(0); + shortcut.keyCode = keyCodeLookup[value] || value.toUpperCase().charCodeAt(0); + } + } + }); + + // Generate unique id for modifier combination and set default state for unused modifiers + id = [shortcut.keyCode]; + for (key in modifierNames) { + if (shortcut[key]) { + id.push(key); + } else { + shortcut[key] = false; + } + } + shortcut.id = id.join(','); + + // Handle special access modifier differently depending on Mac/Win + if (shortcut.access) { + shortcut.alt = true; + + if (Env.mac) { + shortcut.ctrl = true; + } else { + shortcut.shift = true; + } + } + + // Handle special meta modifier differently depending on Mac/Win + if (shortcut.meta) { + if (Env.mac) { + shortcut.meta = true; + } else { + shortcut.ctrl = true; + shortcut.meta = false; + } + } + + return shortcut; + } + + function createShortcut(pattern, desc, cmdFunc, scope) { + var shortcuts; + + shortcuts = Tools.map(explode(pattern, '>'), parseShortcut); + shortcuts[shortcuts.length - 1] = Tools.extend(shortcuts[shortcuts.length - 1], { + func: cmdFunc, + scope: scope || editor + }); + + return Tools.extend(shortcuts[0], { + desc: editor.translate(desc), + subpatterns: shortcuts.slice(1) + }); + } + + function hasModifier(e) { + return e.altKey || e.ctrlKey || e.metaKey; + } + + function isFunctionKey(e) { + return e.keyCode >= 112 && e.keyCode <= 123; + } + + function matchShortcut(e, shortcut) { + if (!shortcut) { + return false; + } + + if (shortcut.ctrl != e.ctrlKey || shortcut.meta != e.metaKey) { + return false; + } + + if (shortcut.alt != e.altKey || shortcut.shift != e.shiftKey) { + return false; + } + + if (e.keyCode == shortcut.keyCode || (e.charCode && e.charCode == shortcut.charCode)) { + e.preventDefault(); + return true; + } + + return false; + } + + function executeShortcutAction(shortcut) { + return shortcut.func ? shortcut.func.call(shortcut.scope) : null; + } + + editor.on('keyup keypress keydown', function(e) { + if ((hasModifier(e) || isFunctionKey(e)) && !e.isDefaultPrevented()) { + each(shortcuts, function(shortcut) { + if (matchShortcut(e, shortcut)) { + pendingPatterns = shortcut.subpatterns.slice(0); + + if (e.type == "keydown") { + executeShortcutAction(shortcut); + } + + return true; + } + }); + + if (matchShortcut(e, pendingPatterns[0])) { + if (pendingPatterns.length === 1) { + if (e.type == "keydown") { + executeShortcutAction(pendingPatterns[0]); + } + } + + pendingPatterns.shift(); + } + } + }); + + /** + * Adds a keyboard shortcut for some command or function. + * + * @method addShortcut + * @param {String} pattern Shortcut pattern. Like for example: ctrl+alt+o. + * @param {String} desc Text description for the command. + * @param {String/Function} cmdFunc Command name string or function to execute when the key is pressed. + * @param {Object} scope Optional scope to execute the function in. + * @return {Boolean} true/false state if the shortcut was added or not. + */ + self.add = function(pattern, desc, cmdFunc, scope) { + var cmd; + + cmd = cmdFunc; + + if (typeof cmdFunc === 'string') { + cmdFunc = function() { + editor.execCommand(cmd, false, null); + }; + } else if (Tools.isArray(cmd)) { + cmdFunc = function() { + editor.execCommand(cmd[0], cmd[1], cmd[2]); + }; + } + + each(explode(Tools.trim(pattern.toLowerCase())), function(pattern) { + var shortcut = createShortcut(pattern, desc, cmdFunc, scope); + shortcuts[shortcut.id] = shortcut; + }); + + return true; + }; + + /** + * Remove a keyboard shortcut by pattern. + * + * @method remove + * @param {String} pattern Shortcut pattern. Like for example: ctrl+alt+o. + * @return {Boolean} true/false state if the shortcut was removed or not. + */ + self.remove = function(pattern) { + var shortcut = createShortcut(pattern); + + if (shortcuts[shortcut.id]) { + delete shortcuts[shortcut.id]; + return true; + } + + return false; + }; + }; +}); + +// Included from: js/tinymce/classes/file/Uploader.js + +/** + * Uploader.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Upload blobs or blob infos to the specified URL or handler. + * + * @private + * @class tinymce.file.Uploader + * @example + * var uploader = new Uploader({ + * url: '/upload.php', + * basePath: '/base/path', + * credentials: true, + * handler: function(data, success, failure) { + * ... + * } + * }); + * + * uploader.upload(blobInfos).then(function(result) { + * ... + * }); + */ +define("tinymce/file/Uploader", [ + "tinymce/util/Promise", + "tinymce/util/Tools", + "tinymce/util/Fun" +], function(Promise, Tools, Fun) { + return function(uploadStatus, settings) { + var pendingPromises = {}; + + function fileName(blobInfo) { + var ext, extensions; + + extensions = { + 'image/jpeg': 'jpg', + 'image/jpg': 'jpg', + 'image/gif': 'gif', + 'image/png': 'png' + }; + + ext = extensions[blobInfo.blob().type.toLowerCase()] || 'dat'; + + return blobInfo.id() + '.' + ext; + } + + function pathJoin(path1, path2) { + if (path1) { + return path1.replace(/\/$/, '') + '/' + path2.replace(/^\//, ''); + } + + return path2; + } + + function blobInfoToData(blobInfo) { + return { + id: blobInfo.id, + blob: blobInfo.blob, + base64: blobInfo.base64, + filename: Fun.constant(fileName(blobInfo)) + }; + } + + function defaultHandler(blobInfo, success, failure, progress) { + var xhr, formData; + + xhr = new XMLHttpRequest(); + xhr.open('POST', settings.url); + xhr.withCredentials = settings.credentials; + + xhr.upload.onprogress = function(e) { + progress(e.loaded / e.total * 100); + }; + + xhr.onerror = function() { + failure("Image upload failed due to a XHR Transport error. Code: " + xhr.status); + }; + + xhr.onload = function() { + var json; + + if (xhr.status != 200) { + failure("HTTP Error: " + xhr.status); + return; + } + + json = JSON.parse(xhr.responseText); + + if (!json || typeof json.location != "string") { + failure("Invalid JSON: " + xhr.responseText); + return; + } + + success(pathJoin(settings.basePath, json.location)); + }; + + formData = new FormData(); + formData.append('file', blobInfo.blob(), fileName(blobInfo)); + + xhr.send(formData); + } + + function noUpload() { + return new Promise(function(resolve) { + resolve([]); + }); + } + + function handlerSuccess(blobInfo, url) { + return { + url: url, + blobInfo: blobInfo, + status: true + }; + } + + function handlerFailure(blobInfo, error) { + return { + url: '', + blobInfo: blobInfo, + status: false, + error: error + }; + } + + function resolvePending(blobUri, result) { + Tools.each(pendingPromises[blobUri], function(resolve) { + resolve(result); + }); + + delete pendingPromises[blobUri]; + } + + function uploadBlobInfo(blobInfo, handler, openNotification) { + uploadStatus.markPending(blobInfo.blobUri()); + + return new Promise(function(resolve) { + var notification, progress; + + var noop = function() { + }; + + try { + var closeNotification = function() { + if (notification) { + notification.close(); + progress = noop; // Once it's closed it's closed + } + }; + + var success = function(url) { + closeNotification(); + uploadStatus.markUploaded(blobInfo.blobUri(), url); + resolvePending(blobInfo.blobUri(), handlerSuccess(blobInfo, url)); + resolve(handlerSuccess(blobInfo, url)); + }; + + var failure = function() { + closeNotification(); + uploadStatus.removeFailed(blobInfo.blobUri()); + resolvePending(blobInfo.blobUri(), handlerFailure(blobInfo, failure)); + resolve(handlerFailure(blobInfo, failure)); + }; + + progress = function(percent) { + if (percent < 0 || percent > 100) { + return; + } + + if (!notification) { + notification = openNotification(); + } + + notification.progressBar.value(percent); + }; + + handler(blobInfoToData(blobInfo), success, failure, progress); + } catch (ex) { + resolve(handlerFailure(blobInfo, ex.message)); + } + }); + } + + function isDefaultHandler(handler) { + return handler === defaultHandler; + } + + function pendingUploadBlobInfo(blobInfo) { + var blobUri = blobInfo.blobUri(); + + return new Promise(function(resolve) { + pendingPromises[blobUri] = pendingPromises[blobUri] || []; + pendingPromises[blobUri].push(resolve); + }); + } + + function uploadBlobs(blobInfos, openNotification) { + blobInfos = Tools.grep(blobInfos, function(blobInfo) { + return !uploadStatus.isUploaded(blobInfo.blobUri()); + }); + + return Promise.all(Tools.map(blobInfos, function(blobInfo) { + return uploadStatus.isPending(blobInfo.blobUri()) ? + pendingUploadBlobInfo(blobInfo) : uploadBlobInfo(blobInfo, settings.handler, openNotification); + })); + } + + function upload(blobInfos, openNotification) { + return (!settings.url && isDefaultHandler(settings.handler)) ? noUpload() : uploadBlobs(blobInfos, openNotification); + } + + settings = Tools.extend({ + credentials: false, + // We are adding a notify argument to this (at the moment, until it doesn't work) + handler: defaultHandler + }, settings); + + return { + upload: upload + }; + }; +}); + +// Included from: js/tinymce/classes/file/Conversions.js + +/** + * Conversions.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Converts blob/uris back and forth. + * + * @private + * @class tinymce.file.Conversions + */ +define("tinymce/file/Conversions", [ + "tinymce/util/Promise" +], function(Promise) { + function blobUriToBlob(url) { + return new Promise(function(resolve) { + var xhr = new XMLHttpRequest(); + + xhr.open('GET', url, true); + xhr.responseType = 'blob'; + + xhr.onload = function() { + if (this.status == 200) { + resolve(this.response); + } + }; + + xhr.send(); + }); + } + + function parseDataUri(uri) { + var type, matches; + + uri = decodeURIComponent(uri).split(','); + + matches = /data:([^;]+)/.exec(uri[0]); + if (matches) { + type = matches[1]; + } + + return { + type: type, + data: uri[1] + }; + } + + function dataUriToBlob(uri) { + return new Promise(function(resolve) { + var str, arr, i; + + uri = parseDataUri(uri); + + // Might throw error if data isn't proper base64 + try { + str = atob(uri.data); + } catch (e) { + resolve(new Blob([])); + return; + } + + arr = new Uint8Array(str.length); + + for (i = 0; i < arr.length; i++) { + arr[i] = str.charCodeAt(i); + } + + resolve(new Blob([arr], {type: uri.type})); + }); + } + + function uriToBlob(url) { + if (url.indexOf('blob:') === 0) { + return blobUriToBlob(url); + } + + if (url.indexOf('data:') === 0) { + return dataUriToBlob(url); + } + + return null; + } + + function blobToDataUri(blob) { + return new Promise(function(resolve) { + var reader = new FileReader(); + + reader.onloadend = function() { + resolve(reader.result); + }; + + reader.readAsDataURL(blob); + }); + } + + return { + uriToBlob: uriToBlob, + blobToDataUri: blobToDataUri, + parseDataUri: parseDataUri + }; +}); + +// Included from: js/tinymce/classes/file/ImageScanner.js + +/** + * ImageScanner.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Finds images with data uris or blob uris. If data uris are found it will convert them into blob uris. + * + * @private + * @class tinymce.file.ImageScanner + */ +define("tinymce/file/ImageScanner", [ + "tinymce/util/Promise", + "tinymce/util/Arr", + "tinymce/util/Fun", + "tinymce/file/Conversions", + "tinymce/Env" +], function(Promise, Arr, Fun, Conversions, Env) { + var count = 0; + + return function(uploadStatus, blobCache) { + var cachedPromises = {}; + + function findAll(elm, predicate) { + var images, promises; + + function imageToBlobInfo(img, resolve) { + var base64, blobInfo; + + if (img.src.indexOf('blob:') === 0) { + blobInfo = blobCache.getByUri(img.src); + + if (blobInfo) { + resolve({ + image: img, + blobInfo: blobInfo + }); + } + + return; + } + + base64 = Conversions.parseDataUri(img.src).data; + blobInfo = blobCache.findFirst(function(cachedBlobInfo) { + return cachedBlobInfo.base64() === base64; + }); + + if (blobInfo) { + resolve({ + image: img, + blobInfo: blobInfo + }); + } else { + Conversions.uriToBlob(img.src).then(function(blob) { + var blobInfoId = 'blobid' + (count++), + blobInfo = blobCache.create(blobInfoId, blob, base64); + + blobCache.add(blobInfo); + + resolve({ + image: img, + blobInfo: blobInfo + }); + }); + } + } + + if (!predicate) { + predicate = Fun.constant(true); + } + + images = Arr.filter(elm.getElementsByTagName('img'), function(img) { + var src = img.src; + + if (!Env.fileApi) { + return false; + } + + if (img.hasAttribute('data-mce-bogus')) { + return false; + } + + if (img.hasAttribute('data-mce-placeholder')) { + return false; + } + + if (!src || src == Env.transparentSrc) { + return false; + } + + if (src.indexOf('blob:') === 0) { + return !uploadStatus.isUploaded(src); + } + + if (src.indexOf('data:') === 0) { + return predicate(img); + } + + return false; + }); + + promises = Arr.map(images, function(img) { + var newPromise; + + if (cachedPromises[img.src]) { + // Since the cached promise will return the cached image + // We need to wrap it and resolve with the actual image + return new Promise(function(resolve) { + cachedPromises[img.src].then(function(imageInfo) { + resolve({ + image: img, + blobInfo: imageInfo.blobInfo + }); + }); + }); + } + + newPromise = new Promise(function(resolve) { + imageToBlobInfo(img, resolve); + }).then(function(result) { + delete cachedPromises[result.image.src]; + return result; + })['catch'](function(error) { + delete cachedPromises[img.src]; + return error; + }); + + cachedPromises[img.src] = newPromise; + + return newPromise; + }); + + return Promise.all(promises); + } + + return { + findAll: findAll + }; + }; +}); + +// Included from: js/tinymce/classes/file/BlobCache.js + +/** + * BlobCache.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Hold blob info objects where a blob has extra internal information. + * + * @private + * @class tinymce.file.BlobCache + */ +define("tinymce/file/BlobCache", [ + "tinymce/util/Arr", + "tinymce/util/Fun" +], function(Arr, Fun) { + return function() { + var cache = [], constant = Fun.constant; + + function create(id, blob, base64) { + return { + id: constant(id), + blob: constant(blob), + base64: constant(base64), + blobUri: constant(URL.createObjectURL(blob)) + }; + } + + function add(blobInfo) { + if (!get(blobInfo.id())) { + cache.push(blobInfo); + } + } + + function get(id) { + return findFirst(function(cachedBlobInfo) { + return cachedBlobInfo.id() === id; + }); + } + + function findFirst(predicate) { + return Arr.filter(cache, predicate)[0]; + } + + function getByUri(blobUri) { + return findFirst(function(blobInfo) { + return blobInfo.blobUri() == blobUri; + }); + } + + function removeByUri(blobUri) { + cache = Arr.filter(cache, function(blobInfo) { + if (blobInfo.blobUri() === blobUri) { + URL.revokeObjectURL(blobInfo.blobUri()); + return false; + } + + return true; + }); + } + + function destroy() { + Arr.each(cache, function(cachedBlobInfo) { + URL.revokeObjectURL(cachedBlobInfo.blobUri()); + }); + + cache = []; + } + + return { + create: create, + add: add, + get: get, + getByUri: getByUri, + findFirst: findFirst, + removeByUri: removeByUri, + destroy: destroy + }; + }; +}); + +// Included from: js/tinymce/classes/file/UploadStatus.js + +/** + * UploadStatus.js + * + * Released under LGPL License. + * Copyright (c) 1999-2016 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Holds the current status of a blob uri, if it's pending or uploaded and what the result urls was. + * + * @private + * @class tinymce.file.UploadStatus + */ +define("tinymce/file/UploadStatus", [ +], function() { + return function() { + var PENDING = 1, UPLOADED = 2; + var blobUriStatuses = {}; + + function createStatus(status, resultUri) { + return { + status: status, + resultUri: resultUri + }; + } + + function hasBlobUri(blobUri) { + return blobUri in blobUriStatuses; + } + + function getResultUri(blobUri) { + var result = blobUriStatuses[blobUri]; + + return result ? result.resultUri : null; + } + + function isPending(blobUri) { + return hasBlobUri(blobUri) ? blobUriStatuses[blobUri].status === PENDING : false; + } + + function isUploaded(blobUri) { + return hasBlobUri(blobUri) ? blobUriStatuses[blobUri].status === UPLOADED : false; + } + + function markPending(blobUri) { + blobUriStatuses[blobUri] = createStatus(PENDING, null); + } + + function markUploaded(blobUri, resultUri) { + blobUriStatuses[blobUri] = createStatus(UPLOADED, resultUri); + } + + function removeFailed(blobUri) { + delete blobUriStatuses[blobUri]; + } + + function destroy() { + blobUriStatuses = {}; + } + + return { + hasBlobUri: hasBlobUri, + getResultUri: getResultUri, + isPending: isPending, + isUploaded: isUploaded, + markPending: markPending, + markUploaded: markUploaded, + removeFailed: removeFailed, + destroy: destroy + }; + }; +}); + +// Included from: js/tinymce/classes/EditorUpload.js + +/** + * EditorUpload.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Handles image uploads, updates undo stack and patches over various internal functions. + * + * @private + * @class tinymce.EditorUpload + */ +define("tinymce/EditorUpload", [ + "tinymce/util/Arr", + "tinymce/file/Uploader", + "tinymce/file/ImageScanner", + "tinymce/file/BlobCache", + "tinymce/file/UploadStatus" +], function(Arr, Uploader, ImageScanner, BlobCache, UploadStatus) { + return function(editor) { + var blobCache = new BlobCache(), uploader, imageScanner, settings = editor.settings; + var uploadStatus = new UploadStatus(); + + function aliveGuard(callback) { + return function(result) { + if (editor.selection) { + return callback(result); + } + + return []; + }; + } + + // Replaces strings without regexps to avoid FF regexp to big issue + function replaceString(content, search, replace) { + var index = 0; + + do { + index = content.indexOf(search, index); + + if (index !== -1) { + content = content.substring(0, index) + replace + content.substr(index + search.length); + index += replace.length - search.length + 1; + } + } while (index !== -1); + + return content; + } + + function replaceImageUrl(content, targetUrl, replacementUrl) { + content = replaceString(content, 'src="' + targetUrl + '"', 'src="' + replacementUrl + '"'); + content = replaceString(content, 'data-mce-src="' + targetUrl + '"', 'data-mce-src="' + replacementUrl + '"'); + + return content; + } + + function replaceUrlInUndoStack(targetUrl, replacementUrl) { + Arr.each(editor.undoManager.data, function(level) { + level.content = replaceImageUrl(level.content, targetUrl, replacementUrl); + }); + } + + function openNotification() { + return editor.notificationManager.open({ + text: editor.translate('Image uploading...'), + type: 'info', + timeout: -1, + progressBar: true + }); + } + + function replaceImageUri(image, resultUri) { + blobCache.removeByUri(image.src); + replaceUrlInUndoStack(image.src, resultUri); + + editor.$(image).attr({ + src: resultUri, + 'data-mce-src': editor.convertURL(resultUri, 'src') + }); + } + + function uploadImages(callback) { + if (!uploader) { + uploader = new Uploader(uploadStatus, { + url: settings.images_upload_url, + basePath: settings.images_upload_base_path, + credentials: settings.images_upload_credentials, + handler: settings.images_upload_handler + }); + } + + return scanForImages().then(aliveGuard(function(imageInfos) { + var blobInfos; + + blobInfos = Arr.map(imageInfos, function(imageInfo) { + return imageInfo.blobInfo; + }); + + return uploader.upload(blobInfos, openNotification).then(aliveGuard(function(result) { + result = Arr.map(result, function(uploadInfo, index) { + var image = imageInfos[index].image; + + if (uploadInfo.status && editor.settings.images_replace_blob_uris !== false) { + replaceImageUri(image, uploadInfo.url); + } + + return { + element: image, + status: uploadInfo.status + }; + }); + + if (callback) { + callback(result); + } + + return result; + })); + })); + } + + function uploadImagesAuto(callback) { + if (settings.automatic_uploads !== false) { + return uploadImages(callback); + } + } + + function isValidDataUriImage(imgElm) { + return settings.images_dataimg_filter ? settings.images_dataimg_filter(imgElm) : true; + } + + function scanForImages() { + if (!imageScanner) { + imageScanner = new ImageScanner(uploadStatus, blobCache); + } + + return imageScanner.findAll(editor.getBody(), isValidDataUriImage).then(aliveGuard(function(result) { + Arr.each(result, function(resultItem) { + replaceUrlInUndoStack(resultItem.image.src, resultItem.blobInfo.blobUri()); + resultItem.image.src = resultItem.blobInfo.blobUri(); + resultItem.image.removeAttribute('data-mce-src'); + }); + + return result; + })); + } + + function destroy() { + blobCache.destroy(); + uploadStatus.destroy(); + imageScanner = uploader = null; + } + + function replaceBlobUris(content) { + return content.replace(/src="(blob:[^"]+)"/g, function(match, blobUri) { + var resultUri = uploadStatus.getResultUri(blobUri); + + if (resultUri) { + return 'src="' + resultUri + '"'; + } + + var blobInfo = blobCache.getByUri(blobUri); + + if (!blobInfo) { + blobInfo = Arr.reduce(editor.editorManager.editors, function(result, editor) { + return result || editor.editorUpload.blobCache.getByUri(blobUri); + }, null); + } + + if (blobInfo) { + return 'src="data:' + blobInfo.blob().type + ';base64,' + blobInfo.base64() + '"'; + } + + return match; + }); + } + + editor.on('setContent', function() { + if (editor.settings.automatic_uploads !== false) { + uploadImagesAuto(); + } else { + scanForImages(); + } + }); + + editor.on('RawSaveContent', function(e) { + e.content = replaceBlobUris(e.content); + }); + + editor.on('getContent', function(e) { + if (e.source_view || e.format == 'raw') { + return; + } + + e.content = replaceBlobUris(e.content); + }); + + editor.on('PostRender', function() { + editor.parser.addNodeFilter('img', function(images) { + Arr.each(images, function(img) { + var src = img.attr('src'); + + if (blobCache.getByUri(src)) { + return; + } + + var resultUri = uploadStatus.getResultUri(src); + if (resultUri) { + img.attr('src', resultUri); + } + }); + }); + }); + + return { + blobCache: blobCache, + uploadImages: uploadImages, + uploadImagesAuto: uploadImagesAuto, + scanForImages: scanForImages, + destroy: destroy + }; + }; +}); + +// Included from: js/tinymce/classes/caret/FakeCaret.js + +/** + * FakeCaret.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This module contains logic for rendering a fake visual caret. + * + * @private + * @class tinymce.caret.FakeCaret + */ +define("tinymce/caret/FakeCaret", [ + "tinymce/caret/CaretContainer", + "tinymce/caret/CaretPosition", + "tinymce/dom/NodeType", + "tinymce/dom/RangeUtils", + "tinymce/dom/DomQuery", + "tinymce/geom/ClientRect", + "tinymce/util/Delay" +], function(CaretContainer, CaretPosition, NodeType, RangeUtils, $, ClientRect, Delay) { + var isContentEditableFalse = NodeType.isContentEditableFalse; + + return function(rootNode, isBlock) { + var cursorInterval, $lastVisualCaret, caretContainerNode; + + function getAbsoluteClientRect(node, before) { + var clientRect = ClientRect.collapse(node.getBoundingClientRect(), before), + docElm, scrollX, scrollY, margin, rootRect; + + if (rootNode.tagName == 'BODY') { + docElm = rootNode.ownerDocument.documentElement; + scrollX = rootNode.scrollLeft || docElm.scrollLeft; + scrollY = rootNode.scrollTop || docElm.scrollTop; + } else { + rootRect = rootNode.getBoundingClientRect(); + scrollX = rootNode.scrollLeft - rootRect.left; + scrollY = rootNode.scrollTop - rootRect.top; + } + + clientRect.left += scrollX; + clientRect.right += scrollX; + clientRect.top += scrollY; + clientRect.bottom += scrollY; + clientRect.width = 1; + + margin = node.offsetWidth - node.clientWidth; + + if (margin > 0) { + if (before) { + margin *= -1; + } + + clientRect.left += margin; + clientRect.right += margin; + } + + return clientRect; + } + + function trimInlineCaretContainers() { + var contentEditableFalseNodes, node, sibling, i, data; + + contentEditableFalseNodes = $('*[contentEditable=false]', rootNode); + for (i = 0; i < contentEditableFalseNodes.length; i++) { + node = contentEditableFalseNodes[i]; + + sibling = node.previousSibling; + if (CaretContainer.endsWithCaretContainer(sibling)) { + data = sibling.data; + + if (data.length == 1) { + sibling.parentNode.removeChild(sibling); + } else { + sibling.deleteData(data.length - 1, 1); + } + } + + sibling = node.nextSibling; + if (CaretContainer.startsWithCaretContainer(sibling)) { + data = sibling.data; + + if (data.length == 1) { + sibling.parentNode.removeChild(sibling); + } else { + sibling.deleteData(0, 1); + } + } + } + + return null; + } + + function show(before, node) { + var clientRect, rng, container; + + hide(); + + if (isBlock(node)) { + caretContainerNode = CaretContainer.insertBlock('p', node, before); + clientRect = getAbsoluteClientRect(node, before); + $(caretContainerNode).css('top', clientRect.top); + + $lastVisualCaret = $('<div class="mce-visual-caret" data-mce-bogus="all"></div>').css(clientRect).appendTo(rootNode); + + if (before) { + $lastVisualCaret.addClass('mce-visual-caret-before'); + } + + startBlink(); + + rng = node.ownerDocument.createRange(); + container = caretContainerNode.firstChild; + rng.setStart(container, 0); + rng.setEnd(container, 1); + } else { + caretContainerNode = CaretContainer.insertInline(node, before); + rng = node.ownerDocument.createRange(); + + if (isContentEditableFalse(caretContainerNode.nextSibling)) { + rng.setStart(caretContainerNode, 0); + rng.setEnd(caretContainerNode, 0); + } else { + rng.setStart(caretContainerNode, 1); + rng.setEnd(caretContainerNode, 1); + } + + return rng; + } + + return rng; + } + + function hide() { + trimInlineCaretContainers(); + + if (caretContainerNode) { + CaretContainer.remove(caretContainerNode); + caretContainerNode = null; + } + + if ($lastVisualCaret) { + $lastVisualCaret.remove(); + $lastVisualCaret = null; + } + + clearInterval(cursorInterval); + } + + function startBlink() { + cursorInterval = Delay.setInterval(function() { + $('div.mce-visual-caret', rootNode).toggleClass('mce-visual-caret-hidden'); + }, 500); + } + + function destroy() { + Delay.clearInterval(cursorInterval); + } + + function getCss() { + return ( + '.mce-visual-caret {' + + 'position: absolute;' + + 'background-color: black;' + + 'background-color: currentcolor;' + + '}' + + '.mce-visual-caret-hidden {' + + 'display: none;' + + '}' + + '*[data-mce-caret] {' + + 'position: absolute;' + + 'left: -1000px;' + + 'right: auto;' + + 'top: 0;' + + 'margin: 0;' + + 'padding: 0;' + + '}' + ); + } + + return { + show: show, + hide: hide, + getCss: getCss, + destroy: destroy + }; + }; +}); + +// Included from: js/tinymce/classes/dom/Dimensions.js + +/** + * Dimensions.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This module measures nodes and returns client rects. The client rects has an + * extra node property. + * + * @private + * @class tinymce.dom.Dimensions + */ +define("tinymce/dom/Dimensions", [ + "tinymce/util/Arr", + "tinymce/dom/NodeType", + "tinymce/geom/ClientRect" +], function(Arr, NodeType, ClientRect) { + + function getClientRects(node) { + function toArrayWithNode(clientRects) { + return Arr.map(clientRects, function(clientRect) { + clientRect = ClientRect.clone(clientRect); + clientRect.node = node; + + return clientRect; + }); + } + + if (Arr.isArray(node)) { + return Arr.reduce(node, function(result, node) { + return result.concat(getClientRects(node)); + }, []); + } + + if (NodeType.isElement(node)) { + return toArrayWithNode(node.getClientRects()); + } + + if (NodeType.isText(node)) { + var rng = node.ownerDocument.createRange(); + + rng.setStart(node, 0); + rng.setEnd(node, node.data.length); + + return toArrayWithNode(rng.getClientRects()); + } + } + + return { + /** + * Returns the client rects for a specific node. + * + * @method getClientRects + * @param {Array/DOMNode} node Node or array of nodes to get client rects on. + * @param {Array} Array of client rects with a extra node property. + */ + getClientRects: getClientRects + }; +}); + +// Included from: js/tinymce/classes/caret/LineWalker.js + +/** + * LineWalker.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This module lets you walk the document line by line + * returing nodes and client rects for each line. + * + * @private + * @class tinymce.caret.LineWalker + */ +define("tinymce/caret/LineWalker", [ + "tinymce/util/Fun", + "tinymce/util/Arr", + "tinymce/dom/Dimensions", + "tinymce/caret/CaretCandidate", + "tinymce/caret/CaretUtils", + "tinymce/caret/CaretWalker", + "tinymce/caret/CaretPosition", + "tinymce/geom/ClientRect" +], function(Fun, Arr, Dimensions, CaretCandidate, CaretUtils, CaretWalker, CaretPosition, ClientRect) { + var curry = Fun.curry; + + function findUntil(direction, rootNode, predicateFn, node) { + while ((node = CaretUtils.findNode(node, direction, CaretCandidate.isEditableCaretCandidate, rootNode))) { + if (predicateFn(node)) { + return; + } + } + } + + function walkUntil(direction, isAboveFn, isBeflowFn, rootNode, predicateFn, caretPosition) { + var line = 0, node, result = [], targetClientRect; + + function add(node) { + var i, clientRect, clientRects; + + clientRects = Dimensions.getClientRects(node); + if (direction == -1) { + clientRects = clientRects.reverse(); + } + + for (i = 0; i < clientRects.length; i++) { + clientRect = clientRects[i]; + if (isBeflowFn(clientRect, targetClientRect)) { + continue; + } + + if (result.length > 0 && isAboveFn(clientRect, Arr.last(result))) { + line++; + } + + clientRect.line = line; + + if (predicateFn(clientRect)) { + return true; + } + + result.push(clientRect); + } + } + + targetClientRect = Arr.last(caretPosition.getClientRects()); + if (!targetClientRect) { + return result; + } + + node = caretPosition.getNode(); + add(node); + findUntil(direction, rootNode, add, node); + + return result; + } + + function aboveLineNumber(lineNumber, clientRect) { + return clientRect.line > lineNumber; + } + + function isLine(lineNumber, clientRect) { + return clientRect.line === lineNumber; + } + + var upUntil = curry(walkUntil, -1, ClientRect.isAbove, ClientRect.isBelow); + var downUntil = curry(walkUntil, 1, ClientRect.isBelow, ClientRect.isAbove); + + function positionsUntil(direction, rootNode, predicateFn, node) { + var caretWalker = new CaretWalker(rootNode), walkFn, isBelowFn, isAboveFn, + caretPosition, result = [], line = 0, clientRect, targetClientRect; + + function getClientRect(caretPosition) { + if (direction == 1) { + return Arr.last(caretPosition.getClientRects()); + } + + return Arr.last(caretPosition.getClientRects()); + } + + if (direction == 1) { + walkFn = caretWalker.next; + isBelowFn = ClientRect.isBelow; + isAboveFn = ClientRect.isAbove; + caretPosition = CaretPosition.after(node); + } else { + walkFn = caretWalker.prev; + isBelowFn = ClientRect.isAbove; + isAboveFn = ClientRect.isBelow; + caretPosition = CaretPosition.before(node); + } + + targetClientRect = getClientRect(caretPosition); + + do { + if (!caretPosition.isVisible()) { + continue; + } + + clientRect = getClientRect(caretPosition); + + if (isAboveFn(clientRect, targetClientRect)) { + continue; + } + + if (result.length > 0 && isBelowFn(clientRect, Arr.last(result))) { + line++; + } + + clientRect = ClientRect.clone(clientRect); + clientRect.position = caretPosition; + clientRect.line = line; + + if (predicateFn(clientRect)) { + return result; + } + + result.push(clientRect); + } while ((caretPosition = walkFn(caretPosition))); + + return result; + } + + return { + upUntil: upUntil, + downUntil: downUntil, + + /** + * Find client rects with line and caret position until the predicate returns true. + * + * @method positionsUntil + * @param {Number} direction Direction forward/backward 1/-1. + * @param {DOMNode} rootNode Root node to walk within. + * @param {function} predicateFn Gets the client rect as it's input. + * @param {DOMNode} node Node to start walking from. + * @return {Array} Array of client rects with line and position properties. + */ + positionsUntil: positionsUntil, + + isAboveLine: curry(aboveLineNumber), + isLine: curry(isLine) + }; +}); + +// Included from: js/tinymce/classes/caret/LineUtils.js + +/** + * LineUtils.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Utility functions for working with lines. + * + * @private + * @class tinymce.caret.LineUtils + */ +define("tinymce/caret/LineUtils", [ + "tinymce/util/Fun", + "tinymce/util/Arr", + "tinymce/dom/NodeType", + "tinymce/dom/Dimensions", + "tinymce/geom/ClientRect", + "tinymce/caret/CaretUtils", + "tinymce/caret/CaretCandidate" +], function(Fun, Arr, NodeType, Dimensions, ClientRect, CaretUtils, CaretCandidate) { + var isContentEditableFalse = NodeType.isContentEditableFalse, + findNode = CaretUtils.findNode, + curry = Fun.curry; + + function distanceToRectLeft(clientRect, clientX) { + return Math.abs(clientRect.left - clientX); + } + + function distanceToRectRight(clientRect, clientX) { + return Math.abs(clientRect.right - clientX); + } + + function findClosestClientRect(clientRects, clientX) { + function isInside(clientX, clientRect) { + return clientX >= clientRect.left && clientX <= clientRect.right; + } + + return Arr.reduce(clientRects, function(oldClientRect, clientRect) { + var oldDistance, newDistance; + + oldDistance = Math.min(distanceToRectLeft(oldClientRect, clientX), distanceToRectRight(oldClientRect, clientX)); + newDistance = Math.min(distanceToRectLeft(clientRect, clientX), distanceToRectRight(clientRect, clientX)); + + if (isInside(clientX, clientRect)) { + return clientRect; + } + + if (isInside(clientX, oldClientRect)) { + return oldClientRect; + } + + // cE=false has higher priority + if (newDistance == oldDistance && isContentEditableFalse(clientRect.node)) { + return clientRect; + } + + if (newDistance < oldDistance) { + return clientRect; + } + + return oldClientRect; + }); + } + + function walkUntil(direction, rootNode, predicateFn, node) { + while ((node = findNode(node, direction, CaretCandidate.isEditableCaretCandidate, rootNode))) { + if (predicateFn(node)) { + return; + } + } + } + + function findLineNodeRects(rootNode, targetNodeRect) { + var clientRects = []; + + function collect(checkPosFn, node) { + var lineRects; + + lineRects = Arr.filter(Dimensions.getClientRects(node), function(clientRect) { + return !checkPosFn(clientRect, targetNodeRect); + }); + + clientRects = clientRects.concat(lineRects); + + return lineRects.length === 0; + } + + clientRects.push(targetNodeRect); + walkUntil(-1, rootNode, curry(collect, ClientRect.isAbove), targetNodeRect.node); + walkUntil(1, rootNode, curry(collect, ClientRect.isBelow), targetNodeRect.node); + + return clientRects; + } + + function getContentEditableFalseChildren(rootNode) { + return Arr.filter(Arr.toArray(rootNode.getElementsByTagName('*')), isContentEditableFalse); + } + + function caretInfo(clientRect, clientX) { + return { + node: clientRect.node, + before: distanceToRectLeft(clientRect, clientX) < distanceToRectRight(clientRect, clientX) + }; + } + + function closestCaret(rootNode, clientX, clientY) { + var contentEditableFalseNodeRects, closestNodeRect; + + contentEditableFalseNodeRects = Dimensions.getClientRects(getContentEditableFalseChildren(rootNode)); + contentEditableFalseNodeRects = Arr.filter(contentEditableFalseNodeRects, function(clientRect) { + return clientY >= clientRect.top && clientY <= clientRect.bottom; + }); + + closestNodeRect = findClosestClientRect(contentEditableFalseNodeRects, clientX); + if (closestNodeRect) { + closestNodeRect = findClosestClientRect(findLineNodeRects(rootNode, closestNodeRect), clientX); + if (closestNodeRect && isContentEditableFalse(closestNodeRect.node)) { + return caretInfo(closestNodeRect, clientX); + } + } + + return null; + } + + return { + findClosestClientRect: findClosestClientRect, + findLineNodeRects: findLineNodeRects, + closestCaret: closestCaret + }; +}); + +// Included from: js/tinymce/classes/DragDropOverrides.js + +/** + * DragDropOverrides.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This module contains logic overriding the drag/drop logic of the editor. + * + * @private + * @class tinymce.DragDropOverrides + */ +define("tinymce/DragDropOverrides", [ + "tinymce/dom/NodeType", + "tinymce/util/Arr", + "tinymce/util/Fun" +], function( + NodeType, + Arr, + Fun +) { + var isContentEditableFalse = NodeType.isContentEditableFalse, + isContentEditableTrue = NodeType.isContentEditableTrue; + + function init(editor) { + var $ = editor.$, rootDocument = document, + editableDoc = editor.getDoc(), + dom = editor.dom, state = {}; + + function isDraggable(elm) { + return isContentEditableFalse(elm); + } + + function setBodyCursor(cursor) { + $(editor.getBody()).css('cursor', cursor); + } + + function isValidDropTarget(elm) { + if (elm == state.element || editor.dom.isChildOf(elm, state.element)) { + return false; + } + + if (isContentEditableFalse(elm)) { + return false; + } + + return true; + } + + function move(e) { + var deltaX, deltaY, pos, viewPort, + overflowX = 0, overflowY = 0, movement, + clientX, clientY, rootClientRect; + + if (e.button !== 0) { + return; + } + + deltaX = e.screenX - state.screenX; + deltaY = e.screenY - state.screenY; + movement = Math.max(Math.abs(deltaX), Math.abs(deltaY)); + + if (!state.dragging && movement > 10) { + state.dragging = true; + setBodyCursor('default'); + + state.clone = state.element.cloneNode(true); + + pos = dom.getPos(state.element); + state.relX = state.clientX - pos.x; + state.relY = state.clientY - pos.y; + state.width = state.element.offsetWidth; + state.height = state.element.offsetHeight; + + $(state.clone).css({ + width: state.width, + height: state.height + }).removeAttr('data-mce-selected'); + + state.ghost = $('<div>').css({ + position: 'absolute', + opacity: 0.5, + overflow: 'hidden', + width: state.width, + height: state.height + }).attr({ + 'data-mce-bogus': 'all', + unselectable: 'on', + contenteditable: 'false' + }).addClass('mce-drag-container mce-reset'). + append(state.clone). + appendTo(editor.getBody())[0]; + + viewPort = editor.dom.getViewPort(editor.getWin()); + state.maxX = viewPort.w; + state.maxY = viewPort.h; + } + + if (state.dragging) { + editor.selection.placeCaretAt(e.clientX, e.clientY); + + clientX = state.clientX + deltaX - state.relX; + clientY = state.clientY + deltaY + 5; + + if (clientX + state.width > state.maxX) { + overflowX = (clientX + state.width) - state.maxX; + } + + if (clientY + state.height > state.maxY) { + overflowY = (clientY + state.height) - state.maxY; + } + + if (editor.getBody().nodeName != 'BODY') { + rootClientRect = editor.getBody().getBoundingClientRect(); + } else { + rootClientRect = {left: 0, top: 0}; + } + + $(state.ghost).css({ + left: clientX - rootClientRect.left, + top: clientY - rootClientRect.top, + width: state.width - overflowX, + height: state.height - overflowY + }); + } + } + + function drop() { + var evt; + + if (state.dragging) { + // Hack for IE since it doesn't sync W3C Range with IE Specific range + editor.selection.setRng(editor.selection.getSel().getRangeAt(0)); + + if (isValidDropTarget(editor.selection.getNode())) { + var targetClone = state.element; + + evt = editor.fire('drop', {targetClone: targetClone}); + if (evt.isDefaultPrevented()) { + return; + } + + targetClone = evt.targetClone; + + editor.undoManager.transact(function() { + editor.insertContent(dom.getOuterHTML(targetClone)); + $(state.element).remove(); + }); + } + } + + stop(); + } + + function start(e) { + var ceElm, evt; + + stop(); + + if (e.button !== 0) { + return; + } + + ceElm = Arr.find(editor.dom.getParents(e.target), Fun.or(isContentEditableFalse, isContentEditableTrue)); + + if (isDraggable(ceElm)) { + evt = editor.fire('dragstart', {target: ceElm}); + if (evt.isDefaultPrevented()) { + return; + } + + editor.on('mousemove', move); + editor.on('mouseup', drop); + + if (rootDocument != editableDoc) { + dom.bind(rootDocument, 'mousemove', move); + dom.bind(rootDocument, 'mouseup', drop); + } + + state = { + screenX: e.screenX, + screenY: e.screenY, + clientX: e.clientX, + clientY: e.clientY, + element: ceElm + }; + } + } + + function stop() { + $(state.ghost).remove(); + setBodyCursor(null); + + editor.off('mousemove', move); + editor.off('mouseup', stop); + + if (rootDocument != editableDoc) { + dom.unbind(rootDocument, 'mousemove', move); + dom.unbind(rootDocument, 'mouseup', stop); + } + + state = {}; + } + + editor.on('mousedown', start); + + // Blocks drop inside cE=false on IE + editor.on('drop', function(e) { + var realTarget = editor.getDoc().elementFromPoint(e.clientX, e.clientY); + + if (isContentEditableFalse(realTarget) || isContentEditableFalse(editor.dom.getContentEditableParent(realTarget))) { + e.preventDefault(); + } + }); + } + + return { + init: init + }; +}); + +// Included from: js/tinymce/classes/SelectionOverrides.js + +/** + * SelectionOverrides.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This module contains logic overriding the selection with keyboard/mouse + * around contentEditable=false regions. + * + * @example + * // Disable the default cE=false selection + * tinymce.activeEditor.on('ShowCaret BeforeObjectSelected', function(e) { + * e.preventDefault(); + * }); + * + * @private + * @class tinymce.SelectionOverrides + */ +define("tinymce/SelectionOverrides", [ + "tinymce/Env", + "tinymce/caret/CaretWalker", + "tinymce/caret/CaretPosition", + "tinymce/caret/CaretContainer", + "tinymce/caret/CaretUtils", + "tinymce/caret/FakeCaret", + "tinymce/caret/LineWalker", + "tinymce/caret/LineUtils", + "tinymce/dom/NodeType", + "tinymce/dom/RangeUtils", + "tinymce/geom/ClientRect", + "tinymce/util/VK", + "tinymce/util/Fun", + "tinymce/util/Arr", + "tinymce/util/Delay", + "tinymce/DragDropOverrides", + "tinymce/text/Zwsp" +], function( + Env, CaretWalker, CaretPosition, CaretContainer, CaretUtils, FakeCaret, LineWalker, + LineUtils, NodeType, RangeUtils, ClientRect, VK, Fun, Arr, Delay, DragDropOverrides, Zwsp +) { + var curry = Fun.curry, + isContentEditableTrue = NodeType.isContentEditableTrue, + isContentEditableFalse = NodeType.isContentEditableFalse, + isElement = NodeType.isElement, + isAfterContentEditableFalse = CaretUtils.isAfterContentEditableFalse, + isBeforeContentEditableFalse = CaretUtils.isBeforeContentEditableFalse, + getSelectedNode = RangeUtils.getSelectedNode; + + function getVisualCaretPosition(walkFn, caretPosition) { + while ((caretPosition = walkFn(caretPosition))) { + if (caretPosition.isVisible()) { + return caretPosition; + } + } + + return caretPosition; + } + + function SelectionOverrides(editor) { + var rootNode = editor.getBody(), caretWalker = new CaretWalker(rootNode); + var getNextVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.next); + var getPrevVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.prev), + fakeCaret = new FakeCaret(editor.getBody(), isBlock), + realSelectionId = 'sel-' + editor.dom.uniqueId(), + selectedContentEditableNode, $ = editor.$; + + function isBlock(node) { + return editor.dom.isBlock(node); + } + + function setRange(range) { + //console.log('setRange', range); + if (range) { + editor.selection.setRng(range); + } + } + + function getRange() { + return editor.selection.getRng(); + } + + function scrollIntoView(node, alignToTop) { + editor.selection.scrollIntoView(node, alignToTop); + } + + function showCaret(direction, node, before) { + var e; + + e = editor.fire('ShowCaret', { + target: node, + direction: direction, + before: before + }); + + if (e.isDefaultPrevented()) { + return null; + } + + scrollIntoView(node, direction === -1); + + return fakeCaret.show(before, node); + } + + function selectNode(node) { + var e; + + fakeCaret.hide(); + + e = editor.fire('BeforeObjectSelected', {target: node}); + if (e.isDefaultPrevented()) { + return null; + } + + return getNodeRange(node); + } + + function getNodeRange(node) { + var rng = node.ownerDocument.createRange(); + + rng.selectNode(node); + + return rng; + } + + function isMoveInsideSameBlock(fromCaretPosition, toCaretPosition) { + var inSameBlock = CaretUtils.isInSameBlock(fromCaretPosition, toCaretPosition); + + // Handle bogus BR <p>abc|<br></p> + if (!inSameBlock && NodeType.isBr(fromCaretPosition.getNode())) { + return true; + } + + return inSameBlock; + } + + function getNormalizedRangeEndPoint(direction, range) { + range = CaretUtils.normalizeRange(direction, rootNode, range); + + if (direction == -1) { + return CaretPosition.fromRangeStart(range); + } + + return CaretPosition.fromRangeEnd(range); + } + + function isRangeInCaretContainerBlock(range) { + return CaretContainer.isCaretContainerBlock(range.startContainer); + } + + function moveToCeFalseHorizontally(direction, getNextPosFn, isBeforeContentEditableFalseFn, range) { + var node, caretPosition, peekCaretPosition, rangeIsInContainerBlock; + + if (!range.collapsed) { + node = getSelectedNode(range); + if (isContentEditableFalse(node)) { + return showCaret(direction, node, direction == -1); + } + } + + rangeIsInContainerBlock = isRangeInCaretContainerBlock(range); + caretPosition = getNormalizedRangeEndPoint(direction, range); + + if (isBeforeContentEditableFalseFn(caretPosition)) { + return selectNode(caretPosition.getNode(direction == -1)); + } + + caretPosition = getNextPosFn(caretPosition); + if (!caretPosition) { + if (rangeIsInContainerBlock) { + return range; + } + + return null; + } + + if (isBeforeContentEditableFalseFn(caretPosition)) { + return showCaret(direction, caretPosition.getNode(direction == -1), direction == 1); + } + + // Peek ahead for handling of ab|c<span cE=false> -> abc|<span cE=false> + peekCaretPosition = getNextPosFn(caretPosition); + if (isBeforeContentEditableFalseFn(peekCaretPosition)) { + if (isMoveInsideSameBlock(caretPosition, peekCaretPosition)) { + return showCaret(direction, peekCaretPosition.getNode(direction == -1), direction == 1); + } + } + + if (rangeIsInContainerBlock) { + return renderRangeCaret(caretPosition.toRange()); + } + + return null; + } + + function moveToCeFalseVertically(direction, walkerFn, range) { + var caretPosition, linePositions, nextLinePositions, + closestNextLineRect, caretClientRect, clientX, + dist1, dist2, contentEditableFalseNode; + + contentEditableFalseNode = getSelectedNode(range); + caretPosition = getNormalizedRangeEndPoint(direction, range); + linePositions = walkerFn(rootNode, LineWalker.isAboveLine(1), caretPosition); + nextLinePositions = Arr.filter(linePositions, LineWalker.isLine(1)); + caretClientRect = Arr.last(caretPosition.getClientRects()); + + if (isBeforeContentEditableFalse(caretPosition)) { + contentEditableFalseNode = caretPosition.getNode(); + } + + if (isAfterContentEditableFalse(caretPosition)) { + contentEditableFalseNode = caretPosition.getNode(true); + } + + if (!caretClientRect) { + return null; + } + + clientX = caretClientRect.left; + + closestNextLineRect = LineUtils.findClosestClientRect(nextLinePositions, clientX); + if (closestNextLineRect) { + if (isContentEditableFalse(closestNextLineRect.node)) { + dist1 = Math.abs(clientX - closestNextLineRect.left); + dist2 = Math.abs(clientX - closestNextLineRect.right); + + return showCaret(direction, closestNextLineRect.node, dist1 < dist2); + } + } + + if (contentEditableFalseNode) { + var caretPositions = LineWalker.positionsUntil(direction, rootNode, LineWalker.isAboveLine(1), contentEditableFalseNode); + + closestNextLineRect = LineUtils.findClosestClientRect(Arr.filter(caretPositions, LineWalker.isLine(1)), clientX); + if (closestNextLineRect) { + return renderRangeCaret(closestNextLineRect.position.toRange()); + } + + closestNextLineRect = Arr.last(Arr.filter(caretPositions, LineWalker.isLine(0))); + if (closestNextLineRect) { + return renderRangeCaret(closestNextLineRect.position.toRange()); + } + } + } + + function exitPreBlock(direction, range) { + var pre, caretPos, newBlock; + + function createTextBlock() { + var textBlock = editor.dom.create(editor.settings.forced_root_block); + + if (!Env.ie || Env.ie >= 11) { + textBlock.innerHTML = '<br data-mce-bogus="1">'; + } + + return textBlock; + } + + if (range.collapsed && editor.settings.forced_root_block) { + pre = editor.dom.getParent(range.startContainer, 'PRE'); + if (!pre) { + return; + } + + if (direction == 1) { + caretPos = getNextVisualCaretPosition(CaretPosition.fromRangeStart(range)); + } else { + caretPos = getPrevVisualCaretPosition(CaretPosition.fromRangeStart(range)); + } + + if (!caretPos) { + newBlock = createTextBlock(); + + if (direction == 1) { + editor.$(pre).after(newBlock); + } else { + editor.$(pre).before(newBlock); + } + + editor.selection.select(newBlock, true); + editor.selection.collapse(); + } + } + } + + function moveH(direction, getNextPosFn, isBeforeContentEditableFalseFn, range) { + var newRange; + + newRange = moveToCeFalseHorizontally(direction, getNextPosFn, isBeforeContentEditableFalseFn, range); + if (newRange) { + return newRange; + } + + newRange = exitPreBlock(direction, range); + if (newRange) { + return newRange; + } + + return null; + } + + function moveV(direction, walkerFn, range) { + var newRange; + + newRange = moveToCeFalseVertically(direction, walkerFn, range); + if (newRange) { + return newRange; + } + + newRange = exitPreBlock(direction, range); + if (newRange) { + return newRange; + } + + return null; + } + + function getBlockCaretContainer() { + return $('*[data-mce-caret]')[0]; + } + + function showBlockCaretContainer(blockCaretContainer) { + blockCaretContainer = $(blockCaretContainer); + + if (blockCaretContainer.attr('data-mce-caret')) { + fakeCaret.hide(); + blockCaretContainer.removeAttr('data-mce-caret'); + blockCaretContainer.removeAttr('data-mce-bogus'); + blockCaretContainer.removeAttr('style'); + + // Removes control rect on IE + setRange(getRange()); + scrollIntoView(blockCaretContainer[0]); + } + } + + function renderCaretAtRange(range) { + var caretPosition, ceRoot; + + range = CaretUtils.normalizeRange(1, rootNode, range); + caretPosition = CaretPosition.fromRangeStart(range); + + if (isContentEditableFalse(caretPosition.getNode())) { + return showCaret(1, caretPosition.getNode(), !caretPosition.isAtEnd()); + } + + if (isContentEditableFalse(caretPosition.getNode(true))) { + return showCaret(1, caretPosition.getNode(true), false); + } + + // TODO: Should render caret before/after depending on where you click on the page forces after now + ceRoot = editor.dom.getParent(caretPosition.getNode(), Fun.or(isContentEditableFalse, isContentEditableTrue)); + if (isContentEditableFalse(ceRoot)) { + return showCaret(1, ceRoot, false); + } + + fakeCaret.hide(); + + return null; + } + + function renderRangeCaret(range) { + var caretRange; + + if (!range || !range.collapsed) { + return range; + } + + caretRange = renderCaretAtRange(range); + if (caretRange) { + return caretRange; + } + + return range; + } + + function deleteContentEditableNode(node) { + var nextCaretPosition, prevCaretPosition, prevCeFalseElm, nextElement; + + if (!isContentEditableFalse(node)) { + return null; + } + + if (isContentEditableFalse(node.previousSibling)) { + prevCeFalseElm = node.previousSibling; + } + + prevCaretPosition = getPrevVisualCaretPosition(CaretPosition.before(node)); + if (!prevCaretPosition) { + nextCaretPosition = getNextVisualCaretPosition(CaretPosition.after(node)); + } + + if (nextCaretPosition && isElement(nextCaretPosition.getNode())) { + nextElement = nextCaretPosition.getNode(); + } + + CaretContainer.remove(node.previousSibling); + CaretContainer.remove(node.nextSibling); + editor.dom.remove(node); + clearContentEditableSelection(); + + if (editor.dom.isEmpty(editor.getBody())) { + editor.setContent(''); + editor.focus(); + return; + } + + if (prevCeFalseElm) { + return CaretPosition.after(prevCeFalseElm).toRange(); + } + + if (nextElement) { + return CaretPosition.before(nextElement).toRange(); + } + + if (prevCaretPosition) { + return prevCaretPosition.toRange(); + } + + if (nextCaretPosition) { + return nextCaretPosition.toRange(); + } + + return null; + } + + function mergeTextBlocks(direction, fromCaretPosition, toCaretPosition) { + var dom = editor.dom, fromBlock, toBlock, node, textBlocks; + + if (direction === -1) { + if (isAfterContentEditableFalse(toCaretPosition) && isBlock(toCaretPosition.getNode(true))) { + return deleteContentEditableNode(toCaretPosition.getNode(true)); + } + } else { + if (isBeforeContentEditableFalse(fromCaretPosition) && isBlock(fromCaretPosition.getNode())) { + return deleteContentEditableNode(fromCaretPosition.getNode()); + } + } + + textBlocks = editor.schema.getTextBlockElements(); + fromBlock = dom.getParent(fromCaretPosition.getNode(), dom.isBlock); + toBlock = dom.getParent(toCaretPosition.getNode(), dom.isBlock); + + // Verify that both blocks are text blocks + if (fromBlock === toBlock || !textBlocks[fromBlock.nodeName] || !textBlocks[toBlock.nodeName]) { + return null; + } + + while ((node = fromBlock.firstChild)) { + toBlock.appendChild(node); + } + + editor.dom.remove(fromBlock); + + return toCaretPosition.toRange(); + } + + function backspaceDelete(direction, beforeFn, range) { + var node, caretPosition, peekCaretPosition; + + if (!range.collapsed) { + node = getSelectedNode(range); + if (isContentEditableFalse(node)) { + return renderRangeCaret(deleteContentEditableNode(node)); + } + } + + caretPosition = getNormalizedRangeEndPoint(direction, range); + + if (beforeFn(caretPosition)) { + return renderRangeCaret(deleteContentEditableNode(caretPosition.getNode(direction == -1))); + } + + peekCaretPosition = direction == -1 ? caretWalker.prev(caretPosition) : caretWalker.next(caretPosition); + if (beforeFn(peekCaretPosition)) { + if (direction === -1) { + return mergeTextBlocks(direction, caretPosition, peekCaretPosition); + } + + return mergeTextBlocks(direction, peekCaretPosition, caretPosition); + } + } + + function registerEvents() { + var right = curry(moveH, 1, getNextVisualCaretPosition, isBeforeContentEditableFalse); + var left = curry(moveH, -1, getPrevVisualCaretPosition, isAfterContentEditableFalse); + var deleteForward = curry(backspaceDelete, 1, isBeforeContentEditableFalse); + var backspace = curry(backspaceDelete, -1, isAfterContentEditableFalse); + var up = curry(moveV, -1, LineWalker.upUntil); + var down = curry(moveV, 1, LineWalker.downUntil); + + function override(evt, moveFn) { + var range = moveFn(getRange()); + + if (range && !evt.isDefaultPrevented()) { + evt.preventDefault(); + setRange(range); + } + } + + function getContentEditableRoot(node) { + var root = editor.getBody(); + + while (node && node != root) { + if (isContentEditableTrue(node) || isContentEditableFalse(node)) { + return node; + } + + node = node.parentNode; + } + + return null; + } + + function isXYWithinRange(clientX, clientY, range) { + if (range.collapsed) { + return false; + } + + return Arr.reduce(range.getClientRects(), function(state, rect) { + return state || ClientRect.containsXY(rect, clientX, clientY); + }, false); + } + + // Some browsers (Chrome) lets you place the caret after a cE=false + // Make sure we render the caret container in this case + editor.on('mouseup', function() { + var range = getRange(); + + if (range.collapsed) { + setRange(renderCaretAtRange(range)); + } + }); + + editor.on('click', function(e) { + var contentEditableRoot; + + // Prevent clicks on links in a cE=false element + contentEditableRoot = getContentEditableRoot(e.target); + if (contentEditableRoot) { + if (isContentEditableFalse(contentEditableRoot)) { + e.preventDefault(); + } + } + }); + + var hasNormalCaretPosition = function (elm) { + var caretWalker = new CaretWalker(elm); + + if (!elm.firstChild) { + return false; + } + + var startPos = CaretPosition.before(elm.firstChild); + var newPos = caretWalker.next(startPos); + + return newPos && !isBeforeContentEditableFalse(newPos) && !isAfterContentEditableFalse(newPos); + }; + + var isInSameBlock = function (node1, node2) { + var block1 = editor.dom.getParent(node1, editor.dom.isBlock); + var block2 = editor.dom.getParent(node2, editor.dom.isBlock); + return block1 === block2; + }; + + // Checks if the target node is in a block and if that block has a caret position better than the + // suggested caretNode this is to prevent the caret from being sucked in towards a cE=false block if + // they are adjacent on the vertical axis + var hasBetterMouseTarget = function (targetNode, caretNode) { + var targetBlock = editor.dom.getParent(targetNode, editor.dom.isBlock); + var caretBlock = editor.dom.getParent(caretNode, editor.dom.isBlock); + + return targetBlock && !isInSameBlock(targetBlock, caretBlock) && hasNormalCaretPosition(targetBlock); + }; + + editor.on('mousedown', function(e) { + var contentEditableRoot; + + contentEditableRoot = getContentEditableRoot(e.target); + if (contentEditableRoot) { + if (isContentEditableFalse(contentEditableRoot)) { + e.preventDefault(); + setContentEditableSelection(selectNode(contentEditableRoot)); + } else { + clearContentEditableSelection(); + + if (!isXYWithinRange(e.clientX, e.clientY, editor.selection.getRng())) { + editor.selection.placeCaretAt(e.clientX, e.clientY); + } + } + } else { + clearContentEditableSelection(); + fakeCaret.hide(); + + var caretInfo = LineUtils.closestCaret(rootNode, e.clientX, e.clientY); + if (caretInfo) { + if (!hasBetterMouseTarget(e.target, caretInfo.node)) { + e.preventDefault(); + editor.getBody().focus(); + setRange(showCaret(1, caretInfo.node, caretInfo.before)); + } + } + } + }); + + editor.on('keydown', function(e) { + if (VK.modifierPressed(e)) { + return; + } + + switch (e.keyCode) { + case VK.RIGHT: + override(e, right); + break; + + case VK.DOWN: + override(e, down); + break; + + case VK.LEFT: + override(e, left); + break; + + case VK.UP: + override(e, up); + break; + + case VK.DELETE: + override(e, deleteForward); + break; + + case VK.BACKSPACE: + override(e, backspace); + break; + + default: + if (isContentEditableFalse(editor.selection.getNode())) { + e.preventDefault(); + } + break; + } + }); + + function paddEmptyContentEditableArea() { + var br, ceRoot = getContentEditableRoot(editor.selection.getNode()); + + if (isContentEditableTrue(ceRoot) && isBlock(ceRoot) && editor.dom.isEmpty(ceRoot)) { + br = editor.dom.create('br', {"data-mce-bogus": "1"}); + editor.$(ceRoot).empty().append(br); + editor.selection.setRng(CaretPosition.before(br).toRange()); + } + } + + function handleBlockContainer(e) { + var blockCaretContainer = getBlockCaretContainer(); + + if (!blockCaretContainer) { + return; + } + + if (e.type == 'compositionstart') { + e.preventDefault(); + e.stopPropagation(); + showBlockCaretContainer(blockCaretContainer); + return; + } + + if (blockCaretContainer.innerHTML != ' ') { + showBlockCaretContainer(blockCaretContainer); + } + } + + function handleEmptyBackspaceDelete(e) { + var prevent; + + switch (e.keyCode) { + case VK.DELETE: + prevent = paddEmptyContentEditableArea(); + break; + + case VK.BACKSPACE: + prevent = paddEmptyContentEditableArea(); + break; + } + + if (prevent) { + e.preventDefault(); + } + } + + // Must be added to "top" since undoManager needs to be executed after + editor.on('keyup compositionstart', function(e) { + handleBlockContainer(e); + handleEmptyBackspaceDelete(e); + }, true); + + editor.on('cut', function() { + var node = editor.selection.getNode(); + + if (isContentEditableFalse(node)) { + Delay.setEditorTimeout(editor, function() { + setRange(renderRangeCaret(deleteContentEditableNode(node))); + }); + } + }); + + editor.on('getSelectionRange', function(e) { + var rng = e.range; + + if (selectedContentEditableNode) { + if (!selectedContentEditableNode.parentNode) { + selectedContentEditableNode = null; + return; + } + + rng = rng.cloneRange(); + rng.selectNode(selectedContentEditableNode); + e.range = rng; + } + }); + + editor.on('setSelectionRange', function(e) { + var rng; + + rng = setContentEditableSelection(e.range); + if (rng) { + e.range = rng; + } + }); + + editor.on('focus', function() { + // Make sure we have a proper fake caret on focus + Delay.setEditorTimeout(editor, function() { + editor.selection.setRng(renderRangeCaret(editor.selection.getRng())); + }, 0); + }); + + DragDropOverrides.init(editor); + } + + function addCss() { + var styles = editor.contentStyles, rootClass = '.mce-content-body'; + + styles.push(fakeCaret.getCss()); + styles.push( + rootClass + ' .mce-offscreen-selection {' + + 'position: absolute;' + + 'left: -9999999999px;' + + 'width: 100px;' + + 'height: 100px;' + + '}' + + rootClass + ' *[contentEditable=false] {' + + 'cursor: default;' + + '}' + + rootClass + ' *[contentEditable=true] {' + + 'cursor: text;' + + '}' + ); + } + + function isRangeInCaretContainer(rng) { + return CaretContainer.isCaretContainer(rng.startContainer) || CaretContainer.isCaretContainer(rng.endContainer); + } + + function setContentEditableSelection(range) { + var node, $ = editor.$, dom = editor.dom, $realSelectionContainer, sel, + startContainer, startOffset, endOffset, e, caretPosition, targetClone, origTargetClone; + + if (!range) { + clearContentEditableSelection(); + return null; + } + + if (range.collapsed) { + clearContentEditableSelection(); + + if (!isRangeInCaretContainer(range)) { + caretPosition = getNormalizedRangeEndPoint(1, range); + + if (isContentEditableFalse(caretPosition.getNode())) { + return showCaret(1, caretPosition.getNode(), !caretPosition.isAtEnd()); + } + + if (isContentEditableFalse(caretPosition.getNode(true))) { + return showCaret(1, caretPosition.getNode(true), false); + } + } + + return null; + } + + startContainer = range.startContainer; + startOffset = range.startOffset; + endOffset = range.endOffset; + + // Normalizes <span cE=false>[</span>] to [<span cE=false></span>] + if (startContainer.nodeType == 3 && startOffset == 0 && isContentEditableFalse(startContainer.parentNode)) { + startContainer = startContainer.parentNode; + startOffset = dom.nodeIndex(startContainer); + startContainer = startContainer.parentNode; + } + + if (startContainer.nodeType != 1) { + clearContentEditableSelection(); + return null; + } + + if (endOffset == startOffset + 1) { + node = startContainer.childNodes[startOffset]; + } + + if (!isContentEditableFalse(node)) { + clearContentEditableSelection(); + return null; + } + + targetClone = origTargetClone = node.cloneNode(true); + e = editor.fire('ObjectSelected', {target: node, targetClone: targetClone}); + if (e.isDefaultPrevented()) { + clearContentEditableSelection(); + return null; + } + + targetClone = e.targetClone; + $realSelectionContainer = $('#' + realSelectionId); + if ($realSelectionContainer.length === 0) { + $realSelectionContainer = $( + '<div data-mce-bogus="all" class="mce-offscreen-selection"></div>' + ).attr('id', realSelectionId); + + $realSelectionContainer.appendTo(editor.getBody()); + } + + range = editor.dom.createRng(); + + // WHY is IE making things so hard! Copy on <i contentEditable="false">x</i> produces: <em>x</em> + if (targetClone === origTargetClone && Env.ie) { + $realSelectionContainer.empty().append(Zwsp.ZWSP).append(targetClone).append(Zwsp.ZWSP); + range.setStart($realSelectionContainer[0].firstChild, 0); + range.setEnd($realSelectionContainer[0].lastChild, 1); + } else { + $realSelectionContainer.empty().append('\u00a0').append(targetClone).append('\u00a0'); + range.setStart($realSelectionContainer[0].firstChild, 1); + range.setEnd($realSelectionContainer[0].lastChild, 0); + } + + $realSelectionContainer.css({ + top: dom.getPos(node, editor.getBody()).y + }); + + editor.getBody().focus(); + $realSelectionContainer[0].focus(); + sel = editor.selection.getSel(); + sel.removeAllRanges(); + sel.addRange(range); + + editor.$('*[data-mce-selected]').removeAttr('data-mce-selected'); + node.setAttribute('data-mce-selected', 1); + selectedContentEditableNode = node; + + return range; + } + + function clearContentEditableSelection() { + if (selectedContentEditableNode) { + selectedContentEditableNode.removeAttribute('data-mce-selected'); + editor.$('#' + realSelectionId).remove(); + selectedContentEditableNode = null; + } + } + + function destroy() { + fakeCaret.destroy(); + selectedContentEditableNode = null; + } + + if (Env.ceFalse) { + registerEvents(); + addCss(); + } + + return { + showBlockCaretContainer: showBlockCaretContainer, + destroy: destroy + }; + } + + return SelectionOverrides; +}); + +// Included from: js/tinymce/classes/Editor.js + +/** + * Editor.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/*jshint scripturl:true */ + +/** + * Include the base event class documentation. + * + * @include ../../../tools/docs/tinymce.Event.js + */ + +/** + * This class contains the core logic for a TinyMCE editor. + * + * @class tinymce.Editor + * @mixes tinymce.util.Observable + * @example + * // Add a class to all paragraphs in the editor. + * tinymce.activeEditor.dom.addClass(tinymce.activeEditor.dom.select('p'), 'someclass'); + * + * // Gets the current editors selection as text + * tinymce.activeEditor.selection.getContent({format: 'text'}); + * + * // Creates a new editor instance + * var ed = new tinymce.Editor('textareaid', { + * some_setting: 1 + * }, tinymce.EditorManager); + * + * // Select each item the user clicks on + * ed.on('click', function(e) { + * ed.selection.select(e.target); + * }); + * + * ed.render(); + */ +define("tinymce/Editor", [ + "tinymce/dom/DOMUtils", + "tinymce/dom/DomQuery", + "tinymce/AddOnManager", + "tinymce/NodeChange", + "tinymce/html/Node", + "tinymce/dom/Serializer", + "tinymce/html/Serializer", + "tinymce/dom/Selection", + "tinymce/Formatter", + "tinymce/UndoManager", + "tinymce/EnterKey", + "tinymce/ForceBlocks", + "tinymce/EditorCommands", + "tinymce/util/URI", + "tinymce/dom/ScriptLoader", + "tinymce/dom/EventUtils", + "tinymce/WindowManager", + "tinymce/NotificationManager", + "tinymce/html/Schema", + "tinymce/html/DomParser", + "tinymce/util/Quirks", + "tinymce/Env", + "tinymce/util/Tools", + "tinymce/util/Delay", + "tinymce/EditorObservable", + "tinymce/Mode", + "tinymce/Shortcuts", + "tinymce/EditorUpload", + "tinymce/SelectionOverrides" +], function( + DOMUtils, DomQuery, AddOnManager, NodeChange, Node, DomSerializer, Serializer, + Selection, Formatter, UndoManager, EnterKey, ForceBlocks, EditorCommands, + URI, ScriptLoader, EventUtils, WindowManager, NotificationManager, + Schema, DomParser, Quirks, Env, Tools, Delay, EditorObservable, Mode, Shortcuts, EditorUpload, + SelectionOverrides +) { + // Shorten these names + var DOM = DOMUtils.DOM, ThemeManager = AddOnManager.ThemeManager, PluginManager = AddOnManager.PluginManager; + var extend = Tools.extend, each = Tools.each, explode = Tools.explode; + var inArray = Tools.inArray, trim = Tools.trim, resolve = Tools.resolve; + var Event = EventUtils.Event; + var isGecko = Env.gecko, ie = Env.ie; + + /** + * Include documentation for all the events. + * + * @include ../../../tools/docs/tinymce.Editor.js + */ + + /** + * Constructs a editor instance by id. + * + * @constructor + * @method Editor + * @param {String} id Unique id for the editor. + * @param {Object} settings Settings for the editor. + * @param {tinymce.EditorManager} editorManager EditorManager instance. + */ + function Editor(id, settings, editorManager) { + var self = this, documentBaseUrl, baseUri, defaultSettings; + + documentBaseUrl = self.documentBaseUrl = editorManager.documentBaseURL; + baseUri = editorManager.baseURI; + defaultSettings = editorManager.defaultSettings; + + /** + * Name/value collection with editor settings. + * + * @property settings + * @type Object + * @example + * // Get the value of the theme setting + * tinymce.activeEditor.windowManager.alert("You are using the " + tinymce.activeEditor.settings.theme + " theme"); + */ + settings = extend({ + id: id, + theme: 'modern', + delta_width: 0, + delta_height: 0, + popup_css: '', + plugins: '', + document_base_url: documentBaseUrl, + add_form_submit_trigger: true, + submit_patch: true, + add_unload_trigger: true, + convert_urls: true, + relative_urls: true, + remove_script_host: true, + object_resizing: true, + doctype: '<!DOCTYPE html>', + visual: true, + font_size_style_values: 'xx-small,x-small,small,medium,large,x-large,xx-large', + + // See: http://www.w3.org/TR/CSS2/fonts.html#propdef-font-size + font_size_legacy_values: 'xx-small,small,medium,large,x-large,xx-large,300%', + forced_root_block: 'p', + hidden_input: true, + padd_empty_editor: true, + render_ui: true, + indentation: '30px', + inline_styles: true, + convert_fonts_to_spans: true, + indent: 'simple', + indent_before: 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,th,ul,ol,li,dl,dt,dd,area,table,thead,' + + 'tfoot,tbody,tr,section,article,hgroup,aside,figure,figcaption,option,optgroup,datalist', + indent_after: 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,th,ul,ol,li,dl,dt,dd,area,table,thead,' + + 'tfoot,tbody,tr,section,article,hgroup,aside,figure,figcaption,option,optgroup,datalist', + validate: true, + entity_encoding: 'named', + url_converter: self.convertURL, + url_converter_scope: self, + ie7_compat: true + }, defaultSettings, settings); + + // Merge external_plugins + if (defaultSettings && defaultSettings.external_plugins && settings.external_plugins) { + settings.external_plugins = extend({}, defaultSettings.external_plugins, settings.external_plugins); + } + + self.settings = settings; + AddOnManager.language = settings.language || 'en'; + AddOnManager.languageLoad = settings.language_load; + AddOnManager.baseURL = editorManager.baseURL; + + /** + * Editor instance id, normally the same as the div/textarea that was replaced. + * + * @property id + * @type String + */ + self.id = settings.id = id; + + /** + * State to force the editor to return false on a isDirty call. + * + * @property isNotDirty + * @type Boolean + * @deprecated Use editor.setDirty instead. + */ + self.setDirty(false); + + /** + * Name/Value object containing plugin instances. + * + * @property plugins + * @type Object + * @example + * // Execute a method inside a plugin directly + * tinymce.activeEditor.plugins.someplugin.someMethod(); + */ + self.plugins = {}; + + /** + * URI object to document configured for the TinyMCE instance. + * + * @property documentBaseURI + * @type tinymce.util.URI + * @example + * // Get relative URL from the location of document_base_url + * tinymce.activeEditor.documentBaseURI.toRelative('/somedir/somefile.htm'); + * + * // Get absolute URL from the location of document_base_url + * tinymce.activeEditor.documentBaseURI.toAbsolute('somefile.htm'); + */ + self.documentBaseURI = new URI(settings.document_base_url || documentBaseUrl, { + base_uri: baseUri + }); + + /** + * URI object to current document that holds the TinyMCE editor instance. + * + * @property baseURI + * @type tinymce.util.URI + * @example + * // Get relative URL from the location of the API + * tinymce.activeEditor.baseURI.toRelative('/somedir/somefile.htm'); + * + * // Get absolute URL from the location of the API + * tinymce.activeEditor.baseURI.toAbsolute('somefile.htm'); + */ + self.baseURI = baseUri; + + /** + * Array with CSS files to load into the iframe. + * + * @property contentCSS + * @type Array + */ + self.contentCSS = []; + + /** + * Array of CSS styles to add to head of document when the editor loads. + * + * @property contentStyles + * @type Array + */ + self.contentStyles = []; + + // Creates all events like onClick, onSetContent etc see Editor.Events.js for the actual logic + self.shortcuts = new Shortcuts(self); + self.loadedCSS = {}; + self.editorCommands = new EditorCommands(self); + + if (settings.target) { + self.targetElm = settings.target; + } + + self.suffix = editorManager.suffix; + self.editorManager = editorManager; + self.inline = settings.inline; + + if (settings.cache_suffix) { + Env.cacheSuffix = settings.cache_suffix.replace(/^[\?\&]+/, ''); + } + + if (settings.override_viewport === false) { + Env.overrideViewPort = false; + } + + // Call setup + editorManager.fire('SetupEditor', self); + self.execCallback('setup', self); + + /** + * Dom query instance with default scope to the editor document and default element is the body of the editor. + * + * @property $ + * @type tinymce.dom.DomQuery + * @example + * tinymce.activeEditor.$('p').css('color', 'red'); + * tinymce.activeEditor.$().append('<p>new</p>'); + */ + self.$ = DomQuery.overrideDefaults(function() { + return { + context: self.inline ? self.getBody() : self.getDoc(), + element: self.getBody() + }; + }); + } + + Editor.prototype = { + /** + * Renders the editor/adds it to the page. + * + * @method render + */ + render: function() { + var self = this, settings = self.settings, id = self.id, suffix = self.suffix; + + function readyHandler() { + DOM.unbind(window, 'ready', readyHandler); + self.render(); + } + + // Page is not loaded yet, wait for it + if (!Event.domLoaded) { + DOM.bind(window, 'ready', readyHandler); + return; + } + + // Element not found, then skip initialization + if (!self.getElement()) { + return; + } + + // No editable support old iOS versions etc + if (!Env.contentEditable) { + return; + } + + // Hide target element early to prevent content flashing + if (!settings.inline) { + self.orgVisibility = self.getElement().style.visibility; + self.getElement().style.visibility = 'hidden'; + } else { + self.inline = true; + } + + var form = self.getElement().form || DOM.getParent(id, 'form'); + if (form) { + self.formElement = form; + + // Add hidden input for non input elements inside form elements + if (settings.hidden_input && !/TEXTAREA|INPUT/i.test(self.getElement().nodeName)) { + DOM.insertAfter(DOM.create('input', {type: 'hidden', name: id}), id); + self.hasHiddenInput = true; + } + + // Pass submit/reset from form to editor instance + self.formEventDelegate = function(e) { + self.fire(e.type, e); + }; + + DOM.bind(form, 'submit reset', self.formEventDelegate); + + // Reset contents in editor when the form is reset + self.on('reset', function() { + self.setContent(self.startContent, {format: 'raw'}); + }); + + // Check page uses id="submit" or name="submit" for it's submit button + if (settings.submit_patch && !form.submit.nodeType && !form.submit.length && !form._mceOldSubmit) { + form._mceOldSubmit = form.submit; + form.submit = function() { + self.editorManager.triggerSave(); + self.setDirty(false); + + return form._mceOldSubmit(form); + }; + } + } + + /** + * Window manager reference, use this to open new windows and dialogs. + * + * @property windowManager + * @type tinymce.WindowManager + * @example + * // Shows an alert message + * tinymce.activeEditor.windowManager.alert('Hello world!'); + * + * // Opens a new dialog with the file.htm file and the size 320x240 + * // It also adds a custom parameter this can be retrieved by using tinyMCEPopup.getWindowArg inside the dialog. + * tinymce.activeEditor.windowManager.open({ + * url: 'file.htm', + * width: 320, + * height: 240 + * }, { + * custom_param: 1 + * }); + */ + self.windowManager = new WindowManager(self); + + /** + * Notification manager reference, use this to open new windows and dialogs. + * + * @property notificationManager + * @type tinymce.NotificationManager + * @example + * // Shows a notification info message. + * tinymce.activeEditor.notificationManager.open({text: 'Hello world!', type: 'info'}); + */ + self.notificationManager = new NotificationManager(self); + + if (settings.encoding == 'xml') { + self.on('GetContent', function(e) { + if (e.save) { + e.content = DOM.encode(e.content); + } + }); + } + + if (settings.add_form_submit_trigger) { + self.on('submit', function() { + if (self.initialized) { + self.save(); + } + }); + } + + if (settings.add_unload_trigger) { + self._beforeUnload = function() { + if (self.initialized && !self.destroyed && !self.isHidden()) { + self.save({format: 'raw', no_events: true, set_dirty: false}); + } + }; + + self.editorManager.on('BeforeUnload', self._beforeUnload); + } + + // Load scripts + function loadScripts() { + var scriptLoader = ScriptLoader.ScriptLoader; + + if (settings.language && settings.language != 'en' && !settings.language_url) { + settings.language_url = self.editorManager.baseURL + '/langs/' + settings.language + '.js'; + } + + if (settings.language_url) { + scriptLoader.add(settings.language_url); + } + + if (settings.theme && typeof settings.theme != "function" && + settings.theme.charAt(0) != '-' && !ThemeManager.urls[settings.theme]) { + var themeUrl = settings.theme_url; + + if (themeUrl) { + themeUrl = self.documentBaseURI.toAbsolute(themeUrl); + } else { + themeUrl = 'themes/' + settings.theme + '/theme' + suffix + '.js'; + } + + ThemeManager.load(settings.theme, themeUrl); + } + + if (Tools.isArray(settings.plugins)) { + settings.plugins = settings.plugins.join(' '); + } + + each(settings.external_plugins, function(url, name) { + PluginManager.load(name, url); + settings.plugins += ' ' + name; + }); + + each(settings.plugins.split(/[ ,]/), function(plugin) { + plugin = trim(plugin); + + if (plugin && !PluginManager.urls[plugin]) { + if (plugin.charAt(0) == '-') { + plugin = plugin.substr(1, plugin.length); + + var dependencies = PluginManager.dependencies(plugin); + + each(dependencies, function(dep) { + var defaultSettings = { + prefix: 'plugins/', + resource: dep, + suffix: '/plugin' + suffix + '.js' + }; + + dep = PluginManager.createUrl(defaultSettings, dep); + PluginManager.load(dep.resource, dep); + }); + } else { + PluginManager.load(plugin, { + prefix: 'plugins/', + resource: plugin, + suffix: '/plugin' + suffix + '.js' + }); + } + } + }); + + scriptLoader.loadQueue(function() { + if (!self.removed) { + self.init(); + } + }); + } + + self.editorManager.add(self); + loadScripts(); + }, + + /** + * Initializes the editor this will be called automatically when + * all plugins/themes and language packs are loaded by the rendered method. + * This method will setup the iframe and create the theme and plugin instances. + * + * @method init + */ + init: function() { + var self = this, settings = self.settings, elm = self.getElement(); + var w, h, minHeight, n, o, Theme, url, bodyId, bodyClass, re, i, initializedPlugins = []; + + this.editorManager.i18n.setCode(settings.language); + self.rtl = settings.rtl_ui || this.editorManager.i18n.rtl; + + settings.aria_label = settings.aria_label || DOM.getAttrib(elm, 'aria-label', self.getLang('aria.rich_text_area')); + + /** + * Reference to the theme instance that was used to generate the UI. + * + * @property theme + * @type tinymce.Theme + * @example + * // Executes a method on the theme directly + * tinymce.activeEditor.theme.someMethod(); + */ + if (settings.theme) { + if (typeof settings.theme != "function") { + settings.theme = settings.theme.replace(/-/, ''); + Theme = ThemeManager.get(settings.theme); + self.theme = new Theme(self, ThemeManager.urls[settings.theme]); + + if (self.theme.init) { + self.theme.init(self, ThemeManager.urls[settings.theme] || self.documentBaseUrl.replace(/\/$/, ''), self.$); + } + } else { + self.theme = settings.theme; + } + } + + function initPlugin(plugin) { + var Plugin = PluginManager.get(plugin), pluginUrl, pluginInstance; + + pluginUrl = PluginManager.urls[plugin] || self.documentBaseUrl.replace(/\/$/, ''); + plugin = trim(plugin); + if (Plugin && inArray(initializedPlugins, plugin) === -1) { + each(PluginManager.dependencies(plugin), function(dep) { + initPlugin(dep); + }); + + if (self.plugins[plugin]) { + return; + } + + pluginInstance = new Plugin(self, pluginUrl, self.$); + + self.plugins[plugin] = pluginInstance; + + if (pluginInstance.init) { + pluginInstance.init(self, pluginUrl); + initializedPlugins.push(plugin); + } + } + } + + // Create all plugins + each(settings.plugins.replace(/\-/g, '').split(/[ ,]/), initPlugin); + + // Measure box + if (settings.render_ui && self.theme) { + self.orgDisplay = elm.style.display; + + if (typeof settings.theme != "function") { + w = settings.width || elm.style.width || elm.offsetWidth; + h = settings.height || elm.style.height || elm.offsetHeight; + minHeight = settings.min_height || 100; + re = /^[0-9\.]+(|px)$/i; + + if (re.test('' + w)) { + w = Math.max(parseInt(w, 10), 100); + } + + if (re.test('' + h)) { + h = Math.max(parseInt(h, 10), minHeight); + } + + // Render UI + o = self.theme.renderUI({ + targetNode: elm, + width: w, + height: h, + deltaWidth: settings.delta_width, + deltaHeight: settings.delta_height + }); + + // Resize editor + if (!settings.content_editable) { + h = (o.iframeHeight || h) + (typeof h == 'number' ? (o.deltaHeight || 0) : ''); + if (h < minHeight) { + h = minHeight; + } + } + } else { + o = settings.theme(self, elm); + + // Convert element type to id:s + if (o.editorContainer.nodeType) { + o.editorContainer = o.editorContainer.id = o.editorContainer.id || self.id + "_parent"; + } + + // Convert element type to id:s + if (o.iframeContainer.nodeType) { + o.iframeContainer = o.iframeContainer.id = o.iframeContainer.id || self.id + "_iframecontainer"; + } + + // Use specified iframe height or the targets offsetHeight + h = o.iframeHeight || elm.offsetHeight; + } + + self.editorContainer = o.editorContainer; + } + + // Load specified content CSS last + if (settings.content_css) { + each(explode(settings.content_css), function(u) { + self.contentCSS.push(self.documentBaseURI.toAbsolute(u)); + }); + } + + // Load specified content CSS last + if (settings.content_style) { + self.contentStyles.push(settings.content_style); + } + + // Content editable mode ends here + if (settings.content_editable) { + elm = n = o = null; // Fix IE leak + return self.initContentBody(); + } + + self.iframeHTML = settings.doctype + '<html><head>'; + + // We only need to override paths if we have to + // IE has a bug where it remove site absolute urls to relative ones if this is specified + if (settings.document_base_url != self.documentBaseUrl) { + self.iframeHTML += '<base href="' + self.documentBaseURI.getURI() + '" />'; + } + + // IE8 doesn't support carets behind images setting ie7_compat would force IE8+ to run in IE7 compat mode. + if (!Env.caretAfter && settings.ie7_compat) { + self.iframeHTML += '<meta http-equiv="X-UA-Compatible" content="IE=7" />'; + } + + self.iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />'; + + // Load the CSS by injecting them into the HTML this will reduce "flicker" + // However we can't do that on Chrome since # will scroll to the editor for some odd reason see #2427 + if (!/#$/.test(document.location.href)) { + for (i = 0; i < self.contentCSS.length; i++) { + var cssUrl = self.contentCSS[i]; + self.iframeHTML += ( + '<link type="text/css" ' + + 'rel="stylesheet" ' + + 'href="' + Tools._addCacheSuffix(cssUrl) + '" />' + ); + self.loadedCSS[cssUrl] = true; + } + } + + bodyId = settings.body_id || 'tinymce'; + if (bodyId.indexOf('=') != -1) { + bodyId = self.getParam('body_id', '', 'hash'); + bodyId = bodyId[self.id] || bodyId; + } + + bodyClass = settings.body_class || ''; + if (bodyClass.indexOf('=') != -1) { + bodyClass = self.getParam('body_class', '', 'hash'); + bodyClass = bodyClass[self.id] || ''; + } + + if (settings.content_security_policy) { + self.iframeHTML += '<meta http-equiv="Content-Security-Policy" content="' + settings.content_security_policy + '" />'; + } + + self.iframeHTML += '</head><body id="' + bodyId + + '" class="mce-content-body ' + bodyClass + + '" data-id="' + self.id + '"><br></body></html>'; + + /*eslint no-script-url:0 */ + var domainRelaxUrl = 'javascript:(function(){' + + 'document.open();document.domain="' + document.domain + '";' + + 'var ed = window.parent.tinymce.get("' + self.id + '");document.write(ed.iframeHTML);' + + 'document.close();ed.initContentBody(true);})()'; + + // Domain relaxing is required since the user has messed around with document.domain + if (document.domain != location.hostname) { + // Edge seems to be able to handle domain relaxing + if (Env.ie && Env.ie < 12) { + url = domainRelaxUrl; + } + } + + // Create iframe + // TODO: ACC add the appropriate description on this. + var ifr = DOM.create('iframe', { + id: self.id + "_ifr", + //src: url || 'javascript:""', // Workaround for HTTPS warning in IE6/7 + frameBorder: '0', + allowTransparency: "true", + title: self.editorManager.translate( + "Rich Text Area. Press ALT-F9 for menu. " + + "Press ALT-F10 for toolbar. Press ALT-0 for help" + ), + style: { + width: '100%', + height: h, + display: 'block' // Important for Gecko to render the iframe correctly + } + }); + + ifr.onload = function() { + ifr.onload = null; + self.fire("load"); + }; + + DOM.setAttrib(ifr, "src", url || 'javascript:""'); + + self.contentAreaContainer = o.iframeContainer; + self.iframeElement = ifr; + + n = DOM.add(o.iframeContainer, ifr); + + // Try accessing the document this will fail on IE when document.domain is set to the same as location.hostname + // Then we have to force domain relaxing using the domainRelaxUrl approach very ugly!! + if (ie) { + try { + self.getDoc(); + } catch (e) { + n.src = url = domainRelaxUrl; + } + } + + if (o.editorContainer) { + DOM.get(o.editorContainer).style.display = self.orgDisplay; + self.hidden = DOM.isHidden(o.editorContainer); + } + + self.getElement().style.display = 'none'; + DOM.setAttrib(self.id, 'aria-hidden', true); + + if (!url) { + self.initContentBody(); + } + + elm = n = o = null; // Cleanup + }, + + /** + * This method get called by the init method once the iframe is loaded. + * It will fill the iframe with contents, sets up DOM and selection objects for the iframe. + * + * @method initContentBody + * @private + */ + initContentBody: function(skipWrite) { + var self = this, settings = self.settings, targetElm = self.getElement(), doc = self.getDoc(), body, contentCssText; + + // Restore visibility on target element + if (!settings.inline) { + self.getElement().style.visibility = self.orgVisibility; + } + + // Setup iframe body + if (!skipWrite && !settings.content_editable) { + doc.open(); + doc.write(self.iframeHTML); + doc.close(); + } + + if (settings.content_editable) { + self.on('remove', function() { + var bodyEl = this.getBody(); + + DOM.removeClass(bodyEl, 'mce-content-body'); + DOM.removeClass(bodyEl, 'mce-edit-focus'); + DOM.setAttrib(bodyEl, 'contentEditable', null); + }); + + DOM.addClass(targetElm, 'mce-content-body'); + self.contentDocument = doc = settings.content_document || document; + self.contentWindow = settings.content_window || window; + self.bodyElement = targetElm; + + // Prevent leak in IE + settings.content_document = settings.content_window = null; + + // TODO: Fix this + settings.root_name = targetElm.nodeName.toLowerCase(); + } + + // It will not steal focus while setting contentEditable + body = self.getBody(); + body.disabled = true; + self.readonly = settings.readonly; + + if (!self.readonly) { + if (self.inline && DOM.getStyle(body, 'position', true) == 'static') { + body.style.position = 'relative'; + } + + body.contentEditable = self.getParam('content_editable_state', true); + } + + body.disabled = false; + + self.editorUpload = new EditorUpload(self); + + /** + * Schema instance, enables you to validate elements and its children. + * + * @property schema + * @type tinymce.html.Schema + */ + self.schema = new Schema(settings); + + /** + * DOM instance for the editor. + * + * @property dom + * @type tinymce.dom.DOMUtils + * @example + * // Adds a class to all paragraphs within the editor + * tinymce.activeEditor.dom.addClass(tinymce.activeEditor.dom.select('p'), 'someclass'); + */ + self.dom = new DOMUtils(doc, { + keep_values: true, + url_converter: self.convertURL, + url_converter_scope: self, + hex_colors: settings.force_hex_style_colors, + class_filter: settings.class_filter, + update_styles: true, + root_element: self.inline ? self.getBody() : null, + collect: settings.content_editable, + schema: self.schema, + onSetAttrib: function(e) { + self.fire('SetAttrib', e); + } + }); + + /** + * HTML parser will be used when contents is inserted into the editor. + * + * @property parser + * @type tinymce.html.DomParser + */ + self.parser = new DomParser(settings, self.schema); + + // Convert src and href into data-mce-src, data-mce-href and data-mce-style + self.parser.addAttributeFilter('src,href,style,tabindex', function(nodes, name) { + var i = nodes.length, node, dom = self.dom, value, internalName; + + while (i--) { + node = nodes[i]; + value = node.attr(name); + internalName = 'data-mce-' + name; + + // Add internal attribute if we need to we don't on a refresh of the document + if (!node.attributes.map[internalName]) { + // Don't duplicate these since they won't get modified by any browser + if (value.indexOf('data:') === 0 || value.indexOf('blob:') === 0) { + continue; + } + + if (name === "style") { + value = dom.serializeStyle(dom.parseStyle(value), node.name); + + if (!value.length) { + value = null; + } + + node.attr(internalName, value); + node.attr(name, value); + } else if (name === "tabindex") { + node.attr(internalName, value); + node.attr(name, null); + } else { + node.attr(internalName, self.convertURL(value, name, node.name)); + } + } + } + }); + + // Keep scripts from executing + self.parser.addNodeFilter('script', function(nodes) { + var i = nodes.length, node, type; + + while (i--) { + node = nodes[i]; + type = node.attr('type') || 'no/type'; + if (type.indexOf('mce-') !== 0) { + node.attr('type', 'mce-' + type); + } + } + }); + + self.parser.addNodeFilter('#cdata', function(nodes) { + var i = nodes.length, node; + + while (i--) { + node = nodes[i]; + node.type = 8; + node.name = '#comment'; + node.value = '[CDATA[' + node.value + ']]'; + } + }); + + self.parser.addNodeFilter('p,h1,h2,h3,h4,h5,h6,div', function(nodes) { + var i = nodes.length, node, nonEmptyElements = self.schema.getNonEmptyElements(); + + while (i--) { + node = nodes[i]; + + if (node.isEmpty(nonEmptyElements)) { + node.append(new Node('br', 1)).shortEnded = true; + } + } + }); + + /** + * DOM serializer for the editor. Will be used when contents is extracted from the editor. + * + * @property serializer + * @type tinymce.dom.Serializer + * @example + * // Serializes the first paragraph in the editor into a string + * tinymce.activeEditor.serializer.serialize(tinymce.activeEditor.dom.select('p')[0]); + */ + self.serializer = new DomSerializer(settings, self); + + /** + * Selection instance for the editor. + * + * @property selection + * @type tinymce.dom.Selection + * @example + * // Sets some contents to the current selection in the editor + * tinymce.activeEditor.selection.setContent('Some contents'); + * + * // Gets the current selection + * alert(tinymce.activeEditor.selection.getContent()); + * + * // Selects the first paragraph found + * tinymce.activeEditor.selection.select(tinymce.activeEditor.dom.select('p')[0]); + */ + self.selection = new Selection(self.dom, self.getWin(), self.serializer, self); + + /** + * Formatter instance. + * + * @property formatter + * @type tinymce.Formatter + */ + self.formatter = new Formatter(self); + + /** + * Undo manager instance, responsible for handling undo levels. + * + * @property undoManager + * @type tinymce.UndoManager + * @example + * // Undoes the last modification to the editor + * tinymce.activeEditor.undoManager.undo(); + */ + self.undoManager = new UndoManager(self); + + self.forceBlocks = new ForceBlocks(self); + self.enterKey = new EnterKey(self); + self._nodeChangeDispatcher = new NodeChange(self); + self._selectionOverrides = new SelectionOverrides(self); + + self.fire('PreInit'); + + if (!settings.browser_spellcheck && !settings.gecko_spellcheck) { + doc.body.spellcheck = false; // Gecko + DOM.setAttrib(body, "spellcheck", "false"); + } + + self.quirks = new Quirks(self); + self.fire('PostRender'); + + if (settings.directionality) { + body.dir = settings.directionality; + } + + if (settings.nowrap) { + body.style.whiteSpace = "nowrap"; + } + + if (settings.protect) { + self.on('BeforeSetContent', function(e) { + each(settings.protect, function(pattern) { + e.content = e.content.replace(pattern, function(str) { + return '<!--mce:protected ' + escape(str) + '-->'; + }); + }); + }); + } + + self.on('SetContent', function() { + self.addVisual(self.getBody()); + }); + + // Remove empty contents + if (settings.padd_empty_editor) { + self.on('PostProcess', function(e) { + e.content = e.content.replace(/^(<p[^>]*>( | |\s|\u00a0|)<\/p>[\r\n]*|<br \/>[\r\n]*)$/, ''); + }); + } + + self.load({initial: true, format: 'html'}); + self.startContent = self.getContent({format: 'raw'}); + + /** + * Is set to true after the editor instance has been initialized + * + * @property initialized + * @type Boolean + * @example + * function isEditorInitialized(editor) { + * return editor && editor.initialized; + * } + */ + self.initialized = true; + self.bindPendingEventDelegates(); + + self.fire('init'); + self.focus(true); + self.nodeChanged({initial: true}); + self.execCallback('init_instance_callback', self); + + self.on('compositionstart compositionend', function(e) { + self.composing = e.type === 'compositionstart'; + }); + + // Add editor specific CSS styles + if (self.contentStyles.length > 0) { + contentCssText = ''; + + each(self.contentStyles, function(style) { + contentCssText += style + "\r\n"; + }); + + self.dom.addStyle(contentCssText); + } + + // Load specified content CSS last + each(self.contentCSS, function(cssUrl) { + if (!self.loadedCSS[cssUrl]) { + self.dom.loadCSS(cssUrl); + self.loadedCSS[cssUrl] = true; + } + }); + + // Handle auto focus + if (settings.auto_focus) { + Delay.setEditorTimeout(self, function() { + var editor; + + if (settings.auto_focus === true) { + editor = self; + } else { + editor = self.editorManager.get(settings.auto_focus); + } + + if (!editor.destroyed) { + editor.focus(); + } + }, 100); + } + + // Clean up references for IE + targetElm = doc = body = null; + }, + + /** + * Focuses/activates the editor. This will set this editor as the activeEditor in the tinymce collection + * it will also place DOM focus inside the editor. + * + * @method focus + * @param {Boolean} skipFocus Skip DOM focus. Just set is as the active editor. + */ + focus: function(skipFocus) { + var self = this, selection = self.selection, contentEditable = self.settings.content_editable, rng; + var controlElm, doc = self.getDoc(), body = self.getBody(), contentEditableHost; + + function getContentEditableHost(node) { + return self.dom.getParent(node, function(node) { + return self.dom.getContentEditable(node) === "true"; + }); + } + + if (!skipFocus) { + // Get selected control element + rng = selection.getRng(); + if (rng.item) { + controlElm = rng.item(0); + } + + self.quirks.refreshContentEditable(); + + // Move focus to contentEditable=true child if needed + contentEditableHost = getContentEditableHost(selection.getNode()); + if (self.$.contains(body, contentEditableHost)) { + contentEditableHost.focus(); + selection.normalize(); + self.editorManager.setActive(self); + return; + } + + // Focus the window iframe + if (!contentEditable) { + // WebKit needs this call to fire focusin event properly see #5948 + // But Opera pre Blink engine will produce an empty selection so skip Opera + if (!Env.opera) { + self.getBody().focus(); + } + + self.getWin().focus(); + } + + // Focus the body as well since it's contentEditable + if (isGecko || contentEditable) { + // Check for setActive since it doesn't scroll to the element + if (body.setActive) { + // IE 11 sometimes throws "Invalid function" then fallback to focus + try { + body.setActive(); + } catch (ex) { + body.focus(); + } + } else { + body.focus(); + } + + if (contentEditable) { + selection.normalize(); + } + } + + // Restore selected control element + // This is needed when for example an image is selected within a + // layer a call to focus will then remove the control selection + if (controlElm && controlElm.ownerDocument == doc) { + rng = doc.body.createControlRange(); + rng.addElement(controlElm); + rng.select(); + } + } + + self.editorManager.setActive(self); + }, + + /** + * Executes a legacy callback. This method is useful to call old 2.x option callbacks. + * There new event model is a better way to add callback so this method might be removed in the future. + * + * @method execCallback + * @param {String} name Name of the callback to execute. + * @return {Object} Return value passed from callback function. + */ + execCallback: function(name) { + var self = this, callback = self.settings[name], scope; + + if (!callback) { + return; + } + + // Look through lookup + if (self.callbackLookup && (scope = self.callbackLookup[name])) { + callback = scope.func; + scope = scope.scope; + } + + if (typeof callback === 'string') { + scope = callback.replace(/\.\w+$/, ''); + scope = scope ? resolve(scope) : 0; + callback = resolve(callback); + self.callbackLookup = self.callbackLookup || {}; + self.callbackLookup[name] = {func: callback, scope: scope}; + } + + return callback.apply(scope || self, Array.prototype.slice.call(arguments, 1)); + }, + + /** + * Translates the specified string by replacing variables with language pack items it will also check if there is + * a key matching the input. + * + * @method translate + * @param {String} text String to translate by the language pack data. + * @return {String} Translated string. + */ + translate: function(text) { + var lang = this.settings.language || 'en', i18n = this.editorManager.i18n; + + if (!text) { + return ''; + } + + text = i18n.data[lang + '.' + text] || text.replace(/\{\#([^\}]+)\}/g, function(a, b) { + return i18n.data[lang + '.' + b] || '{#' + b + '}'; + }); + + return this.editorManager.translate(text); + }, + + /** + * Returns a language pack item by name/key. + * + * @method getLang + * @param {String} name Name/key to get from the language pack. + * @param {String} defaultVal Optional default value to retrieve. + */ + getLang: function(name, defaultVal) { + return ( + this.editorManager.i18n.data[(this.settings.language || 'en') + '.' + name] || + (defaultVal !== undefined ? defaultVal : '{#' + name + '}') + ); + }, + + /** + * Returns a configuration parameter by name. + * + * @method getParam + * @param {String} name Configruation parameter to retrieve. + * @param {String} defaultVal Optional default value to return. + * @param {String} type Optional type parameter. + * @return {String} Configuration parameter value or default value. + * @example + * // Returns a specific config value from the currently active editor + * var someval = tinymce.activeEditor.getParam('myvalue'); + * + * // Returns a specific config value from a specific editor instance by id + * var someval2 = tinymce.get('my_editor').getParam('myvalue'); + */ + getParam: function(name, defaultVal, type) { + var value = name in this.settings ? this.settings[name] : defaultVal, output; + + if (type === 'hash') { + output = {}; + + if (typeof value === 'string') { + each(value.indexOf('=') > 0 ? value.split(/[;,](?![^=;,]*(?:[;,]|$))/) : value.split(','), function(value) { + value = value.split('='); + + if (value.length > 1) { + output[trim(value[0])] = trim(value[1]); + } else { + output[trim(value[0])] = trim(value); + } + }); + } else { + output = value; + } + + return output; + } + + return value; + }, + + /** + * Dispatches out a onNodeChange event to all observers. This method should be called when you + * need to update the UI states or element path etc. + * + * @method nodeChanged + * @param {Object} args Optional args to pass to NodeChange event handlers. + */ + nodeChanged: function(args) { + this._nodeChangeDispatcher.nodeChanged(args); + }, + + /** + * Adds a button that later gets created by the theme in the editors toolbars. + * + * @method addButton + * @param {String} name Button name to add. + * @param {Object} settings Settings object with title, cmd etc. + * @example + * // Adds a custom button to the editor that inserts contents when clicked + * tinymce.init({ + * ... + * + * toolbar: 'example' + * + * setup: function(ed) { + * ed.addButton('example', { + * title: 'My title', + * image: '../js/tinymce/plugins/example/img/example.gif', + * onclick: function() { + * ed.insertContent('Hello world!!'); + * } + * }); + * } + * }); + */ + addButton: function(name, settings) { + var self = this; + + if (settings.cmd) { + settings.onclick = function() { + self.execCommand(settings.cmd); + }; + } + + if (!settings.text && !settings.icon) { + settings.icon = name; + } + + self.buttons = self.buttons || {}; + settings.tooltip = settings.tooltip || settings.title; + self.buttons[name] = settings; + }, + + /** + * Adds a menu item to be used in the menus of the theme. There might be multiple instances + * of this menu item for example it might be used in the main menus of the theme but also in + * the context menu so make sure that it's self contained and supports multiple instances. + * + * @method addMenuItem + * @param {String} name Menu item name to add. + * @param {Object} settings Settings object with title, cmd etc. + * @example + * // Adds a custom menu item to the editor that inserts contents when clicked + * // The context option allows you to add the menu item to an existing default menu + * tinymce.init({ + * ... + * + * setup: function(ed) { + * ed.addMenuItem('example', { + * text: 'My menu item', + * context: 'tools', + * onclick: function() { + * ed.insertContent('Hello world!!'); + * } + * }); + * } + * }); + */ + addMenuItem: function(name, settings) { + var self = this; + + if (settings.cmd) { + settings.onclick = function() { + self.execCommand(settings.cmd); + }; + } + + self.menuItems = self.menuItems || {}; + self.menuItems[name] = settings; + }, + + /** + * Adds a contextual toolbar to be rendered when the selector matches. + * + * @method addContextToolbar + * @param {function/string} predicate Predicate that needs to return true if provided strings get converted into CSS predicates. + * @param {String/Array} items String or array with items to add to the context toolbar. + */ + addContextToolbar: function(predicate, items) { + var self = this, selector; + + self.contextToolbars = self.contextToolbars || []; + + // Convert selector to predicate + if (typeof predicate == "string") { + selector = predicate; + predicate = function(elm) { + return self.dom.is(elm, selector); + }; + } + + self.contextToolbars.push({ + predicate: predicate, + items: items + }); + }, + + /** + * Adds a custom command to the editor, you can also override existing commands with this method. + * The command that you add can be executed with execCommand. + * + * @method addCommand + * @param {String} name Command name to add/override. + * @param {addCommandCallback} callback Function to execute when the command occurs. + * @param {Object} scope Optional scope to execute the function in. + * @example + * // Adds a custom command that later can be executed using execCommand + * tinymce.init({ + * ... + * + * setup: function(ed) { + * // Register example command + * ed.addCommand('mycommand', function(ui, v) { + * ed.windowManager.alert('Hello world!! Selection: ' + ed.selection.getContent({format: 'text'})); + * }); + * } + * }); + */ + addCommand: function(name, callback, scope) { + /** + * Callback function that gets called when a command is executed. + * + * @callback addCommandCallback + * @param {Boolean} ui Display UI state true/false. + * @param {Object} value Optional value for command. + * @return {Boolean} True/false state if the command was handled or not. + */ + this.editorCommands.addCommand(name, callback, scope); + }, + + /** + * Adds a custom query state command to the editor, you can also override existing commands with this method. + * The command that you add can be executed with queryCommandState function. + * + * @method addQueryStateHandler + * @param {String} name Command name to add/override. + * @param {addQueryStateHandlerCallback} callback Function to execute when the command state retrieval occurs. + * @param {Object} scope Optional scope to execute the function in. + */ + addQueryStateHandler: function(name, callback, scope) { + /** + * Callback function that gets called when a queryCommandState is executed. + * + * @callback addQueryStateHandlerCallback + * @return {Boolean} True/false state if the command is enabled or not like is it bold. + */ + this.editorCommands.addQueryStateHandler(name, callback, scope); + }, + + /** + * Adds a custom query value command to the editor, you can also override existing commands with this method. + * The command that you add can be executed with queryCommandValue function. + * + * @method addQueryValueHandler + * @param {String} name Command name to add/override. + * @param {addQueryValueHandlerCallback} callback Function to execute when the command value retrieval occurs. + * @param {Object} scope Optional scope to execute the function in. + */ + addQueryValueHandler: function(name, callback, scope) { + /** + * Callback function that gets called when a queryCommandValue is executed. + * + * @callback addQueryValueHandlerCallback + * @return {Object} Value of the command or undefined. + */ + this.editorCommands.addQueryValueHandler(name, callback, scope); + }, + + /** + * Adds a keyboard shortcut for some command or function. + * + * @method addShortcut + * @param {String} pattern Shortcut pattern. Like for example: ctrl+alt+o. + * @param {String} desc Text description for the command. + * @param {String/Function} cmdFunc Command name string or function to execute when the key is pressed. + * @param {Object} sc Optional scope to execute the function in. + * @return {Boolean} true/false state if the shortcut was added or not. + */ + addShortcut: function(pattern, desc, cmdFunc, scope) { + this.shortcuts.add(pattern, desc, cmdFunc, scope); + }, + + /** + * Executes a command on the current instance. These commands can be TinyMCE internal commands prefixed with "mce" or + * they can be build in browser commands such as "Bold". A compleate list of browser commands is available on MSDN or Mozilla.org. + * This function will dispatch the execCommand function on each plugin, theme or the execcommand_callback option if none of these + * return true it will handle the command as a internal browser command. + * + * @method execCommand + * @param {String} cmd Command name to execute, for example mceLink or Bold. + * @param {Boolean} ui True/false state if a UI (dialog) should be presented or not. + * @param {mixed} value Optional command value, this can be anything. + * @param {Object} args Optional arguments object. + */ + execCommand: function(cmd, ui, value, args) { + return this.editorCommands.execCommand(cmd, ui, value, args); + }, + + /** + * Returns a command specific state, for example if bold is enabled or not. + * + * @method queryCommandState + * @param {string} cmd Command to query state from. + * @return {Boolean} Command specific state, for example if bold is enabled or not. + */ + queryCommandState: function(cmd) { + return this.editorCommands.queryCommandState(cmd); + }, + + /** + * Returns a command specific value, for example the current font size. + * + * @method queryCommandValue + * @param {string} cmd Command to query value from. + * @return {Object} Command specific value, for example the current font size. + */ + queryCommandValue: function(cmd) { + return this.editorCommands.queryCommandValue(cmd); + }, + + /** + * Returns true/false if the command is supported or not. + * + * @method queryCommandSupported + * @param {String} cmd Command that we check support for. + * @return {Boolean} true/false if the command is supported or not. + */ + queryCommandSupported: function(cmd) { + return this.editorCommands.queryCommandSupported(cmd); + }, + + /** + * Shows the editor and hides any textarea/div that the editor is supposed to replace. + * + * @method show + */ + show: function() { + var self = this; + + if (self.hidden) { + self.hidden = false; + + if (self.inline) { + self.getBody().contentEditable = true; + } else { + DOM.show(self.getContainer()); + DOM.hide(self.id); + } + + self.load(); + self.fire('show'); + } + }, + + /** + * Hides the editor and shows any textarea/div that the editor is supposed to replace. + * + * @method hide + */ + hide: function() { + var self = this, doc = self.getDoc(); + + if (!self.hidden) { + // Fixed bug where IE has a blinking cursor left from the editor + if (ie && doc && !self.inline) { + doc.execCommand('SelectAll'); + } + + // We must save before we hide so Safari doesn't crash + self.save(); + + if (self.inline) { + self.getBody().contentEditable = false; + + // Make sure the editor gets blurred + if (self == self.editorManager.focusedEditor) { + self.editorManager.focusedEditor = null; + } + } else { + DOM.hide(self.getContainer()); + DOM.setStyle(self.id, 'display', self.orgDisplay); + } + + self.hidden = true; + self.fire('hide'); + } + }, + + /** + * Returns true/false if the editor is hidden or not. + * + * @method isHidden + * @return {Boolean} True/false if the editor is hidden or not. + */ + isHidden: function() { + return !!this.hidden; + }, + + /** + * Sets the progress state, this will display a throbber/progess for the editor. + * This is ideal for asynchronous operations like an AJAX save call. + * + * @method setProgressState + * @param {Boolean} state Boolean state if the progress should be shown or hidden. + * @param {Number} time Optional time to wait before the progress gets shown. + * @return {Boolean} Same as the input state. + * @example + * // Show progress for the active editor + * tinymce.activeEditor.setProgressState(true); + * + * // Hide progress for the active editor + * tinymce.activeEditor.setProgressState(false); + * + * // Show progress after 3 seconds + * tinymce.activeEditor.setProgressState(true, 3000); + */ + setProgressState: function(state, time) { + this.fire('ProgressState', {state: state, time: time}); + }, + + /** + * Loads contents from the textarea or div element that got converted into an editor instance. + * This method will move the contents from that textarea or div into the editor by using setContent + * so all events etc that method has will get dispatched as well. + * + * @method load + * @param {Object} args Optional content object, this gets passed around through the whole load process. + * @return {String} HTML string that got set into the editor. + */ + load: function(args) { + var self = this, elm = self.getElement(), html; + + if (elm) { + args = args || {}; + args.load = true; + + html = self.setContent(elm.value !== undefined ? elm.value : elm.innerHTML, args); + args.element = elm; + + if (!args.no_events) { + self.fire('LoadContent', args); + } + + args.element = elm = null; + + return html; + } + }, + + /** + * Saves the contents from a editor out to the textarea or div element that got converted into an editor instance. + * This method will move the HTML contents from the editor into that textarea or div by getContent + * so all events etc that method has will get dispatched as well. + * + * @method save + * @param {Object} args Optional content object, this gets passed around through the whole save process. + * @return {String} HTML string that got set into the textarea/div. + */ + save: function(args) { + var self = this, elm = self.getElement(), html, form; + + if (!elm || !self.initialized) { + return; + } + + args = args || {}; + args.save = true; + + args.element = elm; + html = args.content = self.getContent(args); + + if (!args.no_events) { + self.fire('SaveContent', args); + } + + // Always run this internal event + if (args.format == 'raw') { + self.fire('RawSaveContent', args); + } + + html = args.content; + + if (!/TEXTAREA|INPUT/i.test(elm.nodeName)) { + // Update DIV element when not in inline mode + if (!self.inline) { + elm.innerHTML = html; + } + + // Update hidden form element + if ((form = DOM.getParent(self.id, 'form'))) { + each(form.elements, function(elm) { + if (elm.name == self.id) { + elm.value = html; + return false; + } + }); + } + } else { + elm.value = html; + } + + args.element = elm = null; + + if (args.set_dirty !== false) { + self.setDirty(false); + } + + return html; + }, + + /** + * Sets the specified content to the editor instance, this will cleanup the content before it gets set using + * the different cleanup rules options. + * + * @method setContent + * @param {String} content Content to set to editor, normally HTML contents but can be other formats as well. + * @param {Object} args Optional content object, this gets passed around through the whole set process. + * @return {String} HTML string that got set into the editor. + * @example + * // Sets the HTML contents of the activeEditor editor + * tinymce.activeEditor.setContent('<span>some</span> html'); + * + * // Sets the raw contents of the activeEditor editor + * tinymce.activeEditor.setContent('<span>some</span> html', {format: 'raw'}); + * + * // Sets the content of a specific editor (my_editor in this example) + * tinymce.get('my_editor').setContent(data); + * + * // Sets the bbcode contents of the activeEditor editor if the bbcode plugin was added + * tinymce.activeEditor.setContent('[b]some[/b] html', {format: 'bbcode'}); + */ + setContent: function(content, args) { + var self = this, body = self.getBody(), forcedRootBlockName, padd; + + // Setup args object + args = args || {}; + args.format = args.format || 'html'; + args.set = true; + args.content = content; + + // Do preprocessing + if (!args.no_events) { + self.fire('BeforeSetContent', args); + } + + content = args.content; + + // Padd empty content in Gecko and Safari. Commands will otherwise fail on the content + // It will also be impossible to place the caret in the editor unless there is a BR element present + if (content.length === 0 || /^\s+$/.test(content)) { + padd = ie && ie < 11 ? '' : '<br data-mce-bogus="1">'; + + // Todo: There is a lot more root elements that need special padding + // so separate this and add all of them at some point. + if (body.nodeName == 'TABLE') { + content = '<tr><td>' + padd + '</td></tr>'; + } else if (/^(UL|OL)$/.test(body.nodeName)) { + content = '<li>' + padd + '</li>'; + } + + forcedRootBlockName = self.settings.forced_root_block; + + // Check if forcedRootBlock is configured and that the block is a valid child of the body + if (forcedRootBlockName && self.schema.isValidChild(body.nodeName.toLowerCase(), forcedRootBlockName.toLowerCase())) { + // Padd with bogus BR elements on modern browsers and IE 7 and 8 since they don't render empty P tags properly + content = padd; + content = self.dom.createHTML(forcedRootBlockName, self.settings.forced_root_block_attrs, content); + } else if (!ie && !content) { + // We need to add a BR when forced_root_block is disabled on non IE browsers to place the caret + content = '<br data-mce-bogus="1">'; + } + + self.dom.setHTML(body, content); + + self.fire('SetContent', args); + } else { + // Parse and serialize the html + if (args.format !== 'raw') { + content = new Serializer({ + validate: self.validate + }, self.schema).serialize( + self.parser.parse(content, {isRootContent: true}) + ); + } + + // Set the new cleaned contents to the editor + args.content = trim(content); + self.dom.setHTML(body, args.content); + + // Do post processing + if (!args.no_events) { + self.fire('SetContent', args); + } + + // Don't normalize selection if the focused element isn't the body in + // content editable mode since it will steal focus otherwise + /*if (!self.settings.content_editable || document.activeElement === self.getBody()) { + self.selection.normalize(); + }*/ + } + + return args.content; + }, + + /** + * Gets the content from the editor instance, this will cleanup the content before it gets returned using + * the different cleanup rules options. + * + * @method getContent + * @param {Object} args Optional content object, this gets passed around through the whole get process. + * @return {String} Cleaned content string, normally HTML contents. + * @example + * // Get the HTML contents of the currently active editor + * console.debug(tinymce.activeEditor.getContent()); + * + * // Get the raw contents of the currently active editor + * tinymce.activeEditor.getContent({format: 'raw'}); + * + * // Get content of a specific editor: + * tinymce.get('content id').getContent() + */ + getContent: function(args) { + var self = this, content, body = self.getBody(); + + // Setup args object + args = args || {}; + args.format = args.format || 'html'; + args.get = true; + args.getInner = true; + + // Do preprocessing + if (!args.no_events) { + self.fire('BeforeGetContent', args); + } + + // Get raw contents or by default the cleaned contents + if (args.format == 'raw') { + content = self.serializer.getTrimmedContent(); + } else if (args.format == 'text') { + content = body.innerText || body.textContent; + } else { + content = self.serializer.serialize(body, args); + } + + // Trim whitespace in beginning/end of HTML + if (args.format != 'text') { + args.content = trim(content); + } else { + args.content = content; + } + + // Do post processing + if (!args.no_events) { + self.fire('GetContent', args); + } + + return args.content; + }, + + /** + * Inserts content at caret position. + * + * @method insertContent + * @param {String} content Content to insert. + * @param {Object} args Optional args to pass to insert call. + */ + insertContent: function(content, args) { + if (args) { + content = extend({content: content}, args); + } + + this.execCommand('mceInsertContent', false, content); + }, + + /** + * Returns true/false if the editor is dirty or not. It will get dirty if the user has made modifications to the contents. + * + * The dirty state is automatically set to true if you do modifications to the content in other + * words when new undo levels is created or if you undo/redo to update the contents of the editor. It will also be set + * to false if you call editor.save(). + * + * @method isDirty + * @return {Boolean} True/false if the editor is dirty or not. It will get dirty if the user has made modifications to the contents. + * @example + * if (tinymce.activeEditor.isDirty()) + * alert("You must save your contents."); + */ + isDirty: function() { + return !this.isNotDirty; + }, + + /** + * Explicitly sets the dirty state. This will fire the dirty event if the editor dirty state is changed from false to true + * by invoking this method. + * + * @method setDirty + * @param {Boolean} state True/false if the editor is considered dirty. + * @example + * function ajaxSave() { + * var editor = tinymce.get('elm1'); + * + * // Save contents using some XHR call + * alert(editor.getContent()); + * + * editor.setDirty(false); // Force not dirty state + * } + */ + setDirty: function(state) { + var oldState = !this.isNotDirty; + + this.isNotDirty = !state; + + if (state && state != oldState) { + this.fire('dirty'); + } + }, + + /** + * Sets the editor mode. Mode can be for example "design", "code" or "readonly". + * + * @method setMode + * @param {String} mode Mode to set the editor in. + */ + setMode: function(mode) { + Mode.setMode(this, mode); + }, + + /** + * Returns the editors container element. The container element wrappes in + * all the elements added to the page for the editor. Such as UI, iframe etc. + * + * @method getContainer + * @return {Element} HTML DOM element for the editor container. + */ + getContainer: function() { + var self = this; + + if (!self.container) { + self.container = DOM.get(self.editorContainer || self.id + '_parent'); + } + + return self.container; + }, + + /** + * Returns the editors content area container element. The this element is the one who + * holds the iframe or the editable element. + * + * @method getContentAreaContainer + * @return {Element} HTML DOM element for the editor area container. + */ + getContentAreaContainer: function() { + return this.contentAreaContainer; + }, + + /** + * Returns the target element/textarea that got replaced with a TinyMCE editor instance. + * + * @method getElement + * @return {Element} HTML DOM element for the replaced element. + */ + getElement: function() { + if (!this.targetElm) { + this.targetElm = DOM.get(this.id); + } + + return this.targetElm; + }, + + /** + * Returns the iframes window object. + * + * @method getWin + * @return {Window} Iframe DOM window object. + */ + getWin: function() { + var self = this, elm; + + if (!self.contentWindow) { + elm = self.iframeElement; + + if (elm) { + self.contentWindow = elm.contentWindow; + } + } + + return self.contentWindow; + }, + + /** + * Returns the iframes document object. + * + * @method getDoc + * @return {Document} Iframe DOM document object. + */ + getDoc: function() { + var self = this, win; + + if (!self.contentDocument) { + win = self.getWin(); + + if (win) { + self.contentDocument = win.document; + } + } + + return self.contentDocument; + }, + + /** + * Returns the root element of the editable area. + * For a non-inline iframe-based editor, returns the iframe's body element. + * + * @method getBody + * @return {Element} The root element of the editable area. + */ + getBody: function() { + return this.bodyElement || this.getDoc().body; + }, + + /** + * URL converter function this gets executed each time a user adds an img, a or + * any other element that has a URL in it. This will be called both by the DOM and HTML + * manipulation functions. + * + * @method convertURL + * @param {string} url URL to convert. + * @param {string} name Attribute name src, href etc. + * @param {string/HTMLElement} elm Tag name or HTML DOM element depending on HTML or DOM insert. + * @return {string} Converted URL string. + */ + convertURL: function(url, name, elm) { + var self = this, settings = self.settings; + + // Use callback instead + if (settings.urlconverter_callback) { + return self.execCallback('urlconverter_callback', url, elm, true, name); + } + + // Don't convert link href since thats the CSS files that gets loaded into the editor also skip local file URLs + if (!settings.convert_urls || (elm && elm.nodeName == 'LINK') || url.indexOf('file:') === 0 || url.length === 0) { + return url; + } + + // Convert to relative + if (settings.relative_urls) { + return self.documentBaseURI.toRelative(url); + } + + // Convert to absolute + url = self.documentBaseURI.toAbsolute(url, settings.remove_script_host); + + return url; + }, + + /** + * Adds visual aid for tables, anchors etc so they can be more easily edited inside the editor. + * + * @method addVisual + * @param {Element} elm Optional root element to loop though to find tables etc that needs the visual aid. + */ + addVisual: function(elm) { + var self = this, settings = self.settings, dom = self.dom, cls; + + elm = elm || self.getBody(); + + if (self.hasVisual === undefined) { + self.hasVisual = settings.visual; + } + + each(dom.select('table,a', elm), function(elm) { + var value; + + switch (elm.nodeName) { + case 'TABLE': + cls = settings.visual_table_class || 'mce-item-table'; + value = dom.getAttrib(elm, 'border'); + + if ((!value || value == '0') && self.hasVisual) { + dom.addClass(elm, cls); + } else { + dom.removeClass(elm, cls); + } + + return; + + case 'A': + if (!dom.getAttrib(elm, 'href', false)) { + value = dom.getAttrib(elm, 'name') || elm.id; + cls = settings.visual_anchor_class || 'mce-item-anchor'; + + if (value && self.hasVisual) { + dom.addClass(elm, cls); + } else { + dom.removeClass(elm, cls); + } + } + + return; + } + }); + + self.fire('VisualAid', {element: elm, hasVisual: self.hasVisual}); + }, + + /** + * Removes the editor from the dom and tinymce collection. + * + * @method remove + */ + remove: function() { + var self = this; + + if (!self.removed) { + self.save(); + self.removed = 1; + self.unbindAllNativeEvents(); + + // Remove any hidden input + if (self.hasHiddenInput) { + DOM.remove(self.getElement().nextSibling); + } + + if (!self.inline) { + // IE 9 has a bug where the selection stops working if you place the + // caret inside the editor then remove the iframe + if (ie && ie < 10) { + self.getDoc().execCommand('SelectAll', false, null); + } + + DOM.setStyle(self.id, 'display', self.orgDisplay); + self.getBody().onload = null; // Prevent #6816 + } + + self.fire('remove'); + + self.editorManager.remove(self); + DOM.remove(self.getContainer()); + self._selectionOverrides.destroy(); + self.editorUpload.destroy(); + self.destroy(); + } + }, + + /** + * Destroys the editor instance by removing all events, element references or other resources + * that could leak memory. This method will be called automatically when the page is unloaded + * but you can also call it directly if you know what you are doing. + * + * @method destroy + * @param {Boolean} automatic Optional state if the destroy is an automatic destroy or user called one. + */ + destroy: function(automatic) { + var self = this, form; + + // One time is enough + if (self.destroyed) { + return; + } + + // If user manually calls destroy and not remove + // Users seems to have logic that calls destroy instead of remove + if (!automatic && !self.removed) { + self.remove(); + return; + } + + if (!automatic) { + self.editorManager.off('beforeunload', self._beforeUnload); + + // Manual destroy + if (self.theme && self.theme.destroy) { + self.theme.destroy(); + } + + // Destroy controls, selection and dom + self.selection.destroy(); + self.dom.destroy(); + } + + form = self.formElement; + if (form) { + if (form._mceOldSubmit) { + form.submit = form._mceOldSubmit; + form._mceOldSubmit = null; + } + + DOM.unbind(form, 'submit reset', self.formEventDelegate); + } + + self.contentAreaContainer = self.formElement = self.container = self.editorContainer = null; + self.bodyElement = self.contentDocument = self.contentWindow = null; + self.iframeElement = self.targetElm = null; + + if (self.selection) { + self.selection = self.selection.win = self.selection.dom = self.selection.dom.doc = null; + } + + self.destroyed = 1; + }, + + /** + * Uploads all data uri/blob uri images in the editor contents to server. + * + * @method uploadImages + * @param {function} callback Optional callback with images and status for each image. + * @return {tinymce.util.Promise} Promise instance. + */ + uploadImages: function(callback) { + return this.editorUpload.uploadImages(callback); + }, + + // Internal functions + + _scanForImages: function() { + return this.editorUpload.scanForImages(); + } + }; + + extend(Editor.prototype, EditorObservable); + + return Editor; +}); + +// Included from: js/tinymce/classes/util/I18n.js + +/** + * I18n.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * I18n class that handles translation of TinyMCE UI. + * Uses po style with csharp style parameters. + * + * @class tinymce.util.I18n + */ +define("tinymce/util/I18n", [], function() { + "use strict"; + + var data = {}, code = "en"; + + return { + /** + * Sets the current language code. + * + * @method setCode + * @param {String} newCode Current language code. + */ + setCode: function(newCode) { + if (newCode) { + code = newCode; + this.rtl = this.data[newCode] ? this.data[newCode]._dir === 'rtl' : false; + } + }, + + /** + * Returns the current language code. + * + * @method getCode + * @return {String} Current language code. + */ + getCode: function() { + return code; + }, + + /** + * Property gets set to true if a RTL language pack was loaded. + * + * @property rtl + * @type Boolean + */ + rtl: false, + + /** + * Adds translations for a specific language code. + * + * @method add + * @param {String} code Language code like sv_SE. + * @param {Array} items Name/value array with English en_US to sv_SE. + */ + add: function(code, items) { + var langData = data[code]; + + if (!langData) { + data[code] = langData = {}; + } + + for (var name in items) { + langData[name] = items[name]; + } + + this.setCode(code); + }, + + /** + * Translates the specified text. + * + * It has a few formats: + * I18n.translate("Text"); + * I18n.translate(["Text {0}/{1}", 0, 1]); + * I18n.translate({raw: "Raw string"}); + * + * @method translate + * @param {String/Object/Array} text Text to translate. + * @return {String} String that got translated. + */ + translate: function(text) { + var langData; + + langData = data[code]; + if (!langData) { + langData = {}; + } + + if (typeof text == "undefined") { + return text; + } + + if (typeof text != "string" && text.raw) { + return text.raw; + } + + if (text.push) { + var values = text.slice(1); + + text = (langData[text[0]] || text[0]).replace(/\{([0-9]+)\}/g, function(match1, match2) { + return values[match2]; + }); + } + + return (langData[text] || text).replace(/{context:\w+}$/, ''); + }, + + data: data + }; +}); + +// Included from: js/tinymce/classes/FocusManager.js + +/** + * FocusManager.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class manages the focus/blur state of the editor. This class is needed since some + * browsers fire false focus/blur states when the selection is moved to a UI dialog or similar. + * + * This class will fire two events focus and blur on the editor instances that got affected. + * It will also handle the restore of selection when the focus is lost and returned. + * + * @class tinymce.FocusManager + */ +define("tinymce/FocusManager", [ + "tinymce/dom/DOMUtils", + "tinymce/util/Delay", + "tinymce/Env" +], function(DOMUtils, Delay, Env) { + var selectionChangeHandler, documentFocusInHandler, documentMouseUpHandler, DOM = DOMUtils.DOM; + + /** + * Constructs a new focus manager instance. + * + * @constructor FocusManager + * @param {tinymce.EditorManager} editorManager Editor manager instance to handle focus for. + */ + function FocusManager(editorManager) { + function getActiveElement() { + try { + return document.activeElement; + } catch (ex) { + // IE sometimes fails to get the activeElement when resizing table + // TODO: Investigate this + return document.body; + } + } + + // We can't store a real range on IE 11 since it gets mutated so we need to use a bookmark object + // TODO: Move this to a separate range utils class since it's it's logic is present in Selection as well. + function createBookmark(dom, rng) { + if (rng && rng.startContainer) { + // Verify that the range is within the root of the editor + if (!dom.isChildOf(rng.startContainer, dom.getRoot()) || !dom.isChildOf(rng.endContainer, dom.getRoot())) { + return; + } + + return { + startContainer: rng.startContainer, + startOffset: rng.startOffset, + endContainer: rng.endContainer, + endOffset: rng.endOffset + }; + } + + return rng; + } + + function bookmarkToRng(editor, bookmark) { + var rng; + + if (bookmark.startContainer) { + rng = editor.getDoc().createRange(); + rng.setStart(bookmark.startContainer, bookmark.startOffset); + rng.setEnd(bookmark.endContainer, bookmark.endOffset); + } else { + rng = bookmark; + } + + return rng; + } + + function isUIElement(elm) { + return !!DOM.getParent(elm, FocusManager.isEditorUIElement); + } + + function registerEvents(e) { + var editor = e.editor; + + editor.on('init', function() { + // Gecko/WebKit has ghost selections in iframes and IE only has one selection per browser tab + if (editor.inline || Env.ie) { + // Use the onbeforedeactivate event when available since it works better see #7023 + if ("onbeforedeactivate" in document && Env.ie < 9) { + editor.dom.bind(editor.getBody(), 'beforedeactivate', function(e) { + if (e.target != editor.getBody()) { + return; + } + + try { + editor.lastRng = editor.selection.getRng(); + } catch (ex) { + // IE throws "Unexcpected call to method or property access" some times so lets ignore it + } + }); + } else { + // On other browsers take snapshot on nodechange in inline mode since they have Ghost selections for iframes + editor.on('nodechange mouseup keyup', function(e) { + var node = getActiveElement(); + + // Only act on manual nodechanges + if (e.type == 'nodechange' && e.selectionChange) { + return; + } + + // IE 11 reports active element as iframe not body of iframe + if (node && node.id == editor.id + '_ifr') { + node = editor.getBody(); + } + + if (editor.dom.isChildOf(node, editor.getBody())) { + editor.lastRng = editor.selection.getRng(); + } + }); + } + + // Handles the issue with WebKit not retaining selection within inline document + // If the user releases the mouse out side the body since a mouse up event wont occur on the body + if (Env.webkit && !selectionChangeHandler) { + selectionChangeHandler = function() { + var activeEditor = editorManager.activeEditor; + + if (activeEditor && activeEditor.selection) { + var rng = activeEditor.selection.getRng(); + + // Store when it's non collapsed + if (rng && !rng.collapsed) { + editor.lastRng = rng; + } + } + }; + + DOM.bind(document, 'selectionchange', selectionChangeHandler); + } + } + }); + + editor.on('setcontent', function() { + editor.lastRng = null; + }); + + // Remove last selection bookmark on mousedown see #6305 + editor.on('mousedown', function() { + editor.selection.lastFocusBookmark = null; + }); + + editor.on('focusin', function() { + var focusedEditor = editorManager.focusedEditor, lastRng; + + if (editor.selection.lastFocusBookmark) { + lastRng = bookmarkToRng(editor, editor.selection.lastFocusBookmark); + editor.selection.lastFocusBookmark = null; + editor.selection.setRng(lastRng); + } + + if (focusedEditor != editor) { + if (focusedEditor) { + focusedEditor.fire('blur', {focusedEditor: editor}); + } + + editorManager.setActive(editor); + editorManager.focusedEditor = editor; + editor.fire('focus', {blurredEditor: focusedEditor}); + editor.focus(true); + } + + editor.lastRng = null; + }); + + editor.on('focusout', function() { + Delay.setEditorTimeout(editor, function() { + var focusedEditor = editorManager.focusedEditor; + + // Still the same editor the blur was outside any editor UI + if (!isUIElement(getActiveElement()) && focusedEditor == editor) { + editor.fire('blur', {focusedEditor: null}); + editorManager.focusedEditor = null; + + // Make sure selection is valid could be invalid if the editor is blured and removed before the timeout occurs + if (editor.selection) { + editor.selection.lastFocusBookmark = null; + } + } + }); + }); + + // Check if focus is moved to an element outside the active editor by checking if the target node + // isn't within the body of the activeEditor nor a UI element such as a dialog child control + if (!documentFocusInHandler) { + documentFocusInHandler = function(e) { + var activeEditor = editorManager.activeEditor, target; + + target = e.target; + + if (activeEditor && target.ownerDocument == document) { + // Check to make sure we have a valid selection don't update the bookmark if it's + // a focusin to the body of the editor see #7025 + if (activeEditor.selection && target != activeEditor.getBody()) { + activeEditor.selection.lastFocusBookmark = createBookmark(activeEditor.dom, activeEditor.lastRng); + } + + // Fire a blur event if the element isn't a UI element + if (target != document.body && !isUIElement(target) && editorManager.focusedEditor == activeEditor) { + activeEditor.fire('blur', {focusedEditor: null}); + editorManager.focusedEditor = null; + } + } + }; + + DOM.bind(document, 'focusin', documentFocusInHandler); + } + + // Handle edge case when user starts the selection inside the editor and releases + // the mouse outside the editor producing a new selection. This weird workaround is needed since + // Gecko doesn't have the "selectionchange" event we need to do this. Fixes: #6843 + if (editor.inline && !documentMouseUpHandler) { + documentMouseUpHandler = function(e) { + var activeEditor = editorManager.activeEditor; + + if (activeEditor.inline && !activeEditor.dom.isChildOf(e.target, activeEditor.getBody())) { + var rng = activeEditor.selection.getRng(); + + if (!rng.collapsed) { + activeEditor.lastRng = rng; + } + } + }; + + DOM.bind(document, 'mouseup', documentMouseUpHandler); + } + } + + function unregisterDocumentEvents(e) { + if (editorManager.focusedEditor == e.editor) { + editorManager.focusedEditor = null; + } + + if (!editorManager.activeEditor) { + DOM.unbind(document, 'selectionchange', selectionChangeHandler); + DOM.unbind(document, 'focusin', documentFocusInHandler); + DOM.unbind(document, 'mouseup', documentMouseUpHandler); + selectionChangeHandler = documentFocusInHandler = documentMouseUpHandler = null; + } + } + + editorManager.on('AddEditor', registerEvents); + editorManager.on('RemoveEditor', unregisterDocumentEvents); + } + + /** + * Returns true if the specified element is part of the UI for example an button or text input. + * + * @method isEditorUIElement + * @param {Element} elm Element to check if it's part of the UI or not. + * @return {Boolean} True/false state if the element is part of the UI or not. + */ + FocusManager.isEditorUIElement = function(elm) { + // Needs to be converted to string since svg can have focus: #6776 + return elm.className.toString().indexOf('mce-') !== -1; + }; + + return FocusManager; +}); + +// Included from: js/tinymce/classes/EditorManager.js + +/** + * EditorManager.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class used as a factory for manager for tinymce.Editor instances. + * + * @example + * tinymce.EditorManager.init({}); + * + * @class tinymce.EditorManager + * @mixes tinymce.util.Observable + * @static + */ +define("tinymce/EditorManager", [ + "tinymce/Editor", + "tinymce/dom/DomQuery", + "tinymce/dom/DOMUtils", + "tinymce/util/URI", + "tinymce/Env", + "tinymce/util/Tools", + "tinymce/util/Promise", + "tinymce/util/Observable", + "tinymce/util/I18n", + "tinymce/FocusManager" +], function(Editor, $, DOMUtils, URI, Env, Tools, Promise, Observable, I18n, FocusManager) { + var DOM = DOMUtils.DOM; + var explode = Tools.explode, each = Tools.each, extend = Tools.extend; + var instanceCounter = 0, beforeUnloadDelegate, EditorManager, boundGlobalEvents = false; + + function globalEventDelegate(e) { + each(EditorManager.editors, function(editor) { + if (e.type === 'scroll') { + editor.fire('ScrollWindow', e); + } else { + editor.fire('ResizeWindow', e); + } + }); + } + + function toggleGlobalEvents(editors, state) { + if (state !== boundGlobalEvents) { + if (state) { + $(window).on('resize scroll', globalEventDelegate); + } else { + $(window).off('resize scroll', globalEventDelegate); + } + + boundGlobalEvents = state; + } + } + + function removeEditorFromList(editor) { + var editors = EditorManager.editors, removedFromList; + + delete editors[editor.id]; + + for (var i = 0; i < editors.length; i++) { + if (editors[i] == editor) { + editors.splice(i, 1); + removedFromList = true; + break; + } + } + + // Select another editor since the active one was removed + if (EditorManager.activeEditor == editor) { + EditorManager.activeEditor = editors[0]; + } + + // Clear focusedEditor if necessary, so that we don't try to blur the destroyed editor + if (EditorManager.focusedEditor == editor) { + EditorManager.focusedEditor = null; + } + + return removedFromList; + } + + function purgeDestroyedEditor(editor) { + // User has manually destroyed the editor lets clean up the mess + if (editor && editor.initialized && !(editor.getContainer() || editor.getBody()).parentNode) { + removeEditorFromList(editor); + editor.unbindAllNativeEvents(); + editor.destroy(true); + editor.removed = true; + editor = null; + } + + return editor; + } + + EditorManager = { + /** + * Dom query instance. + * + * @property $ + * @type tinymce.dom.DomQuery + */ + $: $, + + /** + * Major version of TinyMCE build. + * + * @property majorVersion + * @type String + */ + majorVersion: '4', + + /** + * Minor version of TinyMCE build. + * + * @property minorVersion + * @type String + */ + minorVersion: '3.13', + + /** + * Release date of TinyMCE build. + * + * @property releaseDate + * @type String + */ + releaseDate: '2016-06-08', + + /** + * Collection of editor instances. + * + * @property editors + * @type Object + * @example + * for (edId in tinymce.editors) + * tinymce.editors[edId].save(); + */ + editors: [], + + /** + * Collection of language pack data. + * + * @property i18n + * @type Object + */ + i18n: I18n, + + /** + * Currently active editor instance. + * + * @property activeEditor + * @type tinymce.Editor + * @example + * tinyMCE.activeEditor.selection.getContent(); + * tinymce.EditorManager.activeEditor.selection.getContent(); + */ + activeEditor: null, + + setup: function() { + var self = this, baseURL, documentBaseURL, suffix = "", preInit, src; + + // Get base URL for the current document + documentBaseURL = URI.getDocumentBaseUrl(document.location); + + // Check if the URL is a document based format like: http://site/dir/file and file:/// + // leave other formats like applewebdata://... intact + if (/^[^:]+:\/\/\/?[^\/]+\//.test(documentBaseURL)) { + documentBaseURL = documentBaseURL.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, ''); + + if (!/[\/\\]$/.test(documentBaseURL)) { + documentBaseURL += '/'; + } + } + + // If tinymce is defined and has a base use that or use the old tinyMCEPreInit + preInit = window.tinymce || window.tinyMCEPreInit; + if (preInit) { + baseURL = preInit.base || preInit.baseURL; + suffix = preInit.suffix; + } else { + // Get base where the tinymce script is located + var scripts = document.getElementsByTagName('script'); + for (var i = 0; i < scripts.length; i++) { + src = scripts[i].src; + + // Script types supported: + // tinymce.js tinymce.min.js tinymce.dev.js + // tinymce.jquery.js tinymce.jquery.min.js tinymce.jquery.dev.js + // tinymce.full.js tinymce.full.min.js tinymce.full.dev.js + var srcScript = src.substring(src.lastIndexOf('/')); + if (/tinymce(\.full|\.jquery|)(\.min|\.dev|)\.js/.test(src)) { + if (srcScript.indexOf('.min') != -1) { + suffix = '.min'; + } + + baseURL = src.substring(0, src.lastIndexOf('/')); + break; + } + } + + // We didn't find any baseURL by looking at the script elements + // Try to use the document.currentScript as a fallback + if (!baseURL && document.currentScript) { + src = document.currentScript.src; + + if (src.indexOf('.min') != -1) { + suffix = '.min'; + } + + baseURL = src.substring(0, src.lastIndexOf('/')); + } + } + + /** + * Base URL where the root directory if TinyMCE is located. + * + * @property baseURL + * @type String + */ + self.baseURL = new URI(documentBaseURL).toAbsolute(baseURL); + + /** + * Document base URL where the current document is located. + * + * @property documentBaseURL + * @type String + */ + self.documentBaseURL = documentBaseURL; + + /** + * Absolute baseURI for the installation path of TinyMCE. + * + * @property baseURI + * @type tinymce.util.URI + */ + self.baseURI = new URI(self.baseURL); + + /** + * Current suffix to add to each plugin/theme that gets loaded for example ".min". + * + * @property suffix + * @type String + */ + self.suffix = suffix; + + self.focusManager = new FocusManager(self); + }, + + /** + * Overrides the default settings for editor instances. + * + * @method overrideDefaults + * @param {Object} defaultSettings Defaults settings object. + */ + overrideDefaults: function(defaultSettings) { + var baseUrl, suffix; + + baseUrl = defaultSettings.base_url; + if (baseUrl) { + this.baseURL = new URI(this.documentBaseURL).toAbsolute(baseUrl.replace(/\/+$/, '')); + this.baseURI = new URI(this.baseURL); + } + + suffix = defaultSettings.suffix; + if (defaultSettings.suffix) { + this.suffix = suffix; + } + + this.defaultSettings = defaultSettings; + }, + + /** + * Initializes a set of editors. This method will create editors based on various settings. + * + * @method init + * @param {Object} settings Settings object to be passed to each editor instance. + * @return {tinymce.util.Promise} Promise that gets resolved with an array of editors when all editor instances are initialized. + * @example + * // Initializes a editor using the longer method + * tinymce.EditorManager.init({ + * some_settings : 'some value' + * }); + * + * // Initializes a editor instance using the shorter version and with a promise + * tinymce.init({ + * some_settings : 'some value' + * }).then(function(editors) { + * ... + * }); + */ + init: function(settings) { + var self = this, result; + + function createId(elm) { + var id = elm.id; + + // Use element id, or unique name or generate a unique id + if (!id) { + id = elm.name; + + if (id && !DOM.get(id)) { + id = elm.name; + } else { + // Generate unique name + id = DOM.uniqueId(); + } + + elm.setAttribute('id', id); + } + + return id; + } + + function execCallback(name) { + var callback = settings[name]; + + if (!callback) { + return; + } + + return callback.apply(self, Array.prototype.slice.call(arguments, 2)); + } + + function hasClass(elm, className) { + return className.constructor === RegExp ? className.test(elm.className) : DOM.hasClass(elm, className); + } + + function findTargets(settings) { + var l, targets = []; + + if (settings.types) { + each(settings.types, function(type) { + targets = targets.concat(DOM.select(type.selector)); + }); + + return targets; + } else if (settings.selector) { + return DOM.select(settings.selector); + } else if (settings.target) { + return [settings.target]; + } + + // Fallback to old setting + switch (settings.mode) { + case "exact": + l = settings.elements || ''; + + if (l.length > 0) { + each(explode(l), function(id) { + var elm; + + if ((elm = DOM.get(id))) { + targets.push(elm); + } else { + each(document.forms, function(f) { + each(f.elements, function(e) { + if (e.name === id) { + id = 'mce_editor_' + instanceCounter++; + DOM.setAttrib(e, 'id', id); + targets.push(e); + } + }); + }); + } + }); + } + break; + + case "textareas": + case "specific_textareas": + each(DOM.select('textarea'), function(elm) { + if (settings.editor_deselector && hasClass(elm, settings.editor_deselector)) { + return; + } + + if (!settings.editor_selector || hasClass(elm, settings.editor_selector)) { + targets.push(elm); + } + }); + break; + } + + return targets; + } + + var provideResults = function(editors) { + result = editors; + }; + + function initEditors() { + var initCount = 0, editors = [], targets; + + function createEditor(id, settings, targetElm) { + var editor = new Editor(id, settings, self); + + editors.push(editor); + + editor.on('init', function() { + if (++initCount === targets.length) { + provideResults(editors); + } + }); + + editor.targetElm = editor.targetElm || targetElm; + editor.render(); + } + + DOM.unbind(window, 'ready', initEditors); + execCallback('onpageload'); + + targets = $.unique(findTargets(settings)); + + // TODO: Deprecate this one + if (settings.types) { + each(settings.types, function(type) { + Tools.each(targets, function(elm) { + if (DOM.is(elm, type.selector)) { + createEditor(createId(elm), extend({}, settings, type), elm); + return false; + } + + return true; + }); + }); + + return; + } + + Tools.each(targets, function(elm) { + purgeDestroyedEditor(self.get(elm.id)); + }); + + targets = Tools.grep(targets, function(elm) { + return !self.get(elm.id); + }); + + each(targets, function(elm) { + createEditor(createId(elm), settings, elm); + }); + } + + self.settings = settings; + DOM.bind(window, 'ready', initEditors); + + return new Promise(function(resolve) { + if (result) { + resolve(result); + } else { + provideResults = function(editors) { + resolve(editors); + }; + } + }); + }, + + /** + * Returns a editor instance by id. + * + * @method get + * @param {String/Number} id Editor instance id or index to return. + * @return {tinymce.Editor} Editor instance to return. + * @example + * // Adds an onclick event to an editor by id (shorter version) + * tinymce.get('mytextbox').on('click', function(e) { + * ed.windowManager.alert('Hello world!'); + * }); + * + * // Adds an onclick event to an editor by id (longer version) + * tinymce.EditorManager.get('mytextbox').on('click', function(e) { + * ed.windowManager.alert('Hello world!'); + * }); + */ + get: function(id) { + if (!arguments.length) { + return this.editors; + } + + return id in this.editors ? this.editors[id] : null; + }, + + /** + * Adds an editor instance to the editor collection. This will also set it as the active editor. + * + * @method add + * @param {tinymce.Editor} editor Editor instance to add to the collection. + * @return {tinymce.Editor} The same instance that got passed in. + */ + add: function(editor) { + var self = this, editors = self.editors; + + // Add named and index editor instance + editors[editor.id] = editor; + editors.push(editor); + + toggleGlobalEvents(editors, true); + + // Doesn't call setActive method since we don't want + // to fire a bunch of activate/deactivate calls while initializing + self.activeEditor = editor; + + /** + * Fires when an editor is added to the EditorManager collection. + * + * @event AddEditor + * @param {Object} e Event arguments. + */ + self.fire('AddEditor', {editor: editor}); + + if (!beforeUnloadDelegate) { + beforeUnloadDelegate = function() { + self.fire('BeforeUnload'); + }; + + DOM.bind(window, 'beforeunload', beforeUnloadDelegate); + } + + return editor; + }, + + /** + * Creates an editor instance and adds it to the EditorManager collection. + * + * @method createEditor + * @param {String} id Instance id to use for editor. + * @param {Object} settings Editor instance settings. + * @return {tinymce.Editor} Editor instance that got created. + */ + createEditor: function(id, settings) { + return this.add(new Editor(id, settings, this)); + }, + + /** + * Removes a editor or editors form page. + * + * @example + * // Remove all editors bound to divs + * tinymce.remove('div'); + * + * // Remove all editors bound to textareas + * tinymce.remove('textarea'); + * + * // Remove all editors + * tinymce.remove(); + * + * // Remove specific instance by id + * tinymce.remove('#id'); + * + * @method remove + * @param {tinymce.Editor/String/Object} [selector] CSS selector or editor instance to remove. + * @return {tinymce.Editor} The editor that got passed in will be return if it was found otherwise null. + */ + remove: function(selector) { + var self = this, i, editors = self.editors, editor; + + // Remove all editors + if (!selector) { + for (i = editors.length - 1; i >= 0; i--) { + self.remove(editors[i]); + } + + return; + } + + // Remove editors by selector + if (typeof selector == "string") { + selector = selector.selector || selector; + + each(DOM.select(selector), function(elm) { + editor = editors[elm.id]; + + if (editor) { + self.remove(editor); + } + }); + + return; + } + + // Remove specific editor + editor = selector; + + // Not in the collection + if (!editors[editor.id]) { + return null; + } + + /** + * Fires when an editor is removed from EditorManager collection. + * + * @event RemoveEditor + * @param {Object} e Event arguments. + */ + if (removeEditorFromList(editor)) { + self.fire('RemoveEditor', {editor: editor}); + } + + if (!editors.length) { + DOM.unbind(window, 'beforeunload', beforeUnloadDelegate); + } + + editor.remove(); + + toggleGlobalEvents(editors, editors.length > 0); + + return editor; + }, + + /** + * Executes a specific command on the currently active editor. + * + * @method execCommand + * @param {String} cmd Command to perform for example Bold. + * @param {Boolean} ui Optional boolean state if a UI should be presented for the command or not. + * @param {String} value Optional value parameter like for example an URL to a link. + * @return {Boolean} true/false if the command was executed or not. + */ + execCommand: function(cmd, ui, value) { + var self = this, editor = self.get(value); + + // Manager commands + switch (cmd) { + case "mceAddEditor": + if (!self.get(value)) { + new Editor(value, self.settings, self).render(); + } + + return true; + + case "mceRemoveEditor": + if (editor) { + editor.remove(); + } + + return true; + + case 'mceToggleEditor': + if (!editor) { + self.execCommand('mceAddEditor', 0, value); + return true; + } + + if (editor.isHidden()) { + editor.show(); + } else { + editor.hide(); + } + + return true; + } + + // Run command on active editor + if (self.activeEditor) { + return self.activeEditor.execCommand(cmd, ui, value); + } + + return false; + }, + + /** + * Calls the save method on all editor instances in the collection. This can be useful when a form is to be submitted. + * + * @method triggerSave + * @example + * // Saves all contents + * tinyMCE.triggerSave(); + */ + triggerSave: function() { + each(this.editors, function(editor) { + editor.save(); + }); + }, + + /** + * Adds a language pack, this gets called by the loaded language files like en.js. + * + * @method addI18n + * @param {String} code Optional language code. + * @param {Object} items Name/value object with translations. + */ + addI18n: function(code, items) { + I18n.add(code, items); + }, + + /** + * Translates the specified string using the language pack items. + * + * @method translate + * @param {String/Array/Object} text String to translate + * @return {String} Translated string. + */ + translate: function(text) { + return I18n.translate(text); + }, + + /** + * Sets the active editor instance and fires the deactivate/activate events. + * + * @method setActive + * @param {tinymce.Editor} editor Editor instance to set as the active instance. + */ + setActive: function(editor) { + var activeEditor = this.activeEditor; + + if (this.activeEditor != editor) { + if (activeEditor) { + activeEditor.fire('deactivate', {relatedTarget: editor}); + } + + editor.fire('activate', {relatedTarget: activeEditor}); + } + + this.activeEditor = editor; + } + }; + + extend(EditorManager, Observable); + + EditorManager.setup(); + + // Export EditorManager as tinymce/tinymce in global namespace + window.tinymce = window.tinyMCE = EditorManager; + + return EditorManager; +}); + +// Included from: js/tinymce/classes/LegacyInput.js + +/** + * LegacyInput.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Converts legacy input to modern HTML. + * + * @class tinymce.LegacyInput + * @private + */ +define("tinymce/LegacyInput", [ + "tinymce/EditorManager", + "tinymce/util/Tools" +], function(EditorManager, Tools) { + var each = Tools.each, explode = Tools.explode; + + EditorManager.on('AddEditor', function(e) { + var editor = e.editor; + + editor.on('preInit', function() { + var filters, fontSizes, dom, settings = editor.settings; + + function replaceWithSpan(node, styles) { + each(styles, function(value, name) { + if (value) { + dom.setStyle(node, name, value); + } + }); + + dom.rename(node, 'span'); + } + + function convert(e) { + dom = editor.dom; + + if (settings.convert_fonts_to_spans) { + each(dom.select('font,u,strike', e.node), function(node) { + filters[node.nodeName.toLowerCase()](dom, node); + }); + } + } + + if (settings.inline_styles) { + fontSizes = explode(settings.font_size_legacy_values); + + filters = { + font: function(dom, node) { + replaceWithSpan(node, { + backgroundColor: node.style.backgroundColor, + color: node.color, + fontFamily: node.face, + fontSize: fontSizes[parseInt(node.size, 10) - 1] + }); + }, + + u: function(dom, node) { + // HTML5 allows U element + if (editor.settings.schema === "html4") { + replaceWithSpan(node, { + textDecoration: 'underline' + }); + } + }, + + strike: function(dom, node) { + replaceWithSpan(node, { + textDecoration: 'line-through' + }); + } + }; + + editor.on('PreProcess SetContent', convert); + } + }); + }); +}); + +// Included from: js/tinymce/classes/util/XHR.js + +/** + * XHR.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class enables you to send XMLHTTPRequests cross browser. + * @class tinymce.util.XHR + * @mixes tinymce.util.Observable + * @static + * @example + * // Sends a low level Ajax request + * tinymce.util.XHR.send({ + * url: 'someurl', + * success: function(text) { + * console.debug(text); + * } + * }); + * + * // Add custom header to XHR request + * tinymce.util.XHR.on('beforeSend', function(e) { + * e.xhr.setRequestHeader('X-Requested-With', 'Something'); + * }); + */ +define("tinymce/util/XHR", [ + "tinymce/util/Observable", + "tinymce/util/Tools" +], function(Observable, Tools) { + var XHR = { + /** + * Sends a XMLHTTPRequest. + * Consult the Wiki for details on what settings this method takes. + * + * @method send + * @param {Object} settings Object will target URL, callbacks and other info needed to make the request. + */ + send: function(settings) { + var xhr, count = 0; + + function ready() { + if (!settings.async || xhr.readyState == 4 || count++ > 10000) { + if (settings.success && count < 10000 && xhr.status == 200) { + settings.success.call(settings.success_scope, '' + xhr.responseText, xhr, settings); + } else if (settings.error) { + settings.error.call(settings.error_scope, count > 10000 ? 'TIMED_OUT' : 'GENERAL', xhr, settings); + } + + xhr = null; + } else { + setTimeout(ready, 10); + } + } + + // Default settings + settings.scope = settings.scope || this; + settings.success_scope = settings.success_scope || settings.scope; + settings.error_scope = settings.error_scope || settings.scope; + settings.async = settings.async === false ? false : true; + settings.data = settings.data || ''; + + XHR.fire('beforeInitialize', {settings: settings}); + + xhr = new XMLHttpRequest(); + + if (xhr) { + if (xhr.overrideMimeType) { + xhr.overrideMimeType(settings.content_type); + } + + xhr.open(settings.type || (settings.data ? 'POST' : 'GET'), settings.url, settings.async); + + if (settings.crossDomain) { + xhr.withCredentials = true; + } + + if (settings.content_type) { + xhr.setRequestHeader('Content-Type', settings.content_type); + } + + if (settings.requestheaders) { + Tools.each(settings.requestheaders, function(header) { + xhr.setRequestHeader(header.key, header.value); + }); + } + + xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); + + xhr = XHR.fire('beforeSend', {xhr: xhr, settings: settings}).xhr; + xhr.send(settings.data); + + // Syncronous request + if (!settings.async) { + return ready(); + } + + // Wait for response, onReadyStateChange can not be used since it leaks memory in IE + setTimeout(ready, 10); + } + } + }; + + Tools.extend(XHR, Observable); + + return XHR; +}); + +// Included from: js/tinymce/classes/util/JSON.js + +/** + * JSON.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * JSON parser and serializer class. + * + * @class tinymce.util.JSON + * @static + * @example + * // JSON parse a string into an object + * var obj = tinymce.util.JSON.parse(somestring); + * + * // JSON serialize a object into an string + * var str = tinymce.util.JSON.serialize(obj); + */ +define("tinymce/util/JSON", [], function() { + function serialize(o, quote) { + var i, v, t, name; + + quote = quote || '"'; + + if (o === null) { + return 'null'; + } + + t = typeof o; + + if (t == 'string') { + v = '\bb\tt\nn\ff\rr\""\'\'\\\\'; + + /*eslint no-control-regex:0 */ + return quote + o.replace(/([\u0080-\uFFFF\x00-\x1f\"\'\\])/g, function(a, b) { + // Make sure single quotes never get encoded inside double quotes for JSON compatibility + if (quote === '"' && a === "'") { + return a; + } + + i = v.indexOf(b); + + if (i + 1) { + return '\\' + v.charAt(i + 1); + } + + a = b.charCodeAt().toString(16); + + return '\\u' + '0000'.substring(a.length) + a; + }) + quote; + } + + if (t == 'object') { + if (o.hasOwnProperty && Object.prototype.toString.call(o) === '[object Array]') { + for (i = 0, v = '['; i < o.length; i++) { + v += (i > 0 ? ',' : '') + serialize(o[i], quote); + } + + return v + ']'; + } + + v = '{'; + + for (name in o) { + if (o.hasOwnProperty(name)) { + v += typeof o[name] != 'function' ? (v.length > 1 ? ',' + quote : quote) + name + + quote + ':' + serialize(o[name], quote) : ''; + } + } + + return v + '}'; + } + + return '' + o; + } + + return { + /** + * Serializes the specified object as a JSON string. + * + * @method serialize + * @param {Object} obj Object to serialize as a JSON string. + * @param {String} quote Optional quote string defaults to ". + * @return {string} JSON string serialized from input. + */ + serialize: serialize, + + /** + * Unserializes/parses the specified JSON string into a object. + * + * @method parse + * @param {string} s JSON String to parse into a JavaScript object. + * @return {Object} Object from input JSON string or undefined if it failed. + */ + parse: function(text) { + try { + // Trick uglify JS + return window[String.fromCharCode(101) + 'val']('(' + text + ')'); + } catch (ex) { + // Ignore + } + } + + /**#@-*/ + }; +}); + +// Included from: js/tinymce/classes/util/JSONRequest.js + +/** + * JSONRequest.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class enables you to use JSON-RPC to call backend methods. + * + * @class tinymce.util.JSONRequest + * @example + * var json = new tinymce.util.JSONRequest({ + * url: 'somebackend.php' + * }); + * + * // Send RPC call 1 + * json.send({ + * method: 'someMethod1', + * params: ['a', 'b'], + * success: function(result) { + * console.dir(result); + * } + * }); + * + * // Send RPC call 2 + * json.send({ + * method: 'someMethod2', + * params: ['a', 'b'], + * success: function(result) { + * console.dir(result); + * } + * }); + */ +define("tinymce/util/JSONRequest", [ + "tinymce/util/JSON", + "tinymce/util/XHR", + "tinymce/util/Tools" +], function(JSON, XHR, Tools) { + var extend = Tools.extend; + + function JSONRequest(settings) { + this.settings = extend({}, settings); + this.count = 0; + } + + /** + * Simple helper function to send a JSON-RPC request without the need to initialize an object. + * Consult the Wiki API documentation for more details on what you can pass to this function. + * + * @method sendRPC + * @static + * @param {Object} o Call object where there are three field id, method and params this object should also contain callbacks etc. + */ + JSONRequest.sendRPC = function(o) { + return new JSONRequest().send(o); + }; + + JSONRequest.prototype = { + /** + * Sends a JSON-RPC call. Consult the Wiki API documentation for more details on what you can pass to this function. + * + * @method send + * @param {Object} args Call object where there are three field id, method and params this object should also contain callbacks etc. + */ + send: function(args) { + var ecb = args.error, scb = args.success; + + args = extend(this.settings, args); + + args.success = function(c, x) { + c = JSON.parse(c); + + if (typeof c == 'undefined') { + c = { + error: 'JSON Parse error.' + }; + } + + if (c.error) { + ecb.call(args.error_scope || args.scope, c.error, x); + } else { + scb.call(args.success_scope || args.scope, c.result); + } + }; + + args.error = function(ty, x) { + if (ecb) { + ecb.call(args.error_scope || args.scope, ty, x); + } + }; + + args.data = JSON.serialize({ + id: args.id || 'c' + (this.count++), + method: args.method, + params: args.params + }); + + // JSON content type for Ruby on rails. Bug: #1883287 + args.content_type = 'application/json'; + + XHR.send(args); + } + }; + + return JSONRequest; +}); + +// Included from: js/tinymce/classes/util/JSONP.js + +/** + * JSONP.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +define("tinymce/util/JSONP", [ + "tinymce/dom/DOMUtils" +], function(DOMUtils) { + return { + callbacks: {}, + count: 0, + + send: function(settings) { + var self = this, dom = DOMUtils.DOM, count = settings.count !== undefined ? settings.count : self.count; + var id = 'tinymce_jsonp_' + count; + + self.callbacks[count] = function(json) { + dom.remove(id); + delete self.callbacks[count]; + + settings.callback(json); + }; + + dom.add(dom.doc.body, 'script', { + id: id, + src: settings.url, + type: 'text/javascript' + }); + + self.count++; + } + }; +}); + +// Included from: js/tinymce/classes/util/LocalStorage.js + +/** + * LocalStorage.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class will simulate LocalStorage on IE 7 and return the native version on modern browsers. + * Storage is done using userData on IE 7 and a special serialization format. The format is designed + * to be as small as possible by making sure that the keys and values doesn't need to be encoded. This + * makes it possible to store for example HTML data. + * + * Storage format for userData: + * <base 32 key length>,<key string>,<base 32 value length>,<value>,... + * + * For example this data key1=value1,key2=value2 would be: + * 4,key1,6,value1,4,key2,6,value2 + * + * @class tinymce.util.LocalStorage + * @static + * @version 4.0 + * @example + * tinymce.util.LocalStorage.setItem('key', 'value'); + * var value = tinymce.util.LocalStorage.getItem('key'); + */ +define("tinymce/util/LocalStorage", [], function() { + var LocalStorage, storageElm, items, keys, userDataKey, hasOldIEDataSupport; + + // Check for native support + try { + if (window.localStorage) { + return localStorage; + } + } catch (ex) { + // Ignore + } + + userDataKey = "tinymce"; + storageElm = document.documentElement; + hasOldIEDataSupport = !!storageElm.addBehavior; + + if (hasOldIEDataSupport) { + storageElm.addBehavior('#default#userData'); + } + + /** + * Gets the keys names and updates LocalStorage.length property. Since IE7 doesn't have any getters/setters. + */ + function updateKeys() { + keys = []; + + for (var key in items) { + keys.push(key); + } + + LocalStorage.length = keys.length; + } + + /** + * Loads the userData string and parses it into the items structure. + */ + function load() { + var key, data, value, pos = 0; + + items = {}; + + // localStorage can be disabled on WebKit/Gecko so make a dummy storage + if (!hasOldIEDataSupport) { + return; + } + + function next(end) { + var value, nextPos; + + nextPos = end !== undefined ? pos + end : data.indexOf(',', pos); + if (nextPos === -1 || nextPos > data.length) { + return null; + } + + value = data.substring(pos, nextPos); + pos = nextPos + 1; + + return value; + } + + storageElm.load(userDataKey); + data = storageElm.getAttribute(userDataKey) || ''; + + do { + var offset = next(); + if (offset === null) { + break; + } + + key = next(parseInt(offset, 32) || 0); + if (key !== null) { + offset = next(); + if (offset === null) { + break; + } + + value = next(parseInt(offset, 32) || 0); + + if (key) { + items[key] = value; + } + } + } while (key !== null); + + updateKeys(); + } + + /** + * Saves the items structure into a the userData format. + */ + function save() { + var value, data = ''; + + // localStorage can be disabled on WebKit/Gecko so make a dummy storage + if (!hasOldIEDataSupport) { + return; + } + + for (var key in items) { + value = items[key]; + data += (data ? ',' : '') + key.length.toString(32) + ',' + key + ',' + value.length.toString(32) + ',' + value; + } + + storageElm.setAttribute(userDataKey, data); + + try { + storageElm.save(userDataKey); + } catch (ex) { + // Ignore disk full + } + + updateKeys(); + } + + LocalStorage = { + /** + * Length of the number of items in storage. + * + * @property length + * @type Number + * @return {Number} Number of items in storage. + */ + //length:0, + + /** + * Returns the key name by index. + * + * @method key + * @param {Number} index Index of key to return. + * @return {String} Key value or null if it wasn't found. + */ + key: function(index) { + return keys[index]; + }, + + /** + * Returns the value if the specified key or null if it wasn't found. + * + * @method getItem + * @param {String} key Key of item to retrieve. + * @return {String} Value of the specified item or null if it wasn't found. + */ + getItem: function(key) { + return key in items ? items[key] : null; + }, + + /** + * Sets the value of the specified item by it's key. + * + * @method setItem + * @param {String} key Key of the item to set. + * @param {String} value Value of the item to set. + */ + setItem: function(key, value) { + items[key] = "" + value; + save(); + }, + + /** + * Removes the specified item by key. + * + * @method removeItem + * @param {String} key Key of item to remove. + */ + removeItem: function(key) { + delete items[key]; + save(); + }, + + /** + * Removes all items. + * + * @method clear + */ + clear: function() { + items = {}; + save(); + } + }; + + load(); + + return LocalStorage; +}); + +// Included from: js/tinymce/classes/Compat.js + +/** + * Compat.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * TinyMCE core class. + * + * @static + * @class tinymce + * @borrow-members tinymce.EditorManager + * @borrow-members tinymce.util.Tools + */ +define("tinymce/Compat", [ + "tinymce/dom/DOMUtils", + "tinymce/dom/EventUtils", + "tinymce/dom/ScriptLoader", + "tinymce/AddOnManager", + "tinymce/util/Tools", + "tinymce/Env" +], function(DOMUtils, EventUtils, ScriptLoader, AddOnManager, Tools, Env) { + var tinymce = window.tinymce; + + /** + * @property {tinymce.dom.DOMUtils} DOM Global DOM instance. + * @property {tinymce.dom.ScriptLoader} ScriptLoader Global ScriptLoader instance. + * @property {tinymce.AddOnManager} PluginManager Global PluginManager instance. + * @property {tinymce.AddOnManager} ThemeManager Global ThemeManager instance. + */ + tinymce.DOM = DOMUtils.DOM; + tinymce.ScriptLoader = ScriptLoader.ScriptLoader; + tinymce.PluginManager = AddOnManager.PluginManager; + tinymce.ThemeManager = AddOnManager.ThemeManager; + + tinymce.dom = tinymce.dom || {}; + tinymce.dom.Event = EventUtils.Event; + + Tools.each(Tools, function(func, key) { + tinymce[key] = func; + }); + + Tools.each('isOpera isWebKit isIE isGecko isMac'.split(' '), function(name) { + tinymce[name] = Env[name.substr(2).toLowerCase()]; + }); + + return {}; +}); + +// Describe the different namespaces + +/** + * Root level namespace this contains classes directly related to the TinyMCE editor. + * + * @namespace tinymce + */ + +/** + * Contains classes for handling the browsers DOM. + * + * @namespace tinymce.dom + */ + +/** + * Contains html parser and serializer logic. + * + * @namespace tinymce.html + */ + +/** + * Contains the different UI types such as buttons, listboxes etc. + * + * @namespace tinymce.ui + */ + +/** + * Contains various utility classes such as json parser, cookies etc. + * + * @namespace tinymce.util + */ + +/** + * Contains modules to handle data binding. + * + * @namespace tinymce.data + */ + +// Included from: js/tinymce/classes/ui/Layout.js + +/** + * Layout.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Base layout manager class. + * + * @class tinymce.ui.Layout + */ +define("tinymce/ui/Layout", [ + "tinymce/util/Class", + "tinymce/util/Tools" +], function(Class, Tools) { + "use strict"; + + return Class.extend({ + Defaults: { + firstControlClass: 'first', + lastControlClass: 'last' + }, + + /** + * Constructs a layout instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + */ + init: function(settings) { + this.settings = Tools.extend({}, this.Defaults, settings); + }, + + /** + * This method gets invoked before the layout renders the controls. + * + * @method preRender + * @param {tinymce.ui.Container} container Container instance to preRender. + */ + preRender: function(container) { + container.bodyClasses.add(this.settings.containerClass); + }, + + /** + * Applies layout classes to the container. + * + * @private + */ + applyClasses: function(items) { + var self = this, settings = self.settings, firstClass, lastClass, firstItem, lastItem; + + firstClass = settings.firstControlClass; + lastClass = settings.lastControlClass; + + items.each(function(item) { + item.classes.remove(firstClass).remove(lastClass).add(settings.controlClass); + + if (item.visible()) { + if (!firstItem) { + firstItem = item; + } + + lastItem = item; + } + }); + + if (firstItem) { + firstItem.classes.add(firstClass); + } + + if (lastItem) { + lastItem.classes.add(lastClass); + } + }, + + /** + * Renders the specified container and any layout specific HTML. + * + * @method renderHtml + * @param {tinymce.ui.Container} container Container to render HTML for. + */ + renderHtml: function(container) { + var self = this, html = ''; + + self.applyClasses(container.items()); + + container.items().each(function(item) { + html += item.renderHtml(); + }); + + return html; + }, + + /** + * Recalculates the positions of the controls in the specified container. + * + * @method recalc + * @param {tinymce.ui.Container} container Container instance to recalc. + */ + recalc: function() { + }, + + /** + * This method gets invoked after the layout renders the controls. + * + * @method postRender + * @param {tinymce.ui.Container} container Container instance to postRender. + */ + postRender: function() { + }, + + isNative: function() { + return false; + } + }); +}); + +// Included from: js/tinymce/classes/ui/AbsoluteLayout.js + +/** + * AbsoluteLayout.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * LayoutManager for absolute positioning. This layout manager is more of + * a base class for other layouts but can be created and used directly. + * + * @-x-less AbsoluteLayout.less + * @class tinymce.ui.AbsoluteLayout + * @extends tinymce.ui.Layout + */ +define("tinymce/ui/AbsoluteLayout", [ + "tinymce/ui/Layout" +], function(Layout) { + "use strict"; + + return Layout.extend({ + Defaults: { + containerClass: 'abs-layout', + controlClass: 'abs-layout-item' + }, + + /** + * Recalculates the positions of the controls in the specified container. + * + * @method recalc + * @param {tinymce.ui.Container} container Container instance to recalc. + */ + recalc: function(container) { + container.items().filter(':visible').each(function(ctrl) { + var settings = ctrl.settings; + + ctrl.layoutRect({ + x: settings.x, + y: settings.y, + w: settings.w, + h: settings.h + }); + + if (ctrl.recalc) { + ctrl.recalc(); + } + }); + }, + + /** + * Renders the specified container and any layout specific HTML. + * + * @method renderHtml + * @param {tinymce.ui.Container} container Container to render HTML for. + */ + renderHtml: function(container) { + return '<div id="' + container._id + '-absend" class="' + container.classPrefix + 'abs-end"></div>' + this._super(container); + } + }); +}); + +// Included from: js/tinymce/classes/ui/Button.js + +/** + * Button.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class is used to create buttons. You can create them directly or through the Factory. + * + * @example + * // Create and render a button to the body element + * tinymce.ui.Factory.create({ + * type: 'button', + * text: 'My button' + * }).renderTo(document.body); + * + * @-x-less Button.less + * @class tinymce.ui.Button + * @extends tinymce.ui.Widget + */ +define("tinymce/ui/Button", [ + "tinymce/ui/Widget" +], function(Widget) { + "use strict"; + + return Widget.extend({ + Defaults: { + classes: "widget btn", + role: "button" + }, + + /** + * Constructs a new button instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + * @setting {String} size Size of the button small|medium|large. + * @setting {String} image Image to use for icon. + * @setting {String} icon Icon to use for button. + */ + init: function(settings) { + var self = this, size; + + self._super(settings); + settings = self.settings; + + size = self.settings.size; + + self.on('click mousedown', function(e) { + e.preventDefault(); + }); + + self.on('touchstart', function(e) { + self.fire('click', e); + e.preventDefault(); + }); + + if (settings.subtype) { + self.classes.add(settings.subtype); + } + + if (size) { + self.classes.add('btn-' + size); + } + + if (settings.icon) { + self.icon(settings.icon); + } + }, + + /** + * Sets/gets the current button icon. + * + * @method icon + * @param {String} [icon] New icon identifier. + * @return {String|tinymce.ui.MenuButton} Current icon or current MenuButton instance. + */ + icon: function(icon) { + if (!arguments.length) { + return this.state.get('icon'); + } + + this.state.set('icon', icon); + + return this; + }, + + /** + * Repaints the button for example after it's been resizes by a layout engine. + * + * @method repaint + */ + repaint: function() { + var btnElm = this.getEl().firstChild, + btnStyle; + + if (btnElm) { + btnStyle = btnElm.style; + btnStyle.width = btnStyle.height = "100%"; + } + + this._super(); + }, + + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this, id = self._id, prefix = self.classPrefix; + var icon = self.state.get('icon'), image, text = self.state.get('text'), textHtml = ''; + + image = self.settings.image; + if (image) { + icon = 'none'; + + // Support for [high dpi, low dpi] image sources + if (typeof image != "string") { + image = window.getSelection ? image[0] : image[1]; + } + + image = ' style="background-image: url(\'' + image + '\')"'; + } else { + image = ''; + } + + if (text) { + self.classes.add('btn-has-text'); + textHtml = '<span class="' + prefix + 'txt">' + self.encode(text) + '</span>'; + } + + icon = self.settings.icon ? prefix + 'ico ' + prefix + 'i-' + icon : ''; + + return ( + '<div id="' + id + '" class="' + self.classes + '" tabindex="-1" aria-labelledby="' + id + '">' + + '<button role="presentation" type="button" tabindex="-1">' + + (icon ? '<i class="' + icon + '"' + image + '></i>' : '') + + textHtml + + '</button>' + + '</div>' + ); + }, + + bindStates: function() { + var self = this, $ = self.$, textCls = self.classPrefix + 'txt'; + + function setButtonText(text) { + var $span = $('span.' + textCls, self.getEl()); + + if (text) { + if (!$span[0]) { + $('button:first', self.getEl()).append('<span class="' + textCls + '"></span>'); + $span = $('span.' + textCls, self.getEl()); + } + + $span.html(self.encode(text)); + } else { + $span.remove(); + } + + self.classes.toggle('btn-has-text', !!text); + } + + self.state.on('change:text', function(e) { + setButtonText(e.value); + }); + + self.state.on('change:icon', function(e) { + var icon = e.value, prefix = self.classPrefix; + + self.settings.icon = icon; + icon = icon ? prefix + 'ico ' + prefix + 'i-' + self.settings.icon : ''; + + var btnElm = self.getEl().firstChild, iconElm = btnElm.getElementsByTagName('i')[0]; + + if (icon) { + if (!iconElm || iconElm != btnElm.firstChild) { + iconElm = document.createElement('i'); + btnElm.insertBefore(iconElm, btnElm.firstChild); + } + + iconElm.className = icon; + } else if (iconElm) { + btnElm.removeChild(iconElm); + } + + setButtonText(self.state.get('text')); + }); + + return self._super(); + } + }); +}); + +// Included from: js/tinymce/classes/ui/ButtonGroup.js + +/** + * ButtonGroup.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This control enables you to put multiple buttons into a group. This is + * useful when you want to combine similar toolbar buttons into a group. + * + * @example + * // Create and render a buttongroup with two buttons to the body element + * tinymce.ui.Factory.create({ + * type: 'buttongroup', + * items: [ + * {text: 'Button A'}, + * {text: 'Button B'} + * ] + * }).renderTo(document.body); + * + * @-x-less ButtonGroup.less + * @class tinymce.ui.ButtonGroup + * @extends tinymce.ui.Container + */ +define("tinymce/ui/ButtonGroup", [ + "tinymce/ui/Container" +], function(Container) { + "use strict"; + + return Container.extend({ + Defaults: { + defaultType: 'button', + role: 'group' + }, + + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this, layout = self._layout; + + self.classes.add('btn-group'); + self.preRender(); + layout.preRender(self); + + return ( + '<div id="' + self._id + '" class="' + self.classes + '">' + + '<div id="' + self._id + '-body">' + + (self.settings.html || '') + layout.renderHtml(self) + + '</div>' + + '</div>' + ); + } + }); +}); + +// Included from: js/tinymce/classes/ui/Checkbox.js + +/** + * Checkbox.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This control creates a custom checkbox. + * + * @example + * // Create and render a checkbox to the body element + * tinymce.ui.Factory.create({ + * type: 'checkbox', + * checked: true, + * text: 'My checkbox' + * }).renderTo(document.body); + * + * @-x-less Checkbox.less + * @class tinymce.ui.Checkbox + * @extends tinymce.ui.Widget + */ +define("tinymce/ui/Checkbox", [ + "tinymce/ui/Widget" +], function(Widget) { + "use strict"; + + return Widget.extend({ + Defaults: { + classes: "checkbox", + role: "checkbox", + checked: false + }, + + /** + * Constructs a new Checkbox instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + * @setting {Boolean} checked True if the checkbox should be checked by default. + */ + init: function(settings) { + var self = this; + + self._super(settings); + + self.on('click mousedown', function(e) { + e.preventDefault(); + }); + + self.on('click', function(e) { + e.preventDefault(); + + if (!self.disabled()) { + self.checked(!self.checked()); + } + }); + + self.checked(self.settings.checked); + }, + + /** + * Getter/setter function for the checked state. + * + * @method checked + * @param {Boolean} [state] State to be set. + * @return {Boolean|tinymce.ui.Checkbox} True/false or checkbox if it's a set operation. + */ + checked: function(state) { + if (!arguments.length) { + return this.state.get('checked'); + } + + this.state.set('checked', state); + + return this; + }, + + /** + * Getter/setter function for the value state. + * + * @method value + * @param {Boolean} [state] State to be set. + * @return {Boolean|tinymce.ui.Checkbox} True/false or checkbox if it's a set operation. + */ + value: function(state) { + if (!arguments.length) { + return this.checked(); + } + + return this.checked(state); + }, + + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this, id = self._id, prefix = self.classPrefix; + + return ( + '<div id="' + id + '" class="' + self.classes + '" unselectable="on" aria-labelledby="' + id + '-al" tabindex="-1">' + + '<i class="' + prefix + 'ico ' + prefix + 'i-checkbox"></i>' + + '<span id="' + id + '-al" class="' + prefix + 'label">' + self.encode(self.state.get('text')) + '</span>' + + '</div>' + ); + }, + + bindStates: function() { + var self = this; + + function checked(state) { + self.classes.toggle("checked", state); + self.aria('checked', state); + } + + self.state.on('change:text', function(e) { + self.getEl('al').firstChild.data = self.translate(e.value); + }); + + self.state.on('change:checked change:value', function(e) { + self.fire('change'); + checked(e.value); + }); + + self.state.on('change:icon', function(e) { + var icon = e.value, prefix = self.classPrefix; + + if (typeof icon == 'undefined') { + return self.settings.icon; + } + + self.settings.icon = icon; + icon = icon ? prefix + 'ico ' + prefix + 'i-' + self.settings.icon : ''; + + var btnElm = self.getEl().firstChild, iconElm = btnElm.getElementsByTagName('i')[0]; + + if (icon) { + if (!iconElm || iconElm != btnElm.firstChild) { + iconElm = document.createElement('i'); + btnElm.insertBefore(iconElm, btnElm.firstChild); + } + + iconElm.className = icon; + } else if (iconElm) { + btnElm.removeChild(iconElm); + } + }); + + if (self.state.get('checked')) { + checked(true); + } + + return self._super(); + } + }); +}); + +// Included from: js/tinymce/classes/ui/ComboBox.js + +/** + * ComboBox.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class creates a combobox control. Select box that you select a value from or + * type a value into. + * + * @-x-less ComboBox.less + * @class tinymce.ui.ComboBox + * @extends tinymce.ui.Widget + */ +define("tinymce/ui/ComboBox", [ + "tinymce/ui/Widget", + "tinymce/ui/Factory", + "tinymce/ui/DomUtils", + "tinymce/dom/DomQuery" +], function(Widget, Factory, DomUtils, $) { + "use strict"; + + return Widget.extend({ + /** + * Constructs a new control instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + * @setting {String} placeholder Placeholder text to display. + */ + init: function(settings) { + var self = this; + + self._super(settings); + settings = self.settings; + + self.classes.add('combobox'); + self.subinput = true; + self.ariaTarget = 'inp'; // TODO: Figure out a better way + + settings.menu = settings.menu || settings.values; + + if (settings.menu) { + settings.icon = 'caret'; + } + + self.on('click', function(e) { + var elm = e.target, root = self.getEl(); + + if (!$.contains(root, elm) && elm != root) { + return; + } + + while (elm && elm != root) { + if (elm.id && elm.id.indexOf('-open') != -1) { + self.fire('action'); + + if (settings.menu) { + self.showMenu(); + + if (e.aria) { + self.menu.items()[0].focus(); + } + } + } + + elm = elm.parentNode; + } + }); + + // TODO: Rework this + self.on('keydown', function(e) { + if (e.target.nodeName == "INPUT" && e.keyCode == 13) { + self.parents().reverse().each(function(ctrl) { + var stateValue = self.state.get('value'), inputValue = self.getEl('inp').value; + + e.preventDefault(); + + self.state.set('value', inputValue); + + if (stateValue != inputValue) { + self.fire('change'); + } + + if (ctrl.hasEventListeners('submit') && ctrl.toJSON) { + ctrl.fire('submit', {data: ctrl.toJSON()}); + return false; + } + }); + } + }); + + self.on('keyup', function(e) { + if (e.target.nodeName == "INPUT") { + self.state.set('value', e.target.value); + } + }); + }, + + showMenu: function() { + var self = this, settings = self.settings, menu; + + if (!self.menu) { + menu = settings.menu || []; + + // Is menu array then auto constuct menu control + if (menu.length) { + menu = { + type: 'menu', + items: menu + }; + } else { + menu.type = menu.type || 'menu'; + } + + self.menu = Factory.create(menu).parent(self).renderTo(self.getContainerElm()); + self.fire('createmenu'); + self.menu.reflow(); + self.menu.on('cancel', function(e) { + if (e.control === self.menu) { + self.focus(); + } + }); + + self.menu.on('show hide', function(e) { + e.control.items().each(function(ctrl) { + ctrl.active(ctrl.value() == self.value()); + }); + }).fire('show'); + + self.menu.on('select', function(e) { + self.value(e.control.value()); + }); + + self.on('focusin', function(e) { + if (e.target.tagName.toUpperCase() == 'INPUT') { + self.menu.hide(); + } + }); + + self.aria('expanded', true); + } + + self.menu.show(); + self.menu.layoutRect({w: self.layoutRect().w}); + self.menu.moveRel(self.getEl(), self.isRtl() ? ['br-tr', 'tr-br'] : ['bl-tl', 'tl-bl']); + }, + + /** + * Focuses the input area of the control. + * + * @method focus + */ + focus: function() { + this.getEl('inp').focus(); + }, + + /** + * Repaints the control after a layout operation. + * + * @method repaint + */ + repaint: function() { + var self = this, elm = self.getEl(), openElm = self.getEl('open'), rect = self.layoutRect(); + var width, lineHeight; + + if (openElm) { + width = rect.w - DomUtils.getSize(openElm).width - 10; + } else { + width = rect.w - 10; + } + + // Detect old IE 7+8 add lineHeight to align caret vertically in the middle + var doc = document; + if (doc.all && (!doc.documentMode || doc.documentMode <= 8)) { + lineHeight = (self.layoutRect().h - 2) + 'px'; + } + + $(elm.firstChild).css({ + width: width, + lineHeight: lineHeight + }); + + self._super(); + + return self; + }, + + /** + * Post render method. Called after the control has been rendered to the target. + * + * @method postRender + * @return {tinymce.ui.ComboBox} Current combobox instance. + */ + postRender: function() { + var self = this; + + $(this.getEl('inp')).on('change', function(e) { + self.state.set('value', e.target.value); + self.fire('change', e); + }); + + return self._super(); + }, + + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this, id = self._id, settings = self.settings, prefix = self.classPrefix; + var value = self.state.get('value') || ''; + var icon, text, openBtnHtml = '', extraAttrs = ''; + + if ("spellcheck" in settings) { + extraAttrs += ' spellcheck="' + settings.spellcheck + '"'; + } + + if (settings.maxLength) { + extraAttrs += ' maxlength="' + settings.maxLength + '"'; + } + + if (settings.size) { + extraAttrs += ' size="' + settings.size + '"'; + } + + if (settings.subtype) { + extraAttrs += ' type="' + settings.subtype + '"'; + } + + if (self.disabled()) { + extraAttrs += ' disabled="disabled"'; + } + + icon = settings.icon; + if (icon && icon != 'caret') { + icon = prefix + 'ico ' + prefix + 'i-' + settings.icon; + } + + text = self.state.get('text'); + + if (icon || text) { + openBtnHtml = ( + '<div id="' + id + '-open" class="' + prefix + 'btn ' + prefix + 'open" tabIndex="-1" role="button">' + + '<button id="' + id + '-action" type="button" hidefocus="1" tabindex="-1">' + + (icon != 'caret' ? '<i class="' + icon + '"></i>' : '<i class="' + prefix + 'caret"></i>') + + (text ? (icon ? ' ' : '') + text : '') + + '</button>' + + '</div>' + ); + + self.classes.add('has-open'); + } + + return ( + '<div id="' + id + '" class="' + self.classes + '">' + + '<input id="' + id + '-inp" class="' + prefix + 'textbox" value="' + + self.encode(value, false) + '" hidefocus="1"' + extraAttrs + ' placeholder="' + + self.encode(settings.placeholder) + '" />' + + openBtnHtml + + '</div>' + ); + }, + + value: function(value) { + if (arguments.length) { + this.state.set('value', value); + return this; + } + + // Make sure the real state is in sync + if (this.state.get('rendered')) { + this.state.set('value', this.getEl('inp').value); + } + + return this.state.get('value'); + }, + + bindStates: function() { + var self = this; + + self.state.on('change:value', function(e) { + if (self.getEl('inp').value != e.value) { + self.getEl('inp').value = e.value; + } + }); + + self.state.on('change:disabled', function(e) { + self.getEl('inp').disabled = e.value; + }); + + return self._super(); + }, + + remove: function() { + $(this.getEl('inp')).off(); + this._super(); + } + }); +}); + +// Included from: js/tinymce/classes/ui/ColorBox.js + +/** + * ColorBox.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This widget lets you enter colors and browse for colors by pressing the color button. It also displays + * a preview of the current color. + * + * @-x-less ColorBox.less + * @class tinymce.ui.ColorBox + * @extends tinymce.ui.ComboBox + */ +define("tinymce/ui/ColorBox", [ + "tinymce/ui/ComboBox" +], function(ComboBox) { + "use strict"; + + return ComboBox.extend({ + /** + * Constructs a new control instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + */ + init: function(settings) { + var self = this; + + settings.spellcheck = false; + + if (settings.onaction) { + settings.icon = 'none'; + } + + self._super(settings); + + self.classes.add('colorbox'); + self.on('change keyup postrender', function() { + self.repaintColor(self.value()); + }); + }, + + repaintColor: function(value) { + var elm = this.getEl().getElementsByTagName('i')[0]; + + if (elm) { + try { + elm.style.background = value; + } catch (ex) { + // Ignore + } + } + }, + + bindStates: function() { + var self = this; + + self.state.on('change:value', function(e) { + if (self.state.get('rendered')) { + self.repaintColor(e.value); + } + }); + + return self._super(); + } + }); +}); + +// Included from: js/tinymce/classes/ui/PanelButton.js + +/** + * PanelButton.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Creates a new panel button. + * + * @class tinymce.ui.PanelButton + * @extends tinymce.ui.Button + */ +define("tinymce/ui/PanelButton", [ + "tinymce/ui/Button", + "tinymce/ui/FloatPanel" +], function(Button, FloatPanel) { + "use strict"; + + return Button.extend({ + /** + * Shows the panel for the button. + * + * @method showPanel + */ + showPanel: function() { + var self = this, settings = self.settings; + + self.active(true); + + if (!self.panel) { + var panelSettings = settings.panel; + + // Wrap panel in grid layout if type if specified + // This makes it possible to add forms or other containers directly in the panel option + if (panelSettings.type) { + panelSettings = { + layout: 'grid', + items: panelSettings + }; + } + + panelSettings.role = panelSettings.role || 'dialog'; + panelSettings.popover = true; + panelSettings.autohide = true; + panelSettings.ariaRoot = true; + + self.panel = new FloatPanel(panelSettings).on('hide', function() { + self.active(false); + }).on('cancel', function(e) { + e.stopPropagation(); + self.focus(); + self.hidePanel(); + }).parent(self).renderTo(self.getContainerElm()); + + self.panel.fire('show'); + self.panel.reflow(); + } else { + self.panel.show(); + } + + self.panel.moveRel(self.getEl(), settings.popoverAlign || (self.isRtl() ? ['bc-tr', 'bc-tc'] : ['bc-tl', 'bc-tc'])); + }, + + /** + * Hides the panel for the button. + * + * @method hidePanel + */ + hidePanel: function() { + var self = this; + + if (self.panel) { + self.panel.hide(); + } + }, + + /** + * Called after the control has been rendered. + * + * @method postRender + */ + postRender: function() { + var self = this; + + self.aria('haspopup', true); + + self.on('click', function(e) { + if (e.control === self) { + if (self.panel && self.panel.visible()) { + self.hidePanel(); + } else { + self.showPanel(); + self.panel.focus(!!e.aria); + } + } + }); + + return self._super(); + }, + + remove: function() { + if (this.panel) { + this.panel.remove(); + this.panel = null; + } + + return this._super(); + } + }); +}); + +// Included from: js/tinymce/classes/ui/ColorButton.js + +/** + * ColorButton.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class creates a color button control. This is a split button in which the main + * button has a visual representation of the currently selected color. When clicked + * the caret button displays a color picker, allowing the user to select a new color. + * + * @-x-less ColorButton.less + * @class tinymce.ui.ColorButton + * @extends tinymce.ui.PanelButton + */ +define("tinymce/ui/ColorButton", [ + "tinymce/ui/PanelButton", + "tinymce/dom/DOMUtils" +], function(PanelButton, DomUtils) { + "use strict"; + + var DOM = DomUtils.DOM; + + return PanelButton.extend({ + /** + * Constructs a new ColorButton instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + */ + init: function(settings) { + this._super(settings); + this.classes.add('colorbutton'); + }, + + /** + * Getter/setter for the current color. + * + * @method color + * @param {String} [color] Color to set. + * @return {String|tinymce.ui.ColorButton} Current color or current instance. + */ + color: function(color) { + if (color) { + this._color = color; + this.getEl('preview').style.backgroundColor = color; + return this; + } + + return this._color; + }, + + /** + * Resets the current color. + * + * @method resetColor + * @return {tinymce.ui.ColorButton} Current instance. + */ + resetColor: function() { + this._color = null; + this.getEl('preview').style.backgroundColor = null; + return this; + }, + + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this, id = self._id, prefix = self.classPrefix, text = self.state.get('text'); + var icon = self.settings.icon ? prefix + 'ico ' + prefix + 'i-' + self.settings.icon : ''; + var image = self.settings.image ? ' style="background-image: url(\'' + self.settings.image + '\')"' : '', + textHtml = ''; + + if (text) { + self.classes.add('btn-has-text'); + textHtml = '<span class="' + prefix + 'txt">' + self.encode(text) + '</span>'; + } + + return ( + '<div id="' + id + '" class="' + self.classes + '" role="button" tabindex="-1" aria-haspopup="true">' + + '<button role="presentation" hidefocus="1" type="button" tabindex="-1">' + + (icon ? '<i class="' + icon + '"' + image + '></i>' : '') + + '<span id="' + id + '-preview" class="' + prefix + 'preview"></span>' + + textHtml + + '</button>' + + '<button type="button" class="' + prefix + 'open" hidefocus="1" tabindex="-1">' + + ' <i class="' + prefix + 'caret"></i>' + + '</button>' + + '</div>' + ); + }, + + /** + * Called after the control has been rendered. + * + * @method postRender + */ + postRender: function() { + var self = this, onClickHandler = self.settings.onclick; + + self.on('click', function(e) { + if (e.aria && e.aria.key == 'down') { + return; + } + + if (e.control == self && !DOM.getParent(e.target, '.' + self.classPrefix + 'open')) { + e.stopImmediatePropagation(); + onClickHandler.call(self, e); + } + }); + + delete self.settings.onclick; + + return self._super(); + } + }); +}); + +// Included from: js/tinymce/classes/util/Color.js + +/** + * Color.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class lets you parse/serialize colors and convert rgb/hsb. + * + * @class tinymce.util.Color + * @example + * var white = new tinymce.util.Color({r: 255, g: 255, b: 255}); + * var red = new tinymce.util.Color('#FF0000'); + * + * console.log(white.toHex(), red.toHsv()); + */ +define("tinymce/util/Color", [], function() { + var min = Math.min, max = Math.max, round = Math.round; + + /** + * Constructs a new color instance. + * + * @constructor + * @method Color + * @param {String} value Optional initial value to parse. + */ + function Color(value) { + var self = this, r = 0, g = 0, b = 0; + + function rgb2hsv(r, g, b) { + var h, s, v, d, minRGB, maxRGB; + + h = 0; + s = 0; + v = 0; + r = r / 255; + g = g / 255; + b = b / 255; + + minRGB = min(r, min(g, b)); + maxRGB = max(r, max(g, b)); + + if (minRGB == maxRGB) { + v = minRGB; + + return { + h: 0, + s: 0, + v: v * 100 + }; + } + + /*eslint no-nested-ternary:0 */ + d = (r == minRGB) ? g - b : ((b == minRGB) ? r - g : b - r); + h = (r == minRGB) ? 3 : ((b == minRGB) ? 1 : 5); + h = 60 * (h - d / (maxRGB - minRGB)); + s = (maxRGB - minRGB) / maxRGB; + v = maxRGB; + + return { + h: round(h), + s: round(s * 100), + v: round(v * 100) + }; + } + + function hsvToRgb(hue, saturation, brightness) { + var side, chroma, x, match; + + hue = (parseInt(hue, 10) || 0) % 360; + saturation = parseInt(saturation, 10) / 100; + brightness = parseInt(brightness, 10) / 100; + saturation = max(0, min(saturation, 1)); + brightness = max(0, min(brightness, 1)); + + if (saturation === 0) { + r = g = b = round(255 * brightness); + return; + } + + side = hue / 60; + chroma = brightness * saturation; + x = chroma * (1 - Math.abs(side % 2 - 1)); + match = brightness - chroma; + + switch (Math.floor(side)) { + case 0: + r = chroma; + g = x; + b = 0; + break; + + case 1: + r = x; + g = chroma; + b = 0; + break; + + case 2: + r = 0; + g = chroma; + b = x; + break; + + case 3: + r = 0; + g = x; + b = chroma; + break; + + case 4: + r = x; + g = 0; + b = chroma; + break; + + case 5: + r = chroma; + g = 0; + b = x; + break; + + default: + r = g = b = 0; + } + + r = round(255 * (r + match)); + g = round(255 * (g + match)); + b = round(255 * (b + match)); + } + + /** + * Returns the hex string of the current color. For example: #ff00ff + * + * @method toHex + * @return {String} Hex string of current color. + */ + function toHex() { + function hex(val) { + val = parseInt(val, 10).toString(16); + + return val.length > 1 ? val : '0' + val; + } + + return '#' + hex(r) + hex(g) + hex(b); + } + + /** + * Returns the r, g, b values of the color. Each channel has a range from 0-255. + * + * @method toRgb + * @return {Object} Object with r, g, b fields. + */ + function toRgb() { + return { + r: r, + g: g, + b: b + }; + } + + /** + * Returns the h, s, v values of the color. Ranges: h=0-360, s=0-100, v=0-100. + * + * @method toHsv + * @return {Object} Object with h, s, v fields. + */ + function toHsv() { + return rgb2hsv(r, g, b); + } + + /** + * Parses the specified value and populates the color instance. + * + * Supported format examples: + * * rbg(255,0,0) + * * #ff0000 + * * #fff + * * {r: 255, g: 0, b: 0} + * * {h: 360, s: 100, v: 100} + * + * @method parse + * @param {Object/String} value Color value to parse. + * @return {tinymce.util.Color} Current color instance. + */ + function parse(value) { + var matches; + + if (typeof value == 'object') { + if ("r" in value) { + r = value.r; + g = value.g; + b = value.b; + } else if ("v" in value) { + hsvToRgb(value.h, value.s, value.v); + } + } else { + if ((matches = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)[^\)]*\)/gi.exec(value))) { + r = parseInt(matches[1], 10); + g = parseInt(matches[2], 10); + b = parseInt(matches[3], 10); + } else if ((matches = /#([0-F]{2})([0-F]{2})([0-F]{2})/gi.exec(value))) { + r = parseInt(matches[1], 16); + g = parseInt(matches[2], 16); + b = parseInt(matches[3], 16); + } else if ((matches = /#([0-F])([0-F])([0-F])/gi.exec(value))) { + r = parseInt(matches[1] + matches[1], 16); + g = parseInt(matches[2] + matches[2], 16); + b = parseInt(matches[3] + matches[3], 16); + } + } + + r = r < 0 ? 0 : (r > 255 ? 255 : r); + g = g < 0 ? 0 : (g > 255 ? 255 : g); + b = b < 0 ? 0 : (b > 255 ? 255 : b); + + return self; + } + + if (value) { + parse(value); + } + + self.toRgb = toRgb; + self.toHsv = toHsv; + self.toHex = toHex; + self.parse = parse; + } + + return Color; +}); + +// Included from: js/tinymce/classes/ui/ColorPicker.js + +/** + * ColorPicker.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Color picker widget lets you select colors. + * + * @-x-less ColorPicker.less + * @class tinymce.ui.ColorPicker + * @extends tinymce.ui.Widget + */ +define("tinymce/ui/ColorPicker", [ + "tinymce/ui/Widget", + "tinymce/ui/DragHelper", + "tinymce/ui/DomUtils", + "tinymce/util/Color" +], function(Widget, DragHelper, DomUtils, Color) { + "use strict"; + + return Widget.extend({ + Defaults: { + classes: "widget colorpicker" + }, + + /** + * Constructs a new colorpicker instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + * @setting {String} color Initial color value. + */ + init: function(settings) { + this._super(settings); + }, + + postRender: function() { + var self = this, color = self.color(), hsv, hueRootElm, huePointElm, svRootElm, svPointElm; + + hueRootElm = self.getEl('h'); + huePointElm = self.getEl('hp'); + svRootElm = self.getEl('sv'); + svPointElm = self.getEl('svp'); + + function getPos(elm, event) { + var pos = DomUtils.getPos(elm), x, y; + + x = event.pageX - pos.x; + y = event.pageY - pos.y; + + x = Math.max(0, Math.min(x / elm.clientWidth, 1)); + y = Math.max(0, Math.min(y / elm.clientHeight, 1)); + + return { + x: x, + y: y + }; + } + + function updateColor(hsv, hueUpdate) { + var hue = (360 - hsv.h) / 360; + + DomUtils.css(huePointElm, { + top: (hue * 100) + '%' + }); + + if (!hueUpdate) { + DomUtils.css(svPointElm, { + left: hsv.s + '%', + top: (100 - hsv.v) + '%' + }); + } + + svRootElm.style.background = new Color({s: 100, v: 100, h: hsv.h}).toHex(); + self.color().parse({s: hsv.s, v: hsv.v, h: hsv.h}); + } + + function updateSaturationAndValue(e) { + var pos; + + pos = getPos(svRootElm, e); + hsv.s = pos.x * 100; + hsv.v = (1 - pos.y) * 100; + + updateColor(hsv); + self.fire('change'); + } + + function updateHue(e) { + var pos; + + pos = getPos(hueRootElm, e); + hsv = color.toHsv(); + hsv.h = (1 - pos.y) * 360; + updateColor(hsv, true); + self.fire('change'); + } + + self._repaint = function() { + hsv = color.toHsv(); + updateColor(hsv); + }; + + self._super(); + + self._svdraghelper = new DragHelper(self._id + '-sv', { + start: updateSaturationAndValue, + drag: updateSaturationAndValue + }); + + self._hdraghelper = new DragHelper(self._id + '-h', { + start: updateHue, + drag: updateHue + }); + + self._repaint(); + }, + + rgb: function() { + return this.color().toRgb(); + }, + + value: function(value) { + var self = this; + + if (arguments.length) { + self.color().parse(value); + + if (self._rendered) { + self._repaint(); + } + } else { + return self.color().toHex(); + } + }, + + color: function() { + if (!this._color) { + this._color = new Color(); + } + + return this._color; + }, + + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this, id = self._id, prefix = self.classPrefix, hueHtml; + var stops = '#ff0000,#ff0080,#ff00ff,#8000ff,#0000ff,#0080ff,#00ffff,#00ff80,#00ff00,#80ff00,#ffff00,#ff8000,#ff0000'; + + function getOldIeFallbackHtml() { + var i, l, html = '', gradientPrefix, stopsList; + + gradientPrefix = 'filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='; + stopsList = stops.split(','); + for (i = 0, l = stopsList.length - 1; i < l; i++) { + html += ( + '<div class="' + prefix + 'colorpicker-h-chunk" style="' + + 'height:' + (100 / l) + '%;' + + gradientPrefix + stopsList[i] + ',endColorstr=' + stopsList[i + 1] + ');' + + '-ms-' + gradientPrefix + stopsList[i] + ',endColorstr=' + stopsList[i + 1] + ')' + + '"></div>' + ); + } + + return html; + } + + var gradientCssText = ( + 'background: -ms-linear-gradient(top,' + stops + ');' + + 'background: linear-gradient(to bottom,' + stops + ');' + ); + + hueHtml = ( + '<div id="' + id + '-h" class="' + prefix + 'colorpicker-h" style="' + gradientCssText + '">' + + getOldIeFallbackHtml() + + '<div id="' + id + '-hp" class="' + prefix + 'colorpicker-h-marker"></div>' + + '</div>' + ); + + return ( + '<div id="' + id + '" class="' + self.classes + '">' + + '<div id="' + id + '-sv" class="' + prefix + 'colorpicker-sv">' + + '<div class="' + prefix + 'colorpicker-overlay1">' + + '<div class="' + prefix + 'colorpicker-overlay2">' + + '<div id="' + id + '-svp" class="' + prefix + 'colorpicker-selector1">' + + '<div class="' + prefix + 'colorpicker-selector2"></div>' + + '</div>' + + '</div>' + + '</div>' + + '</div>' + + hueHtml + + '</div>' + ); + } + }); +}); + +// Included from: js/tinymce/classes/ui/Path.js + +/** + * Path.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Creates a new path control. + * + * @-x-less Path.less + * @class tinymce.ui.Path + * @extends tinymce.ui.Widget + */ +define("tinymce/ui/Path", [ + "tinymce/ui/Widget" +], function(Widget) { + "use strict"; + + return Widget.extend({ + /** + * Constructs a instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + * @setting {String} delimiter Delimiter to display between row in path. + */ + init: function(settings) { + var self = this; + + if (!settings.delimiter) { + settings.delimiter = '\u00BB'; + } + + self._super(settings); + self.classes.add('path'); + self.canFocus = true; + + self.on('click', function(e) { + var index, target = e.target; + + if ((index = target.getAttribute('data-index'))) { + self.fire('select', {value: self.row()[index], index: index}); + } + }); + + self.row(self.settings.row); + }, + + /** + * Focuses the current control. + * + * @method focus + * @return {tinymce.ui.Control} Current control instance. + */ + focus: function() { + var self = this; + + self.getEl().firstChild.focus(); + + return self; + }, + + /** + * Sets/gets the data to be used for the path. + * + * @method row + * @param {Array} row Array with row name is rendered to path. + */ + row: function(row) { + if (!arguments.length) { + return this.state.get('row'); + } + + this.state.set('row', row); + + return this; + }, + + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this; + + return ( + '<div id="' + self._id + '" class="' + self.classes + '">' + + self._getDataPathHtml(self.state.get('row')) + + '</div>' + ); + }, + + bindStates: function() { + var self = this; + + self.state.on('change:row', function(e) { + self.innerHtml(self._getDataPathHtml(e.value)); + }); + + return self._super(); + }, + + _getDataPathHtml: function(data) { + var self = this, parts = data || [], i, l, html = '', prefix = self.classPrefix; + + for (i = 0, l = parts.length; i < l; i++) { + html += ( + (i > 0 ? '<div class="' + prefix + 'divider" aria-hidden="true"> ' + self.settings.delimiter + ' </div>' : '') + + '<div role="button" class="' + prefix + 'path-item' + (i == l - 1 ? ' ' + prefix + 'last' : '') + '" data-index="' + + i + '" tabindex="-1" id="' + self._id + '-' + i + '" aria-level="' + i + '">' + parts[i].name + '</div>' + ); + } + + if (!html) { + html = '<div class="' + prefix + 'path-item">\u00a0</div>'; + } + + return html; + } + }); +}); + +// Included from: js/tinymce/classes/ui/ElementPath.js + +/** + * ElementPath.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This control creates an path for the current selections parent elements in TinyMCE. + * + * @class tinymce.ui.ElementPath + * @extends tinymce.ui.Path + */ +define("tinymce/ui/ElementPath", [ + "tinymce/ui/Path", + "tinymce/EditorManager" +], function(Path, EditorManager) { + return Path.extend({ + /** + * Post render method. Called after the control has been rendered to the target. + * + * @method postRender + * @return {tinymce.ui.ElementPath} Current combobox instance. + */ + postRender: function() { + var self = this, editor = EditorManager.activeEditor; + + function isHidden(elm) { + if (elm.nodeType === 1) { + if (elm.nodeName == "BR" || !!elm.getAttribute('data-mce-bogus')) { + return true; + } + + if (elm.getAttribute('data-mce-type') === 'bookmark') { + return true; + } + } + + return false; + } + + if (editor.settings.elementpath !== false) { + self.on('select', function(e) { + editor.focus(); + editor.selection.select(this.row()[e.index].element); + editor.nodeChanged(); + }); + + editor.on('nodeChange', function(e) { + var outParents = [], parents = e.parents, i = parents.length; + + while (i--) { + if (parents[i].nodeType == 1 && !isHidden(parents[i])) { + var args = editor.fire('ResolveName', { + name: parents[i].nodeName.toLowerCase(), + target: parents[i] + }); + + if (!args.isDefaultPrevented()) { + outParents.push({name: args.name, element: parents[i]}); + } + + if (args.isPropagationStopped()) { + break; + } + } + } + + self.row(outParents); + }); + } + + return self._super(); + } + }); +}); + +// Included from: js/tinymce/classes/ui/FormItem.js + +/** + * FormItem.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class is a container created by the form element with + * a label and control item. + * + * @class tinymce.ui.FormItem + * @extends tinymce.ui.Container + * @setting {String} label Label to display for the form item. + */ +define("tinymce/ui/FormItem", [ + "tinymce/ui/Container" +], function(Container) { + "use strict"; + + return Container.extend({ + Defaults: { + layout: 'flex', + align: 'center', + defaults: { + flex: 1 + } + }, + + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this, layout = self._layout, prefix = self.classPrefix; + + self.classes.add('formitem'); + layout.preRender(self); + + return ( + '<div id="' + self._id + '" class="' + self.classes + '" hidefocus="1" tabindex="-1">' + + (self.settings.title ? ('<div id="' + self._id + '-title" class="' + prefix + 'title">' + + self.settings.title + '</div>') : '') + + '<div id="' + self._id + '-body" class="' + self.bodyClasses + '">' + + (self.settings.html || '') + layout.renderHtml(self) + + '</div>' + + '</div>' + ); + } + }); +}); + +// Included from: js/tinymce/classes/ui/Form.js + +/** + * Form.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class creates a form container. A form container has the ability + * to automatically wrap items in tinymce.ui.FormItem instances. + * + * Each FormItem instance is a container for the label and the item. + * + * @example + * tinymce.ui.Factory.create({ + * type: 'form', + * items: [ + * {type: 'textbox', label: 'My text box'} + * ] + * }).renderTo(document.body); + * + * @class tinymce.ui.Form + * @extends tinymce.ui.Container + */ +define("tinymce/ui/Form", [ + "tinymce/ui/Container", + "tinymce/ui/FormItem", + "tinymce/util/Tools" +], function(Container, FormItem, Tools) { + "use strict"; + + return Container.extend({ + Defaults: { + containerCls: 'form', + layout: 'flex', + direction: 'column', + align: 'stretch', + flex: 1, + padding: 20, + labelGap: 30, + spacing: 10, + callbacks: { + submit: function() { + this.submit(); + } + } + }, + + /** + * This method gets invoked before the control is rendered. + * + * @method preRender + */ + preRender: function() { + var self = this, items = self.items(); + + if (!self.settings.formItemDefaults) { + self.settings.formItemDefaults = { + layout: 'flex', + autoResize: "overflow", + defaults: {flex: 1} + }; + } + + // Wrap any labeled items in FormItems + items.each(function(ctrl) { + var formItem, label = ctrl.settings.label; + + if (label) { + formItem = new FormItem(Tools.extend({ + items: { + type: 'label', + id: ctrl._id + '-l', + text: label, + flex: 0, + forId: ctrl._id, + disabled: ctrl.disabled() + } + }, self.settings.formItemDefaults)); + + formItem.type = 'formitem'; + ctrl.aria('labelledby', ctrl._id + '-l'); + + if (typeof ctrl.settings.flex == "undefined") { + ctrl.settings.flex = 1; + } + + self.replace(ctrl, formItem); + formItem.add(ctrl); + } + }); + }, + + /** + * Fires a submit event with the serialized form. + * + * @method submit + * @return {Object} Event arguments object. + */ + submit: function() { + return this.fire('submit', {data: this.toJSON()}); + }, + + /** + * Post render method. Called after the control has been rendered to the target. + * + * @method postRender + * @return {tinymce.ui.ComboBox} Current combobox instance. + */ + postRender: function() { + var self = this; + + self._super(); + self.fromJSON(self.settings.data); + }, + + bindStates: function() { + var self = this; + + self._super(); + + function recalcLabels() { + var maxLabelWidth = 0, labels = [], i, labelGap, items; + + if (self.settings.labelGapCalc === false) { + return; + } + + if (self.settings.labelGapCalc == "children") { + items = self.find('formitem'); + } else { + items = self.items(); + } + + items.filter('formitem').each(function(item) { + var labelCtrl = item.items()[0], labelWidth = labelCtrl.getEl().clientWidth; + + maxLabelWidth = labelWidth > maxLabelWidth ? labelWidth : maxLabelWidth; + labels.push(labelCtrl); + }); + + labelGap = self.settings.labelGap || 0; + + i = labels.length; + while (i--) { + labels[i].settings.minWidth = maxLabelWidth + labelGap; + } + } + + self.on('show', recalcLabels); + recalcLabels(); + } + }); +}); + +// Included from: js/tinymce/classes/ui/FieldSet.js + +/** + * FieldSet.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class creates fieldset containers. + * + * @-x-less FieldSet.less + * @class tinymce.ui.FieldSet + * @extends tinymce.ui.Form + */ +define("tinymce/ui/FieldSet", [ + "tinymce/ui/Form" +], function(Form) { + "use strict"; + + return Form.extend({ + Defaults: { + containerCls: 'fieldset', + layout: 'flex', + direction: 'column', + align: 'stretch', + flex: 1, + padding: "25 15 5 15", + labelGap: 30, + spacing: 10, + border: 1 + }, + + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this, layout = self._layout, prefix = self.classPrefix; + + self.preRender(); + layout.preRender(self); + + return ( + '<fieldset id="' + self._id + '" class="' + self.classes + '" hidefocus="1" tabindex="-1">' + + (self.settings.title ? ('<legend id="' + self._id + '-title" class="' + prefix + 'fieldset-title">' + + self.settings.title + '</legend>') : '') + + '<div id="' + self._id + '-body" class="' + self.bodyClasses + '">' + + (self.settings.html || '') + layout.renderHtml(self) + + '</div>' + + '</fieldset>' + ); + } + }); +}); + +// Included from: js/tinymce/classes/ui/FilePicker.js + +/** + * FilePicker.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/*global tinymce:true */ + +/** + * This class creates a file picker control. + * + * @class tinymce.ui.FilePicker + * @extends tinymce.ui.ComboBox + */ +define("tinymce/ui/FilePicker", [ + "tinymce/ui/ComboBox", + "tinymce/util/Tools" +], function(ComboBox, Tools) { + "use strict"; + + return ComboBox.extend({ + /** + * Constructs a new control instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + */ + init: function(settings) { + var self = this, editor = tinymce.activeEditor, editorSettings = editor.settings; + var actionCallback, fileBrowserCallback, fileBrowserCallbackTypes; + + settings.spellcheck = false; + + fileBrowserCallbackTypes = editorSettings.file_picker_types || editorSettings.file_browser_callback_types; + if (fileBrowserCallbackTypes) { + fileBrowserCallbackTypes = Tools.makeMap(fileBrowserCallbackTypes, /[, ]/); + } + + if (!fileBrowserCallbackTypes || fileBrowserCallbackTypes[settings.filetype]) { + fileBrowserCallback = editorSettings.file_picker_callback; + if (fileBrowserCallback && (!fileBrowserCallbackTypes || fileBrowserCallbackTypes[settings.filetype])) { + actionCallback = function() { + var meta = self.fire('beforecall').meta; + + meta = Tools.extend({filetype: settings.filetype}, meta); + + // file_picker_callback(callback, currentValue, metaData) + fileBrowserCallback.call( + editor, + function(value, meta) { + self.value(value).fire('change', {meta: meta}); + }, + self.value(), + meta + ); + }; + } else { + // Legacy callback: file_picker_callback(id, currentValue, filetype, window) + fileBrowserCallback = editorSettings.file_browser_callback; + if (fileBrowserCallback && (!fileBrowserCallbackTypes || fileBrowserCallbackTypes[settings.filetype])) { + actionCallback = function() { + fileBrowserCallback( + self.getEl('inp').id, + self.value(), + settings.filetype, + window + ); + }; + } + } + } + + if (actionCallback) { + settings.icon = 'browse'; + settings.onaction = actionCallback; + } + + self._super(settings); + } + }); +}); + +// Included from: js/tinymce/classes/ui/FitLayout.js + +/** + * FitLayout.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This layout manager will resize the control to be the size of it's parent container. + * In other words width: 100% and height: 100%. + * + * @-x-less FitLayout.less + * @class tinymce.ui.FitLayout + * @extends tinymce.ui.AbsoluteLayout + */ +define("tinymce/ui/FitLayout", [ + "tinymce/ui/AbsoluteLayout" +], function(AbsoluteLayout) { + "use strict"; + + return AbsoluteLayout.extend({ + /** + * Recalculates the positions of the controls in the specified container. + * + * @method recalc + * @param {tinymce.ui.Container} container Container instance to recalc. + */ + recalc: function(container) { + var contLayoutRect = container.layoutRect(), paddingBox = container.paddingBox; + + container.items().filter(':visible').each(function(ctrl) { + ctrl.layoutRect({ + x: paddingBox.left, + y: paddingBox.top, + w: contLayoutRect.innerW - paddingBox.right - paddingBox.left, + h: contLayoutRect.innerH - paddingBox.top - paddingBox.bottom + }); + + if (ctrl.recalc) { + ctrl.recalc(); + } + }); + } + }); +}); + +// Included from: js/tinymce/classes/ui/FlexLayout.js + +/** + * FlexLayout.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This layout manager works similar to the CSS flex box. + * + * @setting {String} direction row|row-reverse|column|column-reverse + * @setting {Number} flex A positive-number to flex by. + * @setting {String} align start|end|center|stretch + * @setting {String} pack start|end|justify + * + * @class tinymce.ui.FlexLayout + * @extends tinymce.ui.AbsoluteLayout + */ +define("tinymce/ui/FlexLayout", [ + "tinymce/ui/AbsoluteLayout" +], function(AbsoluteLayout) { + "use strict"; + + return AbsoluteLayout.extend({ + /** + * Recalculates the positions of the controls in the specified container. + * + * @method recalc + * @param {tinymce.ui.Container} container Container instance to recalc. + */ + recalc: function(container) { + // A ton of variables, needs to be in the same scope for performance + var i, l, items, contLayoutRect, contPaddingBox, contSettings, align, pack, spacing, totalFlex, availableSpace, direction; + var ctrl, ctrlLayoutRect, ctrlSettings, flex, maxSizeItems = [], size, maxSize, ratio, rect, pos, maxAlignEndPos; + var sizeName, minSizeName, posName, maxSizeName, beforeName, innerSizeName, deltaSizeName, contentSizeName; + var alignAxisName, alignInnerSizeName, alignSizeName, alignMinSizeName, alignBeforeName, alignAfterName; + var alignDeltaSizeName, alignContentSizeName; + var max = Math.max, min = Math.min; + + // Get container items, properties and settings + items = container.items().filter(':visible'); + contLayoutRect = container.layoutRect(); + contPaddingBox = container.paddingBox; + contSettings = container.settings; + direction = container.isRtl() ? (contSettings.direction || 'row-reversed') : contSettings.direction; + align = contSettings.align; + pack = container.isRtl() ? (contSettings.pack || 'end') : contSettings.pack; + spacing = contSettings.spacing || 0; + + if (direction == "row-reversed" || direction == "column-reverse") { + items = items.set(items.toArray().reverse()); + direction = direction.split('-')[0]; + } + + // Setup axis variable name for row/column direction since the calculations is the same + if (direction == "column") { + posName = "y"; + sizeName = "h"; + minSizeName = "minH"; + maxSizeName = "maxH"; + innerSizeName = "innerH"; + beforeName = 'top'; + deltaSizeName = "deltaH"; + contentSizeName = "contentH"; + + alignBeforeName = "left"; + alignSizeName = "w"; + alignAxisName = "x"; + alignInnerSizeName = "innerW"; + alignMinSizeName = "minW"; + alignAfterName = "right"; + alignDeltaSizeName = "deltaW"; + alignContentSizeName = "contentW"; + } else { + posName = "x"; + sizeName = "w"; + minSizeName = "minW"; + maxSizeName = "maxW"; + innerSizeName = "innerW"; + beforeName = 'left'; + deltaSizeName = "deltaW"; + contentSizeName = "contentW"; + + alignBeforeName = "top"; + alignSizeName = "h"; + alignAxisName = "y"; + alignInnerSizeName = "innerH"; + alignMinSizeName = "minH"; + alignAfterName = "bottom"; + alignDeltaSizeName = "deltaH"; + alignContentSizeName = "contentH"; + } + + // Figure out total flex, availableSpace and collect any max size elements + availableSpace = contLayoutRect[innerSizeName] - contPaddingBox[beforeName] - contPaddingBox[beforeName]; + maxAlignEndPos = totalFlex = 0; + for (i = 0, l = items.length; i < l; i++) { + ctrl = items[i]; + ctrlLayoutRect = ctrl.layoutRect(); + ctrlSettings = ctrl.settings; + flex = ctrlSettings.flex; + availableSpace -= (i < l - 1 ? spacing : 0); + + if (flex > 0) { + totalFlex += flex; + + // Flexed item has a max size then we need to check if we will hit that size + if (ctrlLayoutRect[maxSizeName]) { + maxSizeItems.push(ctrl); + } + + ctrlLayoutRect.flex = flex; + } + + availableSpace -= ctrlLayoutRect[minSizeName]; + + // Calculate the align end position to be used to check for overflow/underflow + size = contPaddingBox[alignBeforeName] + ctrlLayoutRect[alignMinSizeName] + contPaddingBox[alignAfterName]; + if (size > maxAlignEndPos) { + maxAlignEndPos = size; + } + } + + // Calculate minW/minH + rect = {}; + if (availableSpace < 0) { + rect[minSizeName] = contLayoutRect[minSizeName] - availableSpace + contLayoutRect[deltaSizeName]; + } else { + rect[minSizeName] = contLayoutRect[innerSizeName] - availableSpace + contLayoutRect[deltaSizeName]; + } + + rect[alignMinSizeName] = maxAlignEndPos + contLayoutRect[alignDeltaSizeName]; + + rect[contentSizeName] = contLayoutRect[innerSizeName] - availableSpace; + rect[alignContentSizeName] = maxAlignEndPos; + rect.minW = min(rect.minW, contLayoutRect.maxW); + rect.minH = min(rect.minH, contLayoutRect.maxH); + rect.minW = max(rect.minW, contLayoutRect.startMinWidth); + rect.minH = max(rect.minH, contLayoutRect.startMinHeight); + + // Resize container container if minSize was changed + if (contLayoutRect.autoResize && (rect.minW != contLayoutRect.minW || rect.minH != contLayoutRect.minH)) { + rect.w = rect.minW; + rect.h = rect.minH; + + container.layoutRect(rect); + this.recalc(container); + + // Forced recalc for example if items are hidden/shown + if (container._lastRect === null) { + var parentCtrl = container.parent(); + if (parentCtrl) { + parentCtrl._lastRect = null; + parentCtrl.recalc(); + } + } + + return; + } + + // Handle max size elements, check if they will become to wide with current options + ratio = availableSpace / totalFlex; + for (i = 0, l = maxSizeItems.length; i < l; i++) { + ctrl = maxSizeItems[i]; + ctrlLayoutRect = ctrl.layoutRect(); + maxSize = ctrlLayoutRect[maxSizeName]; + size = ctrlLayoutRect[minSizeName] + ctrlLayoutRect.flex * ratio; + + if (size > maxSize) { + availableSpace -= (ctrlLayoutRect[maxSizeName] - ctrlLayoutRect[minSizeName]); + totalFlex -= ctrlLayoutRect.flex; + ctrlLayoutRect.flex = 0; + ctrlLayoutRect.maxFlexSize = maxSize; + } else { + ctrlLayoutRect.maxFlexSize = 0; + } + } + + // Setup new ratio, target layout rect, start position + ratio = availableSpace / totalFlex; + pos = contPaddingBox[beforeName]; + rect = {}; + + // Handle pack setting moves the start position to end, center + if (totalFlex === 0) { + if (pack == "end") { + pos = availableSpace + contPaddingBox[beforeName]; + } else if (pack == "center") { + pos = Math.round( + (contLayoutRect[innerSizeName] / 2) - ((contLayoutRect[innerSizeName] - availableSpace) / 2) + ) + contPaddingBox[beforeName]; + + if (pos < 0) { + pos = contPaddingBox[beforeName]; + } + } else if (pack == "justify") { + pos = contPaddingBox[beforeName]; + spacing = Math.floor(availableSpace / (items.length - 1)); + } + } + + // Default aligning (start) the other ones needs to be calculated while doing the layout + rect[alignAxisName] = contPaddingBox[alignBeforeName]; + + // Start laying out controls + for (i = 0, l = items.length; i < l; i++) { + ctrl = items[i]; + ctrlLayoutRect = ctrl.layoutRect(); + size = ctrlLayoutRect.maxFlexSize || ctrlLayoutRect[minSizeName]; + + // Align the control on the other axis + if (align === "center") { + rect[alignAxisName] = Math.round((contLayoutRect[alignInnerSizeName] / 2) - (ctrlLayoutRect[alignSizeName] / 2)); + } else if (align === "stretch") { + rect[alignSizeName] = max( + ctrlLayoutRect[alignMinSizeName] || 0, + contLayoutRect[alignInnerSizeName] - contPaddingBox[alignBeforeName] - contPaddingBox[alignAfterName] + ); + rect[alignAxisName] = contPaddingBox[alignBeforeName]; + } else if (align === "end") { + rect[alignAxisName] = contLayoutRect[alignInnerSizeName] - ctrlLayoutRect[alignSizeName] - contPaddingBox.top; + } + + // Calculate new size based on flex + if (ctrlLayoutRect.flex > 0) { + size += ctrlLayoutRect.flex * ratio; + } + + rect[sizeName] = size; + rect[posName] = pos; + ctrl.layoutRect(rect); + + // Recalculate containers + if (ctrl.recalc) { + ctrl.recalc(); + } + + // Move x/y position + pos += size + spacing; + } + } + }); +}); + +// Included from: js/tinymce/classes/ui/FlowLayout.js + +/** + * FlowLayout.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This layout manager will place the controls by using the browsers native layout. + * + * @-x-less FlowLayout.less + * @class tinymce.ui.FlowLayout + * @extends tinymce.ui.Layout + */ +define("tinymce/ui/FlowLayout", [ + "tinymce/ui/Layout" +], function(Layout) { + return Layout.extend({ + Defaults: { + containerClass: 'flow-layout', + controlClass: 'flow-layout-item', + endClass: 'break' + }, + + /** + * Recalculates the positions of the controls in the specified container. + * + * @method recalc + * @param {tinymce.ui.Container} container Container instance to recalc. + */ + recalc: function(container) { + container.items().filter(':visible').each(function(ctrl) { + if (ctrl.recalc) { + ctrl.recalc(); + } + }); + }, + + isNative: function() { + return true; + } + }); +}); + +// Included from: js/tinymce/classes/ui/FormatControls.js + +/** + * FormatControls.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Internal class containing all TinyMCE specific control types such as + * format listboxes, fontlist boxes, toolbar buttons etc. + * + * @class tinymce.ui.FormatControls + */ +define("tinymce/ui/FormatControls", [ + "tinymce/ui/Control", + "tinymce/ui/Widget", + "tinymce/ui/FloatPanel", + "tinymce/util/Tools", + "tinymce/EditorManager", + "tinymce/Env" +], function(Control, Widget, FloatPanel, Tools, EditorManager, Env) { + var each = Tools.each; + + EditorManager.on('AddEditor', function(e) { + if (e.editor.rtl) { + Control.rtl = true; + } + + registerControls(e.editor); + }); + + Control.translate = function(text) { + return EditorManager.translate(text); + }; + + Widget.tooltips = !Env.iOS; + + function registerControls(editor) { + var formatMenu; + + function createListBoxChangeHandler(items, formatName) { + return function() { + var self = this; + + editor.on('nodeChange', function(e) { + var formatter = editor.formatter; + var value = null; + + each(e.parents, function(node) { + each(items, function(item) { + if (formatName) { + if (formatter.matchNode(node, formatName, {value: item.value})) { + value = item.value; + } + } else { + if (formatter.matchNode(node, item.value)) { + value = item.value; + } + } + + if (value) { + return false; + } + }); + + if (value) { + return false; + } + }); + + self.value(value); + }); + }; + } + + function createFormats(formats) { + formats = formats.replace(/;$/, '').split(';'); + + var i = formats.length; + while (i--) { + formats[i] = formats[i].split('='); + } + + return formats; + } + + function createFormatMenu() { + var count = 0, newFormats = []; + + var defaultStyleFormats = [ + {title: 'Headings', items: [ + {title: 'Heading 1', format: 'h1'}, + {title: 'Heading 2', format: 'h2'}, + {title: 'Heading 3', format: 'h3'}, + {title: 'Heading 4', format: 'h4'}, + {title: 'Heading 5', format: 'h5'}, + {title: 'Heading 6', format: 'h6'} + ]}, + + {title: 'Inline', items: [ + {title: 'Bold', icon: 'bold', format: 'bold'}, + {title: 'Italic', icon: 'italic', format: 'italic'}, + {title: 'Underline', icon: 'underline', format: 'underline'}, + {title: 'Strikethrough', icon: 'strikethrough', format: 'strikethrough'}, + {title: 'Superscript', icon: 'superscript', format: 'superscript'}, + {title: 'Subscript', icon: 'subscript', format: 'subscript'}, + {title: 'Code', icon: 'code', format: 'code'} + ]}, + + {title: 'Blocks', items: [ + {title: 'Paragraph', format: 'p'}, + {title: 'Blockquote', format: 'blockquote'}, + {title: 'Div', format: 'div'}, + {title: 'Pre', format: 'pre'} + ]}, + + {title: 'Alignment', items: [ + {title: 'Left', icon: 'alignleft', format: 'alignleft'}, + {title: 'Center', icon: 'aligncenter', format: 'aligncenter'}, + {title: 'Right', icon: 'alignright', format: 'alignright'}, + {title: 'Justify', icon: 'alignjustify', format: 'alignjustify'} + ]} + ]; + + function createMenu(formats) { + var menu = []; + + if (!formats) { + return; + } + + each(formats, function(format) { + var menuItem = { + text: format.title, + icon: format.icon + }; + + if (format.items) { + menuItem.menu = createMenu(format.items); + } else { + var formatName = format.format || "custom" + count++; + + if (!format.format) { + format.name = formatName; + newFormats.push(format); + } + + menuItem.format = formatName; + menuItem.cmd = format.cmd; + } + + menu.push(menuItem); + }); + + return menu; + } + + function createStylesMenu() { + var menu; + + if (editor.settings.style_formats_merge) { + if (editor.settings.style_formats) { + menu = createMenu(defaultStyleFormats.concat(editor.settings.style_formats)); + } else { + menu = createMenu(defaultStyleFormats); + } + } else { + menu = createMenu(editor.settings.style_formats || defaultStyleFormats); + } + + return menu; + } + + editor.on('init', function() { + each(newFormats, function(format) { + editor.formatter.register(format.name, format); + }); + }); + + return { + type: 'menu', + items: createStylesMenu(), + onPostRender: function(e) { + editor.fire('renderFormatsMenu', {control: e.control}); + }, + itemDefaults: { + preview: true, + + textStyle: function() { + if (this.settings.format) { + return editor.formatter.getCssText(this.settings.format); + } + }, + + onPostRender: function() { + var self = this; + + self.parent().on('show', function() { + var formatName, command; + + formatName = self.settings.format; + if (formatName) { + self.disabled(!editor.formatter.canApply(formatName)); + self.active(editor.formatter.match(formatName)); + } + + command = self.settings.cmd; + if (command) { + self.active(editor.queryCommandState(command)); + } + }); + }, + + onclick: function() { + if (this.settings.format) { + toggleFormat(this.settings.format); + } + + if (this.settings.cmd) { + editor.execCommand(this.settings.cmd); + } + } + } + }; + } + + formatMenu = createFormatMenu(); + + function initOnPostRender(name) { + return function() { + var self = this; + + // TODO: Fix this + if (editor.formatter) { + editor.formatter.formatChanged(name, function(state) { + self.active(state); + }); + } else { + editor.on('init', function() { + editor.formatter.formatChanged(name, function(state) { + self.active(state); + }); + }); + } + }; + } + + // Simple format controls <control/format>:<UI text> + each({ + bold: 'Bold', + italic: 'Italic', + underline: 'Underline', + strikethrough: 'Strikethrough', + subscript: 'Subscript', + superscript: 'Superscript' + }, function(text, name) { + editor.addButton(name, { + tooltip: text, + onPostRender: initOnPostRender(name), + onclick: function() { + toggleFormat(name); + } + }); + }); + + // Simple command controls <control>:[<UI text>,<Command>] + each({ + outdent: ['Decrease indent', 'Outdent'], + indent: ['Increase indent', 'Indent'], + cut: ['Cut', 'Cut'], + copy: ['Copy', 'Copy'], + paste: ['Paste', 'Paste'], + help: ['Help', 'mceHelp'], + selectall: ['Select all', 'SelectAll'], + removeformat: ['Clear formatting', 'RemoveFormat'], + visualaid: ['Visual aids', 'mceToggleVisualAid'], + newdocument: ['New document', 'mceNewDocument'] + }, function(item, name) { + editor.addButton(name, { + tooltip: item[0], + cmd: item[1] + }); + }); + + // Simple command controls with format state + each({ + blockquote: ['Blockquote', 'mceBlockQuote'], + numlist: ['Numbered list', 'InsertOrderedList'], + bullist: ['Bullet list', 'InsertUnorderedList'], + subscript: ['Subscript', 'Subscript'], + superscript: ['Superscript', 'Superscript'], + alignleft: ['Align left', 'JustifyLeft'], + aligncenter: ['Align center', 'JustifyCenter'], + alignright: ['Align right', 'JustifyRight'], + alignjustify: ['Justify', 'JustifyFull'], + alignnone: ['No alignment', 'JustifyNone'] + }, function(item, name) { + editor.addButton(name, { + tooltip: item[0], + cmd: item[1], + onPostRender: initOnPostRender(name) + }); + }); + + function toggleUndoRedoState(type) { + return function() { + var self = this; + + type = type == 'redo' ? 'hasRedo' : 'hasUndo'; + + function checkState() { + return editor.undoManager ? editor.undoManager[type]() : false; + } + + self.disabled(!checkState()); + editor.on('Undo Redo AddUndo TypingUndo ClearUndos SwitchMode', function() { + self.disabled(editor.readonly || !checkState()); + }); + }; + } + + function toggleVisualAidState() { + var self = this; + + editor.on('VisualAid', function(e) { + self.active(e.hasVisual); + }); + + self.active(editor.hasVisual); + } + + editor.addButton('undo', { + tooltip: 'Undo', + onPostRender: toggleUndoRedoState('undo'), + cmd: 'undo' + }); + + editor.addButton('redo', { + tooltip: 'Redo', + onPostRender: toggleUndoRedoState('redo'), + cmd: 'redo' + }); + + editor.addMenuItem('newdocument', { + text: 'New document', + icon: 'newdocument', + cmd: 'mceNewDocument' + }); + + editor.addMenuItem('undo', { + text: 'Undo', + icon: 'undo', + shortcut: 'Meta+Z', + onPostRender: toggleUndoRedoState('undo'), + cmd: 'undo' + }); + + editor.addMenuItem('redo', { + text: 'Redo', + icon: 'redo', + shortcut: 'Meta+Y', + onPostRender: toggleUndoRedoState('redo'), + cmd: 'redo' + }); + + editor.addMenuItem('visualaid', { + text: 'Visual aids', + selectable: true, + onPostRender: toggleVisualAidState, + cmd: 'mceToggleVisualAid' + }); + + editor.addButton('remove', { + tooltip: 'Remove', + icon: 'remove', + cmd: 'Delete' + }); + + each({ + cut: ['Cut', 'Cut', 'Meta+X'], + copy: ['Copy', 'Copy', 'Meta+C'], + paste: ['Paste', 'Paste', 'Meta+V'], + selectall: ['Select all', 'SelectAll', 'Meta+A'], + bold: ['Bold', 'Bold', 'Meta+B'], + italic: ['Italic', 'Italic', 'Meta+I'], + underline: ['Underline', 'Underline'], + strikethrough: ['Strikethrough', 'Strikethrough'], + subscript: ['Subscript', 'Subscript'], + superscript: ['Superscript', 'Superscript'], + removeformat: ['Clear formatting', 'RemoveFormat'] + }, function(item, name) { + editor.addMenuItem(name, { + text: item[0], + icon: name, + shortcut: item[2], + cmd: item[1] + }); + }); + + editor.on('mousedown', function() { + FloatPanel.hideAll(); + }); + + function toggleFormat(fmt) { + if (fmt.control) { + fmt = fmt.control.value(); + } + + if (fmt) { + editor.execCommand('mceToggleFormat', false, fmt); + } + } + + editor.addButton('styleselect', { + type: 'menubutton', + text: 'Formats', + menu: formatMenu + }); + + editor.addButton('formatselect', function() { + var items = [], blocks = createFormats(editor.settings.block_formats || + 'Paragraph=p;' + + 'Heading 1=h1;' + + 'Heading 2=h2;' + + 'Heading 3=h3;' + + 'Heading 4=h4;' + + 'Heading 5=h5;' + + 'Heading 6=h6;' + + 'Preformatted=pre' + ); + + each(blocks, function(block) { + items.push({ + text: block[0], + value: block[1], + textStyle: function() { + return editor.formatter.getCssText(block[1]); + } + }); + }); + + return { + type: 'listbox', + text: blocks[0][0], + values: items, + fixedWidth: true, + onselect: toggleFormat, + onPostRender: createListBoxChangeHandler(items) + }; + }); + + editor.addButton('fontselect', function() { + var defaultFontsFormats = + 'Andale Mono=andale mono,monospace;' + + 'Arial=arial,helvetica,sans-serif;' + + 'Arial Black=arial black,sans-serif;' + + 'Book Antiqua=book antiqua,palatino,serif;' + + 'Comic Sans MS=comic sans ms,sans-serif;' + + 'Courier New=courier new,courier,monospace;' + + 'Georgia=georgia,palatino,serif;' + + 'Helvetica=helvetica,arial,sans-serif;' + + 'Impact=impact,sans-serif;' + + 'Symbol=symbol;' + + 'Tahoma=tahoma,arial,helvetica,sans-serif;' + + 'Terminal=terminal,monaco,monospace;' + + 'Times New Roman=times new roman,times,serif;' + + 'Trebuchet MS=trebuchet ms,geneva,sans-serif;' + + 'Verdana=verdana,geneva,sans-serif;' + + 'Webdings=webdings;' + + 'Wingdings=wingdings,zapf dingbats'; + + var items = [], fonts = createFormats(editor.settings.font_formats || defaultFontsFormats); + + each(fonts, function(font) { + items.push({ + text: {raw: font[0]}, + value: font[1], + textStyle: font[1].indexOf('dings') == -1 ? 'font-family:' + font[1] : '' + }); + }); + + return { + type: 'listbox', + text: 'Font Family', + tooltip: 'Font Family', + values: items, + fixedWidth: true, + onPostRender: createListBoxChangeHandler(items, 'fontname'), + onselect: function(e) { + if (e.control.settings.value) { + editor.execCommand('FontName', false, e.control.settings.value); + } + } + }; + }); + + editor.addButton('fontsizeselect', function() { + var items = [], defaultFontsizeFormats = '8pt 10pt 12pt 14pt 18pt 24pt 36pt'; + var fontsize_formats = editor.settings.fontsize_formats || defaultFontsizeFormats; + + each(fontsize_formats.split(' '), function(item) { + var text = item, value = item; + // Allow text=value font sizes. + var values = item.split('='); + if (values.length > 1) { + text = values[0]; + value = values[1]; + } + items.push({text: text, value: value}); + }); + + return { + type: 'listbox', + text: 'Font Sizes', + tooltip: 'Font Sizes', + values: items, + fixedWidth: true, + onPostRender: createListBoxChangeHandler(items, 'fontsize'), + onclick: function(e) { + if (e.control.settings.value) { + editor.execCommand('FontSize', false, e.control.settings.value); + } + } + }; + }); + + editor.addMenuItem('formats', { + text: 'Formats', + menu: formatMenu + }); + } +}); + +// Included from: js/tinymce/classes/ui/GridLayout.js + +/** + * GridLayout.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This layout manager places controls in a grid. + * + * @setting {Number} spacing Spacing between controls. + * @setting {Number} spacingH Horizontal spacing between controls. + * @setting {Number} spacingV Vertical spacing between controls. + * @setting {Number} columns Number of columns to use. + * @setting {String/Array} alignH start|end|center|stretch or array of values for each column. + * @setting {String/Array} alignV start|end|center|stretch or array of values for each column. + * @setting {String} pack start|end + * + * @class tinymce.ui.GridLayout + * @extends tinymce.ui.AbsoluteLayout + */ +define("tinymce/ui/GridLayout", [ + "tinymce/ui/AbsoluteLayout" +], function(AbsoluteLayout) { + "use strict"; + + return AbsoluteLayout.extend({ + /** + * Recalculates the positions of the controls in the specified container. + * + * @method recalc + * @param {tinymce.ui.Container} container Container instance to recalc. + */ + recalc: function(container) { + var settings, rows, cols, items, contLayoutRect, width, height, rect, + ctrlLayoutRect, ctrl, x, y, posX, posY, ctrlSettings, contPaddingBox, align, spacingH, spacingV, alignH, alignV, maxX, maxY, + colWidths = [], rowHeights = [], ctrlMinWidth, ctrlMinHeight, availableWidth, availableHeight, reverseRows, idx; + + // Get layout settings + settings = container.settings; + items = container.items().filter(':visible'); + contLayoutRect = container.layoutRect(); + cols = settings.columns || Math.ceil(Math.sqrt(items.length)); + rows = Math.ceil(items.length / cols); + spacingH = settings.spacingH || settings.spacing || 0; + spacingV = settings.spacingV || settings.spacing || 0; + alignH = settings.alignH || settings.align; + alignV = settings.alignV || settings.align; + contPaddingBox = container.paddingBox; + reverseRows = 'reverseRows' in settings ? settings.reverseRows : container.isRtl(); + + if (alignH && typeof alignH == "string") { + alignH = [alignH]; + } + + if (alignV && typeof alignV == "string") { + alignV = [alignV]; + } + + // Zero padd columnWidths + for (x = 0; x < cols; x++) { + colWidths.push(0); + } + + // Zero padd rowHeights + for (y = 0; y < rows; y++) { + rowHeights.push(0); + } + + // Calculate columnWidths and rowHeights + for (y = 0; y < rows; y++) { + for (x = 0; x < cols; x++) { + ctrl = items[y * cols + x]; + + // Out of bounds + if (!ctrl) { + break; + } + + ctrlLayoutRect = ctrl.layoutRect(); + ctrlMinWidth = ctrlLayoutRect.minW; + ctrlMinHeight = ctrlLayoutRect.minH; + + colWidths[x] = ctrlMinWidth > colWidths[x] ? ctrlMinWidth : colWidths[x]; + rowHeights[y] = ctrlMinHeight > rowHeights[y] ? ctrlMinHeight : rowHeights[y]; + } + } + + // Calculate maxX + availableWidth = contLayoutRect.innerW - contPaddingBox.left - contPaddingBox.right; + for (maxX = 0, x = 0; x < cols; x++) { + maxX += colWidths[x] + (x > 0 ? spacingH : 0); + availableWidth -= (x > 0 ? spacingH : 0) + colWidths[x]; + } + + // Calculate maxY + availableHeight = contLayoutRect.innerH - contPaddingBox.top - contPaddingBox.bottom; + for (maxY = 0, y = 0; y < rows; y++) { + maxY += rowHeights[y] + (y > 0 ? spacingV : 0); + availableHeight -= (y > 0 ? spacingV : 0) + rowHeights[y]; + } + + maxX += contPaddingBox.left + contPaddingBox.right; + maxY += contPaddingBox.top + contPaddingBox.bottom; + + // Calculate minW/minH + rect = {}; + rect.minW = maxX + (contLayoutRect.w - contLayoutRect.innerW); + rect.minH = maxY + (contLayoutRect.h - contLayoutRect.innerH); + + rect.contentW = rect.minW - contLayoutRect.deltaW; + rect.contentH = rect.minH - contLayoutRect.deltaH; + rect.minW = Math.min(rect.minW, contLayoutRect.maxW); + rect.minH = Math.min(rect.minH, contLayoutRect.maxH); + rect.minW = Math.max(rect.minW, contLayoutRect.startMinWidth); + rect.minH = Math.max(rect.minH, contLayoutRect.startMinHeight); + + // Resize container container if minSize was changed + if (contLayoutRect.autoResize && (rect.minW != contLayoutRect.minW || rect.minH != contLayoutRect.minH)) { + rect.w = rect.minW; + rect.h = rect.minH; + + container.layoutRect(rect); + this.recalc(container); + + // Forced recalc for example if items are hidden/shown + if (container._lastRect === null) { + var parentCtrl = container.parent(); + if (parentCtrl) { + parentCtrl._lastRect = null; + parentCtrl.recalc(); + } + } + + return; + } + + // Update contentW/contentH so absEnd moves correctly + if (contLayoutRect.autoResize) { + rect = container.layoutRect(rect); + rect.contentW = rect.minW - contLayoutRect.deltaW; + rect.contentH = rect.minH - contLayoutRect.deltaH; + } + + var flexV; + + if (settings.packV == 'start') { + flexV = 0; + } else { + flexV = availableHeight > 0 ? Math.floor(availableHeight / rows) : 0; + } + + // Calculate totalFlex + var totalFlex = 0; + var flexWidths = settings.flexWidths; + if (flexWidths) { + for (x = 0; x < flexWidths.length; x++) { + totalFlex += flexWidths[x]; + } + } else { + totalFlex = cols; + } + + // Calculate new column widths based on flex values + var ratio = availableWidth / totalFlex; + for (x = 0; x < cols; x++) { + colWidths[x] += flexWidths ? flexWidths[x] * ratio : ratio; + } + + // Move/resize controls + posY = contPaddingBox.top; + for (y = 0; y < rows; y++) { + posX = contPaddingBox.left; + height = rowHeights[y] + flexV; + + for (x = 0; x < cols; x++) { + if (reverseRows) { + idx = y * cols + cols - 1 - x; + } else { + idx = y * cols + x; + } + + ctrl = items[idx]; + + // No more controls to render then break + if (!ctrl) { + break; + } + + // Get control settings and calculate x, y + ctrlSettings = ctrl.settings; + ctrlLayoutRect = ctrl.layoutRect(); + width = Math.max(colWidths[x], ctrlLayoutRect.startMinWidth); + ctrlLayoutRect.x = posX; + ctrlLayoutRect.y = posY; + + // Align control horizontal + align = ctrlSettings.alignH || (alignH ? (alignH[x] || alignH[0]) : null); + if (align == "center") { + ctrlLayoutRect.x = posX + (width / 2) - (ctrlLayoutRect.w / 2); + } else if (align == "right") { + ctrlLayoutRect.x = posX + width - ctrlLayoutRect.w; + } else if (align == "stretch") { + ctrlLayoutRect.w = width; + } + + // Align control vertical + align = ctrlSettings.alignV || (alignV ? (alignV[x] || alignV[0]) : null); + if (align == "center") { + ctrlLayoutRect.y = posY + (height / 2) - (ctrlLayoutRect.h / 2); + } else if (align == "bottom") { + ctrlLayoutRect.y = posY + height - ctrlLayoutRect.h; + } else if (align == "stretch") { + ctrlLayoutRect.h = height; + } + + ctrl.layoutRect(ctrlLayoutRect); + + posX += width + spacingH; + + if (ctrl.recalc) { + ctrl.recalc(); + } + } + + posY += height + spacingV; + } + } + }); +}); + +// Included from: js/tinymce/classes/ui/Iframe.js + +/** + * Iframe.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/*jshint scripturl:true */ + +/** + * This class creates an iframe. + * + * @setting {String} url Url to open in the iframe. + * + * @-x-less Iframe.less + * @class tinymce.ui.Iframe + * @extends tinymce.ui.Widget + */ +define("tinymce/ui/Iframe", [ + "tinymce/ui/Widget", + "tinymce/util/Delay" +], function(Widget, Delay) { + "use strict"; + + return Widget.extend({ + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this; + + self.classes.add('iframe'); + self.canFocus = false; + + /*eslint no-script-url:0 */ + return ( + '<iframe id="' + self._id + '" class="' + self.classes + '" tabindex="-1" src="' + + (self.settings.url || "javascript:''") + '" frameborder="0"></iframe>' + ); + }, + + /** + * Setter for the iframe source. + * + * @method src + * @param {String} src Source URL for iframe. + */ + src: function(src) { + this.getEl().src = src; + }, + + /** + * Inner HTML for the iframe. + * + * @method html + * @param {String} html HTML string to set as HTML inside the iframe. + * @param {function} callback Optional callback to execute when the iframe body is filled with contents. + * @return {tinymce.ui.Iframe} Current iframe control. + */ + html: function(html, callback) { + var self = this, body = this.getEl().contentWindow.document.body; + + // Wait for iframe to initialize IE 10 takes time + if (!body) { + Delay.setTimeout(function() { + self.html(html); + }); + } else { + body.innerHTML = html; + + if (callback) { + callback(); + } + } + + return this; + } + }); +}); + +// Included from: js/tinymce/classes/ui/InfoBox.js + +/** + * InfoBox.js + * + * Released under LGPL License. + * Copyright (c) 1999-2016 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * .... + * + * @-x-less InfoBox.less + * @class tinymce.ui.InfoBox + * @extends tinymce.ui.Widget + */ +define("tinymce/ui/InfoBox", [ + "tinymce/ui/Widget" +], function(Widget) { + "use strict"; + + return Widget.extend({ + /** + * Constructs a instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + * @setting {Boolean} multiline Multiline label. + */ + init: function(settings) { + var self = this; + + self._super(settings); + self.classes.add('widget').add('infobox'); + self.canFocus = false; + }, + + severity: function(level) { + this.classes.remove('error'); + this.classes.remove('warning'); + this.classes.remove('success'); + this.classes.add(level); + }, + + help: function(state) { + this.state.set('help', state); + }, + + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this, prefix = self.classPrefix; + + return ( + '<div id="' + self._id + '" class="' + self.classes + '">' + + '<div id="' + self._id + '-body">' + + self.encode(self.state.get('text')) + + '<button role="button" tabindex="-1">' + + '<i class="' + prefix + 'ico ' + prefix + 'i-help"></i>' + + '</button>' + + '</div>' + + '</div>' + ); + }, + + bindStates: function() { + var self = this; + + self.state.on('change:text', function(e) { + self.getEl('body').firstChild.data = self.encode(e.value); + + if (self.state.get('rendered')) { + self.updateLayoutRect(); + } + }); + + self.state.on('change:help', function(e) { + self.classes.toggle('has-help', e.value); + + if (self.state.get('rendered')) { + self.updateLayoutRect(); + } + }); + + return self._super(); + } + }); +}); + +// Included from: js/tinymce/classes/ui/Label.js + +/** + * Label.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class creates a label element. A label is a simple text control + * that can be bound to other controls. + * + * @-x-less Label.less + * @class tinymce.ui.Label + * @extends tinymce.ui.Widget + */ +define("tinymce/ui/Label", [ + "tinymce/ui/Widget", + "tinymce/ui/DomUtils" +], function(Widget, DomUtils) { + "use strict"; + + return Widget.extend({ + /** + * Constructs a instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + * @setting {Boolean} multiline Multiline label. + */ + init: function(settings) { + var self = this; + + self._super(settings); + self.classes.add('widget').add('label'); + self.canFocus = false; + + if (settings.multiline) { + self.classes.add('autoscroll'); + } + + if (settings.strong) { + self.classes.add('strong'); + } + }, + + /** + * Initializes the current controls layout rect. + * This will be executed by the layout managers to determine the + * default minWidth/minHeight etc. + * + * @method initLayoutRect + * @return {Object} Layout rect instance. + */ + initLayoutRect: function() { + var self = this, layoutRect = self._super(); + + if (self.settings.multiline) { + var size = DomUtils.getSize(self.getEl()); + + // Check if the text fits within maxW if not then try word wrapping it + if (size.width > layoutRect.maxW) { + layoutRect.minW = layoutRect.maxW; + self.classes.add('multiline'); + } + + self.getEl().style.width = layoutRect.minW + 'px'; + layoutRect.startMinH = layoutRect.h = layoutRect.minH = Math.min(layoutRect.maxH, DomUtils.getSize(self.getEl()).height); + } + + return layoutRect; + }, + + /** + * Repaints the control after a layout operation. + * + * @method repaint + */ + repaint: function() { + var self = this; + + if (!self.settings.multiline) { + self.getEl().style.lineHeight = self.layoutRect().h + 'px'; + } + + return self._super(); + }, + + severity: function(level) { + this.classes.remove('error'); + this.classes.remove('warning'); + this.classes.remove('success'); + this.classes.add(level); + }, + + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this, targetCtrl, forName, forId = self.settings.forId; + + if (!forId && (forName = self.settings.forName)) { + targetCtrl = self.getRoot().find('#' + forName)[0]; + + if (targetCtrl) { + forId = targetCtrl._id; + } + } + + if (forId) { + return ( + '<label id="' + self._id + '" class="' + self.classes + '"' + (forId ? ' for="' + forId + '"' : '') + '>' + + self.encode(self.state.get('text')) + + '</label>' + ); + } + + return ( + '<span id="' + self._id + '" class="' + self.classes + '">' + + self.encode(self.state.get('text')) + + '</span>' + ); + }, + + bindStates: function() { + var self = this; + + self.state.on('change:text', function(e) { + self.innerHtml(self.encode(e.value)); + + if (self.state.get('rendered')) { + self.updateLayoutRect(); + } + }); + + return self._super(); + } + }); +}); + +// Included from: js/tinymce/classes/ui/Toolbar.js + +/** + * Toolbar.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Creates a new toolbar. + * + * @class tinymce.ui.Toolbar + * @extends tinymce.ui.Container + */ +define("tinymce/ui/Toolbar", [ + "tinymce/ui/Container" +], function(Container) { + "use strict"; + + return Container.extend({ + Defaults: { + role: 'toolbar', + layout: 'flow' + }, + + /** + * Constructs a instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + */ + init: function(settings) { + var self = this; + + self._super(settings); + self.classes.add('toolbar'); + }, + + /** + * Called after the control has been rendered. + * + * @method postRender + */ + postRender: function() { + var self = this; + + self.items().each(function(ctrl) { + ctrl.classes.add('toolbar-item'); + }); + + return self._super(); + } + }); +}); + +// Included from: js/tinymce/classes/ui/MenuBar.js + +/** + * MenuBar.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Creates a new menubar. + * + * @-x-less MenuBar.less + * @class tinymce.ui.MenuBar + * @extends tinymce.ui.Container + */ +define("tinymce/ui/MenuBar", [ + "tinymce/ui/Toolbar" +], function(Toolbar) { + "use strict"; + + return Toolbar.extend({ + Defaults: { + role: 'menubar', + containerCls: 'menubar', + ariaRoot: true, + defaults: { + type: 'menubutton' + } + } + }); +}); + +// Included from: js/tinymce/classes/ui/MenuButton.js + +/** + * MenuButton.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Creates a new menu button. + * + * @-x-less MenuButton.less + * @class tinymce.ui.MenuButton + * @extends tinymce.ui.Button + */ +define("tinymce/ui/MenuButton", [ + "tinymce/ui/Button", + "tinymce/ui/Factory", + "tinymce/ui/MenuBar" +], function(Button, Factory, MenuBar) { + "use strict"; + + // TODO: Maybe add as some global function + function isChildOf(node, parent) { + while (node) { + if (parent === node) { + return true; + } + + node = node.parentNode; + } + + return false; + } + + var MenuButton = Button.extend({ + /** + * Constructs a instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + */ + init: function(settings) { + var self = this; + + self._renderOpen = true; + + self._super(settings); + settings = self.settings; + + self.classes.add('menubtn'); + + if (settings.fixedWidth) { + self.classes.add('fixed-width'); + } + + self.aria('haspopup', true); + + self.state.set('menu', settings.menu || self.render()); + }, + + /** + * Shows the menu for the button. + * + * @method showMenu + */ + showMenu: function() { + var self = this, menu; + + if (self.menu && self.menu.visible()) { + return self.hideMenu(); + } + + if (!self.menu) { + menu = self.state.get('menu') || []; + + // Is menu array then auto constuct menu control + if (menu.length) { + menu = { + type: 'menu', + items: menu + }; + } else { + menu.type = menu.type || 'menu'; + } + + if (!menu.renderTo) { + self.menu = Factory.create(menu).parent(self).renderTo(); + } else { + self.menu = menu.parent(self).show().renderTo(); + } + + self.fire('createmenu'); + self.menu.reflow(); + self.menu.on('cancel', function(e) { + if (e.control.parent() === self.menu) { + e.stopPropagation(); + self.focus(); + self.hideMenu(); + } + }); + + // Move focus to button when a menu item is selected/clicked + self.menu.on('select', function() { + self.focus(); + }); + + self.menu.on('show hide', function(e) { + if (e.control == self.menu) { + self.activeMenu(e.type == 'show'); + } + + self.aria('expanded', e.type == 'show'); + }).fire('show'); + } + + self.menu.show(); + self.menu.layoutRect({w: self.layoutRect().w}); + self.menu.moveRel(self.getEl(), self.isRtl() ? ['br-tr', 'tr-br'] : ['bl-tl', 'tl-bl']); + }, + + /** + * Hides the menu for the button. + * + * @method hideMenu + */ + hideMenu: function() { + var self = this; + + if (self.menu) { + self.menu.items().each(function(item) { + if (item.hideMenu) { + item.hideMenu(); + } + }); + + self.menu.hide(); + } + }, + + /** + * Sets the active menu state. + * + * @private + */ + activeMenu: function(state) { + this.classes.toggle('active', state); + }, + + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this, id = self._id, prefix = self.classPrefix; + var icon = self.settings.icon, image, text = self.state.get('text'), + textHtml = ''; + + image = self.settings.image; + if (image) { + icon = 'none'; + + // Support for [high dpi, low dpi] image sources + if (typeof image != "string") { + image = window.getSelection ? image[0] : image[1]; + } + + image = ' style="background-image: url(\'' + image + '\')"'; + } else { + image = ''; + } + + if (text) { + self.classes.add('btn-has-text'); + textHtml = '<span class="' + prefix + 'txt">' + self.encode(text) + '</span>'; + } + + icon = self.settings.icon ? prefix + 'ico ' + prefix + 'i-' + icon : ''; + + self.aria('role', self.parent() instanceof MenuBar ? 'menuitem' : 'button'); + + return ( + '<div id="' + id + '" class="' + self.classes + '" tabindex="-1" aria-labelledby="' + id + '">' + + '<button id="' + id + '-open" role="presentation" type="button" tabindex="-1">' + + (icon ? '<i class="' + icon + '"' + image + '></i>' : '') + + textHtml + + ' <i class="' + prefix + 'caret"></i>' + + '</button>' + + '</div>' + ); + }, + + /** + * Gets invoked after the control has been rendered. + * + * @method postRender + */ + postRender: function() { + var self = this; + + self.on('click', function(e) { + if (e.control === self && isChildOf(e.target, self.getEl())) { + self.showMenu(); + + if (e.aria) { + self.menu.items()[0].focus(); + } + } + }); + + self.on('mouseenter', function(e) { + var overCtrl = e.control, parent = self.parent(), hasVisibleSiblingMenu; + + if (overCtrl && parent && overCtrl instanceof MenuButton && overCtrl.parent() == parent) { + parent.items().filter('MenuButton').each(function(ctrl) { + if (ctrl.hideMenu && ctrl != overCtrl) { + if (ctrl.menu && ctrl.menu.visible()) { + hasVisibleSiblingMenu = true; + } + + ctrl.hideMenu(); + } + }); + + if (hasVisibleSiblingMenu) { + overCtrl.focus(); // Fix for: #5887 + overCtrl.showMenu(); + } + } + }); + + return self._super(); + }, + + bindStates: function() { + var self = this; + + self.state.on('change:menu', function() { + if (self.menu) { + self.menu.remove(); + } + + self.menu = null; + }); + + return self._super(); + }, + + /** + * Removes the control and it's menus. + * + * @method remove + */ + remove: function() { + this._super(); + + if (this.menu) { + this.menu.remove(); + } + } + }); + + return MenuButton; +}); + +// Included from: js/tinymce/classes/ui/MenuItem.js + +/** + * MenuItem.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Creates a new menu item. + * + * @-x-less MenuItem.less + * @class tinymce.ui.MenuItem + * @extends tinymce.ui.Control + */ +define("tinymce/ui/MenuItem", [ + "tinymce/ui/Widget", + "tinymce/ui/Factory", + "tinymce/Env", + "tinymce/util/Delay" +], function(Widget, Factory, Env, Delay) { + "use strict"; + + return Widget.extend({ + Defaults: { + border: 0, + role: 'menuitem' + }, + + /** + * Constructs a instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + * @setting {Boolean} selectable Selectable menu. + * @setting {Array} menu Submenu array with items. + * @setting {String} shortcut Shortcut to display for menu item. Example: Ctrl+X + */ + init: function(settings) { + var self = this, text; + + self._super(settings); + + settings = self.settings; + + self.classes.add('menu-item'); + + if (settings.menu) { + self.classes.add('menu-item-expand'); + } + + if (settings.preview) { + self.classes.add('menu-item-preview'); + } + + text = self.state.get('text'); + if (text === '-' || text === '|') { + self.classes.add('menu-item-sep'); + self.aria('role', 'separator'); + self.state.set('text', '-'); + } + + if (settings.selectable) { + self.aria('role', 'menuitemcheckbox'); + self.classes.add('menu-item-checkbox'); + settings.icon = 'selected'; + } + + if (!settings.preview && !settings.selectable) { + self.classes.add('menu-item-normal'); + } + + self.on('mousedown', function(e) { + e.preventDefault(); + }); + + if (settings.menu && !settings.ariaHideMenu) { + self.aria('haspopup', true); + } + }, + + /** + * Returns true/false if the menuitem has sub menu. + * + * @method hasMenus + * @return {Boolean} True/false state if it has submenu. + */ + hasMenus: function() { + return !!this.settings.menu; + }, + + /** + * Shows the menu for the menu item. + * + * @method showMenu + */ + showMenu: function() { + var self = this, settings = self.settings, menu, parent = self.parent(); + + parent.items().each(function(ctrl) { + if (ctrl !== self) { + ctrl.hideMenu(); + } + }); + + if (settings.menu) { + menu = self.menu; + + if (!menu) { + menu = settings.menu; + + // Is menu array then auto constuct menu control + if (menu.length) { + menu = { + type: 'menu', + items: menu + }; + } else { + menu.type = menu.type || 'menu'; + } + + if (parent.settings.itemDefaults) { + menu.itemDefaults = parent.settings.itemDefaults; + } + + menu = self.menu = Factory.create(menu).parent(self).renderTo(); + menu.reflow(); + menu.on('cancel', function(e) { + e.stopPropagation(); + self.focus(); + menu.hide(); + }); + menu.on('show hide', function(e) { + e.control.items().each(function(ctrl) { + ctrl.active(ctrl.settings.selected); + }); + }).fire('show'); + + menu.on('hide', function(e) { + if (e.control === menu) { + self.classes.remove('selected'); + } + }); + + menu.submenu = true; + } else { + menu.show(); + } + + menu._parentMenu = parent; + + menu.classes.add('menu-sub'); + + var rel = menu.testMoveRel( + self.getEl(), + self.isRtl() ? ['tl-tr', 'bl-br', 'tr-tl', 'br-bl'] : ['tr-tl', 'br-bl', 'tl-tr', 'bl-br'] + ); + + menu.moveRel(self.getEl(), rel); + menu.rel = rel; + + rel = 'menu-sub-' + rel; + menu.classes.remove(menu._lastRel).add(rel); + menu._lastRel = rel; + + self.classes.add('selected'); + self.aria('expanded', true); + } + }, + + /** + * Hides the menu for the menu item. + * + * @method hideMenu + */ + hideMenu: function() { + var self = this; + + if (self.menu) { + self.menu.items().each(function(item) { + if (item.hideMenu) { + item.hideMenu(); + } + }); + + self.menu.hide(); + self.aria('expanded', false); + } + + return self; + }, + + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this, id = self._id, settings = self.settings, prefix = self.classPrefix, text = self.encode(self.state.get('text')); + var icon = self.settings.icon, image = '', shortcut = settings.shortcut; + + // Converts shortcut format to Mac/PC variants + function convertShortcut(shortcut) { + var i, value, replace = {}; + + if (Env.mac) { + replace = { + alt: '⌥', + ctrl: '⌘', + shift: '⇧', + meta: '⌘' + }; + } else { + replace = { + meta: 'Ctrl' + }; + } + + shortcut = shortcut.split('+'); + + for (i = 0; i < shortcut.length; i++) { + value = replace[shortcut[i].toLowerCase()]; + + if (value) { + shortcut[i] = value; + } + } + + return shortcut.join('+'); + } + + if (icon) { + self.parent().classes.add('menu-has-icons'); + } + + if (settings.image) { + image = ' style="background-image: url(\'' + settings.image + '\')"'; + } + + if (shortcut) { + shortcut = convertShortcut(shortcut); + } + + icon = prefix + 'ico ' + prefix + 'i-' + (self.settings.icon || 'none'); + + return ( + '<div id="' + id + '" class="' + self.classes + '" tabindex="-1">' + + (text !== '-' ? '<i class="' + icon + '"' + image + '></i>\u00a0' : '') + + (text !== '-' ? '<span id="' + id + '-text" class="' + prefix + 'text">' + text + '</span>' : '') + + (shortcut ? '<div id="' + id + '-shortcut" class="' + prefix + 'menu-shortcut">' + shortcut + '</div>' : '') + + (settings.menu ? '<div class="' + prefix + 'caret"></div>' : '') + + '</div>' + ); + }, + + /** + * Gets invoked after the control has been rendered. + * + * @method postRender + */ + postRender: function() { + var self = this, settings = self.settings; + + var textStyle = settings.textStyle; + if (typeof textStyle == "function") { + textStyle = textStyle.call(this); + } + + if (textStyle) { + var textElm = self.getEl('text'); + if (textElm) { + textElm.setAttribute('style', textStyle); + } + } + + self.on('mouseenter click', function(e) { + if (e.control === self) { + if (!settings.menu && e.type === 'click') { + self.fire('select'); + + // Edge will crash if you stress it see #2660 + Delay.requestAnimationFrame(function() { + self.parent().hideAll(); + }); + } else { + self.showMenu(); + + if (e.aria) { + self.menu.focus(true); + } + } + } + }); + + self._super(); + + return self; + }, + + hover: function() { + var self = this; + + self.parent().items().each(function(ctrl) { + ctrl.classes.remove('selected'); + }); + + self.classes.toggle('selected', true); + + return self; + }, + + active: function(state) { + if (typeof state != "undefined") { + this.aria('checked', state); + } + + return this._super(state); + }, + + /** + * Removes the control and it's menus. + * + * @method remove + */ + remove: function() { + this._super(); + + if (this.menu) { + this.menu.remove(); + } + } + }); +}); + +// Included from: js/tinymce/classes/ui/Throbber.js + +/** + * Throbber.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This class enables you to display a Throbber for any element. + * + * @-x-less Throbber.less + * @class tinymce.ui.Throbber + */ +define("tinymce/ui/Throbber", [ + "tinymce/dom/DomQuery", + "tinymce/ui/Control", + "tinymce/util/Delay" +], function($, Control, Delay) { + "use strict"; + + /** + * Constructs a new throbber. + * + * @constructor + * @param {Element} elm DOM Html element to display throbber in. + * @param {Boolean} inline Optional true/false state if the throbber should be appended to end of element for infinite scroll. + */ + return function(elm, inline) { + var self = this, state, classPrefix = Control.classPrefix, timer; + + /** + * Shows the throbber. + * + * @method show + * @param {Number} [time] Time to wait before showing. + * @param {function} [callback] Optional callback to execute when the throbber is shown. + * @return {tinymce.ui.Throbber} Current throbber instance. + */ + self.show = function(time, callback) { + function render() { + if (state) { + $(elm).append( + '<div class="' + classPrefix + 'throbber' + (inline ? ' ' + classPrefix + 'throbber-inline' : '') + '"></div>' + ); + + if (callback) { + callback(); + } + } + } + + self.hide(); + + state = true; + + if (time) { + timer = Delay.setTimeout(render, time); + } else { + render(); + } + + return self; + }; + + /** + * Hides the throbber. + * + * @method hide + * @return {tinymce.ui.Throbber} Current throbber instance. + */ + self.hide = function() { + var child = elm.lastChild; + + Delay.clearTimeout(timer); + + if (child && child.className.indexOf('throbber') != -1) { + child.parentNode.removeChild(child); + } + + state = false; + + return self; + }; + }; +}); + +// Included from: js/tinymce/classes/ui/Menu.js + +/** + * Menu.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Creates a new menu. + * + * @-x-less Menu.less + * @class tinymce.ui.Menu + * @extends tinymce.ui.FloatPanel + */ +define("tinymce/ui/Menu", [ + "tinymce/ui/FloatPanel", + "tinymce/ui/MenuItem", + "tinymce/ui/Throbber", + "tinymce/util/Tools" +], function(FloatPanel, MenuItem, Throbber, Tools) { + "use strict"; + + return FloatPanel.extend({ + Defaults: { + defaultType: 'menuitem', + border: 1, + layout: 'stack', + role: 'application', + bodyRole: 'menu', + ariaRoot: true + }, + + /** + * Constructs a instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + */ + init: function(settings) { + var self = this; + + settings.autohide = true; + settings.constrainToViewport = true; + + if (typeof settings.items === 'function') { + settings.itemsFactory = settings.items; + settings.items = []; + } + + if (settings.itemDefaults) { + var items = settings.items, i = items.length; + + while (i--) { + items[i] = Tools.extend({}, settings.itemDefaults, items[i]); + } + } + + self._super(settings); + self.classes.add('menu'); + }, + + /** + * Repaints the control after a layout operation. + * + * @method repaint + */ + repaint: function() { + this.classes.toggle('menu-align', true); + + this._super(); + + this.getEl().style.height = ''; + this.getEl('body').style.height = ''; + + return this; + }, + + /** + * Hides/closes the menu. + * + * @method cancel + */ + cancel: function() { + var self = this; + + self.hideAll(); + self.fire('select'); + }, + + /** + * Loads new items from the factory items function. + * + * @method load + */ + load: function() { + var self = this, time, factory; + + function hideThrobber() { + if (self.throbber) { + self.throbber.hide(); + self.throbber = null; + } + } + + factory = self.settings.itemsFactory; + if (!factory) { + return; + } + + if (!self.throbber) { + self.throbber = new Throbber(self.getEl('body'), true); + + if (self.items().length === 0) { + self.throbber.show(); + self.fire('loading'); + } else { + self.throbber.show(100, function() { + self.items().remove(); + self.fire('loading'); + }); + } + + self.on('hide close', hideThrobber); + } + + self.requestTime = time = new Date().getTime(); + + self.settings.itemsFactory(function(items) { + if (items.length === 0) { + self.hide(); + return; + } + + if (self.requestTime !== time) { + return; + } + + self.getEl().style.width = ''; + self.getEl('body').style.width = ''; + + hideThrobber(); + self.items().remove(); + self.getEl('body').innerHTML = ''; + + self.add(items); + self.renderNew(); + self.fire('loaded'); + }); + }, + + /** + * Hide menu and all sub menus. + * + * @method hideAll + */ + hideAll: function() { + var self = this; + + this.find('menuitem').exec('hideMenu'); + + return self._super(); + }, + + /** + * Invoked before the menu is rendered. + * + * @method preRender + */ + preRender: function() { + var self = this; + + self.items().each(function(ctrl) { + var settings = ctrl.settings; + + if (settings.icon || settings.image || settings.selectable) { + self._hasIcons = true; + return false; + } + }); + + if (self.settings.itemsFactory) { + self.on('postrender', function() { + if (self.settings.itemsFactory) { + self.load(); + } + }); + } + + return self._super(); + } + }); +}); + +// Included from: js/tinymce/classes/ui/ListBox.js + +/** + * ListBox.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Creates a new list box control. + * + * @-x-less ListBox.less + * @class tinymce.ui.ListBox + * @extends tinymce.ui.MenuButton + */ +define("tinymce/ui/ListBox", [ + "tinymce/ui/MenuButton", + "tinymce/ui/Menu" +], function(MenuButton, Menu) { + "use strict"; + + return MenuButton.extend({ + /** + * Constructs a instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + * @setting {Array} values Array with values to add to list box. + */ + init: function(settings) { + var self = this, values, selected, selectedText, lastItemCtrl; + + function setSelected(menuValues) { + // Try to find a selected value + for (var i = 0; i < menuValues.length; i++) { + selected = menuValues[i].selected || settings.value === menuValues[i].value; + + if (selected) { + selectedText = selectedText || menuValues[i].text; + self.state.set('value', menuValues[i].value); + return true; + } + + // If the value has a submenu, try to find the selected values in that menu + if (menuValues[i].menu) { + if (setSelected(menuValues[i].menu)) { + return true; + } + } + } + } + + self._super(settings); + settings = self.settings; + + self._values = values = settings.values; + if (values) { + if (typeof settings.value != "undefined") { + setSelected(values); + } + + // Default with first item + if (!selected && values.length > 0) { + selectedText = values[0].text; + self.state.set('value', values[0].value); + } + + self.state.set('menu', values); + } + + self.state.set('text', settings.text || selectedText); + + self.classes.add('listbox'); + + self.on('select', function(e) { + var ctrl = e.control; + + if (lastItemCtrl) { + e.lastControl = lastItemCtrl; + } + + if (settings.multiple) { + ctrl.active(!ctrl.active()); + } else { + self.value(e.control.value()); + } + + lastItemCtrl = ctrl; + }); + }, + + /** + * Getter/setter function for the control value. + * + * @method value + * @param {String} [value] Value to be set. + * @return {Boolean/tinymce.ui.ListBox} Value or self if it's a set operation. + */ + bindStates: function() { + var self = this; + + function activateMenuItemsByValue(menu, value) { + if (menu instanceof Menu) { + menu.items().each(function(ctrl) { + if (!ctrl.hasMenus()) { + ctrl.active(ctrl.value() === value); + } + }); + } + } + + function getSelectedItem(menuValues, value) { + var selectedItem; + + if (!menuValues) { + return; + } + + for (var i = 0; i < menuValues.length; i++) { + if (menuValues[i].value === value) { + return menuValues[i]; + } + + if (menuValues[i].menu) { + selectedItem = getSelectedItem(menuValues[i].menu, value); + if (selectedItem) { + return selectedItem; + } + } + } + } + + self.on('show', function(e) { + activateMenuItemsByValue(e.control, self.value()); + }); + + self.state.on('change:value', function(e) { + var selectedItem = getSelectedItem(self.state.get('menu'), e.value); + + if (selectedItem) { + self.text(selectedItem.text); + } else { + self.text(self.settings.text); + } + }); + + return self._super(); + } + }); +}); + +// Included from: js/tinymce/classes/ui/Radio.js + +/** + * Radio.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Creates a new radio button. + * + * @-x-less Radio.less + * @class tinymce.ui.Radio + * @extends tinymce.ui.Checkbox + */ +define("tinymce/ui/Radio", [ + "tinymce/ui/Checkbox" +], function(Checkbox) { + "use strict"; + + return Checkbox.extend({ + Defaults: { + classes: "radio", + role: "radio" + } + }); +}); + +// Included from: js/tinymce/classes/ui/ResizeHandle.js + +/** + * ResizeHandle.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Renders a resize handle that fires ResizeStart, Resize and ResizeEnd events. + * + * @-x-less ResizeHandle.less + * @class tinymce.ui.ResizeHandle + * @extends tinymce.ui.Widget + */ +define("tinymce/ui/ResizeHandle", [ + "tinymce/ui/Widget", + "tinymce/ui/DragHelper" +], function(Widget, DragHelper) { + "use strict"; + + return Widget.extend({ + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this, prefix = self.classPrefix; + + self.classes.add('resizehandle'); + + if (self.settings.direction == "both") { + self.classes.add('resizehandle-both'); + } + + self.canFocus = false; + + return ( + '<div id="' + self._id + '" class="' + self.classes + '">' + + '<i class="' + prefix + 'ico ' + prefix + 'i-resize"></i>' + + '</div>' + ); + }, + + /** + * Called after the control has been rendered. + * + * @method postRender + */ + postRender: function() { + var self = this; + + self._super(); + + self.resizeDragHelper = new DragHelper(this._id, { + start: function() { + self.fire('ResizeStart'); + }, + + drag: function(e) { + if (self.settings.direction != "both") { + e.deltaX = 0; + } + + self.fire('Resize', e); + }, + + stop: function() { + self.fire('ResizeEnd'); + } + }); + }, + + remove: function() { + if (this.resizeDragHelper) { + this.resizeDragHelper.destroy(); + } + + return this._super(); + } + }); +}); + +// Included from: js/tinymce/classes/ui/SelectBox.js + +/** + * SelectBox.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Creates a new select box control. + * + * @-x-less SelectBox.less + * @class tinymce.ui.SelectBox + * @extends tinymce.ui.Widget + */ +define("tinymce/ui/SelectBox", [ + "tinymce/ui/Widget" +], function(Widget) { + "use strict"; + + function createOptions(options) { + var strOptions = ''; + if (options) { + for (var i = 0; i < options.length; i++) { + strOptions += '<option value="' + options[i] + '">' + options[i] + '</option>'; + } + } + return strOptions; + } + + return Widget.extend({ + Defaults: { + classes: "selectbox", + role: "selectbox", + options: [] + }, + /** + * Constructs a instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + * @setting {Array} values Array with values to add to list box. + */ + init: function(settings) { + var self = this; + + self._super(settings); + + if (self.settings.size) { + self.size = self.settings.size; + } + + if (self.settings.options) { + self._options = self.settings.options; + } + + self.on('keydown', function(e) { + var rootControl; + + if (e.keyCode == 13) { + e.preventDefault(); + + // Find root control that we can do toJSON on + self.parents().reverse().each(function(ctrl) { + if (ctrl.toJSON) { + rootControl = ctrl; + return false; + } + }); + + // Fire event on current text box with the serialized data of the whole form + self.fire('submit', {data: rootControl.toJSON()}); + } + }); + }, + + /** + * Getter/setter function for the options state. + * + * @method options + * @param {Array} [state] State to be set. + * @return {Array|tinymce.ui.SelectBox} Array of string options. + */ + options: function(state) { + if (!arguments.length) { + return this.state.get('options'); + } + + this.state.set('options', state); + + return this; + }, + + renderHtml: function() { + var self = this, options, size = ''; + + options = createOptions(self._options); + + if (self.size) { + size = ' size = "' + self.size + '"'; + } + + return ( + '<select id="' + self._id + '" class="' + self.classes + '"' + size + '>' + + options + + '</select>' + ); + }, + + bindStates: function() { + var self = this; + + self.state.on('change:options', function(e) { + self.getEl().innerHTML = createOptions(e.value); + }); + + return self._super(); + } + }); +}); + +// Included from: js/tinymce/classes/ui/Slider.js + +/** + * Slider.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Slider control. + * + * @-x-less Slider.less + * @class tinymce.ui.Slider + * @extends tinymce.ui.Widget + */ +define("tinymce/ui/Slider", [ + "tinymce/ui/Widget", + "tinymce/ui/DragHelper", + "tinymce/ui/DomUtils" +], function(Widget, DragHelper, DomUtils) { + "use strict"; + + function constrain(value, minVal, maxVal) { + if (value < minVal) { + value = minVal; + } + + if (value > maxVal) { + value = maxVal; + } + + return value; + } + + function setAriaProp(el, name, value) { + el.setAttribute('aria-' + name, value); + } + + function updateSliderHandle(ctrl, value) { + var maxHandlePos, shortSizeName, sizeName, stylePosName, styleValue, handleEl; + + if (ctrl.settings.orientation == "v") { + stylePosName = "top"; + sizeName = "height"; + shortSizeName = "h"; + } else { + stylePosName = "left"; + sizeName = "width"; + shortSizeName = "w"; + } + + handleEl = ctrl.getEl('handle'); + maxHandlePos = (ctrl.layoutRect()[shortSizeName] || 100) - DomUtils.getSize(handleEl)[sizeName]; + + styleValue = (maxHandlePos * ((value - ctrl._minValue) / (ctrl._maxValue - ctrl._minValue))) + 'px'; + handleEl.style[stylePosName] = styleValue; + handleEl.style.height = ctrl.layoutRect().h + 'px'; + + setAriaProp(handleEl, 'valuenow', value); + setAriaProp(handleEl, 'valuetext', '' + ctrl.settings.previewFilter(value)); + setAriaProp(handleEl, 'valuemin', ctrl._minValue); + setAriaProp(handleEl, 'valuemax', ctrl._maxValue); + } + + return Widget.extend({ + init: function(settings) { + var self = this; + + if (!settings.previewFilter) { + settings.previewFilter = function(value) { + return Math.round(value * 100) / 100.0; + }; + } + + self._super(settings); + self.classes.add('slider'); + + if (settings.orientation == "v") { + self.classes.add('vertical'); + } + + self._minValue = settings.minValue || 0; + self._maxValue = settings.maxValue || 100; + self._initValue = self.state.get('value'); + }, + + renderHtml: function() { + var self = this, id = self._id, prefix = self.classPrefix; + + return ( + '<div id="' + id + '" class="' + self.classes + '">' + + '<div id="' + id + '-handle" class="' + prefix + 'slider-handle" role="slider" tabindex="-1"></div>' + + '</div>' + ); + }, + + reset: function() { + this.value(this._initValue).repaint(); + }, + + postRender: function() { + var self = this, minValue, maxValue, screenCordName, + stylePosName, sizeName, shortSizeName; + + function toFraction(min, max, val) { + return (val + min) / (max - min); + } + + function fromFraction(min, max, val) { + return (val * (max - min)) - min; + } + + function handleKeyboard(minValue, maxValue) { + function alter(delta) { + var value; + + value = self.value(); + value = fromFraction(minValue, maxValue, toFraction(minValue, maxValue, value) + (delta * 0.05)); + value = constrain(value, minValue, maxValue); + + self.value(value); + + self.fire('dragstart', {value: value}); + self.fire('drag', {value: value}); + self.fire('dragend', {value: value}); + } + + self.on('keydown', function(e) { + switch (e.keyCode) { + case 37: + case 38: + alter(-1); + break; + + case 39: + case 40: + alter(1); + break; + } + }); + } + + function handleDrag(minValue, maxValue, handleEl) { + var startPos, startHandlePos, maxHandlePos, handlePos, value; + + self._dragHelper = new DragHelper(self._id, { + handle: self._id + "-handle", + + start: function(e) { + startPos = e[screenCordName]; + startHandlePos = parseInt(self.getEl('handle').style[stylePosName], 10); + maxHandlePos = (self.layoutRect()[shortSizeName] || 100) - DomUtils.getSize(handleEl)[sizeName]; + self.fire('dragstart', {value: value}); + }, + + drag: function(e) { + var delta = e[screenCordName] - startPos; + + handlePos = constrain(startHandlePos + delta, 0, maxHandlePos); + handleEl.style[stylePosName] = handlePos + 'px'; + + value = minValue + (handlePos / maxHandlePos) * (maxValue - minValue); + self.value(value); + + self.tooltip().text('' + self.settings.previewFilter(value)).show().moveRel(handleEl, 'bc tc'); + + self.fire('drag', {value: value}); + }, + + stop: function() { + self.tooltip().hide(); + self.fire('dragend', {value: value}); + } + }); + } + + minValue = self._minValue; + maxValue = self._maxValue; + + if (self.settings.orientation == "v") { + screenCordName = "screenY"; + stylePosName = "top"; + sizeName = "height"; + shortSizeName = "h"; + } else { + screenCordName = "screenX"; + stylePosName = "left"; + sizeName = "width"; + shortSizeName = "w"; + } + + self._super(); + + handleKeyboard(minValue, maxValue, self.getEl('handle')); + handleDrag(minValue, maxValue, self.getEl('handle')); + }, + + repaint: function() { + this._super(); + updateSliderHandle(this, this.value()); + }, + + bindStates: function() { + var self = this; + + self.state.on('change:value', function(e) { + updateSliderHandle(self, e.value); + }); + + return self._super(); + } + }); +}); + +// Included from: js/tinymce/classes/ui/Spacer.js + +/** + * Spacer.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Creates a spacer. This control is used in flex layouts for example. + * + * @-x-less Spacer.less + * @class tinymce.ui.Spacer + * @extends tinymce.ui.Widget + */ +define("tinymce/ui/Spacer", [ + "tinymce/ui/Widget" +], function(Widget) { + "use strict"; + + return Widget.extend({ + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this; + + self.classes.add('spacer'); + self.canFocus = false; + + return '<div id="' + self._id + '" class="' + self.classes + '"></div>'; + } + }); +}); + +// Included from: js/tinymce/classes/ui/SplitButton.js + +/** + * SplitButton.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Creates a split button. + * + * @-x-less SplitButton.less + * @class tinymce.ui.SplitButton + * @extends tinymce.ui.Button + */ +define("tinymce/ui/SplitButton", [ + "tinymce/ui/MenuButton", + "tinymce/ui/DomUtils", + "tinymce/dom/DomQuery" +], function(MenuButton, DomUtils, $) { + return MenuButton.extend({ + Defaults: { + classes: "widget btn splitbtn", + role: "button" + }, + + /** + * Repaints the control after a layout operation. + * + * @method repaint + */ + repaint: function() { + var self = this, elm = self.getEl(), rect = self.layoutRect(), mainButtonElm, menuButtonElm; + + self._super(); + + mainButtonElm = elm.firstChild; + menuButtonElm = elm.lastChild; + + $(mainButtonElm).css({ + width: rect.w - DomUtils.getSize(menuButtonElm).width, + height: rect.h - 2 + }); + + $(menuButtonElm).css({ + height: rect.h - 2 + }); + + return self; + }, + + /** + * Sets the active menu state. + * + * @private + */ + activeMenu: function(state) { + var self = this; + + $(self.getEl().lastChild).toggleClass(self.classPrefix + 'active', state); + }, + + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this, id = self._id, prefix = self.classPrefix, image; + var icon = self.state.get('icon'), text = self.state.get('text'), + textHtml = ''; + + image = self.settings.image; + if (image) { + icon = 'none'; + + // Support for [high dpi, low dpi] image sources + if (typeof image != "string") { + image = window.getSelection ? image[0] : image[1]; + } + + image = ' style="background-image: url(\'' + image + '\')"'; + } else { + image = ''; + } + + icon = self.settings.icon ? prefix + 'ico ' + prefix + 'i-' + icon : ''; + + if (text) { + self.classes.add('btn-has-text'); + textHtml = '<span class="' + prefix + 'txt">' + self.encode(text) + '</span>'; + } + + return ( + '<div id="' + id + '" class="' + self.classes + '" role="button" tabindex="-1">' + + '<button type="button" hidefocus="1" tabindex="-1">' + + (icon ? '<i class="' + icon + '"' + image + '></i>' : '') + + textHtml + + '</button>' + + '<button type="button" class="' + prefix + 'open" hidefocus="1" tabindex="-1">' + + //(icon ? '<i class="' + icon + '"></i>' : '') + + (self._menuBtnText ? (icon ? '\u00a0' : '') + self._menuBtnText : '') + + ' <i class="' + prefix + 'caret"></i>' + + '</button>' + + '</div>' + ); + }, + + /** + * Called after the control has been rendered. + * + * @method postRender + */ + postRender: function() { + var self = this, onClickHandler = self.settings.onclick; + + self.on('click', function(e) { + var node = e.target; + + if (e.control == this) { + // Find clicks that is on the main button + while (node) { + if ((e.aria && e.aria.key != 'down') || (node.nodeName == 'BUTTON' && node.className.indexOf('open') == -1)) { + e.stopImmediatePropagation(); + + if (onClickHandler) { + onClickHandler.call(this, e); + } + + return; + } + + node = node.parentNode; + } + } + }); + + delete self.settings.onclick; + + return self._super(); + } + }); +}); + +// Included from: js/tinymce/classes/ui/StackLayout.js + +/** + * StackLayout.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This layout uses the browsers layout when the items are blocks. + * + * @-x-less StackLayout.less + * @class tinymce.ui.StackLayout + * @extends tinymce.ui.FlowLayout + */ +define("tinymce/ui/StackLayout", [ + "tinymce/ui/FlowLayout" +], function(FlowLayout) { + "use strict"; + + return FlowLayout.extend({ + Defaults: { + containerClass: 'stack-layout', + controlClass: 'stack-layout-item', + endClass: 'break' + }, + + isNative: function() { + return true; + } + }); +}); + +// Included from: js/tinymce/classes/ui/TabPanel.js + +/** + * TabPanel.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Creates a tab panel control. + * + * @-x-less TabPanel.less + * @class tinymce.ui.TabPanel + * @extends tinymce.ui.Panel + * + * @setting {Number} activeTab Active tab index. + */ +define("tinymce/ui/TabPanel", [ + "tinymce/ui/Panel", + "tinymce/dom/DomQuery", + "tinymce/ui/DomUtils" +], function(Panel, $, DomUtils) { + "use strict"; + + return Panel.extend({ + Defaults: { + layout: 'absolute', + defaults: { + type: 'panel' + } + }, + + /** + * Activates the specified tab by index. + * + * @method activateTab + * @param {Number} idx Index of the tab to activate. + */ + activateTab: function(idx) { + var activeTabElm; + + if (this.activeTabId) { + activeTabElm = this.getEl(this.activeTabId); + $(activeTabElm).removeClass(this.classPrefix + 'active'); + activeTabElm.setAttribute('aria-selected', "false"); + } + + this.activeTabId = 't' + idx; + + activeTabElm = this.getEl('t' + idx); + activeTabElm.setAttribute('aria-selected', "true"); + $(activeTabElm).addClass(this.classPrefix + 'active'); + + this.items()[idx].show().fire('showtab'); + this.reflow(); + + this.items().each(function(item, i) { + if (idx != i) { + item.hide(); + } + }); + }, + + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this, layout = self._layout, tabsHtml = '', prefix = self.classPrefix; + + self.preRender(); + layout.preRender(self); + + self.items().each(function(ctrl, i) { + var id = self._id + '-t' + i; + + ctrl.aria('role', 'tabpanel'); + ctrl.aria('labelledby', id); + + tabsHtml += ( + '<div id="' + id + '" class="' + prefix + 'tab" ' + + 'unselectable="on" role="tab" aria-controls="' + ctrl._id + '" aria-selected="false" tabIndex="-1">' + + self.encode(ctrl.settings.title) + + '</div>' + ); + }); + + return ( + '<div id="' + self._id + '" class="' + self.classes + '" hidefocus="1" tabindex="-1">' + + '<div id="' + self._id + '-head" class="' + prefix + 'tabs" role="tablist">' + + tabsHtml + + '</div>' + + '<div id="' + self._id + '-body" class="' + self.bodyClasses + '">' + + layout.renderHtml(self) + + '</div>' + + '</div>' + ); + }, + + /** + * Called after the control has been rendered. + * + * @method postRender + */ + postRender: function() { + var self = this; + + self._super(); + + self.settings.activeTab = self.settings.activeTab || 0; + self.activateTab(self.settings.activeTab); + + this.on('click', function(e) { + var targetParent = e.target.parentNode; + + if (e.target.parentNode.id == self._id + '-head') { + var i = targetParent.childNodes.length; + + while (i--) { + if (targetParent.childNodes[i] == e.target) { + self.activateTab(i); + } + } + } + }); + }, + + /** + * Initializes the current controls layout rect. + * This will be executed by the layout managers to determine the + * default minWidth/minHeight etc. + * + * @method initLayoutRect + * @return {Object} Layout rect instance. + */ + initLayoutRect: function() { + var self = this, rect, minW, minH; + + minW = DomUtils.getSize(self.getEl('head')).width; + minW = minW < 0 ? 0 : minW; + minH = 0; + + self.items().each(function(item) { + minW = Math.max(minW, item.layoutRect().minW); + minH = Math.max(minH, item.layoutRect().minH); + }); + + self.items().each(function(ctrl) { + ctrl.settings.x = 0; + ctrl.settings.y = 0; + ctrl.settings.w = minW; + ctrl.settings.h = minH; + + ctrl.layoutRect({ + x: 0, + y: 0, + w: minW, + h: minH + }); + }); + + var headH = DomUtils.getSize(self.getEl('head')).height; + + self.settings.minWidth = minW; + self.settings.minHeight = minH + headH; + + rect = self._super(); + rect.deltaH += headH; + rect.innerH = rect.h - rect.deltaH; + + return rect; + } + }); +}); + +// Included from: js/tinymce/classes/ui/TextBox.js + +/** + * TextBox.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * Creates a new textbox. + * + * @-x-less TextBox.less + * @class tinymce.ui.TextBox + * @extends tinymce.ui.Widget + */ +define("tinymce/ui/TextBox", [ + "tinymce/ui/Widget", + "tinymce/util/Tools", + "tinymce/ui/DomUtils" +], function(Widget, Tools, DomUtils) { + return Widget.extend({ + /** + * Constructs a instance with the specified settings. + * + * @constructor + * @param {Object} settings Name/value object with settings. + * @setting {Boolean} multiline True if the textbox is a multiline control. + * @setting {Number} maxLength Max length for the textbox. + * @setting {Number} size Size of the textbox in characters. + */ + init: function(settings) { + var self = this; + + self._super(settings); + + self.classes.add('textbox'); + + if (settings.multiline) { + self.classes.add('multiline'); + } else { + self.on('keydown', function(e) { + var rootControl; + + if (e.keyCode == 13) { + e.preventDefault(); + + // Find root control that we can do toJSON on + self.parents().reverse().each(function(ctrl) { + if (ctrl.toJSON) { + rootControl = ctrl; + return false; + } + }); + + // Fire event on current text box with the serialized data of the whole form + self.fire('submit', {data: rootControl.toJSON()}); + } + }); + + self.on('keyup', function(e) { + self.state.set('value', e.target.value); + }); + } + }, + + /** + * Repaints the control after a layout operation. + * + * @method repaint + */ + repaint: function() { + var self = this, style, rect, borderBox, borderW, borderH = 0, lastRepaintRect; + + style = self.getEl().style; + rect = self._layoutRect; + lastRepaintRect = self._lastRepaintRect || {}; + + // Detect old IE 7+8 add lineHeight to align caret vertically in the middle + var doc = document; + if (!self.settings.multiline && doc.all && (!doc.documentMode || doc.documentMode <= 8)) { + style.lineHeight = (rect.h - borderH) + 'px'; + } + + borderBox = self.borderBox; + borderW = borderBox.left + borderBox.right + 8; + borderH = borderBox.top + borderBox.bottom + (self.settings.multiline ? 8 : 0); + + if (rect.x !== lastRepaintRect.x) { + style.left = rect.x + 'px'; + lastRepaintRect.x = rect.x; + } + + if (rect.y !== lastRepaintRect.y) { + style.top = rect.y + 'px'; + lastRepaintRect.y = rect.y; + } + + if (rect.w !== lastRepaintRect.w) { + style.width = (rect.w - borderW) + 'px'; + lastRepaintRect.w = rect.w; + } + + if (rect.h !== lastRepaintRect.h) { + style.height = (rect.h - borderH) + 'px'; + lastRepaintRect.h = rect.h; + } + + self._lastRepaintRect = lastRepaintRect; + self.fire('repaint', {}, false); + + return self; + }, + + /** + * Renders the control as a HTML string. + * + * @method renderHtml + * @return {String} HTML representing the control. + */ + renderHtml: function() { + var self = this, settings = self.settings, attrs, elm; + + attrs = { + id: self._id, + hidefocus: '1' + }; + + Tools.each([ + 'rows', 'spellcheck', 'maxLength', 'size', 'readonly', 'min', + 'max', 'step', 'list', 'pattern', 'placeholder', 'required', 'multiple' + ], function(name) { + attrs[name] = settings[name]; + }); + + if (self.disabled()) { + attrs.disabled = 'disabled'; + } + + if (settings.subtype) { + attrs.type = settings.subtype; + } + + elm = DomUtils.create(settings.multiline ? 'textarea' : 'input', attrs); + elm.value = self.state.get('value'); + elm.className = self.classes; + + return elm.outerHTML; + }, + + value: function(value) { + if (arguments.length) { + this.state.set('value', value); + return this; + } + + // Make sure the real state is in sync + if (this.state.get('rendered')) { + this.state.set('value', this.getEl().value); + } + + return this.state.get('value'); + }, + + /** + * Called after the control has been rendered. + * + * @method postRender + */ + postRender: function() { + var self = this; + + self.getEl().value = self.state.get('value'); + self._super(); + + self.$el.on('change', function(e) { + self.state.set('value', e.target.value); + self.fire('change', e); + }); + }, + + bindStates: function() { + var self = this; + + self.state.on('change:value', function(e) { + if (self.getEl().value != e.value) { + self.getEl().value = e.value; + } + }); + + self.state.on('change:disabled', function(e) { + self.getEl().disabled = e.value; + }); + + return self._super(); + }, + + remove: function() { + this.$el.off(); + this._super(); + } + }); +}); + +// Included from: js/tinymce/classes/Register.js + +/** + * Register.js + * + * Released under LGPL License. + * Copyright (c) 1999-2015 Ephox Corp. All rights reserved + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/** + * This registers tinymce in common module loaders. + * + * @private + * @class tinymce.Register + */ +define("tinymce/Register", [ +], function() { + /*eslint consistent-this: 0 */ + var context = this || window; + + var tinymce = function() { + return context.tinymce; + }; + + if (typeof context.define === "function") { + // Bolt + if (!context.define.amd) { + context.define("ephox/tinymce", [], tinymce); + } + } + + return {}; +}); + +expose(["tinymce/geom/Rect","tinymce/util/Promise","tinymce/util/Delay","tinymce/Env","tinymce/dom/EventUtils","tinymce/dom/Sizzle","tinymce/util/Tools","tinymce/dom/DomQuery","tinymce/html/Styles","tinymce/dom/TreeWalker","tinymce/html/Entities","tinymce/dom/DOMUtils","tinymce/dom/ScriptLoader","tinymce/AddOnManager","tinymce/dom/RangeUtils","tinymce/html/Node","tinymce/html/Schema","tinymce/html/SaxParser","tinymce/html/DomParser","tinymce/html/Writer","tinymce/html/Serializer","tinymce/dom/Serializer","tinymce/util/VK","tinymce/dom/ControlSelection","tinymce/dom/BookmarkManager","tinymce/dom/Selection","tinymce/Formatter","tinymce/UndoManager","tinymce/EditorCommands","tinymce/util/URI","tinymce/util/Class","tinymce/util/EventDispatcher","tinymce/util/Observable","tinymce/ui/Selector","tinymce/ui/Collection","tinymce/ui/ReflowQueue","tinymce/ui/Control","tinymce/ui/Factory","tinymce/ui/KeyboardNavigation","tinymce/ui/Container","tinymce/ui/DragHelper","tinymce/ui/Scrollable","tinymce/ui/Panel","tinymce/ui/Movable","tinymce/ui/Resizable","tinymce/ui/FloatPanel","tinymce/ui/Window","tinymce/ui/MessageBox","tinymce/WindowManager","tinymce/ui/Tooltip","tinymce/ui/Widget","tinymce/ui/Progress","tinymce/ui/Notification","tinymce/NotificationManager","tinymce/EditorObservable","tinymce/Shortcuts","tinymce/Editor","tinymce/util/I18n","tinymce/FocusManager","tinymce/EditorManager","tinymce/util/XHR","tinymce/util/JSON","tinymce/util/JSONRequest","tinymce/util/JSONP","tinymce/util/LocalStorage","tinymce/Compat","tinymce/ui/Layout","tinymce/ui/AbsoluteLayout","tinymce/ui/Button","tinymce/ui/ButtonGroup","tinymce/ui/Checkbox","tinymce/ui/ComboBox","tinymce/ui/ColorBox","tinymce/ui/PanelButton","tinymce/ui/ColorButton","tinymce/util/Color","tinymce/ui/ColorPicker","tinymce/ui/Path","tinymce/ui/ElementPath","tinymce/ui/FormItem","tinymce/ui/Form","tinymce/ui/FieldSet","tinymce/ui/FilePicker","tinymce/ui/FitLayout","tinymce/ui/FlexLayout","tinymce/ui/FlowLayout","tinymce/ui/FormatControls","tinymce/ui/GridLayout","tinymce/ui/Iframe","tinymce/ui/InfoBox","tinymce/ui/Label","tinymce/ui/Toolbar","tinymce/ui/MenuBar","tinymce/ui/MenuButton","tinymce/ui/MenuItem","tinymce/ui/Throbber","tinymce/ui/Menu","tinymce/ui/ListBox","tinymce/ui/Radio","tinymce/ui/ResizeHandle","tinymce/ui/SelectBox","tinymce/ui/Slider","tinymce/ui/Spacer","tinymce/ui/SplitButton","tinymce/ui/StackLayout","tinymce/ui/TabPanel","tinymce/ui/TextBox"]); +})(this); +!function(a){function b(){function b(a){"remove"===a&&this.each(function(a,b){var c=e(b);c&&c.remove()}),this.find("span.mceEditor,div.mceEditor").each(function(a,b){var c=tinymce.get(b.id.replace(/_parent$/,""));c&&c.remove()})}function d(a){var c,d=this;if(null!=a)b.call(d),d.each(function(b,c){var d;(d=tinymce.get(c.id))&&d.setContent(a)});else if(d.length>0&&(c=tinymce.get(d[0].id)))return c.getContent()}function e(a){var b=null;return a&&a.id&&g.tinymce&&(b=tinymce.get(a.id)),b}function f(a){return!!(a&&a.length&&g.tinymce&&a.is(":tinymce"))}var h={};a.each(["text","html","val"],function(b,g){var i=h[g]=a.fn[g],j="text"===g;a.fn[g]=function(b){var g=this;if(!f(g))return i.apply(g,arguments);if(b!==c)return d.call(g.filter(":tinymce"),b),i.apply(g.not(":tinymce"),arguments),g;var h="",k=arguments;return(j?g:g.eq(0)).each(function(b,c){var d=e(c);h+=d?j?d.getContent().replace(/<(?:"[^"]*"|'[^']*'|[^'">])*>/g,""):d.getContent({save:!0}):i.apply(a(c),k)}),h}}),a.each(["append","prepend"],function(b,d){var g=h[d]=a.fn[d],i="prepend"===d;a.fn[d]=function(a){var b=this;return f(b)?a!==c?("string"==typeof a&&b.filter(":tinymce").each(function(b,c){var d=e(c);d&&d.setContent(i?a+d.getContent():d.getContent()+a)}),g.apply(b.not(":tinymce"),arguments),b):void 0:g.apply(b,arguments)}}),a.each(["remove","replaceWith","replaceAll","empty"],function(c,d){var e=h[d]=a.fn[d];a.fn[d]=function(){return b.call(this,d),e.apply(this,arguments)}}),h.attr=a.fn.attr,a.fn.attr=function(b,g){var i=this,j=arguments;if(!b||"value"!==b||!f(i))return g!==c?h.attr.apply(i,j):h.attr.apply(i,j);if(g!==c)return d.call(i.filter(":tinymce"),g),h.attr.apply(i.not(":tinymce"),j),i;var k=i[0],l=e(k);return l?l.getContent({save:!0}):h.attr.apply(a(k),j)}}var c,d,e,f=[],g=window;a.fn.tinymce=function(c){function h(){var d=[],f=0;e||(b(),e=!0),l.each(function(a,b){var e,g=b.id,h=c.oninit;g||(b.id=g=tinymce.DOM.uniqueId()),tinymce.get(g)||(e=new tinymce.Editor(g,c,tinymce.EditorManager),d.push(e),e.on("init",function(){var a,b=h;l.css("visibility",""),h&&++f==d.length&&("string"==typeof b&&(a=-1===b.indexOf(".")?null:tinymce.resolve(b.replace(/\.\w+$/,"")),b=tinymce.resolve(b)),b.apply(a||tinymce,d))}))}),a.each(d,function(a,b){b.render()})}var i,j,k,l=this,m="";if(!l.length)return l;if(!c)return window.tinymce?tinymce.get(l[0].id):null;if(l.css("visibility","hidden"),g.tinymce||d||!(i=c.script_url))1===d?f.push(h):h();else{d=1,j=i.substring(0,i.lastIndexOf("/")),-1!=i.indexOf(".min")&&(m=".min"),g.tinymce=g.tinyMCEPreInit||{base:j,suffix:m},-1!=i.indexOf("gzip")&&(k=c.language||"en",i=i+(/\?/.test(i)?"&":"?")+"js=true&core=true&suffix="+escape(m)+"&themes="+escape(c.theme||"modern")+"&plugins="+escape(c.plugins||"")+"&languages="+(k||""),g.tinyMCE_GZ||(g.tinyMCE_GZ={start:function(){function b(a){tinymce.ScriptLoader.markDone(tinymce.baseURI.toAbsolute(a))}b("langs/"+k+".js"),b("themes/"+c.theme+"/theme"+m+".js"),b("themes/"+c.theme+"/langs/"+k+".js"),a.each(c.plugins.split(","),function(a,c){c&&(b("plugins/"+c+"/plugin"+m+".js"),b("plugins/"+c+"/langs/"+k+".js"))})},end:function(){}}));var n=document.createElement("script");n.type="text/javascript",n.onload=n.onreadystatechange=function(b){b=b||window.event,2===d||"load"!=b.type&&!/complete|loaded/.test(n.readyState)||(tinymce.dom.Event.domLoaded=1,d=2,c.script_loaded&&c.script_loaded(),h(),a.each(f,function(a,b){b()}))},n.src=i,document.body.appendChild(n)}return l},a.extend(a.expr[":"],{tinymce:function(a){var b;return!!(a.id&&"tinymce"in window&&(b=tinymce.get(a.id),b&&b.editorManager===tinymce))}})}(jQuery); + + + +/*! + * Modernizr v2.7.1 + * www.modernizr.com + * + * Copyright (c) Faruk Ates, Paul Irish, Alex Sexton + * Available under the BSD and MIT licenses: www.modernizr.com/license/ + */ + +/* + * Modernizr tests which native CSS3 and HTML5 features are available in + * the current UA and makes the results available to you in two ways: + * as properties on a global Modernizr object, and as classes on the + * <html> element. This information allows you to progressively enhance + * your pages with a granular level of control over the experience. + * + * Modernizr has an optional (not included) conditional resource loader + * called Modernizr.load(), based on Yepnope.js (yepnopejs.com). + * To get a build that includes Modernizr.load(), as well as choosing + * which tests to include, go to www.modernizr.com/download/ + * + * Authors Faruk Ates, Paul Irish, Alex Sexton + * Contributors Ryan Seddon, Ben Alman + */ + + +window.Modernizr = (function( window, document, undefined ) { + + var version = '2.7.1', + + Modernizr = {}, + + /*>>cssclasses*/ + // option for enabling the HTML classes to be added + enableClasses = true, + /*>>cssclasses*/ + + docElement = document.documentElement, + + /** + * Create our "modernizr" element that we do most feature tests on. + */ + mod = 'modernizr', + modElem = document.createElement(mod), + mStyle = modElem.style, + + /** + * Create the input element for various Web Forms feature tests. + */ + inputElem /*>>inputelem*/ = document.createElement('input') /*>>inputelem*/ , + + /*>>smile*/ + smile = ':)', + /*>>smile*/ + + toString = {}.toString, + + // TODO :: make the prefixes more granular + /*>>prefixes*/ + // List of property values to set for css tests. See ticket #21 + prefixes = ' -webkit- -moz- -o- -ms- '.split(' '), + /*>>prefixes*/ + + /*>>domprefixes*/ + // Following spec is to expose vendor-specific style properties as: + // elem.style.WebkitBorderRadius + // and the following would be incorrect: + // elem.style.webkitBorderRadius + + // Webkit ghosts their properties in lowercase but Opera & Moz do not. + // Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+ + // erik.eae.net/archives/2008/03/10/21.48.10/ + + // More here: github.com/Modernizr/Modernizr/issues/issue/21 + omPrefixes = 'Webkit Moz O ms', + + cssomPrefixes = omPrefixes.split(' '), + + domPrefixes = omPrefixes.toLowerCase().split(' '), + /*>>domprefixes*/ + + /*>>ns*/ + ns = {'svg': 'http://www.w3.org/2000/svg'}, + /*>>ns*/ + + tests = {}, + inputs = {}, + attrs = {}, + + classes = [], + + slice = classes.slice, + + featureName, // used in testing loop + + + /*>>teststyles*/ + // Inject element with style element and some CSS rules + injectElementWithStyles = function( rule, callback, nodes, testnames ) { + + var style, ret, node, docOverflow, + div = document.createElement('div'), + // After page load injecting a fake body doesn't work so check if body exists + body = document.body, + // IE6 and 7 won't return offsetWidth or offsetHeight unless it's in the body element, so we fake it. + fakeBody = body || document.createElement('body'); + + if ( parseInt(nodes, 10) ) { + // In order not to give false positives we create a node for each test + // This also allows the method to scale for unspecified uses + while ( nodes-- ) { + node = document.createElement('div'); + node.id = testnames ? testnames[nodes] : mod + (nodes + 1); + div.appendChild(node); + } + } + + // <style> elements in IE6-9 are considered 'NoScope' elements and therefore will be removed + // when injected with innerHTML. To get around this you need to prepend the 'NoScope' element + // with a 'scoped' element, in our case the soft-hyphen entity as it won't mess with our measurements. + // msdn.microsoft.com/en-us/library/ms533897%28VS.85%29.aspx + // Documents served as xml will throw if using ­ so use xml friendly encoded version. See issue #277 + style = ['­','<style id="s', mod, '">', rule, '</style>'].join(''); + div.id = mod; + // IE6 will false positive on some tests due to the style element inside the test div somehow interfering offsetHeight, so insert it into body or fakebody. + // Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270 + (body ? div : fakeBody).innerHTML += style; + fakeBody.appendChild(div); + if ( !body ) { + //avoid crashing IE8, if background image is used + fakeBody.style.background = ''; + //Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible + fakeBody.style.overflow = 'hidden'; + docOverflow = docElement.style.overflow; + docElement.style.overflow = 'hidden'; + docElement.appendChild(fakeBody); + } + + ret = callback(div, rule); + // If this is done after page load we don't want to remove the body so check if body exists + if ( !body ) { + fakeBody.parentNode.removeChild(fakeBody); + docElement.style.overflow = docOverflow; + } else { + div.parentNode.removeChild(div); + } + + return !!ret; + + }, + /*>>teststyles*/ + + /*>>mq*/ + // adapted from matchMedia polyfill + // by Scott Jehl and Paul Irish + // gist.github.com/786768 + testMediaQuery = function( mq ) { + + var matchMedia = window.matchMedia || window.msMatchMedia; + if ( matchMedia ) { + return matchMedia(mq).matches; + } + + var bool; + + injectElementWithStyles('@media ' + mq + ' { #' + mod + ' { position: absolute; } }', function( node ) { + bool = (window.getComputedStyle ? + getComputedStyle(node, null) : + node.currentStyle)['position'] == 'absolute'; + }); + + return bool; + + }, + /*>>mq*/ + + + /*>>hasevent*/ + // + // isEventSupported determines if a given element supports the given event + // kangax.github.com/iseventsupported/ + // + // The following results are known incorrects: + // Modernizr.hasEvent("webkitTransitionEnd", elem) // false negative + // Modernizr.hasEvent("textInput") // in Webkit. github.com/Modernizr/Modernizr/issues/333 + // ... + isEventSupported = (function() { + + var TAGNAMES = { + 'select': 'input', 'change': 'input', + 'submit': 'form', 'reset': 'form', + 'error': 'img', 'load': 'img', 'abort': 'img' + }; + + function isEventSupported( eventName, element ) { + + element = element || document.createElement(TAGNAMES[eventName] || 'div'); + eventName = 'on' + eventName; + + // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those + var isSupported = eventName in element; + + if ( !isSupported ) { + // If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element + if ( !element.setAttribute ) { + element = document.createElement('div'); + } + if ( element.setAttribute && element.removeAttribute ) { + element.setAttribute(eventName, ''); + isSupported = is(element[eventName], 'function'); + + // If property was created, "remove it" (by setting value to `undefined`) + if ( !is(element[eventName], 'undefined') ) { + element[eventName] = undefined; + } + element.removeAttribute(eventName); + } + } + + element = null; + return isSupported; + } + return isEventSupported; + })(), + /*>>hasevent*/ + + // TODO :: Add flag for hasownprop ? didn't last time + + // hasOwnProperty shim by kangax needed for Safari 2.0 support + _hasOwnProperty = ({}).hasOwnProperty, hasOwnProp; + + if ( !is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined') ) { + hasOwnProp = function (object, property) { + return _hasOwnProperty.call(object, property); + }; + } + else { + hasOwnProp = function (object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */ + return ((property in object) && is(object.constructor.prototype[property], 'undefined')); + }; + } + + // Adapted from ES5-shim https://github.com/kriskowal/es5-shim/blob/master/es5-shim.js + // es5.github.com/#x15.3.4.5 + + if (!Function.prototype.bind) { + Function.prototype.bind = function bind(that) { + + var target = this; + + if (typeof target != "function") { + throw new TypeError(); + } + + var args = slice.call(arguments, 1), + bound = function () { + + if (this instanceof bound) { + + var F = function(){}; + F.prototype = target.prototype; + var self = new F(); + + var result = target.apply( + self, + args.concat(slice.call(arguments)) + ); + if (Object(result) === result) { + return result; + } + return self; + + } else { + + return target.apply( + that, + args.concat(slice.call(arguments)) + ); + + } + + }; + + return bound; + }; + } + + /** + * setCss applies given styles to the Modernizr DOM node. + */ + function setCss( str ) { + mStyle.cssText = str; + } + + /** + * setCssAll extrapolates all vendor-specific css strings. + */ + function setCssAll( str1, str2 ) { + return setCss(prefixes.join(str1 + ';') + ( str2 || '' )); + } + + /** + * is returns a boolean for if typeof obj is exactly type. + */ + function is( obj, type ) { + return typeof obj === type; + } + + /** + * contains returns a boolean for if substr is found within str. + */ + function contains( str, substr ) { + return !!~('' + str).indexOf(substr); + } + + /*>>testprop*/ + + // testProps is a generic CSS / DOM property test. + + // In testing support for a given CSS property, it's legit to test: + // `elem.style[styleName] !== undefined` + // If the property is supported it will return an empty string, + // if unsupported it will return undefined. + + // We'll take advantage of this quick test and skip setting a style + // on our modernizr element, but instead just testing undefined vs + // empty string. + + // Because the testing of the CSS property names (with "-", as + // opposed to the camelCase DOM properties) is non-portable and + // non-standard but works in WebKit and IE (but not Gecko or Opera), + // we explicitly reject properties with dashes so that authors + // developing in WebKit or IE first don't end up with + // browser-specific content by accident. + + function testProps( props, prefixed ) { + for ( var i in props ) { + var prop = props[i]; + if ( !contains(prop, "-") && mStyle[prop] !== undefined ) { + return prefixed == 'pfx' ? prop : true; + } + } + return false; + } + /*>>testprop*/ + + // TODO :: add testDOMProps + /** + * testDOMProps is a generic DOM property test; if a browser supports + * a certain property, it won't return undefined for it. + */ + function testDOMProps( props, obj, elem ) { + for ( var i in props ) { + var item = obj[props[i]]; + if ( item !== undefined) { + + // return the property name as a string + if (elem === false) return props[i]; + + // let's bind a function + if (is(item, 'function')){ + // default to autobind unless override + return item.bind(elem || obj); + } + + // return the unbound function or obj or value + return item; + } + } + return false; + } + + /*>>testallprops*/ + /** + * testPropsAll tests a list of DOM properties we want to check against. + * We specify literally ALL possible (known and/or likely) properties on + * the element including the non-vendor prefixed one, for forward- + * compatibility. + */ + function testPropsAll( prop, prefixed, elem ) { + + var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1), + props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' '); + + // did they call .prefixed('boxSizing') or are we just testing a prop? + if(is(prefixed, "string") || is(prefixed, "undefined")) { + return testProps(props, prefixed); + + // otherwise, they called .prefixed('requestAnimationFrame', window[, elem]) + } else { + props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' '); + return testDOMProps(props, prefixed, elem); + } + } + /*>>testallprops*/ + + + /** + * Tests + * ----- + */ + + // The *new* flexbox + // dev.w3.org/csswg/css3-flexbox + + tests['flexbox'] = function() { + return testPropsAll('flexWrap'); + }; + + // The *old* flexbox + // www.w3.org/TR/2009/WD-css3-flexbox-20090723/ + + tests['flexboxlegacy'] = function() { + return testPropsAll('boxDirection'); + }; + + // On the S60 and BB Storm, getContext exists, but always returns undefined + // so we actually have to call getContext() to verify + // github.com/Modernizr/Modernizr/issues/issue/97/ + + tests['canvas'] = function() { + var elem = document.createElement('canvas'); + return !!(elem.getContext && elem.getContext('2d')); + }; + + tests['canvastext'] = function() { + return !!(Modernizr['canvas'] && is(document.createElement('canvas').getContext('2d').fillText, 'function')); + }; + + // webk.it/70117 is tracking a legit WebGL feature detect proposal + + // We do a soft detect which may false positive in order to avoid + // an expensive context creation: bugzil.la/732441 + + tests['webgl'] = function() { + return !!window.WebGLRenderingContext; + }; + + /* + * The Modernizr.touch test only indicates if the browser supports + * touch events, which does not necessarily reflect a touchscreen + * device, as evidenced by tablets running Windows 7 or, alas, + * the Palm Pre / WebOS (touch) phones. + * + * Additionally, Chrome (desktop) used to lie about its support on this, + * but that has since been rectified: crbug.com/36415 + * + * We also test for Firefox 4 Multitouch Support. + * + * For more info, see: modernizr.github.com/Modernizr/touch.html + */ + + tests['touch'] = function() { + var bool; + + if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) { + bool = true; + } else { + injectElementWithStyles(['@media (',prefixes.join('touch-enabled),('),mod,')','{#modernizr{top:9px;position:absolute}}'].join(''), function( node ) { + bool = node.offsetTop === 9; + }); + } + + return bool; + }; + + + // geolocation is often considered a trivial feature detect... + // Turns out, it's quite tricky to get right: + // + // Using !!navigator.geolocation does two things we don't want. It: + // 1. Leaks memory in IE9: github.com/Modernizr/Modernizr/issues/513 + // 2. Disables page caching in WebKit: webk.it/43956 + // + // Meanwhile, in Firefox < 8, an about:config setting could expose + // a false positive that would throw an exception: bugzil.la/688158 + + tests['geolocation'] = function() { + return 'geolocation' in navigator; + }; + + + tests['postmessage'] = function() { + return !!window.postMessage; + }; + + + // Chrome incognito mode used to throw an exception when using openDatabase + // It doesn't anymore. + tests['websqldatabase'] = function() { + return !!window.openDatabase; + }; + + // Vendors had inconsistent prefixing with the experimental Indexed DB: + // - Webkit's implementation is accessible through webkitIndexedDB + // - Firefox shipped moz_indexedDB before FF4b9, but since then has been mozIndexedDB + // For speed, we don't test the legacy (and beta-only) indexedDB + tests['indexedDB'] = function() { + return !!testPropsAll("indexedDB", window); + }; + + // documentMode logic from YUI to filter out IE8 Compat Mode + // which false positives. + tests['hashchange'] = function() { + return isEventSupported('hashchange', window) && (document.documentMode === undefined || document.documentMode > 7); + }; + + // Per 1.6: + // This used to be Modernizr.historymanagement but the longer + // name has been deprecated in favor of a shorter and property-matching one. + // The old API is still available in 1.6, but as of 2.0 will throw a warning, + // and in the first release thereafter disappear entirely. + tests['history'] = function() { + return !!(window.history && history.pushState); + }; + + tests['draganddrop'] = function() { + var div = document.createElement('div'); + return ('draggable' in div) || ('ondragstart' in div && 'ondrop' in div); + }; + + // FF3.6 was EOL'ed on 4/24/12, but the ESR version of FF10 + // will be supported until FF19 (2/12/13), at which time, ESR becomes FF17. + // FF10 still uses prefixes, so check for it until then. + // for more ESR info, see: mozilla.org/en-US/firefox/organizations/faq/ + tests['websockets'] = function() { + return 'WebSocket' in window || 'MozWebSocket' in window; + }; + + + // css-tricks.com/rgba-browser-support/ + tests['rgba'] = function() { + // Set an rgba() color and check the returned value + + setCss('background-color:rgba(150,255,150,.5)'); + + return contains(mStyle.backgroundColor, 'rgba'); + }; + + tests['hsla'] = function() { + // Same as rgba(), in fact, browsers re-map hsla() to rgba() internally, + // except IE9 who retains it as hsla + + setCss('background-color:hsla(120,40%,100%,.5)'); + + return contains(mStyle.backgroundColor, 'rgba') || contains(mStyle.backgroundColor, 'hsla'); + }; + + tests['multiplebgs'] = function() { + // Setting multiple images AND a color on the background shorthand property + // and then querying the style.background property value for the number of + // occurrences of "url(" is a reliable method for detecting ACTUAL support for this! + + setCss('background:url(https://),url(https://),red url(https://)'); + + // If the UA supports multiple backgrounds, there should be three occurrences + // of the string "url(" in the return value for elemStyle.background + + return (/(url\s*\(.*?){3}/).test(mStyle.background); + }; + + + + // this will false positive in Opera Mini + // github.com/Modernizr/Modernizr/issues/396 + + tests['backgroundsize'] = function() { + return testPropsAll('backgroundSize'); + }; + + tests['borderimage'] = function() { + return testPropsAll('borderImage'); + }; + + + // Super comprehensive table about all the unique implementations of + // border-radius: muddledramblings.com/table-of-css3-border-radius-compliance + + tests['borderradius'] = function() { + return testPropsAll('borderRadius'); + }; + + // WebOS unfortunately false positives on this test. + tests['boxshadow'] = function() { + return testPropsAll('boxShadow'); + }; + + // FF3.0 will false positive on this test + tests['textshadow'] = function() { + return document.createElement('div').style.textShadow === ''; + }; + + + tests['opacity'] = function() { + // Browsers that actually have CSS Opacity implemented have done so + // according to spec, which means their return values are within the + // range of [0.0,1.0] - including the leading zero. + + setCssAll('opacity:.55'); + + // The non-literal . in this regex is intentional: + // German Chrome returns this value as 0,55 + // github.com/Modernizr/Modernizr/issues/#issue/59/comment/516632 + return (/^0.55$/).test(mStyle.opacity); + }; + + + // Note, Android < 4 will pass this test, but can only animate + // a single property at a time + // daneden.me/2011/12/putting-up-with-androids-bullshit/ + tests['cssanimations'] = function() { + return testPropsAll('animationName'); + }; + + + tests['csscolumns'] = function() { + return testPropsAll('columnCount'); + }; + + + tests['cssgradients'] = function() { + /** + * For CSS Gradients syntax, please see: + * webkit.org/blog/175/introducing-css-gradients/ + * developer.mozilla.org/en/CSS/-moz-linear-gradient + * developer.mozilla.org/en/CSS/-moz-radial-gradient + * dev.w3.org/csswg/css3-images/#gradients- + */ + + var str1 = 'background-image:', + str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));', + str3 = 'linear-gradient(left top,#9f9, white);'; + + setCss( + // legacy webkit syntax (FIXME: remove when syntax not in use anymore) + (str1 + '-webkit- '.split(' ').join(str2 + str1) + + // standard syntax // trailing 'background-image:' + prefixes.join(str3 + str1)).slice(0, -str1.length) + ); + + return contains(mStyle.backgroundImage, 'gradient'); + }; + + + tests['cssreflections'] = function() { + return testPropsAll('boxReflect'); + }; + + + tests['csstransforms'] = function() { + return !!testPropsAll('transform'); + }; + + + tests['csstransforms3d'] = function() { + + var ret = !!testPropsAll('perspective'); + + // Webkit's 3D transforms are passed off to the browser's own graphics renderer. + // It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in + // some conditions. As a result, Webkit typically recognizes the syntax but + // will sometimes throw a false positive, thus we must do a more thorough check: + if ( ret && 'webkitPerspective' in docElement.style ) { + + // Webkit allows this media query to succeed only if the feature is enabled. + // `@media (transform-3d),(-webkit-transform-3d){ ... }` + injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}', function( node, rule ) { + ret = node.offsetLeft === 9 && node.offsetHeight === 3; + }); + } + return ret; + }; + + + tests['csstransitions'] = function() { + return testPropsAll('transition'); + }; + + + /*>>fontface*/ + // @font-face detection routine by Diego Perini + // javascript.nwbox.com/CSSSupport/ + + // false positives: + // WebOS github.com/Modernizr/Modernizr/issues/342 + // WP7 github.com/Modernizr/Modernizr/issues/538 + tests['fontface'] = function() { + var bool; + + injectElementWithStyles('@font-face {font-family:"font";src:url("https://")}', function( node, rule ) { + var style = document.getElementById('smodernizr'), + sheet = style.sheet || style.styleSheet, + cssText = sheet ? (sheet.cssRules && sheet.cssRules[0] ? sheet.cssRules[0].cssText : sheet.cssText || '') : ''; + + bool = /src/i.test(cssText) && cssText.indexOf(rule.split(' ')[0]) === 0; + }); + + return bool; + }; + /*>>fontface*/ + + // CSS generated content detection + tests['generatedcontent'] = function() { + var bool; + + injectElementWithStyles(['#',mod,'{font:0/0 a}#',mod,':after{content:"',smile,'";visibility:hidden;font:3px/1 a}'].join(''), function( node ) { + bool = node.offsetHeight >= 3; + }); + + return bool; + }; + + + + // These tests evaluate support of the video/audio elements, as well as + // testing what types of content they support. + // + // We're using the Boolean constructor here, so that we can extend the value + // e.g. Modernizr.video // true + // Modernizr.video.ogg // 'probably' + // + // Codec values from : github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845 + // thx to NielsLeenheer and zcorpan + + // Note: in some older browsers, "no" was a return value instead of empty string. + // It was live in FF3.5.0 and 3.5.1, but fixed in 3.5.2 + // It was also live in Safari 4.0.0 - 4.0.4, but fixed in 4.0.5 + + tests['video'] = function() { + var elem = document.createElement('video'), + bool = false; + + // IE9 Running on Windows Server SKU can cause an exception to be thrown, bug #224 + try { + if ( bool = !!elem.canPlayType ) { + bool = new Boolean(bool); + bool.ogg = elem.canPlayType('video/ogg; codecs="theora"') .replace(/^no$/,''); + + // Without QuickTime, this value will be `undefined`. github.com/Modernizr/Modernizr/issues/546 + bool.h264 = elem.canPlayType('video/mp4; codecs="avc1.42E01E"') .replace(/^no$/,''); + + bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,''); + } + + } catch(e) { } + + return bool; + }; + + tests['audio'] = function() { + var elem = document.createElement('audio'), + bool = false; + + try { + if ( bool = !!elem.canPlayType ) { + bool = new Boolean(bool); + bool.ogg = elem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,''); + bool.mp3 = elem.canPlayType('audio/mpeg;') .replace(/^no$/,''); + + // Mimetypes accepted: + // developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements + // bit.ly/iphoneoscodecs + bool.wav = elem.canPlayType('audio/wav; codecs="1"') .replace(/^no$/,''); + bool.m4a = ( elem.canPlayType('audio/x-m4a;') || + elem.canPlayType('audio/aac;')) .replace(/^no$/,''); + } + } catch(e) { } + + return bool; + }; + + + // In FF4, if disabled, window.localStorage should === null. + + // Normally, we could not test that directly and need to do a + // `('localStorage' in window) && ` test first because otherwise Firefox will + // throw bugzil.la/365772 if cookies are disabled + + // Also in iOS5 Private Browsing mode, attempting to use localStorage.setItem + // will throw the exception: + // QUOTA_EXCEEDED_ERRROR DOM Exception 22. + // Peculiarly, getItem and removeItem calls do not throw. + + // Because we are forced to try/catch this, we'll go aggressive. + + // Just FWIW: IE8 Compat mode supports these features completely: + // www.quirksmode.org/dom/html5.html + // But IE8 doesn't support either with local files + + tests['localstorage'] = function() { + try { + localStorage.setItem(mod, mod); + localStorage.removeItem(mod); + return true; + } catch(e) { + return false; + } + }; + + tests['sessionstorage'] = function() { + try { + sessionStorage.setItem(mod, mod); + sessionStorage.removeItem(mod); + return true; + } catch(e) { + return false; + } + }; + + + tests['webworkers'] = function() { + return !!window.Worker; + }; + + + tests['applicationcache'] = function() { + return !!window.applicationCache; + }; + + + // Thanks to Erik Dahlstrom + tests['svg'] = function() { + return !!document.createElementNS && !!document.createElementNS(ns.svg, 'svg').createSVGRect; + }; + + // specifically for SVG inline in HTML, not within XHTML + // test page: paulirish.com/demo/inline-svg + tests['inlinesvg'] = function() { + var div = document.createElement('div'); + div.innerHTML = '<svg/>'; + return (div.firstChild && div.firstChild.namespaceURI) == ns.svg; + }; + + // SVG SMIL animation + tests['smil'] = function() { + return !!document.createElementNS && /SVGAnimate/.test(toString.call(document.createElementNS(ns.svg, 'animate'))); + }; + + // This test is only for clip paths in SVG proper, not clip paths on HTML content + // demo: srufaculty.sru.edu/david.dailey/svg/newstuff/clipPath4.svg + + // However read the comments to dig into applying SVG clippaths to HTML content here: + // github.com/Modernizr/Modernizr/issues/213#issuecomment-1149491 + tests['svgclippaths'] = function() { + return !!document.createElementNS && /SVGClipPath/.test(toString.call(document.createElementNS(ns.svg, 'clipPath'))); + }; + + /*>>webforms*/ + // input features and input types go directly onto the ret object, bypassing the tests loop. + // Hold this guy to execute in a moment. + function webforms() { + /*>>input*/ + // Run through HTML5's new input attributes to see if the UA understands any. + // We're using f which is the <input> element created early on + // Mike Taylr has created a comprehensive resource for testing these attributes + // when applied to all input types: + // miketaylr.com/code/input-type-attr.html + // spec: www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary + + // Only input placeholder is tested while textarea's placeholder is not. + // Currently Safari 4 and Opera 11 have support only for the input placeholder + // Both tests are available in feature-detects/forms-placeholder.js + Modernizr['input'] = (function( props ) { + for ( var i = 0, len = props.length; i < len; i++ ) { + attrs[ props[i] ] = !!(props[i] in inputElem); + } + if (attrs.list){ + // safari false positive's on datalist: webk.it/74252 + // see also github.com/Modernizr/Modernizr/issues/146 + attrs.list = !!(document.createElement('datalist') && window.HTMLDataListElement); + } + return attrs; + })('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' ')); + /*>>input*/ + + /*>>inputtypes*/ + // Run through HTML5's new input types to see if the UA understands any. + // This is put behind the tests runloop because it doesn't return a + // true/false like all the other tests; instead, it returns an object + // containing each input type with its corresponding true/false value + + // Big thanks to @miketaylr for the html5 forms expertise. miketaylr.com/ + Modernizr['inputtypes'] = (function(props) { + + for ( var i = 0, bool, inputElemType, defaultView, len = props.length; i < len; i++ ) { + + inputElem.setAttribute('type', inputElemType = props[i]); + bool = inputElem.type !== 'text'; + + // We first check to see if the type we give it sticks.. + // If the type does, we feed it a textual value, which shouldn't be valid. + // If the value doesn't stick, we know there's input sanitization which infers a custom UI + if ( bool ) { + + inputElem.value = smile; + inputElem.style.cssText = 'position:absolute;visibility:hidden;'; + + if ( /^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined ) { + + docElement.appendChild(inputElem); + defaultView = document.defaultView; + + // Safari 2-4 allows the smiley as a value, despite making a slider + bool = defaultView.getComputedStyle && + defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' && + // Mobile android web browser has false positive, so must + // check the height to see if the widget is actually there. + (inputElem.offsetHeight !== 0); + + docElement.removeChild(inputElem); + + } else if ( /^(search|tel)$/.test(inputElemType) ){ + // Spec doesn't define any special parsing or detectable UI + // behaviors so we pass these through as true + + // Interestingly, opera fails the earlier test, so it doesn't + // even make it here. + + } else if ( /^(url|email)$/.test(inputElemType) ) { + // Real url and email support comes with prebaked validation. + bool = inputElem.checkValidity && inputElem.checkValidity() === false; + + } else { + // If the upgraded input compontent rejects the :) text, we got a winner + bool = inputElem.value != smile; + } + } + + inputs[ props[i] ] = !!bool; + } + return inputs; + })('search tel url email datetime date month week time datetime-local number range color'.split(' ')); + /*>>inputtypes*/ + } + /*>>webforms*/ + + + // End of test definitions + // ----------------------- + + + + // Run through all tests and detect their support in the current UA. + // todo: hypothetically we could be doing an array of tests and use a basic loop here. + for ( var feature in tests ) { + if ( hasOwnProp(tests, feature) ) { + // run the test, throw the return value into the Modernizr, + // then based on that boolean, define an appropriate className + // and push it into an array of classes we'll join later. + featureName = feature.toLowerCase(); + Modernizr[featureName] = tests[feature](); + + classes.push((Modernizr[featureName] ? '' : 'no-') + featureName); + } + } + + /*>>webforms*/ + // input tests need to run. + Modernizr.input || webforms(); + /*>>webforms*/ + + + /** + * addTest allows the user to define their own feature tests + * the result will be added onto the Modernizr object, + * as well as an appropriate className set on the html element + * + * @param feature - String naming the feature + * @param test - Function returning true if feature is supported, false if not + */ + Modernizr.addTest = function ( feature, test ) { + if ( typeof feature == 'object' ) { + for ( var key in feature ) { + if ( hasOwnProp( feature, key ) ) { + Modernizr.addTest( key, feature[ key ] ); + } + } + } else { + + feature = feature.toLowerCase(); + + if ( Modernizr[feature] !== undefined ) { + // we're going to quit if you're trying to overwrite an existing test + // if we were to allow it, we'd do this: + // var re = new RegExp("\\b(no-)?" + feature + "\\b"); + // docElement.className = docElement.className.replace( re, '' ); + // but, no rly, stuff 'em. + return Modernizr; + } + + test = typeof test == 'function' ? test() : test; + + if (typeof enableClasses !== "undefined" && enableClasses) { + docElement.className += ' ' + (test ? '' : 'no-') + feature; + } + Modernizr[feature] = test; + + } + + return Modernizr; // allow chaining. + }; + + + // Reset modElem.cssText to nothing to reduce memory footprint. + setCss(''); + modElem = inputElem = null; + + /*>>shiv*/ + /** + * @preserve HTML5 Shiv prev3.7.1 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed + */ + ;(function(window, document) { + /*jshint evil:true */ + /** version */ + var version = '3.7.0'; + + /** Preset options */ + var options = window.html5 || {}; + + /** Used to skip problem elements */ + var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i; + + /** Not all elements can be cloned in IE **/ + var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i; + + /** Detect whether the browser supports default html5 styles */ + var supportsHtml5Styles; + + /** Name of the expando, to work with multiple documents or to re-shiv one document */ + var expando = '_html5shiv'; + + /** The id for the the documents expando */ + var expanID = 0; + + /** Cached data for each document */ + var expandoData = {}; + + /** Detect whether the browser supports unknown elements */ + var supportsUnknownElements; + + (function() { + try { + var a = document.createElement('a'); + a.innerHTML = '<xyz></xyz>'; + //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles + supportsHtml5Styles = ('hidden' in a); + + supportsUnknownElements = a.childNodes.length == 1 || (function() { + // assign a false positive if unable to shiv + (document.createElement)('a'); + var frag = document.createDocumentFragment(); + return ( + typeof frag.cloneNode == 'undefined' || + typeof frag.createDocumentFragment == 'undefined' || + typeof frag.createElement == 'undefined' + ); + }()); + } catch(e) { + // assign a false positive if detection fails => unable to shiv + supportsHtml5Styles = true; + supportsUnknownElements = true; + } + + }()); + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a style sheet with the given CSS text and adds it to the document. + * @private + * @param {Document} ownerDocument The document. + * @param {String} cssText The CSS text. + * @returns {StyleSheet} The style element. + */ + function addStyleSheet(ownerDocument, cssText) { + var p = ownerDocument.createElement('p'), + parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement; + + p.innerHTML = 'x<style>' + cssText + '</style>'; + return parent.insertBefore(p.lastChild, parent.firstChild); + } + + /** + * Returns the value of `html5.elements` as an array. + * @private + * @returns {Array} An array of shived element node names. + */ + function getElements() { + var elements = html5.elements; + return typeof elements == 'string' ? elements.split(' ') : elements; + } + + /** + * Returns the data associated to the given document + * @private + * @param {Document} ownerDocument The document. + * @returns {Object} An object of data. + */ + function getExpandoData(ownerDocument) { + var data = expandoData[ownerDocument[expando]]; + if (!data) { + data = {}; + expanID++; + ownerDocument[expando] = expanID; + expandoData[expanID] = data; + } + return data; + } + + /** + * returns a shived element for the given nodeName and document + * @memberOf html5 + * @param {String} nodeName name of the element + * @param {Document} ownerDocument The context document. + * @returns {Object} The shived element. + */ + function createElement(nodeName, ownerDocument, data){ + if (!ownerDocument) { + ownerDocument = document; + } + if(supportsUnknownElements){ + return ownerDocument.createElement(nodeName); + } + if (!data) { + data = getExpandoData(ownerDocument); + } + var node; + + if (data.cache[nodeName]) { + node = data.cache[nodeName].cloneNode(); + } else if (saveClones.test(nodeName)) { + node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode(); + } else { + node = data.createElem(nodeName); + } + + // Avoid adding some elements to fragments in IE < 9 because + // * Attributes like `name` or `type` cannot be set/changed once an element + // is inserted into a document/fragment + // * Link elements with `src` attributes that are inaccessible, as with + // a 403 response, will cause the tab/window to crash + // * Script elements appended to fragments will execute when their `src` + // or `text` property is set + return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node; + } + + /** + * returns a shived DocumentFragment for the given document + * @memberOf html5 + * @param {Document} ownerDocument The context document. + * @returns {Object} The shived DocumentFragment. + */ + function createDocumentFragment(ownerDocument, data){ + if (!ownerDocument) { + ownerDocument = document; + } + if(supportsUnknownElements){ + return ownerDocument.createDocumentFragment(); + } + data = data || getExpandoData(ownerDocument); + var clone = data.frag.cloneNode(), + i = 0, + elems = getElements(), + l = elems.length; + for(;i<l;i++){ + clone.createElement(elems[i]); + } + return clone; + } + + /** + * Shivs the `createElement` and `createDocumentFragment` methods of the document. + * @private + * @param {Document|DocumentFragment} ownerDocument The document. + * @param {Object} data of the document. + */ + function shivMethods(ownerDocument, data) { + if (!data.cache) { + data.cache = {}; + data.createElem = ownerDocument.createElement; + data.createFrag = ownerDocument.createDocumentFragment; + data.frag = data.createFrag(); + } + + + ownerDocument.createElement = function(nodeName) { + //abort shiv + if (!html5.shivMethods) { + return data.createElem(nodeName); + } + return createElement(nodeName, ownerDocument, data); + }; + + ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' + + 'var n=f.cloneNode(),c=n.createElement;' + + 'h.shivMethods&&(' + + // unroll the `createElement` calls + getElements().join().replace(/[\w\-]+/g, function(nodeName) { + data.createElem(nodeName); + data.frag.createElement(nodeName); + return 'c("' + nodeName + '")'; + }) + + ');return n}' + )(html5, data.frag); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Shivs the given document. + * @memberOf html5 + * @param {Document} ownerDocument The document to shiv. + * @returns {Document} The shived document. + */ + function shivDocument(ownerDocument) { + if (!ownerDocument) { + ownerDocument = document; + } + var data = getExpandoData(ownerDocument); + + if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) { + data.hasCSS = !!addStyleSheet(ownerDocument, + // corrects block display not defined in IE6/7/8/9 + 'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' + + // adds styling not present in IE6/7/8/9 + 'mark{background:#FF0;color:#000}' + + // hides non-rendered elements + 'template{display:none}' + ); + } + if (!supportsUnknownElements) { + shivMethods(ownerDocument, data); + } + return ownerDocument; + } + + /*--------------------------------------------------------------------------*/ + + /** + * The `html5` object is exposed so that more elements can be shived and + * existing shiving can be detected on iframes. + * @type Object + * @example + * + * // options can be changed before the script is included + * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false }; + */ + var html5 = { + + /** + * An array or space separated string of node names of the elements to shiv. + * @memberOf html5 + * @type Array|String + */ + 'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video', + + /** + * current version of html5shiv + */ + 'version': version, + + /** + * A flag to indicate that the HTML5 style sheet should be inserted. + * @memberOf html5 + * @type Boolean + */ + 'shivCSS': (options.shivCSS !== false), + + /** + * Is equal to true if a browser supports creating unknown/HTML5 elements + * @memberOf html5 + * @type boolean + */ + 'supportsUnknownElements': supportsUnknownElements, + + /** + * A flag to indicate that the document's `createElement` and `createDocumentFragment` + * methods should be overwritten. + * @memberOf html5 + * @type Boolean + */ + 'shivMethods': (options.shivMethods !== false), + + /** + * A string to describe the type of `html5` object ("default" or "default print"). + * @memberOf html5 + * @type String + */ + 'type': 'default', + + // shivs the document according to the specified `html5` object options + 'shivDocument': shivDocument, + + //creates a shived element + createElement: createElement, + + //creates a shived documentFragment + createDocumentFragment: createDocumentFragment + }; + + /*--------------------------------------------------------------------------*/ + + // expose html5 + window.html5 = html5; + + // shiv the document + shivDocument(document); + + }(this, document)); + /*>>shiv*/ + + // Assign private properties to the return object with prefix + Modernizr._version = version; + + // expose these for the plugin API. Look in the source for how to join() them against your input + /*>>prefixes*/ + Modernizr._prefixes = prefixes; + /*>>prefixes*/ + /*>>domprefixes*/ + Modernizr._domPrefixes = domPrefixes; + Modernizr._cssomPrefixes = cssomPrefixes; + /*>>domprefixes*/ + + /*>>mq*/ + // Modernizr.mq tests a given media query, live against the current state of the window + // A few important notes: + // * If a browser does not support media queries at all (eg. oldIE) the mq() will always return false + // * A max-width or orientation query will be evaluated against the current state, which may change later. + // * You must specify values. Eg. If you are testing support for the min-width media query use: + // Modernizr.mq('(min-width:0)') + // usage: + // Modernizr.mq('only screen and (max-width:768)') + Modernizr.mq = testMediaQuery; + /*>>mq*/ + + /*>>hasevent*/ + // Modernizr.hasEvent() detects support for a given event, with an optional element to test on + // Modernizr.hasEvent('gesturestart', elem) + Modernizr.hasEvent = isEventSupported; + /*>>hasevent*/ + + /*>>testprop*/ + // Modernizr.testProp() investigates whether a given style property is recognized + // Note that the property names must be provided in the camelCase variant. + // Modernizr.testProp('pointerEvents') + Modernizr.testProp = function(prop){ + return testProps([prop]); + }; + /*>>testprop*/ + + /*>>testallprops*/ + // Modernizr.testAllProps() investigates whether a given style property, + // or any of its vendor-prefixed variants, is recognized + // Note that the property names must be provided in the camelCase variant. + // Modernizr.testAllProps('boxSizing') + Modernizr.testAllProps = testPropsAll; + /*>>testallprops*/ + + + /*>>teststyles*/ + // Modernizr.testStyles() allows you to add custom styles to the document and test an element afterwards + // Modernizr.testStyles('#modernizr { position:absolute }', function(elem, rule){ ... }) + Modernizr.testStyles = injectElementWithStyles; + /*>>teststyles*/ + + + /*>>prefixed*/ + // Modernizr.prefixed() returns the prefixed or nonprefixed property name variant of your input + // Modernizr.prefixed('boxSizing') // 'MozBoxSizing' + + // Properties must be passed as dom-style camelcase, rather than `box-sizing` hypentated style. + // Return values will also be the camelCase variant, if you need to translate that to hypenated style use: + // + // str.replace(/([A-Z])/g, function(str,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-'); + + // If you're trying to ascertain which transition end event to bind to, you might do something like... + // + // var transEndEventNames = { + // 'WebkitTransition' : 'webkitTransitionEnd', + // 'MozTransition' : 'transitionend', + // 'OTransition' : 'oTransitionEnd', + // 'msTransition' : 'MSTransitionEnd', + // 'transition' : 'transitionend' + // }, + // transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ]; + + Modernizr.prefixed = function(prop, obj, elem){ + if(!obj) { + return testPropsAll(prop, 'pfx'); + } else { + // Testing DOM property e.g. Modernizr.prefixed('requestAnimationFrame', window) // 'mozRequestAnimationFrame' + return testPropsAll(prop, obj, elem); + } + }; + /*>>prefixed*/ + + + /*>>cssclasses*/ + // Remove "no-js" class from <html> element, if it exists: + docElement.className = docElement.className.replace(/(^|\s)no-js(\s|$)/, '$1$2') + + + // Add the new classes to the <html> element. + (enableClasses ? ' js ' + classes.join(' ') : ''); + /*>>cssclasses*/ + + return Modernizr; + +})(this, this.document); +!function(a){var b=function(){window.asyncWebshims||(window.asyncWebshims={cfg:[],ready:[]})},c=function(){window.jQuery&&(a(jQuery),a=function(){return window.webshims})};window.webshims={setOptions:function(){b(),window.asyncWebshims.cfg.push(arguments)},ready:function(){b(),window.asyncWebshims.ready.push(arguments)},activeLang:function(a){b(),window.asyncWebshims.lang=a},polyfill:function(a){b(),window.asyncWebshims.polyfill=a},_curScript:function(){var a,b,c,d,e,f=document.currentScript;if(!f){try{throw new Error("")}catch(g){for(c=(g.sourceURL||g.stack||"").split("\n"),e=/(?:fil|htt|wid|abo|app|res)(.)+/i,b=0;b<c.length;b++)if(d=c[b].match(e)){c=d[0].replace(/[\:\s\(]+[\d\:\)\(\s]+$/,"");break}}for(a=document.scripts||document.getElementsByTagName("script"),b=0;b<a.length&&(!a[b].getAttribute("src")||(f=a[b],"interactive"!=a[b].readyState&&c!=a[b].src));b++);}return f}()},window.webshim=window.webshims,window.webshims.timer=setInterval(c,0),c(),"function"==typeof define&&define.amd&&define("polyfiller",["jquery"],a)}(function(a){"use strict";function b(a){return document.createElement(a)}var c,d,e=window.navigator,f=window.webshims,g="dom-support",h=a.event.special,i=a([]),j=window.asyncWebshims,k={},l=window.Object,m=function(a){return a+"\n//# sourceURL="+this.url},n=function(a){return q.enhanceAuto||"auto"!=a?a:!1},o={matchmedia:"matchMedia",xhr2:"filereader",promise:"es6",URL:"url"},p="capture"in b("input");clearInterval(f.timer),k.advancedObjectProperties=k.objectAccessor=k.ES5=!!("create"in l&&"seal"in l),!k.ES5||"toJSON"in Date.prototype||(k.ES5=!1),d=a.support.hrefNormalized===!1?f._curScript.getAttribute("src",4):f._curScript.src,d=d.split("?")[0].slice(0,d.lastIndexOf("/")+1)+"shims/",a.extend(f,{version:"1.15.10",cfg:{enhanceAuto:window.Audio&&(!window.matchMedia||matchMedia("(min-device-width: 721px)").matches),waitReady:!0,loadStyles:!0,wsdoc:document,wspopover:{appendTo:"auto",hideOnBlur:!0},ajax:{crossDomain:!0},loadScript:function(b,c){a.ajax(a.extend({},q.ajax,{url:b,success:c,dataType:"script",cache:!0,global:!1,dataFilter:m}))},basePath:d},support:k,bugs:{},modules:{},features:{},featureList:[],setOptions:function(b,c){"string"==typeof b&&arguments.length>1?q[b]=a.isPlainObject(c)?a.extend(!0,q[b]||{},c):c:"object"==typeof b&&a.extend(!0,q,b)},_getAutoEnhance:n,addPolyfill:function(b,c){c=c||{};var d=c.f||b;r[d]||(r[d]=[],f.featureList.push(d),q[d]={}),r[d].push(b),c.options=a.extend(q[d],c.options),y(b,c),c.methodNames&&a.each(c.methodNames,function(a,b){f.addMethodName(b)})},polyfill:function(){return function(a){a||(a=f.featureList),"string"==typeof a&&(a=a.split(" "));return f._polyfill(a)}}(),_polyfill:function(b){var d,e,f=[];c.run||(d=-1!==a.inArray("forms-ext",b),c(),e=d&&!v["form-number-date-ui"].test()||!p&&-1!==a.inArray("mediacapture",b),d&&-1==a.inArray("forms",b)&&b.push("forms"),q.loadStyles&&w.loadCSS("styles/shim"+(e?"-ext":"")+".css")),q.waitReady&&(a.readyWait++,t(b,function(){a.ready(!0)})),a.each(b,function(a,b){return b=o[b]||b,r[b]?(b!==r[b][0]&&t(r[b],function(){s(b,!0)}),void(f=f.concat(r[b]))):void s(b,!0)}),x(f),a.each(b,function(a,b){var c=q[b];c&&("mediaelement"==b&&(c.replaceUI=n(c.replaceUI))&&c.plugins.unshift("mediacontrols"),c.plugins&&c.plugins.length&&x(q[b].plugins))})},reTest:function(){var b,c=function(c,d){var e=v[d],f=d+"Ready";!e||e.loaded||(e.test&&a.isFunction(e.test)?e.test([]):e.test)||(h[f]&&delete h[f],r[e.f],b.push(d))};return function(d){"string"==typeof d&&(d=d.split(" ")),b=[],a.each(d,c),x(b)}}(),isReady:function(b,c){if(b+="Ready",c){if(h[b]&&h[b].add)return!0;h[b]=a.extend(h[b]||{},{add:function(a){a.handler.call(this,b)}}),a(document).triggerHandler(b)}return!(!h[b]||!h[b].add)||!1},ready:function(b,c){var d=arguments[2];if("string"==typeof b&&(b=b.split(" ")),d||(b=a.map(a.grep(b,function(a){return!s(a)}),function(a){return a+"Ready"})),!b.length)return void c(a,f,window,document);var e=b.shift(),g=function(){t(b,c,!0)};a(document).one(e,g)},capturingEvents:function(b,c){document.addEventListener&&("string"==typeof b&&(b=[b]),a.each(b,function(b,d){var e=function(b){return b=a.event.fix(b),c&&f.capturingEventPrevented&&f.capturingEventPrevented(b),a.event.dispatch.call(this,b)};h[d]=h[d]||{},h[d].setup||h[d].teardown||a.extend(h[d],{setup:function(){this.addEventListener(d,e,!0)},teardown:function(){this.removeEventListener(d,e,!0)}})}))},register:function(b,c){var d=v[b];if(!d)return void f.error("can't find module: "+b);d.loaded=!0;var e=function(){c(a,f,window,document,void 0,d.options),s(b,!0)};d.d&&d.d.length?t(d.d,e):e()},c:{},loader:{addModule:function(b,c){v[b]=c,c.name=c.name||b,c.c||(c.c=[]),a.each(c.c,function(a,c){f.c[c]||(f.c[c]=[]),f.c[c].push(b)})},loadList:function(){var b=[],c=function(c,d){"string"==typeof d&&(d=[d]),a.merge(b,d),w.loadScript(c,!1,d)},d=function(c,d){if(s(c)||-1!=a.inArray(c,b))return!0;var e,f=v[c];return f?(e=f.test&&a.isFunction(f.test)?f.test(d):f.test,e?(s(c,!0),!0):!1):!0},e=function(b,c){if(b.d&&b.d.length){var e=function(b,e){d(e,c)||-1!=a.inArray(e,c)||c.push(e)};a.each(b.d,function(b,c){v[c]?v[c].loaded||e(b,c):r[c]&&(a.each(r[c],e),t(r[c],function(){s(c,!0)}))}),b.noAutoCallback||(b.noAutoCallback=!0)}};return function(g){var h,i,j,k,l=[],m=function(d,e){return k=e,a.each(f.c[e],function(c,d){return-1==a.inArray(d,l)||-1!=a.inArray(d,b)?(k=!1,!1):void 0}),k?(c("combos/"+k,f.c[k]),!1):void 0};for(i=0;i<g.length;i++)h=v[g[i]],h&&!d(h.name,g)&&(h.css&&q.loadStyles&&w.loadCSS(h.css),h.loadInit&&h.loadInit(),e(h,g),h.loaded||l.push(h.name),h.loaded=!0);for(i=0,j=l.length;j>i;i++)k=!1,h=l[i],-1==a.inArray(h,b)&&("noCombo"!=q.debug&&a.each(v[h].c,m),k||c(v[h].src||h,h))}}(),makePath:function(a){return-1!=a.indexOf("//")||0===a.indexOf("/")?a:(-1==a.indexOf(".")&&(a+=".js"),q.addCacheBuster&&(a+=q.addCacheBuster),q.basePath+a)},loadCSS:function(){var b,c={};return function(d){d=this.makePath(d),c[d]||(b=b||a("link, style")[0]||a("script")[0],c[d]=1,a('<link rel="stylesheet" />').insertBefore(b).attr({href:d}))}}(),loadScript:function(){var b={};return function(c,d,e,f){if(f||(c=w.makePath(c)),!b[c]){var g=function(){d&&d(),e&&("string"==typeof e&&(e=e.split(" ")),a.each(e,function(a,b){v[b]&&(v[b].afterLoad&&v[b].afterLoad(),s(v[b].noAutoCallback?b+"FileLoaded":b,!0))}))};b[c]=1,q.loadScript(c,g,a.noop)}}}()}});var q=f.cfg,r=f.features,s=f.isReady,t=f.ready,u=f.addPolyfill,v=f.modules,w=f.loader,x=w.loadList,y=w.addModule,z=f.bugs,A=[],B={warn:1,error:1},C=a.fn,D=b("video");f.addMethodName=function(a){a=a.split(":");var b=a[1];1==a.length?(b=a[0],a=a[0]):a=a[0],C[a]=function(){return this.callProp(b,arguments)}},C.callProp=function(b,c){var d;return c||(c=[]),this.each(function(){var e=a.prop(this,b);if(e&&e.apply){if(d=e.apply(this,c),void 0!==d)return!1}else f.warn(b+" is not a method of "+this)}),void 0!==d?d:this},f.activeLang=function(){"language"in e||(e.language=e.browserLanguage||"");var b=a.attr(document.documentElement,"lang")||e.language;return t("webshimLocalization",function(){f.activeLang(b)}),function(a){if(a)if("string"==typeof a)b=a;else if("object"==typeof a){var c=arguments,d=this;t("webshimLocalization",function(){f.activeLang.apply(d,c)})}return b}}(),f.errorLog=[],a.each(["log","error","warn","info"],function(a,b){f[b]=function(a){(B[b]&&q.debug!==!1||q.debug)&&(f.errorLog.push(a),window.console&&console.log&&console[console[b]?b:"log"](a))}}),function(){a.isDOMReady=a.isReady;var b=function(){a.isDOMReady=!0,s("DOM",!0),setTimeout(function(){s("WINDOWLOAD",!0)},9999)};c=function(){if(!c.run){if(!a.isDOMReady&&q.waitReady){var d=a.ready;a.ready=function(a){return a!==!0&&document.body&&b(),d.apply(this,arguments)},a.ready.promise=d.promise}q.readyEvt?a(document).one(q.readyEvt,b):a(b)}c.run=!0},a(window).on("load",function(){b(),setTimeout(function(){s("WINDOWLOAD",!0)},9)});var d=[],e=function(){1==this.nodeType&&f.triggerDomUpdate(this)};a.extend(f,{addReady:function(a){var b=function(b,c){f.ready("DOM",function(){a(b,c)})};d.push(b),q.wsdoc&&b(q.wsdoc,i)},triggerDomUpdate:function(b){if(!b||!b.nodeType)return void(b&&b.jquery&&b.each(function(){f.triggerDomUpdate(this)}));var c=b.nodeType;if(1==c||9==c){var e=b!==document?a(b):i;a.each(d,function(a,c){c(b,e)})}}}),C.clonePolyfill=C.clone,C.htmlPolyfill=function(b){if(!arguments.length)return a(this.clonePolyfill()).html();var c=C.html.call(this,b);return c===this&&a.isDOMReady&&this.each(e),c},C.jProp=function(){return this.pushStack(a(C.prop.apply(this,arguments)||[]))},a.each(["after","before","append","prepend","replaceWith"],function(b,c){C[c+"Polyfill"]=function(b){return b=a(b),C[c].call(this,b),a.isDOMReady&&b.each(e),this}}),a.each(["insertAfter","insertBefore","appendTo","prependTo","replaceAll"],function(b,c){C[c.replace(/[A-Z]/,function(a){return"Polyfill"+a})]=function(){return C[c].apply(this,arguments),a.isDOMReady&&f.triggerDomUpdate(this),this}}),C.updatePolyfill=function(){return a.isDOMReady&&f.triggerDomUpdate(this),this},a.each(["getNativeElement","getShadowElement","getShadowFocusElement"],function(a,b){C[b]=function(){return this.pushStack(this)}})}(),l.create&&(f.objectCreate=function(b,c,d){var e=l.create(b);return d&&(e.options=a.extend(!0,{},e.options||{},d),d=e.options),e._create&&a.isFunction(e._create)&&e._create(d),e}),y("swfmini",{test:function(){return window.swfobject&&!window.swfmini&&(window.swfmini=window.swfobject),"swfmini"in window},c:[16,7,2,8,1,12,23]}),v.swfmini.test(),y("sizzle",{test:a.expr.filters}),u("es5",{test:!(!k.ES5||!Function.prototype.bind),d:["sizzle"]}),u("dom-extend",{f:g,noAutoCallback:!0,d:["es5"],c:[16,7,2,15,30,3,8,4,9,10,25,31,34]}),b("picture"),u("picture",{test:"picturefill"in window||!!window.HTMLPictureElement||"respimage"in window,d:["matchMedia"],c:[18],loadInit:function(){s("picture",!0)}}),u("matchMedia",{test:!(!window.matchMedia||!matchMedia("all").addListener),c:[18]}),u("sticky",{test:-1!=(a(b("b")).attr("style","position: -webkit-sticky; position: sticky").css("position")||"").indexOf("sticky"),d:["es5","matchMedia"]}),u("es6",{test:!!(Math.imul&&Number.MIN_SAFE_INTEGER&&l.is&&window.Promise&&Promise.all),d:["es5"]}),u("geolocation",{test:"geolocation"in e,options:{destroyWrite:!0},c:[21]}),function(){u("canvas",{src:"excanvas",test:"getContext"in b("canvas"),options:{type:"flash"},noAutoCallback:!0,loadInit:function(){var a=this.options.type;!a||-1===a.indexOf("flash")||v.swfmini.test()&&!swfmini.hasFlashPlayerVersion("9.0.0")||(this.src="flash"==a?"FlashCanvas/flashcanvas":"FlashCanvasPro/flashcanvas")},methodNames:["getContext"],d:[g]})}();var E="getUserMedia"in e;u("usermedia-core",{f:"usermedia",test:E&&window.URL,d:["url",g]}),u("usermedia-shim",{f:"usermedia",test:!!(E||e.webkitGetUserMedia||e.mozGetUserMedia||e.msGetUserMedia),d:["url","mediaelement",g]}),u("mediacapture",{test:p,d:["swfmini","usermedia",g,"filereader","forms","canvas"]}),function(){var c,d,h="form-shim-extend",i="formvalidation",j="form-number-date-api",l=!1,m=!1,o=!1,p={},r=b("progress"),s=b("output"),t=function(){var d,f,g="1(",j=b("input");if(f=a('<fieldset><textarea required="" /></fieldset>')[0],k.inputtypes=p,a.each(["range","date","datetime-local","month","color","number"],function(a,b){j.setAttribute("type",b),p[b]=j.type==b&&(j.value=g)&&j.value!=g}),k.datalist=!!("options"in b("datalist")&&window.HTMLDataListElement),k[i]="checkValidity"in j,k.fieldsetelements="elements"in f,k.fieldsetdisabled="disabled"in f){try{f.querySelector(":invalid")&&(f.disabled=!0,d=!f.querySelector(":invalid")&&f.querySelector(":disabled"))}catch(n){}k.fieldsetdisabled=!!d}if(k[i]&&(m=!(k.fieldsetdisabled&&k.fieldsetelements&&"value"in r&&"value"in s),o=m&&/Android/i.test(e.userAgent),l=window.opera||z.bustedValidity||m||!k.datalist,!l&&p.number)){l=!0;try{j.type="number",j.value="",j.stepUp(),l="1"!=j.value}catch(q){}}return z.bustedValidity=l,c=k[i]&&!l?"form-native-extend":h,t=a.noop,!1},w=function(b){var c=!0;return b._types||(b._types=b.types.split(" ")),a.each(b._types,function(a,b){return b in p&&!p[b]?(c=!1,!1):void 0}),c};f.validationMessages=f.validityMessages={langSrc:"i18n/formcfg-",availableLangs:"ar bg ca cs el es fa fi fr he hi hu it ja lt nl no pl pt pt-BR pt-PT ru sv zh-CN zh-TW".split(" ")},f.formcfg=a.extend({},f.validationMessages),f.inputTypes={},u("form-core",{f:"forms",test:t,d:["es5"],options:{placeholderType:"value",messagePopover:{},list:{popover:{constrainWidth:!0}},iVal:{sel:".ws-validate",handleBubble:"hide",recheckDelay:400}},methodNames:["setCustomValidity","checkValidity","setSelectionRange"],c:[16,7,2,8,1,15,30,3,31]}),d=q.forms,u("form-native-extend",{f:"forms",test:function(b){return t(),!k[i]||l||-1==a.inArray(j,b||[])||v[j].test()},d:["form-core",g,"form-message"],c:[6,5,14,29]}),u(h,{f:"forms",test:function(){return t(),k[i]&&!l},d:["form-core",g,"sizzle"],c:[16,15,28]}),u(h+"2",{f:"forms",test:function(){return t(),k[i]&&!m},d:[h],c:[27]}),u("form-message",{f:"forms",test:function(a){return t(),!(d.customMessages||!k[i]||l||!v[c].test(a))},d:[g],c:[16,7,15,30,3,8,4,14,28]}),u(j,{f:"forms-ext",options:{types:"date time range number"},test:function(){t();var a=!l;return a&&(a=w(this.options)),a},methodNames:["stepUp","stepDown"],d:["forms",g],c:[6,5,17,14,28,29,33]}),y("range-ui",{options:{},noAutoCallback:!0,test:function(){return!!C.rangeUI},d:["es5"],c:[6,5,9,10,17,11]}),u("form-number-date-ui",{f:"forms-ext",test:function(){var a=this.options;return a.replaceUI=n(a.replaceUI),t(),!a.replaceUI&&o&&(a.replaceUI=!0),!a.replaceUI&&w(a)},d:["forms",g,j,"range-ui"],options:{widgets:{calculateWidth:!0,animate:!0}},c:[6,5,9,10,17,11]}),u("form-datalist",{f:"forms",test:function(){return t(),o&&(d.customDatalist=!0),k.datalist&&!d.fD},d:["form-core",g],c:[16,7,6,2,9,15,30,31,28,33]})}();var F="FileReader"in window&&"FormData"in window;return u("filereader-xhr",{f:"filereader",test:F,d:[g,"swfmini"],c:[25,27]}),u("canvas-blob",{f:"filereader",methodNames:["toBlob"],test:!(F&&!b("canvas").toBlob)}),u("details",{test:"open"in b("details"),d:[g],options:{text:"Details"},c:[21,22]}),u("url",{test:function(){var a=!1;try{a=new URL("b","http://a"),a=!(!a.searchParams||"http://a/b"!=a.href)}catch(b){}return a},d:["es5"]}),function(){f.mediaelement={};var c=b("track");if(k.mediaelement="canPlayType"in D,k.texttrackapi="addTextTrack"in D,k.track="kind"in c,b("audio"),!(z.track=!k.texttrackapi))try{z.track=!("oncuechange"in D.addTextTrack("metadata"))}catch(d){}u("mediaelement-core",{f:"mediaelement",noAutoCallback:!0,options:{jme:{},plugins:[],vars:{},params:{},attrs:{},changeSWF:a.noop},methodNames:["play","pause","canPlayType","mediaLoad:load"],d:["swfmini"],c:[16,7,2,8,1,12,13,23]}),u("mediaelement-jaris",{f:"mediaelement",d:["mediaelement-core",g],test:function(){var a=this.options;return!k.mediaelement||f.mediaelement.loadSwf?!1:(a.preferFlash&&!v.swfmini.test()&&(a.preferFlash=!1),!(a.preferFlash&&swfmini.hasFlashPlayerVersion("11.3")))},c:[21,25]}),u("track",{options:{positionDisplay:!0,override:z.track},test:function(){var a=this.options;return a.override=n(a.override),!a.override&&!z.track},d:["mediaelement",g],methodNames:["addTextTrack"],c:[21,12,13,22,34]}),y("jmebase",{src:"jme/base",c:[98,99,97]}),a.each([["mediacontrols",{c:[98,99],css:"jme/controls.css"}],["playlist",{c:[98,97]}],["alternate-media"]],function(b,c){y(c[0],a.extend({src:"jme/"+c[0],d:["jmebase"]},c[1]))}),y("track-ui",{d:["track",g]})}(),u("feature-dummy",{test:!0,loaded:!0,c:A}),f.$=a,a.webshims=f,a.webshim=webshim,f.callAsync=function(){f.callAsync=a.noop,j&&(j.cfg&&(j.cfg.length||(j.cfg=[[j.cfg]]),a.each(j.cfg,function(a,b){f.setOptions.apply(f,b)})),j.ready&&a.each(j.ready,function(a,b){f.ready.apply(f,b)}),j.lang&&f.activeLang(j.lang),"polyfill"in j&&f.polyfill(j.polyfill)),f.isReady("jquery",!0)},f.callAsync(),f}); +/* +Copyright 2012 Igor Vaynberg + +Version: 3.5.4 Timestamp: Sun Aug 30 13:30:32 EDT 2015 + +This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU +General Public License version 2 (the "GPL License"). You may choose either license to govern your +use of this software only upon the condition that you accept all of the terms of either the Apache +License or the GPL License. + +You may obtain a copy of the Apache License and the GPL License at: + + http://www.apache.org/licenses/LICENSE-2.0 + http://www.gnu.org/licenses/gpl-2.0.html + +Unless required by applicable law or agreed to in writing, software distributed under the +Apache License or the GPL License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the Apache License and the GPL License for +the specific language governing permissions and limitations under the Apache License and the GPL License. +*/ + +(function ($) { + if(typeof $.fn.each2 == "undefined") { + $.extend($.fn, { + /* + * 4-10 times faster .each replacement + * use it carefully, as it overrides jQuery context of element on each iteration + */ + each2 : function (c) { + var j = $([0]), i = -1, l = this.length; + while ( + ++i < l + && (j.context = j[0] = this[i]) + && c.call(j[0], i, j) !== false //"this"=DOM, i=index, j=jQuery object + ); + return this; + } + }); + } +})(jQuery); + +(function ($, undefined) { + "use strict"; + /*global document, window, jQuery, console */ + + if (window.Select2 !== undefined) { + return; + } + + var AbstractSelect2, SingleSelect2, MultiSelect2, nextUid, sizer, + lastMousePosition={x:0,y:0}, $document, scrollBarDimensions, + + KEY = { + TAB: 9, + ENTER: 13, + ESC: 27, + SPACE: 32, + LEFT: 37, + UP: 38, + RIGHT: 39, + DOWN: 40, + SHIFT: 16, + CTRL: 17, + ALT: 18, + PAGE_UP: 33, + PAGE_DOWN: 34, + HOME: 36, + END: 35, + BACKSPACE: 8, + DELETE: 46, + isArrow: function (k) { + k = k.which ? k.which : k; + switch (k) { + case KEY.LEFT: + case KEY.RIGHT: + case KEY.UP: + case KEY.DOWN: + return true; + } + return false; + }, + isControl: function (e) { + var k = e.which; + switch (k) { + case KEY.SHIFT: + case KEY.CTRL: + case KEY.ALT: + return true; + } + + if (e.metaKey) return true; + + return false; + }, + isFunctionKey: function (k) { + k = k.which ? k.which : k; + return k >= 112 && k <= 123; + } + }, + MEASURE_SCROLLBAR_TEMPLATE = "<div class='select2-measure-scrollbar'></div>", + + DIACRITICS = {"\u24B6":"A","\uFF21":"A","\u00C0":"A","\u00C1":"A","\u00C2":"A","\u1EA6":"A","\u1EA4":"A","\u1EAA":"A","\u1EA8":"A","\u00C3":"A","\u0100":"A","\u0102":"A","\u1EB0":"A","\u1EAE":"A","\u1EB4":"A","\u1EB2":"A","\u0226":"A","\u01E0":"A","\u00C4":"A","\u01DE":"A","\u1EA2":"A","\u00C5":"A","\u01FA":"A","\u01CD":"A","\u0200":"A","\u0202":"A","\u1EA0":"A","\u1EAC":"A","\u1EB6":"A","\u1E00":"A","\u0104":"A","\u023A":"A","\u2C6F":"A","\uA732":"AA","\u00C6":"AE","\u01FC":"AE","\u01E2":"AE","\uA734":"AO","\uA736":"AU","\uA738":"AV","\uA73A":"AV","\uA73C":"AY","\u24B7":"B","\uFF22":"B","\u1E02":"B","\u1E04":"B","\u1E06":"B","\u0243":"B","\u0182":"B","\u0181":"B","\u24B8":"C","\uFF23":"C","\u0106":"C","\u0108":"C","\u010A":"C","\u010C":"C","\u00C7":"C","\u1E08":"C","\u0187":"C","\u023B":"C","\uA73E":"C","\u24B9":"D","\uFF24":"D","\u1E0A":"D","\u010E":"D","\u1E0C":"D","\u1E10":"D","\u1E12":"D","\u1E0E":"D","\u0110":"D","\u018B":"D","\u018A":"D","\u0189":"D","\uA779":"D","\u01F1":"DZ","\u01C4":"DZ","\u01F2":"Dz","\u01C5":"Dz","\u24BA":"E","\uFF25":"E","\u00C8":"E","\u00C9":"E","\u00CA":"E","\u1EC0":"E","\u1EBE":"E","\u1EC4":"E","\u1EC2":"E","\u1EBC":"E","\u0112":"E","\u1E14":"E","\u1E16":"E","\u0114":"E","\u0116":"E","\u00CB":"E","\u1EBA":"E","\u011A":"E","\u0204":"E","\u0206":"E","\u1EB8":"E","\u1EC6":"E","\u0228":"E","\u1E1C":"E","\u0118":"E","\u1E18":"E","\u1E1A":"E","\u0190":"E","\u018E":"E","\u24BB":"F","\uFF26":"F","\u1E1E":"F","\u0191":"F","\uA77B":"F","\u24BC":"G","\uFF27":"G","\u01F4":"G","\u011C":"G","\u1E20":"G","\u011E":"G","\u0120":"G","\u01E6":"G","\u0122":"G","\u01E4":"G","\u0193":"G","\uA7A0":"G","\uA77D":"G","\uA77E":"G","\u24BD":"H","\uFF28":"H","\u0124":"H","\u1E22":"H","\u1E26":"H","\u021E":"H","\u1E24":"H","\u1E28":"H","\u1E2A":"H","\u0126":"H","\u2C67":"H","\u2C75":"H","\uA78D":"H","\u24BE":"I","\uFF29":"I","\u00CC":"I","\u00CD":"I","\u00CE":"I","\u0128":"I","\u012A":"I","\u012C":"I","\u0130":"I","\u00CF":"I","\u1E2E":"I","\u1EC8":"I","\u01CF":"I","\u0208":"I","\u020A":"I","\u1ECA":"I","\u012E":"I","\u1E2C":"I","\u0197":"I","\u24BF":"J","\uFF2A":"J","\u0134":"J","\u0248":"J","\u24C0":"K","\uFF2B":"K","\u1E30":"K","\u01E8":"K","\u1E32":"K","\u0136":"K","\u1E34":"K","\u0198":"K","\u2C69":"K","\uA740":"K","\uA742":"K","\uA744":"K","\uA7A2":"K","\u24C1":"L","\uFF2C":"L","\u013F":"L","\u0139":"L","\u013D":"L","\u1E36":"L","\u1E38":"L","\u013B":"L","\u1E3C":"L","\u1E3A":"L","\u0141":"L","\u023D":"L","\u2C62":"L","\u2C60":"L","\uA748":"L","\uA746":"L","\uA780":"L","\u01C7":"LJ","\u01C8":"Lj","\u24C2":"M","\uFF2D":"M","\u1E3E":"M","\u1E40":"M","\u1E42":"M","\u2C6E":"M","\u019C":"M","\u24C3":"N","\uFF2E":"N","\u01F8":"N","\u0143":"N","\u00D1":"N","\u1E44":"N","\u0147":"N","\u1E46":"N","\u0145":"N","\u1E4A":"N","\u1E48":"N","\u0220":"N","\u019D":"N","\uA790":"N","\uA7A4":"N","\u01CA":"NJ","\u01CB":"Nj","\u24C4":"O","\uFF2F":"O","\u00D2":"O","\u00D3":"O","\u00D4":"O","\u1ED2":"O","\u1ED0":"O","\u1ED6":"O","\u1ED4":"O","\u00D5":"O","\u1E4C":"O","\u022C":"O","\u1E4E":"O","\u014C":"O","\u1E50":"O","\u1E52":"O","\u014E":"O","\u022E":"O","\u0230":"O","\u00D6":"O","\u022A":"O","\u1ECE":"O","\u0150":"O","\u01D1":"O","\u020C":"O","\u020E":"O","\u01A0":"O","\u1EDC":"O","\u1EDA":"O","\u1EE0":"O","\u1EDE":"O","\u1EE2":"O","\u1ECC":"O","\u1ED8":"O","\u01EA":"O","\u01EC":"O","\u00D8":"O","\u01FE":"O","\u0186":"O","\u019F":"O","\uA74A":"O","\uA74C":"O","\u01A2":"OI","\uA74E":"OO","\u0222":"OU","\u24C5":"P","\uFF30":"P","\u1E54":"P","\u1E56":"P","\u01A4":"P","\u2C63":"P","\uA750":"P","\uA752":"P","\uA754":"P","\u24C6":"Q","\uFF31":"Q","\uA756":"Q","\uA758":"Q","\u024A":"Q","\u24C7":"R","\uFF32":"R","\u0154":"R","\u1E58":"R","\u0158":"R","\u0210":"R","\u0212":"R","\u1E5A":"R","\u1E5C":"R","\u0156":"R","\u1E5E":"R","\u024C":"R","\u2C64":"R","\uA75A":"R","\uA7A6":"R","\uA782":"R","\u24C8":"S","\uFF33":"S","\u1E9E":"S","\u015A":"S","\u1E64":"S","\u015C":"S","\u1E60":"S","\u0160":"S","\u1E66":"S","\u1E62":"S","\u1E68":"S","\u0218":"S","\u015E":"S","\u2C7E":"S","\uA7A8":"S","\uA784":"S","\u24C9":"T","\uFF34":"T","\u1E6A":"T","\u0164":"T","\u1E6C":"T","\u021A":"T","\u0162":"T","\u1E70":"T","\u1E6E":"T","\u0166":"T","\u01AC":"T","\u01AE":"T","\u023E":"T","\uA786":"T","\uA728":"TZ","\u24CA":"U","\uFF35":"U","\u00D9":"U","\u00DA":"U","\u00DB":"U","\u0168":"U","\u1E78":"U","\u016A":"U","\u1E7A":"U","\u016C":"U","\u00DC":"U","\u01DB":"U","\u01D7":"U","\u01D5":"U","\u01D9":"U","\u1EE6":"U","\u016E":"U","\u0170":"U","\u01D3":"U","\u0214":"U","\u0216":"U","\u01AF":"U","\u1EEA":"U","\u1EE8":"U","\u1EEE":"U","\u1EEC":"U","\u1EF0":"U","\u1EE4":"U","\u1E72":"U","\u0172":"U","\u1E76":"U","\u1E74":"U","\u0244":"U","\u24CB":"V","\uFF36":"V","\u1E7C":"V","\u1E7E":"V","\u01B2":"V","\uA75E":"V","\u0245":"V","\uA760":"VY","\u24CC":"W","\uFF37":"W","\u1E80":"W","\u1E82":"W","\u0174":"W","\u1E86":"W","\u1E84":"W","\u1E88":"W","\u2C72":"W","\u24CD":"X","\uFF38":"X","\u1E8A":"X","\u1E8C":"X","\u24CE":"Y","\uFF39":"Y","\u1EF2":"Y","\u00DD":"Y","\u0176":"Y","\u1EF8":"Y","\u0232":"Y","\u1E8E":"Y","\u0178":"Y","\u1EF6":"Y","\u1EF4":"Y","\u01B3":"Y","\u024E":"Y","\u1EFE":"Y","\u24CF":"Z","\uFF3A":"Z","\u0179":"Z","\u1E90":"Z","\u017B":"Z","\u017D":"Z","\u1E92":"Z","\u1E94":"Z","\u01B5":"Z","\u0224":"Z","\u2C7F":"Z","\u2C6B":"Z","\uA762":"Z","\u24D0":"a","\uFF41":"a","\u1E9A":"a","\u00E0":"a","\u00E1":"a","\u00E2":"a","\u1EA7":"a","\u1EA5":"a","\u1EAB":"a","\u1EA9":"a","\u00E3":"a","\u0101":"a","\u0103":"a","\u1EB1":"a","\u1EAF":"a","\u1EB5":"a","\u1EB3":"a","\u0227":"a","\u01E1":"a","\u00E4":"a","\u01DF":"a","\u1EA3":"a","\u00E5":"a","\u01FB":"a","\u01CE":"a","\u0201":"a","\u0203":"a","\u1EA1":"a","\u1EAD":"a","\u1EB7":"a","\u1E01":"a","\u0105":"a","\u2C65":"a","\u0250":"a","\uA733":"aa","\u00E6":"ae","\u01FD":"ae","\u01E3":"ae","\uA735":"ao","\uA737":"au","\uA739":"av","\uA73B":"av","\uA73D":"ay","\u24D1":"b","\uFF42":"b","\u1E03":"b","\u1E05":"b","\u1E07":"b","\u0180":"b","\u0183":"b","\u0253":"b","\u24D2":"c","\uFF43":"c","\u0107":"c","\u0109":"c","\u010B":"c","\u010D":"c","\u00E7":"c","\u1E09":"c","\u0188":"c","\u023C":"c","\uA73F":"c","\u2184":"c","\u24D3":"d","\uFF44":"d","\u1E0B":"d","\u010F":"d","\u1E0D":"d","\u1E11":"d","\u1E13":"d","\u1E0F":"d","\u0111":"d","\u018C":"d","\u0256":"d","\u0257":"d","\uA77A":"d","\u01F3":"dz","\u01C6":"dz","\u24D4":"e","\uFF45":"e","\u00E8":"e","\u00E9":"e","\u00EA":"e","\u1EC1":"e","\u1EBF":"e","\u1EC5":"e","\u1EC3":"e","\u1EBD":"e","\u0113":"e","\u1E15":"e","\u1E17":"e","\u0115":"e","\u0117":"e","\u00EB":"e","\u1EBB":"e","\u011B":"e","\u0205":"e","\u0207":"e","\u1EB9":"e","\u1EC7":"e","\u0229":"e","\u1E1D":"e","\u0119":"e","\u1E19":"e","\u1E1B":"e","\u0247":"e","\u025B":"e","\u01DD":"e","\u24D5":"f","\uFF46":"f","\u1E1F":"f","\u0192":"f","\uA77C":"f","\u24D6":"g","\uFF47":"g","\u01F5":"g","\u011D":"g","\u1E21":"g","\u011F":"g","\u0121":"g","\u01E7":"g","\u0123":"g","\u01E5":"g","\u0260":"g","\uA7A1":"g","\u1D79":"g","\uA77F":"g","\u24D7":"h","\uFF48":"h","\u0125":"h","\u1E23":"h","\u1E27":"h","\u021F":"h","\u1E25":"h","\u1E29":"h","\u1E2B":"h","\u1E96":"h","\u0127":"h","\u2C68":"h","\u2C76":"h","\u0265":"h","\u0195":"hv","\u24D8":"i","\uFF49":"i","\u00EC":"i","\u00ED":"i","\u00EE":"i","\u0129":"i","\u012B":"i","\u012D":"i","\u00EF":"i","\u1E2F":"i","\u1EC9":"i","\u01D0":"i","\u0209":"i","\u020B":"i","\u1ECB":"i","\u012F":"i","\u1E2D":"i","\u0268":"i","\u0131":"i","\u24D9":"j","\uFF4A":"j","\u0135":"j","\u01F0":"j","\u0249":"j","\u24DA":"k","\uFF4B":"k","\u1E31":"k","\u01E9":"k","\u1E33":"k","\u0137":"k","\u1E35":"k","\u0199":"k","\u2C6A":"k","\uA741":"k","\uA743":"k","\uA745":"k","\uA7A3":"k","\u24DB":"l","\uFF4C":"l","\u0140":"l","\u013A":"l","\u013E":"l","\u1E37":"l","\u1E39":"l","\u013C":"l","\u1E3D":"l","\u1E3B":"l","\u017F":"l","\u0142":"l","\u019A":"l","\u026B":"l","\u2C61":"l","\uA749":"l","\uA781":"l","\uA747":"l","\u01C9":"lj","\u24DC":"m","\uFF4D":"m","\u1E3F":"m","\u1E41":"m","\u1E43":"m","\u0271":"m","\u026F":"m","\u24DD":"n","\uFF4E":"n","\u01F9":"n","\u0144":"n","\u00F1":"n","\u1E45":"n","\u0148":"n","\u1E47":"n","\u0146":"n","\u1E4B":"n","\u1E49":"n","\u019E":"n","\u0272":"n","\u0149":"n","\uA791":"n","\uA7A5":"n","\u01CC":"nj","\u24DE":"o","\uFF4F":"o","\u00F2":"o","\u00F3":"o","\u00F4":"o","\u1ED3":"o","\u1ED1":"o","\u1ED7":"o","\u1ED5":"o","\u00F5":"o","\u1E4D":"o","\u022D":"o","\u1E4F":"o","\u014D":"o","\u1E51":"o","\u1E53":"o","\u014F":"o","\u022F":"o","\u0231":"o","\u00F6":"o","\u022B":"o","\u1ECF":"o","\u0151":"o","\u01D2":"o","\u020D":"o","\u020F":"o","\u01A1":"o","\u1EDD":"o","\u1EDB":"o","\u1EE1":"o","\u1EDF":"o","\u1EE3":"o","\u1ECD":"o","\u1ED9":"o","\u01EB":"o","\u01ED":"o","\u00F8":"o","\u01FF":"o","\u0254":"o","\uA74B":"o","\uA74D":"o","\u0275":"o","\u01A3":"oi","\u0223":"ou","\uA74F":"oo","\u24DF":"p","\uFF50":"p","\u1E55":"p","\u1E57":"p","\u01A5":"p","\u1D7D":"p","\uA751":"p","\uA753":"p","\uA755":"p","\u24E0":"q","\uFF51":"q","\u024B":"q","\uA757":"q","\uA759":"q","\u24E1":"r","\uFF52":"r","\u0155":"r","\u1E59":"r","\u0159":"r","\u0211":"r","\u0213":"r","\u1E5B":"r","\u1E5D":"r","\u0157":"r","\u1E5F":"r","\u024D":"r","\u027D":"r","\uA75B":"r","\uA7A7":"r","\uA783":"r","\u24E2":"s","\uFF53":"s","\u00DF":"s","\u015B":"s","\u1E65":"s","\u015D":"s","\u1E61":"s","\u0161":"s","\u1E67":"s","\u1E63":"s","\u1E69":"s","\u0219":"s","\u015F":"s","\u023F":"s","\uA7A9":"s","\uA785":"s","\u1E9B":"s","\u24E3":"t","\uFF54":"t","\u1E6B":"t","\u1E97":"t","\u0165":"t","\u1E6D":"t","\u021B":"t","\u0163":"t","\u1E71":"t","\u1E6F":"t","\u0167":"t","\u01AD":"t","\u0288":"t","\u2C66":"t","\uA787":"t","\uA729":"tz","\u24E4":"u","\uFF55":"u","\u00F9":"u","\u00FA":"u","\u00FB":"u","\u0169":"u","\u1E79":"u","\u016B":"u","\u1E7B":"u","\u016D":"u","\u00FC":"u","\u01DC":"u","\u01D8":"u","\u01D6":"u","\u01DA":"u","\u1EE7":"u","\u016F":"u","\u0171":"u","\u01D4":"u","\u0215":"u","\u0217":"u","\u01B0":"u","\u1EEB":"u","\u1EE9":"u","\u1EEF":"u","\u1EED":"u","\u1EF1":"u","\u1EE5":"u","\u1E73":"u","\u0173":"u","\u1E77":"u","\u1E75":"u","\u0289":"u","\u24E5":"v","\uFF56":"v","\u1E7D":"v","\u1E7F":"v","\u028B":"v","\uA75F":"v","\u028C":"v","\uA761":"vy","\u24E6":"w","\uFF57":"w","\u1E81":"w","\u1E83":"w","\u0175":"w","\u1E87":"w","\u1E85":"w","\u1E98":"w","\u1E89":"w","\u2C73":"w","\u24E7":"x","\uFF58":"x","\u1E8B":"x","\u1E8D":"x","\u24E8":"y","\uFF59":"y","\u1EF3":"y","\u00FD":"y","\u0177":"y","\u1EF9":"y","\u0233":"y","\u1E8F":"y","\u00FF":"y","\u1EF7":"y","\u1E99":"y","\u1EF5":"y","\u01B4":"y","\u024F":"y","\u1EFF":"y","\u24E9":"z","\uFF5A":"z","\u017A":"z","\u1E91":"z","\u017C":"z","\u017E":"z","\u1E93":"z","\u1E95":"z","\u01B6":"z","\u0225":"z","\u0240":"z","\u2C6C":"z","\uA763":"z","\u0386":"\u0391","\u0388":"\u0395","\u0389":"\u0397","\u038A":"\u0399","\u03AA":"\u0399","\u038C":"\u039F","\u038E":"\u03A5","\u03AB":"\u03A5","\u038F":"\u03A9","\u03AC":"\u03B1","\u03AD":"\u03B5","\u03AE":"\u03B7","\u03AF":"\u03B9","\u03CA":"\u03B9","\u0390":"\u03B9","\u03CC":"\u03BF","\u03CD":"\u03C5","\u03CB":"\u03C5","\u03B0":"\u03C5","\u03C9":"\u03C9","\u03C2":"\u03C3"}; + + $document = $(document); + + nextUid=(function() { var counter=1; return function() { return counter++; }; }()); + + + function reinsertElement(element) { + var placeholder = $(document.createTextNode('')); + + element.before(placeholder); + placeholder.before(element); + placeholder.remove(); + } + + function stripDiacritics(str) { + // Used 'uni range + named function' from http://jsperf.com/diacritics/18 + function match(a) { + return DIACRITICS[a] || a; + } + + return str.replace(/[^\u0000-\u007E]/g, match); + } + + function indexOf(value, array) { + var i = 0, l = array.length; + for (; i < l; i = i + 1) { + if (equal(value, array[i])) return i; + } + return -1; + } + + function measureScrollbar () { + var $template = $( MEASURE_SCROLLBAR_TEMPLATE ); + $template.appendTo(document.body); + + var dim = { + width: $template.width() - $template[0].clientWidth, + height: $template.height() - $template[0].clientHeight + }; + $template.remove(); + + return dim; + } + + /** + * Compares equality of a and b + * @param a + * @param b + */ + function equal(a, b) { + if (a === b) return true; + if (a === undefined || b === undefined) return false; + if (a === null || b === null) return false; + // Check whether 'a' or 'b' is a string (primitive or object). + // The concatenation of an empty string (+'') converts its argument to a string's primitive. + if (a.constructor === String) return a+'' === b+''; // a+'' - in case 'a' is a String object + if (b.constructor === String) return b+'' === a+''; // b+'' - in case 'b' is a String object + return false; + } + + /** + * Splits the string into an array of values, transforming each value. An empty array is returned for nulls or empty + * strings + * @param string + * @param separator + */ + function splitVal(string, separator, transform) { + var val, i, l; + if (string === null || string.length < 1) return []; + val = string.split(separator); + for (i = 0, l = val.length; i < l; i = i + 1) val[i] = transform(val[i]); + return val; + } + + function getSideBorderPadding(element) { + return element.outerWidth(false) - element.width(); + } + + function installKeyUpChangeEvent(element) { + var key="keyup-change-value"; + element.on("keydown", function () { + if ($.data(element, key) === undefined) { + $.data(element, key, element.val()); + } + }); + element.on("keyup", function () { + var val= $.data(element, key); + if (val !== undefined && element.val() !== val) { + $.removeData(element, key); + element.trigger("keyup-change"); + } + }); + } + + + /** + * filters mouse events so an event is fired only if the mouse moved. + * + * filters out mouse events that occur when mouse is stationary but + * the elements under the pointer are scrolled. + */ + function installFilteredMouseMove(element) { + element.on("mousemove", function (e) { + var lastpos = lastMousePosition; + if (lastpos === undefined || lastpos.x !== e.pageX || lastpos.y !== e.pageY) { + $(e.target).trigger("mousemove-filtered", e); + } + }); + } + + /** + * Debounces a function. Returns a function that calls the original fn function only if no invocations have been made + * within the last quietMillis milliseconds. + * + * @param quietMillis number of milliseconds to wait before invoking fn + * @param fn function to be debounced + * @param ctx object to be used as this reference within fn + * @return debounced version of fn + */ + function debounce(quietMillis, fn, ctx) { + ctx = ctx || undefined; + var timeout; + return function () { + var args = arguments; + window.clearTimeout(timeout); + timeout = window.setTimeout(function() { + fn.apply(ctx, args); + }, quietMillis); + }; + } + + function installDebouncedScroll(threshold, element) { + var notify = debounce(threshold, function (e) { element.trigger("scroll-debounced", e);}); + element.on("scroll", function (e) { + if (indexOf(e.target, element.get()) >= 0) notify(e); + }); + } + + function focus($el) { + if ($el[0] === document.activeElement) return; + + /* set the focus in a 0 timeout - that way the focus is set after the processing + of the current event has finished - which seems like the only reliable way + to set focus */ + window.setTimeout(function() { + var el=$el[0], pos=$el.val().length, range; + + $el.focus(); + + /* make sure el received focus so we do not error out when trying to manipulate the caret. + sometimes modals or others listeners may steal it after its set */ + var isVisible = (el.offsetWidth > 0 || el.offsetHeight > 0); + if (isVisible && el === document.activeElement) { + + /* after the focus is set move the caret to the end, necessary when we val() + just before setting focus */ + if(el.setSelectionRange) + { + el.setSelectionRange(pos, pos); + } + else if (el.createTextRange) { + range = el.createTextRange(); + range.collapse(false); + range.select(); + } + } + }, 0); + } + + function getCursorInfo(el) { + el = $(el)[0]; + var offset = 0; + var length = 0; + if ('selectionStart' in el) { + offset = el.selectionStart; + length = el.selectionEnd - offset; + } else if ('selection' in document) { + el.focus(); + var sel = document.selection.createRange(); + length = document.selection.createRange().text.length; + sel.moveStart('character', -el.value.length); + offset = sel.text.length - length; + } + return { offset: offset, length: length }; + } + + function killEvent(event) { + event.preventDefault(); + event.stopPropagation(); + } + function killEventImmediately(event) { + event.preventDefault(); + event.stopImmediatePropagation(); + } + + function measureTextWidth(e) { + if (!sizer){ + var style = e[0].currentStyle || window.getComputedStyle(e[0], null); + sizer = $(document.createElement("div")).css({ + position: "absolute", + left: "-10000px", + top: "-10000px", + display: "none", + fontSize: style.fontSize, + fontFamily: style.fontFamily, + fontStyle: style.fontStyle, + fontWeight: style.fontWeight, + letterSpacing: style.letterSpacing, + textTransform: style.textTransform, + whiteSpace: "nowrap" + }); + sizer.attr("class","select2-sizer"); + $(document.body).append(sizer); + } + sizer.text(e.val()); + return sizer.width(); + } + + function syncCssClasses(dest, src, adapter) { + var classes, replacements = [], adapted; + + classes = $.trim(dest.attr("class")); + + if (classes) { + classes = '' + classes; // for IE which returns object + + $(classes.split(/\s+/)).each2(function() { + if (this.indexOf("select2-") === 0) { + replacements.push(this); + } + }); + } + + classes = $.trim(src.attr("class")); + + if (classes) { + classes = '' + classes; // for IE which returns object + + $(classes.split(/\s+/)).each2(function() { + if (this.indexOf("select2-") !== 0) { + adapted = adapter(this); + + if (adapted) { + replacements.push(adapted); + } + } + }); + } + + dest.attr("class", replacements.join(" ")); + } + + + function markMatch(text, term, markup, escapeMarkup) { + var match=stripDiacritics(text.toUpperCase()).indexOf(stripDiacritics(term.toUpperCase())), + tl=term.length; + + if (match<0) { + markup.push(escapeMarkup(text)); + return; + } + + markup.push(escapeMarkup(text.substring(0, match))); + markup.push("<span class='select2-match'>"); + markup.push(escapeMarkup(text.substring(match, match + tl))); + markup.push("</span>"); + markup.push(escapeMarkup(text.substring(match + tl, text.length))); + } + + function defaultEscapeMarkup(markup) { + var replace_map = { + '\\': '\', + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + "/": '/' + }; + + return String(markup).replace(/[&<>"'\/\\]/g, function (match) { + return replace_map[match]; + }); + } + + /** + * Produces an ajax-based query function + * + * @param options object containing configuration parameters + * @param options.params parameter map for the transport ajax call, can contain such options as cache, jsonpCallback, etc. see $.ajax + * @param options.transport function that will be used to execute the ajax request. must be compatible with parameters supported by $.ajax + * @param options.url url for the data + * @param options.data a function(searchTerm, pageNumber, context) that should return an object containing query string parameters for the above url. + * @param options.dataType request data type: ajax, jsonp, other datatypes supported by jQuery's $.ajax function or the transport function if specified + * @param options.quietMillis (optional) milliseconds to wait before making the ajaxRequest, helps debounce the ajax function if invoked too often + * @param options.results a function(remoteData, pageNumber, query) that converts data returned form the remote request to the format expected by Select2. + * The expected format is an object containing the following keys: + * results array of objects that will be used as choices + * more (optional) boolean indicating whether there are more results available + * Example: {results:[{id:1, text:'Red'},{id:2, text:'Blue'}], more:true} + */ + function ajax(options) { + var timeout, // current scheduled but not yet executed request + handler = null, + quietMillis = options.quietMillis || 100, + ajaxUrl = options.url, + self = this; + + return function (query) { + window.clearTimeout(timeout); + timeout = window.setTimeout(function () { + var data = options.data, // ajax data function + url = ajaxUrl, // ajax url string or function + transport = options.transport || $.fn.select2.ajaxDefaults.transport, + // deprecated - to be removed in 4.0 - use params instead + deprecated = { + type: options.type || 'GET', // set type of request (GET or POST) + cache: options.cache || false, + jsonpCallback: options.jsonpCallback||undefined, + dataType: options.dataType||"json" + }, + params = $.extend({}, $.fn.select2.ajaxDefaults.params, deprecated); + + data = data ? data.call(self, query.term, query.page, query.context) : null; + url = (typeof url === 'function') ? url.call(self, query.term, query.page, query.context) : url; + + if (handler && typeof handler.abort === "function") { handler.abort(); } + + if (options.params) { + if ($.isFunction(options.params)) { + $.extend(params, options.params.call(self)); + } else { + $.extend(params, options.params); + } + } + + $.extend(params, { + url: url, + dataType: options.dataType, + data: data, + success: function (data) { + // TODO - replace query.page with query so users have access to term, page, etc. + // added query as third paramter to keep backwards compatibility + var results = options.results(data, query.page, query); + query.callback(results); + }, + error: function(jqXHR, textStatus, errorThrown){ + var results = { + hasError: true, + jqXHR: jqXHR, + textStatus: textStatus, + errorThrown: errorThrown + }; + + query.callback(results); + } + }); + handler = transport.call(self, params); + }, quietMillis); + }; + } + + /** + * Produces a query function that works with a local array + * + * @param options object containing configuration parameters. The options parameter can either be an array or an + * object. + * + * If the array form is used it is assumed that it contains objects with 'id' and 'text' keys. + * + * If the object form is used it is assumed that it contains 'data' and 'text' keys. The 'data' key should contain + * an array of objects that will be used as choices. These objects must contain at least an 'id' key. The 'text' + * key can either be a String in which case it is expected that each element in the 'data' array has a key with the + * value of 'text' which will be used to match choices. Alternatively, text can be a function(item) that can extract + * the text. + */ + function local(options) { + var data = options, // data elements + dataText, + tmp, + text = function (item) { return ""+item.text; }; // function used to retrieve the text portion of a data item that is matched against the search + + if ($.isArray(data)) { + tmp = data; + data = { results: tmp }; + } + + if ($.isFunction(data) === false) { + tmp = data; + data = function() { return tmp; }; + } + + var dataItem = data(); + if (dataItem.text) { + text = dataItem.text; + // if text is not a function we assume it to be a key name + if (!$.isFunction(text)) { + dataText = dataItem.text; // we need to store this in a separate variable because in the next step data gets reset and data.text is no longer available + text = function (item) { return item[dataText]; }; + } + } + + return function (query) { + var t = query.term, filtered = { results: [] }, process; + if (t === "") { + query.callback(data()); + return; + } + + process = function(datum, collection) { + var group, attr; + datum = datum[0]; + if (datum.children) { + group = {}; + for (attr in datum) { + if (datum.hasOwnProperty(attr)) group[attr]=datum[attr]; + } + group.children=[]; + $(datum.children).each2(function(i, childDatum) { process(childDatum, group.children); }); + if (group.children.length || query.matcher(t, text(group), datum)) { + collection.push(group); + } + } else { + if (query.matcher(t, text(datum), datum)) { + collection.push(datum); + } + } + }; + + $(data().results).each2(function(i, datum) { process(datum, filtered.results); }); + query.callback(filtered); + }; + } + + // TODO javadoc + function tags(data) { + var isFunc = $.isFunction(data); + return function (query) { + var t = query.term, filtered = {results: []}; + var result = isFunc ? data(query) : data; + if ($.isArray(result)) { + $(result).each(function () { + var isObject = this.text !== undefined, + text = isObject ? this.text : this; + if (t === "" || query.matcher(t, text)) { + filtered.results.push(isObject ? this : {id: this, text: this}); + } + }); + query.callback(filtered); + } + }; + } + + /** + * Checks if the formatter function should be used. + * + * Throws an error if it is not a function. Returns true if it should be used, + * false if no formatting should be performed. + * + * @param formatter + */ + function checkFormatter(formatter, formatterName) { + if ($.isFunction(formatter)) return true; + if (!formatter) return false; + if (typeof(formatter) === 'string') return true; + throw new Error(formatterName +" must be a string, function, or falsy value"); + } + + /** + * Returns a given value + * If given a function, returns its output + * + * @param val string|function + * @param context value of "this" to be passed to function + * @returns {*} + */ + function evaluate(val, context) { + if ($.isFunction(val)) { + var args = Array.prototype.slice.call(arguments, 2); + return val.apply(context, args); + } + return val; + } + + function countResults(results) { + var count = 0; + $.each(results, function(i, item) { + if (item.children) { + count += countResults(item.children); + } else { + count++; + } + }); + return count; + } + + /** + * Default tokenizer. This function uses breaks the input on substring match of any string from the + * opts.tokenSeparators array and uses opts.createSearchChoice to create the choice object. Both of those + * two options have to be defined in order for the tokenizer to work. + * + * @param input text user has typed so far or pasted into the search field + * @param selection currently selected choices + * @param selectCallback function(choice) callback tho add the choice to selection + * @param opts select2's opts + * @return undefined/null to leave the current input unchanged, or a string to change the input to the returned value + */ + function defaultTokenizer(input, selection, selectCallback, opts) { + var original = input, // store the original so we can compare and know if we need to tell the search to update its text + dupe = false, // check for whether a token we extracted represents a duplicate selected choice + token, // token + index, // position at which the separator was found + i, l, // looping variables + separator; // the matched separator + + if (!opts.createSearchChoice || !opts.tokenSeparators || opts.tokenSeparators.length < 1) return undefined; + + while (true) { + index = -1; + + for (i = 0, l = opts.tokenSeparators.length; i < l; i++) { + separator = opts.tokenSeparators[i]; + index = input.indexOf(separator); + if (index >= 0) break; + } + + if (index < 0) break; // did not find any token separator in the input string, bail + + token = input.substring(0, index); + input = input.substring(index + separator.length); + + if (token.length > 0) { + token = opts.createSearchChoice.call(this, token, selection); + if (token !== undefined && token !== null && opts.id(token) !== undefined && opts.id(token) !== null) { + dupe = false; + for (i = 0, l = selection.length; i < l; i++) { + if (equal(opts.id(token), opts.id(selection[i]))) { + dupe = true; break; + } + } + + if (!dupe) selectCallback(token); + } + } + } + + if (original!==input) return input; + } + + function cleanupJQueryElements() { + var self = this; + + $.each(arguments, function (i, element) { + self[element].remove(); + self[element] = null; + }); + } + + /** + * Creates a new class + * + * @param superClass + * @param methods + */ + function clazz(SuperClass, methods) { + var constructor = function () {}; + constructor.prototype = new SuperClass; + constructor.prototype.constructor = constructor; + constructor.prototype.parent = SuperClass.prototype; + constructor.prototype = $.extend(constructor.prototype, methods); + return constructor; + } + + AbstractSelect2 = clazz(Object, { + + // abstract + bind: function (func) { + var self = this; + return function () { + func.apply(self, arguments); + }; + }, + + // abstract + init: function (opts) { + var results, search, resultsSelector = ".select2-results"; + + // prepare options + this.opts = opts = this.prepareOpts(opts); + + this.id=opts.id; + + // destroy if called on an existing component + if (opts.element.data("select2") !== undefined && + opts.element.data("select2") !== null) { + opts.element.data("select2").destroy(); + } + + this.container = this.createContainer(); + + this.liveRegion = $('.select2-hidden-accessible'); + if (this.liveRegion.length == 0) { + this.liveRegion = $("<span>", { + role: "status", + "aria-live": "polite" + }) + .addClass("select2-hidden-accessible") + .appendTo(document.body); + } + + this.containerId="s2id_"+(opts.element.attr("id") || "autogen"+nextUid()); + this.containerEventName= this.containerId + .replace(/([.])/g, '_') + .replace(/([;&,\-\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g, '\\$1'); + this.container.attr("id", this.containerId); + + this.container.attr("title", opts.element.attr("title")); + + this.body = $(document.body); + + syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass); + + this.container.attr("style", opts.element.attr("style")); + this.container.css(evaluate(opts.containerCss, this.opts.element)); + this.container.addClass(evaluate(opts.containerCssClass, this.opts.element)); + + this.elementTabIndex = this.opts.element.attr("tabindex"); + + // swap container for the element + this.opts.element + .data("select2", this) + .attr("tabindex", "-1") + .before(this.container) + .on("click.select2", killEvent); // do not leak click events + + this.container.data("select2", this); + + this.dropdown = this.container.find(".select2-drop"); + + syncCssClasses(this.dropdown, this.opts.element, this.opts.adaptDropdownCssClass); + + this.dropdown.addClass(evaluate(opts.dropdownCssClass, this.opts.element)); + this.dropdown.data("select2", this); + this.dropdown.on("click", killEvent); + + this.results = results = this.container.find(resultsSelector); + this.search = search = this.container.find("input.select2-input"); + + this.queryCount = 0; + this.resultsPage = 0; + this.context = null; + + // initialize the container + this.initContainer(); + + this.container.on("click", killEvent); + + installFilteredMouseMove(this.results); + + this.dropdown.on("mousemove-filtered", resultsSelector, this.bind(this.highlightUnderEvent)); + this.dropdown.on("touchstart touchmove touchend", resultsSelector, this.bind(function (event) { + this._touchEvent = true; + this.highlightUnderEvent(event); + })); + this.dropdown.on("touchmove", resultsSelector, this.bind(this.touchMoved)); + this.dropdown.on("touchstart touchend", resultsSelector, this.bind(this.clearTouchMoved)); + + // Waiting for a click event on touch devices to select option and hide dropdown + // otherwise click will be triggered on an underlying element + this.dropdown.on('click', this.bind(function (event) { + if (this._touchEvent) { + this._touchEvent = false; + this.selectHighlighted(); + } + })); + + installDebouncedScroll(80, this.results); + this.dropdown.on("scroll-debounced", resultsSelector, this.bind(this.loadMoreIfNeeded)); + + // do not propagate change event from the search field out of the component + $(this.container).on("change", ".select2-input", function(e) {e.stopPropagation();}); + $(this.dropdown).on("change", ".select2-input", function(e) {e.stopPropagation();}); + + // if jquery.mousewheel plugin is installed we can prevent out-of-bounds scrolling of results via mousewheel + if ($.fn.mousewheel) { + results.mousewheel(function (e, delta, deltaX, deltaY) { + var top = results.scrollTop(); + if (deltaY > 0 && top - deltaY <= 0) { + results.scrollTop(0); + killEvent(e); + } else if (deltaY < 0 && results.get(0).scrollHeight - results.scrollTop() + deltaY <= results.height()) { + results.scrollTop(results.get(0).scrollHeight - results.height()); + killEvent(e); + } + }); + } + + installKeyUpChangeEvent(search); + search.on("keyup-change input paste", this.bind(this.updateResults)); + search.on("focus", function () { search.addClass("select2-focused"); }); + search.on("blur", function () { search.removeClass("select2-focused");}); + + this.dropdown.on("mouseup", resultsSelector, this.bind(function (e) { + if ($(e.target).closest(".select2-result-selectable").length > 0) { + this.highlightUnderEvent(e); + this.selectHighlighted(e); + } + })); + + // trap all mouse events from leaving the dropdown. sometimes there may be a modal that is listening + // for mouse events outside of itself so it can close itself. since the dropdown is now outside the select2's + // dom it will trigger the popup close, which is not what we want + // focusin can cause focus wars between modals and select2 since the dropdown is outside the modal. + this.dropdown.on("click mouseup mousedown touchstart touchend focusin", function (e) { e.stopPropagation(); }); + + this.lastSearchTerm = undefined; + + if ($.isFunction(this.opts.initSelection)) { + // initialize selection based on the current value of the source element + this.initSelection(); + + // if the user has provided a function that can set selection based on the value of the source element + // we monitor the change event on the element and trigger it, allowing for two way synchronization + this.monitorSource(); + } + + if (opts.maximumInputLength !== null) { + this.search.attr("maxlength", opts.maximumInputLength); + } + + var disabled = opts.element.prop("disabled"); + if (disabled === undefined) disabled = false; + this.enable(!disabled); + + var readonly = opts.element.prop("readonly"); + if (readonly === undefined) readonly = false; + this.readonly(readonly); + + // Calculate size of scrollbar + scrollBarDimensions = scrollBarDimensions || measureScrollbar(); + + this.autofocus = opts.element.prop("autofocus"); + opts.element.prop("autofocus", false); + if (this.autofocus) this.focus(); + + this.search.attr("placeholder", opts.searchInputPlaceholder); + }, + + // abstract + destroy: function () { + var element=this.opts.element, select2 = element.data("select2"), self = this; + + this.close(); + + if (element.length && element[0].detachEvent && self._sync) { + element.each(function () { + if (self._sync) { + this.detachEvent("onpropertychange", self._sync); + } + }); + } + if (this.propertyObserver) { + this.propertyObserver.disconnect(); + this.propertyObserver = null; + } + this._sync = null; + + if (select2 !== undefined) { + select2.container.remove(); + select2.liveRegion.remove(); + select2.dropdown.remove(); + element.removeData("select2") + .off(".select2"); + if (!element.is("input[type='hidden']")) { + element + .show() + .prop("autofocus", this.autofocus || false); + if (this.elementTabIndex) { + element.attr({tabindex: this.elementTabIndex}); + } else { + element.removeAttr("tabindex"); + } + element.show(); + } else { + element.css("display", ""); + } + } + + cleanupJQueryElements.call(this, + "container", + "liveRegion", + "dropdown", + "results", + "search" + ); + }, + + // abstract + optionToData: function(element) { + if (element.is("option")) { + return { + id:element.prop("value"), + text:element.text(), + element: element.get(), + css: element.attr("class"), + disabled: element.prop("disabled"), + locked: equal(element.attr("locked"), "locked") || equal(element.data("locked"), true) + }; + } else if (element.is("optgroup")) { + return { + text:element.attr("label"), + children:[], + element: element.get(), + css: element.attr("class") + }; + } + }, + + // abstract + prepareOpts: function (opts) { + var element, select, idKey, ajaxUrl, self = this; + + element = opts.element; + + if (element.get(0).tagName.toLowerCase() === "select") { + this.select = select = opts.element; + } + + if (select) { + // these options are not allowed when attached to a select because they are picked up off the element itself + $.each(["id", "multiple", "ajax", "query", "createSearchChoice", "initSelection", "data", "tags"], function () { + if (this in opts) { + throw new Error("Option '" + this + "' is not allowed for Select2 when attached to a <select> element."); + } + }); + } + + opts.debug = opts.debug || $.fn.select2.defaults.debug; + + // Warnings for options renamed/removed in Select2 4.0.0 + // Only when it's enabled through debug mode + if (opts.debug && console && console.warn) { + // id was removed + if (opts.id != null) { + console.warn( + 'Select2: The `id` option has been removed in Select2 4.0.0, ' + + 'consider renaming your `id` property or mapping the property before your data makes it to Select2. ' + + 'You can read more at https://select2.github.io/announcements-4.0.html#changed-id' + ); + } + + // text was removed + if (opts.text != null) { + console.warn( + 'Select2: The `text` option has been removed in Select2 4.0.0, ' + + 'consider renaming your `text` property or mapping the property before your data makes it to Select2. ' + + 'You can read more at https://select2.github.io/announcements-4.0.html#changed-id' + ); + } + + // sortResults was renamed to results + if (opts.sortResults != null) { + console.warn( + 'Select2: the `sortResults` option has been renamed to `sorter` in Select2 4.0.0. ' + ); + } + + // selectOnBlur was renamed to selectOnClose + if (opts.selectOnBlur != null) { + console.warn( + 'Select2: The `selectOnBlur` option has been renamed to `selectOnClose` in Select2 4.0.0.' + ); + } + + // ajax.results was renamed to ajax.processResults + if (opts.ajax != null && opts.ajax.results != null) { + console.warn( + 'Select2: The `ajax.results` option has been renamed to `ajax.processResults` in Select2 4.0.0.' + ); + } + + // format* options were renamed to language.* + if (opts.formatNoResults != null) { + console.warn( + 'Select2: The `formatNoResults` option has been renamed to `language.noResults` in Select2 4.0.0.' + ); + } + if (opts.formatSearching != null) { + console.warn( + 'Select2: The `formatSearching` option has been renamed to `language.searching` in Select2 4.0.0.' + ); + } + if (opts.formatInputTooShort != null) { + console.warn( + 'Select2: The `formatInputTooShort` option has been renamed to `language.inputTooShort` in Select2 4.0.0.' + ); + } + if (opts.formatInputTooLong != null) { + console.warn( + 'Select2: The `formatInputTooLong` option has been renamed to `language.inputTooLong` in Select2 4.0.0.' + ); + } + if (opts.formatLoading != null) { + console.warn( + 'Select2: The `formatLoading` option has been renamed to `language.loadingMore` in Select2 4.0.0.' + ); + } + if (opts.formatSelectionTooBig != null) { + console.warn( + 'Select2: The `formatSelectionTooBig` option has been renamed to `language.maximumSelected` in Select2 4.0.0.' + ); + } + + if (opts.element.data('select2Tags')) { + console.warn( + 'Select2: The `data-select2-tags` attribute has been renamed to `data-tags` in Select2 4.0.0.' + ); + } + } + + // Aliasing options renamed in Select2 4.0.0 + + // data-select2-tags -> data-tags + if (opts.element.data('tags') != null) { + var elemTags = opts.element.data('tags'); + + // data-tags should actually be a boolean + if (!$.isArray(elemTags)) { + elemTags = []; + } + + opts.element.data('select2Tags', elemTags); + } + + // sortResults -> sorter + if (opts.sorter != null) { + opts.sortResults = opts.sorter; + } + + // selectOnBlur -> selectOnClose + if (opts.selectOnClose != null) { + opts.selectOnBlur = opts.selectOnClose; + } + + // ajax.results -> ajax.processResults + if (opts.ajax != null) { + if ($.isFunction(opts.ajax.processResults)) { + opts.ajax.results = opts.ajax.processResults; + } + } + + // Formatters/language options + if (opts.language != null) { + var lang = opts.language; + + // formatNoMatches -> language.noMatches + if ($.isFunction(lang.noMatches)) { + opts.formatNoMatches = lang.noMatches; + } + + // formatSearching -> language.searching + if ($.isFunction(lang.searching)) { + opts.formatSearching = lang.searching; + } + + // formatInputTooShort -> language.inputTooShort + if ($.isFunction(lang.inputTooShort)) { + opts.formatInputTooShort = lang.inputTooShort; + } + + // formatInputTooLong -> language.inputTooLong + if ($.isFunction(lang.inputTooLong)) { + opts.formatInputTooLong = lang.inputTooLong; + } + + // formatLoading -> language.loadingMore + if ($.isFunction(lang.loadingMore)) { + opts.formatLoading = lang.loadingMore; + } + + // formatSelectionTooBig -> language.maximumSelected + if ($.isFunction(lang.maximumSelected)) { + opts.formatSelectionTooBig = lang.maximumSelected; + } + } + + opts = $.extend({}, { + populateResults: function(container, results, query) { + var populate, id=this.opts.id, liveRegion=this.liveRegion; + + populate=function(results, container, depth) { + + var i, l, result, selectable, disabled, compound, node, label, innerContainer, formatted; + + results = opts.sortResults(results, container, query); + + // collect the created nodes for bulk append + var nodes = []; + for (i = 0, l = results.length; i < l; i = i + 1) { + + result=results[i]; + + disabled = (result.disabled === true); + selectable = (!disabled) && (id(result) !== undefined); + + compound=result.children && result.children.length > 0; + + node=$("<li></li>"); + node.addClass("select2-results-dept-"+depth); + node.addClass("select2-result"); + node.addClass(selectable ? "select2-result-selectable" : "select2-result-unselectable"); + if (disabled) { node.addClass("select2-disabled"); } + if (compound) { node.addClass("select2-result-with-children"); } + node.addClass(self.opts.formatResultCssClass(result)); + node.attr("role", "presentation"); + + label=$(document.createElement("div")); + label.addClass("select2-result-label"); + label.attr("id", "select2-result-label-" + nextUid()); + label.attr("role", "option"); + + formatted=opts.formatResult(result, label, query, self.opts.escapeMarkup); + if (formatted!==undefined) { + label.html(formatted); + node.append(label); + } + + + if (compound) { + innerContainer=$("<ul></ul>"); + innerContainer.addClass("select2-result-sub"); + populate(result.children, innerContainer, depth+1); + node.append(innerContainer); + } + + node.data("select2-data", result); + nodes.push(node[0]); + } + + // bulk append the created nodes + container.append(nodes); + liveRegion.text(opts.formatMatches(results.length)); + }; + + populate(results, container, 0); + } + }, $.fn.select2.defaults, opts); + + if (typeof(opts.id) !== "function") { + idKey = opts.id; + opts.id = function (e) { return e[idKey]; }; + } + + if ($.isArray(opts.element.data("select2Tags"))) { + if ("tags" in opts) { + throw "tags specified as both an attribute 'data-select2-tags' and in options of Select2 " + opts.element.attr("id"); + } + opts.tags=opts.element.data("select2Tags"); + } + + if (select) { + opts.query = this.bind(function (query) { + var data = { results: [], more: false }, + term = query.term, + children, placeholderOption, process; + + process=function(element, collection) { + var group; + if (element.is("option")) { + if (query.matcher(term, element.text(), element)) { + collection.push(self.optionToData(element)); + } + } else if (element.is("optgroup")) { + group=self.optionToData(element); + element.children().each2(function(i, elm) { process(elm, group.children); }); + if (group.children.length>0) { + collection.push(group); + } + } + }; + + children=element.children(); + + // ignore the placeholder option if there is one + if (this.getPlaceholder() !== undefined && children.length > 0) { + placeholderOption = this.getPlaceholderOption(); + if (placeholderOption) { + children=children.not(placeholderOption); + } + } + + children.each2(function(i, elm) { process(elm, data.results); }); + + query.callback(data); + }); + // this is needed because inside val() we construct choices from options and their id is hardcoded + opts.id=function(e) { return e.id; }; + } else { + if (!("query" in opts)) { + if ("ajax" in opts) { + ajaxUrl = opts.element.data("ajax-url"); + if (ajaxUrl && ajaxUrl.length > 0) { + opts.ajax.url = ajaxUrl; + } + opts.query = ajax.call(opts.element, opts.ajax); + } else if ("data" in opts) { + opts.query = local(opts.data); + } else if ("tags" in opts) { + opts.query = tags(opts.tags); + if (opts.createSearchChoice === undefined) { + opts.createSearchChoice = function (term) { return {id: $.trim(term), text: $.trim(term)}; }; + } + if (opts.initSelection === undefined) { + opts.initSelection = function (element, callback) { + var data = []; + $(splitVal(element.val(), opts.separator, opts.transformVal)).each(function () { + var obj = { id: this, text: this }, + tags = opts.tags; + if ($.isFunction(tags)) tags=tags(); + $(tags).each(function() { if (equal(this.id, obj.id)) { obj = this; return false; } }); + data.push(obj); + }); + + callback(data); + }; + } + } + } + } + if (typeof(opts.query) !== "function") { + throw "query function not defined for Select2 " + opts.element.attr("id"); + } + + if (opts.createSearchChoicePosition === 'top') { + opts.createSearchChoicePosition = function(list, item) { list.unshift(item); }; + } + else if (opts.createSearchChoicePosition === 'bottom') { + opts.createSearchChoicePosition = function(list, item) { list.push(item); }; + } + else if (typeof(opts.createSearchChoicePosition) !== "function") { + throw "invalid createSearchChoicePosition option must be 'top', 'bottom' or a custom function"; + } + + return opts; + }, + + /** + * Monitor the original element for changes and update select2 accordingly + */ + // abstract + monitorSource: function () { + var el = this.opts.element, observer, self = this; + + el.on("change.select2", this.bind(function (e) { + if (this.opts.element.data("select2-change-triggered") !== true) { + this.initSelection(); + } + })); + + this._sync = this.bind(function () { + + // sync enabled state + var disabled = el.prop("disabled"); + if (disabled === undefined) disabled = false; + this.enable(!disabled); + + var readonly = el.prop("readonly"); + if (readonly === undefined) readonly = false; + this.readonly(readonly); + + if (this.container) { + syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass); + this.container.addClass(evaluate(this.opts.containerCssClass, this.opts.element)); + } + + if (this.dropdown) { + syncCssClasses(this.dropdown, this.opts.element, this.opts.adaptDropdownCssClass); + this.dropdown.addClass(evaluate(this.opts.dropdownCssClass, this.opts.element)); + } + + }); + + // IE8-10 (IE9/10 won't fire propertyChange via attachEventListener) + if (el.length && el[0].attachEvent) { + el.each(function() { + this.attachEvent("onpropertychange", self._sync); + }); + } + + // safari, chrome, firefox, IE11 + observer = window.MutationObserver || window.WebKitMutationObserver|| window.MozMutationObserver; + if (observer !== undefined) { + if (this.propertyObserver) { delete this.propertyObserver; this.propertyObserver = null; } + this.propertyObserver = new observer(function (mutations) { + $.each(mutations, self._sync); + }); + this.propertyObserver.observe(el.get(0), { attributes:true, subtree:false }); + } + }, + + // abstract + triggerSelect: function(data) { + var evt = $.Event("select2-selecting", { val: this.id(data), object: data, choice: data }); + this.opts.element.trigger(evt); + return !evt.isDefaultPrevented(); + }, + + /** + * Triggers the change event on the source element + */ + // abstract + triggerChange: function (details) { + + details = details || {}; + details= $.extend({}, details, { type: "change", val: this.val() }); + // prevents recursive triggering + this.opts.element.data("select2-change-triggered", true); + this.opts.element.trigger(details); + this.opts.element.data("select2-change-triggered", false); + + // some validation frameworks ignore the change event and listen instead to keyup, click for selects + // so here we trigger the click event manually + this.opts.element.click(); + + // ValidationEngine ignores the change event and listens instead to blur + // so here we trigger the blur event manually if so desired + if (this.opts.blurOnChange) + this.opts.element.blur(); + }, + + //abstract + isInterfaceEnabled: function() + { + return this.enabledInterface === true; + }, + + // abstract + enableInterface: function() { + var enabled = this._enabled && !this._readonly, + disabled = !enabled; + + if (enabled === this.enabledInterface) return false; + + this.container.toggleClass("select2-container-disabled", disabled); + this.close(); + this.enabledInterface = enabled; + + return true; + }, + + // abstract + enable: function(enabled) { + if (enabled === undefined) enabled = true; + if (this._enabled === enabled) return; + this._enabled = enabled; + + this.opts.element.prop("disabled", !enabled); + this.enableInterface(); + }, + + // abstract + disable: function() { + this.enable(false); + }, + + // abstract + readonly: function(enabled) { + if (enabled === undefined) enabled = false; + if (this._readonly === enabled) return; + this._readonly = enabled; + + this.opts.element.prop("readonly", enabled); + this.enableInterface(); + }, + + // abstract + opened: function () { + return (this.container) ? this.container.hasClass("select2-dropdown-open") : false; + }, + + // abstract + positionDropdown: function() { + var $dropdown = this.dropdown, + container = this.container, + offset = container.offset(), + height = container.outerHeight(false), + width = container.outerWidth(false), + dropHeight = $dropdown.outerHeight(false), + $window = $(window), + windowWidth = $window.width(), + windowHeight = $window.height(), + viewPortRight = $window.scrollLeft() + windowWidth, + viewportBottom = $window.scrollTop() + windowHeight, + dropTop = offset.top + height, + dropLeft = offset.left, + enoughRoomBelow = dropTop + dropHeight <= viewportBottom, + enoughRoomAbove = (offset.top - dropHeight) >= $window.scrollTop(), + dropWidth = $dropdown.outerWidth(false), + enoughRoomOnRight = function() { + return dropLeft + dropWidth <= viewPortRight; + }, + enoughRoomOnLeft = function() { + return offset.left + viewPortRight + container.outerWidth(false) > dropWidth; + }, + aboveNow = $dropdown.hasClass("select2-drop-above"), + bodyOffset, + above, + changeDirection, + css, + resultsListNode; + + // always prefer the current above/below alignment, unless there is not enough room + if (aboveNow) { + above = true; + if (!enoughRoomAbove && enoughRoomBelow) { + changeDirection = true; + above = false; + } + } else { + above = false; + if (!enoughRoomBelow && enoughRoomAbove) { + changeDirection = true; + above = true; + } + } + + //if we are changing direction we need to get positions when dropdown is hidden; + if (changeDirection) { + $dropdown.hide(); + offset = this.container.offset(); + height = this.container.outerHeight(false); + width = this.container.outerWidth(false); + dropHeight = $dropdown.outerHeight(false); + viewPortRight = $window.scrollLeft() + windowWidth; + viewportBottom = $window.scrollTop() + windowHeight; + dropTop = offset.top + height; + dropLeft = offset.left; + dropWidth = $dropdown.outerWidth(false); + $dropdown.show(); + + // fix so the cursor does not move to the left within the search-textbox in IE + this.focusSearch(); + } + + if (this.opts.dropdownAutoWidth) { + resultsListNode = $('.select2-results', $dropdown)[0]; + $dropdown.addClass('select2-drop-auto-width'); + $dropdown.css('width', ''); + // Add scrollbar width to dropdown if vertical scrollbar is present + dropWidth = $dropdown.outerWidth(false) + (resultsListNode.scrollHeight === resultsListNode.clientHeight ? 0 : scrollBarDimensions.width); + dropWidth > width ? width = dropWidth : dropWidth = width; + dropHeight = $dropdown.outerHeight(false); + } + else { + this.container.removeClass('select2-drop-auto-width'); + } + + //console.log("below/ droptop:", dropTop, "dropHeight", dropHeight, "sum", (dropTop+dropHeight)+" viewport bottom", viewportBottom, "enough?", enoughRoomBelow); + //console.log("above/ offset.top", offset.top, "dropHeight", dropHeight, "top", (offset.top-dropHeight), "scrollTop", this.body.scrollTop(), "enough?", enoughRoomAbove); + + // fix positioning when body has an offset and is not position: static + if (this.body.css('position') !== 'static') { + bodyOffset = this.body.offset(); + dropTop -= bodyOffset.top; + dropLeft -= bodyOffset.left; + } + + if (!enoughRoomOnRight() && enoughRoomOnLeft()) { + dropLeft = offset.left + this.container.outerWidth(false) - dropWidth; + } + + css = { + left: dropLeft, + width: width + }; + + if (above) { + this.container.addClass("select2-drop-above"); + $dropdown.addClass("select2-drop-above"); + dropHeight = $dropdown.outerHeight(false); + css.top = offset.top - dropHeight; + css.bottom = 'auto'; + } + else { + css.top = dropTop; + css.bottom = 'auto'; + this.container.removeClass("select2-drop-above"); + $dropdown.removeClass("select2-drop-above"); + } + css = $.extend(css, evaluate(this.opts.dropdownCss, this.opts.element)); + + $dropdown.css(css); + }, + + // abstract + shouldOpen: function() { + var event; + + if (this.opened()) return false; + + if (this._enabled === false || this._readonly === true) return false; + + event = $.Event("select2-opening"); + this.opts.element.trigger(event); + return !event.isDefaultPrevented(); + }, + + // abstract + clearDropdownAlignmentPreference: function() { + // clear the classes used to figure out the preference of where the dropdown should be opened + this.container.removeClass("select2-drop-above"); + this.dropdown.removeClass("select2-drop-above"); + }, + + /** + * Opens the dropdown + * + * @return {Boolean} whether or not dropdown was opened. This method will return false if, for example, + * the dropdown is already open, or if the 'open' event listener on the element called preventDefault(). + */ + // abstract + open: function () { + + if (!this.shouldOpen()) return false; + + this.opening(); + + // Only bind the document mousemove when the dropdown is visible + $document.on("mousemove.select2Event", function (e) { + lastMousePosition.x = e.pageX; + lastMousePosition.y = e.pageY; + }); + + return true; + }, + + /** + * Performs the opening of the dropdown + */ + // abstract + opening: function() { + var cid = this.containerEventName, + scroll = "scroll." + cid, + resize = "resize."+cid, + orient = "orientationchange."+cid, + mask; + + this.container.addClass("select2-dropdown-open").addClass("select2-container-active"); + + this.clearDropdownAlignmentPreference(); + + if(this.dropdown[0] !== this.body.children().last()[0]) { + this.dropdown.detach().appendTo(this.body); + } + + // create the dropdown mask if doesn't already exist + mask = $("#select2-drop-mask"); + if (mask.length === 0) { + mask = $(document.createElement("div")); + mask.attr("id","select2-drop-mask").attr("class","select2-drop-mask"); + mask.hide(); + mask.appendTo(this.body); + mask.on("mousedown touchstart click", function (e) { + // Prevent IE from generating a click event on the body + reinsertElement(mask); + + var dropdown = $("#select2-drop"), self; + if (dropdown.length > 0) { + self=dropdown.data("select2"); + if (self.opts.selectOnBlur) { + self.selectHighlighted({noFocus: true}); + } + self.close(); + e.preventDefault(); + e.stopPropagation(); + } + }); + } + + // ensure the mask is always right before the dropdown + if (this.dropdown.prev()[0] !== mask[0]) { + this.dropdown.before(mask); + } + + // move the global id to the correct dropdown + $("#select2-drop").removeAttr("id"); + this.dropdown.attr("id", "select2-drop"); + + // show the elements + mask.show(); + + this.positionDropdown(); + this.dropdown.show(); + this.positionDropdown(); + + this.dropdown.addClass("select2-drop-active"); + + // attach listeners to events that can change the position of the container and thus require + // the position of the dropdown to be updated as well so it does not come unglued from the container + var that = this; + this.container.parents().add(window).each(function () { + $(this).on(resize+" "+scroll+" "+orient, function (e) { + if (that.opened()) that.positionDropdown(); + }); + }); + + + }, + + // abstract + close: function () { + if (!this.opened()) return; + + var cid = this.containerEventName, + scroll = "scroll." + cid, + resize = "resize."+cid, + orient = "orientationchange."+cid; + + // unbind event listeners + this.container.parents().add(window).each(function () { $(this).off(scroll).off(resize).off(orient); }); + + this.clearDropdownAlignmentPreference(); + + $("#select2-drop-mask").hide(); + this.dropdown.removeAttr("id"); // only the active dropdown has the select2-drop id + this.dropdown.hide(); + this.container.removeClass("select2-dropdown-open").removeClass("select2-container-active"); + this.results.empty(); + + // Now that the dropdown is closed, unbind the global document mousemove event + $document.off("mousemove.select2Event"); + + this.clearSearch(); + this.search.removeClass("select2-active"); + + // Remove the aria active descendant for highlighted element + this.search.removeAttr("aria-activedescendant"); + this.opts.element.trigger($.Event("select2-close")); + }, + + /** + * Opens control, sets input value, and updates results. + */ + // abstract + externalSearch: function (term) { + this.open(); + this.search.val(term); + this.updateResults(false); + }, + + // abstract + clearSearch: function () { + + }, + + /** + * @return {Boolean} Whether or not search value was changed. + * @private + */ + prefillNextSearchTerm: function () { + // initializes search's value with nextSearchTerm (if defined by user) + // ignore nextSearchTerm if the dropdown is opened by the user pressing a letter + if(this.search.val() !== "") { + return false; + } + + var nextSearchTerm = this.opts.nextSearchTerm(this.data(), this.lastSearchTerm); + if(nextSearchTerm !== undefined){ + this.search.val(nextSearchTerm); + this.search.select(); + return true; + } + + return false; + }, + + //abstract + getMaximumSelectionSize: function() { + return evaluate(this.opts.maximumSelectionSize, this.opts.element); + }, + + // abstract + ensureHighlightVisible: function () { + var results = this.results, children, index, child, hb, rb, y, more, topOffset; + + index = this.highlight(); + + if (index < 0) return; + + if (index == 0) { + + // if the first element is highlighted scroll all the way to the top, + // that way any unselectable headers above it will also be scrolled + // into view + + results.scrollTop(0); + return; + } + + children = this.findHighlightableChoices().find('.select2-result-label'); + + child = $(children[index]); + + topOffset = (child.offset() || {}).top || 0; + + hb = topOffset + child.outerHeight(true); + + // if this is the last child lets also make sure select2-more-results is visible + if (index === children.length - 1) { + more = results.find("li.select2-more-results"); + if (more.length > 0) { + hb = more.offset().top + more.outerHeight(true); + } + } + + rb = results.offset().top + results.outerHeight(false); + if (hb > rb) { + results.scrollTop(results.scrollTop() + (hb - rb)); + } + y = topOffset - results.offset().top; + + // make sure the top of the element is visible + if (y < 0 && child.css('display') != 'none' ) { + results.scrollTop(results.scrollTop() + y); // y is negative + } + }, + + // abstract + findHighlightableChoices: function() { + return this.results.find(".select2-result-selectable:not(.select2-disabled):not(.select2-selected)"); + }, + + // abstract + moveHighlight: function (delta) { + var choices = this.findHighlightableChoices(), + index = this.highlight(); + + while (index > -1 && index < choices.length) { + index += delta; + var choice = $(choices[index]); + if (choice.hasClass("select2-result-selectable") && !choice.hasClass("select2-disabled") && !choice.hasClass("select2-selected")) { + this.highlight(index); + break; + } + } + }, + + // abstract + highlight: function (index) { + var choices = this.findHighlightableChoices(), + choice, + data; + + if (arguments.length === 0) { + return indexOf(choices.filter(".select2-highlighted")[0], choices.get()); + } + + if (index >= choices.length) index = choices.length - 1; + if (index < 0) index = 0; + + this.removeHighlight(); + + choice = $(choices[index]); + choice.addClass("select2-highlighted"); + + // ensure assistive technology can determine the active choice + this.search.attr("aria-activedescendant", choice.find(".select2-result-label").attr("id")); + + this.ensureHighlightVisible(); + + this.liveRegion.text(choice.text()); + + data = choice.data("select2-data"); + if (data) { + this.opts.element.trigger({ type: "select2-highlight", val: this.id(data), choice: data }); + } + }, + + removeHighlight: function() { + this.results.find(".select2-highlighted").removeClass("select2-highlighted"); + }, + + touchMoved: function() { + this._touchMoved = true; + }, + + clearTouchMoved: function() { + this._touchMoved = false; + }, + + // abstract + countSelectableResults: function() { + return this.findHighlightableChoices().length; + }, + + // abstract + highlightUnderEvent: function (event) { + var el = $(event.target).closest(".select2-result-selectable"); + if (el.length > 0 && !el.is(".select2-highlighted")) { + var choices = this.findHighlightableChoices(); + this.highlight(choices.index(el)); + } else if (el.length == 0) { + // if we are over an unselectable item remove all highlights + this.removeHighlight(); + } + }, + + // abstract + loadMoreIfNeeded: function () { + var results = this.results, + more = results.find("li.select2-more-results"), + below, // pixels the element is below the scroll fold, below==0 is when the element is starting to be visible + page = this.resultsPage + 1, + self=this, + term=this.search.val(), + context=this.context; + + if (more.length === 0) return; + below = more.offset().top - results.offset().top - results.height(); + + if (below <= this.opts.loadMorePadding) { + more.addClass("select2-active"); + this.opts.query({ + element: this.opts.element, + term: term, + page: page, + context: context, + matcher: this.opts.matcher, + callback: this.bind(function (data) { + + // ignore a response if the select2 has been closed before it was received + if (!self.opened()) return; + + + self.opts.populateResults.call(this, results, data.results, {term: term, page: page, context:context}); + self.postprocessResults(data, false, false); + + if (data.more===true) { + more.detach().appendTo(results).html(self.opts.escapeMarkup(evaluate(self.opts.formatLoadMore, self.opts.element, page+1))); + window.setTimeout(function() { self.loadMoreIfNeeded(); }, 10); + } else { + more.remove(); + } + self.positionDropdown(); + self.resultsPage = page; + self.context = data.context; + this.opts.element.trigger({ type: "select2-loaded", items: data }); + })}); + } + }, + + /** + * Default tokenizer function which does nothing + */ + tokenize: function() { + + }, + + /** + * @param initial whether or not this is the call to this method right after the dropdown has been opened + */ + // abstract + updateResults: function (initial) { + var search = this.search, + results = this.results, + opts = this.opts, + data, + self = this, + input, + term = search.val(), + lastTerm = $.data(this.container, "select2-last-term"), + // sequence number used to drop out-of-order responses + queryNumber; + + // prevent duplicate queries against the same term + if (initial !== true && lastTerm && equal(term, lastTerm)) return; + + $.data(this.container, "select2-last-term", term); + + // if the search is currently hidden we do not alter the results + if (initial !== true && (this.showSearchInput === false || !this.opened())) { + return; + } + + function postRender() { + search.removeClass("select2-active"); + self.positionDropdown(); + if (results.find('.select2-no-results,.select2-selection-limit,.select2-searching').length) { + self.liveRegion.text(results.text()); + } + else { + self.liveRegion.text(self.opts.formatMatches(results.find('.select2-result-selectable:not(".select2-selected")').length)); + } + } + + function render(html) { + results.html(html); + postRender(); + } + + queryNumber = ++this.queryCount; + + var maxSelSize = this.getMaximumSelectionSize(); + if (maxSelSize >=1) { + data = this.data(); + if ($.isArray(data) && data.length >= maxSelSize && checkFormatter(opts.formatSelectionTooBig, "formatSelectionTooBig")) { + render("<li class='select2-selection-limit'>" + evaluate(opts.formatSelectionTooBig, opts.element, maxSelSize) + "</li>"); + return; + } + } + + if (search.val().length < opts.minimumInputLength) { + if (checkFormatter(opts.formatInputTooShort, "formatInputTooShort")) { + render("<li class='select2-no-results'>" + evaluate(opts.formatInputTooShort, opts.element, search.val(), opts.minimumInputLength) + "</li>"); + } else { + render(""); + } + if (initial && this.showSearch) this.showSearch(true); + return; + } + + if (opts.maximumInputLength && search.val().length > opts.maximumInputLength) { + if (checkFormatter(opts.formatInputTooLong, "formatInputTooLong")) { + render("<li class='select2-no-results'>" + evaluate(opts.formatInputTooLong, opts.element, search.val(), opts.maximumInputLength) + "</li>"); + } else { + render(""); + } + return; + } + + if (opts.formatSearching && this.findHighlightableChoices().length === 0) { + render("<li class='select2-searching'>" + evaluate(opts.formatSearching, opts.element) + "</li>"); + } + + search.addClass("select2-active"); + + this.removeHighlight(); + + // give the tokenizer a chance to pre-process the input + input = this.tokenize(); + if (input != undefined && input != null) { + search.val(input); + } + + this.resultsPage = 1; + + opts.query({ + element: opts.element, + term: search.val(), + page: this.resultsPage, + context: null, + matcher: opts.matcher, + callback: this.bind(function (data) { + var def; // default choice + + // ignore old responses + if (queryNumber != this.queryCount) { + return; + } + + // ignore a response if the select2 has been closed before it was received + if (!this.opened()) { + this.search.removeClass("select2-active"); + return; + } + + // handle ajax error + if(data.hasError !== undefined && checkFormatter(opts.formatAjaxError, "formatAjaxError")) { + render("<li class='select2-ajax-error'>" + evaluate(opts.formatAjaxError, opts.element, data.jqXHR, data.textStatus, data.errorThrown) + "</li>"); + return; + } + + // save context, if any + this.context = (data.context===undefined) ? null : data.context; + // create a default choice and prepend it to the list + if (this.opts.createSearchChoice && search.val() !== "") { + def = this.opts.createSearchChoice.call(self, search.val(), data.results); + if (def !== undefined && def !== null && self.id(def) !== undefined && self.id(def) !== null) { + if ($(data.results).filter( + function () { + return equal(self.id(this), self.id(def)); + }).length === 0) { + this.opts.createSearchChoicePosition(data.results, def); + } + } + } + + if (data.results.length === 0 && checkFormatter(opts.formatNoMatches, "formatNoMatches")) { + render("<li class='select2-no-results'>" + evaluate(opts.formatNoMatches, opts.element, search.val()) + "</li>"); + if(this.showSearch){ + this.showSearch(search.val()); + } + return; + } + + results.empty(); + self.opts.populateResults.call(this, results, data.results, {term: search.val(), page: this.resultsPage, context:null}); + + if (data.more === true && checkFormatter(opts.formatLoadMore, "formatLoadMore")) { + results.append("<li class='select2-more-results'>" + opts.escapeMarkup(evaluate(opts.formatLoadMore, opts.element, this.resultsPage)) + "</li>"); + window.setTimeout(function() { self.loadMoreIfNeeded(); }, 10); + } + + this.postprocessResults(data, initial); + + postRender(); + + this.opts.element.trigger({ type: "select2-loaded", items: data }); + })}); + }, + + // abstract + cancel: function () { + this.close(); + }, + + // abstract + blur: function () { + // if selectOnBlur == true, select the currently highlighted option + if (this.opts.selectOnBlur) + this.selectHighlighted({noFocus: true}); + + this.close(); + this.container.removeClass("select2-container-active"); + // synonymous to .is(':focus'), which is available in jquery >= 1.6 + if (this.search[0] === document.activeElement) { this.search.blur(); } + this.clearSearch(); + this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus"); + }, + + // abstract + focusSearch: function () { + focus(this.search); + }, + + // abstract + selectHighlighted: function (options) { + if (this._touchMoved) { + this.clearTouchMoved(); + return; + } + var index=this.highlight(), + highlighted=this.results.find(".select2-highlighted"), + data = highlighted.closest('.select2-result').data("select2-data"); + + if (data) { + this.highlight(index); + this.onSelect(data, options); + } else if (options && options.noFocus) { + this.close(); + } + }, + + // abstract + getPlaceholder: function () { + var placeholderOption; + return this.opts.element.attr("placeholder") || + this.opts.element.attr("data-placeholder") || // jquery 1.4 compat + this.opts.element.data("placeholder") || + this.opts.placeholder || + ((placeholderOption = this.getPlaceholderOption()) !== undefined ? placeholderOption.text() : undefined); + }, + + // abstract + getPlaceholderOption: function() { + if (this.select) { + var firstOption = this.select.children('option').first(); + if (this.opts.placeholderOption !== undefined ) { + //Determine the placeholder option based on the specified placeholderOption setting + return (this.opts.placeholderOption === "first" && firstOption) || + (typeof this.opts.placeholderOption === "function" && this.opts.placeholderOption(this.select)); + } else if ($.trim(firstOption.text()) === "" && firstOption.val() === "") { + //No explicit placeholder option specified, use the first if it's blank + return firstOption; + } + } + }, + + /** + * Get the desired width for the container element. This is + * derived first from option `width` passed to select2, then + * the inline 'style' on the original element, and finally + * falls back to the jQuery calculated element width. + */ + // abstract + initContainerWidth: function () { + function resolveContainerWidth() { + var style, attrs, matches, i, l, attr; + + if (this.opts.width === "off") { + return null; + } else if (this.opts.width === "element"){ + return this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px'; + } else if (this.opts.width === "copy" || this.opts.width === "resolve") { + // check if there is inline style on the element that contains width + style = this.opts.element.attr('style'); + if (typeof(style) === "string") { + attrs = style.split(';'); + for (i = 0, l = attrs.length; i < l; i = i + 1) { + attr = attrs[i].replace(/\s/g, ''); + matches = attr.match(/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i); + if (matches !== null && matches.length >= 1) + return matches[1]; + } + } + + if (this.opts.width === "resolve") { + // next check if css('width') can resolve a width that is percent based, this is sometimes possible + // when attached to input type=hidden or elements hidden via css + style = this.opts.element.css('width'); + if (style.indexOf("%") > 0) return style; + + // finally, fallback on the calculated width of the element + return (this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px'); + } + + return null; + } else if ($.isFunction(this.opts.width)) { + return this.opts.width(); + } else { + return this.opts.width; + } + }; + + var width = resolveContainerWidth.call(this); + if (width !== null) { + this.container.css("width", width); + } + } + }); + + SingleSelect2 = clazz(AbstractSelect2, { + + // single + + createContainer: function () { + var container = $(document.createElement("div")).attr({ + "class": "select2-container" + }).html([ + "<a href='javascript:void(0)' class='select2-choice' tabindex='-1'>", + " <span class='select2-chosen'> </span><abbr class='select2-search-choice-close'></abbr>", + " <span class='select2-arrow' role='presentation'><b role='presentation'></b></span>", + "</a>", + "<label for='' class='select2-offscreen'></label>", + "<input class='select2-focusser select2-offscreen' type='text' aria-haspopup='true' role='button' />", + "<div class='select2-drop select2-display-none'>", + " <div class='select2-search'>", + " <label for='' class='select2-offscreen'></label>", + " <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input' role='combobox' aria-expanded='true'", + " aria-autocomplete='list' />", + " </div>", + " <ul class='select2-results' role='listbox'>", + " </ul>", + "</div>"].join("")); + return container; + }, + + // single + enableInterface: function() { + if (this.parent.enableInterface.apply(this, arguments)) { + this.focusser.prop("disabled", !this.isInterfaceEnabled()); + } + }, + + // single + opening: function () { + var el, range, len; + + if (this.opts.minimumResultsForSearch >= 0) { + this.showSearch(true); + } + + this.parent.opening.apply(this, arguments); + + if (this.showSearchInput !== false) { + // IE appends focusser.val() at the end of field :/ so we manually insert it at the beginning using a range + // all other browsers handle this just fine + + this.search.val(this.focusser.val()); + } + if (this.opts.shouldFocusInput(this)) { + this.search.focus(); + // move the cursor to the end after focussing, otherwise it will be at the beginning and + // new text will appear *before* focusser.val() + el = this.search.get(0); + if (el.createTextRange) { + range = el.createTextRange(); + range.collapse(false); + range.select(); + } else if (el.setSelectionRange) { + len = this.search.val().length; + el.setSelectionRange(len, len); + } + } + + this.prefillNextSearchTerm(); + + this.focusser.prop("disabled", true).val(""); + this.updateResults(true); + this.opts.element.trigger($.Event("select2-open")); + }, + + // single + close: function () { + if (!this.opened()) return; + this.parent.close.apply(this, arguments); + + this.focusser.prop("disabled", false); + + if (this.opts.shouldFocusInput(this)) { + this.focusser.focus(); + } + }, + + // single + focus: function () { + if (this.opened()) { + this.close(); + } else { + this.focusser.prop("disabled", false); + if (this.opts.shouldFocusInput(this)) { + this.focusser.focus(); + } + } + }, + + // single + isFocused: function () { + return this.container.hasClass("select2-container-active"); + }, + + // single + cancel: function () { + this.parent.cancel.apply(this, arguments); + this.focusser.prop("disabled", false); + + if (this.opts.shouldFocusInput(this)) { + this.focusser.focus(); + } + }, + + // single + destroy: function() { + $("label[for='" + this.focusser.attr('id') + "']") + .attr('for', this.opts.element.attr("id")); + this.parent.destroy.apply(this, arguments); + + cleanupJQueryElements.call(this, + "selection", + "focusser" + ); + }, + + // single + initContainer: function () { + + var selection, + container = this.container, + dropdown = this.dropdown, + idSuffix = nextUid(), + elementLabel; + + if (this.opts.minimumResultsForSearch < 0) { + this.showSearch(false); + } else { + this.showSearch(true); + } + + this.selection = selection = container.find(".select2-choice"); + + this.focusser = container.find(".select2-focusser"); + + // add aria associations + selection.find(".select2-chosen").attr("id", "select2-chosen-"+idSuffix); + this.focusser.attr("aria-labelledby", "select2-chosen-"+idSuffix); + this.results.attr("id", "select2-results-"+idSuffix); + this.search.attr("aria-owns", "select2-results-"+idSuffix); + + // rewrite labels from original element to focusser + this.focusser.attr("id", "s2id_autogen"+idSuffix); + + elementLabel = $("label[for='" + this.opts.element.attr("id") + "']"); + this.opts.element.on('focus.select2', this.bind(function () { this.focus(); })); + + this.focusser.prev() + .text(elementLabel.text()) + .attr('for', this.focusser.attr('id')); + + // Ensure the original element retains an accessible name + var originalTitle = this.opts.element.attr("title"); + this.opts.element.attr("title", (originalTitle || elementLabel.text())); + + this.focusser.attr("tabindex", this.elementTabIndex); + + // write label for search field using the label from the focusser element + this.search.attr("id", this.focusser.attr('id') + '_search'); + + this.search.prev() + .text($("label[for='" + this.focusser.attr('id') + "']").text()) + .attr('for', this.search.attr('id')); + + this.search.on("keydown", this.bind(function (e) { + if (!this.isInterfaceEnabled()) return; + + // filter 229 keyCodes (input method editor is processing key input) + if (229 == e.keyCode) return; + + if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) { + // prevent the page from scrolling + killEvent(e); + return; + } + + switch (e.which) { + case KEY.UP: + case KEY.DOWN: + this.moveHighlight((e.which === KEY.UP) ? -1 : 1); + killEvent(e); + return; + case KEY.ENTER: + this.selectHighlighted(); + killEvent(e); + return; + case KEY.TAB: + this.selectHighlighted({noFocus: true}); + return; + case KEY.ESC: + this.cancel(e); + killEvent(e); + return; + } + })); + + this.search.on("blur", this.bind(function(e) { + // a workaround for chrome to keep the search field focussed when the scroll bar is used to scroll the dropdown. + // without this the search field loses focus which is annoying + if (document.activeElement === this.body.get(0)) { + window.setTimeout(this.bind(function() { + if (this.opened() && this.results && this.results.length > 1) { + this.search.focus(); + } + }), 0); + } + })); + + this.focusser.on("keydown", this.bind(function (e) { + if (!this.isInterfaceEnabled()) return; + + if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) { + return; + } + + if (this.opts.openOnEnter === false && e.which === KEY.ENTER) { + killEvent(e); + return; + } + + if (e.which == KEY.DOWN || e.which == KEY.UP + || (e.which == KEY.ENTER && this.opts.openOnEnter)) { + + if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) return; + + this.open(); + killEvent(e); + return; + } + + if (e.which == KEY.DELETE || e.which == KEY.BACKSPACE) { + if (this.opts.allowClear) { + this.clear(); + } + killEvent(e); + return; + } + })); + + + installKeyUpChangeEvent(this.focusser); + this.focusser.on("keyup-change input", this.bind(function(e) { + if (this.opts.minimumResultsForSearch >= 0) { + e.stopPropagation(); + if (this.opened()) return; + this.open(); + } + })); + + selection.on("mousedown touchstart", "abbr", this.bind(function (e) { + if (!this.isInterfaceEnabled()) { + return; + } + + this.clear(); + killEventImmediately(e); + this.close(); + + if (this.selection) { + this.selection.focus(); + } + })); + + selection.on("mousedown touchstart", this.bind(function (e) { + // Prevent IE from generating a click event on the body + reinsertElement(selection); + + if (!this.container.hasClass("select2-container-active")) { + this.opts.element.trigger($.Event("select2-focus")); + } + + if (this.opened()) { + this.close(); + } else if (this.isInterfaceEnabled()) { + this.open(); + } + + killEvent(e); + })); + + dropdown.on("mousedown touchstart", this.bind(function() { + if (this.opts.shouldFocusInput(this)) { + this.search.focus(); + } + })); + + selection.on("focus", this.bind(function(e) { + killEvent(e); + })); + + this.focusser.on("focus", this.bind(function(){ + if (!this.container.hasClass("select2-container-active")) { + this.opts.element.trigger($.Event("select2-focus")); + } + this.container.addClass("select2-container-active"); + })).on("blur", this.bind(function() { + if (!this.opened()) { + this.container.removeClass("select2-container-active"); + this.opts.element.trigger($.Event("select2-blur")); + } + })); + this.search.on("focus", this.bind(function(){ + if (!this.container.hasClass("select2-container-active")) { + this.opts.element.trigger($.Event("select2-focus")); + } + this.container.addClass("select2-container-active"); + })); + + this.initContainerWidth(); + this.opts.element.hide(); + this.setPlaceholder(); + + }, + + // single + clear: function(triggerChange) { + var data=this.selection.data("select2-data"); + if (data) { // guard against queued quick consecutive clicks + var evt = $.Event("select2-clearing"); + this.opts.element.trigger(evt); + if (evt.isDefaultPrevented()) { + return; + } + var placeholderOption = this.getPlaceholderOption(); + this.opts.element.val(placeholderOption ? placeholderOption.val() : ""); + this.selection.find(".select2-chosen").empty(); + this.selection.removeData("select2-data"); + this.setPlaceholder(); + + if (triggerChange !== false){ + this.opts.element.trigger({ type: "select2-removed", val: this.id(data), choice: data }); + this.triggerChange({removed:data}); + } + } + }, + + /** + * Sets selection based on source element's value + */ + // single + initSelection: function () { + var selected; + if (this.isPlaceholderOptionSelected()) { + this.updateSelection(null); + this.close(); + this.setPlaceholder(); + } else { + var self = this; + this.opts.initSelection.call(null, this.opts.element, function(selected){ + if (selected !== undefined && selected !== null) { + self.updateSelection(selected); + self.close(); + self.setPlaceholder(); + self.lastSearchTerm = self.search.val(); + } + }); + } + }, + + isPlaceholderOptionSelected: function() { + var placeholderOption; + if (this.getPlaceholder() === undefined) return false; // no placeholder specified so no option should be considered + return ((placeholderOption = this.getPlaceholderOption()) !== undefined && placeholderOption.prop("selected")) + || (this.opts.element.val() === "") + || (this.opts.element.val() === undefined) + || (this.opts.element.val() === null); + }, + + // single + prepareOpts: function () { + var opts = this.parent.prepareOpts.apply(this, arguments), + self=this; + + if (opts.element.get(0).tagName.toLowerCase() === "select") { + // install the selection initializer + opts.initSelection = function (element, callback) { + var selected = element.find("option").filter(function() { return this.selected && !this.disabled }); + // a single select box always has a value, no need to null check 'selected' + callback(self.optionToData(selected)); + }; + } else if ("data" in opts) { + // install default initSelection when applied to hidden input and data is local + opts.initSelection = opts.initSelection || function (element, callback) { + var id = element.val(); + //search in data by id, storing the actual matching item + var match = null; + opts.query({ + matcher: function(term, text, el){ + var is_match = equal(id, opts.id(el)); + if (is_match) { + match = el; + } + return is_match; + }, + callback: !$.isFunction(callback) ? $.noop : function() { + callback(match); + } + }); + }; + } + + return opts; + }, + + // single + getPlaceholder: function() { + // if a placeholder is specified on a single select without a valid placeholder option ignore it + if (this.select) { + if (this.getPlaceholderOption() === undefined) { + return undefined; + } + } + + return this.parent.getPlaceholder.apply(this, arguments); + }, + + // single + setPlaceholder: function () { + var placeholder = this.getPlaceholder(); + + if (this.isPlaceholderOptionSelected() && placeholder !== undefined) { + + // check for a placeholder option if attached to a select + if (this.select && this.getPlaceholderOption() === undefined) return; + + this.selection.find(".select2-chosen").html(this.opts.escapeMarkup(placeholder)); + + this.selection.addClass("select2-default"); + + this.container.removeClass("select2-allowclear"); + } + }, + + // single + postprocessResults: function (data, initial, noHighlightUpdate) { + var selected = 0, self = this, showSearchInput = true; + + // find the selected element in the result list + + this.findHighlightableChoices().each2(function (i, elm) { + if (equal(self.id(elm.data("select2-data")), self.opts.element.val())) { + selected = i; + return false; + } + }); + + // and highlight it + if (noHighlightUpdate !== false) { + if (initial === true && selected >= 0) { + this.highlight(selected); + } else { + this.highlight(0); + } + } + + // hide the search box if this is the first we got the results and there are enough of them for search + + if (initial === true) { + var min = this.opts.minimumResultsForSearch; + if (min >= 0) { + this.showSearch(countResults(data.results) >= min); + } + } + }, + + // single + showSearch: function(showSearchInput) { + if (this.showSearchInput === showSearchInput) return; + + this.showSearchInput = showSearchInput; + + this.dropdown.find(".select2-search").toggleClass("select2-search-hidden", !showSearchInput); + this.dropdown.find(".select2-search").toggleClass("select2-offscreen", !showSearchInput); + //add "select2-with-searchbox" to the container if search box is shown + $(this.dropdown, this.container).toggleClass("select2-with-searchbox", showSearchInput); + }, + + // single + onSelect: function (data, options) { + + if (!this.triggerSelect(data)) { return; } + + var old = this.opts.element.val(), + oldData = this.data(); + + this.opts.element.val(this.id(data)); + this.updateSelection(data); + + this.opts.element.trigger({ type: "select2-selected", val: this.id(data), choice: data }); + + this.lastSearchTerm = this.search.val(); + this.close(); + + if ((!options || !options.noFocus) && this.opts.shouldFocusInput(this)) { + this.focusser.focus(); + } + + if (!equal(old, this.id(data))) { + this.triggerChange({ added: data, removed: oldData }); + } + }, + + // single + updateSelection: function (data) { + + var container=this.selection.find(".select2-chosen"), formatted, cssClass; + + this.selection.data("select2-data", data); + + container.empty(); + if (data !== null) { + formatted=this.opts.formatSelection(data, container, this.opts.escapeMarkup); + } + if (formatted !== undefined) { + container.append(formatted); + } + cssClass=this.opts.formatSelectionCssClass(data, container); + if (cssClass !== undefined) { + container.addClass(cssClass); + } + + this.selection.removeClass("select2-default"); + + if (this.opts.allowClear && this.getPlaceholder() !== undefined) { + this.container.addClass("select2-allowclear"); + } + }, + + // single + val: function () { + var val, + triggerChange = false, + data = null, + self = this, + oldData = this.data(); + + if (arguments.length === 0) { + return this.opts.element.val(); + } + + val = arguments[0]; + + if (arguments.length > 1) { + triggerChange = arguments[1]; + + if (this.opts.debug && console && console.warn) { + console.warn( + 'Select2: The second option to `select2("val")` is not supported in Select2 4.0.0. ' + + 'The `change` event will always be triggered in 4.0.0.' + ); + } + } + + if (this.select) { + if (this.opts.debug && console && console.warn) { + console.warn( + 'Select2: Setting the value on a <select> using `select2("val")` is no longer supported in 4.0.0. ' + + 'You can use the `.val(newValue).trigger("change")` method provided by jQuery instead.' + ); + } + + this.select + .val(val) + .find("option").filter(function() { return this.selected }).each2(function (i, elm) { + data = self.optionToData(elm); + return false; + }); + this.updateSelection(data); + this.setPlaceholder(); + if (triggerChange) { + this.triggerChange({added: data, removed:oldData}); + } + } else { + // val is an id. !val is true for [undefined,null,'',0] - 0 is legal + if (!val && val !== 0) { + this.clear(triggerChange); + return; + } + if (this.opts.initSelection === undefined) { + throw new Error("cannot call val() if initSelection() is not defined"); + } + this.opts.element.val(val); + this.opts.initSelection(this.opts.element, function(data){ + self.opts.element.val(!data ? "" : self.id(data)); + self.updateSelection(data); + self.setPlaceholder(); + if (triggerChange) { + self.triggerChange({added: data, removed:oldData}); + } + }); + } + }, + + // single + clearSearch: function () { + this.search.val(""); + this.focusser.val(""); + }, + + // single + data: function(value) { + var data, + triggerChange = false; + + if (arguments.length === 0) { + data = this.selection.data("select2-data"); + if (data == undefined) data = null; + return data; + } else { + if (this.opts.debug && console && console.warn) { + console.warn( + 'Select2: The `select2("data")` method can no longer set selected values in 4.0.0, ' + + 'consider using the `.val()` method instead.' + ); + } + + if (arguments.length > 1) { + triggerChange = arguments[1]; + } + if (!value) { + this.clear(triggerChange); + } else { + data = this.data(); + this.opts.element.val(!value ? "" : this.id(value)); + this.updateSelection(value); + if (triggerChange) { + this.triggerChange({added: value, removed:data}); + } + } + } + } + }); + + MultiSelect2 = clazz(AbstractSelect2, { + + // multi + createContainer: function () { + var container = $(document.createElement("div")).attr({ + "class": "select2-container select2-container-multi" + }).html([ + "<ul class='select2-choices'>", + " <li class='select2-search-field'>", + " <label for='' class='select2-offscreen'></label>", + " <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input'>", + " </li>", + "</ul>", + "<div class='select2-drop select2-drop-multi select2-display-none'>", + " <ul class='select2-results'>", + " </ul>", + "</div>"].join("")); + return container; + }, + + // multi + prepareOpts: function () { + var opts = this.parent.prepareOpts.apply(this, arguments), + self=this; + + // TODO validate placeholder is a string if specified + if (opts.element.get(0).tagName.toLowerCase() === "select") { + // install the selection initializer + opts.initSelection = function (element, callback) { + + var data = []; + + element.find("option").filter(function() { return this.selected && !this.disabled }).each2(function (i, elm) { + data.push(self.optionToData(elm)); + }); + callback(data); + }; + } else if ("data" in opts) { + // install default initSelection when applied to hidden input and data is local + opts.initSelection = opts.initSelection || function (element, callback) { + var ids = splitVal(element.val(), opts.separator, opts.transformVal); + //search in data by array of ids, storing matching items in a list + var matches = []; + opts.query({ + matcher: function(term, text, el){ + var is_match = $.grep(ids, function(id) { + return equal(id, opts.id(el)); + }).length; + if (is_match) { + matches.push(el); + } + return is_match; + }, + callback: !$.isFunction(callback) ? $.noop : function() { + // reorder matches based on the order they appear in the ids array because right now + // they are in the order in which they appear in data array + var ordered = []; + for (var i = 0; i < ids.length; i++) { + var id = ids[i]; + for (var j = 0; j < matches.length; j++) { + var match = matches[j]; + if (equal(id, opts.id(match))) { + ordered.push(match); + matches.splice(j, 1); + break; + } + } + } + callback(ordered); + } + }); + }; + } + + return opts; + }, + + // multi + selectChoice: function (choice) { + + var selected = this.container.find(".select2-search-choice-focus"); + if (selected.length && choice && choice[0] == selected[0]) { + + } else { + if (selected.length) { + this.opts.element.trigger("choice-deselected", selected); + } + selected.removeClass("select2-search-choice-focus"); + if (choice && choice.length) { + this.close(); + choice.addClass("select2-search-choice-focus"); + this.opts.element.trigger("choice-selected", choice); + } + } + }, + + // multi + destroy: function() { + $("label[for='" + this.search.attr('id') + "']") + .attr('for', this.opts.element.attr("id")); + this.parent.destroy.apply(this, arguments); + + cleanupJQueryElements.call(this, + "searchContainer", + "selection" + ); + }, + + // multi + initContainer: function () { + + var selector = ".select2-choices", selection; + + this.searchContainer = this.container.find(".select2-search-field"); + this.selection = selection = this.container.find(selector); + + var _this = this; + this.selection.on("click", ".select2-container:not(.select2-container-disabled) .select2-search-choice:not(.select2-locked)", function (e) { + _this.search[0].focus(); + _this.selectChoice($(this)); + }); + + // rewrite labels from original element to focusser + this.search.attr("id", "s2id_autogen"+nextUid()); + + this.search.prev() + .text($("label[for='" + this.opts.element.attr("id") + "']").text()) + .attr('for', this.search.attr('id')); + this.opts.element.on('focus.select2', this.bind(function () { this.focus(); })); + + this.search.on("input paste", this.bind(function() { + if (this.search.attr('placeholder') && this.search.val().length == 0) return; + if (!this.isInterfaceEnabled()) return; + if (!this.opened()) { + this.open(); + } + })); + + this.search.attr("tabindex", this.elementTabIndex); + + this.keydowns = 0; + this.search.on("keydown", this.bind(function (e) { + if (!this.isInterfaceEnabled()) return; + + ++this.keydowns; + var selected = selection.find(".select2-search-choice-focus"); + var prev = selected.prev(".select2-search-choice:not(.select2-locked)"); + var next = selected.next(".select2-search-choice:not(.select2-locked)"); + var pos = getCursorInfo(this.search); + + if (selected.length && + (e.which == KEY.LEFT || e.which == KEY.RIGHT || e.which == KEY.BACKSPACE || e.which == KEY.DELETE || e.which == KEY.ENTER)) { + var selectedChoice = selected; + if (e.which == KEY.LEFT && prev.length) { + selectedChoice = prev; + } + else if (e.which == KEY.RIGHT) { + selectedChoice = next.length ? next : null; + } + else if (e.which === KEY.BACKSPACE) { + if (this.unselect(selected.first())) { + this.search.width(10); + selectedChoice = prev.length ? prev : next; + } + } else if (e.which == KEY.DELETE) { + if (this.unselect(selected.first())) { + this.search.width(10); + selectedChoice = next.length ? next : null; + } + } else if (e.which == KEY.ENTER) { + selectedChoice = null; + } + + this.selectChoice(selectedChoice); + killEvent(e); + if (!selectedChoice || !selectedChoice.length) { + this.open(); + } + return; + } else if (((e.which === KEY.BACKSPACE && this.keydowns == 1) + || e.which == KEY.LEFT) && (pos.offset == 0 && !pos.length)) { + + this.selectChoice(selection.find(".select2-search-choice:not(.select2-locked)").last()); + killEvent(e); + return; + } else { + this.selectChoice(null); + } + + if (this.opened()) { + switch (e.which) { + case KEY.UP: + case KEY.DOWN: + this.moveHighlight((e.which === KEY.UP) ? -1 : 1); + killEvent(e); + return; + case KEY.ENTER: + this.selectHighlighted(); + killEvent(e); + return; + case KEY.TAB: + this.selectHighlighted({noFocus:true}); + this.close(); + return; + case KEY.ESC: + this.cancel(e); + killEvent(e); + return; + } + } + + if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) + || e.which === KEY.BACKSPACE || e.which === KEY.ESC) { + return; + } + + if (e.which === KEY.ENTER) { + if (this.opts.openOnEnter === false) { + return; + } else if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) { + return; + } + } + + this.open(); + + if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) { + // prevent the page from scrolling + killEvent(e); + } + + if (e.which === KEY.ENTER) { + // prevent form from being submitted + killEvent(e); + } + + })); + + this.search.on("keyup", this.bind(function (e) { + this.keydowns = 0; + this.resizeSearch(); + }) + ); + + this.search.on("blur", this.bind(function(e) { + this.container.removeClass("select2-container-active"); + this.search.removeClass("select2-focused"); + this.selectChoice(null); + if (!this.opened()) this.clearSearch(); + e.stopImmediatePropagation(); + this.opts.element.trigger($.Event("select2-blur")); + })); + + this.container.on("click", selector, this.bind(function (e) { + if (!this.isInterfaceEnabled()) return; + if ($(e.target).closest(".select2-search-choice").length > 0) { + // clicked inside a select2 search choice, do not open + return; + } + this.selectChoice(null); + this.clearPlaceholder(); + if (!this.container.hasClass("select2-container-active")) { + this.opts.element.trigger($.Event("select2-focus")); + } + this.open(); + this.focusSearch(); + e.preventDefault(); + })); + + this.container.on("focus", selector, this.bind(function () { + if (!this.isInterfaceEnabled()) return; + if (!this.container.hasClass("select2-container-active")) { + this.opts.element.trigger($.Event("select2-focus")); + } + this.container.addClass("select2-container-active"); + this.dropdown.addClass("select2-drop-active"); + this.clearPlaceholder(); + })); + + this.initContainerWidth(); + this.opts.element.hide(); + + // set the placeholder if necessary + this.clearSearch(); + }, + + // multi + enableInterface: function() { + if (this.parent.enableInterface.apply(this, arguments)) { + this.search.prop("disabled", !this.isInterfaceEnabled()); + } + }, + + // multi + initSelection: function () { + var data; + if (this.opts.element.val() === "" && this.opts.element.text() === "") { + this.updateSelection([]); + this.close(); + // set the placeholder if necessary + this.clearSearch(); + } + if (this.select || this.opts.element.val() !== "") { + var self = this; + this.opts.initSelection.call(null, this.opts.element, function(data){ + if (data !== undefined && data !== null) { + self.updateSelection(data); + self.close(); + // set the placeholder if necessary + self.clearSearch(); + } + }); + } + }, + + // multi + clearSearch: function () { + var placeholder = this.getPlaceholder(), + maxWidth = this.getMaxSearchWidth(); + + if (placeholder !== undefined && this.getVal().length === 0 && this.search.hasClass("select2-focused") === false) { + this.search.val(placeholder).addClass("select2-default"); + // stretch the search box to full width of the container so as much of the placeholder is visible as possible + // we could call this.resizeSearch(), but we do not because that requires a sizer and we do not want to create one so early because of a firefox bug, see #944 + this.search.width(maxWidth > 0 ? maxWidth : this.container.css("width")); + } else { + this.search.val("").width(10); + } + }, + + // multi + clearPlaceholder: function () { + if (this.search.hasClass("select2-default")) { + this.search.val("").removeClass("select2-default"); + } + }, + + // multi + opening: function () { + this.clearPlaceholder(); // should be done before super so placeholder is not used to search + this.resizeSearch(); + + this.parent.opening.apply(this, arguments); + + this.focusSearch(); + + this.prefillNextSearchTerm(); + this.updateResults(true); + + if (this.opts.shouldFocusInput(this)) { + this.search.focus(); + } + this.opts.element.trigger($.Event("select2-open")); + }, + + // multi + close: function () { + if (!this.opened()) return; + this.parent.close.apply(this, arguments); + }, + + // multi + focus: function () { + this.close(); + this.search.focus(); + }, + + // multi + isFocused: function () { + return this.search.hasClass("select2-focused"); + }, + + // multi + updateSelection: function (data) { + var ids = {}, filtered = [], self = this; + + // filter out duplicates + $(data).each(function () { + if (!(self.id(this) in ids)) { + ids[self.id(this)] = 0; + filtered.push(this); + } + }); + + this.selection.find(".select2-search-choice").remove(); + this.addSelectedChoice(filtered); + self.postprocessResults(); + }, + + // multi + tokenize: function() { + var input = this.search.val(); + input = this.opts.tokenizer.call(this, input, this.data(), this.bind(this.onSelect), this.opts); + if (input != null && input != undefined) { + this.search.val(input); + if (input.length > 0) { + this.open(); + } + } + + }, + + // multi + onSelect: function (data, options) { + + if (!this.triggerSelect(data) || data.text === "") { return; } + + this.addSelectedChoice(data); + + this.opts.element.trigger({ type: "selected", val: this.id(data), choice: data }); + + // keep track of the search's value before it gets cleared + this.lastSearchTerm = this.search.val(); + + this.clearSearch(); + this.updateResults(); + + if (this.select || !this.opts.closeOnSelect) this.postprocessResults(data, false, this.opts.closeOnSelect===true); + + if (this.opts.closeOnSelect) { + this.close(); + this.search.width(10); + } else { + if (this.countSelectableResults()>0) { + this.search.width(10); + this.resizeSearch(); + if (this.getMaximumSelectionSize() > 0 && this.val().length >= this.getMaximumSelectionSize()) { + // if we reached max selection size repaint the results so choices + // are replaced with the max selection reached message + this.updateResults(true); + } else { + // initializes search's value with nextSearchTerm and update search result + if (this.prefillNextSearchTerm()) { + this.updateResults(); + } + } + this.positionDropdown(); + } else { + // if nothing left to select close + this.close(); + this.search.width(10); + } + } + + // since its not possible to select an element that has already been + // added we do not need to check if this is a new element before firing change + this.triggerChange({ added: data }); + + if (!options || !options.noFocus) + this.focusSearch(); + }, + + // multi + cancel: function () { + this.close(); + this.focusSearch(); + }, + + addSelectedChoice: function (data) { + var val = this.getVal(), self = this; + $(data).each(function () { + val.push(self.createChoice(this)); + }); + this.setVal(val); + }, + + createChoice: function (data) { + var enableChoice = !data.locked, + enabledItem = $( + "<li class='select2-search-choice'>" + + " <div></div>" + + " <a href='#' class='select2-search-choice-close' tabindex='-1'></a>" + + "</li>"), + disabledItem = $( + "<li class='select2-search-choice select2-locked'>" + + "<div></div>" + + "</li>"); + var choice = enableChoice ? enabledItem : disabledItem, + id = this.id(data), + formatted, + cssClass; + + formatted=this.opts.formatSelection(data, choice.find("div"), this.opts.escapeMarkup); + if (formatted != undefined) { + choice.find("div").replaceWith($("<div></div>").html(formatted)); + } + cssClass=this.opts.formatSelectionCssClass(data, choice.find("div")); + if (cssClass != undefined) { + choice.addClass(cssClass); + } + + if(enableChoice){ + choice.find(".select2-search-choice-close") + .on("mousedown", killEvent) + .on("click dblclick", this.bind(function (e) { + if (!this.isInterfaceEnabled()) return; + + this.unselect($(e.target)); + this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus"); + killEvent(e); + this.close(); + this.focusSearch(); + })).on("focus", this.bind(function () { + if (!this.isInterfaceEnabled()) return; + this.container.addClass("select2-container-active"); + this.dropdown.addClass("select2-drop-active"); + })); + } + + choice.data("select2-data", data); + choice.insertBefore(this.searchContainer); + + return id; + }, + + // multi + unselect: function (selected) { + var val = this.getVal(), + data, + index; + selected = selected.closest(".select2-search-choice"); + + if (selected.length === 0) { + throw "Invalid argument: " + selected + ". Must be .select2-search-choice"; + } + + data = selected.data("select2-data"); + + if (!data) { + // prevent a race condition when the 'x' is clicked really fast repeatedly the event can be queued + // and invoked on an element already removed + return; + } + + var evt = $.Event("select2-removing"); + evt.val = this.id(data); + evt.choice = data; + this.opts.element.trigger(evt); + + if (evt.isDefaultPrevented()) { + return false; + } + + while((index = indexOf(this.id(data), val)) >= 0) { + val.splice(index, 1); + this.setVal(val); + if (this.select) this.postprocessResults(); + } + + selected.remove(); + + this.opts.element.trigger({ type: "select2-removed", val: this.id(data), choice: data }); + this.triggerChange({ removed: data }); + + return true; + }, + + // multi + postprocessResults: function (data, initial, noHighlightUpdate) { + var val = this.getVal(), + choices = this.results.find(".select2-result"), + compound = this.results.find(".select2-result-with-children"), + self = this; + + choices.each2(function (i, choice) { + var id = self.id(choice.data("select2-data")); + if (indexOf(id, val) >= 0) { + choice.addClass("select2-selected"); + // mark all children of the selected parent as selected + choice.find(".select2-result-selectable").addClass("select2-selected"); + } + }); + + compound.each2(function(i, choice) { + // hide an optgroup if it doesn't have any selectable children + if (!choice.is('.select2-result-selectable') + && choice.find(".select2-result-selectable:not(.select2-selected)").length === 0) { + choice.addClass("select2-selected"); + } + }); + + if (this.highlight() == -1 && noHighlightUpdate !== false && this.opts.closeOnSelect === true){ + self.highlight(0); + } + + //If all results are chosen render formatNoMatches + if(!this.opts.createSearchChoice && !choices.filter('.select2-result:not(.select2-selected)').length > 0){ + if(!data || data && !data.more && this.results.find(".select2-no-results").length === 0) { + if (checkFormatter(self.opts.formatNoMatches, "formatNoMatches")) { + this.results.append("<li class='select2-no-results'>" + evaluate(self.opts.formatNoMatches, self.opts.element, self.search.val()) + "</li>"); + } + } + } + + }, + + // multi + getMaxSearchWidth: function() { + return this.selection.width() - getSideBorderPadding(this.search); + }, + + // multi + resizeSearch: function () { + var minimumWidth, left, maxWidth, containerLeft, searchWidth, + sideBorderPadding = getSideBorderPadding(this.search); + + minimumWidth = measureTextWidth(this.search) + 10; + + left = this.search.offset().left; + + maxWidth = this.selection.width(); + containerLeft = this.selection.offset().left; + + searchWidth = maxWidth - (left - containerLeft) - sideBorderPadding; + + if (searchWidth < minimumWidth) { + searchWidth = maxWidth - sideBorderPadding; + } + + if (searchWidth < 40) { + searchWidth = maxWidth - sideBorderPadding; + } + + if (searchWidth <= 0) { + searchWidth = minimumWidth; + } + + this.search.width(Math.floor(searchWidth)); + }, + + // multi + getVal: function () { + var val; + if (this.select) { + val = this.select.val(); + return val === null ? [] : val; + } else { + val = this.opts.element.val(); + return splitVal(val, this.opts.separator, this.opts.transformVal); + } + }, + + // multi + setVal: function (val) { + if (this.select) { + this.select.val(val); + } else { + var unique = [], valMap = {}; + // filter out duplicates + $(val).each(function () { + if (!(this in valMap)) { + unique.push(this); + valMap[this] = 0; + } + }); + this.opts.element.val(unique.length === 0 ? "" : unique.join(this.opts.separator)); + } + }, + + // multi + buildChangeDetails: function (old, current) { + var current = current.slice(0), + old = old.slice(0); + + // remove intersection from each array + for (var i = 0; i < current.length; i++) { + for (var j = 0; j < old.length; j++) { + if (equal(this.opts.id(current[i]), this.opts.id(old[j]))) { + current.splice(i, 1); + i--; + old.splice(j, 1); + break; + } + } + } + + return {added: current, removed: old}; + }, + + + // multi + val: function (val, triggerChange) { + var oldData, self=this; + + if (arguments.length === 0) { + return this.getVal(); + } + + oldData=this.data(); + if (!oldData.length) oldData=[]; + + // val is an id. !val is true for [undefined,null,'',0] - 0 is legal + if (!val && val !== 0) { + this.opts.element.val(""); + this.updateSelection([]); + this.clearSearch(); + if (triggerChange) { + this.triggerChange({added: this.data(), removed: oldData}); + } + return; + } + + // val is a list of ids + this.setVal(val); + + if (this.select) { + this.opts.initSelection(this.select, this.bind(this.updateSelection)); + if (triggerChange) { + this.triggerChange(this.buildChangeDetails(oldData, this.data())); + } + } else { + if (this.opts.initSelection === undefined) { + throw new Error("val() cannot be called if initSelection() is not defined"); + } + + this.opts.initSelection(this.opts.element, function(data){ + var ids=$.map(data, self.id); + self.setVal(ids); + self.updateSelection(data); + self.clearSearch(); + if (triggerChange) { + self.triggerChange(self.buildChangeDetails(oldData, self.data())); + } + }); + } + this.clearSearch(); + }, + + // multi + onSortStart: function() { + if (this.select) { + throw new Error("Sorting of elements is not supported when attached to <select>. Attach to <input type='hidden'/> instead."); + } + + // collapse search field into 0 width so its container can be collapsed as well + this.search.width(0); + // hide the container + this.searchContainer.hide(); + }, + + // multi + onSortEnd:function() { + + var val=[], self=this; + + // show search and move it to the end of the list + this.searchContainer.show(); + // make sure the search container is the last item in the list + this.searchContainer.appendTo(this.searchContainer.parent()); + // since we collapsed the width in dragStarted, we resize it here + this.resizeSearch(); + + // update selection + this.selection.find(".select2-search-choice").each(function() { + val.push(self.opts.id($(this).data("select2-data"))); + }); + this.setVal(val); + this.triggerChange(); + }, + + // multi + data: function(values, triggerChange) { + var self=this, ids, old; + if (arguments.length === 0) { + return this.selection + .children(".select2-search-choice") + .map(function() { return $(this).data("select2-data"); }) + .get(); + } else { + old = this.data(); + if (!values) { values = []; } + ids = $.map(values, function(e) { return self.opts.id(e); }); + this.setVal(ids); + this.updateSelection(values); + this.clearSearch(); + if (triggerChange) { + this.triggerChange(this.buildChangeDetails(old, this.data())); + } + } + } + }); + + $.fn.select2 = function () { + + var args = Array.prototype.slice.call(arguments, 0), + opts, + select2, + method, value, multiple, + allowedMethods = ["val", "destroy", "opened", "open", "close", "focus", "isFocused", "container", "dropdown", "onSortStart", "onSortEnd", "enable", "disable", "readonly", "positionDropdown", "data", "search"], + valueMethods = ["opened", "isFocused", "container", "dropdown"], + propertyMethods = ["val", "data"], + methodsMap = { search: "externalSearch" }; + + this.each(function () { + if (args.length === 0 || typeof(args[0]) === "object") { + opts = args.length === 0 ? {} : $.extend({}, args[0]); + opts.element = $(this); + + if (opts.element.get(0).tagName.toLowerCase() === "select") { + multiple = opts.element.prop("multiple"); + } else { + multiple = opts.multiple || false; + if ("tags" in opts) {opts.multiple = multiple = true;} + } + + select2 = multiple ? new window.Select2["class"].multi() : new window.Select2["class"].single(); + select2.init(opts); + } else if (typeof(args[0]) === "string") { + + if (indexOf(args[0], allowedMethods) < 0) { + throw "Unknown method: " + args[0]; + } + + value = undefined; + select2 = $(this).data("select2"); + if (select2 === undefined) return; + + method=args[0]; + + if (method === "container") { + value = select2.container; + } else if (method === "dropdown") { + value = select2.dropdown; + } else { + if (methodsMap[method]) method = methodsMap[method]; + + value = select2[method].apply(select2, args.slice(1)); + } + if (indexOf(args[0], valueMethods) >= 0 + || (indexOf(args[0], propertyMethods) >= 0 && args.length == 1)) { + return false; // abort the iteration, ready to return first matched value + } + } else { + throw "Invalid arguments to select2 plugin: " + args; + } + }); + return (value === undefined) ? this : value; + }; + + // plugin defaults, accessible to users + $.fn.select2.defaults = { + debug: false, + width: "copy", + loadMorePadding: 0, + closeOnSelect: true, + openOnEnter: true, + containerCss: {}, + dropdownCss: {}, + containerCssClass: "", + dropdownCssClass: "", + formatResult: function(result, container, query, escapeMarkup) { + var markup=[]; + markMatch(this.text(result), query.term, markup, escapeMarkup); + return markup.join(""); + }, + transformVal: function(val) { + return $.trim(val); + }, + formatSelection: function (data, container, escapeMarkup) { + return data ? escapeMarkup(this.text(data)) : undefined; + }, + sortResults: function (results, container, query) { + return results; + }, + formatResultCssClass: function(data) {return data.css;}, + formatSelectionCssClass: function(data, container) {return undefined;}, + minimumResultsForSearch: 0, + minimumInputLength: 0, + maximumInputLength: null, + maximumSelectionSize: 0, + id: function (e) { return e == undefined ? null : e.id; }, + text: function (e) { + if (e && this.data && this.data.text) { + if ($.isFunction(this.data.text)) { + return this.data.text(e); + } else { + return e[this.data.text]; + } + } else { + return e.text; + } + }, + matcher: function(term, text) { + return stripDiacritics(''+text).toUpperCase().indexOf(stripDiacritics(''+term).toUpperCase()) >= 0; + }, + separator: ",", + tokenSeparators: [], + tokenizer: defaultTokenizer, + escapeMarkup: defaultEscapeMarkup, + blurOnChange: false, + selectOnBlur: false, + adaptContainerCssClass: function(c) { return c; }, + adaptDropdownCssClass: function(c) { return null; }, + nextSearchTerm: function(selectedObject, currentSearchTerm) { return undefined; }, + searchInputPlaceholder: '', + createSearchChoicePosition: 'top', + shouldFocusInput: function (instance) { + // Attempt to detect touch devices + var supportsTouchEvents = (('ontouchstart' in window) || + (navigator.msMaxTouchPoints > 0)); + + // Only devices which support touch events should be special cased + if (!supportsTouchEvents) { + return true; + } + + // Never focus the input if search is disabled + if (instance.opts.minimumResultsForSearch < 0) { + return false; + } + + return true; + } + }; + + $.fn.select2.locales = []; + + $.fn.select2.locales['en'] = { + formatMatches: function (matches) { if (matches === 1) { return "One result is available, press enter to select it."; } return matches + " results are available, use up and down arrow keys to navigate."; }, + formatNoMatches: function () { return "No matches found"; }, + formatAjaxError: function (jqXHR, textStatus, errorThrown) { return "Loading failed"; }, + formatInputTooShort: function (input, min) { var n = min - input.length; return "Please enter " + n + " or more character" + (n == 1 ? "" : "s"); }, + formatInputTooLong: function (input, max) { var n = input.length - max; return "Please delete " + n + " character" + (n == 1 ? "" : "s"); }, + formatSelectionTooBig: function (limit) { return "You can only select " + limit + " item" + (limit == 1 ? "" : "s"); }, + formatLoadMore: function (pageNumber) { return "Loading more results…"; }, + formatSearching: function () { return "Searching…"; } + }; + + $.extend($.fn.select2.defaults, $.fn.select2.locales['en']); + + $.fn.select2.ajaxDefaults = { + transport: $.ajax, + params: { + type: "GET", + cache: false, + dataType: "json" + } + }; + + // exports + window.Select2 = { + query: { + ajax: ajax, + local: local, + tags: tags + }, util: { + debounce: debounce, + markMatch: markMatch, + escapeMarkup: defaultEscapeMarkup, + stripDiacritics: stripDiacritics + }, "class": { + "abstract": AbstractSelect2, + "single": SingleSelect2, + "multi": MultiSelect2 + } + }; + +}(jQuery)); +/** + * Select2 French translation + */ + +(function ($) { + "use strict"; + + $.fn.select2.locales['fr'] = { + formatMatches: function (matches) { return matches + " résultats sont disponibles, utilisez les flèches haut et bas pour naviguer."; }, + formatNoMatches: function () { return "Aucun résultat trouvé"; }, + formatInputTooShort: function (input, min) { var n = min - input.length; return "Saisissez " + n + " caractère" + (n == 1? "" : "s") + " supplémentaire" + (n == 1? "" : "s") ; }, + formatInputTooLong: function (input, max) { var n = input.length - max; return "Supprimez " + n + " caractère" + (n == 1? "" : "s"); }, + formatSelectionTooBig: function (limit) { return "Vous pouvez seulement sélectionner " + limit + " élément" + (limit == 1 ? "" : "s"); }, + formatLoadMore: function (pageNumber) { return "Chargement de résultats supplémentaires…"; }, + formatSearching: function () { return "Recherche en cours…"; } + }; + + $.extend($.fn.select2.defaults, $.fn.select2.locales['fr']); +})(jQuery); +/* + Leaflet, a JavaScript library for mobile-friendly interactive maps. http://leafletjs.com + (c) 2010-2013, Vladimir Agafonkin + (c) 2010-2011, CloudMade +*/ + + + + + +(function (window, document, undefined) { +var oldL = window.L, + L = {}; + +L.version = '0.7.7'; + +// define Leaflet for Node module pattern loaders, including Browserify +if (typeof module === 'object' && typeof module.exports === 'object') { + module.exports = L; + +// define Leaflet as an AMD module +} else if (typeof define === 'function' && define.amd) { + define(L); +} + +// define Leaflet as a global L variable, saving the original L to restore later if needed + +L.noConflict = function () { + window.L = oldL; + return this; +}; + +window.L = L; + + +/* + * L.Util contains various utility functions used throughout Leaflet code. + */ + +L.Util = { + extend: function (dest) { // (Object[, Object, ...]) -> + var sources = Array.prototype.slice.call(arguments, 1), + i, j, len, src; + + for (j = 0, len = sources.length; j < len; j++) { + src = sources[j] || {}; + for (i in src) { + if (src.hasOwnProperty(i)) { + dest[i] = src[i]; + } + } + } + return dest; + }, + + bind: function (fn, obj) { // (Function, Object) -> Function + var args = arguments.length > 2 ? Array.prototype.slice.call(arguments, 2) : null; + return function () { + return fn.apply(obj, args || arguments); + }; + }, + + stamp: (function () { + var lastId = 0, + key = '_leaflet_id'; + return function (obj) { + obj[key] = obj[key] || ++lastId; + return obj[key]; + }; + }()), + + invokeEach: function (obj, method, context) { + var i, args; + + if (typeof obj === 'object') { + args = Array.prototype.slice.call(arguments, 3); + + for (i in obj) { + method.apply(context, [i, obj[i]].concat(args)); + } + return true; + } + + return false; + }, + + limitExecByInterval: function (fn, time, context) { + var lock, execOnUnlock; + + return function wrapperFn() { + var args = arguments; + + if (lock) { + execOnUnlock = true; + return; + } + + lock = true; + + setTimeout(function () { + lock = false; + + if (execOnUnlock) { + wrapperFn.apply(context, args); + execOnUnlock = false; + } + }, time); + + fn.apply(context, args); + }; + }, + + falseFn: function () { + return false; + }, + + formatNum: function (num, digits) { + var pow = Math.pow(10, digits || 5); + return Math.round(num * pow) / pow; + }, + + trim: function (str) { + return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, ''); + }, + + splitWords: function (str) { + return L.Util.trim(str).split(/\s+/); + }, + + setOptions: function (obj, options) { + obj.options = L.extend({}, obj.options, options); + return obj.options; + }, + + getParamString: function (obj, existingUrl, uppercase) { + var params = []; + for (var i in obj) { + params.push(encodeURIComponent(uppercase ? i.toUpperCase() : i) + '=' + encodeURIComponent(obj[i])); + } + return ((!existingUrl || existingUrl.indexOf('?') === -1) ? '?' : '&') + params.join('&'); + }, + template: function (str, data) { + return str.replace(/\{ *([\w_]+) *\}/g, function (str, key) { + var value = data[key]; + if (value === undefined) { + throw new Error('No value provided for variable ' + str); + } else if (typeof value === 'function') { + value = value(data); + } + return value; + }); + }, + + isArray: Array.isArray || function (obj) { + return (Object.prototype.toString.call(obj) === '[object Array]'); + }, + + emptyImageUrl: 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=' +}; + +(function () { + + // inspired by http://paulirish.com/2011/requestanimationframe-for-smart-animating/ + + function getPrefixed(name) { + var i, fn, + prefixes = ['webkit', 'moz', 'o', 'ms']; + + for (i = 0; i < prefixes.length && !fn; i++) { + fn = window[prefixes[i] + name]; + } + + return fn; + } + + var lastTime = 0; + + function timeoutDefer(fn) { + var time = +new Date(), + timeToCall = Math.max(0, 16 - (time - lastTime)); + + lastTime = time + timeToCall; + return window.setTimeout(fn, timeToCall); + } + + var requestFn = window.requestAnimationFrame || + getPrefixed('RequestAnimationFrame') || timeoutDefer; + + var cancelFn = window.cancelAnimationFrame || + getPrefixed('CancelAnimationFrame') || + getPrefixed('CancelRequestAnimationFrame') || + function (id) { window.clearTimeout(id); }; + + + L.Util.requestAnimFrame = function (fn, context, immediate, element) { + fn = L.bind(fn, context); + + if (immediate && requestFn === timeoutDefer) { + fn(); + } else { + return requestFn.call(window, fn, element); + } + }; + + L.Util.cancelAnimFrame = function (id) { + if (id) { + cancelFn.call(window, id); + } + }; + +}()); + +// shortcuts for most used utility functions +L.extend = L.Util.extend; +L.bind = L.Util.bind; +L.stamp = L.Util.stamp; +L.setOptions = L.Util.setOptions; + + +/* + * L.Class powers the OOP facilities of the library. + * Thanks to John Resig and Dean Edwards for inspiration! + */ + +L.Class = function () {}; + +L.Class.extend = function (props) { + + // extended class with the new prototype + var NewClass = function () { + + // call the constructor + if (this.initialize) { + this.initialize.apply(this, arguments); + } + + // call all constructor hooks + if (this._initHooks) { + this.callInitHooks(); + } + }; + + // instantiate class without calling constructor + var F = function () {}; + F.prototype = this.prototype; + + var proto = new F(); + proto.constructor = NewClass; + + NewClass.prototype = proto; + + //inherit parent's statics + for (var i in this) { + if (this.hasOwnProperty(i) && i !== 'prototype') { + NewClass[i] = this[i]; + } + } + + // mix static properties into the class + if (props.statics) { + L.extend(NewClass, props.statics); + delete props.statics; + } + + // mix includes into the prototype + if (props.includes) { + L.Util.extend.apply(null, [proto].concat(props.includes)); + delete props.includes; + } + + // merge options + if (props.options && proto.options) { + props.options = L.extend({}, proto.options, props.options); + } + + // mix given properties into the prototype + L.extend(proto, props); + + proto._initHooks = []; + + var parent = this; + // jshint camelcase: false + NewClass.__super__ = parent.prototype; + + // add method for calling all hooks + proto.callInitHooks = function () { + + if (this._initHooksCalled) { return; } + + if (parent.prototype.callInitHooks) { + parent.prototype.callInitHooks.call(this); + } + + this._initHooksCalled = true; + + for (var i = 0, len = proto._initHooks.length; i < len; i++) { + proto._initHooks[i].call(this); + } + }; + + return NewClass; +}; + + +// method for adding properties to prototype +L.Class.include = function (props) { + L.extend(this.prototype, props); +}; + +// merge new default options to the Class +L.Class.mergeOptions = function (options) { + L.extend(this.prototype.options, options); +}; + +// add a constructor hook +L.Class.addInitHook = function (fn) { // (Function) || (String, args...) + var args = Array.prototype.slice.call(arguments, 1); + + var init = typeof fn === 'function' ? fn : function () { + this[fn].apply(this, args); + }; + + this.prototype._initHooks = this.prototype._initHooks || []; + this.prototype._initHooks.push(init); +}; + + +/* + * L.Mixin.Events is used to add custom events functionality to Leaflet classes. + */ + +var eventsKey = '_leaflet_events'; + +L.Mixin = {}; + +L.Mixin.Events = { + + addEventListener: function (types, fn, context) { // (String, Function[, Object]) or (Object[, Object]) + + // types can be a map of types/handlers + if (L.Util.invokeEach(types, this.addEventListener, this, fn, context)) { return this; } + + var events = this[eventsKey] = this[eventsKey] || {}, + contextId = context && context !== this && L.stamp(context), + i, len, event, type, indexKey, indexLenKey, typeIndex; + + // types can be a string of space-separated words + types = L.Util.splitWords(types); + + for (i = 0, len = types.length; i < len; i++) { + event = { + action: fn, + context: context || this + }; + type = types[i]; + + if (contextId) { + // store listeners of a particular context in a separate hash (if it has an id) + // gives a major performance boost when removing thousands of map layers + + indexKey = type + '_idx'; + indexLenKey = indexKey + '_len'; + + typeIndex = events[indexKey] = events[indexKey] || {}; + + if (!typeIndex[contextId]) { + typeIndex[contextId] = []; + + // keep track of the number of keys in the index to quickly check if it's empty + events[indexLenKey] = (events[indexLenKey] || 0) + 1; + } + + typeIndex[contextId].push(event); + + + } else { + events[type] = events[type] || []; + events[type].push(event); + } + } + + return this; + }, + + hasEventListeners: function (type) { // (String) -> Boolean + var events = this[eventsKey]; + return !!events && ((type in events && events[type].length > 0) || + (type + '_idx' in events && events[type + '_idx_len'] > 0)); + }, + + removeEventListener: function (types, fn, context) { // ([String, Function, Object]) or (Object[, Object]) + + if (!this[eventsKey]) { + return this; + } + + if (!types) { + return this.clearAllEventListeners(); + } + + if (L.Util.invokeEach(types, this.removeEventListener, this, fn, context)) { return this; } + + var events = this[eventsKey], + contextId = context && context !== this && L.stamp(context), + i, len, type, listeners, j, indexKey, indexLenKey, typeIndex, removed; + + types = L.Util.splitWords(types); + + for (i = 0, len = types.length; i < len; i++) { + type = types[i]; + indexKey = type + '_idx'; + indexLenKey = indexKey + '_len'; + + typeIndex = events[indexKey]; + + if (!fn) { + // clear all listeners for a type if function isn't specified + delete events[type]; + delete events[indexKey]; + delete events[indexLenKey]; + + } else { + listeners = contextId && typeIndex ? typeIndex[contextId] : events[type]; + + if (listeners) { + for (j = listeners.length - 1; j >= 0; j--) { + if ((listeners[j].action === fn) && (!context || (listeners[j].context === context))) { + removed = listeners.splice(j, 1); + // set the old action to a no-op, because it is possible + // that the listener is being iterated over as part of a dispatch + removed[0].action = L.Util.falseFn; + } + } + + if (context && typeIndex && (listeners.length === 0)) { + delete typeIndex[contextId]; + events[indexLenKey]--; + } + } + } + } + + return this; + }, + + clearAllEventListeners: function () { + delete this[eventsKey]; + return this; + }, + + fireEvent: function (type, data) { // (String[, Object]) + if (!this.hasEventListeners(type)) { + return this; + } + + var event = L.Util.extend({}, data, { type: type, target: this }); + + var events = this[eventsKey], + listeners, i, len, typeIndex, contextId; + + if (events[type]) { + // make sure adding/removing listeners inside other listeners won't cause infinite loop + listeners = events[type].slice(); + + for (i = 0, len = listeners.length; i < len; i++) { + listeners[i].action.call(listeners[i].context, event); + } + } + + // fire event for the context-indexed listeners as well + typeIndex = events[type + '_idx']; + + for (contextId in typeIndex) { + listeners = typeIndex[contextId].slice(); + + if (listeners) { + for (i = 0, len = listeners.length; i < len; i++) { + listeners[i].action.call(listeners[i].context, event); + } + } + } + + return this; + }, + + addOneTimeEventListener: function (types, fn, context) { + + if (L.Util.invokeEach(types, this.addOneTimeEventListener, this, fn, context)) { return this; } + + var handler = L.bind(function () { + this + .removeEventListener(types, fn, context) + .removeEventListener(types, handler, context); + }, this); + + return this + .addEventListener(types, fn, context) + .addEventListener(types, handler, context); + } +}; + +L.Mixin.Events.on = L.Mixin.Events.addEventListener; +L.Mixin.Events.off = L.Mixin.Events.removeEventListener; +L.Mixin.Events.once = L.Mixin.Events.addOneTimeEventListener; +L.Mixin.Events.fire = L.Mixin.Events.fireEvent; + + +/* + * L.Browser handles different browser and feature detections for internal Leaflet use. + */ + +(function () { + + var ie = 'ActiveXObject' in window, + ielt9 = ie && !document.addEventListener, + + // terrible browser detection to work around Safari / iOS / Android browser bugs + ua = navigator.userAgent.toLowerCase(), + webkit = ua.indexOf('webkit') !== -1, + chrome = ua.indexOf('chrome') !== -1, + phantomjs = ua.indexOf('phantom') !== -1, + android = ua.indexOf('android') !== -1, + android23 = ua.search('android [23]') !== -1, + gecko = ua.indexOf('gecko') !== -1, + + mobile = typeof orientation !== undefined + '', + msPointer = !window.PointerEvent && window.MSPointerEvent, + pointer = (window.PointerEvent && window.navigator.pointerEnabled) || + msPointer, + retina = ('devicePixelRatio' in window && window.devicePixelRatio > 1) || + ('matchMedia' in window && window.matchMedia('(min-resolution:144dpi)') && + window.matchMedia('(min-resolution:144dpi)').matches), + + doc = document.documentElement, + ie3d = ie && ('transition' in doc.style), + webkit3d = ('WebKitCSSMatrix' in window) && ('m11' in new window.WebKitCSSMatrix()) && !android23, + gecko3d = 'MozPerspective' in doc.style, + opera3d = 'OTransition' in doc.style, + any3d = !window.L_DISABLE_3D && (ie3d || webkit3d || gecko3d || opera3d) && !phantomjs; + + var touch = !window.L_NO_TOUCH && !phantomjs && (pointer || 'ontouchstart' in window || + (window.DocumentTouch && document instanceof window.DocumentTouch)); + + L.Browser = { + ie: ie, + ielt9: ielt9, + webkit: webkit, + gecko: gecko && !webkit && !window.opera && !ie, + + android: android, + android23: android23, + + chrome: chrome, + + ie3d: ie3d, + webkit3d: webkit3d, + gecko3d: gecko3d, + opera3d: opera3d, + any3d: any3d, + + mobile: mobile, + mobileWebkit: mobile && webkit, + mobileWebkit3d: mobile && webkit3d, + mobileOpera: mobile && window.opera, + + touch: touch, + msPointer: msPointer, + pointer: pointer, + + retina: retina + }; + +}()); + + +/* + * L.Point represents a point with x and y coordinates. + */ + +L.Point = function (/*Number*/ x, /*Number*/ y, /*Boolean*/ round) { + this.x = (round ? Math.round(x) : x); + this.y = (round ? Math.round(y) : y); +}; + +L.Point.prototype = { + + clone: function () { + return new L.Point(this.x, this.y); + }, + + // non-destructive, returns a new point + add: function (point) { + return this.clone()._add(L.point(point)); + }, + + // destructive, used directly for performance in situations where it's safe to modify existing point + _add: function (point) { + this.x += point.x; + this.y += point.y; + return this; + }, + + subtract: function (point) { + return this.clone()._subtract(L.point(point)); + }, + + _subtract: function (point) { + this.x -= point.x; + this.y -= point.y; + return this; + }, + + divideBy: function (num) { + return this.clone()._divideBy(num); + }, + + _divideBy: function (num) { + this.x /= num; + this.y /= num; + return this; + }, + + multiplyBy: function (num) { + return this.clone()._multiplyBy(num); + }, + + _multiplyBy: function (num) { + this.x *= num; + this.y *= num; + return this; + }, + + round: function () { + return this.clone()._round(); + }, + + _round: function () { + this.x = Math.round(this.x); + this.y = Math.round(this.y); + return this; + }, + + floor: function () { + return this.clone()._floor(); + }, + + _floor: function () { + this.x = Math.floor(this.x); + this.y = Math.floor(this.y); + return this; + }, + + distanceTo: function (point) { + point = L.point(point); + + var x = point.x - this.x, + y = point.y - this.y; + + return Math.sqrt(x * x + y * y); + }, + + equals: function (point) { + point = L.point(point); + + return point.x === this.x && + point.y === this.y; + }, + + contains: function (point) { + point = L.point(point); + + return Math.abs(point.x) <= Math.abs(this.x) && + Math.abs(point.y) <= Math.abs(this.y); + }, + + toString: function () { + return 'Point(' + + L.Util.formatNum(this.x) + ', ' + + L.Util.formatNum(this.y) + ')'; + } +}; + +L.point = function (x, y, round) { + if (x instanceof L.Point) { + return x; + } + if (L.Util.isArray(x)) { + return new L.Point(x[0], x[1]); + } + if (x === undefined || x === null) { + return x; + } + return new L.Point(x, y, round); +}; + + +/* + * L.Bounds represents a rectangular area on the screen in pixel coordinates. + */ + +L.Bounds = function (a, b) { //(Point, Point) or Point[] + if (!a) { return; } + + var points = b ? [a, b] : a; + + for (var i = 0, len = points.length; i < len; i++) { + this.extend(points[i]); + } +}; + +L.Bounds.prototype = { + // extend the bounds to contain the given point + extend: function (point) { // (Point) + point = L.point(point); + + if (!this.min && !this.max) { + this.min = point.clone(); + this.max = point.clone(); + } else { + this.min.x = Math.min(point.x, this.min.x); + this.max.x = Math.max(point.x, this.max.x); + this.min.y = Math.min(point.y, this.min.y); + this.max.y = Math.max(point.y, this.max.y); + } + return this; + }, + + getCenter: function (round) { // (Boolean) -> Point + return new L.Point( + (this.min.x + this.max.x) / 2, + (this.min.y + this.max.y) / 2, round); + }, + + getBottomLeft: function () { // -> Point + return new L.Point(this.min.x, this.max.y); + }, + + getTopRight: function () { // -> Point + return new L.Point(this.max.x, this.min.y); + }, + + getSize: function () { + return this.max.subtract(this.min); + }, + + contains: function (obj) { // (Bounds) or (Point) -> Boolean + var min, max; + + if (typeof obj[0] === 'number' || obj instanceof L.Point) { + obj = L.point(obj); + } else { + obj = L.bounds(obj); + } + + if (obj instanceof L.Bounds) { + min = obj.min; + max = obj.max; + } else { + min = max = obj; + } + + return (min.x >= this.min.x) && + (max.x <= this.max.x) && + (min.y >= this.min.y) && + (max.y <= this.max.y); + }, + + intersects: function (bounds) { // (Bounds) -> Boolean + bounds = L.bounds(bounds); + + var min = this.min, + max = this.max, + min2 = bounds.min, + max2 = bounds.max, + xIntersects = (max2.x >= min.x) && (min2.x <= max.x), + yIntersects = (max2.y >= min.y) && (min2.y <= max.y); + + return xIntersects && yIntersects; + }, + + isValid: function () { + return !!(this.min && this.max); + } +}; + +L.bounds = function (a, b) { // (Bounds) or (Point, Point) or (Point[]) + if (!a || a instanceof L.Bounds) { + return a; + } + return new L.Bounds(a, b); +}; + + +/* + * L.Transformation is an utility class to perform simple point transformations through a 2d-matrix. + */ + +L.Transformation = function (a, b, c, d) { + this._a = a; + this._b = b; + this._c = c; + this._d = d; +}; + +L.Transformation.prototype = { + transform: function (point, scale) { // (Point, Number) -> Point + return this._transform(point.clone(), scale); + }, + + // destructive transform (faster) + _transform: function (point, scale) { + scale = scale || 1; + point.x = scale * (this._a * point.x + this._b); + point.y = scale * (this._c * point.y + this._d); + return point; + }, + + untransform: function (point, scale) { + scale = scale || 1; + return new L.Point( + (point.x / scale - this._b) / this._a, + (point.y / scale - this._d) / this._c); + } +}; + + +/* + * L.DomUtil contains various utility functions for working with DOM. + */ + +L.DomUtil = { + get: function (id) { + return (typeof id === 'string' ? document.getElementById(id) : id); + }, + + getStyle: function (el, style) { + + var value = el.style[style]; + + if (!value && el.currentStyle) { + value = el.currentStyle[style]; + } + + if ((!value || value === 'auto') && document.defaultView) { + var css = document.defaultView.getComputedStyle(el, null); + value = css ? css[style] : null; + } + + return value === 'auto' ? null : value; + }, + + getViewportOffset: function (element) { + + var top = 0, + left = 0, + el = element, + docBody = document.body, + docEl = document.documentElement, + pos; + + do { + top += el.offsetTop || 0; + left += el.offsetLeft || 0; + + //add borders + top += parseInt(L.DomUtil.getStyle(el, 'borderTopWidth'), 10) || 0; + left += parseInt(L.DomUtil.getStyle(el, 'borderLeftWidth'), 10) || 0; + + pos = L.DomUtil.getStyle(el, 'position'); + + if (el.offsetParent === docBody && pos === 'absolute') { break; } + + if (pos === 'fixed') { + top += docBody.scrollTop || docEl.scrollTop || 0; + left += docBody.scrollLeft || docEl.scrollLeft || 0; + break; + } + + if (pos === 'relative' && !el.offsetLeft) { + var width = L.DomUtil.getStyle(el, 'width'), + maxWidth = L.DomUtil.getStyle(el, 'max-width'), + r = el.getBoundingClientRect(); + + if (width !== 'none' || maxWidth !== 'none') { + left += r.left + el.clientLeft; + } + + //calculate full y offset since we're breaking out of the loop + top += r.top + (docBody.scrollTop || docEl.scrollTop || 0); + + break; + } + + el = el.offsetParent; + + } while (el); + + el = element; + + do { + if (el === docBody) { break; } + + top -= el.scrollTop || 0; + left -= el.scrollLeft || 0; + + el = el.parentNode; + } while (el); + + return new L.Point(left, top); + }, + + documentIsLtr: function () { + if (!L.DomUtil._docIsLtrCached) { + L.DomUtil._docIsLtrCached = true; + L.DomUtil._docIsLtr = L.DomUtil.getStyle(document.body, 'direction') === 'ltr'; + } + return L.DomUtil._docIsLtr; + }, + + create: function (tagName, className, container) { + + var el = document.createElement(tagName); + el.className = className; + + if (container) { + container.appendChild(el); + } + + return el; + }, + + hasClass: function (el, name) { + if (el.classList !== undefined) { + return el.classList.contains(name); + } + var className = L.DomUtil._getClass(el); + return className.length > 0 && new RegExp('(^|\\s)' + name + '(\\s|$)').test(className); + }, + + addClass: function (el, name) { + if (el.classList !== undefined) { + var classes = L.Util.splitWords(name); + for (var i = 0, len = classes.length; i < len; i++) { + el.classList.add(classes[i]); + } + } else if (!L.DomUtil.hasClass(el, name)) { + var className = L.DomUtil._getClass(el); + L.DomUtil._setClass(el, (className ? className + ' ' : '') + name); + } + }, + + removeClass: function (el, name) { + if (el.classList !== undefined) { + el.classList.remove(name); + } else { + L.DomUtil._setClass(el, L.Util.trim((' ' + L.DomUtil._getClass(el) + ' ').replace(' ' + name + ' ', ' '))); + } + }, + + _setClass: function (el, name) { + if (el.className.baseVal === undefined) { + el.className = name; + } else { + // in case of SVG element + el.className.baseVal = name; + } + }, + + _getClass: function (el) { + return el.className.baseVal === undefined ? el.className : el.className.baseVal; + }, + + setOpacity: function (el, value) { + + if ('opacity' in el.style) { + el.style.opacity = value; + + } else if ('filter' in el.style) { + + var filter = false, + filterName = 'DXImageTransform.Microsoft.Alpha'; + + // filters collection throws an error if we try to retrieve a filter that doesn't exist + try { + filter = el.filters.item(filterName); + } catch (e) { + // don't set opacity to 1 if we haven't already set an opacity, + // it isn't needed and breaks transparent pngs. + if (value === 1) { return; } + } + + value = Math.round(value * 100); + + if (filter) { + filter.Enabled = (value !== 100); + filter.Opacity = value; + } else { + el.style.filter += ' progid:' + filterName + '(opacity=' + value + ')'; + } + } + }, + + testProp: function (props) { + + var style = document.documentElement.style; + + for (var i = 0; i < props.length; i++) { + if (props[i] in style) { + return props[i]; + } + } + return false; + }, + + getTranslateString: function (point) { + // on WebKit browsers (Chrome/Safari/iOS Safari/Android) using translate3d instead of translate + // makes animation smoother as it ensures HW accel is used. Firefox 13 doesn't care + // (same speed either way), Opera 12 doesn't support translate3d + + var is3d = L.Browser.webkit3d, + open = 'translate' + (is3d ? '3d' : '') + '(', + close = (is3d ? ',0' : '') + ')'; + + return open + point.x + 'px,' + point.y + 'px' + close; + }, + + getScaleString: function (scale, origin) { + + var preTranslateStr = L.DomUtil.getTranslateString(origin.add(origin.multiplyBy(-1 * scale))), + scaleStr = ' scale(' + scale + ') '; + + return preTranslateStr + scaleStr; + }, + + setPosition: function (el, point, disable3D) { // (HTMLElement, Point[, Boolean]) + + // jshint camelcase: false + el._leaflet_pos = point; + + if (!disable3D && L.Browser.any3d) { + el.style[L.DomUtil.TRANSFORM] = L.DomUtil.getTranslateString(point); + } else { + el.style.left = point.x + 'px'; + el.style.top = point.y + 'px'; + } + }, + + getPosition: function (el) { + // this method is only used for elements previously positioned using setPosition, + // so it's safe to cache the position for performance + + // jshint camelcase: false + return el._leaflet_pos; + } +}; + + +// prefix style property names + +L.DomUtil.TRANSFORM = L.DomUtil.testProp( + ['transform', 'WebkitTransform', 'OTransform', 'MozTransform', 'msTransform']); + +// webkitTransition comes first because some browser versions that drop vendor prefix don't do +// the same for the transitionend event, in particular the Android 4.1 stock browser + +L.DomUtil.TRANSITION = L.DomUtil.testProp( + ['webkitTransition', 'transition', 'OTransition', 'MozTransition', 'msTransition']); + +L.DomUtil.TRANSITION_END = + L.DomUtil.TRANSITION === 'webkitTransition' || L.DomUtil.TRANSITION === 'OTransition' ? + L.DomUtil.TRANSITION + 'End' : 'transitionend'; + +(function () { + if ('onselectstart' in document) { + L.extend(L.DomUtil, { + disableTextSelection: function () { + L.DomEvent.on(window, 'selectstart', L.DomEvent.preventDefault); + }, + + enableTextSelection: function () { + L.DomEvent.off(window, 'selectstart', L.DomEvent.preventDefault); + } + }); + } else { + var userSelectProperty = L.DomUtil.testProp( + ['userSelect', 'WebkitUserSelect', 'OUserSelect', 'MozUserSelect', 'msUserSelect']); + + L.extend(L.DomUtil, { + disableTextSelection: function () { + if (userSelectProperty) { + var style = document.documentElement.style; + this._userSelect = style[userSelectProperty]; + style[userSelectProperty] = 'none'; + } + }, + + enableTextSelection: function () { + if (userSelectProperty) { + document.documentElement.style[userSelectProperty] = this._userSelect; + delete this._userSelect; + } + } + }); + } + + L.extend(L.DomUtil, { + disableImageDrag: function () { + L.DomEvent.on(window, 'dragstart', L.DomEvent.preventDefault); + }, + + enableImageDrag: function () { + L.DomEvent.off(window, 'dragstart', L.DomEvent.preventDefault); + } + }); +})(); + + +/* + * L.LatLng represents a geographical point with latitude and longitude coordinates. + */ + +L.LatLng = function (lat, lng, alt) { // (Number, Number, Number) + lat = parseFloat(lat); + lng = parseFloat(lng); + + if (isNaN(lat) || isNaN(lng)) { + throw new Error('Invalid LatLng object: (' + lat + ', ' + lng + ')'); + } + + this.lat = lat; + this.lng = lng; + + if (alt !== undefined) { + this.alt = parseFloat(alt); + } +}; + +L.extend(L.LatLng, { + DEG_TO_RAD: Math.PI / 180, + RAD_TO_DEG: 180 / Math.PI, + MAX_MARGIN: 1.0E-9 // max margin of error for the "equals" check +}); + +L.LatLng.prototype = { + equals: function (obj) { // (LatLng) -> Boolean + if (!obj) { return false; } + + obj = L.latLng(obj); + + var margin = Math.max( + Math.abs(this.lat - obj.lat), + Math.abs(this.lng - obj.lng)); + + return margin <= L.LatLng.MAX_MARGIN; + }, + + toString: function (precision) { // (Number) -> String + return 'LatLng(' + + L.Util.formatNum(this.lat, precision) + ', ' + + L.Util.formatNum(this.lng, precision) + ')'; + }, + + // Haversine distance formula, see http://en.wikipedia.org/wiki/Haversine_formula + // TODO move to projection code, LatLng shouldn't know about Earth + distanceTo: function (other) { // (LatLng) -> Number + other = L.latLng(other); + + var R = 6378137, // earth radius in meters + d2r = L.LatLng.DEG_TO_RAD, + dLat = (other.lat - this.lat) * d2r, + dLon = (other.lng - this.lng) * d2r, + lat1 = this.lat * d2r, + lat2 = other.lat * d2r, + sin1 = Math.sin(dLat / 2), + sin2 = Math.sin(dLon / 2); + + var a = sin1 * sin1 + sin2 * sin2 * Math.cos(lat1) * Math.cos(lat2); + + return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + }, + + wrap: function (a, b) { // (Number, Number) -> LatLng + var lng = this.lng; + + a = a || -180; + b = b || 180; + + lng = (lng + b) % (b - a) + (lng < a || lng === b ? b : a); + + return new L.LatLng(this.lat, lng); + } +}; + +L.latLng = function (a, b) { // (LatLng) or ([Number, Number]) or (Number, Number) + if (a instanceof L.LatLng) { + return a; + } + if (L.Util.isArray(a)) { + if (typeof a[0] === 'number' || typeof a[0] === 'string') { + return new L.LatLng(a[0], a[1], a[2]); + } else { + return null; + } + } + if (a === undefined || a === null) { + return a; + } + if (typeof a === 'object' && 'lat' in a) { + return new L.LatLng(a.lat, 'lng' in a ? a.lng : a.lon); + } + if (b === undefined) { + return null; + } + return new L.LatLng(a, b); +}; + + + +/* + * L.LatLngBounds represents a rectangular area on the map in geographical coordinates. + */ + +L.LatLngBounds = function (southWest, northEast) { // (LatLng, LatLng) or (LatLng[]) + if (!southWest) { return; } + + var latlngs = northEast ? [southWest, northEast] : southWest; + + for (var i = 0, len = latlngs.length; i < len; i++) { + this.extend(latlngs[i]); + } +}; + +L.LatLngBounds.prototype = { + // extend the bounds to contain the given point or bounds + extend: function (obj) { // (LatLng) or (LatLngBounds) + if (!obj) { return this; } + + var latLng = L.latLng(obj); + if (latLng !== null) { + obj = latLng; + } else { + obj = L.latLngBounds(obj); + } + + if (obj instanceof L.LatLng) { + if (!this._southWest && !this._northEast) { + this._southWest = new L.LatLng(obj.lat, obj.lng); + this._northEast = new L.LatLng(obj.lat, obj.lng); + } else { + this._southWest.lat = Math.min(obj.lat, this._southWest.lat); + this._southWest.lng = Math.min(obj.lng, this._southWest.lng); + + this._northEast.lat = Math.max(obj.lat, this._northEast.lat); + this._northEast.lng = Math.max(obj.lng, this._northEast.lng); + } + } else if (obj instanceof L.LatLngBounds) { + this.extend(obj._southWest); + this.extend(obj._northEast); + } + return this; + }, + + // extend the bounds by a percentage + pad: function (bufferRatio) { // (Number) -> LatLngBounds + var sw = this._southWest, + ne = this._northEast, + heightBuffer = Math.abs(sw.lat - ne.lat) * bufferRatio, + widthBuffer = Math.abs(sw.lng - ne.lng) * bufferRatio; + + return new L.LatLngBounds( + new L.LatLng(sw.lat - heightBuffer, sw.lng - widthBuffer), + new L.LatLng(ne.lat + heightBuffer, ne.lng + widthBuffer)); + }, + + getCenter: function () { // -> LatLng + return new L.LatLng( + (this._southWest.lat + this._northEast.lat) / 2, + (this._southWest.lng + this._northEast.lng) / 2); + }, + + getSouthWest: function () { + return this._southWest; + }, + + getNorthEast: function () { + return this._northEast; + }, + + getNorthWest: function () { + return new L.LatLng(this.getNorth(), this.getWest()); + }, + + getSouthEast: function () { + return new L.LatLng(this.getSouth(), this.getEast()); + }, + + getWest: function () { + return this._southWest.lng; + }, + + getSouth: function () { + return this._southWest.lat; + }, + + getEast: function () { + return this._northEast.lng; + }, + + getNorth: function () { + return this._northEast.lat; + }, + + contains: function (obj) { // (LatLngBounds) or (LatLng) -> Boolean + if (typeof obj[0] === 'number' || obj instanceof L.LatLng) { + obj = L.latLng(obj); + } else { + obj = L.latLngBounds(obj); + } + + var sw = this._southWest, + ne = this._northEast, + sw2, ne2; + + if (obj instanceof L.LatLngBounds) { + sw2 = obj.getSouthWest(); + ne2 = obj.getNorthEast(); + } else { + sw2 = ne2 = obj; + } + + return (sw2.lat >= sw.lat) && (ne2.lat <= ne.lat) && + (sw2.lng >= sw.lng) && (ne2.lng <= ne.lng); + }, + + intersects: function (bounds) { // (LatLngBounds) + bounds = L.latLngBounds(bounds); + + var sw = this._southWest, + ne = this._northEast, + sw2 = bounds.getSouthWest(), + ne2 = bounds.getNorthEast(), + + latIntersects = (ne2.lat >= sw.lat) && (sw2.lat <= ne.lat), + lngIntersects = (ne2.lng >= sw.lng) && (sw2.lng <= ne.lng); + + return latIntersects && lngIntersects; + }, + + toBBoxString: function () { + return [this.getWest(), this.getSouth(), this.getEast(), this.getNorth()].join(','); + }, + + equals: function (bounds) { // (LatLngBounds) + if (!bounds) { return false; } + + bounds = L.latLngBounds(bounds); + + return this._southWest.equals(bounds.getSouthWest()) && + this._northEast.equals(bounds.getNorthEast()); + }, + + isValid: function () { + return !!(this._southWest && this._northEast); + } +}; + +//TODO International date line? + +L.latLngBounds = function (a, b) { // (LatLngBounds) or (LatLng, LatLng) + if (!a || a instanceof L.LatLngBounds) { + return a; + } + return new L.LatLngBounds(a, b); +}; + + +/* + * L.Projection contains various geographical projections used by CRS classes. + */ + +L.Projection = {}; + + +/* + * Spherical Mercator is the most popular map projection, used by EPSG:3857 CRS used by default. + */ + +L.Projection.SphericalMercator = { + MAX_LATITUDE: 85.0511287798, + + project: function (latlng) { // (LatLng) -> Point + var d = L.LatLng.DEG_TO_RAD, + max = this.MAX_LATITUDE, + lat = Math.max(Math.min(max, latlng.lat), -max), + x = latlng.lng * d, + y = lat * d; + + y = Math.log(Math.tan((Math.PI / 4) + (y / 2))); + + return new L.Point(x, y); + }, + + unproject: function (point) { // (Point, Boolean) -> LatLng + var d = L.LatLng.RAD_TO_DEG, + lng = point.x * d, + lat = (2 * Math.atan(Math.exp(point.y)) - (Math.PI / 2)) * d; + + return new L.LatLng(lat, lng); + } +}; + + +/* + * Simple equirectangular (Plate Carree) projection, used by CRS like EPSG:4326 and Simple. + */ + +L.Projection.LonLat = { + project: function (latlng) { + return new L.Point(latlng.lng, latlng.lat); + }, + + unproject: function (point) { + return new L.LatLng(point.y, point.x); + } +}; + + +/* + * L.CRS is a base object for all defined CRS (Coordinate Reference Systems) in Leaflet. + */ + +L.CRS = { + latLngToPoint: function (latlng, zoom) { // (LatLng, Number) -> Point + var projectedPoint = this.projection.project(latlng), + scale = this.scale(zoom); + + return this.transformation._transform(projectedPoint, scale); + }, + + pointToLatLng: function (point, zoom) { // (Point, Number[, Boolean]) -> LatLng + var scale = this.scale(zoom), + untransformedPoint = this.transformation.untransform(point, scale); + + return this.projection.unproject(untransformedPoint); + }, + + project: function (latlng) { + return this.projection.project(latlng); + }, + + scale: function (zoom) { + return 256 * Math.pow(2, zoom); + }, + + getSize: function (zoom) { + var s = this.scale(zoom); + return L.point(s, s); + } +}; + + +/* + * A simple CRS that can be used for flat non-Earth maps like panoramas or game maps. + */ + +L.CRS.Simple = L.extend({}, L.CRS, { + projection: L.Projection.LonLat, + transformation: new L.Transformation(1, 0, -1, 0), + + scale: function (zoom) { + return Math.pow(2, zoom); + } +}); + + +/* + * L.CRS.EPSG3857 (Spherical Mercator) is the most common CRS for web mapping + * and is used by Leaflet by default. + */ + +L.CRS.EPSG3857 = L.extend({}, L.CRS, { + code: 'EPSG:3857', + + projection: L.Projection.SphericalMercator, + transformation: new L.Transformation(0.5 / Math.PI, 0.5, -0.5 / Math.PI, 0.5), + + project: function (latlng) { // (LatLng) -> Point + var projectedPoint = this.projection.project(latlng), + earthRadius = 6378137; + return projectedPoint.multiplyBy(earthRadius); + } +}); + +L.CRS.EPSG900913 = L.extend({}, L.CRS.EPSG3857, { + code: 'EPSG:900913' +}); + + +/* + * L.CRS.EPSG4326 is a CRS popular among advanced GIS specialists. + */ + +L.CRS.EPSG4326 = L.extend({}, L.CRS, { + code: 'EPSG:4326', + + projection: L.Projection.LonLat, + transformation: new L.Transformation(1 / 360, 0.5, -1 / 360, 0.5) +}); + + +/* + * L.Map is the central class of the API - it is used to create a map. + */ + +L.Map = L.Class.extend({ + + includes: L.Mixin.Events, + + options: { + crs: L.CRS.EPSG3857, + + /* + center: LatLng, + zoom: Number, + layers: Array, + */ + + fadeAnimation: L.DomUtil.TRANSITION && !L.Browser.android23, + trackResize: true, + markerZoomAnimation: L.DomUtil.TRANSITION && L.Browser.any3d + }, + + initialize: function (id, options) { // (HTMLElement or String, Object) + options = L.setOptions(this, options); + + + this._initContainer(id); + this._initLayout(); + + // hack for https://github.com/Leaflet/Leaflet/issues/1980 + this._onResize = L.bind(this._onResize, this); + + this._initEvents(); + + if (options.maxBounds) { + this.setMaxBounds(options.maxBounds); + } + + if (options.center && options.zoom !== undefined) { + this.setView(L.latLng(options.center), options.zoom, {reset: true}); + } + + this._handlers = []; + + this._layers = {}; + this._zoomBoundLayers = {}; + this._tileLayersNum = 0; + + this.callInitHooks(); + + this._addLayers(options.layers); + }, + + + // public methods that modify map state + + // replaced by animation-powered implementation in Map.PanAnimation.js + setView: function (center, zoom) { + zoom = zoom === undefined ? this.getZoom() : zoom; + this._resetView(L.latLng(center), this._limitZoom(zoom)); + return this; + }, + + setZoom: function (zoom, options) { + if (!this._loaded) { + this._zoom = this._limitZoom(zoom); + return this; + } + return this.setView(this.getCenter(), zoom, {zoom: options}); + }, + + zoomIn: function (delta, options) { + return this.setZoom(this._zoom + (delta || 1), options); + }, + + zoomOut: function (delta, options) { + return this.setZoom(this._zoom - (delta || 1), options); + }, + + setZoomAround: function (latlng, zoom, options) { + var scale = this.getZoomScale(zoom), + viewHalf = this.getSize().divideBy(2), + containerPoint = latlng instanceof L.Point ? latlng : this.latLngToContainerPoint(latlng), + + centerOffset = containerPoint.subtract(viewHalf).multiplyBy(1 - 1 / scale), + newCenter = this.containerPointToLatLng(viewHalf.add(centerOffset)); + + return this.setView(newCenter, zoom, {zoom: options}); + }, + + fitBounds: function (bounds, options) { + + options = options || {}; + bounds = bounds.getBounds ? bounds.getBounds() : L.latLngBounds(bounds); + + var paddingTL = L.point(options.paddingTopLeft || options.padding || [0, 0]), + paddingBR = L.point(options.paddingBottomRight || options.padding || [0, 0]), + + zoom = this.getBoundsZoom(bounds, false, paddingTL.add(paddingBR)); + + zoom = (options.maxZoom) ? Math.min(options.maxZoom, zoom) : zoom; + + var paddingOffset = paddingBR.subtract(paddingTL).divideBy(2), + + swPoint = this.project(bounds.getSouthWest(), zoom), + nePoint = this.project(bounds.getNorthEast(), zoom), + center = this.unproject(swPoint.add(nePoint).divideBy(2).add(paddingOffset), zoom); + + return this.setView(center, zoom, options); + }, + + fitWorld: function (options) { + return this.fitBounds([[-90, -180], [90, 180]], options); + }, + + panTo: function (center, options) { // (LatLng) + return this.setView(center, this._zoom, {pan: options}); + }, + + panBy: function (offset) { // (Point) + // replaced with animated panBy in Map.PanAnimation.js + this.fire('movestart'); + + this._rawPanBy(L.point(offset)); + + this.fire('move'); + return this.fire('moveend'); + }, + + setMaxBounds: function (bounds) { + bounds = L.latLngBounds(bounds); + + this.options.maxBounds = bounds; + + if (!bounds) { + return this.off('moveend', this._panInsideMaxBounds, this); + } + + if (this._loaded) { + this._panInsideMaxBounds(); + } + + return this.on('moveend', this._panInsideMaxBounds, this); + }, + + panInsideBounds: function (bounds, options) { + var center = this.getCenter(), + newCenter = this._limitCenter(center, this._zoom, bounds); + + if (center.equals(newCenter)) { return this; } + + return this.panTo(newCenter, options); + }, + + addLayer: function (layer) { + // TODO method is too big, refactor + + var id = L.stamp(layer); + + if (this._layers[id]) { return this; } + + this._layers[id] = layer; + + // TODO getMaxZoom, getMinZoom in ILayer (instead of options) + if (layer.options && (!isNaN(layer.options.maxZoom) || !isNaN(layer.options.minZoom))) { + this._zoomBoundLayers[id] = layer; + this._updateZoomLevels(); + } + + // TODO looks ugly, refactor!!! + if (this.options.zoomAnimation && L.TileLayer && (layer instanceof L.TileLayer)) { + this._tileLayersNum++; + this._tileLayersToLoad++; + layer.on('load', this._onTileLayerLoad, this); + } + + if (this._loaded) { + this._layerAdd(layer); + } + + return this; + }, + + removeLayer: function (layer) { + var id = L.stamp(layer); + + if (!this._layers[id]) { return this; } + + if (this._loaded) { + layer.onRemove(this); + } + + delete this._layers[id]; + + if (this._loaded) { + this.fire('layerremove', {layer: layer}); + } + + if (this._zoomBoundLayers[id]) { + delete this._zoomBoundLayers[id]; + this._updateZoomLevels(); + } + + // TODO looks ugly, refactor + if (this.options.zoomAnimation && L.TileLayer && (layer instanceof L.TileLayer)) { + this._tileLayersNum--; + this._tileLayersToLoad--; + layer.off('load', this._onTileLayerLoad, this); + } + + return this; + }, + + hasLayer: function (layer) { + if (!layer) { return false; } + + return (L.stamp(layer) in this._layers); + }, + + eachLayer: function (method, context) { + for (var i in this._layers) { + method.call(context, this._layers[i]); + } + return this; + }, + + invalidateSize: function (options) { + if (!this._loaded) { return this; } + + options = L.extend({ + animate: false, + pan: true + }, options === true ? {animate: true} : options); + + var oldSize = this.getSize(); + this._sizeChanged = true; + this._initialCenter = null; + + var newSize = this.getSize(), + oldCenter = oldSize.divideBy(2).round(), + newCenter = newSize.divideBy(2).round(), + offset = oldCenter.subtract(newCenter); + + if (!offset.x && !offset.y) { return this; } + + if (options.animate && options.pan) { + this.panBy(offset); + + } else { + if (options.pan) { + this._rawPanBy(offset); + } + + this.fire('move'); + + if (options.debounceMoveend) { + clearTimeout(this._sizeTimer); + this._sizeTimer = setTimeout(L.bind(this.fire, this, 'moveend'), 200); + } else { + this.fire('moveend'); + } + } + + return this.fire('resize', { + oldSize: oldSize, + newSize: newSize + }); + }, + + // TODO handler.addTo + addHandler: function (name, HandlerClass) { + if (!HandlerClass) { return this; } + + var handler = this[name] = new HandlerClass(this); + + this._handlers.push(handler); + + if (this.options[name]) { + handler.enable(); + } + + return this; + }, + + remove: function () { + if (this._loaded) { + this.fire('unload'); + } + + this._initEvents('off'); + + try { + // throws error in IE6-8 + delete this._container._leaflet; + } catch (e) { + this._container._leaflet = undefined; + } + + this._clearPanes(); + if (this._clearControlPos) { + this._clearControlPos(); + } + + this._clearHandlers(); + + return this; + }, + + + // public methods for getting map state + + getCenter: function () { // (Boolean) -> LatLng + this._checkIfLoaded(); + + if (this._initialCenter && !this._moved()) { + return this._initialCenter; + } + return this.layerPointToLatLng(this._getCenterLayerPoint()); + }, + + getZoom: function () { + return this._zoom; + }, + + getBounds: function () { + var bounds = this.getPixelBounds(), + sw = this.unproject(bounds.getBottomLeft()), + ne = this.unproject(bounds.getTopRight()); + + return new L.LatLngBounds(sw, ne); + }, + + getMinZoom: function () { + return this.options.minZoom === undefined ? + (this._layersMinZoom === undefined ? 0 : this._layersMinZoom) : + this.options.minZoom; + }, + + getMaxZoom: function () { + return this.options.maxZoom === undefined ? + (this._layersMaxZoom === undefined ? Infinity : this._layersMaxZoom) : + this.options.maxZoom; + }, + + getBoundsZoom: function (bounds, inside, padding) { // (LatLngBounds[, Boolean, Point]) -> Number + bounds = L.latLngBounds(bounds); + + var zoom = this.getMinZoom() - (inside ? 1 : 0), + maxZoom = this.getMaxZoom(), + size = this.getSize(), + + nw = bounds.getNorthWest(), + se = bounds.getSouthEast(), + + zoomNotFound = true, + boundsSize; + + padding = L.point(padding || [0, 0]); + + do { + zoom++; + boundsSize = this.project(se, zoom).subtract(this.project(nw, zoom)).add(padding); + zoomNotFound = !inside ? size.contains(boundsSize) : boundsSize.x < size.x || boundsSize.y < size.y; + + } while (zoomNotFound && zoom <= maxZoom); + + if (zoomNotFound && inside) { + return null; + } + + return inside ? zoom : zoom - 1; + }, + + getSize: function () { + if (!this._size || this._sizeChanged) { + this._size = new L.Point( + this._container.clientWidth, + this._container.clientHeight); + + this._sizeChanged = false; + } + return this._size.clone(); + }, + + getPixelBounds: function () { + var topLeftPoint = this._getTopLeftPoint(); + return new L.Bounds(topLeftPoint, topLeftPoint.add(this.getSize())); + }, + + getPixelOrigin: function () { + this._checkIfLoaded(); + return this._initialTopLeftPoint; + }, + + getPanes: function () { + return this._panes; + }, + + getContainer: function () { + return this._container; + }, + + + // TODO replace with universal implementation after refactoring projections + + getZoomScale: function (toZoom) { + var crs = this.options.crs; + return crs.scale(toZoom) / crs.scale(this._zoom); + }, + + getScaleZoom: function (scale) { + return this._zoom + (Math.log(scale) / Math.LN2); + }, + + + // conversion methods + + project: function (latlng, zoom) { // (LatLng[, Number]) -> Point + zoom = zoom === undefined ? this._zoom : zoom; + return this.options.crs.latLngToPoint(L.latLng(latlng), zoom); + }, + + unproject: function (point, zoom) { // (Point[, Number]) -> LatLng + zoom = zoom === undefined ? this._zoom : zoom; + return this.options.crs.pointToLatLng(L.point(point), zoom); + }, + + layerPointToLatLng: function (point) { // (Point) + var projectedPoint = L.point(point).add(this.getPixelOrigin()); + return this.unproject(projectedPoint); + }, + + latLngToLayerPoint: function (latlng) { // (LatLng) + var projectedPoint = this.project(L.latLng(latlng))._round(); + return projectedPoint._subtract(this.getPixelOrigin()); + }, + + containerPointToLayerPoint: function (point) { // (Point) + return L.point(point).subtract(this._getMapPanePos()); + }, + + layerPointToContainerPoint: function (point) { // (Point) + return L.point(point).add(this._getMapPanePos()); + }, + + containerPointToLatLng: function (point) { + var layerPoint = this.containerPointToLayerPoint(L.point(point)); + return this.layerPointToLatLng(layerPoint); + }, + + latLngToContainerPoint: function (latlng) { + return this.layerPointToContainerPoint(this.latLngToLayerPoint(L.latLng(latlng))); + }, + + mouseEventToContainerPoint: function (e) { // (MouseEvent) + return L.DomEvent.getMousePosition(e, this._container); + }, + + mouseEventToLayerPoint: function (e) { // (MouseEvent) + return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(e)); + }, + + mouseEventToLatLng: function (e) { // (MouseEvent) + return this.layerPointToLatLng(this.mouseEventToLayerPoint(e)); + }, + + + // map initialization methods + + _initContainer: function (id) { + var container = this._container = L.DomUtil.get(id); + + if (!container) { + throw new Error('Map container not found.'); + } else if (container._leaflet) { + throw new Error('Map container is already initialized.'); + } + + container._leaflet = true; + }, + + _initLayout: function () { + var container = this._container; + + L.DomUtil.addClass(container, 'leaflet-container' + + (L.Browser.touch ? ' leaflet-touch' : '') + + (L.Browser.retina ? ' leaflet-retina' : '') + + (L.Browser.ielt9 ? ' leaflet-oldie' : '') + + (this.options.fadeAnimation ? ' leaflet-fade-anim' : '')); + + var position = L.DomUtil.getStyle(container, 'position'); + + if (position !== 'absolute' && position !== 'relative' && position !== 'fixed') { + container.style.position = 'relative'; + } + + this._initPanes(); + + if (this._initControlPos) { + this._initControlPos(); + } + }, + + _initPanes: function () { + var panes = this._panes = {}; + + this._mapPane = panes.mapPane = this._createPane('leaflet-map-pane', this._container); + + this._tilePane = panes.tilePane = this._createPane('leaflet-tile-pane', this._mapPane); + panes.objectsPane = this._createPane('leaflet-objects-pane', this._mapPane); + panes.shadowPane = this._createPane('leaflet-shadow-pane'); + panes.overlayPane = this._createPane('leaflet-overlay-pane'); + panes.markerPane = this._createPane('leaflet-marker-pane'); + panes.popupPane = this._createPane('leaflet-popup-pane'); + + var zoomHide = ' leaflet-zoom-hide'; + + if (!this.options.markerZoomAnimation) { + L.DomUtil.addClass(panes.markerPane, zoomHide); + L.DomUtil.addClass(panes.shadowPane, zoomHide); + L.DomUtil.addClass(panes.popupPane, zoomHide); + } + }, + + _createPane: function (className, container) { + return L.DomUtil.create('div', className, container || this._panes.objectsPane); + }, + + _clearPanes: function () { + this._container.removeChild(this._mapPane); + }, + + _addLayers: function (layers) { + layers = layers ? (L.Util.isArray(layers) ? layers : [layers]) : []; + + for (var i = 0, len = layers.length; i < len; i++) { + this.addLayer(layers[i]); + } + }, + + + // private methods that modify map state + + _resetView: function (center, zoom, preserveMapOffset, afterZoomAnim) { + + var zoomChanged = (this._zoom !== zoom); + + if (!afterZoomAnim) { + this.fire('movestart'); + + if (zoomChanged) { + this.fire('zoomstart'); + } + } + + this._zoom = zoom; + this._initialCenter = center; + + this._initialTopLeftPoint = this._getNewTopLeftPoint(center); + + if (!preserveMapOffset) { + L.DomUtil.setPosition(this._mapPane, new L.Point(0, 0)); + } else { + this._initialTopLeftPoint._add(this._getMapPanePos()); + } + + this._tileLayersToLoad = this._tileLayersNum; + + var loading = !this._loaded; + this._loaded = true; + + this.fire('viewreset', {hard: !preserveMapOffset}); + + if (loading) { + this.fire('load'); + this.eachLayer(this._layerAdd, this); + } + + this.fire('move'); + + if (zoomChanged || afterZoomAnim) { + this.fire('zoomend'); + } + + this.fire('moveend', {hard: !preserveMapOffset}); + }, + + _rawPanBy: function (offset) { + L.DomUtil.setPosition(this._mapPane, this._getMapPanePos().subtract(offset)); + }, + + _getZoomSpan: function () { + return this.getMaxZoom() - this.getMinZoom(); + }, + + _updateZoomLevels: function () { + var i, + minZoom = Infinity, + maxZoom = -Infinity, + oldZoomSpan = this._getZoomSpan(); + + for (i in this._zoomBoundLayers) { + var layer = this._zoomBoundLayers[i]; + if (!isNaN(layer.options.minZoom)) { + minZoom = Math.min(minZoom, layer.options.minZoom); + } + if (!isNaN(layer.options.maxZoom)) { + maxZoom = Math.max(maxZoom, layer.options.maxZoom); + } + } + + if (i === undefined) { // we have no tilelayers + this._layersMaxZoom = this._layersMinZoom = undefined; + } else { + this._layersMaxZoom = maxZoom; + this._layersMinZoom = minZoom; + } + + if (oldZoomSpan !== this._getZoomSpan()) { + this.fire('zoomlevelschange'); + } + }, + + _panInsideMaxBounds: function () { + this.panInsideBounds(this.options.maxBounds); + }, + + _checkIfLoaded: function () { + if (!this._loaded) { + throw new Error('Set map center and zoom first.'); + } + }, + + // map events + + _initEvents: function (onOff) { + if (!L.DomEvent) { return; } + + onOff = onOff || 'on'; + + L.DomEvent[onOff](this._container, 'click', this._onMouseClick, this); + + var events = ['dblclick', 'mousedown', 'mouseup', 'mouseenter', + 'mouseleave', 'mousemove', 'contextmenu'], + i, len; + + for (i = 0, len = events.length; i < len; i++) { + L.DomEvent[onOff](this._container, events[i], this._fireMouseEvent, this); + } + + if (this.options.trackResize) { + L.DomEvent[onOff](window, 'resize', this._onResize, this); + } + }, + + _onResize: function () { + L.Util.cancelAnimFrame(this._resizeRequest); + this._resizeRequest = L.Util.requestAnimFrame( + function () { this.invalidateSize({debounceMoveend: true}); }, this, false, this._container); + }, + + _onMouseClick: function (e) { + if (!this._loaded || (!e._simulated && + ((this.dragging && this.dragging.moved()) || + (this.boxZoom && this.boxZoom.moved()))) || + L.DomEvent._skipped(e)) { return; } + + this.fire('preclick'); + this._fireMouseEvent(e); + }, + + _fireMouseEvent: function (e) { + if (!this._loaded || L.DomEvent._skipped(e)) { return; } + + var type = e.type; + + type = (type === 'mouseenter' ? 'mouseover' : (type === 'mouseleave' ? 'mouseout' : type)); + + if (!this.hasEventListeners(type)) { return; } + + if (type === 'contextmenu') { + L.DomEvent.preventDefault(e); + } + + var containerPoint = this.mouseEventToContainerPoint(e), + layerPoint = this.containerPointToLayerPoint(containerPoint), + latlng = this.layerPointToLatLng(layerPoint); + + this.fire(type, { + latlng: latlng, + layerPoint: layerPoint, + containerPoint: containerPoint, + originalEvent: e + }); + }, + + _onTileLayerLoad: function () { + this._tileLayersToLoad--; + if (this._tileLayersNum && !this._tileLayersToLoad) { + this.fire('tilelayersload'); + } + }, + + _clearHandlers: function () { + for (var i = 0, len = this._handlers.length; i < len; i++) { + this._handlers[i].disable(); + } + }, + + whenReady: function (callback, context) { + if (this._loaded) { + callback.call(context || this, this); + } else { + this.on('load', callback, context); + } + return this; + }, + + _layerAdd: function (layer) { + layer.onAdd(this); + this.fire('layeradd', {layer: layer}); + }, + + + // private methods for getting map state + + _getMapPanePos: function () { + return L.DomUtil.getPosition(this._mapPane); + }, + + _moved: function () { + var pos = this._getMapPanePos(); + return pos && !pos.equals([0, 0]); + }, + + _getTopLeftPoint: function () { + return this.getPixelOrigin().subtract(this._getMapPanePos()); + }, + + _getNewTopLeftPoint: function (center, zoom) { + var viewHalf = this.getSize()._divideBy(2); + // TODO round on display, not calculation to increase precision? + return this.project(center, zoom)._subtract(viewHalf)._round(); + }, + + _latLngToNewLayerPoint: function (latlng, newZoom, newCenter) { + var topLeft = this._getNewTopLeftPoint(newCenter, newZoom).add(this._getMapPanePos()); + return this.project(latlng, newZoom)._subtract(topLeft); + }, + + // layer point of the current center + _getCenterLayerPoint: function () { + return this.containerPointToLayerPoint(this.getSize()._divideBy(2)); + }, + + // offset of the specified place to the current center in pixels + _getCenterOffset: function (latlng) { + return this.latLngToLayerPoint(latlng).subtract(this._getCenterLayerPoint()); + }, + + // adjust center for view to get inside bounds + _limitCenter: function (center, zoom, bounds) { + + if (!bounds) { return center; } + + var centerPoint = this.project(center, zoom), + viewHalf = this.getSize().divideBy(2), + viewBounds = new L.Bounds(centerPoint.subtract(viewHalf), centerPoint.add(viewHalf)), + offset = this._getBoundsOffset(viewBounds, bounds, zoom); + + return this.unproject(centerPoint.add(offset), zoom); + }, + + // adjust offset for view to get inside bounds + _limitOffset: function (offset, bounds) { + if (!bounds) { return offset; } + + var viewBounds = this.getPixelBounds(), + newBounds = new L.Bounds(viewBounds.min.add(offset), viewBounds.max.add(offset)); + + return offset.add(this._getBoundsOffset(newBounds, bounds)); + }, + + // returns offset needed for pxBounds to get inside maxBounds at a specified zoom + _getBoundsOffset: function (pxBounds, maxBounds, zoom) { + var nwOffset = this.project(maxBounds.getNorthWest(), zoom).subtract(pxBounds.min), + seOffset = this.project(maxBounds.getSouthEast(), zoom).subtract(pxBounds.max), + + dx = this._rebound(nwOffset.x, -seOffset.x), + dy = this._rebound(nwOffset.y, -seOffset.y); + + return new L.Point(dx, dy); + }, + + _rebound: function (left, right) { + return left + right > 0 ? + Math.round(left - right) / 2 : + Math.max(0, Math.ceil(left)) - Math.max(0, Math.floor(right)); + }, + + _limitZoom: function (zoom) { + var min = this.getMinZoom(), + max = this.getMaxZoom(); + + return Math.max(min, Math.min(max, zoom)); + } +}); + +L.map = function (id, options) { + return new L.Map(id, options); +}; + + +/* + * Mercator projection that takes into account that the Earth is not a perfect sphere. + * Less popular than spherical mercator; used by projections like EPSG:3395. + */ + +L.Projection.Mercator = { + MAX_LATITUDE: 85.0840591556, + + R_MINOR: 6356752.314245179, + R_MAJOR: 6378137, + + project: function (latlng) { // (LatLng) -> Point + var d = L.LatLng.DEG_TO_RAD, + max = this.MAX_LATITUDE, + lat = Math.max(Math.min(max, latlng.lat), -max), + r = this.R_MAJOR, + r2 = this.R_MINOR, + x = latlng.lng * d * r, + y = lat * d, + tmp = r2 / r, + eccent = Math.sqrt(1.0 - tmp * tmp), + con = eccent * Math.sin(y); + + con = Math.pow((1 - con) / (1 + con), eccent * 0.5); + + var ts = Math.tan(0.5 * ((Math.PI * 0.5) - y)) / con; + y = -r * Math.log(ts); + + return new L.Point(x, y); + }, + + unproject: function (point) { // (Point, Boolean) -> LatLng + var d = L.LatLng.RAD_TO_DEG, + r = this.R_MAJOR, + r2 = this.R_MINOR, + lng = point.x * d / r, + tmp = r2 / r, + eccent = Math.sqrt(1 - (tmp * tmp)), + ts = Math.exp(- point.y / r), + phi = (Math.PI / 2) - 2 * Math.atan(ts), + numIter = 15, + tol = 1e-7, + i = numIter, + dphi = 0.1, + con; + + while ((Math.abs(dphi) > tol) && (--i > 0)) { + con = eccent * Math.sin(phi); + dphi = (Math.PI / 2) - 2 * Math.atan(ts * + Math.pow((1.0 - con) / (1.0 + con), 0.5 * eccent)) - phi; + phi += dphi; + } + + return new L.LatLng(phi * d, lng); + } +}; + + + +L.CRS.EPSG3395 = L.extend({}, L.CRS, { + code: 'EPSG:3395', + + projection: L.Projection.Mercator, + + transformation: (function () { + var m = L.Projection.Mercator, + r = m.R_MAJOR, + scale = 0.5 / (Math.PI * r); + + return new L.Transformation(scale, 0.5, -scale, 0.5); + }()) +}); + + +/* + * L.TileLayer is used for standard xyz-numbered tile layers. + */ + +L.TileLayer = L.Class.extend({ + includes: L.Mixin.Events, + + options: { + minZoom: 0, + maxZoom: 18, + tileSize: 256, + subdomains: 'abc', + errorTileUrl: '', + attribution: '', + zoomOffset: 0, + opacity: 1, + /* + maxNativeZoom: null, + zIndex: null, + tms: false, + continuousWorld: false, + noWrap: false, + zoomReverse: false, + detectRetina: false, + reuseTiles: false, + bounds: false, + */ + unloadInvisibleTiles: L.Browser.mobile, + updateWhenIdle: L.Browser.mobile + }, + + initialize: function (url, options) { + options = L.setOptions(this, options); + + // detecting retina displays, adjusting tileSize and zoom levels + if (options.detectRetina && L.Browser.retina && options.maxZoom > 0) { + + options.tileSize = Math.floor(options.tileSize / 2); + options.zoomOffset++; + + if (options.minZoom > 0) { + options.minZoom--; + } + this.options.maxZoom--; + } + + if (options.bounds) { + options.bounds = L.latLngBounds(options.bounds); + } + + this._url = url; + + var subdomains = this.options.subdomains; + + if (typeof subdomains === 'string') { + this.options.subdomains = subdomains.split(''); + } + }, + + onAdd: function (map) { + this._map = map; + this._animated = map._zoomAnimated; + + // create a container div for tiles + this._initContainer(); + + // set up events + map.on({ + 'viewreset': this._reset, + 'moveend': this._update + }, this); + + if (this._animated) { + map.on({ + 'zoomanim': this._animateZoom, + 'zoomend': this._endZoomAnim + }, this); + } + + if (!this.options.updateWhenIdle) { + this._limitedUpdate = L.Util.limitExecByInterval(this._update, 150, this); + map.on('move', this._limitedUpdate, this); + } + + this._reset(); + this._update(); + }, + + addTo: function (map) { + map.addLayer(this); + return this; + }, + + onRemove: function (map) { + this._container.parentNode.removeChild(this._container); + + map.off({ + 'viewreset': this._reset, + 'moveend': this._update + }, this); + + if (this._animated) { + map.off({ + 'zoomanim': this._animateZoom, + 'zoomend': this._endZoomAnim + }, this); + } + + if (!this.options.updateWhenIdle) { + map.off('move', this._limitedUpdate, this); + } + + this._container = null; + this._map = null; + }, + + bringToFront: function () { + var pane = this._map._panes.tilePane; + + if (this._container) { + pane.appendChild(this._container); + this._setAutoZIndex(pane, Math.max); + } + + return this; + }, + + bringToBack: function () { + var pane = this._map._panes.tilePane; + + if (this._container) { + pane.insertBefore(this._container, pane.firstChild); + this._setAutoZIndex(pane, Math.min); + } + + return this; + }, + + getAttribution: function () { + return this.options.attribution; + }, + + getContainer: function () { + return this._container; + }, + + setOpacity: function (opacity) { + this.options.opacity = opacity; + + if (this._map) { + this._updateOpacity(); + } + + return this; + }, + + setZIndex: function (zIndex) { + this.options.zIndex = zIndex; + this._updateZIndex(); + + return this; + }, + + setUrl: function (url, noRedraw) { + this._url = url; + + if (!noRedraw) { + this.redraw(); + } + + return this; + }, + + redraw: function () { + if (this._map) { + this._reset({hard: true}); + this._update(); + } + return this; + }, + + _updateZIndex: function () { + if (this._container && this.options.zIndex !== undefined) { + this._container.style.zIndex = this.options.zIndex; + } + }, + + _setAutoZIndex: function (pane, compare) { + + var layers = pane.children, + edgeZIndex = -compare(Infinity, -Infinity), // -Infinity for max, Infinity for min + zIndex, i, len; + + for (i = 0, len = layers.length; i < len; i++) { + + if (layers[i] !== this._container) { + zIndex = parseInt(layers[i].style.zIndex, 10); + + if (!isNaN(zIndex)) { + edgeZIndex = compare(edgeZIndex, zIndex); + } + } + } + + this.options.zIndex = this._container.style.zIndex = + (isFinite(edgeZIndex) ? edgeZIndex : 0) + compare(1, -1); + }, + + _updateOpacity: function () { + var i, + tiles = this._tiles; + + if (L.Browser.ielt9) { + for (i in tiles) { + L.DomUtil.setOpacity(tiles[i], this.options.opacity); + } + } else { + L.DomUtil.setOpacity(this._container, this.options.opacity); + } + }, + + _initContainer: function () { + var tilePane = this._map._panes.tilePane; + + if (!this._container) { + this._container = L.DomUtil.create('div', 'leaflet-layer'); + + this._updateZIndex(); + + if (this._animated) { + var className = 'leaflet-tile-container'; + + this._bgBuffer = L.DomUtil.create('div', className, this._container); + this._tileContainer = L.DomUtil.create('div', className, this._container); + + } else { + this._tileContainer = this._container; + } + + tilePane.appendChild(this._container); + + if (this.options.opacity < 1) { + this._updateOpacity(); + } + } + }, + + _reset: function (e) { + for (var key in this._tiles) { + this.fire('tileunload', {tile: this._tiles[key]}); + } + + this._tiles = {}; + this._tilesToLoad = 0; + + if (this.options.reuseTiles) { + this._unusedTiles = []; + } + + this._tileContainer.innerHTML = ''; + + if (this._animated && e && e.hard) { + this._clearBgBuffer(); + } + + this._initContainer(); + }, + + _getTileSize: function () { + var map = this._map, + zoom = map.getZoom() + this.options.zoomOffset, + zoomN = this.options.maxNativeZoom, + tileSize = this.options.tileSize; + + if (zoomN && zoom > zoomN) { + tileSize = Math.round(map.getZoomScale(zoom) / map.getZoomScale(zoomN) * tileSize); + } + + return tileSize; + }, + + _update: function () { + + if (!this._map) { return; } + + var map = this._map, + bounds = map.getPixelBounds(), + zoom = map.getZoom(), + tileSize = this._getTileSize(); + + if (zoom > this.options.maxZoom || zoom < this.options.minZoom) { + return; + } + + var tileBounds = L.bounds( + bounds.min.divideBy(tileSize)._floor(), + bounds.max.divideBy(tileSize)._floor()); + + this._addTilesFromCenterOut(tileBounds); + + if (this.options.unloadInvisibleTiles || this.options.reuseTiles) { + this._removeOtherTiles(tileBounds); + } + }, + + _addTilesFromCenterOut: function (bounds) { + var queue = [], + center = bounds.getCenter(); + + var j, i, point; + + for (j = bounds.min.y; j <= bounds.max.y; j++) { + for (i = bounds.min.x; i <= bounds.max.x; i++) { + point = new L.Point(i, j); + + if (this._tileShouldBeLoaded(point)) { + queue.push(point); + } + } + } + + var tilesToLoad = queue.length; + + if (tilesToLoad === 0) { return; } + + // load tiles in order of their distance to center + queue.sort(function (a, b) { + return a.distanceTo(center) - b.distanceTo(center); + }); + + var fragment = document.createDocumentFragment(); + + // if its the first batch of tiles to load + if (!this._tilesToLoad) { + this.fire('loading'); + } + + this._tilesToLoad += tilesToLoad; + + for (i = 0; i < tilesToLoad; i++) { + this._addTile(queue[i], fragment); + } + + this._tileContainer.appendChild(fragment); + }, + + _tileShouldBeLoaded: function (tilePoint) { + if ((tilePoint.x + ':' + tilePoint.y) in this._tiles) { + return false; // already loaded + } + + var options = this.options; + + if (!options.continuousWorld) { + var limit = this._getWrapTileNum(); + + // don't load if exceeds world bounds + if ((options.noWrap && (tilePoint.x < 0 || tilePoint.x >= limit.x)) || + tilePoint.y < 0 || tilePoint.y >= limit.y) { return false; } + } + + if (options.bounds) { + var tileSize = this._getTileSize(), + nwPoint = tilePoint.multiplyBy(tileSize), + sePoint = nwPoint.add([tileSize, tileSize]), + nw = this._map.unproject(nwPoint), + se = this._map.unproject(sePoint); + + // TODO temporary hack, will be removed after refactoring projections + // https://github.com/Leaflet/Leaflet/issues/1618 + if (!options.continuousWorld && !options.noWrap) { + nw = nw.wrap(); + se = se.wrap(); + } + + if (!options.bounds.intersects([nw, se])) { return false; } + } + + return true; + }, + + _removeOtherTiles: function (bounds) { + var kArr, x, y, key; + + for (key in this._tiles) { + kArr = key.split(':'); + x = parseInt(kArr[0], 10); + y = parseInt(kArr[1], 10); + + // remove tile if it's out of bounds + if (x < bounds.min.x || x > bounds.max.x || y < bounds.min.y || y > bounds.max.y) { + this._removeTile(key); + } + } + }, + + _removeTile: function (key) { + var tile = this._tiles[key]; + + this.fire('tileunload', {tile: tile, url: tile.src}); + + if (this.options.reuseTiles) { + L.DomUtil.removeClass(tile, 'leaflet-tile-loaded'); + this._unusedTiles.push(tile); + + } else if (tile.parentNode === this._tileContainer) { + this._tileContainer.removeChild(tile); + } + + // for https://github.com/CloudMade/Leaflet/issues/137 + if (!L.Browser.android) { + tile.onload = null; + tile.src = L.Util.emptyImageUrl; + } + + delete this._tiles[key]; + }, + + _addTile: function (tilePoint, container) { + var tilePos = this._getTilePos(tilePoint); + + // get unused tile - or create a new tile + var tile = this._getTile(); + + /* + Chrome 20 layouts much faster with top/left (verify with timeline, frames) + Android 4 browser has display issues with top/left and requires transform instead + (other browsers don't currently care) - see debug/hacks/jitter.html for an example + */ + L.DomUtil.setPosition(tile, tilePos, L.Browser.chrome); + + this._tiles[tilePoint.x + ':' + tilePoint.y] = tile; + + this._loadTile(tile, tilePoint); + + if (tile.parentNode !== this._tileContainer) { + container.appendChild(tile); + } + }, + + _getZoomForUrl: function () { + + var options = this.options, + zoom = this._map.getZoom(); + + if (options.zoomReverse) { + zoom = options.maxZoom - zoom; + } + + zoom += options.zoomOffset; + + return options.maxNativeZoom ? Math.min(zoom, options.maxNativeZoom) : zoom; + }, + + _getTilePos: function (tilePoint) { + var origin = this._map.getPixelOrigin(), + tileSize = this._getTileSize(); + + return tilePoint.multiplyBy(tileSize).subtract(origin); + }, + + // image-specific code (override to implement e.g. Canvas or SVG tile layer) + + getTileUrl: function (tilePoint) { + return L.Util.template(this._url, L.extend({ + s: this._getSubdomain(tilePoint), + z: tilePoint.z, + x: tilePoint.x, + y: tilePoint.y + }, this.options)); + }, + + _getWrapTileNum: function () { + var crs = this._map.options.crs, + size = crs.getSize(this._map.getZoom()); + return size.divideBy(this._getTileSize())._floor(); + }, + + _adjustTilePoint: function (tilePoint) { + + var limit = this._getWrapTileNum(); + + // wrap tile coordinates + if (!this.options.continuousWorld && !this.options.noWrap) { + tilePoint.x = ((tilePoint.x % limit.x) + limit.x) % limit.x; + } + + if (this.options.tms) { + tilePoint.y = limit.y - tilePoint.y - 1; + } + + tilePoint.z = this._getZoomForUrl(); + }, + + _getSubdomain: function (tilePoint) { + var index = Math.abs(tilePoint.x + tilePoint.y) % this.options.subdomains.length; + return this.options.subdomains[index]; + }, + + _getTile: function () { + if (this.options.reuseTiles && this._unusedTiles.length > 0) { + var tile = this._unusedTiles.pop(); + this._resetTile(tile); + return tile; + } + return this._createTile(); + }, + + // Override if data stored on a tile needs to be cleaned up before reuse + _resetTile: function (/*tile*/) {}, + + _createTile: function () { + var tile = L.DomUtil.create('img', 'leaflet-tile'); + tile.style.width = tile.style.height = this._getTileSize() + 'px'; + tile.galleryimg = 'no'; + + tile.onselectstart = tile.onmousemove = L.Util.falseFn; + + if (L.Browser.ielt9 && this.options.opacity !== undefined) { + L.DomUtil.setOpacity(tile, this.options.opacity); + } + // without this hack, tiles disappear after zoom on Chrome for Android + // https://github.com/Leaflet/Leaflet/issues/2078 + if (L.Browser.mobileWebkit3d) { + tile.style.WebkitBackfaceVisibility = 'hidden'; + } + return tile; + }, + + _loadTile: function (tile, tilePoint) { + tile._layer = this; + tile.onload = this._tileOnLoad; + tile.onerror = this._tileOnError; + + this._adjustTilePoint(tilePoint); + tile.src = this.getTileUrl(tilePoint); + + this.fire('tileloadstart', { + tile: tile, + url: tile.src + }); + }, + + _tileLoaded: function () { + this._tilesToLoad--; + + if (this._animated) { + L.DomUtil.addClass(this._tileContainer, 'leaflet-zoom-animated'); + } + + if (!this._tilesToLoad) { + this.fire('load'); + + if (this._animated) { + // clear scaled tiles after all new tiles are loaded (for performance) + clearTimeout(this._clearBgBufferTimer); + this._clearBgBufferTimer = setTimeout(L.bind(this._clearBgBuffer, this), 500); + } + } + }, + + _tileOnLoad: function () { + var layer = this._layer; + + //Only if we are loading an actual image + if (this.src !== L.Util.emptyImageUrl) { + L.DomUtil.addClass(this, 'leaflet-tile-loaded'); + + layer.fire('tileload', { + tile: this, + url: this.src + }); + } + + layer._tileLoaded(); + }, + + _tileOnError: function () { + var layer = this._layer; + + layer.fire('tileerror', { + tile: this, + url: this.src + }); + + var newUrl = layer.options.errorTileUrl; + if (newUrl) { + this.src = newUrl; + } + + layer._tileLoaded(); + } +}); + +L.tileLayer = function (url, options) { + return new L.TileLayer(url, options); +}; + + +/* + * L.TileLayer.WMS is used for putting WMS tile layers on the map. + */ + +L.TileLayer.WMS = L.TileLayer.extend({ + + defaultWmsParams: { + service: 'WMS', + request: 'GetMap', + version: '1.1.1', + layers: '', + styles: '', + format: 'image/jpeg', + transparent: false + }, + + initialize: function (url, options) { // (String, Object) + + this._url = url; + + var wmsParams = L.extend({}, this.defaultWmsParams), + tileSize = options.tileSize || this.options.tileSize; + + if (options.detectRetina && L.Browser.retina) { + wmsParams.width = wmsParams.height = tileSize * 2; + } else { + wmsParams.width = wmsParams.height = tileSize; + } + + for (var i in options) { + // all keys that are not TileLayer options go to WMS params + if (!this.options.hasOwnProperty(i) && i !== 'crs') { + wmsParams[i] = options[i]; + } + } + + this.wmsParams = wmsParams; + + L.setOptions(this, options); + }, + + onAdd: function (map) { + + this._crs = this.options.crs || map.options.crs; + + this._wmsVersion = parseFloat(this.wmsParams.version); + + var projectionKey = this._wmsVersion >= 1.3 ? 'crs' : 'srs'; + this.wmsParams[projectionKey] = this._crs.code; + + L.TileLayer.prototype.onAdd.call(this, map); + }, + + getTileUrl: function (tilePoint) { // (Point, Number) -> String + + var map = this._map, + tileSize = this.options.tileSize, + + nwPoint = tilePoint.multiplyBy(tileSize), + sePoint = nwPoint.add([tileSize, tileSize]), + + nw = this._crs.project(map.unproject(nwPoint, tilePoint.z)), + se = this._crs.project(map.unproject(sePoint, tilePoint.z)), + bbox = this._wmsVersion >= 1.3 && this._crs === L.CRS.EPSG4326 ? + [se.y, nw.x, nw.y, se.x].join(',') : + [nw.x, se.y, se.x, nw.y].join(','), + + url = L.Util.template(this._url, {s: this._getSubdomain(tilePoint)}); + + return url + L.Util.getParamString(this.wmsParams, url, true) + '&BBOX=' + bbox; + }, + + setParams: function (params, noRedraw) { + + L.extend(this.wmsParams, params); + + if (!noRedraw) { + this.redraw(); + } + + return this; + } +}); + +L.tileLayer.wms = function (url, options) { + return new L.TileLayer.WMS(url, options); +}; + + +/* + * L.TileLayer.Canvas is a class that you can use as a base for creating + * dynamically drawn Canvas-based tile layers. + */ + +L.TileLayer.Canvas = L.TileLayer.extend({ + options: { + async: false + }, + + initialize: function (options) { + L.setOptions(this, options); + }, + + redraw: function () { + if (this._map) { + this._reset({hard: true}); + this._update(); + } + + for (var i in this._tiles) { + this._redrawTile(this._tiles[i]); + } + return this; + }, + + _redrawTile: function (tile) { + this.drawTile(tile, tile._tilePoint, this._map._zoom); + }, + + _createTile: function () { + var tile = L.DomUtil.create('canvas', 'leaflet-tile'); + tile.width = tile.height = this.options.tileSize; + tile.onselectstart = tile.onmousemove = L.Util.falseFn; + return tile; + }, + + _loadTile: function (tile, tilePoint) { + tile._layer = this; + tile._tilePoint = tilePoint; + + this._redrawTile(tile); + + if (!this.options.async) { + this.tileDrawn(tile); + } + }, + + drawTile: function (/*tile, tilePoint*/) { + // override with rendering code + }, + + tileDrawn: function (tile) { + this._tileOnLoad.call(tile); + } +}); + + +L.tileLayer.canvas = function (options) { + return new L.TileLayer.Canvas(options); +}; + + +/* + * L.ImageOverlay is used to overlay images over the map (to specific geographical bounds). + */ + +L.ImageOverlay = L.Class.extend({ + includes: L.Mixin.Events, + + options: { + opacity: 1 + }, + + initialize: function (url, bounds, options) { // (String, LatLngBounds, Object) + this._url = url; + this._bounds = L.latLngBounds(bounds); + + L.setOptions(this, options); + }, + + onAdd: function (map) { + this._map = map; + + if (!this._image) { + this._initImage(); + } + + map._panes.overlayPane.appendChild(this._image); + + map.on('viewreset', this._reset, this); + + if (map.options.zoomAnimation && L.Browser.any3d) { + map.on('zoomanim', this._animateZoom, this); + } + + this._reset(); + }, + + onRemove: function (map) { + map.getPanes().overlayPane.removeChild(this._image); + + map.off('viewreset', this._reset, this); + + if (map.options.zoomAnimation) { + map.off('zoomanim', this._animateZoom, this); + } + }, + + addTo: function (map) { + map.addLayer(this); + return this; + }, + + setOpacity: function (opacity) { + this.options.opacity = opacity; + this._updateOpacity(); + return this; + }, + + // TODO remove bringToFront/bringToBack duplication from TileLayer/Path + bringToFront: function () { + if (this._image) { + this._map._panes.overlayPane.appendChild(this._image); + } + return this; + }, + + bringToBack: function () { + var pane = this._map._panes.overlayPane; + if (this._image) { + pane.insertBefore(this._image, pane.firstChild); + } + return this; + }, + + setUrl: function (url) { + this._url = url; + this._image.src = this._url; + }, + + getAttribution: function () { + return this.options.attribution; + }, + + _initImage: function () { + this._image = L.DomUtil.create('img', 'leaflet-image-layer'); + + if (this._map.options.zoomAnimation && L.Browser.any3d) { + L.DomUtil.addClass(this._image, 'leaflet-zoom-animated'); + } else { + L.DomUtil.addClass(this._image, 'leaflet-zoom-hide'); + } + + this._updateOpacity(); + + //TODO createImage util method to remove duplication + L.extend(this._image, { + galleryimg: 'no', + onselectstart: L.Util.falseFn, + onmousemove: L.Util.falseFn, + onload: L.bind(this._onImageLoad, this), + src: this._url + }); + }, + + _animateZoom: function (e) { + var map = this._map, + image = this._image, + scale = map.getZoomScale(e.zoom), + nw = this._bounds.getNorthWest(), + se = this._bounds.getSouthEast(), + + topLeft = map._latLngToNewLayerPoint(nw, e.zoom, e.center), + size = map._latLngToNewLayerPoint(se, e.zoom, e.center)._subtract(topLeft), + origin = topLeft._add(size._multiplyBy((1 / 2) * (1 - 1 / scale))); + + image.style[L.DomUtil.TRANSFORM] = + L.DomUtil.getTranslateString(origin) + ' scale(' + scale + ') '; + }, + + _reset: function () { + var image = this._image, + topLeft = this._map.latLngToLayerPoint(this._bounds.getNorthWest()), + size = this._map.latLngToLayerPoint(this._bounds.getSouthEast())._subtract(topLeft); + + L.DomUtil.setPosition(image, topLeft); + + image.style.width = size.x + 'px'; + image.style.height = size.y + 'px'; + }, + + _onImageLoad: function () { + this.fire('load'); + }, + + _updateOpacity: function () { + L.DomUtil.setOpacity(this._image, this.options.opacity); + } +}); + +L.imageOverlay = function (url, bounds, options) { + return new L.ImageOverlay(url, bounds, options); +}; + + +/* + * L.Icon is an image-based icon class that you can use with L.Marker for custom markers. + */ + +L.Icon = L.Class.extend({ + options: { + /* + iconUrl: (String) (required) + iconRetinaUrl: (String) (optional, used for retina devices if detected) + iconSize: (Point) (can be set through CSS) + iconAnchor: (Point) (centered by default, can be set in CSS with negative margins) + popupAnchor: (Point) (if not specified, popup opens in the anchor point) + shadowUrl: (String) (no shadow by default) + shadowRetinaUrl: (String) (optional, used for retina devices if detected) + shadowSize: (Point) + shadowAnchor: (Point) + */ + className: '' + }, + + initialize: function (options) { + L.setOptions(this, options); + }, + + createIcon: function (oldIcon) { + return this._createIcon('icon', oldIcon); + }, + + createShadow: function (oldIcon) { + return this._createIcon('shadow', oldIcon); + }, + + _createIcon: function (name, oldIcon) { + var src = this._getIconUrl(name); + + if (!src) { + if (name === 'icon') { + throw new Error('iconUrl not set in Icon options (see the docs).'); + } + return null; + } + + var img; + if (!oldIcon || oldIcon.tagName !== 'IMG') { + img = this._createImg(src); + } else { + img = this._createImg(src, oldIcon); + } + this._setIconStyles(img, name); + + return img; + }, + + _setIconStyles: function (img, name) { + var options = this.options, + size = L.point(options[name + 'Size']), + anchor; + + if (name === 'shadow') { + anchor = L.point(options.shadowAnchor || options.iconAnchor); + } else { + anchor = L.point(options.iconAnchor); + } + + if (!anchor && size) { + anchor = size.divideBy(2, true); + } + + img.className = 'leaflet-marker-' + name + ' ' + options.className; + + if (anchor) { + img.style.marginLeft = (-anchor.x) + 'px'; + img.style.marginTop = (-anchor.y) + 'px'; + } + + if (size) { + img.style.width = size.x + 'px'; + img.style.height = size.y + 'px'; + } + }, + + _createImg: function (src, el) { + el = el || document.createElement('img'); + el.src = src; + return el; + }, + + _getIconUrl: function (name) { + if (L.Browser.retina && this.options[name + 'RetinaUrl']) { + return this.options[name + 'RetinaUrl']; + } + return this.options[name + 'Url']; + } +}); + +L.icon = function (options) { + return new L.Icon(options); +}; + + +/* + * L.Icon.Default is the blue marker icon used by default in Leaflet. + */ + +L.Icon.Default = L.Icon.extend({ + + options: { + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + + shadowSize: [41, 41] + }, + + _getIconUrl: function (name) { + var key = name + 'Url'; + + if (this.options[key]) { + return this.options[key]; + } + + if (L.Browser.retina && name === 'icon') { + return "/assets/marker-icon-2x-454dc479e82b487529b6b93d6a9b29ac69ca7b4f5a9d5fdf8e01871f6d216113.png"; + } + + if (name == 'shadow') { + return "/assets/marker-shadow-4f340d2d61746333dffe056e074ce1704ae4e47fec5a7de98322fbdbcfcb2b6d.png"; + } else { + return "/assets/marker-icon-915e83a6fc798c599e5c9e3f759d6bc065d65151019acd0410d1f4731bcaaf72.png"; + } + } +}); + +L.Icon.Default.imagePath = (function () { + var scripts = document.getElementsByTagName('script'), + leafletRe = /[\/^]leaflet[\-\._]?([\w\-\._]*)\.js\??/; + + var i, len, src, matches, path; + + for (i = 0, len = scripts.length; i < len; i++) { + src = scripts[i].src; + matches = src.match(leafletRe); + + if (matches) { + path = src.split(leafletRe)[0]; + return (path ? path + '/' : ''); + } + } +}()); + + +/* + * L.Marker is used to display clickable/draggable icons on the map. + */ + +L.Marker = L.Class.extend({ + + includes: L.Mixin.Events, + + options: { + icon: new L.Icon.Default(), + title: '', + alt: '', + clickable: true, + draggable: false, + keyboard: true, + zIndexOffset: 0, + opacity: 1, + riseOnHover: false, + riseOffset: 250 + }, + + initialize: function (latlng, options) { + L.setOptions(this, options); + this._latlng = L.latLng(latlng); + }, + + onAdd: function (map) { + this._map = map; + + map.on('viewreset', this.update, this); + + this._initIcon(); + this.update(); + this.fire('add'); + + if (map.options.zoomAnimation && map.options.markerZoomAnimation) { + map.on('zoomanim', this._animateZoom, this); + } + }, + + addTo: function (map) { + map.addLayer(this); + return this; + }, + + onRemove: function (map) { + if (this.dragging) { + this.dragging.disable(); + } + + this._removeIcon(); + this._removeShadow(); + + this.fire('remove'); + + map.off({ + 'viewreset': this.update, + 'zoomanim': this._animateZoom + }, this); + + this._map = null; + }, + + getLatLng: function () { + return this._latlng; + }, + + setLatLng: function (latlng) { + this._latlng = L.latLng(latlng); + + this.update(); + + return this.fire('move', { latlng: this._latlng }); + }, + + setZIndexOffset: function (offset) { + this.options.zIndexOffset = offset; + this.update(); + + return this; + }, + + setIcon: function (icon) { + + this.options.icon = icon; + + if (this._map) { + this._initIcon(); + this.update(); + } + + if (this._popup) { + this.bindPopup(this._popup); + } + + return this; + }, + + update: function () { + if (this._icon) { + this._setPos(this._map.latLngToLayerPoint(this._latlng).round()); + } + return this; + }, + + _initIcon: function () { + var options = this.options, + map = this._map, + animation = (map.options.zoomAnimation && map.options.markerZoomAnimation), + classToAdd = animation ? 'leaflet-zoom-animated' : 'leaflet-zoom-hide'; + + var icon = options.icon.createIcon(this._icon), + addIcon = false; + + // if we're not reusing the icon, remove the old one and init new one + if (icon !== this._icon) { + if (this._icon) { + this._removeIcon(); + } + addIcon = true; + + if (options.title) { + icon.title = options.title; + } + + if (options.alt) { + icon.alt = options.alt; + } + } + + L.DomUtil.addClass(icon, classToAdd); + + if (options.keyboard) { + icon.tabIndex = '0'; + } + + this._icon = icon; + + this._initInteraction(); + + if (options.riseOnHover) { + L.DomEvent + .on(icon, 'mouseover', this._bringToFront, this) + .on(icon, 'mouseout', this._resetZIndex, this); + } + + var newShadow = options.icon.createShadow(this._shadow), + addShadow = false; + + if (newShadow !== this._shadow) { + this._removeShadow(); + addShadow = true; + } + + if (newShadow) { + L.DomUtil.addClass(newShadow, classToAdd); + } + this._shadow = newShadow; + + + if (options.opacity < 1) { + this._updateOpacity(); + } + + + var panes = this._map._panes; + + if (addIcon) { + panes.markerPane.appendChild(this._icon); + } + + if (newShadow && addShadow) { + panes.shadowPane.appendChild(this._shadow); + } + }, + + _removeIcon: function () { + if (this.options.riseOnHover) { + L.DomEvent + .off(this._icon, 'mouseover', this._bringToFront) + .off(this._icon, 'mouseout', this._resetZIndex); + } + + this._map._panes.markerPane.removeChild(this._icon); + + this._icon = null; + }, + + _removeShadow: function () { + if (this._shadow) { + this._map._panes.shadowPane.removeChild(this._shadow); + } + this._shadow = null; + }, + + _setPos: function (pos) { + L.DomUtil.setPosition(this._icon, pos); + + if (this._shadow) { + L.DomUtil.setPosition(this._shadow, pos); + } + + this._zIndex = pos.y + this.options.zIndexOffset; + + this._resetZIndex(); + }, + + _updateZIndex: function (offset) { + this._icon.style.zIndex = this._zIndex + offset; + }, + + _animateZoom: function (opt) { + var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round(); + + this._setPos(pos); + }, + + _initInteraction: function () { + + if (!this.options.clickable) { return; } + + // TODO refactor into something shared with Map/Path/etc. to DRY it up + + var icon = this._icon, + events = ['dblclick', 'mousedown', 'mouseover', 'mouseout', 'contextmenu']; + + L.DomUtil.addClass(icon, 'leaflet-clickable'); + L.DomEvent.on(icon, 'click', this._onMouseClick, this); + L.DomEvent.on(icon, 'keypress', this._onKeyPress, this); + + for (var i = 0; i < events.length; i++) { + L.DomEvent.on(icon, events[i], this._fireMouseEvent, this); + } + + if (L.Handler.MarkerDrag) { + this.dragging = new L.Handler.MarkerDrag(this); + + if (this.options.draggable) { + this.dragging.enable(); + } + } + }, + + _onMouseClick: function (e) { + var wasDragged = this.dragging && this.dragging.moved(); + + if (this.hasEventListeners(e.type) || wasDragged) { + L.DomEvent.stopPropagation(e); + } + + if (wasDragged) { return; } + + if ((!this.dragging || !this.dragging._enabled) && this._map.dragging && this._map.dragging.moved()) { return; } + + this.fire(e.type, { + originalEvent: e, + latlng: this._latlng + }); + }, + + _onKeyPress: function (e) { + if (e.keyCode === 13) { + this.fire('click', { + originalEvent: e, + latlng: this._latlng + }); + } + }, + + _fireMouseEvent: function (e) { + + this.fire(e.type, { + originalEvent: e, + latlng: this._latlng + }); + + // TODO proper custom event propagation + // this line will always be called if marker is in a FeatureGroup + if (e.type === 'contextmenu' && this.hasEventListeners(e.type)) { + L.DomEvent.preventDefault(e); + } + if (e.type !== 'mousedown') { + L.DomEvent.stopPropagation(e); + } else { + L.DomEvent.preventDefault(e); + } + }, + + setOpacity: function (opacity) { + this.options.opacity = opacity; + if (this._map) { + this._updateOpacity(); + } + + return this; + }, + + _updateOpacity: function () { + L.DomUtil.setOpacity(this._icon, this.options.opacity); + if (this._shadow) { + L.DomUtil.setOpacity(this._shadow, this.options.opacity); + } + }, + + _bringToFront: function () { + this._updateZIndex(this.options.riseOffset); + }, + + _resetZIndex: function () { + this._updateZIndex(0); + } +}); + +L.marker = function (latlng, options) { + return new L.Marker(latlng, options); +}; + + +/* + * L.DivIcon is a lightweight HTML-based icon class (as opposed to the image-based L.Icon) + * to use with L.Marker. + */ + +L.DivIcon = L.Icon.extend({ + options: { + iconSize: [12, 12], // also can be set through CSS + /* + iconAnchor: (Point) + popupAnchor: (Point) + html: (String) + bgPos: (Point) + */ + className: 'leaflet-div-icon', + html: false + }, + + createIcon: function (oldIcon) { + var div = (oldIcon && oldIcon.tagName === 'DIV') ? oldIcon : document.createElement('div'), + options = this.options; + + if (options.html !== false) { + div.innerHTML = options.html; + } else { + div.innerHTML = ''; + } + + if (options.bgPos) { + div.style.backgroundPosition = + (-options.bgPos.x) + 'px ' + (-options.bgPos.y) + 'px'; + } + + this._setIconStyles(div, 'icon'); + return div; + }, + + createShadow: function () { + return null; + } +}); + +L.divIcon = function (options) { + return new L.DivIcon(options); +}; + + +/* + * L.Popup is used for displaying popups on the map. + */ + +L.Map.mergeOptions({ + closePopupOnClick: true +}); + +L.Popup = L.Class.extend({ + includes: L.Mixin.Events, + + options: { + minWidth: 50, + maxWidth: 300, + // maxHeight: null, + autoPan: true, + closeButton: true, + offset: [0, 7], + autoPanPadding: [5, 5], + // autoPanPaddingTopLeft: null, + // autoPanPaddingBottomRight: null, + keepInView: false, + className: '', + zoomAnimation: true + }, + + initialize: function (options, source) { + L.setOptions(this, options); + + this._source = source; + this._animated = L.Browser.any3d && this.options.zoomAnimation; + this._isOpen = false; + }, + + onAdd: function (map) { + this._map = map; + + if (!this._container) { + this._initLayout(); + } + + var animFade = map.options.fadeAnimation; + + if (animFade) { + L.DomUtil.setOpacity(this._container, 0); + } + map._panes.popupPane.appendChild(this._container); + + map.on(this._getEvents(), this); + + this.update(); + + if (animFade) { + L.DomUtil.setOpacity(this._container, 1); + } + + this.fire('open'); + + map.fire('popupopen', {popup: this}); + + if (this._source) { + this._source.fire('popupopen', {popup: this}); + } + }, + + addTo: function (map) { + map.addLayer(this); + return this; + }, + + openOn: function (map) { + map.openPopup(this); + return this; + }, + + onRemove: function (map) { + map._panes.popupPane.removeChild(this._container); + + L.Util.falseFn(this._container.offsetWidth); // force reflow + + map.off(this._getEvents(), this); + + if (map.options.fadeAnimation) { + L.DomUtil.setOpacity(this._container, 0); + } + + this._map = null; + + this.fire('close'); + + map.fire('popupclose', {popup: this}); + + if (this._source) { + this._source.fire('popupclose', {popup: this}); + } + }, + + getLatLng: function () { + return this._latlng; + }, + + setLatLng: function (latlng) { + this._latlng = L.latLng(latlng); + if (this._map) { + this._updatePosition(); + this._adjustPan(); + } + return this; + }, + + getContent: function () { + return this._content; + }, + + setContent: function (content) { + this._content = content; + this.update(); + return this; + }, + + update: function () { + if (!this._map) { return; } + + this._container.style.visibility = 'hidden'; + + this._updateContent(); + this._updateLayout(); + this._updatePosition(); + + this._container.style.visibility = ''; + + this._adjustPan(); + }, + + _getEvents: function () { + var events = { + viewreset: this._updatePosition + }; + + if (this._animated) { + events.zoomanim = this._zoomAnimation; + } + if ('closeOnClick' in this.options ? this.options.closeOnClick : this._map.options.closePopupOnClick) { + events.preclick = this._close; + } + if (this.options.keepInView) { + events.moveend = this._adjustPan; + } + + return events; + }, + + _close: function () { + if (this._map) { + this._map.closePopup(this); + } + }, + + _initLayout: function () { + var prefix = 'leaflet-popup', + containerClass = prefix + ' ' + this.options.className + ' leaflet-zoom-' + + (this._animated ? 'animated' : 'hide'), + container = this._container = L.DomUtil.create('div', containerClass), + closeButton; + + if (this.options.closeButton) { + closeButton = this._closeButton = + L.DomUtil.create('a', prefix + '-close-button', container); + closeButton.href = '#close'; + closeButton.innerHTML = '×'; + L.DomEvent.disableClickPropagation(closeButton); + + L.DomEvent.on(closeButton, 'click', this._onCloseButtonClick, this); + } + + var wrapper = this._wrapper = + L.DomUtil.create('div', prefix + '-content-wrapper', container); + L.DomEvent.disableClickPropagation(wrapper); + + this._contentNode = L.DomUtil.create('div', prefix + '-content', wrapper); + + L.DomEvent.disableScrollPropagation(this._contentNode); + L.DomEvent.on(wrapper, 'contextmenu', L.DomEvent.stopPropagation); + + this._tipContainer = L.DomUtil.create('div', prefix + '-tip-container', container); + this._tip = L.DomUtil.create('div', prefix + '-tip', this._tipContainer); + }, + + _updateContent: function () { + if (!this._content) { return; } + + if (typeof this._content === 'string') { + this._contentNode.innerHTML = this._content; + } else { + while (this._contentNode.hasChildNodes()) { + this._contentNode.removeChild(this._contentNode.firstChild); + } + this._contentNode.appendChild(this._content); + } + this.fire('contentupdate'); + }, + + _updateLayout: function () { + var container = this._contentNode, + style = container.style; + + style.width = ''; + style.whiteSpace = 'nowrap'; + + var width = container.offsetWidth; + width = Math.min(width, this.options.maxWidth); + width = Math.max(width, this.options.minWidth); + + style.width = (width + 1) + 'px'; + style.whiteSpace = ''; + + style.height = ''; + + var height = container.offsetHeight, + maxHeight = this.options.maxHeight, + scrolledClass = 'leaflet-popup-scrolled'; + + if (maxHeight && height > maxHeight) { + style.height = maxHeight + 'px'; + L.DomUtil.addClass(container, scrolledClass); + } else { + L.DomUtil.removeClass(container, scrolledClass); + } + + this._containerWidth = this._container.offsetWidth; + }, + + _updatePosition: function () { + if (!this._map) { return; } + + var pos = this._map.latLngToLayerPoint(this._latlng), + animated = this._animated, + offset = L.point(this.options.offset); + + if (animated) { + L.DomUtil.setPosition(this._container, pos); + } + + this._containerBottom = -offset.y - (animated ? 0 : pos.y); + this._containerLeft = -Math.round(this._containerWidth / 2) + offset.x + (animated ? 0 : pos.x); + + // bottom position the popup in case the height of the popup changes (images loading etc) + this._container.style.bottom = this._containerBottom + 'px'; + this._container.style.left = this._containerLeft + 'px'; + }, + + _zoomAnimation: function (opt) { + var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center); + + L.DomUtil.setPosition(this._container, pos); + }, + + _adjustPan: function () { + if (!this.options.autoPan) { return; } + + var map = this._map, + containerHeight = this._container.offsetHeight, + containerWidth = this._containerWidth, + + layerPos = new L.Point(this._containerLeft, -containerHeight - this._containerBottom); + + if (this._animated) { + layerPos._add(L.DomUtil.getPosition(this._container)); + } + + var containerPos = map.layerPointToContainerPoint(layerPos), + padding = L.point(this.options.autoPanPadding), + paddingTL = L.point(this.options.autoPanPaddingTopLeft || padding), + paddingBR = L.point(this.options.autoPanPaddingBottomRight || padding), + size = map.getSize(), + dx = 0, + dy = 0; + + if (containerPos.x + containerWidth + paddingBR.x > size.x) { // right + dx = containerPos.x + containerWidth - size.x + paddingBR.x; + } + if (containerPos.x - dx - paddingTL.x < 0) { // left + dx = containerPos.x - paddingTL.x; + } + if (containerPos.y + containerHeight + paddingBR.y > size.y) { // bottom + dy = containerPos.y + containerHeight - size.y + paddingBR.y; + } + if (containerPos.y - dy - paddingTL.y < 0) { // top + dy = containerPos.y - paddingTL.y; + } + + if (dx || dy) { + map + .fire('autopanstart') + .panBy([dx, dy]); + } + }, + + _onCloseButtonClick: function (e) { + this._close(); + L.DomEvent.stop(e); + } +}); + +L.popup = function (options, source) { + return new L.Popup(options, source); +}; + + +L.Map.include({ + openPopup: function (popup, latlng, options) { // (Popup) or (String || HTMLElement, LatLng[, Object]) + this.closePopup(); + + if (!(popup instanceof L.Popup)) { + var content = popup; + + popup = new L.Popup(options) + .setLatLng(latlng) + .setContent(content); + } + popup._isOpen = true; + + this._popup = popup; + return this.addLayer(popup); + }, + + closePopup: function (popup) { + if (!popup || popup === this._popup) { + popup = this._popup; + this._popup = null; + } + if (popup) { + this.removeLayer(popup); + popup._isOpen = false; + } + return this; + } +}); + + +/* + * Popup extension to L.Marker, adding popup-related methods. + */ + +L.Marker.include({ + openPopup: function () { + if (this._popup && this._map && !this._map.hasLayer(this._popup)) { + this._popup.setLatLng(this._latlng); + this._map.openPopup(this._popup); + } + + return this; + }, + + closePopup: function () { + if (this._popup) { + this._popup._close(); + } + return this; + }, + + togglePopup: function () { + if (this._popup) { + if (this._popup._isOpen) { + this.closePopup(); + } else { + this.openPopup(); + } + } + return this; + }, + + bindPopup: function (content, options) { + var anchor = L.point(this.options.icon.options.popupAnchor || [0, 0]); + + anchor = anchor.add(L.Popup.prototype.options.offset); + + if (options && options.offset) { + anchor = anchor.add(options.offset); + } + + options = L.extend({offset: anchor}, options); + + if (!this._popupHandlersAdded) { + this + .on('click', this.togglePopup, this) + .on('remove', this.closePopup, this) + .on('move', this._movePopup, this); + this._popupHandlersAdded = true; + } + + if (content instanceof L.Popup) { + L.setOptions(content, options); + this._popup = content; + content._source = this; + } else { + this._popup = new L.Popup(options, this) + .setContent(content); + } + + return this; + }, + + setPopupContent: function (content) { + if (this._popup) { + this._popup.setContent(content); + } + return this; + }, + + unbindPopup: function () { + if (this._popup) { + this._popup = null; + this + .off('click', this.togglePopup, this) + .off('remove', this.closePopup, this) + .off('move', this._movePopup, this); + this._popupHandlersAdded = false; + } + return this; + }, + + getPopup: function () { + return this._popup; + }, + + _movePopup: function (e) { + this._popup.setLatLng(e.latlng); + } +}); + + +/* + * L.LayerGroup is a class to combine several layers into one so that + * you can manipulate the group (e.g. add/remove it) as one layer. + */ + +L.LayerGroup = L.Class.extend({ + initialize: function (layers) { + this._layers = {}; + + var i, len; + + if (layers) { + for (i = 0, len = layers.length; i < len; i++) { + this.addLayer(layers[i]); + } + } + }, + + addLayer: function (layer) { + var id = this.getLayerId(layer); + + this._layers[id] = layer; + + if (this._map) { + this._map.addLayer(layer); + } + + return this; + }, + + removeLayer: function (layer) { + var id = layer in this._layers ? layer : this.getLayerId(layer); + + if (this._map && this._layers[id]) { + this._map.removeLayer(this._layers[id]); + } + + delete this._layers[id]; + + return this; + }, + + hasLayer: function (layer) { + if (!layer) { return false; } + + return (layer in this._layers || this.getLayerId(layer) in this._layers); + }, + + clearLayers: function () { + this.eachLayer(this.removeLayer, this); + return this; + }, + + invoke: function (methodName) { + var args = Array.prototype.slice.call(arguments, 1), + i, layer; + + for (i in this._layers) { + layer = this._layers[i]; + + if (layer[methodName]) { + layer[methodName].apply(layer, args); + } + } + + return this; + }, + + onAdd: function (map) { + this._map = map; + this.eachLayer(map.addLayer, map); + }, + + onRemove: function (map) { + this.eachLayer(map.removeLayer, map); + this._map = null; + }, + + addTo: function (map) { + map.addLayer(this); + return this; + }, + + eachLayer: function (method, context) { + for (var i in this._layers) { + method.call(context, this._layers[i]); + } + return this; + }, + + getLayer: function (id) { + return this._layers[id]; + }, + + getLayers: function () { + var layers = []; + + for (var i in this._layers) { + layers.push(this._layers[i]); + } + return layers; + }, + + setZIndex: function (zIndex) { + return this.invoke('setZIndex', zIndex); + }, + + getLayerId: function (layer) { + return L.stamp(layer); + } +}); + +L.layerGroup = function (layers) { + return new L.LayerGroup(layers); +}; + + +/* + * L.FeatureGroup extends L.LayerGroup by introducing mouse events and additional methods + * shared between a group of interactive layers (like vectors or markers). + */ + +L.FeatureGroup = L.LayerGroup.extend({ + includes: L.Mixin.Events, + + statics: { + EVENTS: 'click dblclick mouseover mouseout mousemove contextmenu popupopen popupclose' + }, + + addLayer: function (layer) { + if (this.hasLayer(layer)) { + return this; + } + + if ('on' in layer) { + layer.on(L.FeatureGroup.EVENTS, this._propagateEvent, this); + } + + L.LayerGroup.prototype.addLayer.call(this, layer); + + if (this._popupContent && layer.bindPopup) { + layer.bindPopup(this._popupContent, this._popupOptions); + } + + return this.fire('layeradd', {layer: layer}); + }, + + removeLayer: function (layer) { + if (!this.hasLayer(layer)) { + return this; + } + if (layer in this._layers) { + layer = this._layers[layer]; + } + + if ('off' in layer) { + layer.off(L.FeatureGroup.EVENTS, this._propagateEvent, this); + } + + L.LayerGroup.prototype.removeLayer.call(this, layer); + + if (this._popupContent) { + this.invoke('unbindPopup'); + } + + return this.fire('layerremove', {layer: layer}); + }, + + bindPopup: function (content, options) { + this._popupContent = content; + this._popupOptions = options; + return this.invoke('bindPopup', content, options); + }, + + openPopup: function (latlng) { + // open popup on the first layer + for (var id in this._layers) { + this._layers[id].openPopup(latlng); + break; + } + return this; + }, + + setStyle: function (style) { + return this.invoke('setStyle', style); + }, + + bringToFront: function () { + return this.invoke('bringToFront'); + }, + + bringToBack: function () { + return this.invoke('bringToBack'); + }, + + getBounds: function () { + var bounds = new L.LatLngBounds(); + + this.eachLayer(function (layer) { + bounds.extend(layer instanceof L.Marker ? layer.getLatLng() : layer.getBounds()); + }); + + return bounds; + }, + + _propagateEvent: function (e) { + e = L.extend({ + layer: e.target, + target: this + }, e); + this.fire(e.type, e); + } +}); + +L.featureGroup = function (layers) { + return new L.FeatureGroup(layers); +}; + + +/* + * L.Path is a base class for rendering vector paths on a map. Inherited by Polyline, Circle, etc. + */ + +L.Path = L.Class.extend({ + includes: [L.Mixin.Events], + + statics: { + // how much to extend the clip area around the map view + // (relative to its size, e.g. 0.5 is half the screen in each direction) + // set it so that SVG element doesn't exceed 1280px (vectors flicker on dragend if it is) + CLIP_PADDING: (function () { + var max = L.Browser.mobile ? 1280 : 2000, + target = (max / Math.max(window.outerWidth, window.outerHeight) - 1) / 2; + return Math.max(0, Math.min(0.5, target)); + })() + }, + + options: { + stroke: true, + color: '#0033ff', + dashArray: null, + lineCap: null, + lineJoin: null, + weight: 5, + opacity: 0.5, + + fill: false, + fillColor: null, //same as color by default + fillOpacity: 0.2, + + clickable: true + }, + + initialize: function (options) { + L.setOptions(this, options); + }, + + onAdd: function (map) { + this._map = map; + + if (!this._container) { + this._initElements(); + this._initEvents(); + } + + this.projectLatlngs(); + this._updatePath(); + + if (this._container) { + this._map._pathRoot.appendChild(this._container); + } + + this.fire('add'); + + map.on({ + 'viewreset': this.projectLatlngs, + 'moveend': this._updatePath + }, this); + }, + + addTo: function (map) { + map.addLayer(this); + return this; + }, + + onRemove: function (map) { + map._pathRoot.removeChild(this._container); + + // Need to fire remove event before we set _map to null as the event hooks might need the object + this.fire('remove'); + this._map = null; + + if (L.Browser.vml) { + this._container = null; + this._stroke = null; + this._fill = null; + } + + map.off({ + 'viewreset': this.projectLatlngs, + 'moveend': this._updatePath + }, this); + }, + + projectLatlngs: function () { + // do all projection stuff here + }, + + setStyle: function (style) { + L.setOptions(this, style); + + if (this._container) { + this._updateStyle(); + } + + return this; + }, + + redraw: function () { + if (this._map) { + this.projectLatlngs(); + this._updatePath(); + } + return this; + } +}); + +L.Map.include({ + _updatePathViewport: function () { + var p = L.Path.CLIP_PADDING, + size = this.getSize(), + panePos = L.DomUtil.getPosition(this._mapPane), + min = panePos.multiplyBy(-1)._subtract(size.multiplyBy(p)._round()), + max = min.add(size.multiplyBy(1 + p * 2)._round()); + + this._pathViewport = new L.Bounds(min, max); + } +}); + + +/* + * Extends L.Path with SVG-specific rendering code. + */ + +L.Path.SVG_NS = 'http://www.w3.org/2000/svg'; + +L.Browser.svg = !!(document.createElementNS && document.createElementNS(L.Path.SVG_NS, 'svg').createSVGRect); + +L.Path = L.Path.extend({ + statics: { + SVG: L.Browser.svg + }, + + bringToFront: function () { + var root = this._map._pathRoot, + path = this._container; + + if (path && root.lastChild !== path) { + root.appendChild(path); + } + return this; + }, + + bringToBack: function () { + var root = this._map._pathRoot, + path = this._container, + first = root.firstChild; + + if (path && first !== path) { + root.insertBefore(path, first); + } + return this; + }, + + getPathString: function () { + // form path string here + }, + + _createElement: function (name) { + return document.createElementNS(L.Path.SVG_NS, name); + }, + + _initElements: function () { + this._map._initPathRoot(); + this._initPath(); + this._initStyle(); + }, + + _initPath: function () { + this._container = this._createElement('g'); + + this._path = this._createElement('path'); + + if (this.options.className) { + L.DomUtil.addClass(this._path, this.options.className); + } + + this._container.appendChild(this._path); + }, + + _initStyle: function () { + if (this.options.stroke) { + this._path.setAttribute('stroke-linejoin', 'round'); + this._path.setAttribute('stroke-linecap', 'round'); + } + if (this.options.fill) { + this._path.setAttribute('fill-rule', 'evenodd'); + } + if (this.options.pointerEvents) { + this._path.setAttribute('pointer-events', this.options.pointerEvents); + } + if (!this.options.clickable && !this.options.pointerEvents) { + this._path.setAttribute('pointer-events', 'none'); + } + this._updateStyle(); + }, + + _updateStyle: function () { + if (this.options.stroke) { + this._path.setAttribute('stroke', this.options.color); + this._path.setAttribute('stroke-opacity', this.options.opacity); + this._path.setAttribute('stroke-width', this.options.weight); + if (this.options.dashArray) { + this._path.setAttribute('stroke-dasharray', this.options.dashArray); + } else { + this._path.removeAttribute('stroke-dasharray'); + } + if (this.options.lineCap) { + this._path.setAttribute('stroke-linecap', this.options.lineCap); + } + if (this.options.lineJoin) { + this._path.setAttribute('stroke-linejoin', this.options.lineJoin); + } + } else { + this._path.setAttribute('stroke', 'none'); + } + if (this.options.fill) { + this._path.setAttribute('fill', this.options.fillColor || this.options.color); + this._path.setAttribute('fill-opacity', this.options.fillOpacity); + } else { + this._path.setAttribute('fill', 'none'); + } + }, + + _updatePath: function () { + var str = this.getPathString(); + if (!str) { + // fix webkit empty string parsing bug + str = 'M0 0'; + } + this._path.setAttribute('d', str); + }, + + // TODO remove duplication with L.Map + _initEvents: function () { + if (this.options.clickable) { + if (L.Browser.svg || !L.Browser.vml) { + L.DomUtil.addClass(this._path, 'leaflet-clickable'); + } + + L.DomEvent.on(this._container, 'click', this._onMouseClick, this); + + var events = ['dblclick', 'mousedown', 'mouseover', + 'mouseout', 'mousemove', 'contextmenu']; + for (var i = 0; i < events.length; i++) { + L.DomEvent.on(this._container, events[i], this._fireMouseEvent, this); + } + } + }, + + _onMouseClick: function (e) { + if (this._map.dragging && this._map.dragging.moved()) { return; } + + this._fireMouseEvent(e); + }, + + _fireMouseEvent: function (e) { + if (!this._map || !this.hasEventListeners(e.type)) { return; } + + var map = this._map, + containerPoint = map.mouseEventToContainerPoint(e), + layerPoint = map.containerPointToLayerPoint(containerPoint), + latlng = map.layerPointToLatLng(layerPoint); + + this.fire(e.type, { + latlng: latlng, + layerPoint: layerPoint, + containerPoint: containerPoint, + originalEvent: e + }); + + if (e.type === 'contextmenu') { + L.DomEvent.preventDefault(e); + } + if (e.type !== 'mousemove') { + L.DomEvent.stopPropagation(e); + } + } +}); + +L.Map.include({ + _initPathRoot: function () { + if (!this._pathRoot) { + this._pathRoot = L.Path.prototype._createElement('svg'); + this._panes.overlayPane.appendChild(this._pathRoot); + + if (this.options.zoomAnimation && L.Browser.any3d) { + L.DomUtil.addClass(this._pathRoot, 'leaflet-zoom-animated'); + + this.on({ + 'zoomanim': this._animatePathZoom, + 'zoomend': this._endPathZoom + }); + } else { + L.DomUtil.addClass(this._pathRoot, 'leaflet-zoom-hide'); + } + + this.on('moveend', this._updateSvgViewport); + this._updateSvgViewport(); + } + }, + + _animatePathZoom: function (e) { + var scale = this.getZoomScale(e.zoom), + offset = this._getCenterOffset(e.center)._multiplyBy(-scale)._add(this._pathViewport.min); + + this._pathRoot.style[L.DomUtil.TRANSFORM] = + L.DomUtil.getTranslateString(offset) + ' scale(' + scale + ') '; + + this._pathZooming = true; + }, + + _endPathZoom: function () { + this._pathZooming = false; + }, + + _updateSvgViewport: function () { + + if (this._pathZooming) { + // Do not update SVGs while a zoom animation is going on otherwise the animation will break. + // When the zoom animation ends we will be updated again anyway + // This fixes the case where you do a momentum move and zoom while the move is still ongoing. + return; + } + + this._updatePathViewport(); + + var vp = this._pathViewport, + min = vp.min, + max = vp.max, + width = max.x - min.x, + height = max.y - min.y, + root = this._pathRoot, + pane = this._panes.overlayPane; + + // Hack to make flicker on drag end on mobile webkit less irritating + if (L.Browser.mobileWebkit) { + pane.removeChild(root); + } + + L.DomUtil.setPosition(root, min); + root.setAttribute('width', width); + root.setAttribute('height', height); + root.setAttribute('viewBox', [min.x, min.y, width, height].join(' ')); + + if (L.Browser.mobileWebkit) { + pane.appendChild(root); + } + } +}); + + +/* + * Popup extension to L.Path (polylines, polygons, circles), adding popup-related methods. + */ + +L.Path.include({ + + bindPopup: function (content, options) { + + if (content instanceof L.Popup) { + this._popup = content; + } else { + if (!this._popup || options) { + this._popup = new L.Popup(options, this); + } + this._popup.setContent(content); + } + + if (!this._popupHandlersAdded) { + this + .on('click', this._openPopup, this) + .on('remove', this.closePopup, this); + + this._popupHandlersAdded = true; + } + + return this; + }, + + unbindPopup: function () { + if (this._popup) { + this._popup = null; + this + .off('click', this._openPopup) + .off('remove', this.closePopup); + + this._popupHandlersAdded = false; + } + return this; + }, + + openPopup: function (latlng) { + + if (this._popup) { + // open the popup from one of the path's points if not specified + latlng = latlng || this._latlng || + this._latlngs[Math.floor(this._latlngs.length / 2)]; + + this._openPopup({latlng: latlng}); + } + + return this; + }, + + closePopup: function () { + if (this._popup) { + this._popup._close(); + } + return this; + }, + + _openPopup: function (e) { + this._popup.setLatLng(e.latlng); + this._map.openPopup(this._popup); + } +}); + + +/* + * Vector rendering for IE6-8 through VML. + * Thanks to Dmitry Baranovsky and his Raphael library for inspiration! + */ + +L.Browser.vml = !L.Browser.svg && (function () { + try { + var div = document.createElement('div'); + div.innerHTML = '<v:shape adj="1"/>'; + + var shape = div.firstChild; + shape.style.behavior = 'url(#default#VML)'; + + return shape && (typeof shape.adj === 'object'); + + } catch (e) { + return false; + } +}()); + +L.Path = L.Browser.svg || !L.Browser.vml ? L.Path : L.Path.extend({ + statics: { + VML: true, + CLIP_PADDING: 0.02 + }, + + _createElement: (function () { + try { + document.namespaces.add('lvml', 'urn:schemas-microsoft-com:vml'); + return function (name) { + return document.createElement('<lvml:' + name + ' class="lvml">'); + }; + } catch (e) { + return function (name) { + return document.createElement( + '<' + name + ' xmlns="urn:schemas-microsoft.com:vml" class="lvml">'); + }; + } + }()), + + _initPath: function () { + var container = this._container = this._createElement('shape'); + + L.DomUtil.addClass(container, 'leaflet-vml-shape' + + (this.options.className ? ' ' + this.options.className : '')); + + if (this.options.clickable) { + L.DomUtil.addClass(container, 'leaflet-clickable'); + } + + container.coordsize = '1 1'; + + this._path = this._createElement('path'); + container.appendChild(this._path); + + this._map._pathRoot.appendChild(container); + }, + + _initStyle: function () { + this._updateStyle(); + }, + + _updateStyle: function () { + var stroke = this._stroke, + fill = this._fill, + options = this.options, + container = this._container; + + container.stroked = options.stroke; + container.filled = options.fill; + + if (options.stroke) { + if (!stroke) { + stroke = this._stroke = this._createElement('stroke'); + stroke.endcap = 'round'; + container.appendChild(stroke); + } + stroke.weight = options.weight + 'px'; + stroke.color = options.color; + stroke.opacity = options.opacity; + + if (options.dashArray) { + stroke.dashStyle = L.Util.isArray(options.dashArray) ? + options.dashArray.join(' ') : + options.dashArray.replace(/( *, *)/g, ' '); + } else { + stroke.dashStyle = ''; + } + if (options.lineCap) { + stroke.endcap = options.lineCap.replace('butt', 'flat'); + } + if (options.lineJoin) { + stroke.joinstyle = options.lineJoin; + } + + } else if (stroke) { + container.removeChild(stroke); + this._stroke = null; + } + + if (options.fill) { + if (!fill) { + fill = this._fill = this._createElement('fill'); + container.appendChild(fill); + } + fill.color = options.fillColor || options.color; + fill.opacity = options.fillOpacity; + + } else if (fill) { + container.removeChild(fill); + this._fill = null; + } + }, + + _updatePath: function () { + var style = this._container.style; + + style.display = 'none'; + this._path.v = this.getPathString() + ' '; // the space fixes IE empty path string bug + style.display = ''; + } +}); + +L.Map.include(L.Browser.svg || !L.Browser.vml ? {} : { + _initPathRoot: function () { + if (this._pathRoot) { return; } + + var root = this._pathRoot = document.createElement('div'); + root.className = 'leaflet-vml-container'; + this._panes.overlayPane.appendChild(root); + + this.on('moveend', this._updatePathViewport); + this._updatePathViewport(); + } +}); + + +/* + * Vector rendering for all browsers that support canvas. + */ + +L.Browser.canvas = (function () { + return !!document.createElement('canvas').getContext; +}()); + +L.Path = (L.Path.SVG && !window.L_PREFER_CANVAS) || !L.Browser.canvas ? L.Path : L.Path.extend({ + statics: { + //CLIP_PADDING: 0.02, // not sure if there's a need to set it to a small value + CANVAS: true, + SVG: false + }, + + redraw: function () { + if (this._map) { + this.projectLatlngs(); + this._requestUpdate(); + } + return this; + }, + + setStyle: function (style) { + L.setOptions(this, style); + + if (this._map) { + this._updateStyle(); + this._requestUpdate(); + } + return this; + }, + + onRemove: function (map) { + map + .off('viewreset', this.projectLatlngs, this) + .off('moveend', this._updatePath, this); + + if (this.options.clickable) { + this._map.off('click', this._onClick, this); + this._map.off('mousemove', this._onMouseMove, this); + } + + this._requestUpdate(); + + this.fire('remove'); + this._map = null; + }, + + _requestUpdate: function () { + if (this._map && !L.Path._updateRequest) { + L.Path._updateRequest = L.Util.requestAnimFrame(this._fireMapMoveEnd, this._map); + } + }, + + _fireMapMoveEnd: function () { + L.Path._updateRequest = null; + this.fire('moveend'); + }, + + _initElements: function () { + this._map._initPathRoot(); + this._ctx = this._map._canvasCtx; + }, + + _updateStyle: function () { + var options = this.options; + + if (options.stroke) { + this._ctx.lineWidth = options.weight; + this._ctx.strokeStyle = options.color; + } + if (options.fill) { + this._ctx.fillStyle = options.fillColor || options.color; + } + + if (options.lineCap) { + this._ctx.lineCap = options.lineCap; + } + if (options.lineJoin) { + this._ctx.lineJoin = options.lineJoin; + } + }, + + _drawPath: function () { + var i, j, len, len2, point, drawMethod; + + this._ctx.beginPath(); + + for (i = 0, len = this._parts.length; i < len; i++) { + for (j = 0, len2 = this._parts[i].length; j < len2; j++) { + point = this._parts[i][j]; + drawMethod = (j === 0 ? 'move' : 'line') + 'To'; + + this._ctx[drawMethod](point.x, point.y); + } + // TODO refactor ugly hack + if (this instanceof L.Polygon) { + this._ctx.closePath(); + } + } + }, + + _checkIfEmpty: function () { + return !this._parts.length; + }, + + _updatePath: function () { + if (this._checkIfEmpty()) { return; } + + var ctx = this._ctx, + options = this.options; + + this._drawPath(); + ctx.save(); + this._updateStyle(); + + if (options.fill) { + ctx.globalAlpha = options.fillOpacity; + ctx.fill(options.fillRule || 'evenodd'); + } + + if (options.stroke) { + ctx.globalAlpha = options.opacity; + ctx.stroke(); + } + + ctx.restore(); + + // TODO optimization: 1 fill/stroke for all features with equal style instead of 1 for each feature + }, + + _initEvents: function () { + if (this.options.clickable) { + this._map.on('mousemove', this._onMouseMove, this); + this._map.on('click dblclick contextmenu', this._fireMouseEvent, this); + } + }, + + _fireMouseEvent: function (e) { + if (this._containsPoint(e.layerPoint)) { + this.fire(e.type, e); + } + }, + + _onMouseMove: function (e) { + if (!this._map || this._map._animatingZoom) { return; } + + // TODO don't do on each move + if (this._containsPoint(e.layerPoint)) { + this._ctx.canvas.style.cursor = 'pointer'; + this._mouseInside = true; + this.fire('mouseover', e); + + } else if (this._mouseInside) { + this._ctx.canvas.style.cursor = ''; + this._mouseInside = false; + this.fire('mouseout', e); + } + } +}); + +L.Map.include((L.Path.SVG && !window.L_PREFER_CANVAS) || !L.Browser.canvas ? {} : { + _initPathRoot: function () { + var root = this._pathRoot, + ctx; + + if (!root) { + root = this._pathRoot = document.createElement('canvas'); + root.style.position = 'absolute'; + ctx = this._canvasCtx = root.getContext('2d'); + + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + + this._panes.overlayPane.appendChild(root); + + if (this.options.zoomAnimation) { + this._pathRoot.className = 'leaflet-zoom-animated'; + this.on('zoomanim', this._animatePathZoom); + this.on('zoomend', this._endPathZoom); + } + this.on('moveend', this._updateCanvasViewport); + this._updateCanvasViewport(); + } + }, + + _updateCanvasViewport: function () { + // don't redraw while zooming. See _updateSvgViewport for more details + if (this._pathZooming) { return; } + this._updatePathViewport(); + + var vp = this._pathViewport, + min = vp.min, + size = vp.max.subtract(min), + root = this._pathRoot; + + //TODO check if this works properly on mobile webkit + L.DomUtil.setPosition(root, min); + root.width = size.x; + root.height = size.y; + root.getContext('2d').translate(-min.x, -min.y); + } +}); + + +/* + * L.LineUtil contains different utility functions for line segments + * and polylines (clipping, simplification, distances, etc.) + */ + +/*jshint bitwise:false */ // allow bitwise operations for this file + +L.LineUtil = { + + // Simplify polyline with vertex reduction and Douglas-Peucker simplification. + // Improves rendering performance dramatically by lessening the number of points to draw. + + simplify: function (/*Point[]*/ points, /*Number*/ tolerance) { + if (!tolerance || !points.length) { + return points.slice(); + } + + var sqTolerance = tolerance * tolerance; + + // stage 1: vertex reduction + points = this._reducePoints(points, sqTolerance); + + // stage 2: Douglas-Peucker simplification + points = this._simplifyDP(points, sqTolerance); + + return points; + }, + + // distance from a point to a segment between two points + pointToSegmentDistance: function (/*Point*/ p, /*Point*/ p1, /*Point*/ p2) { + return Math.sqrt(this._sqClosestPointOnSegment(p, p1, p2, true)); + }, + + closestPointOnSegment: function (/*Point*/ p, /*Point*/ p1, /*Point*/ p2) { + return this._sqClosestPointOnSegment(p, p1, p2); + }, + + // Douglas-Peucker simplification, see http://en.wikipedia.org/wiki/Douglas-Peucker_algorithm + _simplifyDP: function (points, sqTolerance) { + + var len = points.length, + ArrayConstructor = typeof Uint8Array !== undefined + '' ? Uint8Array : Array, + markers = new ArrayConstructor(len); + + markers[0] = markers[len - 1] = 1; + + this._simplifyDPStep(points, markers, sqTolerance, 0, len - 1); + + var i, + newPoints = []; + + for (i = 0; i < len; i++) { + if (markers[i]) { + newPoints.push(points[i]); + } + } + + return newPoints; + }, + + _simplifyDPStep: function (points, markers, sqTolerance, first, last) { + + var maxSqDist = 0, + index, i, sqDist; + + for (i = first + 1; i <= last - 1; i++) { + sqDist = this._sqClosestPointOnSegment(points[i], points[first], points[last], true); + + if (sqDist > maxSqDist) { + index = i; + maxSqDist = sqDist; + } + } + + if (maxSqDist > sqTolerance) { + markers[index] = 1; + + this._simplifyDPStep(points, markers, sqTolerance, first, index); + this._simplifyDPStep(points, markers, sqTolerance, index, last); + } + }, + + // reduce points that are too close to each other to a single point + _reducePoints: function (points, sqTolerance) { + var reducedPoints = [points[0]]; + + for (var i = 1, prev = 0, len = points.length; i < len; i++) { + if (this._sqDist(points[i], points[prev]) > sqTolerance) { + reducedPoints.push(points[i]); + prev = i; + } + } + if (prev < len - 1) { + reducedPoints.push(points[len - 1]); + } + return reducedPoints; + }, + + // Cohen-Sutherland line clipping algorithm. + // Used to avoid rendering parts of a polyline that are not currently visible. + + clipSegment: function (a, b, bounds, useLastCode) { + var codeA = useLastCode ? this._lastCode : this._getBitCode(a, bounds), + codeB = this._getBitCode(b, bounds), + + codeOut, p, newCode; + + // save 2nd code to avoid calculating it on the next segment + this._lastCode = codeB; + + while (true) { + // if a,b is inside the clip window (trivial accept) + if (!(codeA | codeB)) { + return [a, b]; + // if a,b is outside the clip window (trivial reject) + } else if (codeA & codeB) { + return false; + // other cases + } else { + codeOut = codeA || codeB; + p = this._getEdgeIntersection(a, b, codeOut, bounds); + newCode = this._getBitCode(p, bounds); + + if (codeOut === codeA) { + a = p; + codeA = newCode; + } else { + b = p; + codeB = newCode; + } + } + } + }, + + _getEdgeIntersection: function (a, b, code, bounds) { + var dx = b.x - a.x, + dy = b.y - a.y, + min = bounds.min, + max = bounds.max; + + if (code & 8) { // top + return new L.Point(a.x + dx * (max.y - a.y) / dy, max.y); + } else if (code & 4) { // bottom + return new L.Point(a.x + dx * (min.y - a.y) / dy, min.y); + } else if (code & 2) { // right + return new L.Point(max.x, a.y + dy * (max.x - a.x) / dx); + } else if (code & 1) { // left + return new L.Point(min.x, a.y + dy * (min.x - a.x) / dx); + } + }, + + _getBitCode: function (/*Point*/ p, bounds) { + var code = 0; + + if (p.x < bounds.min.x) { // left + code |= 1; + } else if (p.x > bounds.max.x) { // right + code |= 2; + } + if (p.y < bounds.min.y) { // bottom + code |= 4; + } else if (p.y > bounds.max.y) { // top + code |= 8; + } + + return code; + }, + + // square distance (to avoid unnecessary Math.sqrt calls) + _sqDist: function (p1, p2) { + var dx = p2.x - p1.x, + dy = p2.y - p1.y; + return dx * dx + dy * dy; + }, + + // return closest point on segment or distance to that point + _sqClosestPointOnSegment: function (p, p1, p2, sqDist) { + var x = p1.x, + y = p1.y, + dx = p2.x - x, + dy = p2.y - y, + dot = dx * dx + dy * dy, + t; + + if (dot > 0) { + t = ((p.x - x) * dx + (p.y - y) * dy) / dot; + + if (t > 1) { + x = p2.x; + y = p2.y; + } else if (t > 0) { + x += dx * t; + y += dy * t; + } + } + + dx = p.x - x; + dy = p.y - y; + + return sqDist ? dx * dx + dy * dy : new L.Point(x, y); + } +}; + + +/* + * L.Polyline is used to display polylines on a map. + */ + +L.Polyline = L.Path.extend({ + initialize: function (latlngs, options) { + L.Path.prototype.initialize.call(this, options); + + this._latlngs = this._convertLatLngs(latlngs); + }, + + options: { + // how much to simplify the polyline on each zoom level + // more = better performance and smoother look, less = more accurate + smoothFactor: 1.0, + noClip: false + }, + + projectLatlngs: function () { + this._originalPoints = []; + + for (var i = 0, len = this._latlngs.length; i < len; i++) { + this._originalPoints[i] = this._map.latLngToLayerPoint(this._latlngs[i]); + } + }, + + getPathString: function () { + for (var i = 0, len = this._parts.length, str = ''; i < len; i++) { + str += this._getPathPartStr(this._parts[i]); + } + return str; + }, + + getLatLngs: function () { + return this._latlngs; + }, + + setLatLngs: function (latlngs) { + this._latlngs = this._convertLatLngs(latlngs); + return this.redraw(); + }, + + addLatLng: function (latlng) { + this._latlngs.push(L.latLng(latlng)); + return this.redraw(); + }, + + spliceLatLngs: function () { // (Number index, Number howMany) + var removed = [].splice.apply(this._latlngs, arguments); + this._convertLatLngs(this._latlngs, true); + this.redraw(); + return removed; + }, + + closestLayerPoint: function (p) { + var minDistance = Infinity, parts = this._parts, p1, p2, minPoint = null; + + for (var j = 0, jLen = parts.length; j < jLen; j++) { + var points = parts[j]; + for (var i = 1, len = points.length; i < len; i++) { + p1 = points[i - 1]; + p2 = points[i]; + var sqDist = L.LineUtil._sqClosestPointOnSegment(p, p1, p2, true); + if (sqDist < minDistance) { + minDistance = sqDist; + minPoint = L.LineUtil._sqClosestPointOnSegment(p, p1, p2); + } + } + } + if (minPoint) { + minPoint.distance = Math.sqrt(minDistance); + } + return minPoint; + }, + + getBounds: function () { + return new L.LatLngBounds(this.getLatLngs()); + }, + + _convertLatLngs: function (latlngs, overwrite) { + var i, len, target = overwrite ? latlngs : []; + + for (i = 0, len = latlngs.length; i < len; i++) { + if (L.Util.isArray(latlngs[i]) && typeof latlngs[i][0] !== 'number') { + return; + } + target[i] = L.latLng(latlngs[i]); + } + return target; + }, + + _initEvents: function () { + L.Path.prototype._initEvents.call(this); + }, + + _getPathPartStr: function (points) { + var round = L.Path.VML; + + for (var j = 0, len2 = points.length, str = '', p; j < len2; j++) { + p = points[j]; + if (round) { + p._round(); + } + str += (j ? 'L' : 'M') + p.x + ' ' + p.y; + } + return str; + }, + + _clipPoints: function () { + var points = this._originalPoints, + len = points.length, + i, k, segment; + + if (this.options.noClip) { + this._parts = [points]; + return; + } + + this._parts = []; + + var parts = this._parts, + vp = this._map._pathViewport, + lu = L.LineUtil; + + for (i = 0, k = 0; i < len - 1; i++) { + segment = lu.clipSegment(points[i], points[i + 1], vp, i); + if (!segment) { + continue; + } + + parts[k] = parts[k] || []; + parts[k].push(segment[0]); + + // if segment goes out of screen, or it's the last one, it's the end of the line part + if ((segment[1] !== points[i + 1]) || (i === len - 2)) { + parts[k].push(segment[1]); + k++; + } + } + }, + + // simplify each clipped part of the polyline + _simplifyPoints: function () { + var parts = this._parts, + lu = L.LineUtil; + + for (var i = 0, len = parts.length; i < len; i++) { + parts[i] = lu.simplify(parts[i], this.options.smoothFactor); + } + }, + + _updatePath: function () { + if (!this._map) { return; } + + this._clipPoints(); + this._simplifyPoints(); + + L.Path.prototype._updatePath.call(this); + } +}); + +L.polyline = function (latlngs, options) { + return new L.Polyline(latlngs, options); +}; + + +/* + * L.PolyUtil contains utility functions for polygons (clipping, etc.). + */ + +/*jshint bitwise:false */ // allow bitwise operations here + +L.PolyUtil = {}; + +/* + * Sutherland-Hodgeman polygon clipping algorithm. + * Used to avoid rendering parts of a polygon that are not currently visible. + */ +L.PolyUtil.clipPolygon = function (points, bounds) { + var clippedPoints, + edges = [1, 4, 2, 8], + i, j, k, + a, b, + len, edge, p, + lu = L.LineUtil; + + for (i = 0, len = points.length; i < len; i++) { + points[i]._code = lu._getBitCode(points[i], bounds); + } + + // for each edge (left, bottom, right, top) + for (k = 0; k < 4; k++) { + edge = edges[k]; + clippedPoints = []; + + for (i = 0, len = points.length, j = len - 1; i < len; j = i++) { + a = points[i]; + b = points[j]; + + // if a is inside the clip window + if (!(a._code & edge)) { + // if b is outside the clip window (a->b goes out of screen) + if (b._code & edge) { + p = lu._getEdgeIntersection(b, a, edge, bounds); + p._code = lu._getBitCode(p, bounds); + clippedPoints.push(p); + } + clippedPoints.push(a); + + // else if b is inside the clip window (a->b enters the screen) + } else if (!(b._code & edge)) { + p = lu._getEdgeIntersection(b, a, edge, bounds); + p._code = lu._getBitCode(p, bounds); + clippedPoints.push(p); + } + } + points = clippedPoints; + } + + return points; +}; + + +/* + * L.Polygon is used to display polygons on a map. + */ + +L.Polygon = L.Polyline.extend({ + options: { + fill: true + }, + + initialize: function (latlngs, options) { + L.Polyline.prototype.initialize.call(this, latlngs, options); + this._initWithHoles(latlngs); + }, + + _initWithHoles: function (latlngs) { + var i, len, hole; + if (latlngs && L.Util.isArray(latlngs[0]) && (typeof latlngs[0][0] !== 'number')) { + this._latlngs = this._convertLatLngs(latlngs[0]); + this._holes = latlngs.slice(1); + + for (i = 0, len = this._holes.length; i < len; i++) { + hole = this._holes[i] = this._convertLatLngs(this._holes[i]); + if (hole[0].equals(hole[hole.length - 1])) { + hole.pop(); + } + } + } + + // filter out last point if its equal to the first one + latlngs = this._latlngs; + + if (latlngs.length >= 2 && latlngs[0].equals(latlngs[latlngs.length - 1])) { + latlngs.pop(); + } + }, + + projectLatlngs: function () { + L.Polyline.prototype.projectLatlngs.call(this); + + // project polygon holes points + // TODO move this logic to Polyline to get rid of duplication + this._holePoints = []; + + if (!this._holes) { return; } + + var i, j, len, len2; + + for (i = 0, len = this._holes.length; i < len; i++) { + this._holePoints[i] = []; + + for (j = 0, len2 = this._holes[i].length; j < len2; j++) { + this._holePoints[i][j] = this._map.latLngToLayerPoint(this._holes[i][j]); + } + } + }, + + setLatLngs: function (latlngs) { + if (latlngs && L.Util.isArray(latlngs[0]) && (typeof latlngs[0][0] !== 'number')) { + this._initWithHoles(latlngs); + return this.redraw(); + } else { + return L.Polyline.prototype.setLatLngs.call(this, latlngs); + } + }, + + _clipPoints: function () { + var points = this._originalPoints, + newParts = []; + + this._parts = [points].concat(this._holePoints); + + if (this.options.noClip) { return; } + + for (var i = 0, len = this._parts.length; i < len; i++) { + var clipped = L.PolyUtil.clipPolygon(this._parts[i], this._map._pathViewport); + if (clipped.length) { + newParts.push(clipped); + } + } + + this._parts = newParts; + }, + + _getPathPartStr: function (points) { + var str = L.Polyline.prototype._getPathPartStr.call(this, points); + return str + (L.Browser.svg ? 'z' : 'x'); + } +}); + +L.polygon = function (latlngs, options) { + return new L.Polygon(latlngs, options); +}; + + +/* + * Contains L.MultiPolyline and L.MultiPolygon layers. + */ + +(function () { + function createMulti(Klass) { + + return L.FeatureGroup.extend({ + + initialize: function (latlngs, options) { + this._layers = {}; + this._options = options; + this.setLatLngs(latlngs); + }, + + setLatLngs: function (latlngs) { + var i = 0, + len = latlngs.length; + + this.eachLayer(function (layer) { + if (i < len) { + layer.setLatLngs(latlngs[i++]); + } else { + this.removeLayer(layer); + } + }, this); + + while (i < len) { + this.addLayer(new Klass(latlngs[i++], this._options)); + } + + return this; + }, + + getLatLngs: function () { + var latlngs = []; + + this.eachLayer(function (layer) { + latlngs.push(layer.getLatLngs()); + }); + + return latlngs; + } + }); + } + + L.MultiPolyline = createMulti(L.Polyline); + L.MultiPolygon = createMulti(L.Polygon); + + L.multiPolyline = function (latlngs, options) { + return new L.MultiPolyline(latlngs, options); + }; + + L.multiPolygon = function (latlngs, options) { + return new L.MultiPolygon(latlngs, options); + }; +}()); + + +/* + * L.Rectangle extends Polygon and creates a rectangle when passed a LatLngBounds object. + */ + +L.Rectangle = L.Polygon.extend({ + initialize: function (latLngBounds, options) { + L.Polygon.prototype.initialize.call(this, this._boundsToLatLngs(latLngBounds), options); + }, + + setBounds: function (latLngBounds) { + this.setLatLngs(this._boundsToLatLngs(latLngBounds)); + }, + + _boundsToLatLngs: function (latLngBounds) { + latLngBounds = L.latLngBounds(latLngBounds); + return [ + latLngBounds.getSouthWest(), + latLngBounds.getNorthWest(), + latLngBounds.getNorthEast(), + latLngBounds.getSouthEast() + ]; + } +}); + +L.rectangle = function (latLngBounds, options) { + return new L.Rectangle(latLngBounds, options); +}; + + +/* + * L.Circle is a circle overlay (with a certain radius in meters). + */ + +L.Circle = L.Path.extend({ + initialize: function (latlng, radius, options) { + L.Path.prototype.initialize.call(this, options); + + this._latlng = L.latLng(latlng); + this._mRadius = radius; + }, + + options: { + fill: true + }, + + setLatLng: function (latlng) { + this._latlng = L.latLng(latlng); + return this.redraw(); + }, + + setRadius: function (radius) { + this._mRadius = radius; + return this.redraw(); + }, + + projectLatlngs: function () { + var lngRadius = this._getLngRadius(), + latlng = this._latlng, + pointLeft = this._map.latLngToLayerPoint([latlng.lat, latlng.lng - lngRadius]); + + this._point = this._map.latLngToLayerPoint(latlng); + this._radius = Math.max(this._point.x - pointLeft.x, 1); + }, + + getBounds: function () { + var lngRadius = this._getLngRadius(), + latRadius = (this._mRadius / 40075017) * 360, + latlng = this._latlng; + + return new L.LatLngBounds( + [latlng.lat - latRadius, latlng.lng - lngRadius], + [latlng.lat + latRadius, latlng.lng + lngRadius]); + }, + + getLatLng: function () { + return this._latlng; + }, + + getPathString: function () { + var p = this._point, + r = this._radius; + + if (this._checkIfEmpty()) { + return ''; + } + + if (L.Browser.svg) { + return 'M' + p.x + ',' + (p.y - r) + + 'A' + r + ',' + r + ',0,1,1,' + + (p.x - 0.1) + ',' + (p.y - r) + ' z'; + } else { + p._round(); + r = Math.round(r); + return 'AL ' + p.x + ',' + p.y + ' ' + r + ',' + r + ' 0,' + (65535 * 360); + } + }, + + getRadius: function () { + return this._mRadius; + }, + + // TODO Earth hardcoded, move into projection code! + + _getLatRadius: function () { + return (this._mRadius / 40075017) * 360; + }, + + _getLngRadius: function () { + return this._getLatRadius() / Math.cos(L.LatLng.DEG_TO_RAD * this._latlng.lat); + }, + + _checkIfEmpty: function () { + if (!this._map) { + return false; + } + var vp = this._map._pathViewport, + r = this._radius, + p = this._point; + + return p.x - r > vp.max.x || p.y - r > vp.max.y || + p.x + r < vp.min.x || p.y + r < vp.min.y; + } +}); + +L.circle = function (latlng, radius, options) { + return new L.Circle(latlng, radius, options); +}; + + +/* + * L.CircleMarker is a circle overlay with a permanent pixel radius. + */ + +L.CircleMarker = L.Circle.extend({ + options: { + radius: 10, + weight: 2 + }, + + initialize: function (latlng, options) { + L.Circle.prototype.initialize.call(this, latlng, null, options); + this._radius = this.options.radius; + }, + + projectLatlngs: function () { + this._point = this._map.latLngToLayerPoint(this._latlng); + }, + + _updateStyle : function () { + L.Circle.prototype._updateStyle.call(this); + this.setRadius(this.options.radius); + }, + + setLatLng: function (latlng) { + L.Circle.prototype.setLatLng.call(this, latlng); + if (this._popup && this._popup._isOpen) { + this._popup.setLatLng(latlng); + } + return this; + }, + + setRadius: function (radius) { + this.options.radius = this._radius = radius; + return this.redraw(); + }, + + getRadius: function () { + return this._radius; + } +}); + +L.circleMarker = function (latlng, options) { + return new L.CircleMarker(latlng, options); +}; + + +/* + * Extends L.Polyline to be able to manually detect clicks on Canvas-rendered polylines. + */ + +L.Polyline.include(!L.Path.CANVAS ? {} : { + _containsPoint: function (p, closed) { + var i, j, k, len, len2, dist, part, + w = this.options.weight / 2; + + if (L.Browser.touch) { + w += 10; // polyline click tolerance on touch devices + } + + for (i = 0, len = this._parts.length; i < len; i++) { + part = this._parts[i]; + for (j = 0, len2 = part.length, k = len2 - 1; j < len2; k = j++) { + if (!closed && (j === 0)) { + continue; + } + + dist = L.LineUtil.pointToSegmentDistance(p, part[k], part[j]); + + if (dist <= w) { + return true; + } + } + } + return false; + } +}); + + +/* + * Extends L.Polygon to be able to manually detect clicks on Canvas-rendered polygons. + */ + +L.Polygon.include(!L.Path.CANVAS ? {} : { + _containsPoint: function (p) { + var inside = false, + part, p1, p2, + i, j, k, + len, len2; + + // TODO optimization: check if within bounds first + + if (L.Polyline.prototype._containsPoint.call(this, p, true)) { + // click on polygon border + return true; + } + + // ray casting algorithm for detecting if point is in polygon + + for (i = 0, len = this._parts.length; i < len; i++) { + part = this._parts[i]; + + for (j = 0, len2 = part.length, k = len2 - 1; j < len2; k = j++) { + p1 = part[j]; + p2 = part[k]; + + if (((p1.y > p.y) !== (p2.y > p.y)) && + (p.x < (p2.x - p1.x) * (p.y - p1.y) / (p2.y - p1.y) + p1.x)) { + inside = !inside; + } + } + } + + return inside; + } +}); + + +/* + * Extends L.Circle with Canvas-specific code. + */ + +L.Circle.include(!L.Path.CANVAS ? {} : { + _drawPath: function () { + var p = this._point; + this._ctx.beginPath(); + this._ctx.arc(p.x, p.y, this._radius, 0, Math.PI * 2, false); + }, + + _containsPoint: function (p) { + var center = this._point, + w2 = this.options.stroke ? this.options.weight / 2 : 0; + + return (p.distanceTo(center) <= this._radius + w2); + } +}); + + +/* + * CircleMarker canvas specific drawing parts. + */ + +L.CircleMarker.include(!L.Path.CANVAS ? {} : { + _updateStyle: function () { + L.Path.prototype._updateStyle.call(this); + } +}); + + +/* + * L.GeoJSON turns any GeoJSON data into a Leaflet layer. + */ + +L.GeoJSON = L.FeatureGroup.extend({ + + initialize: function (geojson, options) { + L.setOptions(this, options); + + this._layers = {}; + + if (geojson) { + this.addData(geojson); + } + }, + + addData: function (geojson) { + var features = L.Util.isArray(geojson) ? geojson : geojson.features, + i, len, feature; + + if (features) { + for (i = 0, len = features.length; i < len; i++) { + // Only add this if geometry or geometries are set and not null + feature = features[i]; + if (feature.geometries || feature.geometry || feature.features || feature.coordinates) { + this.addData(features[i]); + } + } + return this; + } + + var options = this.options; + + if (options.filter && !options.filter(geojson)) { return; } + + var layer = L.GeoJSON.geometryToLayer(geojson, options.pointToLayer, options.coordsToLatLng, options); + layer.feature = L.GeoJSON.asFeature(geojson); + + layer.defaultOptions = layer.options; + this.resetStyle(layer); + + if (options.onEachFeature) { + options.onEachFeature(geojson, layer); + } + + return this.addLayer(layer); + }, + + resetStyle: function (layer) { + var style = this.options.style; + if (style) { + // reset any custom styles + L.Util.extend(layer.options, layer.defaultOptions); + + this._setLayerStyle(layer, style); + } + }, + + setStyle: function (style) { + this.eachLayer(function (layer) { + this._setLayerStyle(layer, style); + }, this); + }, + + _setLayerStyle: function (layer, style) { + if (typeof style === 'function') { + style = style(layer.feature); + } + if (layer.setStyle) { + layer.setStyle(style); + } + } +}); + +L.extend(L.GeoJSON, { + geometryToLayer: function (geojson, pointToLayer, coordsToLatLng, vectorOptions) { + var geometry = geojson.type === 'Feature' ? geojson.geometry : geojson, + coords = geometry.coordinates, + layers = [], + latlng, latlngs, i, len; + + coordsToLatLng = coordsToLatLng || this.coordsToLatLng; + + switch (geometry.type) { + case 'Point': + latlng = coordsToLatLng(coords); + return pointToLayer ? pointToLayer(geojson, latlng) : new L.Marker(latlng); + + case 'MultiPoint': + for (i = 0, len = coords.length; i < len; i++) { + latlng = coordsToLatLng(coords[i]); + layers.push(pointToLayer ? pointToLayer(geojson, latlng) : new L.Marker(latlng)); + } + return new L.FeatureGroup(layers); + + case 'LineString': + latlngs = this.coordsToLatLngs(coords, 0, coordsToLatLng); + return new L.Polyline(latlngs, vectorOptions); + + case 'Polygon': + if (coords.length === 2 && !coords[1].length) { + throw new Error('Invalid GeoJSON object.'); + } + latlngs = this.coordsToLatLngs(coords, 1, coordsToLatLng); + return new L.Polygon(latlngs, vectorOptions); + + case 'MultiLineString': + latlngs = this.coordsToLatLngs(coords, 1, coordsToLatLng); + return new L.MultiPolyline(latlngs, vectorOptions); + + case 'MultiPolygon': + latlngs = this.coordsToLatLngs(coords, 2, coordsToLatLng); + return new L.MultiPolygon(latlngs, vectorOptions); + + case 'GeometryCollection': + for (i = 0, len = geometry.geometries.length; i < len; i++) { + + layers.push(this.geometryToLayer({ + geometry: geometry.geometries[i], + type: 'Feature', + properties: geojson.properties + }, pointToLayer, coordsToLatLng, vectorOptions)); + } + return new L.FeatureGroup(layers); + + default: + throw new Error('Invalid GeoJSON object.'); + } + }, + + coordsToLatLng: function (coords) { // (Array[, Boolean]) -> LatLng + return new L.LatLng(coords[1], coords[0], coords[2]); + }, + + coordsToLatLngs: function (coords, levelsDeep, coordsToLatLng) { // (Array[, Number, Function]) -> Array + var latlng, i, len, + latlngs = []; + + for (i = 0, len = coords.length; i < len; i++) { + latlng = levelsDeep ? + this.coordsToLatLngs(coords[i], levelsDeep - 1, coordsToLatLng) : + (coordsToLatLng || this.coordsToLatLng)(coords[i]); + + latlngs.push(latlng); + } + + return latlngs; + }, + + latLngToCoords: function (latlng) { + var coords = [latlng.lng, latlng.lat]; + + if (latlng.alt !== undefined) { + coords.push(latlng.alt); + } + return coords; + }, + + latLngsToCoords: function (latLngs) { + var coords = []; + + for (var i = 0, len = latLngs.length; i < len; i++) { + coords.push(L.GeoJSON.latLngToCoords(latLngs[i])); + } + + return coords; + }, + + getFeature: function (layer, newGeometry) { + return layer.feature ? L.extend({}, layer.feature, {geometry: newGeometry}) : L.GeoJSON.asFeature(newGeometry); + }, + + asFeature: function (geoJSON) { + if (geoJSON.type === 'Feature') { + return geoJSON; + } + + return { + type: 'Feature', + properties: {}, + geometry: geoJSON + }; + } +}); + +var PointToGeoJSON = { + toGeoJSON: function () { + return L.GeoJSON.getFeature(this, { + type: 'Point', + coordinates: L.GeoJSON.latLngToCoords(this.getLatLng()) + }); + } +}; + +L.Marker.include(PointToGeoJSON); +L.Circle.include(PointToGeoJSON); +L.CircleMarker.include(PointToGeoJSON); + +L.Polyline.include({ + toGeoJSON: function () { + return L.GeoJSON.getFeature(this, { + type: 'LineString', + coordinates: L.GeoJSON.latLngsToCoords(this.getLatLngs()) + }); + } +}); + +L.Polygon.include({ + toGeoJSON: function () { + var coords = [L.GeoJSON.latLngsToCoords(this.getLatLngs())], + i, len, hole; + + coords[0].push(coords[0][0]); + + if (this._holes) { + for (i = 0, len = this._holes.length; i < len; i++) { + hole = L.GeoJSON.latLngsToCoords(this._holes[i]); + hole.push(hole[0]); + coords.push(hole); + } + } + + return L.GeoJSON.getFeature(this, { + type: 'Polygon', + coordinates: coords + }); + } +}); + +(function () { + function multiToGeoJSON(type) { + return function () { + var coords = []; + + this.eachLayer(function (layer) { + coords.push(layer.toGeoJSON().geometry.coordinates); + }); + + return L.GeoJSON.getFeature(this, { + type: type, + coordinates: coords + }); + }; + } + + L.MultiPolyline.include({toGeoJSON: multiToGeoJSON('MultiLineString')}); + L.MultiPolygon.include({toGeoJSON: multiToGeoJSON('MultiPolygon')}); + + L.LayerGroup.include({ + toGeoJSON: function () { + + var geometry = this.feature && this.feature.geometry, + jsons = [], + json; + + if (geometry && geometry.type === 'MultiPoint') { + return multiToGeoJSON('MultiPoint').call(this); + } + + var isGeometryCollection = geometry && geometry.type === 'GeometryCollection'; + + this.eachLayer(function (layer) { + if (layer.toGeoJSON) { + json = layer.toGeoJSON(); + jsons.push(isGeometryCollection ? json.geometry : L.GeoJSON.asFeature(json)); + } + }); + + if (isGeometryCollection) { + return L.GeoJSON.getFeature(this, { + geometries: jsons, + type: 'GeometryCollection' + }); + } + + return { + type: 'FeatureCollection', + features: jsons + }; + } + }); +}()); + +L.geoJson = function (geojson, options) { + return new L.GeoJSON(geojson, options); +}; + + +/* + * L.DomEvent contains functions for working with DOM events. + */ + +L.DomEvent = { + /* inspired by John Resig, Dean Edwards and YUI addEvent implementations */ + addListener: function (obj, type, fn, context) { // (HTMLElement, String, Function[, Object]) + + var id = L.stamp(fn), + key = '_leaflet_' + type + id, + handler, originalHandler, newType; + + if (obj[key]) { return this; } + + handler = function (e) { + return fn.call(context || obj, e || L.DomEvent._getEvent()); + }; + + if (L.Browser.pointer && type.indexOf('touch') === 0) { + return this.addPointerListener(obj, type, handler, id); + } + if (L.Browser.touch && (type === 'dblclick') && this.addDoubleTapListener) { + this.addDoubleTapListener(obj, handler, id); + } + + if ('addEventListener' in obj) { + + if (type === 'mousewheel') { + obj.addEventListener('DOMMouseScroll', handler, false); + obj.addEventListener(type, handler, false); + + } else if ((type === 'mouseenter') || (type === 'mouseleave')) { + + originalHandler = handler; + newType = (type === 'mouseenter' ? 'mouseover' : 'mouseout'); + + handler = function (e) { + if (!L.DomEvent._checkMouse(obj, e)) { return; } + return originalHandler(e); + }; + + obj.addEventListener(newType, handler, false); + + } else if (type === 'click' && L.Browser.android) { + originalHandler = handler; + handler = function (e) { + return L.DomEvent._filterClick(e, originalHandler); + }; + + obj.addEventListener(type, handler, false); + } else { + obj.addEventListener(type, handler, false); + } + + } else if ('attachEvent' in obj) { + obj.attachEvent('on' + type, handler); + } + + obj[key] = handler; + + return this; + }, + + removeListener: function (obj, type, fn) { // (HTMLElement, String, Function) + + var id = L.stamp(fn), + key = '_leaflet_' + type + id, + handler = obj[key]; + + if (!handler) { return this; } + + if (L.Browser.pointer && type.indexOf('touch') === 0) { + this.removePointerListener(obj, type, id); + } else if (L.Browser.touch && (type === 'dblclick') && this.removeDoubleTapListener) { + this.removeDoubleTapListener(obj, id); + + } else if ('removeEventListener' in obj) { + + if (type === 'mousewheel') { + obj.removeEventListener('DOMMouseScroll', handler, false); + obj.removeEventListener(type, handler, false); + + } else if ((type === 'mouseenter') || (type === 'mouseleave')) { + obj.removeEventListener((type === 'mouseenter' ? 'mouseover' : 'mouseout'), handler, false); + } else { + obj.removeEventListener(type, handler, false); + } + } else if ('detachEvent' in obj) { + obj.detachEvent('on' + type, handler); + } + + obj[key] = null; + + return this; + }, + + stopPropagation: function (e) { + + if (e.stopPropagation) { + e.stopPropagation(); + } else { + e.cancelBubble = true; + } + L.DomEvent._skipped(e); + + return this; + }, + + disableScrollPropagation: function (el) { + var stop = L.DomEvent.stopPropagation; + + return L.DomEvent + .on(el, 'mousewheel', stop) + .on(el, 'MozMousePixelScroll', stop); + }, + + disableClickPropagation: function (el) { + var stop = L.DomEvent.stopPropagation; + + for (var i = L.Draggable.START.length - 1; i >= 0; i--) { + L.DomEvent.on(el, L.Draggable.START[i], stop); + } + + return L.DomEvent + .on(el, 'click', L.DomEvent._fakeStop) + .on(el, 'dblclick', stop); + }, + + preventDefault: function (e) { + + if (e.preventDefault) { + e.preventDefault(); + } else { + e.returnValue = false; + } + return this; + }, + + stop: function (e) { + return L.DomEvent + .preventDefault(e) + .stopPropagation(e); + }, + + getMousePosition: function (e, container) { + if (!container) { + return new L.Point(e.clientX, e.clientY); + } + + var rect = container.getBoundingClientRect(); + + return new L.Point( + e.clientX - rect.left - container.clientLeft, + e.clientY - rect.top - container.clientTop); + }, + + getWheelDelta: function (e) { + + var delta = 0; + + if (e.wheelDelta) { + delta = e.wheelDelta / 120; + } + if (e.detail) { + delta = -e.detail / 3; + } + return delta; + }, + + _skipEvents: {}, + + _fakeStop: function (e) { + // fakes stopPropagation by setting a special event flag, checked/reset with L.DomEvent._skipped(e) + L.DomEvent._skipEvents[e.type] = true; + }, + + _skipped: function (e) { + var skipped = this._skipEvents[e.type]; + // reset when checking, as it's only used in map container and propagates outside of the map + this._skipEvents[e.type] = false; + return skipped; + }, + + // check if element really left/entered the event target (for mouseenter/mouseleave) + _checkMouse: function (el, e) { + + var related = e.relatedTarget; + + if (!related) { return true; } + + try { + while (related && (related !== el)) { + related = related.parentNode; + } + } catch (err) { + return false; + } + return (related !== el); + }, + + _getEvent: function () { // evil magic for IE + /*jshint noarg:false */ + var e = window.event; + if (!e) { + var caller = arguments.callee.caller; + while (caller) { + e = caller['arguments'][0]; + if (e && window.Event === e.constructor) { + break; + } + caller = caller.caller; + } + } + return e; + }, + + // this is a horrible workaround for a bug in Android where a single touch triggers two click events + _filterClick: function (e, handler) { + var timeStamp = (e.timeStamp || e.originalEvent.timeStamp), + elapsed = L.DomEvent._lastClick && (timeStamp - L.DomEvent._lastClick); + + // are they closer together than 500ms yet more than 100ms? + // Android typically triggers them ~300ms apart while multiple listeners + // on the same event should be triggered far faster; + // or check if click is simulated on the element, and if it is, reject any non-simulated events + + if ((elapsed && elapsed > 100 && elapsed < 500) || (e.target._simulatedClick && !e._simulated)) { + L.DomEvent.stop(e); + return; + } + L.DomEvent._lastClick = timeStamp; + + return handler(e); + } +}; + +L.DomEvent.on = L.DomEvent.addListener; +L.DomEvent.off = L.DomEvent.removeListener; + + +/* + * L.Draggable allows you to add dragging capabilities to any element. Supports mobile devices too. + */ + +L.Draggable = L.Class.extend({ + includes: L.Mixin.Events, + + statics: { + START: L.Browser.touch ? ['touchstart', 'mousedown'] : ['mousedown'], + END: { + mousedown: 'mouseup', + touchstart: 'touchend', + pointerdown: 'touchend', + MSPointerDown: 'touchend' + }, + MOVE: { + mousedown: 'mousemove', + touchstart: 'touchmove', + pointerdown: 'touchmove', + MSPointerDown: 'touchmove' + } + }, + + initialize: function (element, dragStartTarget) { + this._element = element; + this._dragStartTarget = dragStartTarget || element; + }, + + enable: function () { + if (this._enabled) { return; } + + for (var i = L.Draggable.START.length - 1; i >= 0; i--) { + L.DomEvent.on(this._dragStartTarget, L.Draggable.START[i], this._onDown, this); + } + + this._enabled = true; + }, + + disable: function () { + if (!this._enabled) { return; } + + for (var i = L.Draggable.START.length - 1; i >= 0; i--) { + L.DomEvent.off(this._dragStartTarget, L.Draggable.START[i], this._onDown, this); + } + + this._enabled = false; + this._moved = false; + }, + + _onDown: function (e) { + this._moved = false; + + if (e.shiftKey || ((e.which !== 1) && (e.button !== 1) && !e.touches)) { return; } + + L.DomEvent.stopPropagation(e); + + if (L.Draggable._disabled) { return; } + + L.DomUtil.disableImageDrag(); + L.DomUtil.disableTextSelection(); + + if (this._moving) { return; } + + var first = e.touches ? e.touches[0] : e; + + this._startPoint = new L.Point(first.clientX, first.clientY); + this._startPos = this._newPos = L.DomUtil.getPosition(this._element); + + L.DomEvent + .on(document, L.Draggable.MOVE[e.type], this._onMove, this) + .on(document, L.Draggable.END[e.type], this._onUp, this); + }, + + _onMove: function (e) { + if (e.touches && e.touches.length > 1) { + this._moved = true; + return; + } + + var first = (e.touches && e.touches.length === 1 ? e.touches[0] : e), + newPoint = new L.Point(first.clientX, first.clientY), + offset = newPoint.subtract(this._startPoint); + + if (!offset.x && !offset.y) { return; } + if (L.Browser.touch && Math.abs(offset.x) + Math.abs(offset.y) < 3) { return; } + + L.DomEvent.preventDefault(e); + + if (!this._moved) { + this.fire('dragstart'); + + this._moved = true; + this._startPos = L.DomUtil.getPosition(this._element).subtract(offset); + + L.DomUtil.addClass(document.body, 'leaflet-dragging'); + this._lastTarget = e.target || e.srcElement; + L.DomUtil.addClass(this._lastTarget, 'leaflet-drag-target'); + } + + this._newPos = this._startPos.add(offset); + this._moving = true; + + L.Util.cancelAnimFrame(this._animRequest); + this._animRequest = L.Util.requestAnimFrame(this._updatePosition, this, true, this._dragStartTarget); + }, + + _updatePosition: function () { + this.fire('predrag'); + L.DomUtil.setPosition(this._element, this._newPos); + this.fire('drag'); + }, + + _onUp: function () { + L.DomUtil.removeClass(document.body, 'leaflet-dragging'); + + if (this._lastTarget) { + L.DomUtil.removeClass(this._lastTarget, 'leaflet-drag-target'); + this._lastTarget = null; + } + + for (var i in L.Draggable.MOVE) { + L.DomEvent + .off(document, L.Draggable.MOVE[i], this._onMove) + .off(document, L.Draggable.END[i], this._onUp); + } + + L.DomUtil.enableImageDrag(); + L.DomUtil.enableTextSelection(); + + if (this._moved && this._moving) { + // ensure drag is not fired after dragend + L.Util.cancelAnimFrame(this._animRequest); + + this.fire('dragend', { + distance: this._newPos.distanceTo(this._startPos) + }); + } + + this._moving = false; + } +}); + + +/* + L.Handler is a base class for handler classes that are used internally to inject + interaction features like dragging to classes like Map and Marker. +*/ + +L.Handler = L.Class.extend({ + initialize: function (map) { + this._map = map; + }, + + enable: function () { + if (this._enabled) { return; } + + this._enabled = true; + this.addHooks(); + }, + + disable: function () { + if (!this._enabled) { return; } + + this._enabled = false; + this.removeHooks(); + }, + + enabled: function () { + return !!this._enabled; + } +}); + + +/* + * L.Handler.MapDrag is used to make the map draggable (with panning inertia), enabled by default. + */ + +L.Map.mergeOptions({ + dragging: true, + + inertia: !L.Browser.android23, + inertiaDeceleration: 3400, // px/s^2 + inertiaMaxSpeed: Infinity, // px/s + inertiaThreshold: L.Browser.touch ? 32 : 18, // ms + easeLinearity: 0.25, + + // TODO refactor, move to CRS + worldCopyJump: false +}); + +L.Map.Drag = L.Handler.extend({ + addHooks: function () { + if (!this._draggable) { + var map = this._map; + + this._draggable = new L.Draggable(map._mapPane, map._container); + + this._draggable.on({ + 'dragstart': this._onDragStart, + 'drag': this._onDrag, + 'dragend': this._onDragEnd + }, this); + + if (map.options.worldCopyJump) { + this._draggable.on('predrag', this._onPreDrag, this); + map.on('viewreset', this._onViewReset, this); + + map.whenReady(this._onViewReset, this); + } + } + this._draggable.enable(); + }, + + removeHooks: function () { + this._draggable.disable(); + }, + + moved: function () { + return this._draggable && this._draggable._moved; + }, + + _onDragStart: function () { + var map = this._map; + + if (map._panAnim) { + map._panAnim.stop(); + } + + map + .fire('movestart') + .fire('dragstart'); + + if (map.options.inertia) { + this._positions = []; + this._times = []; + } + }, + + _onDrag: function () { + if (this._map.options.inertia) { + var time = this._lastTime = +new Date(), + pos = this._lastPos = this._draggable._newPos; + + this._positions.push(pos); + this._times.push(time); + + if (time - this._times[0] > 200) { + this._positions.shift(); + this._times.shift(); + } + } + + this._map + .fire('move') + .fire('drag'); + }, + + _onViewReset: function () { + // TODO fix hardcoded Earth values + var pxCenter = this._map.getSize()._divideBy(2), + pxWorldCenter = this._map.latLngToLayerPoint([0, 0]); + + this._initialWorldOffset = pxWorldCenter.subtract(pxCenter).x; + this._worldWidth = this._map.project([0, 180]).x; + }, + + _onPreDrag: function () { + // TODO refactor to be able to adjust map pane position after zoom + var worldWidth = this._worldWidth, + halfWidth = Math.round(worldWidth / 2), + dx = this._initialWorldOffset, + x = this._draggable._newPos.x, + newX1 = (x - halfWidth + dx) % worldWidth + halfWidth - dx, + newX2 = (x + halfWidth + dx) % worldWidth - halfWidth - dx, + newX = Math.abs(newX1 + dx) < Math.abs(newX2 + dx) ? newX1 : newX2; + + this._draggable._newPos.x = newX; + }, + + _onDragEnd: function (e) { + var map = this._map, + options = map.options, + delay = +new Date() - this._lastTime, + + noInertia = !options.inertia || delay > options.inertiaThreshold || !this._positions[0]; + + map.fire('dragend', e); + + if (noInertia) { + map.fire('moveend'); + + } else { + + var direction = this._lastPos.subtract(this._positions[0]), + duration = (this._lastTime + delay - this._times[0]) / 1000, + ease = options.easeLinearity, + + speedVector = direction.multiplyBy(ease / duration), + speed = speedVector.distanceTo([0, 0]), + + limitedSpeed = Math.min(options.inertiaMaxSpeed, speed), + limitedSpeedVector = speedVector.multiplyBy(limitedSpeed / speed), + + decelerationDuration = limitedSpeed / (options.inertiaDeceleration * ease), + offset = limitedSpeedVector.multiplyBy(-decelerationDuration / 2).round(); + + if (!offset.x || !offset.y) { + map.fire('moveend'); + + } else { + offset = map._limitOffset(offset, map.options.maxBounds); + + L.Util.requestAnimFrame(function () { + map.panBy(offset, { + duration: decelerationDuration, + easeLinearity: ease, + noMoveStart: true + }); + }); + } + } + } +}); + +L.Map.addInitHook('addHandler', 'dragging', L.Map.Drag); + + +/* + * L.Handler.DoubleClickZoom is used to handle double-click zoom on the map, enabled by default. + */ + +L.Map.mergeOptions({ + doubleClickZoom: true +}); + +L.Map.DoubleClickZoom = L.Handler.extend({ + addHooks: function () { + this._map.on('dblclick', this._onDoubleClick, this); + }, + + removeHooks: function () { + this._map.off('dblclick', this._onDoubleClick, this); + }, + + _onDoubleClick: function (e) { + var map = this._map, + zoom = map.getZoom() + (e.originalEvent.shiftKey ? -1 : 1); + + if (map.options.doubleClickZoom === 'center') { + map.setZoom(zoom); + } else { + map.setZoomAround(e.containerPoint, zoom); + } + } +}); + +L.Map.addInitHook('addHandler', 'doubleClickZoom', L.Map.DoubleClickZoom); + + +/* + * L.Handler.ScrollWheelZoom is used by L.Map to enable mouse scroll wheel zoom on the map. + */ + +L.Map.mergeOptions({ + scrollWheelZoom: true +}); + +L.Map.ScrollWheelZoom = L.Handler.extend({ + addHooks: function () { + L.DomEvent.on(this._map._container, 'mousewheel', this._onWheelScroll, this); + L.DomEvent.on(this._map._container, 'MozMousePixelScroll', L.DomEvent.preventDefault); + this._delta = 0; + }, + + removeHooks: function () { + L.DomEvent.off(this._map._container, 'mousewheel', this._onWheelScroll); + L.DomEvent.off(this._map._container, 'MozMousePixelScroll', L.DomEvent.preventDefault); + }, + + _onWheelScroll: function (e) { + var delta = L.DomEvent.getWheelDelta(e); + + this._delta += delta; + this._lastMousePos = this._map.mouseEventToContainerPoint(e); + + if (!this._startTime) { + this._startTime = +new Date(); + } + + var left = Math.max(40 - (+new Date() - this._startTime), 0); + + clearTimeout(this._timer); + this._timer = setTimeout(L.bind(this._performZoom, this), left); + + L.DomEvent.preventDefault(e); + L.DomEvent.stopPropagation(e); + }, + + _performZoom: function () { + var map = this._map, + delta = this._delta, + zoom = map.getZoom(); + + delta = delta > 0 ? Math.ceil(delta) : Math.floor(delta); + delta = Math.max(Math.min(delta, 4), -4); + delta = map._limitZoom(zoom + delta) - zoom; + + this._delta = 0; + this._startTime = null; + + if (!delta) { return; } + + if (map.options.scrollWheelZoom === 'center') { + map.setZoom(zoom + delta); + } else { + map.setZoomAround(this._lastMousePos, zoom + delta); + } + } +}); + +L.Map.addInitHook('addHandler', 'scrollWheelZoom', L.Map.ScrollWheelZoom); + + +/* + * Extends the event handling code with double tap support for mobile browsers. + */ + +L.extend(L.DomEvent, { + + _touchstart: L.Browser.msPointer ? 'MSPointerDown' : L.Browser.pointer ? 'pointerdown' : 'touchstart', + _touchend: L.Browser.msPointer ? 'MSPointerUp' : L.Browser.pointer ? 'pointerup' : 'touchend', + + // inspired by Zepto touch code by Thomas Fuchs + addDoubleTapListener: function (obj, handler, id) { + var last, + doubleTap = false, + delay = 250, + touch, + pre = '_leaflet_', + touchstart = this._touchstart, + touchend = this._touchend, + trackedTouches = []; + + function onTouchStart(e) { + var count; + + if (L.Browser.pointer) { + trackedTouches.push(e.pointerId); + count = trackedTouches.length; + } else { + count = e.touches.length; + } + if (count > 1) { + return; + } + + var now = Date.now(), + delta = now - (last || now); + + touch = e.touches ? e.touches[0] : e; + doubleTap = (delta > 0 && delta <= delay); + last = now; + } + + function onTouchEnd(e) { + if (L.Browser.pointer) { + var idx = trackedTouches.indexOf(e.pointerId); + if (idx === -1) { + return; + } + trackedTouches.splice(idx, 1); + } + + if (doubleTap) { + if (L.Browser.pointer) { + // work around .type being readonly with MSPointer* events + var newTouch = { }, + prop; + + // jshint forin:false + for (var i in touch) { + prop = touch[i]; + if (typeof prop === 'function') { + newTouch[i] = prop.bind(touch); + } else { + newTouch[i] = prop; + } + } + touch = newTouch; + } + touch.type = 'dblclick'; + handler(touch); + last = null; + } + } + obj[pre + touchstart + id] = onTouchStart; + obj[pre + touchend + id] = onTouchEnd; + + // on pointer we need to listen on the document, otherwise a drag starting on the map and moving off screen + // will not come through to us, so we will lose track of how many touches are ongoing + var endElement = L.Browser.pointer ? document.documentElement : obj; + + obj.addEventListener(touchstart, onTouchStart, false); + endElement.addEventListener(touchend, onTouchEnd, false); + + if (L.Browser.pointer) { + endElement.addEventListener(L.DomEvent.POINTER_CANCEL, onTouchEnd, false); + } + + return this; + }, + + removeDoubleTapListener: function (obj, id) { + var pre = '_leaflet_'; + + obj.removeEventListener(this._touchstart, obj[pre + this._touchstart + id], false); + (L.Browser.pointer ? document.documentElement : obj).removeEventListener( + this._touchend, obj[pre + this._touchend + id], false); + + if (L.Browser.pointer) { + document.documentElement.removeEventListener(L.DomEvent.POINTER_CANCEL, obj[pre + this._touchend + id], + false); + } + + return this; + } +}); + + +/* + * Extends L.DomEvent to provide touch support for Internet Explorer and Windows-based devices. + */ + +L.extend(L.DomEvent, { + + //static + POINTER_DOWN: L.Browser.msPointer ? 'MSPointerDown' : 'pointerdown', + POINTER_MOVE: L.Browser.msPointer ? 'MSPointerMove' : 'pointermove', + POINTER_UP: L.Browser.msPointer ? 'MSPointerUp' : 'pointerup', + POINTER_CANCEL: L.Browser.msPointer ? 'MSPointerCancel' : 'pointercancel', + + _pointers: [], + _pointerDocumentListener: false, + + // Provides a touch events wrapper for (ms)pointer events. + // Based on changes by veproza https://github.com/CloudMade/Leaflet/pull/1019 + //ref http://www.w3.org/TR/pointerevents/ https://www.w3.org/Bugs/Public/show_bug.cgi?id=22890 + + addPointerListener: function (obj, type, handler, id) { + + switch (type) { + case 'touchstart': + return this.addPointerListenerStart(obj, type, handler, id); + case 'touchend': + return this.addPointerListenerEnd(obj, type, handler, id); + case 'touchmove': + return this.addPointerListenerMove(obj, type, handler, id); + default: + throw 'Unknown touch event type'; + } + }, + + addPointerListenerStart: function (obj, type, handler, id) { + var pre = '_leaflet_', + pointers = this._pointers; + + var cb = function (e) { + if (e.pointerType !== 'mouse' && e.pointerType !== e.MSPOINTER_TYPE_MOUSE) { + L.DomEvent.preventDefault(e); + } + + var alreadyInArray = false; + for (var i = 0; i < pointers.length; i++) { + if (pointers[i].pointerId === e.pointerId) { + alreadyInArray = true; + break; + } + } + if (!alreadyInArray) { + pointers.push(e); + } + + e.touches = pointers.slice(); + e.changedTouches = [e]; + + handler(e); + }; + + obj[pre + 'touchstart' + id] = cb; + obj.addEventListener(this.POINTER_DOWN, cb, false); + + // need to also listen for end events to keep the _pointers list accurate + // this needs to be on the body and never go away + if (!this._pointerDocumentListener) { + var internalCb = function (e) { + for (var i = 0; i < pointers.length; i++) { + if (pointers[i].pointerId === e.pointerId) { + pointers.splice(i, 1); + break; + } + } + }; + //We listen on the documentElement as any drags that end by moving the touch off the screen get fired there + document.documentElement.addEventListener(this.POINTER_UP, internalCb, false); + document.documentElement.addEventListener(this.POINTER_CANCEL, internalCb, false); + + this._pointerDocumentListener = true; + } + + return this; + }, + + addPointerListenerMove: function (obj, type, handler, id) { + var pre = '_leaflet_', + touches = this._pointers; + + function cb(e) { + + // don't fire touch moves when mouse isn't down + if ((e.pointerType === e.MSPOINTER_TYPE_MOUSE || e.pointerType === 'mouse') && e.buttons === 0) { return; } + + for (var i = 0; i < touches.length; i++) { + if (touches[i].pointerId === e.pointerId) { + touches[i] = e; + break; + } + } + + e.touches = touches.slice(); + e.changedTouches = [e]; + + handler(e); + } + + obj[pre + 'touchmove' + id] = cb; + obj.addEventListener(this.POINTER_MOVE, cb, false); + + return this; + }, + + addPointerListenerEnd: function (obj, type, handler, id) { + var pre = '_leaflet_', + touches = this._pointers; + + var cb = function (e) { + for (var i = 0; i < touches.length; i++) { + if (touches[i].pointerId === e.pointerId) { + touches.splice(i, 1); + break; + } + } + + e.touches = touches.slice(); + e.changedTouches = [e]; + + handler(e); + }; + + obj[pre + 'touchend' + id] = cb; + obj.addEventListener(this.POINTER_UP, cb, false); + obj.addEventListener(this.POINTER_CANCEL, cb, false); + + return this; + }, + + removePointerListener: function (obj, type, id) { + var pre = '_leaflet_', + cb = obj[pre + type + id]; + + switch (type) { + case 'touchstart': + obj.removeEventListener(this.POINTER_DOWN, cb, false); + break; + case 'touchmove': + obj.removeEventListener(this.POINTER_MOVE, cb, false); + break; + case 'touchend': + obj.removeEventListener(this.POINTER_UP, cb, false); + obj.removeEventListener(this.POINTER_CANCEL, cb, false); + break; + } + + return this; + } +}); + + +/* + * L.Handler.TouchZoom is used by L.Map to add pinch zoom on supported mobile browsers. + */ + +L.Map.mergeOptions({ + touchZoom: L.Browser.touch && !L.Browser.android23, + bounceAtZoomLimits: true +}); + +L.Map.TouchZoom = L.Handler.extend({ + addHooks: function () { + L.DomEvent.on(this._map._container, 'touchstart', this._onTouchStart, this); + }, + + removeHooks: function () { + L.DomEvent.off(this._map._container, 'touchstart', this._onTouchStart, this); + }, + + _onTouchStart: function (e) { + var map = this._map; + + if (!e.touches || e.touches.length !== 2 || map._animatingZoom || this._zooming) { return; } + + var p1 = map.mouseEventToLayerPoint(e.touches[0]), + p2 = map.mouseEventToLayerPoint(e.touches[1]), + viewCenter = map._getCenterLayerPoint(); + + this._startCenter = p1.add(p2)._divideBy(2); + this._startDist = p1.distanceTo(p2); + + this._moved = false; + this._zooming = true; + + this._centerOffset = viewCenter.subtract(this._startCenter); + + if (map._panAnim) { + map._panAnim.stop(); + } + + L.DomEvent + .on(document, 'touchmove', this._onTouchMove, this) + .on(document, 'touchend', this._onTouchEnd, this); + + L.DomEvent.preventDefault(e); + }, + + _onTouchMove: function (e) { + var map = this._map; + + if (!e.touches || e.touches.length !== 2 || !this._zooming) { return; } + + var p1 = map.mouseEventToLayerPoint(e.touches[0]), + p2 = map.mouseEventToLayerPoint(e.touches[1]); + + this._scale = p1.distanceTo(p2) / this._startDist; + this._delta = p1._add(p2)._divideBy(2)._subtract(this._startCenter); + + if (this._scale === 1) { return; } + + if (!map.options.bounceAtZoomLimits) { + if ((map.getZoom() === map.getMinZoom() && this._scale < 1) || + (map.getZoom() === map.getMaxZoom() && this._scale > 1)) { return; } + } + + if (!this._moved) { + L.DomUtil.addClass(map._mapPane, 'leaflet-touching'); + + map + .fire('movestart') + .fire('zoomstart'); + + this._moved = true; + } + + L.Util.cancelAnimFrame(this._animRequest); + this._animRequest = L.Util.requestAnimFrame( + this._updateOnMove, this, true, this._map._container); + + L.DomEvent.preventDefault(e); + }, + + _updateOnMove: function () { + var map = this._map, + origin = this._getScaleOrigin(), + center = map.layerPointToLatLng(origin), + zoom = map.getScaleZoom(this._scale); + + map._animateZoom(center, zoom, this._startCenter, this._scale, this._delta, false, true); + }, + + _onTouchEnd: function () { + if (!this._moved || !this._zooming) { + this._zooming = false; + return; + } + + var map = this._map; + + this._zooming = false; + L.DomUtil.removeClass(map._mapPane, 'leaflet-touching'); + L.Util.cancelAnimFrame(this._animRequest); + + L.DomEvent + .off(document, 'touchmove', this._onTouchMove) + .off(document, 'touchend', this._onTouchEnd); + + var origin = this._getScaleOrigin(), + center = map.layerPointToLatLng(origin), + + oldZoom = map.getZoom(), + floatZoomDelta = map.getScaleZoom(this._scale) - oldZoom, + roundZoomDelta = (floatZoomDelta > 0 ? + Math.ceil(floatZoomDelta) : Math.floor(floatZoomDelta)), + + zoom = map._limitZoom(oldZoom + roundZoomDelta), + scale = map.getZoomScale(zoom) / this._scale; + + map._animateZoom(center, zoom, origin, scale); + }, + + _getScaleOrigin: function () { + var centerOffset = this._centerOffset.subtract(this._delta).divideBy(this._scale); + return this._startCenter.add(centerOffset); + } +}); + +L.Map.addInitHook('addHandler', 'touchZoom', L.Map.TouchZoom); + + +/* + * L.Map.Tap is used to enable mobile hacks like quick taps and long hold. + */ + +L.Map.mergeOptions({ + tap: true, + tapTolerance: 15 +}); + +L.Map.Tap = L.Handler.extend({ + addHooks: function () { + L.DomEvent.on(this._map._container, 'touchstart', this._onDown, this); + }, + + removeHooks: function () { + L.DomEvent.off(this._map._container, 'touchstart', this._onDown, this); + }, + + _onDown: function (e) { + if (!e.touches) { return; } + + L.DomEvent.preventDefault(e); + + this._fireClick = true; + + // don't simulate click or track longpress if more than 1 touch + if (e.touches.length > 1) { + this._fireClick = false; + clearTimeout(this._holdTimeout); + return; + } + + var first = e.touches[0], + el = first.target; + + this._startPos = this._newPos = new L.Point(first.clientX, first.clientY); + + // if touching a link, highlight it + if (el.tagName && el.tagName.toLowerCase() === 'a') { + L.DomUtil.addClass(el, 'leaflet-active'); + } + + // simulate long hold but setting a timeout + this._holdTimeout = setTimeout(L.bind(function () { + if (this._isTapValid()) { + this._fireClick = false; + this._onUp(); + this._simulateEvent('contextmenu', first); + } + }, this), 1000); + + L.DomEvent + .on(document, 'touchmove', this._onMove, this) + .on(document, 'touchend', this._onUp, this); + }, + + _onUp: function (e) { + clearTimeout(this._holdTimeout); + + L.DomEvent + .off(document, 'touchmove', this._onMove, this) + .off(document, 'touchend', this._onUp, this); + + if (this._fireClick && e && e.changedTouches) { + + var first = e.changedTouches[0], + el = first.target; + + if (el && el.tagName && el.tagName.toLowerCase() === 'a') { + L.DomUtil.removeClass(el, 'leaflet-active'); + } + + // simulate click if the touch didn't move too much + if (this._isTapValid()) { + this._simulateEvent('click', first); + } + } + }, + + _isTapValid: function () { + return this._newPos.distanceTo(this._startPos) <= this._map.options.tapTolerance; + }, + + _onMove: function (e) { + var first = e.touches[0]; + this._newPos = new L.Point(first.clientX, first.clientY); + }, + + _simulateEvent: function (type, e) { + var simulatedEvent = document.createEvent('MouseEvents'); + + simulatedEvent._simulated = true; + e.target._simulatedClick = true; + + simulatedEvent.initMouseEvent( + type, true, true, window, 1, + e.screenX, e.screenY, + e.clientX, e.clientY, + false, false, false, false, 0, null); + + e.target.dispatchEvent(simulatedEvent); + } +}); + +if (L.Browser.touch && !L.Browser.pointer) { + L.Map.addInitHook('addHandler', 'tap', L.Map.Tap); +} + + +/* + * L.Handler.ShiftDragZoom is used to add shift-drag zoom interaction to the map + * (zoom to a selected bounding box), enabled by default. + */ + +L.Map.mergeOptions({ + boxZoom: true +}); + +L.Map.BoxZoom = L.Handler.extend({ + initialize: function (map) { + this._map = map; + this._container = map._container; + this._pane = map._panes.overlayPane; + this._moved = false; + }, + + addHooks: function () { + L.DomEvent.on(this._container, 'mousedown', this._onMouseDown, this); + }, + + removeHooks: function () { + L.DomEvent.off(this._container, 'mousedown', this._onMouseDown); + this._moved = false; + }, + + moved: function () { + return this._moved; + }, + + _onMouseDown: function (e) { + this._moved = false; + + if (!e.shiftKey || ((e.which !== 1) && (e.button !== 1))) { return false; } + + L.DomUtil.disableTextSelection(); + L.DomUtil.disableImageDrag(); + + this._startLayerPoint = this._map.mouseEventToLayerPoint(e); + + L.DomEvent + .on(document, 'mousemove', this._onMouseMove, this) + .on(document, 'mouseup', this._onMouseUp, this) + .on(document, 'keydown', this._onKeyDown, this); + }, + + _onMouseMove: function (e) { + if (!this._moved) { + this._box = L.DomUtil.create('div', 'leaflet-zoom-box', this._pane); + L.DomUtil.setPosition(this._box, this._startLayerPoint); + + //TODO refactor: move cursor to styles + this._container.style.cursor = 'crosshair'; + this._map.fire('boxzoomstart'); + } + + var startPoint = this._startLayerPoint, + box = this._box, + + layerPoint = this._map.mouseEventToLayerPoint(e), + offset = layerPoint.subtract(startPoint), + + newPos = new L.Point( + Math.min(layerPoint.x, startPoint.x), + Math.min(layerPoint.y, startPoint.y)); + + L.DomUtil.setPosition(box, newPos); + + this._moved = true; + + // TODO refactor: remove hardcoded 4 pixels + box.style.width = (Math.max(0, Math.abs(offset.x) - 4)) + 'px'; + box.style.height = (Math.max(0, Math.abs(offset.y) - 4)) + 'px'; + }, + + _finish: function () { + if (this._moved) { + this._pane.removeChild(this._box); + this._container.style.cursor = ''; + } + + L.DomUtil.enableTextSelection(); + L.DomUtil.enableImageDrag(); + + L.DomEvent + .off(document, 'mousemove', this._onMouseMove) + .off(document, 'mouseup', this._onMouseUp) + .off(document, 'keydown', this._onKeyDown); + }, + + _onMouseUp: function (e) { + + this._finish(); + + var map = this._map, + layerPoint = map.mouseEventToLayerPoint(e); + + if (this._startLayerPoint.equals(layerPoint)) { return; } + + var bounds = new L.LatLngBounds( + map.layerPointToLatLng(this._startLayerPoint), + map.layerPointToLatLng(layerPoint)); + + map.fitBounds(bounds); + + map.fire('boxzoomend', { + boxZoomBounds: bounds + }); + }, + + _onKeyDown: function (e) { + if (e.keyCode === 27) { + this._finish(); + } + } +}); + +L.Map.addInitHook('addHandler', 'boxZoom', L.Map.BoxZoom); + + +/* + * L.Map.Keyboard is handling keyboard interaction with the map, enabled by default. + */ + +L.Map.mergeOptions({ + keyboard: true, + keyboardPanOffset: 80, + keyboardZoomOffset: 1 +}); + +L.Map.Keyboard = L.Handler.extend({ + + keyCodes: { + left: [37], + right: [39], + down: [40], + up: [38], + zoomIn: [187, 107, 61, 171], + zoomOut: [189, 109, 173] + }, + + initialize: function (map) { + this._map = map; + + this._setPanOffset(map.options.keyboardPanOffset); + this._setZoomOffset(map.options.keyboardZoomOffset); + }, + + addHooks: function () { + var container = this._map._container; + + // make the container focusable by tabbing + if (container.tabIndex === -1) { + container.tabIndex = '0'; + } + + L.DomEvent + .on(container, 'focus', this._onFocus, this) + .on(container, 'blur', this._onBlur, this) + .on(container, 'mousedown', this._onMouseDown, this); + + this._map + .on('focus', this._addHooks, this) + .on('blur', this._removeHooks, this); + }, + + removeHooks: function () { + this._removeHooks(); + + var container = this._map._container; + + L.DomEvent + .off(container, 'focus', this._onFocus, this) + .off(container, 'blur', this._onBlur, this) + .off(container, 'mousedown', this._onMouseDown, this); + + this._map + .off('focus', this._addHooks, this) + .off('blur', this._removeHooks, this); + }, + + _onMouseDown: function () { + if (this._focused) { return; } + + var body = document.body, + docEl = document.documentElement, + top = body.scrollTop || docEl.scrollTop, + left = body.scrollLeft || docEl.scrollLeft; + + this._map._container.focus(); + + window.scrollTo(left, top); + }, + + _onFocus: function () { + this._focused = true; + this._map.fire('focus'); + }, + + _onBlur: function () { + this._focused = false; + this._map.fire('blur'); + }, + + _setPanOffset: function (pan) { + var keys = this._panKeys = {}, + codes = this.keyCodes, + i, len; + + for (i = 0, len = codes.left.length; i < len; i++) { + keys[codes.left[i]] = [-1 * pan, 0]; + } + for (i = 0, len = codes.right.length; i < len; i++) { + keys[codes.right[i]] = [pan, 0]; + } + for (i = 0, len = codes.down.length; i < len; i++) { + keys[codes.down[i]] = [0, pan]; + } + for (i = 0, len = codes.up.length; i < len; i++) { + keys[codes.up[i]] = [0, -1 * pan]; + } + }, + + _setZoomOffset: function (zoom) { + var keys = this._zoomKeys = {}, + codes = this.keyCodes, + i, len; + + for (i = 0, len = codes.zoomIn.length; i < len; i++) { + keys[codes.zoomIn[i]] = zoom; + } + for (i = 0, len = codes.zoomOut.length; i < len; i++) { + keys[codes.zoomOut[i]] = -zoom; + } + }, + + _addHooks: function () { + L.DomEvent.on(document, 'keydown', this._onKeyDown, this); + }, + + _removeHooks: function () { + L.DomEvent.off(document, 'keydown', this._onKeyDown, this); + }, + + _onKeyDown: function (e) { + var key = e.keyCode, + map = this._map; + + if (key in this._panKeys) { + + if (map._panAnim && map._panAnim._inProgress) { return; } + + map.panBy(this._panKeys[key]); + + if (map.options.maxBounds) { + map.panInsideBounds(map.options.maxBounds); + } + + } else if (key in this._zoomKeys) { + map.setZoom(map.getZoom() + this._zoomKeys[key]); + + } else { + return; + } + + L.DomEvent.stop(e); + } +}); + +L.Map.addInitHook('addHandler', 'keyboard', L.Map.Keyboard); + + +/* + * L.Handler.MarkerDrag is used internally by L.Marker to make the markers draggable. + */ + +L.Handler.MarkerDrag = L.Handler.extend({ + initialize: function (marker) { + this._marker = marker; + }, + + addHooks: function () { + var icon = this._marker._icon; + if (!this._draggable) { + this._draggable = new L.Draggable(icon, icon); + } + + this._draggable + .on('dragstart', this._onDragStart, this) + .on('drag', this._onDrag, this) + .on('dragend', this._onDragEnd, this); + this._draggable.enable(); + L.DomUtil.addClass(this._marker._icon, 'leaflet-marker-draggable'); + }, + + removeHooks: function () { + this._draggable + .off('dragstart', this._onDragStart, this) + .off('drag', this._onDrag, this) + .off('dragend', this._onDragEnd, this); + + this._draggable.disable(); + L.DomUtil.removeClass(this._marker._icon, 'leaflet-marker-draggable'); + }, + + moved: function () { + return this._draggable && this._draggable._moved; + }, + + _onDragStart: function () { + this._marker + .closePopup() + .fire('movestart') + .fire('dragstart'); + }, + + _onDrag: function () { + var marker = this._marker, + shadow = marker._shadow, + iconPos = L.DomUtil.getPosition(marker._icon), + latlng = marker._map.layerPointToLatLng(iconPos); + + // update shadow position + if (shadow) { + L.DomUtil.setPosition(shadow, iconPos); + } + + marker._latlng = latlng; + + marker + .fire('move', {latlng: latlng}) + .fire('drag'); + }, + + _onDragEnd: function (e) { + this._marker + .fire('moveend') + .fire('dragend', e); + } +}); + + +/* + * L.Control is a base class for implementing map controls. Handles positioning. + * All other controls extend from this class. + */ + +L.Control = L.Class.extend({ + options: { + position: 'topright' + }, + + initialize: function (options) { + L.setOptions(this, options); + }, + + getPosition: function () { + return this.options.position; + }, + + setPosition: function (position) { + var map = this._map; + + if (map) { + map.removeControl(this); + } + + this.options.position = position; + + if (map) { + map.addControl(this); + } + + return this; + }, + + getContainer: function () { + return this._container; + }, + + addTo: function (map) { + this._map = map; + + var container = this._container = this.onAdd(map), + pos = this.getPosition(), + corner = map._controlCorners[pos]; + + L.DomUtil.addClass(container, 'leaflet-control'); + + if (pos.indexOf('bottom') !== -1) { + corner.insertBefore(container, corner.firstChild); + } else { + corner.appendChild(container); + } + + return this; + }, + + removeFrom: function (map) { + var pos = this.getPosition(), + corner = map._controlCorners[pos]; + + corner.removeChild(this._container); + this._map = null; + + if (this.onRemove) { + this.onRemove(map); + } + + return this; + }, + + _refocusOnMap: function () { + if (this._map) { + this._map.getContainer().focus(); + } + } +}); + +L.control = function (options) { + return new L.Control(options); +}; + + +// adds control-related methods to L.Map + +L.Map.include({ + addControl: function (control) { + control.addTo(this); + return this; + }, + + removeControl: function (control) { + control.removeFrom(this); + return this; + }, + + _initControlPos: function () { + var corners = this._controlCorners = {}, + l = 'leaflet-', + container = this._controlContainer = + L.DomUtil.create('div', l + 'control-container', this._container); + + function createCorner(vSide, hSide) { + var className = l + vSide + ' ' + l + hSide; + + corners[vSide + hSide] = L.DomUtil.create('div', className, container); + } + + createCorner('top', 'left'); + createCorner('top', 'right'); + createCorner('bottom', 'left'); + createCorner('bottom', 'right'); + }, + + _clearControlPos: function () { + this._container.removeChild(this._controlContainer); + } +}); + + +/* + * L.Control.Zoom is used for the default zoom buttons on the map. + */ + +L.Control.Zoom = L.Control.extend({ + options: { + position: 'topleft', + zoomInText: '+', + zoomInTitle: 'Zoom in', + zoomOutText: '-', + zoomOutTitle: 'Zoom out' + }, + + onAdd: function (map) { + var zoomName = 'leaflet-control-zoom', + container = L.DomUtil.create('div', zoomName + ' leaflet-bar'); + + this._map = map; + + this._zoomInButton = this._createButton( + this.options.zoomInText, this.options.zoomInTitle, + zoomName + '-in', container, this._zoomIn, this); + this._zoomOutButton = this._createButton( + this.options.zoomOutText, this.options.zoomOutTitle, + zoomName + '-out', container, this._zoomOut, this); + + this._updateDisabled(); + map.on('zoomend zoomlevelschange', this._updateDisabled, this); + + return container; + }, + + onRemove: function (map) { + map.off('zoomend zoomlevelschange', this._updateDisabled, this); + }, + + _zoomIn: function (e) { + this._map.zoomIn(e.shiftKey ? 3 : 1); + }, + + _zoomOut: function (e) { + this._map.zoomOut(e.shiftKey ? 3 : 1); + }, + + _createButton: function (html, title, className, container, fn, context) { + var link = L.DomUtil.create('a', className, container); + link.innerHTML = html; + link.href = '#'; + link.title = title; + + var stop = L.DomEvent.stopPropagation; + + L.DomEvent + .on(link, 'click', stop) + .on(link, 'mousedown', stop) + .on(link, 'dblclick', stop) + .on(link, 'click', L.DomEvent.preventDefault) + .on(link, 'click', fn, context) + .on(link, 'click', this._refocusOnMap, context); + + return link; + }, + + _updateDisabled: function () { + var map = this._map, + className = 'leaflet-disabled'; + + L.DomUtil.removeClass(this._zoomInButton, className); + L.DomUtil.removeClass(this._zoomOutButton, className); + + if (map._zoom === map.getMinZoom()) { + L.DomUtil.addClass(this._zoomOutButton, className); + } + if (map._zoom === map.getMaxZoom()) { + L.DomUtil.addClass(this._zoomInButton, className); + } + } +}); + +L.Map.mergeOptions({ + zoomControl: true +}); + +L.Map.addInitHook(function () { + if (this.options.zoomControl) { + this.zoomControl = new L.Control.Zoom(); + this.addControl(this.zoomControl); + } +}); + +L.control.zoom = function (options) { + return new L.Control.Zoom(options); +}; + + + +/* + * L.Control.Attribution is used for displaying attribution on the map (added by default). + */ + +L.Control.Attribution = L.Control.extend({ + options: { + position: 'bottomright', + prefix: '<a href="http://leafletjs.com" title="A JS library for interactive maps">Leaflet</a>' + }, + + initialize: function (options) { + L.setOptions(this, options); + + this._attributions = {}; + }, + + onAdd: function (map) { + this._container = L.DomUtil.create('div', 'leaflet-control-attribution'); + L.DomEvent.disableClickPropagation(this._container); + + for (var i in map._layers) { + if (map._layers[i].getAttribution) { + this.addAttribution(map._layers[i].getAttribution()); + } + } + + map + .on('layeradd', this._onLayerAdd, this) + .on('layerremove', this._onLayerRemove, this); + + this._update(); + + return this._container; + }, + + onRemove: function (map) { + map + .off('layeradd', this._onLayerAdd) + .off('layerremove', this._onLayerRemove); + + }, + + setPrefix: function (prefix) { + this.options.prefix = prefix; + this._update(); + return this; + }, + + addAttribution: function (text) { + if (!text) { return; } + + if (!this._attributions[text]) { + this._attributions[text] = 0; + } + this._attributions[text]++; + + this._update(); + + return this; + }, + + removeAttribution: function (text) { + if (!text) { return; } + + if (this._attributions[text]) { + this._attributions[text]--; + this._update(); + } + + return this; + }, + + _update: function () { + if (!this._map) { return; } + + var attribs = []; + + for (var i in this._attributions) { + if (this._attributions[i]) { + attribs.push(i); + } + } + + var prefixAndAttribs = []; + + if (this.options.prefix) { + prefixAndAttribs.push(this.options.prefix); + } + if (attribs.length) { + prefixAndAttribs.push(attribs.join(', ')); + } + + this._container.innerHTML = prefixAndAttribs.join(' | '); + }, + + _onLayerAdd: function (e) { + if (e.layer.getAttribution) { + this.addAttribution(e.layer.getAttribution()); + } + }, + + _onLayerRemove: function (e) { + if (e.layer.getAttribution) { + this.removeAttribution(e.layer.getAttribution()); + } + } +}); + +L.Map.mergeOptions({ + attributionControl: true +}); + +L.Map.addInitHook(function () { + if (this.options.attributionControl) { + this.attributionControl = (new L.Control.Attribution()).addTo(this); + } +}); + +L.control.attribution = function (options) { + return new L.Control.Attribution(options); +}; + + +/* + * L.Control.Scale is used for displaying metric/imperial scale on the map. + */ + +L.Control.Scale = L.Control.extend({ + options: { + position: 'bottomleft', + maxWidth: 100, + metric: true, + imperial: true, + updateWhenIdle: false + }, + + onAdd: function (map) { + this._map = map; + + var className = 'leaflet-control-scale', + container = L.DomUtil.create('div', className), + options = this.options; + + this._addScales(options, className, container); + + map.on(options.updateWhenIdle ? 'moveend' : 'move', this._update, this); + map.whenReady(this._update, this); + + return container; + }, + + onRemove: function (map) { + map.off(this.options.updateWhenIdle ? 'moveend' : 'move', this._update, this); + }, + + _addScales: function (options, className, container) { + if (options.metric) { + this._mScale = L.DomUtil.create('div', className + '-line', container); + } + if (options.imperial) { + this._iScale = L.DomUtil.create('div', className + '-line', container); + } + }, + + _update: function () { + var bounds = this._map.getBounds(), + centerLat = bounds.getCenter().lat, + halfWorldMeters = 6378137 * Math.PI * Math.cos(centerLat * Math.PI / 180), + dist = halfWorldMeters * (bounds.getNorthEast().lng - bounds.getSouthWest().lng) / 180, + + size = this._map.getSize(), + options = this.options, + maxMeters = 0; + + if (size.x > 0) { + maxMeters = dist * (options.maxWidth / size.x); + } + + this._updateScales(options, maxMeters); + }, + + _updateScales: function (options, maxMeters) { + if (options.metric && maxMeters) { + this._updateMetric(maxMeters); + } + + if (options.imperial && maxMeters) { + this._updateImperial(maxMeters); + } + }, + + _updateMetric: function (maxMeters) { + var meters = this._getRoundNum(maxMeters); + + this._mScale.style.width = this._getScaleWidth(meters / maxMeters) + 'px'; + this._mScale.innerHTML = meters < 1000 ? meters + ' m' : (meters / 1000) + ' km'; + }, + + _updateImperial: function (maxMeters) { + var maxFeet = maxMeters * 3.2808399, + scale = this._iScale, + maxMiles, miles, feet; + + if (maxFeet > 5280) { + maxMiles = maxFeet / 5280; + miles = this._getRoundNum(maxMiles); + + scale.style.width = this._getScaleWidth(miles / maxMiles) + 'px'; + scale.innerHTML = miles + ' mi'; + + } else { + feet = this._getRoundNum(maxFeet); + + scale.style.width = this._getScaleWidth(feet / maxFeet) + 'px'; + scale.innerHTML = feet + ' ft'; + } + }, + + _getScaleWidth: function (ratio) { + return Math.round(this.options.maxWidth * ratio) - 10; + }, + + _getRoundNum: function (num) { + var pow10 = Math.pow(10, (Math.floor(num) + '').length - 1), + d = num / pow10; + + d = d >= 10 ? 10 : d >= 5 ? 5 : d >= 3 ? 3 : d >= 2 ? 2 : 1; + + return pow10 * d; + } +}); + +L.control.scale = function (options) { + return new L.Control.Scale(options); +}; + + +/* + * L.Control.Layers is a control to allow users to switch between different layers on the map. + */ + +L.Control.Layers = L.Control.extend({ + options: { + collapsed: true, + position: 'topright', + autoZIndex: true + }, + + initialize: function (baseLayers, overlays, options) { + L.setOptions(this, options); + + this._layers = {}; + this._lastZIndex = 0; + this._handlingClick = false; + + for (var i in baseLayers) { + this._addLayer(baseLayers[i], i); + } + + for (i in overlays) { + this._addLayer(overlays[i], i, true); + } + }, + + onAdd: function (map) { + this._initLayout(); + this._update(); + + map + .on('layeradd', this._onLayerChange, this) + .on('layerremove', this._onLayerChange, this); + + return this._container; + }, + + onRemove: function (map) { + map + .off('layeradd', this._onLayerChange, this) + .off('layerremove', this._onLayerChange, this); + }, + + addBaseLayer: function (layer, name) { + this._addLayer(layer, name); + this._update(); + return this; + }, + + addOverlay: function (layer, name) { + this._addLayer(layer, name, true); + this._update(); + return this; + }, + + removeLayer: function (layer) { + var id = L.stamp(layer); + delete this._layers[id]; + this._update(); + return this; + }, + + _initLayout: function () { + var className = 'leaflet-control-layers', + container = this._container = L.DomUtil.create('div', className); + + //Makes this work on IE10 Touch devices by stopping it from firing a mouseout event when the touch is released + container.setAttribute('aria-haspopup', true); + + if (!L.Browser.touch) { + L.DomEvent + .disableClickPropagation(container) + .disableScrollPropagation(container); + } else { + L.DomEvent.on(container, 'click', L.DomEvent.stopPropagation); + } + + var form = this._form = L.DomUtil.create('form', className + '-list'); + + if (this.options.collapsed) { + if (!L.Browser.android) { + L.DomEvent + .on(container, 'mouseover', this._expand, this) + .on(container, 'mouseout', this._collapse, this); + } + var link = this._layersLink = L.DomUtil.create('a', className + '-toggle', container); + link.href = '#'; + link.title = 'Layers'; + + if (L.Browser.touch) { + L.DomEvent + .on(link, 'click', L.DomEvent.stop) + .on(link, 'click', this._expand, this); + } + else { + L.DomEvent.on(link, 'focus', this._expand, this); + } + //Work around for Firefox android issue https://github.com/Leaflet/Leaflet/issues/2033 + L.DomEvent.on(form, 'click', function () { + setTimeout(L.bind(this._onInputClick, this), 0); + }, this); + + this._map.on('click', this._collapse, this); + // TODO keyboard accessibility + } else { + this._expand(); + } + + this._baseLayersList = L.DomUtil.create('div', className + '-base', form); + this._separator = L.DomUtil.create('div', className + '-separator', form); + this._overlaysList = L.DomUtil.create('div', className + '-overlays', form); + + container.appendChild(form); + }, + + _addLayer: function (layer, name, overlay) { + var id = L.stamp(layer); + + this._layers[id] = { + layer: layer, + name: name, + overlay: overlay + }; + + if (this.options.autoZIndex && layer.setZIndex) { + this._lastZIndex++; + layer.setZIndex(this._lastZIndex); + } + }, + + _update: function () { + if (!this._container) { + return; + } + + this._baseLayersList.innerHTML = ''; + this._overlaysList.innerHTML = ''; + + var baseLayersPresent = false, + overlaysPresent = false, + i, obj; + + for (i in this._layers) { + obj = this._layers[i]; + this._addItem(obj); + overlaysPresent = overlaysPresent || obj.overlay; + baseLayersPresent = baseLayersPresent || !obj.overlay; + } + + this._separator.style.display = overlaysPresent && baseLayersPresent ? '' : 'none'; + }, + + _onLayerChange: function (e) { + var obj = this._layers[L.stamp(e.layer)]; + + if (!obj) { return; } + + if (!this._handlingClick) { + this._update(); + } + + var type = obj.overlay ? + (e.type === 'layeradd' ? 'overlayadd' : 'overlayremove') : + (e.type === 'layeradd' ? 'baselayerchange' : null); + + if (type) { + this._map.fire(type, obj); + } + }, + + // IE7 bugs out if you create a radio dynamically, so you have to do it this hacky way (see http://bit.ly/PqYLBe) + _createRadioElement: function (name, checked) { + + var radioHtml = '<input type="radio" class="leaflet-control-layers-selector" name="' + name + '"'; + if (checked) { + radioHtml += ' checked="checked"'; + } + radioHtml += '/>'; + + var radioFragment = document.createElement('div'); + radioFragment.innerHTML = radioHtml; + + return radioFragment.firstChild; + }, + + _addItem: function (obj) { + var label = document.createElement('label'), + input, + checked = this._map.hasLayer(obj.layer); + + if (obj.overlay) { + input = document.createElement('input'); + input.type = 'checkbox'; + input.className = 'leaflet-control-layers-selector'; + input.defaultChecked = checked; + } else { + input = this._createRadioElement('leaflet-base-layers', checked); + } + + input.layerId = L.stamp(obj.layer); + + L.DomEvent.on(input, 'click', this._onInputClick, this); + + var name = document.createElement('span'); + name.innerHTML = ' ' + obj.name; + + label.appendChild(input); + label.appendChild(name); + + var container = obj.overlay ? this._overlaysList : this._baseLayersList; + container.appendChild(label); + + return label; + }, + + _onInputClick: function () { + var i, input, obj, + inputs = this._form.getElementsByTagName('input'), + inputsLen = inputs.length; + + this._handlingClick = true; + + for (i = 0; i < inputsLen; i++) { + input = inputs[i]; + obj = this._layers[input.layerId]; + + if (input.checked && !this._map.hasLayer(obj.layer)) { + this._map.addLayer(obj.layer); + + } else if (!input.checked && this._map.hasLayer(obj.layer)) { + this._map.removeLayer(obj.layer); + } + } + + this._handlingClick = false; + + this._refocusOnMap(); + }, + + _expand: function () { + L.DomUtil.addClass(this._container, 'leaflet-control-layers-expanded'); + }, + + _collapse: function () { + this._container.className = this._container.className.replace(' leaflet-control-layers-expanded', ''); + } +}); + +L.control.layers = function (baseLayers, overlays, options) { + return new L.Control.Layers(baseLayers, overlays, options); +}; + + +/* + * L.PosAnimation is used by Leaflet internally for pan animations. + */ + +L.PosAnimation = L.Class.extend({ + includes: L.Mixin.Events, + + run: function (el, newPos, duration, easeLinearity) { // (HTMLElement, Point[, Number, Number]) + this.stop(); + + this._el = el; + this._inProgress = true; + this._newPos = newPos; + + this.fire('start'); + + el.style[L.DomUtil.TRANSITION] = 'all ' + (duration || 0.25) + + 's cubic-bezier(0,0,' + (easeLinearity || 0.5) + ',1)'; + + L.DomEvent.on(el, L.DomUtil.TRANSITION_END, this._onTransitionEnd, this); + L.DomUtil.setPosition(el, newPos); + + // toggle reflow, Chrome flickers for some reason if you don't do this + L.Util.falseFn(el.offsetWidth); + + // there's no native way to track value updates of transitioned properties, so we imitate this + this._stepTimer = setInterval(L.bind(this._onStep, this), 50); + }, + + stop: function () { + if (!this._inProgress) { return; } + + // if we just removed the transition property, the element would jump to its final position, + // so we need to make it stay at the current position + + L.DomUtil.setPosition(this._el, this._getPos()); + this._onTransitionEnd(); + L.Util.falseFn(this._el.offsetWidth); // force reflow in case we are about to start a new animation + }, + + _onStep: function () { + var stepPos = this._getPos(); + if (!stepPos) { + this._onTransitionEnd(); + return; + } + // jshint camelcase: false + // make L.DomUtil.getPosition return intermediate position value during animation + this._el._leaflet_pos = stepPos; + + this.fire('step'); + }, + + // you can't easily get intermediate values of properties animated with CSS3 Transitions, + // we need to parse computed style (in case of transform it returns matrix string) + + _transformRe: /([-+]?(?:\d*\.)?\d+)\D*, ([-+]?(?:\d*\.)?\d+)\D*\)/, + + _getPos: function () { + var left, top, matches, + el = this._el, + style = window.getComputedStyle(el); + + if (L.Browser.any3d) { + matches = style[L.DomUtil.TRANSFORM].match(this._transformRe); + if (!matches) { return; } + left = parseFloat(matches[1]); + top = parseFloat(matches[2]); + } else { + left = parseFloat(style.left); + top = parseFloat(style.top); + } + + return new L.Point(left, top, true); + }, + + _onTransitionEnd: function () { + L.DomEvent.off(this._el, L.DomUtil.TRANSITION_END, this._onTransitionEnd, this); + + if (!this._inProgress) { return; } + this._inProgress = false; + + this._el.style[L.DomUtil.TRANSITION] = ''; + + // jshint camelcase: false + // make sure L.DomUtil.getPosition returns the final position value after animation + this._el._leaflet_pos = this._newPos; + + clearInterval(this._stepTimer); + + this.fire('step').fire('end'); + } + +}); + + +/* + * Extends L.Map to handle panning animations. + */ + +L.Map.include({ + + setView: function (center, zoom, options) { + + zoom = zoom === undefined ? this._zoom : this._limitZoom(zoom); + center = this._limitCenter(L.latLng(center), zoom, this.options.maxBounds); + options = options || {}; + + if (this._panAnim) { + this._panAnim.stop(); + } + + if (this._loaded && !options.reset && options !== true) { + + if (options.animate !== undefined) { + options.zoom = L.extend({animate: options.animate}, options.zoom); + options.pan = L.extend({animate: options.animate}, options.pan); + } + + // try animating pan or zoom + var animated = (this._zoom !== zoom) ? + this._tryAnimatedZoom && this._tryAnimatedZoom(center, zoom, options.zoom) : + this._tryAnimatedPan(center, options.pan); + + if (animated) { + // prevent resize handler call, the view will refresh after animation anyway + clearTimeout(this._sizeTimer); + return this; + } + } + + // animation didn't start, just reset the map view + this._resetView(center, zoom); + + return this; + }, + + panBy: function (offset, options) { + offset = L.point(offset).round(); + options = options || {}; + + if (!offset.x && !offset.y) { + return this; + } + + if (!this._panAnim) { + this._panAnim = new L.PosAnimation(); + + this._panAnim.on({ + 'step': this._onPanTransitionStep, + 'end': this._onPanTransitionEnd + }, this); + } + + // don't fire movestart if animating inertia + if (!options.noMoveStart) { + this.fire('movestart'); + } + + // animate pan unless animate: false specified + if (options.animate !== false) { + L.DomUtil.addClass(this._mapPane, 'leaflet-pan-anim'); + + var newPos = this._getMapPanePos().subtract(offset); + this._panAnim.run(this._mapPane, newPos, options.duration || 0.25, options.easeLinearity); + } else { + this._rawPanBy(offset); + this.fire('move').fire('moveend'); + } + + return this; + }, + + _onPanTransitionStep: function () { + this.fire('move'); + }, + + _onPanTransitionEnd: function () { + L.DomUtil.removeClass(this._mapPane, 'leaflet-pan-anim'); + this.fire('moveend'); + }, + + _tryAnimatedPan: function (center, options) { + // difference between the new and current centers in pixels + var offset = this._getCenterOffset(center)._floor(); + + // don't animate too far unless animate: true specified in options + if ((options && options.animate) !== true && !this.getSize().contains(offset)) { return false; } + + this.panBy(offset, options); + + return true; + } +}); + + +/* + * L.PosAnimation fallback implementation that powers Leaflet pan animations + * in browsers that don't support CSS3 Transitions. + */ + +L.PosAnimation = L.DomUtil.TRANSITION ? L.PosAnimation : L.PosAnimation.extend({ + + run: function (el, newPos, duration, easeLinearity) { // (HTMLElement, Point[, Number, Number]) + this.stop(); + + this._el = el; + this._inProgress = true; + this._duration = duration || 0.25; + this._easeOutPower = 1 / Math.max(easeLinearity || 0.5, 0.2); + + this._startPos = L.DomUtil.getPosition(el); + this._offset = newPos.subtract(this._startPos); + this._startTime = +new Date(); + + this.fire('start'); + + this._animate(); + }, + + stop: function () { + if (!this._inProgress) { return; } + + this._step(); + this._complete(); + }, + + _animate: function () { + // animation loop + this._animId = L.Util.requestAnimFrame(this._animate, this); + this._step(); + }, + + _step: function () { + var elapsed = (+new Date()) - this._startTime, + duration = this._duration * 1000; + + if (elapsed < duration) { + this._runFrame(this._easeOut(elapsed / duration)); + } else { + this._runFrame(1); + this._complete(); + } + }, + + _runFrame: function (progress) { + var pos = this._startPos.add(this._offset.multiplyBy(progress)); + L.DomUtil.setPosition(this._el, pos); + + this.fire('step'); + }, + + _complete: function () { + L.Util.cancelAnimFrame(this._animId); + + this._inProgress = false; + this.fire('end'); + }, + + _easeOut: function (t) { + return 1 - Math.pow(1 - t, this._easeOutPower); + } +}); + + +/* + * Extends L.Map to handle zoom animations. + */ + +L.Map.mergeOptions({ + zoomAnimation: true, + zoomAnimationThreshold: 4 +}); + +if (L.DomUtil.TRANSITION) { + + L.Map.addInitHook(function () { + // don't animate on browsers without hardware-accelerated transitions or old Android/Opera + this._zoomAnimated = this.options.zoomAnimation && L.DomUtil.TRANSITION && + L.Browser.any3d && !L.Browser.android23 && !L.Browser.mobileOpera; + + // zoom transitions run with the same duration for all layers, so if one of transitionend events + // happens after starting zoom animation (propagating to the map pane), we know that it ended globally + if (this._zoomAnimated) { + L.DomEvent.on(this._mapPane, L.DomUtil.TRANSITION_END, this._catchTransitionEnd, this); + } + }); +} + +L.Map.include(!L.DomUtil.TRANSITION ? {} : { + + _catchTransitionEnd: function (e) { + if (this._animatingZoom && e.propertyName.indexOf('transform') >= 0) { + this._onZoomTransitionEnd(); + } + }, + + _nothingToAnimate: function () { + return !this._container.getElementsByClassName('leaflet-zoom-animated').length; + }, + + _tryAnimatedZoom: function (center, zoom, options) { + + if (this._animatingZoom) { return true; } + + options = options || {}; + + // don't animate if disabled, not supported or zoom difference is too large + if (!this._zoomAnimated || options.animate === false || this._nothingToAnimate() || + Math.abs(zoom - this._zoom) > this.options.zoomAnimationThreshold) { return false; } + + // offset is the pixel coords of the zoom origin relative to the current center + var scale = this.getZoomScale(zoom), + offset = this._getCenterOffset(center)._divideBy(1 - 1 / scale), + origin = this._getCenterLayerPoint()._add(offset); + + // don't animate if the zoom origin isn't within one screen from the current center, unless forced + if (options.animate !== true && !this.getSize().contains(offset)) { return false; } + + this + .fire('movestart') + .fire('zoomstart'); + + this._animateZoom(center, zoom, origin, scale, null, true); + + return true; + }, + + _animateZoom: function (center, zoom, origin, scale, delta, backwards, forTouchZoom) { + + if (!forTouchZoom) { + this._animatingZoom = true; + } + + // put transform transition on all layers with leaflet-zoom-animated class + L.DomUtil.addClass(this._mapPane, 'leaflet-zoom-anim'); + + // remember what center/zoom to set after animation + this._animateToCenter = center; + this._animateToZoom = zoom; + + // disable any dragging during animation + if (L.Draggable) { + L.Draggable._disabled = true; + } + + L.Util.requestAnimFrame(function () { + this.fire('zoomanim', { + center: center, + zoom: zoom, + origin: origin, + scale: scale, + delta: delta, + backwards: backwards + }); + // horrible hack to work around a Chrome bug https://github.com/Leaflet/Leaflet/issues/3689 + setTimeout(L.bind(this._onZoomTransitionEnd, this), 250); + }, this); + }, + + _onZoomTransitionEnd: function () { + if (!this._animatingZoom) { return; } + + this._animatingZoom = false; + + L.DomUtil.removeClass(this._mapPane, 'leaflet-zoom-anim'); + + L.Util.requestAnimFrame(function () { + this._resetView(this._animateToCenter, this._animateToZoom, true, true); + + if (L.Draggable) { + L.Draggable._disabled = false; + } + }, this); + } +}); + + +/* + Zoom animation logic for L.TileLayer. +*/ + +L.TileLayer.include({ + _animateZoom: function (e) { + if (!this._animating) { + this._animating = true; + this._prepareBgBuffer(); + } + + var bg = this._bgBuffer, + transform = L.DomUtil.TRANSFORM, + initialTransform = e.delta ? L.DomUtil.getTranslateString(e.delta) : bg.style[transform], + scaleStr = L.DomUtil.getScaleString(e.scale, e.origin); + + bg.style[transform] = e.backwards ? + scaleStr + ' ' + initialTransform : + initialTransform + ' ' + scaleStr; + }, + + _endZoomAnim: function () { + var front = this._tileContainer, + bg = this._bgBuffer; + + front.style.visibility = ''; + front.parentNode.appendChild(front); // Bring to fore + + // force reflow + L.Util.falseFn(bg.offsetWidth); + + var zoom = this._map.getZoom(); + if (zoom > this.options.maxZoom || zoom < this.options.minZoom) { + this._clearBgBuffer(); + } + + this._animating = false; + }, + + _clearBgBuffer: function () { + var map = this._map; + + if (map && !map._animatingZoom && !map.touchZoom._zooming) { + this._bgBuffer.innerHTML = ''; + this._bgBuffer.style[L.DomUtil.TRANSFORM] = ''; + } + }, + + _prepareBgBuffer: function () { + + var front = this._tileContainer, + bg = this._bgBuffer; + + // if foreground layer doesn't have many tiles but bg layer does, + // keep the existing bg layer and just zoom it some more + + var bgLoaded = this._getLoadedTilesPercentage(bg), + frontLoaded = this._getLoadedTilesPercentage(front); + + if (bg && bgLoaded > 0.5 && frontLoaded < 0.5) { + + front.style.visibility = 'hidden'; + this._stopLoadingImages(front); + return; + } + + // prepare the buffer to become the front tile pane + bg.style.visibility = 'hidden'; + bg.style[L.DomUtil.TRANSFORM] = ''; + + // switch out the current layer to be the new bg layer (and vice-versa) + this._tileContainer = bg; + bg = this._bgBuffer = front; + + this._stopLoadingImages(bg); + + //prevent bg buffer from clearing right after zoom + clearTimeout(this._clearBgBufferTimer); + }, + + _getLoadedTilesPercentage: function (container) { + var tiles = container.getElementsByTagName('img'), + i, len, count = 0; + + for (i = 0, len = tiles.length; i < len; i++) { + if (tiles[i].complete) { + count++; + } + } + return count / len; + }, + + // stops loading all tiles in the background layer + _stopLoadingImages: function (container) { + var tiles = Array.prototype.slice.call(container.getElementsByTagName('img')), + i, len, tile; + + for (i = 0, len = tiles.length; i < len; i++) { + tile = tiles[i]; + + if (!tile.complete) { + tile.onload = L.Util.falseFn; + tile.onerror = L.Util.falseFn; + tile.src = L.Util.emptyImageUrl; + + tile.parentNode.removeChild(tile); + } + } + } +}); + + +/* + * Provides L.Map with convenient shortcuts for using browser geolocation features. + */ + +L.Map.include({ + _defaultLocateOptions: { + watch: false, + setView: false, + maxZoom: Infinity, + timeout: 10000, + maximumAge: 0, + enableHighAccuracy: false + }, + + locate: function (/*Object*/ options) { + + options = this._locateOptions = L.extend(this._defaultLocateOptions, options); + + if (!navigator.geolocation) { + this._handleGeolocationError({ + code: 0, + message: 'Geolocation not supported.' + }); + return this; + } + + var onResponse = L.bind(this._handleGeolocationResponse, this), + onError = L.bind(this._handleGeolocationError, this); + + if (options.watch) { + this._locationWatchId = + navigator.geolocation.watchPosition(onResponse, onError, options); + } else { + navigator.geolocation.getCurrentPosition(onResponse, onError, options); + } + return this; + }, + + stopLocate: function () { + if (navigator.geolocation) { + navigator.geolocation.clearWatch(this._locationWatchId); + } + if (this._locateOptions) { + this._locateOptions.setView = false; + } + return this; + }, + + _handleGeolocationError: function (error) { + var c = error.code, + message = error.message || + (c === 1 ? 'permission denied' : + (c === 2 ? 'position unavailable' : 'timeout')); + + if (this._locateOptions.setView && !this._loaded) { + this.fitWorld(); + } + + this.fire('locationerror', { + code: c, + message: 'Geolocation error: ' + message + '.' + }); + }, + + _handleGeolocationResponse: function (pos) { + var lat = pos.coords.latitude, + lng = pos.coords.longitude, + latlng = new L.LatLng(lat, lng), + + latAccuracy = 180 * pos.coords.accuracy / 40075017, + lngAccuracy = latAccuracy / Math.cos(L.LatLng.DEG_TO_RAD * lat), + + bounds = L.latLngBounds( + [lat - latAccuracy, lng - lngAccuracy], + [lat + latAccuracy, lng + lngAccuracy]), + + options = this._locateOptions; + + if (options.setView) { + var zoom = Math.min(this.getBoundsZoom(bounds), options.maxZoom); + this.setView(latlng, zoom); + } + + var data = { + latlng: latlng, + bounds: bounds, + timestamp: pos.timestamp + }; + + for (var i in pos.coords) { + if (typeof pos.coords[i] === 'number') { + data[i] = pos.coords[i]; + } + } + + this.fire('locationfound', data); + } +}); + + +}(window, document)); +/* + Leaflet.markercluster, Provides Beautiful Animated Marker Clustering functionality for Leaflet, a JS library for interactive maps. + https://github.com/Leaflet/Leaflet.markercluster + (c) 2012-2013, Dave Leaver, smartrak +*/ + +!function(t,e){L.MarkerClusterGroup=L.FeatureGroup.extend({options:{maxClusterRadius:80,iconCreateFunction:null,spiderfyOnMaxZoom:!0,showCoverageOnHover:!0,zoomToBoundsOnClick:!0,singleMarkerMode:!1,disableClusteringAtZoom:null,removeOutsideVisibleBounds:!0,animateAddingMarkers:!1,spiderfyDistanceMultiplier:1,chunkedLoading:!1,chunkInterval:200,chunkDelay:50,chunkProgress:null,polygonOptions:{}},initialize:function(t){L.Util.setOptions(this,t),this.options.iconCreateFunction||(this.options.iconCreateFunction=this._defaultIconCreateFunction),this._featureGroup=L.featureGroup(),this._featureGroup.on(L.FeatureGroup.EVENTS,this._propagateEvent,this),this._nonPointGroup=L.featureGroup(),this._nonPointGroup.on(L.FeatureGroup.EVENTS,this._propagateEvent,this),this._inZoomAnimation=0,this._needsClustering=[],this._needsRemoving=[],this._currentShownBounds=null,this._queue=[]},addLayer:function(t){if(t instanceof L.LayerGroup){var e=[];for(var i in t._layers)e.push(t._layers[i]);return this.addLayers(e)}if(!t.getLatLng)return this._nonPointGroup.addLayer(t),this;if(!this._map)return this._needsClustering.push(t),this;if(this.hasLayer(t))return this;this._unspiderfy&&this._unspiderfy(),this._addLayer(t,this._maxZoom);var n=t,s=this._map.getZoom();if(t.__parent)for(;n.__parent._zoom>=s;)n=n.__parent;return this._currentShownBounds.contains(n.getLatLng())&&(this.options.animateAddingMarkers?this._animationAddLayer(t,n):this._animationAddLayerNonAnimated(t,n)),this},removeLayer:function(t){if(t instanceof L.LayerGroup){var e=[];for(var i in t._layers)e.push(t._layers[i]);return this.removeLayers(e)}return t.getLatLng?this._map?t.__parent?(this._unspiderfy&&(this._unspiderfy(),this._unspiderfyLayer(t)),this._removeLayer(t,!0),this._featureGroup.hasLayer(t)&&(this._featureGroup.removeLayer(t),t.setOpacity&&t.setOpacity(1)),this):this:(!this._arraySplice(this._needsClustering,t)&&this.hasLayer(t)&&this._needsRemoving.push(t),this):(this._nonPointGroup.removeLayer(t),this)},addLayers:function(t){var e,i,n,s,r=this._featureGroup,o=this._nonPointGroup,a=this.options.chunkedLoading,h=this.options.chunkInterval,_=this.options.chunkProgress;if(this._map){var u=0,l=(new Date).getTime(),d=L.bind(function(){for(var e=(new Date).getTime();u<t.length;u++){if(a&&0===u%200){var i=(new Date).getTime()-e;if(i>h)break}if(s=t[u],s.getLatLng){if(!this.hasLayer(s)&&(this._addLayer(s,this._maxZoom),s.__parent&&2===s.__parent.getChildCount())){var n=s.__parent.getAllChildMarkers(),p=n[0]===s?n[1]:n[0];r.removeLayer(p)}}else o.addLayer(s)}_&&_(u,t.length,(new Date).getTime()-l),u===t.length?(this._featureGroup.eachLayer(function(t){t instanceof L.MarkerCluster&&t._iconNeedsUpdate&&t._updateIcon()}),this._topClusterLevel._recursivelyAddChildrenToMap(null,this._zoom,this._currentShownBounds)):setTimeout(d,this.options.chunkDelay)},this);d()}else{for(e=[],i=0,n=t.length;n>i;i++)s=t[i],s.getLatLng?this.hasLayer(s)||e.push(s):o.addLayer(s);this._needsClustering=this._needsClustering.concat(e)}return this},removeLayers:function(t){var e,i,n,s=this._featureGroup,r=this._nonPointGroup;if(!this._map){for(e=0,i=t.length;i>e;e++)n=t[e],this._arraySplice(this._needsClustering,n),r.removeLayer(n);return this}for(e=0,i=t.length;i>e;e++)n=t[e],n.__parent?(this._removeLayer(n,!0,!0),s.hasLayer(n)&&(s.removeLayer(n),n.setOpacity&&n.setOpacity(1))):r.removeLayer(n);return this._topClusterLevel._recursivelyAddChildrenToMap(null,this._zoom,this._currentShownBounds),s.eachLayer(function(t){t instanceof L.MarkerCluster&&t._updateIcon()}),this},clearLayers:function(){return this._map||(this._needsClustering=[],delete this._gridClusters,delete this._gridUnclustered),this._noanimationUnspiderfy&&this._noanimationUnspiderfy(),this._featureGroup.clearLayers(),this._nonPointGroup.clearLayers(),this.eachLayer(function(t){delete t.__parent}),this._map&&this._generateInitialClusters(),this},getBounds:function(){var t=new L.LatLngBounds;if(this._topClusterLevel)t.extend(this._topClusterLevel._bounds);else for(var e=this._needsClustering.length-1;e>=0;e--)t.extend(this._needsClustering[e].getLatLng());return t.extend(this._nonPointGroup.getBounds()),t},eachLayer:function(t,e){var i,n=this._needsClustering.slice();for(this._topClusterLevel&&this._topClusterLevel.getAllChildMarkers(n),i=n.length-1;i>=0;i--)t.call(e,n[i]);this._nonPointGroup.eachLayer(t,e)},getLayers:function(){var t=[];return this.eachLayer(function(e){t.push(e)}),t},getLayer:function(t){var e=null;return this.eachLayer(function(i){L.stamp(i)===t&&(e=i)}),e},hasLayer:function(t){if(!t)return!1;var e,i=this._needsClustering;for(e=i.length-1;e>=0;e--)if(i[e]===t)return!0;for(i=this._needsRemoving,e=i.length-1;e>=0;e--)if(i[e]===t)return!1;return!(!t.__parent||t.__parent._group!==this)||this._nonPointGroup.hasLayer(t)},zoomToShowLayer:function(t,e){var i=function(){if((t._icon||t.__parent._icon)&&!this._inZoomAnimation)if(this._map.off("moveend",i,this),this.off("animationend",i,this),t._icon)e();else if(t.__parent._icon){var n=function(){this.off("spiderfied",n,this),e()};this.on("spiderfied",n,this),t.__parent.spiderfy()}};t._icon&&this._map.getBounds().contains(t.getLatLng())?e():t.__parent._zoom<this._map.getZoom()?(this._map.on("moveend",i,this),this._map.panTo(t.getLatLng())):(this._map.on("moveend",i,this),this.on("animationend",i,this),this._map.setView(t.getLatLng(),t.__parent._zoom+1),t.__parent.zoomToBounds())},onAdd:function(t){this._map=t;var e,i,n;if(!isFinite(this._map.getMaxZoom()))throw"Map has no maxZoom specified";for(this._featureGroup.onAdd(t),this._nonPointGroup.onAdd(t),this._gridClusters||this._generateInitialClusters(),e=0,i=this._needsRemoving.length;i>e;e++)n=this._needsRemoving[e],this._removeLayer(n,!0);this._needsRemoving=[],this._zoom=this._map.getZoom(),this._currentShownBounds=this._getExpandedVisibleBounds(),this._map.on("zoomend",this._zoomEnd,this),this._map.on("moveend",this._moveEnd,this),this._spiderfierOnAdd&&this._spiderfierOnAdd(),this._bindEvents(),i=this._needsClustering,this._needsClustering=[],this.addLayers(i)},onRemove:function(t){t.off("zoomend",this._zoomEnd,this),t.off("moveend",this._moveEnd,this),this._unbindEvents(),this._map._mapPane.className=this._map._mapPane.className.replace(" leaflet-cluster-anim",""),this._spiderfierOnRemove&&this._spiderfierOnRemove(),this._hideCoverage(),this._featureGroup.onRemove(t),this._nonPointGroup.onRemove(t),this._featureGroup.clearLayers(),this._map=null},getVisibleParent:function(t){for(var e=t;e&&!e._icon;)e=e.__parent;return e||null},_arraySplice:function(t,e){for(var i=t.length-1;i>=0;i--)if(t[i]===e)return t.splice(i,1),!0},_removeLayer:function(t,e,i){var n=this._gridClusters,s=this._gridUnclustered,r=this._featureGroup,o=this._map;if(e)for(var a=this._maxZoom;a>=0&&s[a].removeObject(t,o.project(t.getLatLng(),a));a--);var h,_=t.__parent,u=_._markers;for(this._arraySplice(u,t);_&&(_._childCount--,!(_._zoom<0));)e&&_._childCount<=1?(h=_._markers[0]===t?_._markers[1]:_._markers[0],n[_._zoom].removeObject(_,o.project(_._cLatLng,_._zoom)),s[_._zoom].addObject(h,o.project(h.getLatLng(),_._zoom)),this._arraySplice(_.__parent._childClusters,_),_.__parent._markers.push(h),h.__parent=_.__parent,_._icon&&(r.removeLayer(_),i||r.addLayer(h))):(_._recalculateBounds(),i&&_._icon||_._updateIcon()),_=_.__parent;delete t.__parent},_isOrIsParent:function(t,e){for(;e;){if(t===e)return!0;e=e.parentNode}return!1},_propagateEvent:function(t){if(t.layer instanceof L.MarkerCluster){if(t.originalEvent&&this._isOrIsParent(t.layer._icon,t.originalEvent.relatedTarget))return;t.type="cluster"+t.type}this.fire(t.type,t)},_defaultIconCreateFunction:function(t){var e=t.getChildCount(),i=" marker-cluster-";return i+=10>e?"small":100>e?"medium":"large",new L.DivIcon({html:"<div><span>"+e+"</span></div>",className:"marker-cluster"+i,iconSize:new L.Point(40,40)})},_bindEvents:function(){var t=this._map,e=this.options.spiderfyOnMaxZoom,i=this.options.showCoverageOnHover,n=this.options.zoomToBoundsOnClick;(e||n)&&this.on("clusterclick",this._zoomOrSpiderfy,this),i&&(this.on("clustermouseover",this._showCoverage,this),this.on("clustermouseout",this._hideCoverage,this),t.on("zoomend",this._hideCoverage,this))},_zoomOrSpiderfy:function(t){var e=this._map;e.getMaxZoom()===e.getZoom()?this.options.spiderfyOnMaxZoom&&t.layer.spiderfy():this.options.zoomToBoundsOnClick&&t.layer.zoomToBounds(),t.originalEvent&&13===t.originalEvent.keyCode&&e._container.focus()},_showCoverage:function(t){var e=this._map;this._inZoomAnimation||(this._shownPolygon&&e.removeLayer(this._shownPolygon),t.layer.getChildCount()>2&&t.layer!==this._spiderfied&&(this._shownPolygon=new L.Polygon(t.layer.getConvexHull(),this.options.polygonOptions),e.addLayer(this._shownPolygon)))},_hideCoverage:function(){this._shownPolygon&&(this._map.removeLayer(this._shownPolygon),this._shownPolygon=null)},_unbindEvents:function(){var t=this.options.spiderfyOnMaxZoom,e=this.options.showCoverageOnHover,i=this.options.zoomToBoundsOnClick,n=this._map;(t||i)&&this.off("clusterclick",this._zoomOrSpiderfy,this),e&&(this.off("clustermouseover",this._showCoverage,this),this.off("clustermouseout",this._hideCoverage,this),n.off("zoomend",this._hideCoverage,this))},_zoomEnd:function(){this._map&&(this._mergeSplitClusters(),this._zoom=this._map._zoom,this._currentShownBounds=this._getExpandedVisibleBounds())},_moveEnd:function(){if(!this._inZoomAnimation){var t=this._getExpandedVisibleBounds();this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds,this._zoom,t),this._topClusterLevel._recursivelyAddChildrenToMap(null,this._map._zoom,t),this._currentShownBounds=t}},_generateInitialClusters:function(){var t=this._map.getMaxZoom(),e=this.options.maxClusterRadius,i=e;"function"!=typeof e&&(i=function(){return e}),this.options.disableClusteringAtZoom&&(t=this.options.disableClusteringAtZoom-1),this._maxZoom=t,this._gridClusters={},this._gridUnclustered={};for(var n=t;n>=0;n--)this._gridClusters[n]=new L.DistanceGrid(i(n)),this._gridUnclustered[n]=new L.DistanceGrid(i(n));this._topClusterLevel=new L.MarkerCluster(this,-1)},_addLayer:function(t,e){var i,n,s=this._gridClusters,r=this._gridUnclustered;for(this.options.singleMarkerMode&&(t.options.icon=this.options.iconCreateFunction({getChildCount:function(){return 1},getAllChildMarkers:function(){return[t]}}));e>=0;e--){i=this._map.project(t.getLatLng(),e);var o=s[e].getNearObject(i);if(o)return o._addChild(t),t.__parent=o,void 0;if(o=r[e].getNearObject(i)){var a=o.__parent;a&&this._removeLayer(o,!1);var h=new L.MarkerCluster(this,e,o,t);s[e].addObject(h,this._map.project(h._cLatLng,e)),o.__parent=h,t.__parent=h;var _=h;for(n=e-1;n>a._zoom;n--)_=new L.MarkerCluster(this,n,_),s[n].addObject(_,this._map.project(o.getLatLng(),n));for(a._addChild(_),n=e;n>=0&&r[n].removeObject(o,this._map.project(o.getLatLng(),n));n--);return}r[e].addObject(t,i)}this._topClusterLevel._addChild(t),t.__parent=this._topClusterLevel},_enqueue:function(t){this._queue.push(t),this._queueTimeout||(this._queueTimeout=setTimeout(L.bind(this._processQueue,this),300))},_processQueue:function(){for(var t=0;t<this._queue.length;t++)this._queue[t].call(this);this._queue.length=0,clearTimeout(this._queueTimeout),this._queueTimeout=null},_mergeSplitClusters:function(){this._processQueue(),this._zoom<this._map._zoom&&this._currentShownBounds.contains(this._getExpandedVisibleBounds())?(this._animationStart(),this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds,this._zoom,this._getExpandedVisibleBounds()),this._animationZoomIn(this._zoom,this._map._zoom)):this._zoom>this._map._zoom?(this._animationStart(),this._animationZoomOut(this._zoom,this._map._zoom)):this._moveEnd()},_getExpandedVisibleBounds:function(){if(!this.options.removeOutsideVisibleBounds)return this.getBounds();var t=this._map,e=t.getBounds(),i=e._southWest,n=e._northEast,s=L.Browser.mobile?0:Math.abs(i.lat-n.lat),r=L.Browser.mobile?0:Math.abs(i.lng-n.lng);return new L.LatLngBounds(new L.LatLng(i.lat-s,i.lng-r,!0),new L.LatLng(n.lat+s,n.lng+r,!0))},_animationAddLayerNonAnimated:function(t,e){if(e===t)this._featureGroup.addLayer(t);else if(2===e._childCount){e._addToMap();var i=e.getAllChildMarkers();this._featureGroup.removeLayer(i[0]),this._featureGroup.removeLayer(i[1])}else e._updateIcon()}}),L.MarkerClusterGroup.include(L.DomUtil.TRANSITION?{_animationStart:function(){this._map._mapPane.className+=" leaflet-cluster-anim",this._inZoomAnimation++},_animationEnd:function(){this._map&&(this._map._mapPane.className=this._map._mapPane.className.replace(" leaflet-cluster-anim","")),this._inZoomAnimation--,this.fire("animationend")},_animationZoomIn:function(t,e){var i,n=this._getExpandedVisibleBounds(),s=this._featureGroup;this._topClusterLevel._recursively(n,t,0,function(r){var o,a=r._latlng,h=r._markers;for(n.contains(a)||(a=null),r._isSingleParent()&&t+1===e?(s.removeLayer(r),r._recursivelyAddChildrenToMap(null,e,n)):(r.setOpacity(0),r._recursivelyAddChildrenToMap(a,e,n)),i=h.length-1;i>=0;i--)o=h[i],n.contains(o._latlng)||s.removeLayer(o)}),this._forceLayout(),this._topClusterLevel._recursivelyBecomeVisible(n,e),s.eachLayer(function(t){t instanceof L.MarkerCluster||!t._icon||t.setOpacity(1)}),this._topClusterLevel._recursively(n,t,e,function(t){t._recursivelyRestoreChildPositions(e)}),this._enqueue(function(){this._topClusterLevel._recursively(n,t,0,function(t){s.removeLayer(t),t.setOpacity(1)}),this._animationEnd()})},_animationZoomOut:function(t,e){this._animationZoomOutSingle(this._topClusterLevel,t-1,e),this._topClusterLevel._recursivelyAddChildrenToMap(null,e,this._getExpandedVisibleBounds()),this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds,t,this._getExpandedVisibleBounds())},_animationZoomOutSingle:function(t,e,i){var n=this._getExpandedVisibleBounds();t._recursivelyAnimateChildrenInAndAddSelfToMap(n,e+1,i);var s=this;this._forceLayout(),t._recursivelyBecomeVisible(n,i),this._enqueue(function(){if(1===t._childCount){var r=t._markers[0];r.setLatLng(r.getLatLng()),r.setOpacity&&r.setOpacity(1)}else t._recursively(n,i,0,function(t){t._recursivelyRemoveChildrenFromMap(n,e+1)});s._animationEnd()})},_animationAddLayer:function(t,e){var i=this,n=this._featureGroup;n.addLayer(t),e!==t&&(e._childCount>2?(e._updateIcon(),this._forceLayout(),this._animationStart(),t._setPos(this._map.latLngToLayerPoint(e.getLatLng())),t.setOpacity(0),this._enqueue(function(){n.removeLayer(t),t.setOpacity(1),i._animationEnd()})):(this._forceLayout(),i._animationStart(),i._animationZoomOutSingle(e,this._map.getMaxZoom(),this._map.getZoom())))},_forceLayout:function(){L.Util.falseFn(e.body.offsetWidth)}}:{_animationStart:function(){},_animationZoomIn:function(t,e){this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds,t),this._topClusterLevel._recursivelyAddChildrenToMap(null,e,this._getExpandedVisibleBounds()),this.fire("animationend")},_animationZoomOut:function(t,e){this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds,t),this._topClusterLevel._recursivelyAddChildrenToMap(null,e,this._getExpandedVisibleBounds()),this.fire("animationend")},_animationAddLayer:function(t,e){this._animationAddLayerNonAnimated(t,e)}}),L.markerClusterGroup=function(t){return new L.MarkerClusterGroup(t)},L.MarkerCluster=L.Marker.extend({initialize:function(t,e,i,n){L.Marker.prototype.initialize.call(this,i?i._cLatLng||i.getLatLng():new L.LatLng(0,0),{icon:this}),this._group=t,this._zoom=e,this._markers=[],this._childClusters=[],this._childCount=0,this._iconNeedsUpdate=!0,this._bounds=new L.LatLngBounds,i&&this._addChild(i),n&&this._addChild(n)},getAllChildMarkers:function(t){t=t||[];for(var e=this._childClusters.length-1;e>=0;e--)this._childClusters[e].getAllChildMarkers(t);for(var i=this._markers.length-1;i>=0;i--)t.push(this._markers[i]);return t},getChildCount:function(){return this._childCount},zoomToBounds:function(){for(var t,e=this._childClusters.slice(),i=this._group._map,n=i.getBoundsZoom(this._bounds),s=this._zoom+1,r=i.getZoom();e.length>0&&n>s;){s++;var o=[];for(t=0;t<e.length;t++)o=o.concat(e[t]._childClusters);e=o}n>s?this._group._map.setView(this._latlng,s):r>=n?this._group._map.setView(this._latlng,r+1):this._group._map.fitBounds(this._bounds)},getBounds:function(){var t=new L.LatLngBounds;return t.extend(this._bounds),t},_updateIcon:function(){this._iconNeedsUpdate=!0,this._icon&&this.setIcon(this)},createIcon:function(){return this._iconNeedsUpdate&&(this._iconObj=this._group.options.iconCreateFunction(this),this._iconNeedsUpdate=!1),this._iconObj.createIcon()},createShadow:function(){return this._iconObj.createShadow()},_addChild:function(t,e){this._iconNeedsUpdate=!0,this._expandBounds(t),t instanceof L.MarkerCluster?(e||(this._childClusters.push(t),t.__parent=this),this._childCount+=t._childCount):(e||this._markers.push(t),this._childCount++),this.__parent&&this.__parent._addChild(t,!0)},_expandBounds:function(t){var e,i=t._wLatLng||t._latlng;t instanceof L.MarkerCluster?(this._bounds.extend(t._bounds),e=t._childCount):(this._bounds.extend(i),e=1),this._cLatLng||(this._cLatLng=t._cLatLng||i);var n=this._childCount+e;this._wLatLng?(this._wLatLng.lat=(i.lat*e+this._wLatLng.lat*this._childCount)/n,this._wLatLng.lng=(i.lng*e+this._wLatLng.lng*this._childCount)/n):this._latlng=this._wLatLng=new L.LatLng(i.lat,i.lng)},_addToMap:function(t){t&&(this._backupLatlng=this._latlng,this.setLatLng(t)),this._group._featureGroup.addLayer(this)},_recursivelyAnimateChildrenIn:function(t,e,i){this._recursively(t,0,i-1,function(t){var i,n,s=t._markers;for(i=s.length-1;i>=0;i--)n=s[i],n._icon&&(n._setPos(e),n.setOpacity(0))},function(t){var i,n,s=t._childClusters;for(i=s.length-1;i>=0;i--)n=s[i],n._icon&&(n._setPos(e),n.setOpacity(0))})},_recursivelyAnimateChildrenInAndAddSelfToMap:function(t,e,i){this._recursively(t,i,0,function(n){n._recursivelyAnimateChildrenIn(t,n._group._map.latLngToLayerPoint(n.getLatLng()).round(),e),n._isSingleParent()&&e-1===i?(n.setOpacity(1),n._recursivelyRemoveChildrenFromMap(t,e)):n.setOpacity(0),n._addToMap()})},_recursivelyBecomeVisible:function(t,e){this._recursively(t,0,e,null,function(t){t.setOpacity(1)})},_recursivelyAddChildrenToMap:function(t,e,i){this._recursively(i,-1,e,function(n){if(e!==n._zoom)for(var s=n._markers.length-1;s>=0;s--){var r=n._markers[s];i.contains(r._latlng)&&(t&&(r._backupLatlng=r.getLatLng(),r.setLatLng(t),r.setOpacity&&r.setOpacity(0)),n._group._featureGroup.addLayer(r))}},function(e){e._addToMap(t)})},_recursivelyRestoreChildPositions:function(t){for(var e=this._markers.length-1;e>=0;e--){var i=this._markers[e];i._backupLatlng&&(i.setLatLng(i._backupLatlng),delete i._backupLatlng)}if(t-1===this._zoom)for(var n=this._childClusters.length-1;n>=0;n--)this._childClusters[n]._restorePosition();else for(var s=this._childClusters.length-1;s>=0;s--)this._childClusters[s]._recursivelyRestoreChildPositions(t)},_restorePosition:function(){this._backupLatlng&&(this.setLatLng(this._backupLatlng),delete this._backupLatlng)},_recursivelyRemoveChildrenFromMap:function(t,e,i){var n,s;this._recursively(t,-1,e-1,function(t){for(s=t._markers.length-1;s>=0;s--)n=t._markers[s],i&&i.contains(n._latlng)||(t._group._featureGroup.removeLayer(n),n.setOpacity&&n.setOpacity(1))},function(t){for(s=t._childClusters.length-1;s>=0;s--)n=t._childClusters[s],i&&i.contains(n._latlng)||(t._group._featureGroup.removeLayer(n),n.setOpacity&&n.setOpacity(1))})},_recursively:function(t,e,i,n,s){var r,o,a=this._childClusters,h=this._zoom;if(e>h)for(r=a.length-1;r>=0;r--)o=a[r],t.intersects(o._bounds)&&o._recursively(t,e,i,n,s);else if(n&&n(this),s&&this._zoom===i&&s(this),i>h)for(r=a.length-1;r>=0;r--)o=a[r],t.intersects(o._bounds)&&o._recursively(t,e,i,n,s)},_recalculateBounds:function(){var t,e=this._markers,i=this._childClusters;for(this._bounds=new L.LatLngBounds,delete this._wLatLng,t=e.length-1;t>=0;t--)this._expandBounds(e[t]);for(t=i.length-1;t>=0;t--)this._expandBounds(i[t])},_isSingleParent:function(){return this._childClusters.length>0&&this._childClusters[0]._childCount===this._childCount}}),L.DistanceGrid=function(t){this._cellSize=t,this._sqCellSize=t*t,this._grid={},this._objectPoint={}},L.DistanceGrid.prototype={addObject:function(t,e){var i=this._getCoord(e.x),n=this._getCoord(e.y),s=this._grid,r=s[n]=s[n]||{},o=r[i]=r[i]||[],a=L.Util.stamp(t);this._objectPoint[a]=e,o.push(t)},updateObject:function(t,e){this.removeObject(t),this.addObject(t,e)},removeObject:function(t,e){var i,n,s=this._getCoord(e.x),r=this._getCoord(e.y),o=this._grid,a=o[r]=o[r]||{},h=a[s]=a[s]||[];for(delete this._objectPoint[L.Util.stamp(t)],i=0,n=h.length;n>i;i++)if(h[i]===t)return h.splice(i,1),1===n&&delete a[s],!0},eachObject:function(t,e){var i,n,s,r,o,a,h,_=this._grid;for(i in _){o=_[i];for(n in o)for(a=o[n],s=0,r=a.length;r>s;s++)h=t.call(e,a[s]),h&&(s--,r--)}},getNearObject:function(t){var e,i,n,s,r,o,a,h,_=this._getCoord(t.x),u=this._getCoord(t.y),l=this._objectPoint,d=this._sqCellSize,p=null;for(e=u-1;u+1>=e;e++)if(s=this._grid[e])for(i=_-1;_+1>=i;i++)if(r=s[i])for(n=0,o=r.length;o>n;n++)a=r[n],h=this._sqDist(l[L.Util.stamp(a)],t),d>h&&(d=h,p=a);return p},_getCoord:function(t){return Math.floor(t/this._cellSize)},_sqDist:function(t,e){var i=e.x-t.x,n=e.y-t.y;return i*i+n*n}},function(){L.QuickHull={getDistant:function(t,e){var i=e[1].lat-e[0].lat,n=e[0].lng-e[1].lng;return n*(t.lat-e[0].lat)+i*(t.lng-e[0].lng)},findMostDistantPointFromBaseLine:function(t,e){var i,n,s,r=0,o=null,a=[];for(i=e.length-1;i>=0;i--)n=e[i],s=this.getDistant(n,t),s>0&&(a.push(n),s>r&&(r=s,o=n));return{maxPoint:o,newPoints:a}},buildConvexHull:function(t,e){var i=[],n=this.findMostDistantPointFromBaseLine(t,e);return n.maxPoint?(i=i.concat(this.buildConvexHull([t[0],n.maxPoint],n.newPoints)),i=i.concat(this.buildConvexHull([n.maxPoint,t[1]],n.newPoints))):[t[0]]},getConvexHull:function(t){var e,i=!1,n=!1,s=null,r=null;for(e=t.length-1;e>=0;e--){var o=t[e];(i===!1||o.lat>i)&&(s=o,i=o.lat),(n===!1||o.lat<n)&&(r=o,n=o.lat)}var a=[].concat(this.buildConvexHull([r,s],t),this.buildConvexHull([s,r],t));return a}}}(),L.MarkerCluster.include({getConvexHull:function(){var t,e,i=this.getAllChildMarkers(),n=[];for(e=i.length-1;e>=0;e--)t=i[e].getLatLng(),n.push(t);return L.QuickHull.getConvexHull(n)}}),L.MarkerCluster.include({_2PI:2*Math.PI,_circleFootSeparation:25,_circleStartAngle:Math.PI/6,_spiralFootSeparation:28,_spiralLengthStart:11,_spiralLengthFactor:5,_circleSpiralSwitchover:9,spiderfy:function(){if(this._group._spiderfied!==this&&!this._group._inZoomAnimation){var t,e=this.getAllChildMarkers(),i=this._group,n=i._map,s=n.latLngToLayerPoint(this._latlng);this._group._unspiderfy(),this._group._spiderfied=this,e.length>=this._circleSpiralSwitchover?t=this._generatePointsSpiral(e.length,s):(s.y+=10,t=this._generatePointsCircle(e.length,s)),this._animationSpiderfy(e,t)}},unspiderfy:function(t){this._group._inZoomAnimation||(this._animationUnspiderfy(t),this._group._spiderfied=null)},_generatePointsCircle:function(t,e){var i,n,s=this._group.options.spiderfyDistanceMultiplier*this._circleFootSeparation*(2+t),r=s/this._2PI,o=this._2PI/t,a=[];for(a.length=t,i=t-1;i>=0;i--)n=this._circleStartAngle+i*o,a[i]=new L.Point(e.x+r*Math.cos(n),e.y+r*Math.sin(n))._round();return a},_generatePointsSpiral:function(t,e){var i,n=this._group.options.spiderfyDistanceMultiplier*this._spiralLengthStart,s=this._group.options.spiderfyDistanceMultiplier*this._spiralFootSeparation,r=this._group.options.spiderfyDistanceMultiplier*this._spiralLengthFactor,o=0,a=[];for(a.length=t,i=t-1;i>=0;i--)o+=s/n+5e-4*i,a[i]=new L.Point(e.x+n*Math.cos(o),e.y+n*Math.sin(o))._round(),n+=this._2PI*r/o;return a},_noanimationUnspiderfy:function(){var t,e,i=this._group,n=i._map,s=i._featureGroup,r=this.getAllChildMarkers();for(this.setOpacity(1),e=r.length-1;e>=0;e--)t=r[e],s.removeLayer(t),t._preSpiderfyLatlng&&(t.setLatLng(t._preSpiderfyLatlng),delete t._preSpiderfyLatlng),t.setZIndexOffset&&t.setZIndexOffset(0),t._spiderLeg&&(n.removeLayer(t._spiderLeg),delete t._spiderLeg);i._spiderfied=null}}),L.MarkerCluster.include(L.DomUtil.TRANSITION?{SVG_ANIMATION:function(){return e.createElementNS("http://www.w3.org/2000/svg","animate").toString().indexOf("SVGAnimate")>-1}(),_animationSpiderfy:function(t,i){var n,s,r,o,a=this,h=this._group,_=h._map,u=h._featureGroup,l=_.latLngToLayerPoint(this._latlng);for(n=t.length-1;n>=0;n--)s=t[n],s.setOpacity?(s.setZIndexOffset(1e6),s.setOpacity(0),u.addLayer(s),s._setPos(l)):u.addLayer(s);h._forceLayout(),h._animationStart();var d=L.Path.SVG?0:.3,p=L.Path.SVG_NS;for(n=t.length-1;n>=0;n--)if(o=_.layerPointToLatLng(i[n]),s=t[n],s._preSpiderfyLatlng=s._latlng,s.setLatLng(o),s.setOpacity&&s.setOpacity(1),r=new L.Polyline([a._latlng,o],{weight:1.5,color:"#222",opacity:d}),_.addLayer(r),s._spiderLeg=r,L.Path.SVG&&this.SVG_ANIMATION){var c=r._path.getTotalLength();r._path.setAttribute("stroke-dasharray",c+","+c);var m=e.createElementNS(p,"animate");m.setAttribute("attributeName","stroke-dashoffset"),m.setAttribute("begin","indefinite"),m.setAttribute("from",c),m.setAttribute("to",0),m.setAttribute("dur",.25),r._path.appendChild(m),m.beginElement(),m=e.createElementNS(p,"animate"),m.setAttribute("attributeName","stroke-opacity"),m.setAttribute("attributeName","stroke-opacity"),m.setAttribute("begin","indefinite"),m.setAttribute("from",0),m.setAttribute("to",.5),m.setAttribute("dur",.25),r._path.appendChild(m),m.beginElement()}if(a.setOpacity(.3),L.Path.SVG)for(this._group._forceLayout(),n=t.length-1;n>=0;n--)s=t[n]._spiderLeg,s.options.opacity=.5,s._path.setAttribute("stroke-opacity",.5);setTimeout(function(){h._animationEnd(),h.fire("spiderfied")},200)},_animationUnspiderfy:function(t){var e,i,n,s=this._group,r=s._map,o=s._featureGroup,a=t?r._latLngToNewLayerPoint(this._latlng,t.zoom,t.center):r.latLngToLayerPoint(this._latlng),h=this.getAllChildMarkers(),_=L.Path.SVG&&this.SVG_ANIMATION;for(s._animationStart(),this.setOpacity(1),i=h.length-1;i>=0;i--)e=h[i],e._preSpiderfyLatlng&&(e.setLatLng(e._preSpiderfyLatlng),delete e._preSpiderfyLatlng,e.setOpacity?(e._setPos(a),e.setOpacity(0)):o.removeLayer(e),_&&(n=e._spiderLeg._path.childNodes[0],n.setAttribute("to",n.getAttribute("from")),n.setAttribute("from",0),n.beginElement(),n=e._spiderLeg._path.childNodes[1],n.setAttribute("from",.5),n.setAttribute("to",0),n.setAttribute("stroke-opacity",0),n.beginElement(),e._spiderLeg._path.setAttribute("stroke-opacity",0)));setTimeout(function(){var t=0;for(i=h.length-1;i>=0;i--)e=h[i],e._spiderLeg&&t++;for(i=h.length-1;i>=0;i--)e=h[i],e._spiderLeg&&(e.setOpacity&&(e.setOpacity(1),e.setZIndexOffset(0)),t>1&&o.removeLayer(e),r.removeLayer(e._spiderLeg),delete e._spiderLeg);s._animationEnd()},200)}}:{_animationSpiderfy:function(t,e){var i,n,s,r,o=this._group,a=o._map,h=o._featureGroup;for(i=t.length-1;i>=0;i--)r=a.layerPointToLatLng(e[i]),n=t[i],n._preSpiderfyLatlng=n._latlng,n.setLatLng(r),n.setZIndexOffset&&n.setZIndexOffset(1e6),h.addLayer(n),s=new L.Polyline([this._latlng,r],{weight:1.5,color:"#222"}),a.addLayer(s),n._spiderLeg=s;this.setOpacity(.3),o.fire("spiderfied")},_animationUnspiderfy:function(){this._noanimationUnspiderfy()}}),L.MarkerClusterGroup.include({_spiderfied:null,_spiderfierOnAdd:function(){this._map.on("click",this._unspiderfyWrapper,this),this._map.options.zoomAnimation&&this._map.on("zoomstart",this._unspiderfyZoomStart,this),this._map.on("zoomend",this._noanimationUnspiderfy,this),L.Path.SVG&&!L.Browser.touch&&this._map._initPathRoot()},_spiderfierOnRemove:function(){this._map.off("click",this._unspiderfyWrapper,this),this._map.off("zoomstart",this._unspiderfyZoomStart,this),this._map.off("zoomanim",this._unspiderfyZoomAnim,this),this._unspiderfy()},_unspiderfyZoomStart:function(){this._map&&this._map.on("zoomanim",this._unspiderfyZoomAnim,this)},_unspiderfyZoomAnim:function(t){L.DomUtil.hasClass(this._map._mapPane,"leaflet-touching")||(this._map.off("zoomanim",this._unspiderfyZoomAnim,this),this._unspiderfy(t))},_unspiderfyWrapper:function(){this._unspiderfy()},_unspiderfy:function(t){this._spiderfied&&this._spiderfied.unspiderfy(t)},_noanimationUnspiderfy:function(){this._spiderfied&&this._spiderfied._noanimationUnspiderfy()},_unspiderfyLayer:function(t){t._spiderLeg&&(this._featureGroup.removeLayer(t),t.setOpacity(1),t.setZIndexOffset(0),this._map.removeLayer(t._spiderLeg),delete t._spiderLeg)}})}(window,document); +/* + Leaflet.AwesomeMarkers, a plugin that adds colorful iconic markers for Leaflet, based on the Font Awesome icons + (c) 2012-2013, Lennard Voogdt + + http://leafletjs.com + https://github.com/lvoogdt +*/ + +/*global L*/ + + +(function (window, document, undefined) { + "use strict"; + /* + * Leaflet.AwesomeMarkers assumes that you have already included the Leaflet library. + */ + + L.AwesomeMarkers = {}; + + L.AwesomeMarkers.version = '2.0.1'; + + L.AwesomeMarkers.Icon = L.Icon.extend({ + options: { + iconSize: [35, 45], + iconAnchor: [17, 42], + popupAnchor: [1, -32], + shadowAnchor: [10, 12], + shadowSize: [36, 16], + className: 'awesome-marker', + prefix: 'glyphicon', + spinClass: 'fa-spin', + extraClasses: '', + icon: 'home', + markerColor: 'blue', + iconColor: 'white' + }, + + initialize: function (options) { + options = L.Util.setOptions(this, options); + }, + + createIcon: function () { + var div = document.createElement('div'), + options = this.options; + + if (options.icon) { + div.innerHTML = this._createInner(); + } + + if (options.bgPos) { + div.style.backgroundPosition = + (-options.bgPos.x) + 'px ' + (-options.bgPos.y) + 'px'; + } + + this._setIconStyles(div, 'icon-' + options.markerColor); + return div; + }, + + _createInner: function() { + var iconClass, iconSpinClass = "", iconColorClass = "", iconColorStyle = "", options = this.options; + + if(options.icon.slice(0,options.prefix.length+1) === options.prefix + "-") { + iconClass = options.icon; + } else { + iconClass = options.prefix + "-" + options.icon; + } + + if(options.spin && typeof options.spinClass === "string") { + iconSpinClass = options.spinClass; + } + + if(options.iconColor) { + if(options.iconColor === 'white' || options.iconColor === 'black') { + iconColorClass = "icon-" + options.iconColor; + } else { + iconColorStyle = "style='color: " + options.iconColor + "' "; + } + } + + return "<i " + iconColorStyle + "class='" + options.extraClasses + " " + options.prefix + " " + iconClass + " " + iconSpinClass + " " + iconColorClass + "'></i>"; + }, + + _setIconStyles: function (img, name) { + var options = this.options, + size = L.point(options[name === 'shadow' ? 'shadowSize' : 'iconSize']), + anchor; + + if (name === 'shadow') { + anchor = L.point(options.shadowAnchor || options.iconAnchor); + } else { + anchor = L.point(options.iconAnchor); + } + + if (!anchor && size) { + anchor = size.divideBy(2, true); + } + + img.className = 'awesome-marker-' + name + ' ' + options.className; + + if (anchor) { + img.style.marginLeft = (-anchor.x) + 'px'; + img.style.marginTop = (-anchor.y) + 'px'; + } + + if (size) { + img.style.width = size.x + 'px'; + img.style.height = size.y + 'px'; + } + }, + + createShadow: function () { + var div = document.createElement('div'); + + this._setIconStyles(div, 'shadow'); + return div; + } + }); + + L.AwesomeMarkers.icon = function (options) { + return new L.AwesomeMarkers.Icon(options); + }; + +}(this, document)); + + + +(function() { + $(document).on('turbolinks:load', function() { + if ($('#event_repeat').val() === '0') { + $('.field.rule').hide(); + } + return $('#event_repeat').change(function() { + if ($(this).val() > 0) { + $('.field.rule').show(); + } else { + $('.field.rule').hide(); + } + $('#event_tags').each(function() { + var elt; + elt = $(this); + return $.ajax({ + url: '/tags.json' + }).done(function(data) { + var tags; + tags = jQuery.map(data, function(n) { + return n[0]; + }); + return elt.select2({ + tags: tags, + separator: [' '], + tokenSeparators: [' '] + }); + }); + }); + $('label[for=event_tags]').attr('for', 's2id_autogen1'); + $('#event_start_time').change(function() { + if ($('#event_start_time').val() >= $('#event_end_time').val()) { + return $('#event_end_time').val($('#event_start_time').val()); + } + }); + return $('#event_end_time').change(function() { + if ($('#event_start_time').val() >= $('#event_end_time').val()) { + return $('#event_start_time').val($('#event_end_time').val()); + } + }); + }); + }); + +}).call(this); +(function() { + $(document).on('turbolinks:load', function() {}); + +}).call(this); +(function() { + $(document).on('turbolinks:load', function() {}); + +}).call(this); +(function() { + var modulo = function(a, b) { return (+a % (b = +b) + b) % b; }; + + $(document).on('turbolinks:load', function() { + var idx, markerColors; + markerColors = ['blue', 'red', 'darkred', 'orange', 'green', 'darkgreen', 'purple', 'darkpuple', 'cadetblue']; + idx = 0; + $('#map.list').each(function() { + var controls, map; + map = L.map('map'); + L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { + attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a>' + }).addTo(map); + controls = L.control.layers(null, null, { + collapsed: false + }).addTo(map); + return $('li a', this).each(function() { + var markerColor, text, url; + url = $(this).attr('href'); + text = $(this).html(); + markerColor = markerColors[modulo(idx++, markerColors.length)]; + if (location.search && url.indexOf('?') >= 0) { + url += '&' + location.search.substr(1); + } else { + url += location.search; + } + return $.getJSON(url, function(json) { + var layer; + if (json) { + layer = L.markerClusterGroup({ + maxClusterRadius: 30 + }).addLayer(L.geoJson(json, { + pointToLayer: function(feature, latlng) { + var marker; + marker = L.AwesomeMarkers.icon({ + prefix: 'fa', + icon: feature.properties.icon || 'calendar', + markerColor: markerColor + }); + return L.marker(latlng, { + icon: marker + }); + }, + onEachFeature: function(feature, layer) { + if (feature.properties && feature.properties.popupContent) { + return layer.bindPopup(feature.properties.popupContent); + } + } + })); + map.addLayer(layer); + controls.addOverlay(layer, text + ' - ' + json.length); + if ((/maps\//.test(location.href) || /maps.json/.test(url)) && layer.getBounds()._northEast && layer.getBounds()._southWest) { + return map.fitBounds(layer.getBounds()); + } + } + }); + }); + }); + return $('#map.event, #map.orga').each(function() { + var coord, map, marker, markerColor, url; + coord = [$(this).data('latitude'), $(this).data('longitude')]; + map = L.map('map').setView([coord[0], coord[1]], 16); + L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { + attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a>' + }).addTo(map); + url = $(this).data('url'); + markerColor = markerColors[modulo(idx++, markerColors.length)]; + if (location.search && url.indexOf('?') >= 0) { + url += '&' + location.search.substr(1); + } else { + url += location.search; + } + marker = L.AwesomeMarkers.icon({ + prefix: 'fa', + icon: 'calendar' + }); + L.marker([coord[0], coord[1]], { + icon: marker + }).addTo(map); + return $.getJSON(url, function(json) { + var layer; + layer = L.markerClusterGroup({ + maxClusterRadius: 30 + }).addLayer(L.geoJson(json, { + pointToLayer: function(feature, latlng) { + marker = L.AwesomeMarkers.icon({ + prefix: 'fa', + icon: feature.properties.icon || 'calendar', + markerColor: markerColor + }); + return L.marker(latlng, { + icon: marker + }); + }, + onEachFeature: function(feature, layer) { + if (feature.properties && feature.properties.popupContent) { + return layer.bindPopup(feature.properties.popupContent); + } + } + })); + return map.addLayer(layer); + }); + }); + }); + +}).call(this); +(function() { + $(document).on('turbolinks:load', function() { + $('body.moderations .field.closer input[type=radio]').click(function() { + return $('body.moderations #event_reason').parent().slideUp(); + }); + return $('body.moderations .field.opener input[type=radio]').click(function() { + return $('body.moderations #event_reason').parent().slideDown(); + }); + }); + +}).call(this); +(function() { + + +}).call(this); +(function() { + $(document).on('turbolinks:load', function() { + $('#orga_tags').each(function() { + var elt; + elt = $(this); + return $.ajax({ + url: '/tags/orgas.json' + }).done(function(data) { + var tags; + tags = jQuery.map(data, function(n) { + return n[0]; + }); + return elt.select2({ + tags: tags, + separator: [' '], + tokenSeparators: [' '] + }); + }); + }); + return $('label[for=orga_tags]').attr('for', 's2id_autogen1'); + }); + +}).call(this); +(function() { + var pager; + + pager = true; + + $(document).on('turbolinks:load', function() { + $('.pagination .next a').attr('data-remote', true).click(function() { + return $('#loading').fadeIn(); + }); + if (pager) { + pager = false; + $(document).on('ajax:success', '.pagination .next a', function(event, data, status, xhr) { + var elts, next; + $('#loading').fadeOut(); + elts = $('tbody tr', data); + $(this).parents('tfoot').prev().append(elts); + next = $('.pagination .next a', data).attr('href'); + if (next != null) { + return $(this).show().data('remote', true).attr('href', next); + } else { + return $(this).parents('.pagination').remove(); + } + }); + } + if ($('.pagination .next a').size() > 0) { + return $(document).scroll(function() { + if ($(window).scrollTop() === $(document).height() - $(window).height() && $('.pagination .next a').is(':visible')) { + return $('.pagination .next a').hide().click(); + } + }); + } + }); + +}).call(this); +(function() { + $(document).on('turbolinks:load', function() { + $('table.list.dates tbody tr').each(function() { + var vals; + vals = $(this).find('td.quantity').map(function() { + var val; + val = $(this).find('a').html().replace(' ', '').trim(); + if (val && val !== '') { + return parseInt(val); + } else { + return 0; + } + }); + return $(this).find('.sparkline').sparkline(vals, { + width: '5em' + }); + }); + return $('table.list.dates tfoot').each(function() { + var vals; + vals = $(this).find('th.quantity').map(function() { + return parseInt($(this).html().replace(' ', '')); + }); + return $(this).find('.sparkline').sparkline(vals, { + type: 'bar', + height: '3em', + barWidth: '100%', + barColor: '#9CC5EE', + barSpacing: 2 + }); + }); + }); + +}).call(this); +(function() { + $(document).on('turbolinks:load', function() { + return tinyMCE.init({ + schema: 'html5', + menubar: false, + language: 'fr_FR', + selector: 'textarea.description', + content_css: '/assets/application-2fb50a7174d540a1e61def8f3733ef9b16048a46d710d6b766260ee4589d4840.css', + entity_encoding: 'raw', + add_unload_trigger: true, + browser_spellcheck: true, + toolbar: [' bold italic strikethrough | bullist numlist outdent indent | alignleft aligncenter alignright alignjustify | link image media insertdatetime charmap table | undo redo | searchreplace | code visualblocks preview fullscreen'], + plugins: 'lists, advlist, autolink, link, image, charmap, paste, print, preview, table, fullscreen, searchreplace, media, insertdatetime, visualblocks, visualchars, wordcount, contextmenu, code' + }); + }); + + $(document).on('turbolinks:before-cache', function() { + return tinymce.remove(); + }); + +}).call(this); +(function() { + + +}).call(this); +(function() { + $.webshims.setOptions('basePath', '/webshims/1.15.10/shims/'); + + $.webshims.setOptions('forms-ext', { + 'widgets': { + 'startView': 2, + 'stepfactor': 10, + 'classes': 'show-yearbtns hide-btnrow show-uparrow' + } + }); + + $.webshims.polyfill('forms forms-ext'); + + $(document).on('turbolinks:load', function() { + $(this).updatePolyfill(); + if (!Modernizr.testAllProps('forceBrokenImageIcon')) { + return $('img.favicon').one('error', function() { + return $(this).css({ + visibility: 'hidden' + }); + }); + } + }); + +}).call(this); diff --git a/public/assets/application-e0182820be578ba7db1bc56b9933acaa65e9d2ec18d340e667afe68de5d750cc.js.gz b/public/assets/application-e0182820be578ba7db1bc56b9933acaa65e9d2ec18d340e667afe68de5d750cc.js.gz new file mode 100644 index 0000000000000000000000000000000000000000..a32b78c37cd0159f74608f418fc35ee94a3e3047 GIT binary patch literal 532298 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π#Nn)<&prC-Yi*=f~bq8p8=2gNicwB5R%~W!(eG{&r2v%ez)fmz8o%*h<TJQ znpM<<j<pIyNJmeD0sh$-m9HJ}X;5$qPv~ku;<avhV5MKuWKkkQyL~C$qA;Xg>FJ(M z%Q!!LxE4|9%B;W$JZHBp5igjFV_w(!vf$LL2(lu>LAg+b(nFi%%3^e^J*Z-EkifOr zN|2PPJ<EurjClL#kt=bsu$ezA7Bjg>9lM?`WLMdJ&B`oy8V%$5*<1zfjI(5{h3u3V z7s#O?Omy!hyas7^rnOPekc+gSjbIQuaoNa@x&Hbn5dJTciID>gA6_~vNYd*e`a1ZL zfWS;FXl@~Of{6eCD>dhpO5dqnX!8*M996I@Qgkd~t4*>bKc)1(4+evOY#zfY96f$# zaj}ssFsRZ797i_BdA^aI&ElLDmF&5qA8N*V6~EDmp7atasPof#2lwXAc?YDn`$2-C zI%ZeF{Y~qfqGG(U)|2if_fO-vuqVM=u-ofHpAIl!_XuxD8)S40&^WT8$<%%wveD>R zn+;Uy3k5XY<ZMDKmQF~)g9EM1^YY^AAUeU2mfa49Anx?=(tv|)y*y23lP<umwsfex ztn}!2ed<{MLwx)(DV_t2C?i*EL^1288P69~K;imX&`B1HI794ofJpckhHmQ|Rj_5# z&U;Quf%nenez>8+pQBy>G#Yb|y<iH5*gQf1LKUWEnI-cCUAJ>_I-V~2T!h@4bs8sY zFzFB&;yw3{h#VTK0FqUDW4HRb$X{k|Ng4>s{VGh%SZ6G<8~yytuldjC?7h_K^*je% zuIW1_vmINlB2g5PS*7}feKIua_IzMPbk$n8vWy9sts?!9c^XtMpwlR4udNEZlL$lg zgz4#JPZwYKsd=g_J$JL;zj@uN&GY%p)nKn-g}e8r5*LzeH2i5)A-{I4tbOvm-E;ZA zFOz$5=LOl-2_iaq$z?~#8qZ*PS5}I971YtSIRKfK%7yqoW*l;mPT4J~QkM5s^0)WC z%D!TnM@!dz4&A+w*{1kI>2}N$huW=Cv!0*=YUz?m_zq)<6!z|7@t*S26<1h^q<6tq z>H0)toA?Rd^~rSL-L%^o0w;Zncc8vo0W$j>Q6(W!4?7-xC6xuXPiYPLQHs*o2b8Wi zb{BLpe}%$zDbUN}wSc!uz*`l-b#S-p;XXK`OPuAQ|K35(6`#`RXRqm=<hpukI42T< ze;pT!Iz5!ncu!z0ZS8)M?CLB%ql@lz*k)r@#dT6rsCKs0$*!wT%5qSLe5=tTA-eXa z$#HD;U-_$Ex*#cuww#<gvDPMNRSSez|7DXR=_ex*dw{aI3UYiZUiO-=gCwclOw)hu zV)+g|TUEvXGF_a<3s&+=LJ>@ky7V)Xq!M^7ZlkI0B@d(`CLh<Gw_CHwcvgG${Y5;Z zEi1P5VMKG{Ydmv&lYz?B6_umR_$)(ny7$pZ`~$md*A@BEQ-nI<>;tk&CugUx(gM+? z+T<aevtp%s;N<O(W22}j;G^K4am8f0u6A4)R4$)898}u}M7bjCP)r*KmISm!A>}0J zOQ(4SqlcMkzU)<5jKYFzY0<~CC8l_O#hB>&6=sf}vdp4)bL<oii3~+<L?lIi?2E!K zl96Tk!9}+vI9D0*vQJSSDWDw)l*=r=WNS0+y$}w2HT6NRI*%Ro>3w~D3Tf}CO7E*x zO(f^$ro_rvL5nri;8-k*66AtG=358OUSWMM-F58M)<X1LTDS?R#D&4oT=YYwb}0Qa zsvYU6+ffGuO5$s;&$3QG&61O35zQoo*jrM8%;mn!XmvBsK8S-SCqP~$1kZeyBv(7u zFS^DFzSlonV7lpUhw9@bp!KOe(n>8?oiL~pB1a!_k+9A`tCu}4<{$T$_|&`waKRt_ z1$Ssa=-Vf0Ny_(ZT6Qt>CXyDXMp3-0?|2PVE?DM!VdLHv;|}GxdfQFntC#0i2!?pf zu*OF0X7oZfaZ6p0<zEi-i+nj2u~@`r!@{AXB-%RUdz^GwZn{o@hC;RNUagack&xQW z;_i;4RYi;I&pvYs&;!265*TydW-$U3GMzGWLKzPDJiiB9ZMsmhL)U9oWFg;uJ$qd@ z3~W}1;>DoY+t?<voy4Gsv6lD!sZ3=h;`w7ZfKjN93H+JMS;Vp&8FE>l-*#R0T(fi> z&3=#-jOpGG(E8}@;H&zhqw0@k)goOwYKn=&uyP@DAbBhgg-b5&-M+oXCqeVEu5PyP znmH(y0dNQyuFW4zf)53<#or%277+~dPC3h}j76IRr+mlbd`YETYBQ~VO9{>`#g$+@ zxN2e(7O~;wPsgpRSd}u`Qi!V;>qIZ;8p@=>=#;WgYqQA;AI#C&6l7YME3LU+Tg&Hr zQgAa4$X>KIZa!@&Q7#~Lq3vPy+R?AUiiFfe^mL$v2Dj=4tr6%7a;UpVVpNi39NbIh zm|Qb*IVVo!9&ii``D1O-s)uB4@hR$e*}cptSL60kqim{V+Oo`>?eFMgUwV?d%zqJO z7%z=7Y{}&;(HMGS2e^a)m2J$^CHcKW*6W5)?bkfXyk2gY;wubtYtU-~@?$NK9}$Rc zo=OHJWT8d5zOoo|<>eUb1bCU|%WEANI-di|1ztNnk030HshRN<Q}e-O54E05lJm`{ z7`wH)<k8t$YugnpiWY}H>D59VGIj0@-LA?mi*1Kg->#=}_&4u_xVk?`yCxY{r!pF| zWTsN(DvHc$`&Jrfx8x;RvXs1BCoK9zj^`s?(()F?<TE2puyU$DiN(0&f-kxka1u=~ z$}=hOUYJ=tkOuiUOJ_5;E<;wUt7IuNSXBN%6<;Ouyhf*C7p<4R%W}gemsai_<E$Kn zdh1>~^i@oWT?t>;)Y=o*`8J?+4bX*cHejJa9btOji?IM_K$yRMz`mj5<qhAB0$#X% zlmb-2mP>#>O4|nmnivEOY|BM~v4IEKgNj*0rIS^TrjNW7ZCVVTgc;AbiqJF$nLyj7 zaS!BG)bS}JY8F|$QwTv3bE(GQ=a1(6RobHwxMj2s%@wjmHJhG*J3K+Mq_EU*7u9ez z6u)M1rz-jR?mrlP-g!~j^_ZbIEEm7l!>pr|(PbE1xoGIJ*~L(eiUiclReTcLh~<~+ zHk!e2*jq;x$dys$%B*sLyGA=tcVkom|JR~<z3EZF|5dwCe<--8a}p5$?rF>jel}2% zd;NW8;%H-Ju&Z^K2xx-1B;(PlwCT`%Ucvd%+=E>GyfQb77I?Wd;o=0i0AE&jA*W{$ zgIw2H{nN^h)}nzukuIo&Q;Ylx_pLTS(P)6XTskB@5PaavmERxGxV5vjoX&l+UJ2c> zOF883c9(EB5XdY;h%(l@ZtI{AkxhTQM!+D;%HfM{2}S}I(ciVZOVa?*uxW#(o{2#E zX!@DGs~$*o&wI=a)U8*ZmZlDPCuG?kijN{riQb@NzxslL{wW(lM+sJ4RPI1T66R5h zcmUE3(zbG(FH7rI)^eh8xm%A_;*jmyDB%Y3I_pE@)`Cq)3Iqv51$;N%qpJboz23Ug z;m2$qyQbdy6gO6%zF>xnvdl^<u5;<JMK=C2V#8+le}2mEKe@ND(fh5tvGEjse9`;u zr+j_$1SGhQa+C>OVqC40wra1$y=$v>hw-=71}uQ}cvdOWsq$7WeJ)J{6<6MX4tfK* z0K3V_C@Dlcy$^MM^rpFtN-n^Pn0sHakt#1f+XTCY2H-?JKg%h-T7+5pFn2MgK`&A~ z)X)i=7>mdn=hdRlmvx5!%V^=V;uN*}%6J}i!BNLwSR+@cR|8cy<c5N#9XBFPymz00 z%pHLW`tL$bG`Jl|J%)F66t70$q?=a6U!|OC0s%jT=+@j-0&`h&SK9WOc6*w^jYYTb z6Ak)J4%8gg^snUi^}!)(msy(uR875aG5Z=;yir@4xs1*zzWnlLjDqmus2FG2A}x~X zRXuhh7zFeL_B8a>;}mI8QAFhEr}|fBAE)mNKn<}Ekr_7)V(ECI3U*ebhqAjNsR&lu z?fhp$_vK_&LOL|J`l}`M|44LD$||CWCA9RmU5#kBJ8pCRhLu-wu23eGRU=8ql~F}A z%Za6et^ULQfTnd87xC;$TslrfTDE9Gu7=ZKC=?3Ajm@gbxAYxhse}mEZ7r&jzc6_# zpPjth8A^2#F?)8E;Y?X@T<cIbJ9-@sd6{=zweQ)5I(Xv&(u~_Tw|URTcB>RB<a_^e zGVe0fipb(=oT1S*1=2=Di^Wrar7D^$4cW<-y>2O!TQb)=Oek&yIbg70TUSv#y(q6@ ztRDtjHH-NA#(`>NTV(Tl$T;Tpa^wuC=bZ{CtMKw|Zi3_fS?*Mp0<7ooO)3vllQJKd zmYu7su28=y%l<5GJ%1J&zgoX0w1Q7CY2CK*dXm!F(HDteIdc&UtfHkm7(uL+KTM8{ zc!H9O$kd)!np9Pa4T?T^7vm@2RAWP1M~wP-=AUGvU)9;Bt=3T+QN+}g^t@Ud(fKi^ z+Rh7+pHVUief!0EXtCsBxyxPfG|E9f2Y#6>;P`{PD5gtgW-tk+Svse6|LWZv7nI#; zkibp~FklA^u0XO^V3LJk850J<NtUUb03P^dUbrAqE@;j7y#JYxS5a(7**|P#9D#ht ze(BT-v=7G*F_iuvH*a+j6R27}U$od6)(||=WNM|iUnK@Ddi?Sh5s1y$ie%~1u(Wo0 zDWVgv=0`CE3M3j&-buk@qVhO$HbRwk?w}Hkl{Nk)d~q~)|AI~Q)3xg^g<QrBFL(VL zoU&hnpcqraNoSB7Qen8c=eCu@DUT^!27l~x8bWuoMxs4)Bz-%%9yvnm1uFGn?AUna zgDtrkxYo2q(3Z%vDCI`S6^>aKwq!kDr;E8*Q?H@s&=?KEQzL*MM=kfl8u&(Mj~cJ! z=5cnS!%=aFKV3^Qt<bSf_ofnBzqKtft1le#YOSu7rKAQYm4vRSO}yJiNd`Rvs4D!C zAx{agD)<Z_TYJ~Wzfqs+rppR@Ww~5>-73|YHgr`RinpW(6M(4&72{n;B-I9_s_Hr$ zRh`_fA4S$44#oTV*>PTE7!rR=sOJtl_29KyTXdW&V@*G(*LfP-PFb<utyDDZi(&=u zEro3Fw=QX7g%);I4TT>upS*}6vcENI7`-;{uO4NvvDT>Lr6{W*wv@AZSP5@v<D4s_ zw|Om!9Wx_pZr$<Z)W&D4&_*k>Q`a)*soZY%6gEoL_>WU~0<kAJLLrIhH_T++yCHIm z&|~~vvqh5Mc+>W%0!fHUEe39Ts_Wa<Ax9=QIoLC8_`$H!aocd#5_5hQ5{+9L6e^O5 z$~;u-8r`6Pa^24Q-I42^sr7rK${kK?muh*d<G9y0?Vb3+@9@G#-tOyQop_bp&ayj@ z;MtNb5J`KgecLoJeIW7?)nBd3FfR!O61=CQ!LPP=_+iNHT@PP^ru$`tpsr?fWLOmi z)kZaqRj7Bd*YlbQNwRaAVbvS8Fd{$bwrwJU3gxc*P@QS3>bHiCn_l-@2N7Jindax? z;w+lYuH?ltO*rQ@Pn%}H8jjy(%w%BAi&mII<A$uWeWS2(I%6|trv?RkTs|U)b{Iu6 zp=~z`PJj{?!R6*vFitnp3=YG<hMbr<kuErO)?GDSP)-kcF975?C#ioDq^ztUv!=-g zxkg@w&E2Vb1ljD+WqC&a)fUgFGLo8X*IMWU@A}r_AGp$^UT`DZ4iluO)kOpX@|F4i zTV=a-NdYLS#1qW=<lO*Wj-Ad<X<IbEC^1>>uZc+9j};uBGQC=*+(_XFZlk%@KZcb} zn!{*op~$8H&zzJVT^D!MVdNz%cG$Vny$qoy@K1#!phZ32KnQFAe^jGEl_IQA=fZP2 z>$c*LHFNJ}nJwnHtsHRY2(_lO(GrgD&@=}|^G>2_TX%ENwjx!BZI#twpO$`UlyTWd zJKw|@;1#(xZDp{Fiu;Qo!jwQ2UmSB6aXIESiB_dFsdHTipN=CoE$cWOS)kD@A*uE7 z$d?-@6p@P6!wl2lOhw8t3~q_)AZJ?4Zv=qy`M>aR1l&V@nVyHPm{gnqLpCTf?NGbF zY`0lTZ8c1`z+t)X%G^M512E=^hhVQi)p?IcmzLe5Iucd6E`F{oW7?1i9Ob<xMVZt8 z4Mo3$q?maOLIe%10}-L$6epA%t)b;8`blBMwWpn6J!k?BMLJJ50mRdv7M%vqX(Ty| zx*eEw9v4LI8&ABj43R-|B{)w2HPO*S@p!ZfWS%o8U`c$O@unVZxxkt+rjn}Ks54gS z3UHvbYZkOVfmmPw_go61a(e^)ZpXOYQVK_5Rlz85NsemNhYoLOrAOoXtrTg~^D;A3 za&&0)yC%k6_ZK4~I`B1Z$UThdR}&x77|Y==M|ux#p4CQCkOJMj;%4j%!;~!XRb`5z zn1R*W$Oj6#*TdaP7MFXYqlloKvb+(__>)ha%Ag&|b6QE9Wtuw9<0gK?F{2~1fp$F9 z_Y33T7sP?U9Q^V-`7{5LgwV$<1hX00>bO?o{>NmA1?nx;)Wwp58#dXr(8a~j$<O&- zs3}`hem3<&*r#uup5H*G&KQ-WcB_nfWGto)%+;Wt85(sy&32bUFybqAW7ETJPRu`S zX1wiDpVZdY>D@(qN+bl?3%@y**v{kzt@_Q`3Vy0+)0`5$z8PAIZHL5T38sc19nHo{ zj24N=b@xelQ5&xE)Tmpr5H`NL2#`-|3vb2O{M}WR;@yV9oPxq+C&$1lDqb2CYuo5V z-IN#wn`8pfbDy=$Wq~TnVDFzV^h5@g{=>jG|L61W;b7zIXk&WRb3J{rnQ&gmF%JM( zi(co`gX^CEhgI3lps6cfXGB7+XTK)<O}=WN2K4yEkAi2x*5hDky8-)loQI9ERJbdA z*(j2wbt#1uB?9MR>@Es^I84w38Es%5_u#xoy}U08u1A?f9(?uH4Qy|N4yGwbF2em0 zOE+X;xz}m5&2=v6u}O5IigM*Tj>=Q|8_fBPmys);hwny>XzKJun107$GFrw-Dc!Qp zb|2s7heiuWPW>X6tl0LFwbyY>%0QWcMW};0PBEF5!AFO1%N=sjmuj!<EpAdmduZaL zWD}mnRGt+SSoZQz?^Rd4nl>4)oi1lTB*iJiQ8mM|%N_!5LORL5^JrOiQcrCwU$%(w zEQ|J&iDxOT>R;s<{oM{;fpGTwx>Z=+rdyTL`A^c7xZS+rn$kz)T34P`h{+oeYYFLM zJkHePnaqIRuh<UXGL)L(&E`MK<^C0zc$Qi&R+nEew-#MqD|IK{V`=4pz|ho~erd4t zD949K1P-uK=f5R-BO*nsipgYU8+Ds*c=Jpq`3<wvih(x|q1tG!)*GdSD$*<tenFo< zWa46R--W>m0H^JtOx@MoH@B-?ZDIq-rR>ON*S>7?uhFH5?rifq>ssMIE&k{>6)v+2 z{alFW>|xL$kEA;_v*6~KJ0P@@H-te8XfE4}I4hEIoclt>^9*t75odu*#aNx6uNpqj zlf^u`^nJ!HzMwsRf0-7$6Mw{dn3sa+sIE|HeNhv)r+P14cmJFCb_Yh8i9=d%u-E6J z3_0hpxFo~c<!;ukKs0i1j@2hh%e-<6k(KTeQ%2}t(OHMyKe66#9W~@>H%hzmO58Am z#Hxqr8;H`*WW^3lk^*UH&~Zh65y-7l!R63cAC02+Rc%An@?+K!R5i^M*4=l^pMu!_ z(pOV`bk*dTFhdi)J_o=X-faH9Cn02Yv9i{djIR;VZEp*6;81(fBst4%B})0lg;;fr zK^9l9y-_7<;k=dvP@~MLArYgs&;;v}S{bc36HPf}x5Arl1EI$1yj9ank+%rR0BFtj zGRelXxXZmF#~|^zb>vpNmhFcnLke9T@kSZbO49aYym6juM2Feu>iHCXZRu!b?`2j$ z8m}m;Q(TL_*DTv;=)*TU@-$PSgLJ8oIq)FUEG|P9>83`ZgHRhWizQ9W;+wm|EW&D; zz@@b%MKxz!Z2)zPhMXoWQqILbh(Wk3x2Dr3ORj47cp`4tJyE&!WY=}i2ssG!#o=G> zMhO7#Ww3YS$n4nUO@Nm^h*xI0D{na^4(rmfGe;Wx66N~^hD73{HO4Ngze|)O^D20i z@5)*1xkkhm1DTw+t4j8a>qJ*QnQ_-sGd;$vxa5DYKA}%)ftgp+X+YJt-Jun@Q+mzX zT!ECWSysuHx~lvEAO(f=%i)!izlj-UeE=sQhYbuf2YOE6SMCa1{t7(j?J8)_I0C^w zsom%}d#kkRF?*-9>8iJ6t%|_tR#G3?O3;K9xrMiv_O`R2``j9(i7_^E5xb%G#Wk(y zu~MUlaZPMZmDR62s{*~iuKSAH;$7~F&G7+YNM#^Pcuq5P-=)hS9Bs5*&aUWgD3lm* zsUhG?2?d^YD9OSD#o3ulU+ZE_p4KmY&6U;abRU;q*Oij>U-`=@wlAKv#`KMDnWb=I z$te?}@FKb^TSs;a;~a}g<r>)h>a;}HO3+BW^`py9&vA~hI&iN|JXfpElahXFO{WF1 znYG*IUa$uGw50s{HhGztwO7x=U^?TV3bUM)szJH0_{$lFrbh-^3s1+VKi>l*vkuVq z4F`pka+iZ5c>09-2gS2h2Wb1oGxfu&qxzv~u6{5k>#}yTE^8<2huh57T@Q>QmJ@ba zJ7Jf#6ZS*RUZ%5HJOjTi7il#~CkE*a1MNg?9&R;n8<EG@sWz^#+v*;C1D;zCByw7w zT@@5~Uq7>JmK=tY&_-bXz8`dLcDSLl;7y5uo=eRnUGucoD&Q;7O{Da+Hk@HQlv-mC z&KAZ5;;^mRl3tIR5~voTLW9<G+`+AWJ>7PnZl~&WI8N$A^^`ZgB@McEDpSS1k)ck# zJH4p?8pTl-=i^c?xR69G)b;pAsx92t&Xj4a=E6uFNE!HV&UZlY?}Gd`E|+P}|I+WO zK^-<9aM>$)?hfe&PnmfnvzdHeqKk&>IDQtRx&}&|&gen-hJ}H!36weqDPEH4T~$k~ z-yGh;uE3R3Ln>dKv9=u|Yb8FRTZ>`>b8Aq%RuuBEC64wo7X6hO(Dw<Q_nl^g^JQ@r zpi?UxG|NluJiiH^O5Qrsh>ml5e^w=9?KGt`R1W?!KwG|G=q|Bcg=U=1boT6oW|XK- z0MfKI17+xrEyrY-y8W)smYx`2?+1@a6fhW3wMfsM`cGppgZ9@Ao~e%}$`(Q-%f?vm z=!}NJ&yozpnjAg7qk>w_*%WS?RD+_KE4Iz84q_>|x1yWB(*2vw*@6{JsooMsz^rg% ztsC+lQqDW8Sn3Z1m91n$Z13YZndz8sd)R6kQgnG&L-HL5ZZRZt>95~4D%^^uZnt65 zYY<3C>PjpPtQjZQaMw3NT|MqNztRmb$GqZqCZpWIkh3?pz$zfss}t-ttTG+vUaGA} z{p~P#{h4bk<E5~%;o$hSN0{pA(BgIK@bzv1Yo=2ZRKz@{-TZ7;yK$r3=P*qoaS-3* zgY`{pkqdUUsor2+X_rgp7FvIEbJcitb6Kh(oi{g^qED&}S>?Oa5?$570g=}fWQ-GI z*N{li;NRHx#d+=0rS_J>G~VdwLq_2O1QmaaRH<F7Ana%#wjCDej3gZ7I&f3frww|C z2ToTwFvH>sD1*oV7VkhF0bH2WXvMvwUp0oZqnn?m_{?fHDHf?R2y2Ya?52KKF>w)s zk2f-mm8Zw%i<#A~my8@wb$Ve*_#WZ6egxb~3r(=u3KU$mm3xTc8lN^zj8$n(YuqvH zX%xY+`Dm+agmgZ7v|3IWX>{d)x{99Z%Bx!PkY_m_VW71ASu^E%i(c1l6XluSv0TbS zzH298Z(v?RZMK1Bogc7RumsKP1KfgwD*L!*7+6Pj8VTX!q1Kd)3?Is=t<qKRsD^cv zSS&eBKc_IugStys?ozs9u5MU9?9!CQojgbvv#TJ2Q{duchK9Py0)u4}H46O@1<Ag^ zMYbsP047P{15cq%nD(L>o0wmmCgW4ehma$zk8!*t@F;9!`6TyFmX7GBZk>j%+dzJ) zdJD(gX_CQ4<hRn7h$OL}r5<>s*`((!G#5Tv1;OQtsogkgR~?K5r9d$PI)Z0;Atr;# zm*TYHcNRpMXM|-;bHY1@3<F|Jr*x)wEl-X3ZoNh|oiy8}mB3-ix{d0*M!McFJ&#|= z^{oZ=zqY*2^QBSO-OpDE9Oo<WnqF(y2+fm<6+dvEuob4x)UFu-OT}@=7rR+}x7AX5 zO>f*~QKC;*5iPUbmF=Myv$)e)YS7xnlUVs&q>SaIVVmlDDHtEsSRRdiR<sTh5yr>< zlS*l@)b6-aA1UI-!j!8UO&4~}Hq-TeB{Vkpt6i_=vE8r;8r6SwC!rh6>SaYGe!FSD z?evxdU2T?Em|Y*f{anmxwMJJD_eQ1xn9u5`X2wm$oYxjo(}I+7hxDe^ZJO_Nu?ltE zda2)(4h(C$)ff7Ti@a_kYL@-=%5!Y#tXH37wo?4xG{?g3@(-S4b0S*LvFjGubl()1 zhyPxe@157n)vMJ?cJ3zs;9k{1_yzi*HTnl1M<`P8zs=skmAD}ehhZplxBkLtSpq<% zA&830V$7o~fI{omz(FifV1F5nInT5ghA85NV%V8ASPa(IjxHNa^Xh7&*_ppO+YmZz zSc+);k-NRSnBu%#`3h0*HvFZ~@c_#0lcPi!oWMF?zCmi>r|2?dK-3?Xq3+pS=I}-@ z5Q^+6&b9xFv-J5T`hs6Z@Q2ghhrt}7qZ<i@>Y=vi!R1&&O`~<mIff?;gI}OG)I^Rs zorTxQRVpA~0gRU*f13xlovEE>DZ7==x_#<LixcU|gUXh;h_g9sP-4{C;7b|@w(Rkz z9x&=0K{3!vrtU!4%0os?u;K4w`p5`>6~M_PzI-<&UzOl#u(9QLSSi68VQk2Yz_SmE z33UeF_kwRoGNX^bl2Ih*v@pv3X4MSh<m^sqm5J8)E`a>zlf@<)$&<N7f&7*YbE2FG z-w98yE}wC~JNrplGxB;9_-i6IRl83V>!`!2#$II2Rc{7Vf1fHo)Z8KsPu9Gt8;Zju zOwpWp^2U`=ig9NqIBn;WkM2_C?o|G8*@LD<G<#763L;l+JtMOS{O#Il;U%CRT^UwR zfjurF8gP1&n2{-}!SRh9$~CcqwWBCv?z2{U8MQOvMW|kK+YORP#M*o<kZy=JL0N>N zwlT-8h_?TgGz1MD9zheT;&w&Sp^^tU$u6j>1VerspSW&oZofg$@rC>B)rR5bTEB}Z zrJ0P`bM79MfioUER~XckV+;tu21;t{mQh(*D!>uoNXqC-$nToMw3d9H#>6puEdlMB ziYiDAP;^pTc)_cD`E|SY{u^6sd+9C9KXs?TXh8eABO_M(TX2JVc=s5Pi>hSSEjuO0 z@T6UFi!1~cNNcU=IPdy5yVf`H4RqKBam~nU-GgfD`dIOxE$|1FsIWgQ_wwFtrdV+> z<v4p639p+ozxmgg<TIW{*2tx51;TE<sML0Gw#M3Oj<ZsK0^Oebr9IWS$9oiO`=!j< z+L|P0Khmb>?2pEFaE9jgW~)J_ZrP6-WN%*)E{X+zwh!W*{Cui}F>ll&{KfnZ(P`N^ zkVb_@vloUu`U4>C(SRx6yA#+WJ`kf%M!e@>r=E&uS<`8CSZW#^*7s$2g0fd4sckc` zxh<4x;IONn-LM^y#(GuxwSsiBhW5+l)?qBYu76eYuGEui;F>b9QTN2^haIcBR@uzt zA`X_bw4h1cM6?ObNoml6>G0^zJjBA$WCGv#Ws#EqONv?*8?*qk5$wg2vvExJ6!CN# zbH+m5a{|>dXO<~U#lvi8iU%u2B}joR0QCS})qG_e!2{{GV!d~{p)e?If?RYXm08#i zIaAs~=$WFx+;w0UiZO(splz7#3avbx2rHfU*nkR{$d5`BZt=EP>vL}5cViSh@C5Qu z{jRpqsLl7SrxIwxNF6JytSg=zlUnM(tPGX2G<y@FF^bn3MV5JSwTsHP3inkYwwvnH zUg-{1RG-<h(gSzkQ%`fPyIUrCvS0vZyWY3A=<p#zx9xD1xzY8I<e>ETjv{xe)VxIV z(^;Bk-Ah=XRaH@MyDqn{$eJjAJvCxWDMQO=nk?Z+>-z@;z4SPjqL>gb^0O?~Zb+RW zD7|@=Jt@!#NF@=(s==tw1zpt~Lbw-vEbth#ib$RUm^WspYETpn{l-LU^O=q50<@ci za>NGOJa@0n(KO}Vq<^8PK&*aZQr*+(hjuZL^HqoG54>;^R)tZy_?IU<slgds%;4tH zHih>yup38`5XJRs^l)QWgiKK$7QVREZpqUnFg{94vBfm4j896iftB6o*w^4^PUAb_ zyK7rUp!6ggXpEoZ9KQyksUwaJr7LGcCLuBR74ExxTb8|X&!;B%+w=&{TCYk&Xdhkc z4O*2CWu2oIE3cG5gpJ@c26re|SnxL^84Ief?d&3TIaMjYG>}FYjsu)vIkWggCAV~S z3zP%W^JTarBU*70OH|x^m6|6c`_Q!Fh9ZT4QX=r)U&~VRI{SuUG%n@FgL8S`AsN(1 z(x5YqLlO_0WMz55UM*KfDG>~iw>EVr4`;$qM28dsC+HRx4nXhW5Ln>NKAh;@RL+WG z`i(o~90{5}3<D&FymFzUhsku?S}Wxs`V3o4n)9=butVhXMSZn(WZYX($}nqSg9M?< z_^f)L{nn#UtQx(aHF~#5ZlRV?g}aw90!=h9GkSTOZAz<lMJGx@BTspAkv}&mfP*?F zxvI+~#a1{R4rgNCv;s6r$Rw!Cm#eB)+w2eS-bNu?60&~!t1|&_AJmlP$GRIkVU$4| zY=gc)*1RW36wUzUGON>MkJCkwEPTcoZiRmd*=xyh?H(9&&6=AdGY}J>gDftFhKAM! ziA$-0Tl=~z$yhD9sP?zo8i(@TjJ~&E<Oj#Jk=3_kttc{i7x-04Y(ROnS`wtp^^xfI zieuH90UY{3=sUtjO-o*(#(6Z+<a|&35TAVD1#hu8D@$R!g!JXvtu=o-Rk}WlQ8fy! zqB$+#?^aD7LM~m|xZ0h<yvC&mSpv+aXp@1akVSFLtH-;sHI)GWw-}sS7hqy^cV~F` zZ)dfn)H|GBPL7r%5BL6XGpGNkZ2vc_Y#R*PZmqBtTy_;z?O!#MkUx=7jRS_zO8NoR zCkQHKff@*nipv|P0CK7!TPPpfrE6G8W%viGGAk;||LZ!mvIn+?$!DtOR8kt6)b>q0 zU7?9(n%`IlTv4dLXr<isWFM{slD&<F?+zE!DsgC4;ve}pnoWIiWm)JSI~I%`qn1w# zWT@b}RW2JbV+<Q$IGEFCE9v~U-8%Ue)QqRUvRm8!kjPr!H|%5a4M_aTZPL3+b4`P( zRy108P)GTmQ)@*F?K{6JmR1`rt6eg(+B5L2&cDvpe)}VDn-k}&B!@F&s}tu$799oJ z<K3J%CBVBqaZ0Fv!bwkY)Rm7~^IDfApPgx~H<G84acMF)BDA+S0vdbS1)tg3i7h%S z(hlDb7-vLfmUZDd_$C<0mNl}PG=Cu+rA@O5SM?&Ee=vG!Roecm<jkne!tn2zF{3vB z!Y%S;)SMWN6EU+(Zzqr;sV%<}Ux&Zg^s7k*Rcpfg!Jz-Ja#^nfYm=Vtt`542^#60n zz5S8&FC|RR%M>8!tnIN7mkaG?H{%-LHTdvdi1zJLMi|S}TCmm9OC>y72EKKbII9O; zcF6Py)r)QfX?nhBGNyEvw^p`wDv-#tV*7F`6^*4VmE0zu?z85U4YswLvu&qHY;x}6 zG>h}obT-j~8u4A2yBKK=@KXC(P!DJ54P&<b7m|=EHSMKL-69@>b)6tq5Q<*_vjQq_ z5$1ynjso@2EDl#Adr;lGziTODJK*)U6?cK!ywlJN=OW9hU<v^Mo}#nYVjPPo6kFo& z1M&A^8?o6DL7*zmLi2(%0f}i1!<?VZCc$xBjc+TgT7-Pa;X->A0~HQuUp~qFl5G5P z_~3|r;HnlZ^m6N{v`*cst8K^HUiA#Hs`y`#6OlB9_)~jTQ2Mj610+5TJ+3{i+_Jdg zMgdT@yItd<S98SC{9vlSaLos~`m-LN2PaVx`AV#QcIrIp58`<Tkn1}vnOpG}@vNUG z^W`i?cG$fz(^gp*O!H-$gTz<~z`;4&P3v@D&`wT0;x;+?{qKCpVIL<YnV7-|4v}W- zc~Mq&+vv;sl{1k>6^EkGk!>{l%w1~eGHv<`3F1?1?qhsqNyYvA>^Lv7?jQ`ddaDcH zvier<$d{|@CO1Q;xOklz)obPNoA^6ew4^Qi#$yImHPJtbXQ&)=QHT}I;vy-=r$N_0 z8BR$GcxKSaIzx992W+X#i$+Hoj;rgQGW|5;wl_KkndalRryI-m-FRPa%-vhHS+s9c z@SGbocU`*|RF1FQct4qVcbG$2f`VH37q8CEvUoX*#_@-wIOPz-f{sFNt~RY;B}rwr zXgImjZmFFE#aho6K8tI)pSd+9tc$}_jRIV17<*E6Ar3iV{ei*Q!7`O%G4J%Cd+73c z^!pq~^u}AANnFV#2V^&^VT^S3P7hVT3coVH+Hz{m8&Ni{PVkmvez9cR>6K9LW_C6C z{dYZS-qqB$P!on4I&qRKU2cT&sJ9|@Fym`Y7(A{jX$+3st`AKlQNr^Q1%^_o&OTQZ zHh^>q+w-ZRDk>E>>YQeT4B^zPqN2{JR_;SLRv}@o`PZjjkdD<L!=Pz0m}}{XTa6@} zq+AhHtLh_rQ$1u7x}-BY<(LYPTVy?TdLKM!5ev*KrzLgaa((gyh=akp?NI9!TtrE~ z$l{5^UFtFFLh>|-eK#7~a;wukuKsfCh9erRJR*6Jy~$vTL7Tx8gO-E2K?LLXNt@gL zWrBm|e{Z1Fgo<~s(Ii_NjxlE^GKTi<_?BN+3sH>GXenqRnNV<9cDLnQro4sXNC3&r ziWCAxg1v<uLA`#js$=qMb}sbH;HS=*93CsD(lXF#YP70*KlO-ae7)AkztP@Uk`4Xc zUgdUKNGl?Luy*k(RkIc0$063+c>({U^!mSW`wX0D4Bu;8)veTlF>eh9^`_cpJOaG3 zP={a>S$}IPFTKw1(vbTPRM(*$GmXdGm-p!w$E>SqJRERZ>-}!1;A^MLk)!Etuc&j9 z6>HT_TA>=vQ&n6iY~H~Bp`C2r*8V|pUyT<#yu#89di=q4y`p{UcpVq)O8nNDE`ZW~ zpo|YImbQWSyEXB1YHdK&#-zAF=u0{)y7?^VKDaMh?cMM4+s%iM2Y69GaK=2y3J`%7 z6D=ix%Yxb&(74{Uy7q8`?RxXqLU(F&+cI8QjNn*x=P4}GNphY{;^6qoAJn~sjDBch zuI>kA7*piA2))-^!K0W>J8+Lkn*3jDSabqxxtSyTqoFqX;NFQJuE$;6ZFT`i3Ff(C zT?XdgU_)P+p+Sx1ZtIUE;9Cp;pp9`|JFP=Ic6GN#UB5R|BhFtvBypPH@}zV}Y7Ydf zb*Np&G@D{H;aU-o4%Md$)X=V@#*u1K$7j17WUHQ7G{=kN2zeLgAx#&ZLXaZyEdi|U z1s1Qbq$xXIMOH8sJd_)yNV7Qj<t*pSu0s0oLvv^^k`+&1H%PCPUQ$fbdb6t(RnYwJ zO$@Hm%e&Q00Ki)*AMVaS`z{Pi>W!`Mxk4B=8;NYSVc1rbtNmntHp93EDjsc3j4S6! z+G9bzb(hD~GA>mG37^>B0!VK5YbP{Lk-wh7R+!9K{dgVLRGr5YZ{4kix@Z1o9~@bW z^~hsbKTFSwSpv+fF>IU>Y_S}AYV|<^yl$8OF}r2^ncaT2TKlsL`1j*2#(!atUjS@7 z{#&-6+3jbo+HVm-@{gCVT&I*<IDKn(mc|uei}-Er%-ZM4!X4wm@(i-m=G0k!+7{W3 z>G9^#Wm6}}m&e@+w>fD|Cp=m9%Ji5c*FjY-iZGDu0mRo|;h$f(;J*j(-$RfURiUgb z<dA-of5j;HCB;5Gxny8%!@h+KT(5EmQP&+bu2M2TO)uW@cyeXAZ|Kv%@*VjUb5<Ji zf#(FN*qCOK>@NB1R$1nOugrt8%tK$9hh>>Zo-$dbS6}%`Rz~{xXvGLyRTK<bpkS*7 z3LdmT!Nb-lcyx5*!0OVRJ<W=4$(AEH``~dz@bn1J<=d4A!fN1BNKkU;maF6gSIGyi zk`G-aAG*TZ{EAqB@*B{R?Nt{}uX)-vT-SskTv^+tcd%^DzF{eKP)`xhaJ<Fw-nSHw zJe=MC-t$B}swe2=Xw`H<m2)c$7G_}m_PxvQpm*1|<a$-EK_UdEU;o{hM|IqFZ8lwA zDv2FW80BW@x@XY3C?8$dnbqasf>k0;KDuC)r7~5@C?<Dd<*O%^Ib9`|Y?NZsdWF^8 zV9gt%Mwzstl8&BpTRXFm>RsK?RQ)Rhy6x~4SCNQ*qNdh+WnNLWm9@*ZFd&=i+`5Ld zrZnVbbd;8<z;z6@tRlMmy7V<%t>QOH8MSxi^zw?PpQ`n-0;;qBpnByj@0**bLHo>u zSu#|tGnnntX4;7DUai$_)oQf9d{;;*dUGqb@Q<GN=qfeYm$ma^7j7{Zfa)1CMnTv< zoRd3k?eNuJbGMk^bQ;?Ju9NL<(&zN-L+oDzd5;>9_d7Mb5wz%sshZ|~G*fFv5ZjQe zKF;h<qt1u_{?wWMS=5>R+fnB{o+QzNq72*|-*A%t6SlA4qtUOM5X<;#z-vY1XKcEK z{hWpCn@Q)5(_~}K*{vHQ(uQ4G_5e3`OBH`^x7O>r<#&UrwU+<GCZaV`TX5mK>(u() zc53xWxZ%D1X0RU@XUiZ8&g1MV-~a@{+If-{XVFZIa1Bk|=h4SF!1=|f=4gH}jV}UW zVt)|_i#VPHag--wlLyELz=Q+%|7bjp^E^2Qz)>E2(VeDgPY-p_Q+;_A7jRYxj<fV4 zk27&S1rPbza+zkFWK?NIjk_vjIg@mJHjfuYe-X{&d>KKjsI|N2c;7#_S&?OVa2n;` zzj^J9jo<<oO(xyWc_$1yXW3$yk5A)ylyA(FahB%kwAdJ@^Wph?h6O&K#M9_(R(uZd zb=NYd?#kCIO0uiZ>Sy|eU5qA)s+(+Iu``SDSGU7cs<&Ki<RvF~9R>I9b>mr|sBclA z=@#JAc+u@Vm=I?cbR{SA`+Z>uqg!`;@>*=jkTYmYi#8r%052*jiLIy^^x!goKywAB zJuQO9npd_*8GXejF&7d1F|JGHBQLzV+fv<Fm`k&rFkMS+`<(i`tMhxF2eN|kqVnhE zWfq^rm&0JQ`_p8-*Ii!rp8b^H|6((#F_E#ti@0O&(M{Wh&myeZtgIS2#ewxQP_4sL zrR9tRO4xm3cjAoPPgn6&`EYRLw{BBSG-L(&qK~0s6w!8m{^i&F=X0^J*nh<1Eh6_v zeJU=u!r%)2yL<qD;Xid6;76xLp6(KgFqzB_4;j``7#uRRqazPIfA<KK-oGVX8*5Oe zQcKaYgFm0d9BZ}Pp+A74!&X3#YP!klIs=asURPQp-c5hG73}az(Ca!bEpGi?CnMYE zXf8#Tw&KavWXn;=CadFU-&Ea@P{CInj>Teb(SL+r_Pqt%Bfqnj*autKm}%A_EmJy* zYH=`6bF>&m_o3Mp@LmvRFu9lX67-qBy)M~U+x}^suT>{s&SDS{qQwO5f?~EK<uQ8l zPUdkfuA&(Xt=nN>i?j$xtV0aPla6N=erAN&7Mt!p=nKJSd;Qa5K7)e2cH@j@V>Ug+ z5pu%&Ndo=K$*?G$HjVt}v4rp*E5AzSdCmUGfb715MEk=JKd>B}pHd*ZWtJXC$3PUv zXcRe47t`eAEJGVhA@f&*07k|5)D9MhF^7cxlHC9M@nt;jIxSLh`=dHuJ5MdpKE+yt zvK6z5`UE;AgfGNFrzf`e`qN6ycrF|%x?2uMnuXnXG!j5L80t;8cLPh<f5wYA6PB>V z1=8bR@Th|;5#&`gRzO;lXC63Xxv5ezMI+@izF?`D9$lg{QWD9<RN^IOR9s)TLRrbW z{j)`WnoNssGI0y7m{aKcQnF>S-Pwy)YxVhLqR;{dO<b7h1tiv}FuecuEIx~!IMD>{ z3RXPqN~_YAX;qj#xdI01LfGNMwgkiy0kl(H&28{f(|fSe*)k}UkI9+<ZrJr*;=WqX zqbU-e=sN6H?a<Cl{5jUW*>G$CH=c=kdS0%pX_n4u0REn5RKu~+if((+uT{HYXTM1n zC9Oxojbj;)lW79-!R6)^YzZ4_Hc1x1404~GAUws}c$|yAmz8deWg>@YHe<w2r0OSK zh$UMqMKqZiD-=^JbzO9ykjGMCp`VfU<FoEW(&{W6av11nT#-o3Hhpd*?gO^t?5eun zUSad6A8CbPR(8MFAEQzN^K}4^x*7(sx=}FSIG&~Bj~#)Ip^25D!p=F&egepQK1)s( zn7%Syb}H75EFCb{(A%y<u0x8eOt&@)@AQ~4HA?BgU%?Da<xON%Mr#L3L$#H7Tsg`u ze~o{o^y;o|v0n_k1(muIj}fJ7a>W!{7$_&x9_Y1C{4ceK`YK%Uz)pb&gi_M5<gX|v ztLsKJ)$EZWn&{_6mVS))i!1URR{-iWA8}PR1W{2uTekX`=UaWPc3GjMeV4I{?69id zDoGjD_j!yo90(orqD^?W5(=ODI>uwE7HP3UWHxd2{=@}h5VKQdrsSU+>CPHZ*aXcP zMQw@J&rZ}I$0y0+eN;Wy$O0(!9HgWMgiQp!-PVIa|0^CGzS$CQdY*6tTiiTl`z=mO zAKc&xcgts#tuG+ifuz!bMDGB_kq2P}e#n3eC&@Vw#aRxb0c=jJ3fN$Fj)3z953U>Y zif*HG*bUcox1HA+Z;C&7;so*6A1hzIEhqW=6gH<_CKbJf(12Kz<k!8x#9C={rvBNj z_*JXzRvO@2uDTm8t|%K@+F#&)dSDX1>Z{M0^lv}O|Bj2TLYOYazK1k#uHnA{mG*AO z_Z^|g{KV@Xn2Urh=3djvc$Vg|tD}Du#r%gM*V4Ux`(x4kZLfjK>rDmtkZywLmJ>F9 z(Lm)lJaVH);_9gK!nz%Gtr&f@t0)?M@i!dNYz^s@eZOUmUgKT2JHn_yVD+OZ%HLEU zslphtIBg8TA$@M&6f;VKRM=?~zeN_N04j={eI6i2X%9M^+`L)^ldD60?!bL6ke}ZU z`}74PpW?B|<!Q}v#imJ?7nbLjiGJu&Bl=}ya`@;lc+?`n%<2=JmzNnldE0(kpbo)Y zG?73*Uvj7(x4*1!rYj)>)u<4stH<22kkJn5TKB10k|T2&NT|w6oGVcjRSTi&@2MG@ zT^rU#H@yqE6)U+5{?M91DC$5bzY@J})UL?r>P)KY$i?I-tKDk+8)DwSE<MR+?v!b- zcJX3}e52sfYuEN8e7$n!B(rUIE4C>P`Rz7wURK;xa<iPL6kRn}2_^K&wN9m>H{DaH z1<Lz9^on*6fpSRoSpk}NCmATNHu$V0hQkht!5H?RISJmgABnIoeBZ?HtxI?JY2==9 z>EIf}<|g04i6Y5)9ONmyVk_?=4L-*4vW!8O2T_(qS9KeVLo3@xGka~DI9G1|&gZkc zy!Lagi<2xpTgH}2sn-5&t^oh^YrJ-MkohvIBrad=0+13GQgF9U7SAH2DR>JzRyLib z7x4BpnM~qE<5l4thL#|d!SWKpMw3ahI8nb{H;MlzE)oTiVuFe%=R^7hTrkZhX_f%O zMr(s$u*PrDQ)RS<%*3{JS`Rvb`CeFb!3V71+<QAgj<-ysH8sW2ah}f3ig+8aKOAhM zzcT#cdG$2Ayxiu2j(qJyiM6LsHpSSUcKjF<(&*%u2n{g5J$UoF+c}PbmB%{^jKn8U z<(eeM+o(d@r^##rn`pOJS%2DIO<@u(&y3QdEQ^J81I$q8kG)Jf$C|`lU75pS&M>7m ztHl^-7?9F!g6nC<w>P0z1RUJ(dgokR-w;ADTuphwgDz^F(0I9ZRKKtBFfd{Z^+Je@ zgR01Q>+4uXlzt0bsofEUCZjc?hqVC1b;`FNn9ykjmOUU6UlT<LY*~U^!9^HYbdR&8 z-|srQg5S!Xa7R>mZlkPDZO9sUY_GJ)lpzr<b1L(XbBzKhTn={Nk_T^rIaj=jC84|J zRe_UPb%F#&1zRFDsiY|o*8FwEY&*UX>Z|W-*da4QU}VG>70Vmeu)HRwDfd5wCbmX= zbPuLOD|ECrC&bAmgNU5b8=k&j(qz#^Pqm)Hv6yrC8LvHcLq^U_*t9vbII*1T0@NRR zsb?~_b6b$R#P~oA-u!Uo`|y990hB8@#q5B0wbHx`ZS{4A%M07Q5{rZ)rqG*9`KDY~ zGFbV2_Kc>l+PbWMW+?>6UPtPGfqTMp78nS~rTBYAfG+9ZtFUQpkkUr=fk;bs!|xG@ zte%dL=&G8>@tiVboknnoMDGVUQUn*LATMx+iHIP_zn%eclG!)C=r<f;yRsYT4X!%K z5m39@^?A>m+Cq#d81x6e-bQABrSEeD^9B?tQd1PCQ31!MIL9FIJfwjuU50GW=v{3* zQl2-|9Rb~GF6103A<et`!0!v1>1|hGT%m@^0V4-K-vS2GOHD6Ig7DX`>w&Yrn+h)_ z1zzH{sT>=>y7DO<eWdb4&4Ne$2sH6Ni_hT*A$;TKX#GqnKXNuRKaP<e<_UoP2m}Hr z=m<z9ouR`~T$g~O(`ggS3_1|!IkXSE^z14)Ny+m*Mb{zrktmWZ7IYY*f(DMfm>{4W zrJM9GgONU|t}V`>9XWxG(Q}(8318i4LOh7GI-w3au&FC1dZj&=<K_EcgV8#9<k9c6 z_iz21?e+hW(*GPO{Zbu;Nty{RBEP798T?M-`JZayQL)_c+IZN;Agh~rG@3V;TB3fk zSi~7>mufURtC)<C$QH|NVz*KGmzf8IUdn3%Bu7%OFgvd(%No2Vm97i(e%eCi^<UPe zCBB5M95-210Cqliupq}x)ZI*(Z2E9;)K7s6Ny753%UhX{U|2rkz(|pN$WTFYS$1Ru zu8E%(Wssi&h2SEMME0R9o=3?7v6arGH`om@icy#ySe4zwrRBK&V|}AxAkqHLTHfW= zDJNz7>+Y!~O9{{P(znKoINyYehJB{=+BKwMkmDYO7w5@Qug?Yp?F?LRXW((8b@e+e zEEk_6=T{e-yRB_Si$VJ?AjH(X#9N21Hh|t;7$%rGh~pXX(tdt+3=&lLA3Z<IO>S&j zP+mFLZATbFn8E-cZ%OFPBYlt)bTQR3NG*Zy6!rUAxigy^lII3myT7S3RnweLuQBG; z=KaqO&a&ea1dNY)@Kt}%AAI&QU0!j>)BpGXA3PXrJq}((c|4Bh%P@HT`sHWn7yFqO z!|apqnL1X2AAJ%*(BjEZD<wVh&t|iGql;uQNiX_Pu}HHkG9}$Fq9XqCOXGVM|9TeZ zaO_Iv5rX+9i{|llw-=r#APbk!<1kYV6n!+Q$Wk~fWPK_}pRYr*uy`4bPh&^7j9O*M zZtwc~x~FAqF@9`Q&Y_Vt{%s$gXsw0WHnz3AdPiXuM(TT^3WSU8Z1m}R8+d6qCNKBi zVpJT)M_~s4jNq%tmvkKpoAX?Uqv0YJou%=|Bdae(7)wyaNZqH)2XUhw@`QBbk!q{= zOv9k;Husiru^n&sJ|)v`++U=V_y9N{oc`XzV}IxM&YPXL2S2}k_iE?MFGVJtI4pWS z+2QSY6!(`AS_@$fz&^}2bSj?4nSm?0;^X2Vna8j%!6>(Sh!MQl$MvbBB<5ZMYQr>4 z!d#9!8S(I97}BTfFdro{Yg7i0<7hFCXBhG%T)<B>SP0XRZFzutm+l(<$=7;eO4b$p zwg~SH0Mcl5Z-5^VfM{^>Y=I4S`B(ldA4;%2H2{W@LQNdj+%YCe2y&WZKtSf0W~Qn3 zQ!O4c`2gg{?Z^3kJOi?YV+jnP=wHOgACuyZ{V9V_^Stsp#@Fe;toJ;_XJ>GhcJ-VH zD;uq?g~ccyZEZh%{B#s=7o+v{xR<Suz6R_Tzx}rLNc<JQAJFe-Ya46Bt*`j;(c19A zfF8SA0?<dC;y8<d;mo_e-ugd!{UY5jFtAB?>v3<WmEHQvDr}T2m!-iZLY-6gU#DZ@ zWcpCmhE!-wU>i{no&EC5ZUKYu!Mu7*Ue+S~+CR<WDNK{<5g?U91qx-scYCi#TnHFJ zhM^PX^=J6tY5YuVF2ruJs9ks1Z7R{v#Xa^$ESp}8Pt!~`#-F!(y=%qh!c-Au|00W) zt_6;^U3q~Ek)o_5`Lkk(qCP%CF<cqTEG<$Lw9ujY9jkmC9KO=u<qY<QwavBgVUP6_ z@LUCmPAfH>Q>>6;RPsr?AzC@z&7a`^4*%z;&7=EWe0a8fbicRRgH>_3bu^@;(}Nxi z4m#oN!^?EOOc%&xe1j7OyS;K~J%#oPObp>=z-<6qw%?UdH@48qqyl;8vf$`dtE0`; zFKA9;uz&bJ{iFL|FxCbJ)-0qYIZ9PELsFeA!T(S9+3>fY`ta{*G5-yNc>Q*X|Mq&& zq7D8%tfb^Jp1ioKZsBr}u+ZQgFNP%F!JDIl6yE&yTiUg$gm|~vgs9+L7535|jl@<` zJS&WKD^O&@E>e<i{wu!nVW?c_cFq6a{=2s=mX}?PxzfrNDXY=DX{&lp0U_=dC0pqB z){AnPm@-jW1vgh*J3v;&IxWZ4z3&!^=fyHTElfmw9WLt2Z&<|(*aELTTLux78=Omu z<&$O{f)GP{1xT#dAaH(L6w5uHQs>SCJ1nweA<Lt|`3dYWqb$^k;U$Sf@njTtU9Us# zyZ#A9v&p-&!m1%(J8FCrCDj)ArK9xgG@4XO^GiqR_gQ+9;XRdIqx_)PI?HCGa>J$# zs=MfED?<VY(G*T?m9lBiSl?`>M?3cq-|oSLE8*?!&cTOwd;j(GH_vxpf48?Y0+F$Q zu={4`-FFA--NqKYELhSVJ;oB{8p+{ISYfr>`ZBpZ&A$ASPquhV_l!rsNQ-28^?Zp2 zXw>f)q)8QYvX2)`Qi=dETOz4D5bppeHC>j0Jp|<4HQALl5MQ8w>9i}(NRqA;5~+=N z@~p64bbFF-iNDvzfLSj0@dO%dIabxz=om8<x*=96#Km;Qs>Pk@tiWTzvkG#c43Xa^ zN@7Jct8Gq@uV);9S}_$}M`vsnA?N$SVDN-bYcxM_s6NYkUw-*;FhD6!O@UgxDMqgX zl%slfFV11h&5>nd<xKoMh%aHO(kse*&2PVrBlP-MD-XUKlK$6vJ&+gsQ(ntJ64iEj zNs~^Py7&?fdtJTHVYLsyu&+hlR3|zG@3<{G)okCO|6}NDk)7eO#$MJ9omZ^#uhM;s z12uGC?G4S{w*a)@LN1`{l-yk_6a@}NZ#L+5d@cNhC+^`V;N(Ne(nFxCq2vj0Qfuf8 zDUwBBb{3P>djbQ$K|j<!QN!d$cntdC&1-FMFBx;XjNv@<&z*xcwV8$Ybj~gJlCAjR zecqb1xfdUGK3|9?<g$N09>+^S@fvzBZK9YQ;vJ&I+a^iQ>zDJ{TCWa_#y$4LM!IJ1 zt6KGRu@roERI`1HqR59w9=Sji0r+q}^++0`jKq^yei7wpcNw|lB6DWTh2WLz0ibV( zw#X5-ULp0vj;9NdV!K6SgDVhpotu!hZTXKdLMbh=?%LdA&*olE%QMFY+chA&dng7_ zFWcz5?^bUW>EoMZk>scG1aW7*>M9fpNf^-_mMaf_L05lwv0V=AMU;6IMnYnT!`1lX zES7Su_^C^?WJCf(Q*p&dnn1d5f0W~w^W&)V-u%>My-udIU?UJYSaXXxL|*RikJkDn zf83CeH;$p!r=J#q=66L0>ur3eoV3U}i(a9vOE92EvVRfJ();S+@{)cZN8^ttWWYBJ zJ|7JJ{&+g2_y5{R78A@t@iqL90cO!cw#+_HYwOwi+C0Z3G4TfS!602m<D|I4FPjhO zTlqw#l0^v%wy*h+AJGl#;Y7G}4th}Ldd)cBVv1QGkH^ak6f${f2o0QgN!vO*N5Wnw z!soeWP<*e<mZS>UCl82PNM~s22~Lwq+|WCDu7IKdLGUg9q53!l#%p(=r4Vzr@DBib zpDwk|!yAR2E%+gOv86<plFbw*Bcz;3UWQCch*6>TCFsX#*H+hf=D~qJrN=#mO;B9* zve46YFV)bjK}HaC<?8N(g(}|!T5Fq|Wv{={Agn1O7Q<*O^xY&l24#UNs~)G5t6nW? z9pvMks`?%eLi4_;|JD7>YRpG)ZLwJ1T|M(+N53?80r8Nju~tXEt5tmi*hRN!px$S$ zmqXXf5g<rDn|q0kC}Z(CdPA3}PEhitn031cytx|ML$SMgra-RWZn;?3jeDBSt%0op z6{O|>>AZ7p%dYCy)Yf4A>%sj(ba3r&YubsbsL1}cjKq|Jyca{%I?CT<hB9JNeVpgG z1>rMAEl|6<CjXb4c38MNSF<)+c5RZJQ^&^W2>%u^JX-Sz2W!-Y-(A#t!I|8iPoiZJ zXFesV5VuNO0jVOzeO#B;Br7*x>jK$QD@_+#y0k~Klyz4P;<v8H4Hp1GK)%1D+}1IK z3B0oo?qNFmYG5i1$tnU`TcWSrK`PZYs1A5OHg6{l^|d*4W=P*7EEf!U9c{NORD5m) zTaxEzu~HNueVj&%llWV<6QMVFuA|$F$^If*0)i_V1!`u`P$)L;7l8AUkKj3(lgpXS z{Px=#l!czeYxm%E(T@n^GuKShLG4uxvTL_DbQP%Ubb}hw+wYS9)Bsl+KaYwN(5v)- zHDFvCB#UhFiv+bI@HED>aEl@RNrvV<6E@iGZ3~t&^mU}BC*sWJ#T81iO_*=M$`mL* zz1WK<NroX>EC|c!1hy~W>&YZ4{5mi>R_hq<Bb+9Q0}2aKW~56sF1C}_x7ng4s$zHD zLTno_SOu0b2?s`(tD~wY8cCy5Z9~|K&E(~ahUTVS!?-fM$-Y4+jc76<Q=Qkqr7(F; zcMUtR7CLo>sMYFLzu<umm4NrQkoO3F=iG&eFiquzIGLo2_vw<%=<wdze8W4BymMOE zVx?EK5*IY`2wENLGF_s=K3=o?z(di1pb^w{xUfXXrk1-bEZ?Hltx}xU8%LYNk<)@O zu3Y6wi<Yw`E^ufb>aK+>6E6%JC6nlzf)&+WkhQrjfg46`rc#V@czp}<?<|%TyS*>J z>?Wm27fpQ;_ns{@y^J!c=vFT@t%cSD$s+0VhDa}VC+O%mP2$W{o=G!L=*ZHRH}+iB zyU4NJv*sGu$hDl%=FY6jST+_s&JIah$}DB{NyEh_=ir7JY(`>8hsF9D^<nL(yC7XG z2|bG%##8jAK;c~8v2Fu~bAU(w5NQVw%ArU^3XG8FF?*H`eKIx{liGKztl2vHs$j7- z#U|pFtg=|ulcjSqS4Z|8tDki?GT!bNba@b$M$(eeAyio`R_)ZN29&|rC&bCH=!4*p zT}cB(g()0;^`pQEwWA$`X6eF3dDv7e+mVySrBNx+#Y-4&M^20R(QXHCT+_60*$pZx zks8;EE!BQppg}%x767q^R#RwR7V>dJg6wA1CQ0&r$)dic8>?7SsYb?FX+s<k)-0eP zPCsXRKz)9S?8>3NAgoxkaF|R+owapXZ=EB6J&uHEd2KdBhFRxHe1X^V)lRQ1QaD^v z0TSWG5Gup%_H3|J#1E9lz7oh1b1ob3a#BkoGBENSc+1*6E}}zB?mg;gr)PyFwDdg8 zgw?{v)={V!0Ji?TD6-`E3^$%JD+1O^o*OqFxDSumnhDO%dm{U}_m0B68j#uEtLA}* zP3U5zM6JWY5r}H#PZ&xudibP#BgXhl7`&_Z;e+1r@W`^?qCL5siIJw?AdCJ5oyTDh z8cC^d0bE^ni|zKiDcWwO&(h(7wK!p+qv)E<z18Ir{18DhGhxlG%MAG8d!R_~0Y+`4 zNVgx7*^Ch`?g-<H7py|HFRiG!n45`N*w!1%vy0h{nqFwfovvGdHO`V{;o`|U`xoBd zXq9b|B;J^BXha=Ddt{Q=_3s!twMl!1q2AJeg&8><*rxJT7lAMe&&c*X0ZA#69fQ|E z`A~B}E&;-;ZSfR{dwso^kCMX-$qg_Kt1>(r34LT3ak%sX59{S9)9|dP2rH^rbHS+q zn7}Jo@yRT2G#{5E2*)%Aw!x5>c%l9?AAPzG$0Pj}N0GxFDGzfP>Dg#3M|$=&-_BvA z$!L6-AB9PSi$^yCBq^uC(B7hC7kY=$(X$x-8R9=6g8{%{+D(9<vuOM=o(vcGLl%c6 zjb}solTn-aEX$2ONYDz3o`&_SDcS@^?<xk)2iz$EYd<+zL{PQPzsCB)E<Q#hKu(88 zJXhF(tcSe2IO+=ogy<S2Xh>1aLZ=mB!tStOH<n`lHZ67+6*4NS2GXKDd27Hfg_Eq; zRm&}OSm9T+*LT^hg6(X&2|)dt-%hP*$>p>xa9UCz{Pb{f6e3+y3R(0MQiY>?<b2|w zwC<w!+i!wWGjfoWTHUI#f0m+3DqTb~ITnvgkJJw%M_QQuE}h2~y>zrd=dpa0a+ec) z5M))rb4h~ijP%=Y$unu|_;d^Xw6NP^E6l>8bmbV@pEM_!F!h*Y_nt}08D{*eoY3;j z=cv5Knw>Vg1r2YlV&H9^JYZvpPVn-fU%;XCBF<h$sA~*m|JXV^yBP?&dqD`l{kDdk zqUSHa)JN+W2n>-{@QU{xns%tXqL9})qv9H=0qdnm5php>-leD$C=S!3Q4If-j75`< zG?`VWRFaVv@aAWZDg5)#W=X``r)yjY?=BX2*AQpL)pmLKt;&p<F$|K@^x)y@)Xcgp z6lK&ap>Pl-^?j0$I@+7A3nt0eJq5P~0IhYaGRjw@N*O%TsADzAlOP8!Dng)_FBZmz zlRwX5R!6`rc6-9+VjgEFWR%-gx9L)_?CL5buZmNtuW$ri6r!deXXW3ZwZZeVBBft= z0@6${x;@RdLfD(=vSim%W2sL1giQ2|eakaY-9zNa^g_noRt}vm*h_M7@KgsdXDO$K zk0#mYlY(K$Vf<Le-MwUv?$P-DeVomsMQIwKibQ!1V#Qk~C%Y3h<lx0?Wogt1GF?2| zI2J=~6|;-A^XT2qc%xNk=sH43anp;@S7Nk~!fEz2-i|>yEqKFAdAl`@XE@G{u)QdS z@6_LYV+vR8x;_7Q(rwLfPlu1=@eQcWifB8w#&vbmK^k^3ZRX|{gQ#2bzcX>wEdLro zuiAef14(LnFJwV!6FW_yyF8sPXx+5edzSD>Q_ZwVvOzIY($<S&;{HH6*qcN5^Tw4& zURhc#hHV<X8fzy70Ide<8=20q>x}-6b@>1bn{ev)T(6~#@~2hPTC;EWo)z3q*L}%S z$9jDmOm(NIKLd6>+fvWl6)(9obi;f4ZQq6Ve6xAaZ6RdTvZwYVZ{1QOE3(>oQPIzn zHu^A`939#xv89BIT6>ey>v@k$7&aD>eM9j1+IrDXChKb}^ufnYRv*07JyyrqYB9GN z;9(?z@Hjy7R;u^^rKiOm^w6mu6$`^EPufG^g(37_ow86LVVRKBp0aLyV0tBHjV?a% z;8cGE==y!>D&Xp9q-u1n?nxy&O!#-P`~C&C-K<W%xeCJSR&my9brpU4#>BkHciQPl zJ-n}9<@I~3Yhe32R+%f>m0UNF4pRiBI9JLG{k~lvfd#L!ybS%S5{5@bKNpZgG;km< zJk(#7m$!_kd6a#8E?;#Q($_70rma>r+7ucaY9EMm01Jq%P8vX+tl*h(6_VHL8RcDa zxV9!*j}06D7FC@{tj>!W;>^~f$?HXf-a?@kGl(M8=2aLWIeS3(^EGd<WnbHb`QP1c z8&-cho4tt^(TVp0+HWw&wWYPT{B0V`6?bPWmlOCkv-Q$sO}^>64CjhFF`R4Yfy-#l zXqd_$q;+mMqR{T5NTmwU1>(JM_p7shpfCo+B(6eXeI~1Ss~#z8I(-{FTY$-iyPqzH z0w@~r{_t)(g~c9T=`Vlem)EwFkO8R4dsY_HW9b<Vsm~-<B*d3w^)8)*#7k{PTA7!T z1xmx#MB&iIYWNsm;boT~1OWtZhfV7Z%c!R@`cbUzQx(k0Hsk=3Ooc09gkipVB|$KY zk0vUzQjwmGPpKsn?((dt@ng8i65z`Cx*keqD68utJgMP<$Ya8wwjBGSW_IWTvp5=A zouN)T7K{x@pb2NRPwuYornrB`PdBziXcYP+Qjf)<T>kX-Y>}TP(*i3<|E#$!I^erj znl`;1MR7vGR@g#gv0Z@B2#1BkqExWy$!|3b>&mrk<dD~^#<p76tL`7NH<52li+D>_ zcOv#I8KuHiD9+HQ*xam)m%3w7qAXQM99B_oC(>}&5!FbvDx9BeM<4NCZ4p4sYa%BX z%;rSwCPgw&7AJ3F^wv{sqYPHsyo(wz<qZTi_e_Rs8mHOhKx?PFR{9jJ^^6XRt!&L0 zn&E;Z&R{J=4C(4N1>EYTsf81sgguVUfbi6v6a5laTxPe&B5K5%r(eQPW!0Y5<8Nm% zv9KrG0sQ$RDhQ<ZEEgIaulYugN?}LmwF<e1jj?QQG-NRxj)l{HEbQI%tk8dP|LOx% z>E3E};da?AiHeE6zVz}R8H-g99B70^d8XV2h8oKN*1u3&Nr`G;m|X*`yeD<ow~NYV z_gDta43pT>RnIGnlC}P>;nc?=o=3(Kd1m?mN%wQ{Ro=muzK_D<(lsC>Xp8_L!j!q^ zOxo&BTxVgO&hB-K3TLcT{wB@Taogx$ulL(;nu)WTUJjCqQ4~rO>8`7Y?R{9zIaM|c zpSwLtPKD*MWji(2yOCFhXM2EEoiY7Xui2&BK+%R_<fRzhoWYK#of%7ttg!X7t~Ff( z#wRIA4C7GY4N>*~k@v3cZ5&6U@Mq#z3}J5wh#*Kxwj+b4xw0;ap0#YnQsU&H=y(VW z$&o++!2lu|llkp$UAwD$dO%8ca`xFb=d4A{^z@~=y1MRFzgUwAW#%c8p^mobFBLpc z;^(%6C&g3`0NQ|;HvVz-E@_UmgB5U!iBA$zdR&-V%Arhvk2E%eVC*}?Zm}A6i!|&w zi%2={P-eN?cJ<?CR;->`(L6K1nXsGb`zweaZ4MCS_clmM^Q&+V#Yp=&=tMkSQwNDd zK-Y%cQs|$kO&?)ys#HAIEuF8rM&fznMY1X<Vl7}hmGddZ$k^}OAA)*OCd$Oq;O763 z#E~DFN-H_TAe~nF#qIM<rh9DA^4UYQUx@BvjuxOMY^Vtq^KLi6e#e36QdyxnrQ^yd z^M>g*4x3JWNc=>@9BT39ABd97U4I}#>ZlP$x&&p-TOCS^O`I9MHEgHjE%pQ6;=r_i zJ!R@pjGPJ$n3ABu>*>tpJCH}h(j;5<g1OXr%%*WyR<a0{Y=$;H$rpKD*CsI3M0)jG zFIHG0d)-9D!bPvXwj=(odEiw{;jJ@y-K;5IwZ>mA2Rps1!Ol(XOvGs3Oz^^u2-E}J z!vzL>EHL0>akSq-4*v<|<~!w71~H?_kBxpIUBX4ns&o=V#!lsuo?^l2DZDi0oXtP< znr!b;NBQVI%JA)hbj!y|yG5nehxB<<%iIw0#|b@3!%<#Wg=)-x57uki55pZck`SwB z9)(%zY%!e_rx|`*Klry;>QnlY6U@`Je@phJ)#iNef>S+;&qI@`-p-&2K-Ap<w~Qv_ z-<#9>Z`VgY_Ik#&Qd0Gi<8t`!o8|GbNyToTS#2Xde+(Dcavn9-he6V#{Im#@w)-cx zohTnv@|W~KrU6-R`7IflY^KY=BFJq5D`6){4If+&7z-yWFeRYwuEIp?mlnTr8Q0Yy zSGNZeoZ1OMQm)>5`zPPOkT6CDSv!WRvE<nm^Be-RqDiR~ni|DNVUi!qm7Gq^T2|>` z=q&tvHzHpjZMa+ws^llX0$PSSfxnwzwcDTtbhy)a^U_N}O-l+pyF01uL=lHB$-(SB zyHA`sI#H4Jry<dZNznWV#j=Vl6mUm6omJ622>6WW+=P@$@UAma_G-F6mwTmqFdeu{ zFTr=ON;C%RnSe+iWfs{l(k#u&d}9HOpjU#D2?KTK@}M(yil`sL<Ns_rH&XA!?)P7` zl3eeXh-M6?H>o8g=AKXtTdZib&(spHG)vu)$wv$91?OKM3Wsxd#c=&B-?Ab<JRYb> zO!+WIXtj`<Xg|Nj=v73};Mm%a1I35)ivRZI{L0P!(3CwX3bl9VRmpX6VEhbMp3Gad zPQj6N{BW-!p-*#nz4)w8dZAqeS?BJpTO%T|lEo-rTte1qG%Bo&MRivTc0qms2a>3! zq3j7u6OZr0?IXh#xfhzGD4p&d1&Boc_WB%LOk+cB2y6_OmK7@Y8z$K^K$&T-IV|F> zdR(u`R7iC{Otg>o!KSD1(dge?J*SAEP@Up)7=<d6Tcz;3xM3yOnrPTXL$67{rrWzU z`jJ$>k#Ezji0s2IB2qve)?uIfi(ACUSW!rbqJE2sJf%T`lg2>LyB+5+X-gwe8|$F( zBomz~3ODi-2{hlgktswVqsyVG<OGY_^}Ls>YZx_8;Vz@Tl>TefC6GB&DV*;jK&UW_ zLckqFGt)dV8<mzD%K6qsBk{wck7?-V6$aD7tuxH&Y!W-KC&4k{-<Feia2<Td^?JBg zZ5P{45^V*<czwWUsEwCVYjVIdveKX+01f?hk6ubhi?J*<&hZH+Y3(=<GfZAE49DoX z>Hv$*r1uNU2!o=@%z4+Tq}<A*Bw1-BdW;aRuZ%qZ)?KRWm%PBZTFb2h)2(Ez;aJxM zFH|ZQx6I~47TDyvoh())$o>oC)1c`2dPVcF#-cBYJXqhkxmzixW|$SXP3)LD*dlBS z$|x1TW?BTcUoorOrgKNQL~P96YfA}KIOp75%V~v|&s`zUccfdZ#J|CDzH8;ICIx9z z)hrtBPJQd`kXjV0L<*pb1*t?DhT}ZFadj?lW3lBM$(E2<xED2UNiFJ1X~#D(x<the zg66dio??-PyRWwl#r(UWeT}m)1JzV2Ez+sD>}XLDb*X8dH)e&c!Z%O2o_ZO%n)Q}W zu}h0Z(=4rb*&syn==niDaLSKmO|ctThbn9lIk-*fBdz5buqew9P8fa%o@P<AX?40O z&Z5p7Bt~5CENXYh^|dkxD5<d`^y!FM1AKRJRu0d;-o-!j@#24qEBtG?n2+U8OfD&Z zl0!KBT^CeSj7gHpFhoX0q);TOt3o#~kkj)+tWSP40LXO?dFn^qcB9)~6QfhlkZe+< zhN(~EM3^{!yBi7gcFI)TzF|HACv+FH=q*XCn01o0t*T&+DPsW9#+6exX9MXtMEVFv zkz|bP`}_0NGi%o^h6z|TRe11~vpa#%9)>EC*ECo0PU%OIlHrP|$d6Sg)ka>`(Opg9 zu}?y149AqVcgS21V#T7-3^hj;iul<YV=OxF*k}XPcJvmtnjV3xY=aZS{=R6XeFaD8 zz4mM$_*xD;-EXQ`tA-G7ox})g2}R&nVR07Jb%sT@<5~b_{C(67Oge;4vN#Lao34d& zdrJ3%^U%r8r=um-IOBi&#U+{$s)O+7{$fyf?#X~0mlODu|Ly1JBmEn%Ts!PuOQsF? z^40mU$o8}7!S!|aOABk-RmC97vW@M$s)|LmE$=sa@UmK-z_A)+8yl^gz1H@2_F4Zy zfA>Mwxxcgf#nuk||A*aHYx~~4R(3DL+Y8;GvT_1oDzf**91}(Kv(C5W@jRbj;mV6H zG~LE;-ogbiS!C5Yzz@!LHCW7-MK4<dvvwkXW2HO)3%HW;mHd5NE-p%#xV*{Fi!pje z&~NO2``+nzdJLo|`*a9{(vU4<vS%R6XfWAP7l5(WURFg`;k~(N@3mTMh*G>Q6~OP8 z8+_(1+r>YY<-F*WqY7s*9%FSt>c)K6!!5&)50CKUHQ;|UN`p|svz<No=c^1l&~T+} zbF<_w*7$p9B@;M=W{2g`5$+qD_38LM4GoWAuc3W;l6BU(t@N<AI0F>VHl!z7C~3Cf zPfRIP46ib{6|)mAXt<GWX51n5cZ1Vi!`ZVHL%POy^h#H(*^JS_ffkERZY-b#LCaB3 z2c8VeqUxC$@r-c^g6Kde;L6B0a5E;S8?qu<kfejlY76V>BYe567TK}91*FU;Bm9|X z(xqDnj%w$X!SRmp;w~cxUFhJ|tQaB{AH~DDt@zl%Tn7%!E5=k*4Z-gzoy9mrv?D+} zKSZ#@-ur`kZ`kY+>^Ao*G<1F4^d5iX(b*p#=G0&wa#Z)^`N=##rSaiaIie`QMQ8i4 z|7QDWyBi*{6FFlic*xv$=BS<MS);SVBObbjhbM5_^eFK%%)xN;OMYe`&m03air0-x ztLPN_b(cM9+{^I5xNdvdY)*MLUN9W}QX42qxw)z6lmO)#;MKl8?zhABj)2X!vfTi< ze5_MYN+Q3`x7L>E@0#0yJM2KPRrY;i$}~cVqwx9K8vK8__MXyC=@z&<0U@%4Ly|3k z`Ksh_3zYkhUOf5s@!wxRef9d4EG^tYzajnT1>Vdz2IeJRsXC~FDf~tbZL|OZz}?Vf zO`>9J9n-aAx@(yAehotjg76Ih@cCpoUXFkaW7>~F_SUf(+f=NtsJ2gw>G}2#z$o?K zR*t36-<kXxV_n=4;mkby_75+=&Au&%#iT0w%z(_U=2)>e>kPZu?w4PFxdnX6=h@TQ z+4K_L&S(AX(RiFun+nNJF@Il-q<86Qkew|Sv%&WE#f9UQFc@Qd%<p-i35zkPy=iJc zG>w$!xu;*}<)q5sES1w`l`W>zF(VT?zi(@7J~9=<<(Sn*GRglYaAi6U0<Digq5<Th zZ7XOUNZY;auyqtu{3N#nh_;_mp-cD^?$i9z{mw6Y85KX)C-eiq#D%TV1|hYB>75m{ z6jy#3_UxE;4pV2)OI+6b!ZpY+wLSH*m{JQl-PlVXpVPblJ}(w$(~<jJO?CWome2F^ z>=#_{4G;fnx||PXD$p;Sj`HLR&Jz5cQ&APyee^Ytj(-yh^2hJZyx~E-plmwhowD7% zB4*=;-v1CUx}Slh2Sgx8tq&G=-Z~!B=i9;M7_PO0bMBcL_OOY+Kwy)udf7!UJJUu# z>K}h3nsVt#CY`QJJf~OTvnzad0nZ3N7x?Q;f1Tkk={WrA!oT@r_~vYn@4_)W?%+Q_ z;Wjq9a?8M9d&(KX%flVM7&eZT?Yqi0_x%zKABC-VrS)7}U;5TR)>>=d!=P_M<c>~# zJG<X)9A+2{V?X>c{o#Z9YPR;Xvs$~)>g#}Z7mfW5gZ_9TXXz<?R-e23<Rbh;>+F)g zw&QV0`8+-8ukpfj1WXYcNm+)+7LUaF6!_6<$$A?&Cq?}nV<x+A3bf|l?L6yQM8cI< zSw+YDBhPQ@GtO8Cv^n_FJp~CGWb5dJKbp_;D>~p+Mt^4@zSQU&K?b>mEI&oszo?z_ zCRilSdoWEp{)T~s5rK6~vWM6(aq+_!bhz(AXGGpqrWro%UuIwLhf{(_zx!Rr?>6b* zi|nho%>}%wf5of~d~sFp^-6oal3vg1y`I&2y$V@)U4-y6A=;ye6CwKZ$q8y9%$){! z0HSZkk!rZLb-XV5qubCJ7%7lSLv;FXd462XZ?X%2T~MWG-#$CON`G?ZKRGLi4N80? zE0yVdhlRzcMKSW1p+!qsieLkg0xQ=Ep_udjZDE5s@6{GwKy%&c3mE&p{Kh>x!{0Gc zvFt;MmAfm3a7OjujATpw<dak2GE=~pFPp&s8oHu#_r4oG=I59!Fi98Y)7cODDRe!Z zj8=Uc!uWN=Y8Dq$vyKeTDxzOj(%Y+SG@WcL{D+B+kvFn6I!D6^>;n0Q|GNahU)|@s ze;0*>{8Bc|f7QRFJK!pKe`VfZ(fiB$_`aOzhHuIa+m7%A>W>TVHTddEzdEzs+po?% zKL7)6!9sv|?I6=|g+H(8ryT3><R&jM2L|e@r=2umU(Q$pjQ05qP>pGRgn#ssR{{H5 z67xP}B0+sA$9arfUzMYRzBgahu$JDfA{Y+WXegal)Mbpf_}1NJbPq=zgkOCFf=H21 zZZfi^yej`$WUuGTVw-F@h?$sZDP!kKTpKk@BK>25UXrHJv=nW1iakH5M`055PR7%V zzwY+@kH5hWxXt;+egF60?)Qkh3Gg0<z(0oe1k63->waE2{El$jVQ_@K_<TqoxHT~H zyI=I_@G5L_6*OVa*ep}d-%c;+6%m(?l7T_0<(0$iH4h-)kd6S%IcV@V(}0c!%($zt z+T6E$AP}<;|F-MSYP5d{%=+gD%J_TQGh|8qoVjW6@Nf6s0mpU3t*`FKjX#<aJf`NA zkrDauu^}gMcBy^xPQEl}_cC)%Aj!5@rtQ@&Z7)n);t!fx0&T`TK_eTGTxM`;Ychdl z1b(?3kmxy}w*zW0$j)v)2((C=&f(o~T#_Mn2r@<!&{2`}*tH8*?;qcouCgcJzsUS6 z+wn)iBb-3T50qk%{99naPl)ch2aD+}_)Ys6JmIZVG}XD{v19IRpln)?#q5BQAJkZT zY}F)g3>pQI9*rkV$H4O+_?#%vfC&-(rd1DQ^)y}ptwC-308!AGa5r7ya#4=AU&7n6 zDy+KDJo-;)3}rZwMaEYrB{btvUOa!Djjb}V8f<T$!gaemCdJ?)zZy^HXZbr=$&9<$ z(k}jky2z}k#;}Q75_QQ|(@d<g<>_QPF9u}Xwz|s~s6qpHGH;V-Ck0jN$!Pf~Xkc&( zUi`UJQi@W#pHxxWokT5VO-YFtix{q@S#Z3<S4wQQvp?HyK{>c87SGSmi&2UCdwd`n zEztiZBaxgHpm~+g;67ALD)pOZ6XZYDJQ?&xx)q)E1`4V6br-%v{MS{Tps^EMU`B%J zasdx|8C*dbY5Za8FYUCS$!Er2<QSH0$PoUdKG5v{Xnq=iCpPh&s4-6(*X(%$L9#?u ztj^eHwMJim0~lPlREHGT6V$N{l8dqilsyxqIRdPGC?uacJ!;GP-Lhl@7+j%k80XH` zVeVq1o3X_duN17z$Z5JaqziA2bp;6kKi`*h1#Qr>P3I>Q?%M5VL+5BX&okeObf4&l z^LNS)2vAdzgrCyVYfne)8#po^0wYXJLgrB1RN7s!kMb6G-NU!6prJ$pv1##)irIIx zf8&;blfZA>y6vR*d4kRk9n4X4r%IQ5t-vmdx)eM-ofzkE)ZsDmn1zmWkZCXd>EzjR zjOY$~GO&+-p!F3a=iGpOg!5bLB)b%F+3pxvU24xrxK}sp%3SAUsD;(fue|06S@`4l zbNYmehG(6^ThW3sJ558y(}fLPG}zR&1)$(x<iNFLe%ZEC&y3J!sfTA+jDRjD?;p8y zs;zuBURM4minpJDoVul#(%kikkGMzO4V??^3E^P+oIJ{;w``bC@X#C=x*nFTvvN@t z<CFe|cVlsV11Z&W8H}d~A8AqYy+4<_E#y;hR-koDoA&Ydo;Oh|btxusCu*7YXOoT~ zHto6Yx*v2}Ba~pAxbde>sR%kW?fJ)!jL4vDyDumCxCorTps&neX2#?DCcUh{E2oBN zgt8Hy1@j?QK!U89`J|>348skCK7<}oy=+W-6q6pOwa&i67FK=Dq|Poa`dD40Zjxlz z=zQG-|43cVJBB#*GEb6vncHI_EDlbVob4-a1`k7K;UEhMU~oP75p7@oS-mUwF6v21 z;=az@yrEloUse*Ed4NfUYi>40KkpJCe3ijjJ}%Dk_i(9eXLIj_ge>4WepC^yfG+I% z@U59-K1aI{^oe^%w$!0961_kMIh#zg(<O*?AZ?)7cnlm9@Mu?)ArPC%RZS=hZ_kGP z^S9w>Ith_lY5vK?-D8>KavZ6^&$^jCzS5C9t!rlJj=eHGe~Y%cyi(t{59nBzq2F`I z(V@RIu1&RG<4#SV#bwt!ZmcOA>=?Sk4H{qrolX2gV$cR<W`RhG@0e+}M-pFRfW8oE z$3@(_hXF^U>R`Bp90%!Y0Y`_nPCm{HBIh4|{>{a0SA}*W3nxEmV7n{FS(~^Y6zq5| zjxkp!B|PrCcqIxW?pt8#Z#e$;HxK~J*{_C7)&LsB9h|70!Hy!5<4O+20hM{Da}cGF zH0)>QOTMKHJJTt98Jr5|sOnfP8WY~ws~>+h-1_cS{lX8fd}wEG`#azFNF$4hlU?lD z<=NY{z;){2r{e@yyxi~Z9|REGO+39lzx=H&14ah9&PQR6pXwmoTm9r?Yvw>NyD^WE zaznQJW!=JLi85Qy`PR|h-!e(sDO<~Yo!`Kir-PUD)Ygxq7J>Y)`21eEj+?t8x%-|$ z>4|e{L2@}J*Ygo4N_J%BnE5aP!Rn)j)Vg~Cd&PaO;;PoT3G6si@VN5?8p!0FE{64a zu}Y}`9)ML%qJQGpbyhOnS^4**7z5!nsz3MO|CFoXpJA=#;wodWKRmS;(>cavv*<L! zMI$4{jtJSfM9#~pmKvM}5rBPySF=ivUX$D4T3S~ZxD(ow$=5(4VWPu}D2Ae*Sy4j^ zKuD3AaMnFK`3>sHe27c32~cUkz3H5EEgR?6Mh`<H{)zuw6vyw%#fF4vI5CBFn|S|s z!uXCgtsCXFcz(`1-kU0Rz>x{)eF~Iry>T`6Fy6l8L+Kjtlg(`7htvlfM}cQp^U!w~ z)xai*GDx;hY-lWTiQ4#83ZM&kQda`P!)zU{jR~2$T!ctT?BGs(BUFtYH_zlbS~!3V z{`OO8>bYSqk1_Y3PCp8)7)I|_b>W6h^<iJu4NW8vvX=yHGKgX*?8#1Nly#KEyAxRv zIlSexEEL($?PZLV_?V;a&~JwXz0j>Ufk4tkOnbVn8y9hvJ=Q<S+o>2X7e#h~OdZ=8 zd1@t0_<dedHiv%L<&*DUXpKxo&+L10<pt(aA3)#La5{sI7VJC7a%URn2c9xEkTP-2 zY^IW)`D$*%7qg>Gd+9)xRXwocrcqL|lIeOl|Ft!R%zjv3I0(^5lXu5T7-E2YL}EQR zy_Q8jIFywj)to{iD#AJ0^(uDKQN$o@AeSrpaK41AlCH-(3VJ&6@pzXSrDmBY>fq3f zenCGMd5IcQ%#y(#LplcFuZ%%abQF|NM{Gy?*Tbp<$TBb#j_Hy|TEECao$#h0F5YJE zWu_kj`+SiV?~D1B?}214c#J(YY=P3EkKcn}zW>YjLRULT+&$^tC`Kg;MM_+Ob*Zwd zJO}bNCrafu6DB$=W(x*5EN6IDAZcbFL+u9Lk;x2NRy<6#AZzZJoKN-axaFVXBoqJ* z8~BuZPM##?Lb=I}PU2}a7j&w`$%@}CdT&F|q=Y7)nE%U%Gk~7COc+!?*x2$T&LCc6 zq+)xVkaOxwDhm79JMFp?s0=)NlBURY`cTJ6#pwUHDEa>{$`Y>mu9!r6Gu%e@^XDDi zPcg>74z=L^2Np!%20SQ@nMOf_>oUn2QmT^~8YCBsvAvFb0cS)%GCl;zLpF%C&u`Ox zrK9{>nsmZdSgQXtDm`;EeeK}oo&Ge+-=UQ*H_7Ctu!!{p63!~pV~jUOCGOPL{KZ-z z;3!_O*0_e4jU+G5R={>bqeZnOZtccTma<HzW}KXs|JL~5q!1K8PSMS3iX`!ZT>oYJ zQYaT3mNdFNj|g&|J_MZ%l7eE>td;Tj@JT0Gf|!`Co^s5(J`Vc*AV0#VllNAKC_n#C zX%Hzof%SjGIPSQZyf5d|35ju}Y|k<NpOlCqrfUutXuBBFvcE&0IkW>`O_vg*a*>OG zJSk63lwc0)UBK)BR{$GeuPXZfEPqc+L_$V)E3ysc`D|KMr3NdAgW;%HP_)G>j{YMb zFw%hzDefkz=!E^Gr^q&z!=$nknk3y0Da&5|9tGt5eR-PGZMnpBL8mPA!sEXCy~iI+ zXT?14Wvor?Wo3c?x4TRKz2Ae2X83N3A=N{8@}zhVTiin#YCfe*59PRcG%I@<;LilT zM^IIPAy=f|t6t*MKzDkM_MR8$Wca5g2w0te;C}<XPTMzWXQetzW(Vd|`KnJ(U{?mt z7LFo3Ey$}?`RDI`7yRxYFU#?Wk1%{D>w%B9AMu~teT;kTIA9^2WDsGaAB*GvDHo|W zC8{UZr6sCL-SD057q6Z_-99b5@n`(@>E&z;7vkKvz}*63@m<a&p1Ll{4n<vMoi`Vo z-8cR1KGHAK-{I~NHQ&W(3-{QSKi_ygr^49V8(mZYZjpJmlV~@8KX6U1uQM|p-{w2u zLx%aR(1vKzg>n6kAQoW&b)x^Lqthao#5%8T9j8tm-48nA<-<&9Y5XrnQ4oqoV5cSs zsXyS$)J_3Lr@`|gAL^uVSjKtW^-lRRA6=J()ZJ8<avGp*`x#Ii%xGp&7^c&H22Fk_ za!l<Rz4`MG-$swt*WsCDp=2Lb_zlC*S)=fm@GP~7Gpyi)f_+*#=lSK<h~~dV{`rIK zvxhsg%Wj)-PSGAg$;-r5@EN{a|K&tGez<dM$CfChLH{GS$f$|m1a_##-DXPR4x&Bw zcz2?n4L50<H;E>R?t2({`2DNTh1es@$tPIJJV<@WL9?<KT1Kxc>b=UZD&!f?a=w*J z63I+Ts?co#-OovPJDFyfAQRssy+?72+)ATw0dW<{&`Vix2>$c{qMhh$V+PHFr}k#M z^Ja9fyN!n(gN{Fc@Y!C2^82w|k|MlT<UymNtKN6;_<JIZmIs>6k$Nqz_>Pc=Xg|m# z=1v}wYn<bEsPRDVmDb11M4;b!m7l<+zx^1PcOZf3sa;UpyUvX<XP~#;>e-#Md;+ZF zKa2S^G0*2u({n0|yUwS?D462ophT1{JprPKcbx+@9>_(1_nAy9d;-KW`~FpW7C>R| zItOSvARgmG$1j@(hZlF=gzsMs9B=cX6A)6Do`k%->qMma!0}ffju%3RD$+?|2t#sS z5ed5M{G!hWaX;aFU(fSNg#qU1Msc2>0y_*BVz!)*)00~G_OIr5#+>l0K}H!`2Q(gV zQYU+u@aBupdOz%p|M2~j@!6w4J^JR+^GE!@m)qOhSAYEcn@3OS=ePXyn@9Bf`8Pj2 zdi48txF#3u9|RcN4HyEsn9@HWWKiKDQE{L@evWyM@s8qLlgH!f@EwaTC{^Q})1aA5 zALI9wHu=t*<-R}?gIDRpUxQB*&e4G3h(BPO=&BFoFZ*&cJ>fYvX__gSAhE$fd2%dN z1ClF?2*?c45QZIU*aes<OhQe0l&O>aO(xI{yil{P3SJnVgl@j@YIi3+aqa5`bY<ty zqJo>gZ8pd}+j<|k){ZkR+E#d>|Go?S?C#D-Yy<KfIjs-%Gr%Hb`K(N@Kp2Qsz?UWi zC%*j(yogA^J|BvCaVkkhQq-q-hK*LuP?`*o>mxTh?v{A|?Cb1dm!>=_s&|X&Y>=%p zON^T!5@>5JU^fSWMEZdWm(lcmn{tn%V^bCAUV^9pS5z?K`Zk_UXDGK*dRlURW8XJ8 zU0e8Wi(c+D=xtEXRaumAB!rT(L+_{Mkd-0CXTe0^c}d5ZRBu&-egt--@8O=*kAxeR zatISoG4mL8DuH_#HR+*xtugN$t>h_XqM33oZxsEYw=GH&-rmz>yzni}=LeD_f9f0z z=-D+Lp34Q$h-LSha@=prH=|-UFNQfsQ6M}2uDH^a;6Ot#%kWh(|EvG=Z}cbg{}j}M zza7W>V)~xE7Wjkk8Gi}=n>ujWuDC~POvN{Fd?*0k?jbqLIOYA+*&f97z!~@BU<WNQ z)X|Kg6LNF&>i8j-Gcq1a+)-SaC`c4qd)sN~mSij>CK7s3$Q|xRSuFD58Fdv6;9qn$ zFmz=znz;=@P_X@Za-0HO0%pUNKr?lmJ{WF^8c^ZNQbnRZ5_+Se0ea@e-J$mfG;)!F zmC=o}E4mbh)me_35;*Od+%1^JnAoXV4s->j|4~uQUgnZ%!a@{FPEdc(fb74bo}Nt4 zJ2aBBJ#h<@rYv8$1cjV!*ta4R3fw0@l5vcisJjsgDx6V=M<O=rqR1u%N2M>2E8*-; z`U&1fG#>XlMXdrR4~Ne-;C8^?r7x@&kTD0`BW*`MTrAOs63jtn$C_|Vh$F9&T>^O< z)1br6h^qAWJE+a(uh>zp1ALeW;m`}gcAxj8k3TdhmtJ7DGlaKzi+=3_0UXru_2G_p z>%8Nvc5AajE@hO@M_tWfOEc0P*F14{w)(E)!!}n>IyviF2DTtkvLdfrQ|<Ii3^^?E zEyj2Q<+51rOc8PoBBleCg_eL2yo`DlzRS)O_yy$up9%tFH3f&aeAKxAeHOzgU9Y5) zSJZv7JU_pRtj%O-mJ+HiaVRF;J>^|s?-u>0Y6T%P2pwYNI-$RZ3thYUcaDr%prU~_ zcudDdW{eW!83IBlj|6-HDFaSDqbKB<ImrTm%P7zz-^<&4C*#34H@Q1TM4Dj8(Q-)W zagon4aK>fz_TL=ha4w-YO@tr8J_a-3ry+W#P8P^MOH40N&4=PZs-D%1TMI+-*6bs9 zi2Rp`L@MK0r~*q=%u70{V@st)XpjNXa9Nm^jtHj*Zy?wa-Uo{ac3RRB<K1vt{B`?p zcx|1RRfTa0xE-9i246UzTbXDu1kwu2(6JdHXwpZKh7{r9V;b0}53e_nDNrs4YGS++ zxa#0^=(a&F*69UY*H2Uejy6QXMcqfx&IzTmhprj=!P<807wb1dX5TR7O%i)?N$`)< zB>lEHp&3!n@CN^lUICrm;-m=XYwk1ob@*zh8&B|W4HNuZa)Pg?vxfP}n-$YbeH*;l z3DED+2oJn19Vzs^<)$CLt$S~9v$A>;RkxxrXr*@y5ITeGs}prAWHcmgaw94ENl~`? zi)g~mX=PQTv=>$Qg%M$#g(pKf{b?8uc(Z3fiw-X@frRILH#ne1&sRXzw0gCmTHmYT z8u$Dg0ygTp0kTo6yMUG}>v4frjikO4XkA{QCK#t0tN?bZc^c|#4LjM<%s+mj4Dpyj zsKV>5ethnFx}GV|au<}TH@?e~pT%quE=%tyDMClAF<jyg!*CuRM%!Rysw+{k5v<TP ziI^}gLG_;RgqukA2POq%7O9=bm5v4AIS|aM@>-snf4vcQMH!BinnWOyi%QJV033?s z<b1whO)bohTyVF&M>X&eGPL+qpLo9c@2J<Qybo@Ld1`YY&Siy~cuCf94qIE!#vD{p z)fj0M*1w;ief|pbcUb|raQY;hh(Ti6+@<Q7>|bzW2H6HpV&lf;oAmwk-Ew4uoUbXh zsi!JpoFJiCmgAg?1(-Bg$Oyv&O$=b`#;lmeTIyYp%^@{W$8`E2uDo14n*whlU35H? z{Ft_MD1{?4@||83bBqXmU&!XN!kI1UIo+@Fu}a8z!jYFQDOjqaL&2ycoHfc_n4DO@ z<*X9JJ^|&G%N^C$d9*26TB?PaU0c}z?6vD7p1ghrUiPv!bwMi`Qd!M*uLcko{ABm2 z0ho*V)hpsm6pB9k021&MTs;5^_|j2Ne9hqh<|Tmn_$qr+7N^tfC9v9)QnUPxOyWOi zB2iCT$s%6@b3#sxG=ON2-vVn43{p8;^d}d`(@RnzKYtpKg>A_IQsXq?w=AKJ*(BSt z)Ord4j*2$Hk8bhJ;bJie^|WA0y&oSu_RN+dL4!8&Rvhs=Uf(r)^*S{t(UFaqcy9E9 zvuU>7bRzSIt##A){eB3VNoPNz-}Q0=CmWSdXsKjwx5tD;o*8;#h_eMw)5eOIT_00p z5!mnt+;Jvjh9YrIP<`fnz)#=`xl-DmA7cdsRfR|r=M#|6I6oqu|LF*WFfpl2s|I!~ zYn%XekS)mDEI6p2y*x2jB-{quOVZ#53LNrC7b;YVkC95*<P6HGhG2ft-B`PCyph6W zSz+j9lJM%il(#}<&2YM;D~2r&J+ulwgRQ8ZPw4L#B$gtn`nJe1RPj7~KzJY@tE3lN zFF;7z#MsIwnEkceb%_u=4><dBeGoKwOeZuDvP<mMRx^MaS<}y%KRv-8<>c1y&THfT z;zu1|P(1v=M9Leo?lCrVFP4i9D#S$~gpYTXb9`kkn>vegk=rN>G%PPDNM(EyT#b&E zqBm~O_>aB7y82XEBh)%Ev%txG=8oCmoC&$t1gh50+ES@#Rp^mU*aY<B{elt8=KxL> z_bEr2Y(D<UDNO*c$J6OM9N+t|o62uAbvZ{B-2PPW&1OuL6(CXVVcLUnU_)S6ZVG>3 z&~V8w%lqJ$*}iECB*pzWgb_)(a^&+Xn(vg%_yh(p0qo4Q3A2X;xkKC>qED#q2Dfmm z3k>aA7ndc5mY<VN_t?k%AtB3ze3Xu5vzhg!2cJa8^@*$2;17!Eplm+w5k++)aaeS{ zb=)W1K`^BSZ;f##%x7YH!LlrAKvi-BJa9Q=fnVSovhwr90al7Movuy)W3ma|M3QE3 zHq^*CG%-i{L`CUFQ&}x&gOkl#q-Xb8EwPiaA~D07(c9v0i#|K7V_$h{Cd6u@4|E`X z=ymY{F`k~aivz1%r_<qZIgdlDbSWI!|BC*Lai>U60&&X?AhkDLFqH+IkErr<eVmRv zJH<ShSboVy>jAkV1UIt2wNF;|{L_pLwZH&^8pU8!1-j{cM}P6fD>TR1At}PZ`S?2q z=R0d=QL^e*F_Uls58y^wl}Ru)WEvUd0ux|<XQ$So!zcn&L@3cdgH##B3*?AcY9i8U zcv!T8P-F_hlL{|gGKx}}6<|P#--s%IQd%+IPi%@gOo<{qXnOImu{bCaH}W;d;mC5x z_ZZv`3JmTrE<P$Ca#jioq@as-b92vF(Og5S*16|pO)Uf|wK4-fnmUWV4=4Q!7BY)y z10N17bg7~cLyO#~Wc%=QZnrP(9mpI)y~0{=a_Ffd5$;WqgS;Y!;snd+l?(zva&kfc zB*ZT4nETu3ezl%lrnzL@3zLTK;tYMhI_1`u0-4NE(o!o!tp$h08>j<B<(7KD=&oba zzGGul==(D{a*+;Y0#`sjLXsD=NKS{z6GB-jZsKGnois}=?I7z0qCX2A`IrY)Wd?U2 z@mz30`T@B+O3<br4Muv)HdJ`qs7F@Py(-r!9#c`<VBa?`<t;KG<wUg~e!>jV%=4k! zp7Wgh(BeAR?B-#%A!2aVp64%JZR>B=c)NY1w5LVNnJwq+AV6gmijj5<i{m%MlP&u4 zOI;dVLcp=OB4Hc(W!xTW%#nWJ9Uq9g%209`p&f}!=(Dg0Z$1|EOwU-8h*GhQBvymI z%rnRKZ!4c~2P~Y0(?L;Zh8z}8r>`M~24sr<F8VM^zVF(3$i%(rNItD%sG9eu+Du9R zL<^vFXlG@HlfU}x`0*W(csGuwYV_P5OV}lrJU~wqwP!n^tm|COSa@OWXUVH;&o&~4 zTrgvyw~Uv%vIF@+r(z>hiHy$6M%0tqdS&V6ZG-6HVXMh1BR*4)>N8yTF<L%QmyRj( zS?=7Xe>u3<A6J!7F_y`b87HbzFkJ8yI%szdby14yb*A>HC%Qb4zuN$y_VIW*7wUM& zGk%B7YTPOsm-b0!Lz|?_a$9uE7Tm<dk*{UPjiMCcuTZN_2~^4=|9Q5+_%-nMq$Iwz zxP2tTVe&j;a0f9vI^ch9j`qTffn-IqW%_5Tncr^tYfojYs98<CG;$@HdXQv=`z_ko z5Q^258FJCr;mMslL35FqV2nePkRPbawuWOu&+}0ErCuEVW{PiOkC)b<;^l&XqsNQg zAyG&nYp$YhL*xWDi3f3(S=(!B!d(8uG8ldd&e##K2I&d2DjqmS<zdKgf1&_XiG(gY z^8Lc%6bW5GxP4T?Vm119Q{r{tbr&6n9Wwl47J^B3UYt+oYFM<1AUv8nQ>%*V>ew2x z-F$f;U%AZ@S0`@*oO``jr6PT^AkRqsZx!Wz(ma|wO&N>zPVOeoyU&LyxjyVgC2g<u zy%9xSXuFK$YdP7sOW3!G)<Y*=(^_BTv%UX^k|!OwP?BS$Qsu|o37|EC6ba^yG9rZy zhjz^uR4FM|KeDVR>ek>aD!HfvA*NA!Ymnbk5?q4}m%a;O+Mz^X;N{t7;;2<2DY<~o z^O?yXp1eJ&vmZ!pnaGA`8N~?Ic)DeSjy2|Uhr!|#6FMB0M}5w=v%jCE#!`3I@IGt4 z?DnEB1F<)8)Auranb+@lFYU;UIaayeZ5WFudL6SYVpN(Jq;&P}+{bWHuy=#p4iyF7 zm|<eoxSbZI-luAsWfvunVZP`j8o(B9X1m?)UPHIHaR?1xHS<SzVv<bL5XYlcnm%uC zk#Pix@s9DTJmX1#R4z|td}IZei`(}fqp3O&mE0#l<`P&RC%?xiHF9!@kFgi&>Y*KJ zC_AR7dFy&ftWAhX&HNGaqW+4GEm2mW4&0%2d3DCAfsFmfSFea-u7O`_Qj24O#YrDC zlAX^MS3RMvj6w@Bmvj0kUW2`q9MN43qWB`Tx-f$@#)~jOrs)0>+}A0v8@p53+Hw`- z@~82z<v1h6SG9_SF3Ui%Up%u|EsNNxi#J)>!3<j!3r<Q*9y<KGt|ZoKKmkV^0WIQ7 zQOS|!N<YAUbW+ZXe<RZ=OrNrvI9h{^hqB8#7Skn}<K&dWtD)2BF~x{_Q_)9qnmCgt zK2s9USr+qu8Ta@NrgREJY(NqrqYvtQ$eRR~(2^o1qA%ehKR&4*6%-LY$wV(SeyF09 zwGqHUb6!}_&^Sg0OF4ohrJsX{Rr$-sSyPSOZ?&N#;$mxx7@VBZ#CRI=V?KVDiD~4? z_b<YDCV{b69~!{dVhUUkADI*WQWh8HDR=RsSmNmH3&SUaVOTanFy%7a>4xbs8_qQo zH};w!Bcz5AJ8-Ivs&>HH!^iuS3b{rnBkG9<2=)aqW;_xcc4;;9#R`%!G<g{APBQ{Z z@sWp?My{V)ds2J6pg9))bJC=dE&q3lfw)1&*E6-ZI+q4RB(JVxqJjJ%vK^yoK{q-k z^+ThlcpO#VT)oauiSHmo16+g0`SJJ)W3}wwF(-gVMr!6VQ4m=d(M(|<0j{4Ktrm8u zC(j1;xHagFFRU8g&t#iq^fkPihmkRotr|au9P4OhA%0q^E;<|cR2C+|P(BKT!h|sF z6;<+qal2Wu#mP-h=)qP~mnTKFm`|^)Yk-_ha)#jiA)HfW;RuMR&EWXGtD-YG;{KW< zAS%atx&Vf6i_?5)A|OvVhs>}bdj)^xPCPviYyrl5)$L)?-~&`NMr?Gtdo_spC;{=C zG&wJximyAm3|d#ly?QJ15|NtNJ@twY^H)+r4jtBi|Dl;WUX}m+=Qt>^?w|Z0$k0I< zG1wHkh3Q+Oq#eiQ0@Vrw+BR|(om2h}j0`71M&DG+V|h{h19>3%L1w_>L|dKbmvC+e z_dowUGZ{c^_4N?Q+2dEQGEU`#>G3D0nC9sHfB)s_53ino{~flIRaVseZAD9zWqG*Y z-`RQCga7V+mc6CigUnkIlJ*b}`dpP0xvI<oXgaSF+lxoq6t_2XcuQ$S`_uWU*%T_v z1wa^N|NZ3A>!*$RMR>ibG^~8(w${W>0)IV)UFcz+%EfEAQsJ+%`s<5t;orsdT`?*D zS-_v@qflZBEj;5`b+@%P1uk!XKCKpyIZX(@gASihW?1k7J!zjTXE1Y^ZI2TmVup~h zzlC5X752AKUJkw*1%D#-HV>aye|$|7n;$PvPp|&;>XG~V1v^jmFma~-rKWBf{kbqG zTTWeok>)Mqa@^)^Z)cm?R>wFRLtj9vxV-I?si}!&XIsuGZ#}wowzL>1{z-@bG2DBk zTp|x9`qk+wgqvOp%;!z-5!&C+N1@#{%X`^z=Cf=7OMq;RJ_@$QSb%SQj1?AFx)GTD z0eQ}Ryfs_SXVa?i8I56d_*7%Kd?{V`2<G?V(O>`m-P1ojdj0$_Ptm72`|7Lg!EUr0 z>O4;f^Zf<h-W{N|eg5@Qk}^SW`Fu_V-ElK0eK<Vm!(aG&S)Kh|j9Bs<p2&;v2`L=q z5&hk3sWU}R`E!uz--5lxG~$%@6E!Pr$^<@aN$q4PO4X#TxJ&(oc}U!jAg7a=a%+MZ zYip(~vu8g@CzFNs12c1hQhO?K3EOJAcKcVF;05=PlEu=l9&;`$#MCy$t`(zeKGX0A zRRO-vfmo4&o&K7Q^D9aPG@p*EYbx`6EfjWieO8V}#pJrI&hyzdYKE`Xz3duxZgPz` zDduIp#sD6W-(f7Y09-($zX*=nf(Abnr%SA7fj2=>aW>PI3F*P>=HdYn!Ph@*53B0I zRweYi+WrI>wM9|Qa`brdf8)vy-@LiJzw_qJ;?0}+n>Uj;Z%&SM$YjrOG2GwXhSeiY z=$|dl$DfeT`4+5qt8|%%V87kpI85hY@CN?ZzlQNHwvMh3e}Zv$cDCTZ`OZ;yQ^$O? z;5z^-3CipT>4})t<@%9dG8_YaNE`U(%^^}Nv-ZubeXoPh%tYZ?7iJo_WY&)Is^WFn zQ62bw%vb`w9Nzos)9dwr9Ubg<)1S8evbeHkc8*r#W4>qo1gh*%`~Lh0g|&**P3G|f zPD;o>K09jj1P%rp9S`B3@ZXK2?!E5D^_zD5;!PXhylG#j7T>*2t)PAH%^SvwSye1Y zQ-bKA0eElTbnp!?{55jf6vIb85tMuny>{F_QR*C0>&O+V<}SeUXXSW-%3!`yyxMHQ zeed?Oe=MiyMddc+!JdbW1=Q!XQJoJ5Quo>|<$fP)%FM_BCf$C)-A3Pbx`5+HNBCuC zkPyLh&-C{Id7rBV>9k01AE8zM9ye`w-@L(XQPu$Hgr>TfOeb3frR^SJ*3FV+48M13 z1jDBkVTJ9@)(+2d42DFs!!#wb4*+{$9w|ZP943D*askjEV1GJU`=|Oj+Pp>>{3Po? z>MB5By@|%30<+aVZD*AGZ;tAS{0?K>>m{C1C)5XsCHaEOYu?&Z=kV*zfARi=Z@NuG zz!+{P|AaVK8)rW`4#4AR190iyL8@yyR0b4$xT2o*#L+?nnp$6Hco;vGeu>XR)>Sgl zwVyv}52CL>NgZZ}?ppitw~t=Es(k|cyXvFYkN!~mB+>r*@ZOR8=F#idKh!>ojuE$f z`ReJPpM0NeYXJsx|Ksy->&qQ<=&GemUDv>NF0LnwGyK0T{L$U&kn-Ysda^|+V3?{U z2qV&76wR-vqY<2e!%eu^x}7(e(R*^8+H&YgS~c_r-)_QbPooQwfvjCBypThw1DWqH z$GzaDd}==<4L5t#1FapG$MbxSb|IIR3&}vg1o>YQp%uR91@c@kzkkIk<*^;~@G}$h zpK(S=%_|XelDiYFiBICd1F`tW^(kx#Z;0O?zXjq&9{?3z0wXc%9uVZ4K-W3gKl}+m z|EU9_FnT~BK@zJpr6c_kPVX8Qk^^sc4cNDsPP(6NqewVEqtyTO#o3z?J%p!@v)=yc z@TXsnHsAd6rn>j$P#(Xz*cKZ8G_T6>)z%Eex&pbwZQwm&3*M6~{`?8vTyT8wA3A!O z;cDi<91h>fX{PCZ(m6zq3b2OiNL<6Qlm{?bnii(6r*iJu_91|K8yCRW20nu8@6Gn9 z%naEPepTI>{gWGL%U>tZ|8n9+2#|m-NVp$I`PRwNFT1@jZtB~0aNSAJ=IcK18<R^6 z;&CH*3F7ZPnf}QA@uTm?ixy|)Dat$Tol6`^@6fGm=W=%k{<kMdxAO1A?1MMwa5^ex z(~>l?=w`%ffdQE+Po|e&-TzF^%XI!OpR;XaJ_p$ctK9(WQ_Mk<rVIpd+e+>`V1+hu z5?=nGnW5V_{Q=@peHjO&fRs58NLIzRUu8S|ii~J4US@W}Yin$|?4!=@G3?Z1c-i4W zHg(wmpn>zETFx{}-#B|Y&e1(a`^!4j5>|G~S-8r1_m%;^{yN*;$*y6TCl7aadi?Nr z@bkg5XZ-jv4lbqKiPc_|=g16_yFLh{QaKCv7j0bRiqLI|Dcm%GiF8>0C7G4OLNcq9 z=o4xGj;tZ1uvlw&+gig3*^QQxGGBex-)XUJAFBcZR|wMQVthq5csyr*J|v7EHjS^I zCP&V&ve$C<_Ds-KB=cV~>Tp29vwU~pbk6TVGC3`H%_xRz4I>lv+sV`l49uoV!bTsU z5Y|=(eg)=Akwl?`R)qb}pMLeF$Vbi>3M*q_&Q3TO!^QaOwprkTeCv%7yt<yVJkV+6 z)NkaoF-Or!u|Qgz*eYjYc)PiY&Id5iVF`bBakv|k%2fS)VC*f7Bj>cGum!D_Q{S_8 zu;VB&2S1|@57osOh>4ERa134DCb}89x^OQ$?`68Ra`XP_)gw{ot(Cp(6v)I3x|oiE zUQN*16Nsg13Gr`L!D{Uk_<u5i>_Gpjn|Za#Ai%t=OLWC)6&d<QtLXdI+zR@8-@OSF z(+LbHjD`P#_lHMrw(ANvG9t3#%RR!$v{}GyXF=&G=}acU>-M%sw{CsJ>!LD2t`$D{ zGVB%S<vR>jrDWT78`;vh>iJ^0TxjMgEW?9G6Bg?(VJ_L^*VOH1K0D5<8FaX{oDCF> z+MfXH-F5n@&bb!nIov&RAM(4v)cR!>6uvef@P@l@uAYxN*?HF8i^2emX8?s4;}R%7 z`I~V*d<XJ45Yf;2Ur6ez%6-iSV=|XR59mxco=#4={4ytT5<KdNYX6fjzWm}r*IW8n z=LUeqf31T;*ZSE@>>c~gR}?xu$5bgj*0)fNGE5<hg@ROXw<yjl--EcR+u+9MPmHT9 zkB@E{0LpVSx}q;T=8KBZ#L7ju7&zR8@dC-V4NiG-yxBn!y%-gc26E|>jZsX|{s#?G z*nsIP)sIgD+B^*tt*Gu%0!FJqv})C@#xsC|Vb_EQ(}MXF+&^+7+e_b3+B()7bG12y zS&(1IPq1-LeHL+R(=sRY!4bhpj6vZP9;4-goD4pE`tDoWuBMqsNp|oSk(|;rPo332 zDlSpC?(9BDc>OO<a+)Gn6LMREdkAk#w)4=a{yy?pr!Sm+a6cwj9ERg=E}HW{U@{lL z8ds>)#1u!sF=6T)hQ!u<N~%0G<&~7|Pef0QjKa?{VW~+Bg(J_lsVi26!IYs-5}lYh zVQ<n0(huwaTP|lVD=-k5&g-*$@{SyZkhMcI)^awTEPR-JF+7`;Fr{wGxjjB~t|l}q z<l)(aL=y?Mk|car6QJnDMdkMv({HC2Xt$!w%5))eZ*7N3%pxFnBnncyed1WbxXPPn zkjyEaJMD7R_Iqu1yDxc}2}@C+=%I-A>F?TEx=ylmUfIqw?48(`%oa_SLE4AqXnzBx zEc^|E+{RJX)_G$(U|L_wt0XJ8w)~X29hq~ar^Qqeu#@?>;S?<PsvKN91msIoIP<J0 zzrmg5`Kmqb+Z+H{##<1NI_+NDI$$s|nARqZmaZ;EFEqHst)WkLZtdm~N;W~a{DG3^ z6m=Hqq62i|DF|?yEDfGh&7tv?4X(@95u=PBxXgmxW+LQjN(-YU{m{>X%=}f$`0&8Q z{YDsEM7=X$;-|YP>o>C8#Hx$if@HjSS6ppz3Z!99IYNLL7=tLepm_6tlGlJZ=vBV> zbceZ6U^(dUb#H>oMEsDmt#je03T8{nFRn<qpiE!rUkKf=`C?Dx7YrSANNnG#mM16W zC59yOa9ny(f}&`;<X4Kq$(+m85r;`{zNO>Q#s0}#TQ&7q=@5$zOaPb2#lhFkwl;7T zP5?X=*@lB!t~5diU-l$_6mPnidpqy~4{p}(QX-%CSP^nK9gj;Yxky<tM8ySbUrfpA z*7%!uV7Id8RR#Tivite(HOoIuM)(Rh0*w51ZP|vU{vIn=zAFlLhDD!>3@sNE27z20 z;?GV!9P%*LS$VPmI2=VL{ElxV6F~YxKwufjhfqR0i*PS;ypuvlFS?WRF{w-8iem1f zWn4*pweyon_WG;{f(*~0$8ZnviNjI+gaC0eIdq=MN8U3*{k$f2mLjGTd7}%k(hF0Z z3Y#YP5*@L`?~yPG#rgM=Xa|<L;AEbpW0rFn&K<v>FZ`@2&uWP^ja_y)?pPRrP8;5~ z=|)q!C@WfDKY`Wbx3ncLAR!R$Tm{j9l6l`sy7u9uia3PZ<I~5mKv=#{2r1!Hp?!~0 zh2y702n9pU*<nc?3d;#6Wad>%48)DuoJU$PqC!gH(i}-_t)!*$uCizZsalCx1bUIZ zEN5u{#&@_|6k!g1c+*LGuXR|&M)85>pmg-JJ|<nxxFn}IySbwg%WWMVyyv=cd(B!n zdMmM&?dvw_+e-IbFa1{H$|oX#&3K?g>=5sF#P~B8&t}0%;;!-Cos!27g7IRS$=x3S zK`;*hn0$I1UKUy>Uay96QB_Q)cQ{2H+faev9iw8WplE*k{sc%S7R5adVJS1C*;}V1 z$@Y?=OA;_Bd5=)(<b=~|(4&5x#XPP*Lp1JW|2pnh)8%|vJV(zP<Yoe|BT0}C?ef*_ z_F65I&(t=>MQX(bycdtBcrmalRZbYpJ~*}b#FzbbF<ZwDR=IqNE0&tUs^w$Yz<>J_ zU=Cg}6uW@~5H+zrU4fHNz@o^D9II7l18U$gOSe1^gTmQ>ruN1Y%6>e<!odLj<Uz$3 zsau*n0bf!-9csk$RnpevA0=VOB)X?Xiaif%pDKYS*>*y|OCYi!1+-{DKXm169{ZqG ze?y=Ao0r|Gtvg8i!qaYde`9FOrd7$oURBc#n}Wzo_nAUPZ%<iGzz`TuM)8ahAi1CW z*{1$&K+@0&^3=UdoI(TDJWC?<hE6(pKj58=F0=TVs_e}~y!zgLXDB}1nB<J=Q}CW} z;MF3!_)7k`)gT(O1_Y*Yn04Mp1Hz2~OrIBGsM%Y*L)JU8RQ@S1x_glTLo7!qY4A0Z z6KSK}26nL=l~^ViABzLE2rY@5<(dVG{hOeTyJx~y*HTgQhAwEPFElVx+u^X7alu{_ zh@KNKbj3_;h-E1uH^47_h5|8b>sP7VNMR9pw|X51LySrYp*yVBRY%hY$3$qE$YIga zm;37B?;rd^20;cqo7<}FuP?rpYo!skH%v1gO?=?d+-h0_fO`mYebf{Fxa2*aY>|CH z2PJ@#+qa*t{!CFU06~-l89RPo%o(*gJOt}FvEIA%kxW;GWPqSfI@J<RN{&ed*#Aqj z<r9~gZDpT)_V58}-=&^GFyg*b#gqQHZZN{9-9)x#y{4o74&o<{4zmsmA%+RCgef<B z_zH_2=*L@{1r6q0a{5IoE#V3S+FWzN-ZgCcAv8LQcHOgs66nPQn<8%)fgvNr3hmQs z0upoCZW#lb!QkMbM~sOREyxQYudp&6h!;JsMJ$?B05JYj-zRz*TJ^|+olE9FO6u-| zI|C^nqZXz!4Bc_k{nODYYAEK!X#r-vN1d#wJ6Ou&^v9GG6C@e{8pd{EmSHMp$HgEE zOxq6gDX3fr$oik$|KhXzEu-HOG?FaxY)Fp7%2B&Y(J)aV6DK#dBrDTo>i3i?L)MR% zV?(u&s<-*k-98G-Z1p3nA*#$1>G31h)muSjZh+evu*1flGx8_^f9|<R4c)2uyjgbx zBGy$L(t#HjksDr2H~a>z@n1hwKrw~zi$%axRe3t$T9s{m(RSyL;90saF+<OBQJ{Q3 zres<i0-&+~gg9AyR?Mli4dv4Xiau(S+smAdjCe<J-J8UC#64(a&?mbOzI^b7jPS)4 z>e<Oark4R%4fKJ_PR~|NRj5~))m=!k@A8_eL(*Tk&vG94N!P2qo<H5)B_d3tQ#`3D z8Qa6*P&_9GZdB<}hEOw1ts;eUwn)G3WbNey;oI)jq6`D;yy%pBQbRkg-0Ft+lZ{6< zm2WX+{|5~l)^+uM`hcQazsdh72rYIkVPyUbUYA#{nxuE82d)`aJxa8Vn<%?SF9JPe zaf$pA;^OnC51oT#*F|{sgOCAHV0qe2>K+0RDuss5=7*w1+wj-x_&PMdxW;YeCkcq2 zsp?eSZ?5kB=Ad*Eb<$$mz6XMj!VVo`jSVYl=TyG$R^YG$kgCbh>4~+`9D3eqx5dyI zK`cE*ZyUNv&^z=#y2U8FpNVItSblIqP4?Tw0J}R)utY1n1E7;)#2<k^dd+py-xZVi zGcAQOqEP)A7Wi3G^8Qnxy)aw!yt>*#9)+{RQFql;0;|Xtnjd4D++ZcN2wY_V6dG{# zrt!rTZ5+NPrvPgbc6$~>QM3D`-*lYLI<=wCpKzQ#9@`TN`)GxhZC!;?4&n!g=*)f; zuvnBb&&oC$4b~*kP`@crCc1i+IFgsw3LhMA2mMt(I3MDIL#{Vg!9~n|;B<449m3Ni z;2sZ6b=f@+OayuooK_cr6q0bMw5DTq#ig4>ymD>Xv$QV9*Q!IztJ|xIRpSA9!Y+E< z+oZ#z`o;F|`B}8N;%WnIjIcSR!a;ni#K)`UtVR)Pk*XpEq5lwwNa2P1=K@D-(4y^4 z;cv2~HP<SOjU9;dT%QeqjiBe_3go$E4<Y*WkQQatt#J_ffu4TgIbEfAh%jokqYw<8 z*+N}|TPH?^dpX1!?e^z04X{-g)n3auOC@PTVgfDA=Z%P!AuU(G-CB|s`h+x=_q=O} zQ-zCDm<;c|T_az-*fiix`>>*vhgXn%TPts$&m8CyJ_a{J(CJDIaD-i~8nMLR!GMW= zHyq~_?@7vuGprGQo4eJ}-umkNOMKa%UOn0t?Vx&B{N}6~`exy67mZ`GGDD;2WoN*( z3z2KXMwN&HTy6%nSDoiizuYFr$!vGGk718N)W5U+lRsA88Bp-@iteP$`TgB)OZ>5N zG|Y$>Rx!+x9YHH&2E(u}>f!d6l4MB~3lo+HsRQg9z16dyofVjuBs=soNvR|=vI+>k zW@(h!vS|-P%y|wxdAv|(Iho>sDLOr4z)B4rtPbjZ7VrrOuYNYKK>Cy@7npw4mqZen z$^sa$cg13R_rZhTKQw6+901wn%KF`<xXjpL$2;7)JZISHyf`f`)m#mKl84-)IK9g9 z(R8+uOesP2M^y7Svva(-u_QhuMc0(`AFA&OmeJu<1)4_*ceLcXLg-TR{OJb#K(?K= zXD4)p0uMJXhb24p6GvJsNTTx207EVr;)SuEHkHJL6m43uwunntfyiD=aPwM0mCB|) zx&PqvFV!|*PC$ef%}Dzzb|uQrE5Z<or`_M!`1-5qjE$`lzfaG$`62wlkH2nv7g5ht zJQPo4I8a-=_xrnFXpN#N$L{(yXy<%@EVwH%Xl6fQS@Y~u`tQAc2YTk&J;+>m_;T`Y z!YLMH67V)_SNTcNCf)Im<>ZIgA=J*R(WHM~V#UJg$$|h^OtzNQHb?qhZI{LN+1Y1b zeE#6!!+u`PE`9j?->YIMC851fM9t}}eHg;`CjjP=6Vv=v?3_;dW@%%T{Ly|oC~^aX zu-{PhXjBx)Y=q_q6hw=p{WftfZQ+y`jJuc`b~<-qDB{=Fuq@rbyDX+5pTNO@W^rAM zz^pBdUD}0KZ)F3?Frnxa_{bqCWc;;GrcD_d?(gjGZvXJ~@m81w0&^ej?tFRw%k58O zEa%kvP-!(Q?#L2BZnLOQBOP2(NO=O$O0I^aF6LG^nwERk<aP(@rg*{m3ajj)77cqe zn^pE;A-_Y~AWC9yaAuDBBRro3;1S2k8-l{hQuWNIgd}8s+cz2w=e)$mWvTpxf5$$u zI1h|p<UAmX4mD*757CXk#>wN?PuhlYOq`9U6QBx14yAytpP)VYJ(?zweg^=!?TlmV z{W~26np+~Y*CoZM;r_E{*@OP)i1l1{YqUMkJSntQ3?r{m>BJ9k@2Ul2r*zQ$_u;aP za0fuRrm#_NLAAxpWwNtn)y%9*$4hxyEw(r(LOCJBvN{$hy40t5uQ#|9)QitouYYgA zuWq_QIF)iPG5Z;FF={1etS23jKDoX&ilYl6XD_1Of+pwFf3AE#UHx?xz3wVAbvv<O zB@CJT3RkVl$yy6EC}lN%pT1->S6Km5GhsqZ!ZNVg*_VWK3P;=Kg@lPomlA{uQv$p| zCr5LHiR-e}kja~t0vbqH&37^7mm0pCdVC?|?m68f^X(D<)lz4TXz0Ug9dByDmCPcG zfK`!reIL-*<xmJP$8y0Q(d1O1{=fu!`}gb;e=RECSR4uGu&OU@6ZA*o+G7c9`YmO& zHE)|uarT6gLw>K867}A3N@TSgy5eK`gxoaf<xA$iPnKxFaQo_VFu-OG$IA*Yv{6wF z;ew!h2tDc1=HD|uy#8w$NIcSgUN>@?bj!KEZd{Kv??$>BlPQf=T$J`}KXyR;GCP1r zvDI|Iu8V7H$IF>IGakp~&Yb%lx$8kg)FZEV=ud3FoF#l6J5rz>CgbPM5%AGd?ntBC z*Yd`#Bd^Mam)gniGL`|lE+o1MRzzx#>-w5wgo6P=tgJa^{aY5--nC`OqDYHWnol|$ zuYfvX#>wAWfAJ)Av#oR(n`_S?-9ak_BgsZG&QD328M%CW<Y%3aKP)w$&CBOP<#7E- z#>KapJZebx#M%H8ia}GqDztYu?7g@i4jn~UZ^ogmZ2h?D<zCB0cydp%%8H)a`9IFb z!{wMVE$9H~A&b7XlD6cyK&yb}kgu%Gp9-bxlmU!&j}k;Oge@Rl{pGPxg0)p=f{vB) zHqHy}qR3Ek#VK78yJjy)Z0!oSKZ$SGDuxjpIOYY`I_rAhBAPu>_Y<NhjWg6GN(09< zFlR8GN@ZC}Hsfe2X|T%56><dVqHl-uya}Rq4UVE$27)yLCcX+{@qIb;suQ^LWO;Xm zx3Z-VGSu<M4|QA{YB%InU%*FnqfF=JDaKXsX}5`(HIb<h-i~I26xPEhI;DNsYJQD~ zq!ikp;P7AoDtrc)%oe(6Q=Ud_pQOFydWbcY@;RJw39@2)8ur6UsD{6u!iblCuN7DV za=PkrL*nVN+<@_8Dq(U6Q(%k2G5<Wyj`WDUr1lhW;FnO8lr>lJkaD|6hm7T#T&`2T zy?&`(w}?j!Q@*CnLw$x_*e3K-fBoA~prwWQ!oAZ_j-D1y1nxc0C?!Ki>V(KIhBiak zig5j@&<jg@19FC`tukcSD72=M_?!~BA-GK{%00)9t%#{*MRx|rDCB$TxP=4*kk9(d z2?wij%!7s(NhHYKdpb_{)bbT2h>0UD`5Z;!>6AjGxlj-y(!7|#(yq*i`ApNP9@AgS z=5Tp%dtOV%1>zGhU#w)H8rs5?yrb-3MFuZY_cJU>v<i0zN9?(Q6ITxRhs4S_;SqW< zZD;uE3IY=8ar?NbfxO?5Bt^yzkR4pb@zaaT#-NL7qrLLNI$Udh8E(QgO!&XPd8&US zuZM<XP8IHak6#swFpV?<A2Hea#))Y#=@NX0j4{q$D3;+DSf97TESBuHP*3MdXP6Ur zQcCGLyO-GT-ze82$gcYvpYCoPiR2tOhQt7=`)yDJR7bNQyl~o!=!pnJ0={na8A`qQ zzf?K}_lYnT&hHg3hdC8P2<36RQBD<rDus=zW)BQSd~~u*@k<PoIhXNh)=4lIwI*WZ zMS+M`?~kc$UJ}=HOu;R2mJ;aTWS*ajq)K!5`DvU8=$sIou`lqn-QA7Zk9n~$c6p9f zFF0+J3DOD=jY};q2j`G+^2qraWnbfcZO)Jpi;bZ<%87FK^K)w&rVq`#WDVHKge}2p z@USGvz{I5^`HzzUD$t1ffm#gbq@MKRND^al$r^MoKS8_62;Jz|6}_L1D)(-~4|gc2 z9OOlcOG2#Ur08<oqG|L}(-1-DB!FL!eAz+|1G)vA<B7QmaCiihcS<>sN#Q367gKSS zv)yxMznVLgZYGW0;dQ2+d$1wp{K4t;eF)WoI1`P<zlV7&_N_O##5!|}Oy|`p?>B3x zsX_=g>SXO#SAd?Es)}4r=EZP&iWy2qCQ11qL(>5D5(I)gvG=nkLm;Uie>g=z5aaV` zKF_bdE#DP4>TyB=7&7-IWomiFaYKFq>XYMwF4T|5kKvqo-YNqxY3Df7bwZ3caDewv zqP^$1PR{=4yXm3DXvsMr%DFRgw_;(!$*|mmdxicpo|iW5@Zl?p^TLhQj7(e+G~>L9 z?%@<;?!6Ai-<QE8qEOmZ{zE>K7cxcK1Q<LYRfk~nU=T%eX<e+$U~hfoo}2WHm*V?4 z%-#ZFKo_OGAd3jrxmGirq~Z|tp>jSPe$RnERp8-K4Ys#WL10>vo<J&wNb!>G861P{ z`}aQ&!Ow@IRr7H&NQ`xD(6|;PfskCTnxTW}Iv+aplbK)~drtPaC*QxQ$FUKPU%MD| z1Uw<R)Ew~<M*cy{b5Pv|d(4ufb41%AHvVDK=>@J~K6RgK;Ugm`_{JqPWG5gjtf`?w z%r58}Ery8;BMud!7fT3iug|gcq4Rz7ybUg3lLIy=a*>0m6f=yZ7paIPV9MyH<0p;- zk%)HOtjFTNf_rJq?a+cu!vyqYh3Pgq8N^8A87tN-vaJ>9BnU6TJ+-_0`2&~y#5!}@ zQTOXf5d$|_)7Hd)C@5bm4AINR)+^&$8FJ34BNB<o=)6Y{_JX%2q~7vq!8RCI!JAw5 z;z14apM}v>4hR2&Cxy8nj~XQxjB=QP5!Umm1{R^&Yrf<I$T-sq_(?plk}%mt=cz2R zPaHev7A4#ry<Jud=05QBE-Tb_nOro3?DHMWl`H|<WG5R0A=NJB`XF<e*YTNWKnB3j z;uG|X)W1p3SiZ-1m`D5THvEAJRN?;g!aauS;I<9eJMV^)fM@BZ@^;g{oda2#E-TsC zWN-gk(LTG8gxRh(gUnX)wi~X2qzyqF&2VXwUEb~(tqMpj$a@N~nFt+SOkGYsbhRQi zm{fwmyyg=XE_LV!N2L9BKL8i`@6XKNpVQxMICOWLT$r|yj_tqpy>G4=xy>w)KA<#1 z_4;h|-d*ZFJRo$y5#BzHeFKQM@43Kz@)UH4cPL*T(WG|S8-|nLV}kX5zt362?gJom ztdkbxy{A_Xd{n<r)Ba|35C3mM$?P#@{ekc6v+NR+WuMQc6Y(6poNQj1Uhta({Q8<d z_&h^L8*b=7q*q^Lm&xb9cb{BEZysh>iN{pZFNuj!;)rN#p@H9$2VzKQ1L*utW1Pm~ zZ0lYog?lQuQlFh*-R-_J=~<3jN82&!>s;TGIQ)`0WUPaW-mnX;lxji~`n1*h9b8TY zRa+rF3~3Lx>6{O9N}7eT0TP@sh4t=i?;5oI3?a1H@u%d#ACgUR2|4_N4$Lk{CE0yo zV9fa<7$K^({qfSrfIMxV=F;^_!)X`4KXT{g;Sp!vOLgLi1ecGatSfjgoR!Dr!dHt) zry4a|v2rKsXVjcZSB0YCSdzGLiT6}bs&NXL+E<JKAY!17kdYYuf)gytCO^MedE%;U zJM+yWN)Vy6(U+ahtF5w%Fx>#eQ?(Uz(tDv{EihT8Eh$5U$gQ|>J6sDCZP@QbR_flk z9Jb^Kv(T|Plc$yq>VWvUoL7X=OjbJ5&Zf@PK6`xUb#2%A=sne06GJMpK-q9SB_4w> zR-ms8H`BNFs1?mR=<M0^k3|QyrL#r@Nc7TMByk$jj?+&Rr|i^7otw?s@td<_Nt6z< z7jL8+vZ1Z1MN7y;rg3rbtwdF%Op(;7VXC8s^^SA2)UEEWxZNIj{+&4?<tBXTm@sJq z#%aU}G*!rvAkVnjZTEORXOInu3I^238&;#(aOuo?W@I;_SZN66s&Ts-@3JD75sj^{ z<Z`f#fz;+nM9f$)&8VUi>g0Tt#Y59navug2y!9JV8h3mjK}C<wPfeASg6<O~J+Kms zIf8y>LD<hNu#{N|&9GvXiO{w}m4e&9_POb6O0~Pi)k%PNyQ?gu?33l-YCJM47^hNH zt|zv!P~=+?6v+ArFVmoS5$b+za$s%EYK<BYbruY%_5HR@qAR&zwMqP~_epYrVl>v~ zzPlyT!vME@;3u{(01y|g+KhbL_0?^EqPE<?smnZdRxo4RopcZP?$*QC-XI=z@M*FG zp?+KR+&dHBvh;sZUmcMm6t<iz^+V=#od!2L0|wLE5lqwxZc?D2{{V*GYU>cr+bpC> zHDP5z`XUrDe2y@YKCx7B6$DyJl|2r4jo9yXWxtuB0uJ~hpO2!pTc2r5>{^;mPek2C zf)2BhEatQWs>g0X&c~1@$GCFfu4t_cK^*vixc|<idl$;Tz8)1r(7eoS&t8kIIL`2M zd2UWEIh`P(>}6D2_%Z)Y3O~xJ$bVA~v>uSJoT?Yo|3I?G2uubs!bm}Q0C4q6AI#oV z*B3}1F5OVH7MHP_?_+`Z>g!FvSyqKs?_I~WVm%J-z!s0!{4I`OqU{)TOd&U9Txtc} zY&8g3yD0;qT1teCdAw$nmaZy9O{Izd9MY#Y=GKiSK#+t^tFCwi+Q2tU#_6sl96i^9 z!W6+@#LlrokZbX%j(UJl0+F@DC412aLsO1XLFQ`Ob)69UpoX6?$K^+CV;60%n?fz% zuK<JG+-{<Z8perLuM9uRp+QJVTjMpAnEHyJ;a2mbqdkKOn63@6ht4FSKnK+ll&~Av zSWdD{iM#<2KXYF{TjbEeVKELP4fxrj@GkoqapGr|Kq&Dmof81*kR1{|yN;B{9Z^^x zk7*M)0|oBXpJM7eUyEcYU;C~Oc_)sv;Eq9A&c?bg`LB0aX4b0P=nP2Dcl}42Rd!|j z`{5vh`8<|OtYnH?9h&!kk7~zfb2I41rXrA2h5V<*=x6zOe4M*@4su$u`$0~yh)wRJ zjx5juXNPz-YKOJ4JKe4&D(obMQJj>LvZv|UCHtj89+G&D=SBXm6`cFjIfiv@Zqi(I zrM1e`5yH4##)BbS63}+)?Z}V;n#x|C7TlOqf|iat&K554AWr71XVpsWdN|MxU$K+y zh%su%&j_)*y0ETCun6%CL<0QW4Gw(ju<M<SG$Qf5!!<q+w&Zf?IK^eHtdBDbsb4kL z?WXJ@$E25L1YC`MABXV226e@s<F~naJkACvN){8`^@Sb_RJs;9W^<hk;miOAdz^~y z#1v)4wK5Ds^ogH^=o6lc+F`h9MI)~`bn(eaU8py$`eAww%bm}r7_ZM28BR_rtZ%nK z>cK2?eu`c^i)?r`92Z=M!XWn6J~5e5Q6=7Y<j;s7MNsgw|1uov4tcxb(`|YB^}aX+ zm=KZG3QJbz^x_=CxHNvXMY1htp(4*PiY<i&NpxwkDi+xkX}7((0zWV3<#Z0c{F4eM zPysL-wOUU2*>DLr__+&9!&&4b)JRdd+;Rqz4z(K>3$8z^ssD`%9Cn3`R_G&oR?N{v zN=MejS90R|Q&HD?A0}yXsH!i*O?u;d)t9k<lRM6#p1BPu%l;jOhIq2Cj0|C81lbOm zo#$7S{>$1PkqE*0W48`mr&c}k%HDaQ`a8@$#dT6R;DPjaiVE@}+CP!RNg88}EpwXU zu<}Htem)5jQHM&!Z$MT$*H{8g=!lFcR+vFcPELA8Gm!V)^ZYOF44rtzS^c-&Hu!rK z<Ti>nsn3pKFC}+mC%tD~jUxMyRM{FMKDtzyMxroBk}aFRic@6UEZI&Yti&K$2?;(J z;XM$!(VIDqOd%vqdW{pyIPta4+&@cwrj_no)LfHjYY~8@)*V`A<q1*UlyWk$`d>L; z1NFstIYkGDl9D^39d8Wxi$A9A$rOuAH*QX-B__9sQf_8_H<R)vQ|i7PD-rX#V(^?G zYdJ1B-!k%fi#b<#)r2Of$V6*OW(v^9xdJpzl+O*NPZ;Rr!q0QKwG@&P1*=pq=Jre; zwC;+wt8@!K)fL*TJQmA<+7tWR!q+`mlgH;$(y0f@-c#w`eb+$yf0oWg97|(9vo_+W z;y$M&@8)<AzL#N=_wq<2`5Jz=0xZ9q0){r1jW9+#;J{OIIE#Ug^Fj=ZbFI7bipa-V z?S7XpY#>*6$MicT+pAZ!<yL{SbUY39L~fpo&6Xzh)}&b2Z<HjkQ}>k;_vF6!%YrA7 zdy-X>${fFT0d;1HfSv6h#h1i{R#OBZdvc0bP@WCO`Q#LCiOQ!6K<BVZ@|IWAv6MDM ziX$CuU}3Mx=@Q+>I59t$E-jF>6#rP}V>LT+WZFpy^LQ+-(O6!iIE7VWW8!$?hFN)j zUW`h(*|7{Yr5fVdwzt~-mg6D_K`Hyw34Eh$>8fesvf!qKtNI*M=|r60_{wx1%qPsB zEPjDpD8Y|FZrJVCow!H*Xp64^L`eJ@Bcnked~N7I{p9s%VkMo7pS4c}GWQSJtVG|F zX{X!ZH4t!f*qnJeo`;X#q~H7W_~WgUD~v+;;9KaNDGA&NHmba%Z%qv@>vyiM=QPQI zeG=NbfS}P4U~^ZZ0ly5SQZuyvnOI<GA?5b_3@#mtzH}#=-mpbNEILu`-PpxB(pYx` z?X(qq112&yb2yUmqO69+7-msSm&BQHY4Je7vYRAH|1mkp1?4U3kEg)7OXh*-5%Q{M zcH`+w4sLL^bT!UM{az#MVF}d6i5M_zxaU*3$mDZMuJ<9|C$jl*En4>u=KYLP_L(B$ z?qP?+7S`80z7CI~*V(){!5{zPSNSoiLX36QWCimfBDf08$a9Bv^j!)f61!a<1qO#p z=kvimsk&P_(u7w{{g6r_d;IFvgI-foFbe+HSIC#TEMdQSda%gF;+C3AzUY$sBrG^3 z<}Vqb>oh#RE$2D2jdgL>n6A%OLGh8RJV1Wxu3W%*{;sGT$hMBJwtOK#x@~C&6iE6i zKgs7M7y9MzO%}PPs^-yiH-Ey}x*!y+F@Z2zF`Rd`O<4t3E&H~MlsfP?DcR3BRUu|c zMt>vb9Fzm<?2_hGvpRBsU<X;LLH1xT8=^I3kbSm?1vpV<14ng`ecsiij~QhwL{0$u z<N~l+NBp=4*~7gCNA5xPd+2d7>}z5#N1wmSzK}A~nts%TRCVrmwQK}tRYPsgZ|?`6 z$ft{wicP)7Kv&Ds643<4mfJ|ndZ3CDOgOTB_zq)){%+fPbSO=LEL+TP8)weVG`KbJ zRkDYWkM(Vxagvf-JCj0et1iyT2hpJ0>)q*?$%=4hYKZGACx!^P*J^O@N+{g@j6A{c zv!dbfo%1#b>tRUt(c&UQ*6ni>Voe+_*171P_Inu+$$UOM11?RD0!a?3!6a)#M<PiR z938nybi2-f2s50(+tk{4`XM@ME*6j-wy<!p%QD)g(+9w9sDBq1CJ_K1W;;^JSL9Rj z^SHg2pfp@B3-kH8zMaSBZa7HskB=Rqu3dM7xffrdhl&5WsnZxlnoTzw^soMvOC~*4 zrd%`A#yxoQm9)dZH}|vqp=Yqx@~g-B1&S$YX6KB4+rQD2cmG3E9xr~oP1m`9z@7)I z+}bM1z_a&TE$;Mx(c(5Y?I!-}1yX5X3H<VRCVGw?#YP=G*l1Kno^dpiN~Y%Obed<L zYKffTFWEdFl~WF#5|6p#>81WYDKW~6|3+0aFf1eeU7qKsg~nX*LPHx<Nh<k7W!RES z-UrjDmdEGiLi<KV)#9#whxJ#bbE?^xS6A7im(Mw{Q5E6n^y>{Nrhc(|)}c%d#@ONm z_xEj}N)_$EUMsTFh>Nl98TQAy`a7Rj^Q5j7Maa*qf-1(lm{`#mix#}ckpY0!<e-RQ z`qO9m9LqOPmos?m0^P_WD2@^mPaqB&P6=yVs5yHXw+_M_{frLK`Bd73q1-4P&@@Pm z&Yi<!o|5FB_Yrs=miok&)8>ABroG3MSeA?Ipt*RyoV0=vC73YEWapB>bWWLQ`*5s= zuCp*QJcxJkc^ohtmO|mhVnU&tIoV1`?<R?(WR>`@0>K3}IJ%F{4%ot<dWMD2gAVT@ zL8fcc92w&qbK(vJ##F<KF}qxS*|6xy7}DnqOH7e?B0MeC$pJ?;a9HPx0-;l>r1i`x zL8u#+oJ!EH#Fa(>Ee9SXHLDOh0sHD~D*);PQGz^BdYF|A(^)Mi_OJ%K?I7jDlf)Av z1{Z05JeC@FHRd+8qk0pEQy%Cmp`HMH67B*_J?TD4uCy~Q`yT*F34N}eBF)03P9;8v zfdtr~)?GT{OkytIGsopnTXN6bm=|o7N9sY=N1OJlC%L1w%tq#N1_^O%C5VqwI$g>@ zAFw7k)NLCx)1Vdm{^%I84HCZLX|Ry3Zb0MkVm1}DU3nAf&68`Ft^nq#bXT(k6S?+j zurSsj<_F=A%}tlCM(MQnb66g6Hk2UgjwiV{W|H}6<Ozpj0tRikhdna?_^GqItbgB! z2Xu)btMJ`)q9tiCs~dhuo;>2KZzH}b1@=T0aQG)?TQfO=+yG3{4_YSWwevh0Pb(@g zA?ek&;n)oevTJ)6t-F{$Q~LCp_j6;xA<T&sFF#hBI3sFm5^;5IcAKv)7t6miFSWYk zT5%Vr<I&@qqdn)&DK6Bf*SetTRvqp6LJycOW`i7%fb~5t7g&YEc_F)M)>K)P(xq}q zz~f?4oRkapQ9=kKvmnj~1Yv8DzSF*Z<i?nbzG+{q^*!n3T}xSP9WDQ@lMlSF@9dzu z7dRX!7DOJ{GDA`0;8@a*^b@fgwST#*FBMs=`zEDkqu_Sn1RRo8Q|Cf}zRz2zjm}TW zlWXdHc?0#oHJxiWhaeZ@0{v9rw|9uBJHP%=pn?@XAO4D2)Ii4UJw4eA)-5;xIaN*J ziw|M6M>Xxsv3udH%I}I|#+xq(!|z$V=9TyxMs6f9*tmYCvTxsnw}n99g$^lWhp8X+ zq4jh-_yE%6y~bQ0d#wh~8Oxi@@#4Gf7=MTko45kk_s&rWi*rDiayBj=^GKCt4rKJI zSI^QF-Td0pFLcFKUw3iQ&nbnd^~JeK<aaWYhwnzfDNx|J5glheah^==j&+~{B>c1S zpJLCiXlbrz!`Gan%9h#PS+?$TQLR|??XFRb1j5w=<>S9@!34X4M2SGT8fdl-dEj@X zt1%}f$mD2y4<Qeir8_=OM(CL>bu1WGOwrf;H|&}G9Y&0E1et42Hb(!m?%Haa?uQfd zF9eB9*EqWA8h<u*JsCB0omxSFtt&nJ1eKGd1F>^aoC5}zJ@4lS5Pp%HqLw&v_+Va8 z=KPXeIMi!R5w_)XGnA7O{WiUmAF(euFK0!(TxgcVN<0NAyF??MAkUk7ZMPhM|6@&C zO`VCAZQXj=9ntxi7lQO~V_<?wb-WZeJ#z1wzvn7;c;N7q;k34tQdC!yAqZKM@}IeS zN=qNlCsu|fsn@M&-3U(XVB^UNt)7N{fz-rcc(i8&XCkV2K{D|7OP^L&q&7*>rq^R0 z;1bM&fq>owgeB8Ch0D=w4MJ0HEx*}{OEiGNS_(*@Zx77+2f??{#-0=npv8Ii`~4DQ zM8s<?umYnQ8h-$n%<W+}2f?RPm-89f6Wt{aaU5Ui4aQFg*4Os=WY1|nCa~;zd5*le zC<0m`s~f6({5Af3;;7H}h(C1^Mb#^hW;2ksJq&b!04m}#Ni}6Xg4hA{G%_vqA9v&= z!x^njLU8}jlP%_{PDBr9tCUN!O#tS3rV({+jhfINhqx1ap?42{5PIbLwH)eN&>z=2 z=)!=tcg9=yrmkrr+_N`Zh@2iLgGri3ZhAtwI3xmV9GD}9K`Fc^&XFX*Tlg`xohqXt z8mB@k1q&N#ST^W9^!2}k!?S^7<nc_bIt97<4U~GD^sN-Y#`xacE>gdzO%`>k-w^LJ zou$2|4MFILw{s_;Plrd{o*-!;zbm<-^lr)@C9aHx7dVvLCv5cuncb9DK{g54Rd99k zTu1iL?C(J`>Ovd>213uN7s|w71Uqs{#||0oHIb@5v99TXa3PdrWZ>hW(sNaB%^YEE zlB^_35E*QZBQ>qH=#@|N>ce0hWHnc-q4T{u<bA0n|B6Z`?X^~%#5y*)Wm<CRF)5H( z5q+_i;`pkQ`Yy^;*^Q(WZubl@?=>k0>$*r1GaoCNb?oQc73xWe9r;0WJF2Nhb3Goa zB68=5T{2iaIOh_(=Bv0L4L)-nwX?PpE#k&hx**$8Ukr5Brl97W&AslngNabCCkmDe zDlN`2u9MOaOUkX;*0^|IjFsATs;)|a0w1&khZ@tnxsh5Jvj<5QgF`cS^>oNbldF## zH9X1T_DXXN6}Zbh*cNw~-9>(PF%9eSZV?BGElvJ-Ow&P1lyf*Bk6luEcAsQ(ik-a| zm%D~lHpfxgHB8VRTo2nOF_AR@M|ToVeZW)t7?gSpB5RufHr(509g91hUGbQylfcj( zU7vu`5vD@^tqb|vi_)c0rgb<>%Nfb81q%~1=TxCnYDMbQR6M0}r!EPd0?Ox4!n_^% z<f==e3VWsk(?1z$a2loL-rOwrG)oR`%v;@<w{Bx}I_V90tMD+qh7FT87nL`kxGhnh z=W9-Vuwuiamc}Av;;h+7=C%1W$Ls=)%4u6_4;@O2`GRW5%jrd^ZK-SP&-XO<hfr>x zYp5jmuP&B~80L%4FPT^r1u*pfes*L$=`u{OggN2{m;vlYG75AXBKZOf<lF(^E7&8= z2bsE!bcP_izs1uhAIioyeCiG4VJB}%?^*96Wssvr#_z@{9+_!$64PEy#nZg)jW_Tg z&}JwfRGp{?w39d-GuQL+)ho(#ZeE&@HeBWLm4+qk$9+aEt0f$$7mifK`V~t94UghT zbddg&sODSGFj#x`V@#CbiiXkc-QH<yu28QxBwiSHMk7bv8b>CaRA%)J2y#?rEWR<E z_rZ@61(lC4@+&F8B*nyNAb0npG1;xjsBUVy8xL8Sq!8B0=#UaQ9(7oGW1!<^@@Fbq zyC_bJxwDjDHUmv8Px%zwcZP(nN$WpT%?C_9qMvWN%TECzF00H20ocy^b0oOu9lAev z`nxh8=HX~*LF6i@af<hLt#%>r2lurtfiv_BjmgbwIePRFGt#-kZdGX*mR~;qAC!fD zE`P@2T9nvOs%l|o1Pu6}`p&DV2G=se{miwnj|)Jyoi>$^yr@?c|LV)0#6M^d^>kcN zmJ75?e_NtIf~m&x{3*~q23vbiJ{)9UO_rE|;p?ssJ+ul4_5<>K0|HKnkhKL?Bv7du z+^`i|4$-1t7@Ph!^D$x0%;=eb2;PTpZE1p!uzX4|Z%s`erxyvO=mrdPSe`jMBIA2> z`|4?WJx3jmryE|LCVl2Y6o8cl9MVjy2zib6XF?Am3#XV2Ohrtzs=K1uO2!l7wAz_; zH!O@S9&T;9g}CuK$$r7^F<dEw>M*>=5(=^)m*s#}m<uxns}!;{G_@tMl<gIE23C0R z>JV+kBpj$t=|x)xE3BR|I%sKYrtE|Y3WJyC5{q%tVWY7~`TL;BVWQOlBI00)1k=%0 z&Pe&(1(K2S9Qmn2_))2M;p+WH$3&L-H9GpZeP~K!K?bRgHCB<cpIc3==2{D0k!EHl z;#(YGpRm}v6=TI&O!CHgi-<itn~qTvArTZ}C!ie2`Eapx{JWrgaQ}Lpt$AG2bRoGn zP&LFnt+)vLYWd`IBdSJJ6@HVd<#1RqPpn21epXc{%duy;DtN_}gze@<#E0_v3A^Fv zVE7}a9*cH-GsSszUH+CJ1&%M(RNJ`lJbn-79;2~gs0mLVS;gr|b~>IO=VQ7=CIuDj zumq`rpspmR&G$Jo67|TvrMFzJ1vMf0{2#QUL>yVbR(7>4n0rM0u%rU<KF<C@%Eg(L z``h=j=ctuNK@)i@a`L;kZLI0+Eaw>uWgBCLL!UcWXBmEeo450N;O<N+^$D{Jxi60d z8|SjLyQiXY8gc=arKV*ehb~Si<~-Dl8$+NW2vWRP)?!Nd<dnlkFPtDrZp{f9id}GB zdK}~6os!_~N#L7Dp;K2|#*#>?eNYZuJuhWvMmB*{dfPg6v-yXMSzWc9y+X#o0h!X` zFzoYS5`E*FY24UNb;De&{=S~pqYPM4(Jk^fl(5u!iXxtH>?g&t@d??e94N34KQ)J7 zw!YRYVwSJ<P~Q0FkNlrh0(UkqwpMqX9WQ}PuyfJVYDaXnyi|gUt9{*Mhe8C8Qtyx& zAJOcnmWs6kF!GDnBb5o`ImVTa8i<Eu70j)pN0_OGkB`8AB}@VhNaR!PFmPY<r&mG3 zd>ymRmx&D9@`u*lH2(B<4BBY_ed`IJe+x$Xv`YGyBt&g7OH85@FfhQx{8JTZ9Nw+s z64}Oh<%rC5=_A`qp35!6+vug{lk$p29ZTNk7^BZgp*bRdA%~PN6DfI&IT<{Vu*Ab8 zdyXYroQh^uc?Tv3Tt3X28sL(>Pcjp$#P+>ep=%UW&!4!6Q!OkAOwKn~&qqc^?MDUE z8mj58t)&%)yMe;6<+T!2fXQeEU@}Lt3RSAw0Ebjcly1)yRHaSMy5w!<I7$CHDk>|U zUEUwWVXkA2Nag_!3H}Q_M|pB34#e{-^2-GlW0oyvu+2oB;vy!lKOK4)GZAshZ{{Qt zG*Wk4b#)x+z>eza7><I70AnzTE*Jq&o}MkX7E>UmCkrQh+q;l!%OF2r3CH6~%viq_ z3R4QOt>N~JaIf?Z(2tHW+n;2bMis2l(Y6{C&>e{yV+^4j-sXPwvh<A)O+m!+dVN5$ zEHWlA1C24!J-M?vFo|~xp{BXsT)FZvt(y!)fZiu6DEjF}JZ{MCBRbc)jH9(HLSrDs z(BK<qfvKYsp9HI#3)1ee+MMQ#Wg02V1If&)*PR!bm9eKKO;u%^&((`Yv2f<}&Mr4j zh`e4#XwV?<8BuXP&Ro_k1$kMjex3ul&gfTSXG4zqA}$(fGe#;cnK30HpQ_&Ll@9Ym z;x7&pv-$LWNkx*0ZqN@=rv2=51;V@x2PBw&J{@uC-5~EEB@S+_8Hz#s7p4E}xv;u! zr^T)VeBU}nZd5p!%X~Udtq8FUv_BZ7xVUVh0xAe+lVWR8o)=j5wmhA%W&~eQ4c=;z zA5(SIR-%mUzB0{(S&L4)-L03d?Z2It6MV%9j`#x}+UY4Dp8+FVWV@ejJ@|Z+B6wM; zEtPmpjbFZju?!uhy7vhnm6y)vWo5X{R#TN;<XhHlHC>+4b9Q`0F2g2PliV`Ce7Y^0 z-HlfBV{!bhTzvKUgWvZb+|RZ&|I8Qto&JMuS?c}Ik<?vMl6hVJ{oi-7pC`qF`F~E* z0((e?en1456)w9+A{9B%-3xZceY}srD_}1?%Q!0E@A_KeK`x@*9wm6uD)pbi<Y*um zwA=E@jNk9}8ODV!UIWfMJ{1&)B@4gYX~S2PZ|!#&?0*x(ijraQZT=orRxS<3w#)R> zCReT5l+_09md}oJUX6fWm&5tAnw~7EBycg=T2|ZR@))CYpuy)4zWD6^m;ZJD;a^_$ zAAbH{_rL7t)$Fpx^eY7+1`zzg`3Q+w0=Da`Jj3)=`x~EZeErpS{&joLg2kktiBfLh zM}qq8PudwmfJewjBQ7J_$tW+!HMYDyEAYm@z9>gn93@!|z6Vt8uT;a_ndH~)lOTOb zz5aNzZ2JGl-rM&#aU_evf5WF3ytykWj3pZ|0Xc+Yz-%}-fm}>Bd#>%xZ!C@M0eMEz zNEm0scYo@wyQ_P8WSNjXXZJq&?PASLzgAaQSJx|t{J`iSqF}k>bb!{M+|w%D6upmZ zjK6Y}!IH&rB--)7Kzz?ePvG8?Mg2O<K}Np=T804rwKrwyIW_s5)>t!B$E1neh%cIH z_<C!!MwT!WS0)ybOhJ3S^$AnUBdMGat9ina)@sbXT6*P@DTZCUYKtgH`fF`ttl2;_ zQ2?6$*MT5jV*%c~S0el&hX6XZ5x6jLeiO`M9Mgq1W07(YP+dvCMTaev>yvE=u>y~+ zcQW(y(ws@$=q<|r-+p*?uz%Bw+G@z)mpNP#%Ecx}x5IlspFor)c}!MX!{lu}SQO>u z`6wSq%=N(%?l*(I`Mm$Ob}|=!Oz7b?r%)d!OES#+?k_)lmwX4DUs>mU{Qk6>UDDMe z>5h8I_QQt{F#tY5!M|+WPO?8ct3JTj`K%8o@RY9~b;5@ABtF5~($Y}JD3c))37+zI z?x<vt78pvirTj=0y2((mbHY&RlAWDq-<L7`$827_hf{`rb7XtdB$n?(RceYYD7za5 zga&jQY;NrbCL&=;&AmS2-uvbm9c@hE>g25#4&oJMs&`>B0NGeR#Yzn-P8<7>bJ}y$ z$4I+K-mHA6>5J=t1KIO<;3au`kOvWMgIh8<DldD%lon%UQp&QYQZnU6`YyuG*9q%k zU1WBs%qkfuNS8k?x0LBpDT#35eC2@a=vHvIKLK{%4ZifoTlpJy%ie#<3ISnU*}|2% zh@kGx=Iztb6){ZAm`8)zR5&(1PT1+YY5Jv_zMXu@lP}%mvD48BFBzJF9F~9}F#f9N zB1wjhbz2QjW-pKXw^@BgoN}!O1BYa#`>euX_GQmA>RNkD!Jrz>jcN(E!{s~AW?h0L z=E&j1JZ=#yF#@Nxp@o*Bc1IKoq}!y3li@%emVuk*beWV_t;akDi=<6%!Q~<xn>e^- z(4QJpI3hKg_x?}_^(gS@#D0PiSSVLK(DzD8?++;)kcnFheZF@i^0sCsjfeX$Te177 z9_>C@+V>%<6}#=rx!G9Hc|KmkP2WXngLyAVkpm}dHUdr^wQzVvMI)WP`Kg)*tF+BT zOacnC9luWQ8dBq$Apx1`N~C!-K$<^K))jCtu#@-OGDBs=mk|czR{fzjXyJruhD^EA zO^hlzj;BH78NiD!fiZZPb#1IA9T2VSiO{p{hBFaDO9Wl^f-mhXcGp{I5?`$|3(7UI z&cyA~V-+O6o7+Cwmcfrd9ETvcWI7xr2KH0P=$)QwAsZ-y=9|a6o*^PJ)O_v@&1s#I z=w05)k5nkbkd7wt#vPK^FRrCzDi;4=Y?C+j(CluO#o#U)%5LI%0>GhzrFlQJ8Wo)G zkS0whyt(wQ$=SUD#<<qJoqh3d#ofI@>p*7ROkM)uv*#3hV7VZc&#M0VXwg)&O&pwg z6^fCnniYE1xK2X#OXr;F2tzPgo-x8F5@_2wMf!}q;>{cO!+!Z5Z9AJR<xR~{La7w_ zJQlaWjBn7&omcPkTIWx;*~VOI01|GZ3TtAm0{d8<n)naN(~VZh{KC_Segrm(f3bNA z_7`^7=Xz#8nTi;SRBRAQ70Q*zsy0;|FrQ3s5AZE#kOty1`1?`)<!|u+F9xSRTMJ|D zLet*1#}}NpOd^q*XT|G1PCA`rm~=NV2tPJpCGuhSDU>u(*9^2Nm<&k_vqTtgz&M5~ z-{nTETOiZ44;keX&4j)+A&x2I6}*}0|A;Ni1;E)mP^;CX?^UP;&h+usOdJa6$yS7s z1gj(Q&_B{;c0dfD(L#E2BJs4nq0%ixR?D$1b(iiCtcEdyiCgZ`GCVLPkL%vmE}No? zOgaRo4qlJ(@)@~{gb^mxNg;}6?CBA!orA^up2B-)w2KEaQ*`P^UKE#5mWff7wt92L zFhuzG+00u78sxy>Jo2P<@`C;)Mf|&5_0o@SurZp_xdo)hLfq0x3~qMO$z?x^G1!5v zjt{7T7>{Kziz>hXQw^m>1Id1YL!5Ah#xl#SiQmRhMmRo-cA=O7KI0c`{>^`F0#cse zBbg_>?xdYvz4)f*M5SXlJdbWtlmgU_j^{U%fEdv9KR$BHwn{@cS!`}v6QS856#~AA z!~29t1tmffK%!{GBclB&#@Xak0Bs)^*#bxaT5M1A1@Ih<c<6mQ&fz?o)_kPE1`~u5 z<0cZv<2?>H-A~24qKSGe18*VFPi-c?)a0;3Ej1DT8Adty5J#LDoVbQT!u99AYJ)#U z3Bq!cSOa9YU{Q~rWNV3Fu{MpcVV<P2kV4X?P)d40m7E3fNmc_mseAfpxd1BB?U?7f zI?sV}zspYZ{sH_ZaCA~!Wwg(M|LoggAfb`(_#bv{m<NtGk7{Ts@G-S3g8wm~RyT%y zN<r5Q{h}~Z(pqG~7NxE~^MmCHPxE@9vDH2iI`|)=wWtfby<I9#hT)u;`wxWa)t!fn z;P>0%ZQB_J-SO-1uNsvZ8Snkb*gmei`j&1CgpjnazZ7Ui1JhD-xjzf$>eE4ngh5ME zq5$qxsPif2sKvzrLJ6NyHa{xiH~uriqr{2^P-BO2D1kfsnn~6-$=3vcZ-!r!H7tYU z8xige{@(2}6naVTarf}(qJMn5*BzQ)y~hI%JzCRAF+!PLeRx+~HM@iE-+w#m_qs<H zw|id<iXNu1b~uid)Yw&WUQEmT6K{t>h-GnZl<e>{oyg+6Jm^wChOrzR^`Vn52E<Sb zglx=N>Mff>#qniAe)A^SNLe3_%43i3(Z)T<%_OtsJWqUFp}IB9h8QZrY-xp?MC*9x zz(gAd@PvkLBnI9~YAq$$;R4dA8aB^*XaX^#;P!StGl(-awV8}b<0GeqB;?rk!luBP zq?)7SO^&RadV2VGmqU9_00|aw_YrtHkvgEOU50%sVu80~##YbF(!!Otn!eBZqickN z>k4k|Sll}5JG|PC;g#z&0MCsP#=xu11ZY6xT-hlh2+%~q_}&E79T36{3C<CBc32}M z*rbN{rj^O*RD-@bvh*$7#dZ2sv>D;V-TUbdN9&Bnp|D#3>C`|>xzI7maM&TpfRbIL zM0S`HKx!M)ENq<`hY`zoKlZ#XDt1B`=ViQ~wr<?w8-5FxnY9g8Y)hS55XJ}A1a%YE z7Sc9y-%3ymtb>q`M32zVZdAIiTE-Mn74*VAT<fzEfj0Q^ZGBe2n1S^f;_VJkm>Wi& znT)H&W?3!BT4T6H-xQP&4VgQR!<z@HhWD}8&^0lQpvx?VNAN_oMtv+<hAqg_M1lls zN$$3h<et{;f?Nqn0cDIvj5Rr^9xh5Z0){-AVTB4EDA`k)S*J@jomw2?mtzw=6KnIw zn92(k6(?`G2GlkYkFQYlK$YN1w9jU9<3M8I1j;B3LE|F4YvKH?@MJO1^X5(GBAdR8 z3r4J11nS|v0!u=#NC^Gw$;4XmPm<?O7fPBae?0LUdFk#nv?y>ja*||>9)RY4PGVBq z!Dzt`rI$j*f8B4nw%JbVQN=<VV}eLAr<``EaV5vjP&qmw<(;TUt<Dqowo`j5?Sb9C zsO+jNStE2ok&Dr}I>j{VK@=`doaT@;4dn_|rWYfW9U6mC?`rbUa?N&(7e?E5ayE5? zjNFr79<;3MOWT~wdG1N;`X~KSf81|FK(k_%70}^Dxm2yD-qlx9H?|01fQ?l1lO{3# zJLUl}+hvBX=__u^33C6goydIwSkmZ?5vZ;F?D%&QB+}|WLa!-6<jO|;s|N~HKG&_I z<<bH3V%4=G*Y64O3BPeGF#PEqj;It7Qm0QdRvI`a(=kord#q>e*4gaf@Vz~p@wXKo z38wS*df!lIRRQUI&1_}uob{2VH8zt<Buhelh5gKX0sG(F0K%%a;QtR9W(lrLso#nF zoJmYb@HG(sJH&4zZDtH7`*RfB7bpw_a=V<4Ioi1y>o~p%1cvCCh0Rdly{t5?!%Z>= zZb-HT>G@GYY%$p|_8pmgr+L9OMH;9!{X|q_7NKnC4}?0SSW+Wh+{<AVejVTl6n3#i zE~|_XyObX1B%h$167esapzxWFNcJvi;8^})Hid&Ns*TX<B7#6%X)#WoHRaq^z#XhH z%|k`BkTq5U`z$?4M|O?jgIZ%5Ev#{xoTNZiMv+xEg;2n)bQyG>7B#*W^+ceHsKY&u z=O`M#SZTFLyfNV6oaNRY@A)%^uR;s!gXLsWeCRIcQ-@_E_W@m4%J+Ts#vbwNoeT~d z!Po=Xm`#e@dEDXCdUG4~V2@D|*7-BMyPbHA1{(PJw5cw~i418v96b)vjp><Ct`({! zyKWq$p-(lrx>JmiQbk@~tsd)3Ni)Keh>8pE2<wh!pe+KFDvBms)MzE(&--ar!d-At z2Q09qaEPuLEpM9qXZAij7|n~>!fFK@(-(V#wWiM<OBb#|2Mh5QWt&485a**WN)B}F z=4>q<aL&r=K@>nkqY3gS{{yFiCs?wbjc5~)*=GF>G5v~zu9xVURx3JPiCJQwwfN>L zfNpoh6VHh!<_?Vk*orF#`)(*xC0=)1(;Tsk8<b?nj+{D0pMQ#OA@F>oYr}1fIdtRE zfCD(s7Q<w8!WXVId6!@QT+M%Gv$5DJ<9J(^SZifqUB!5*@0WIWoY4tMyM2(T%S3qL ziS>EaWyH>%E+amT79#y(A%6X`rTBv-!g#ef+)nSLcaH<hI;L5|@u6S|c5i>2pDa(i z8-L~SYN)P%kFf>PM2uzd4V!2gv9yJ-KNd!?$YB1F4arMonA}N|(J%?e_3nD(`rr8_ zKfen{HL!+5=8hFm4|myt3jvd(lS}ps=3UH}cy#iXWfW9({4gw!Y#p}!u9M4ZsVD^Z zgdS|%{uJXh$vH|+KQR<NM^*QYrt3L3AtYsD)y!8TszIVF?&Pq1o!XzfiA=?@W-csa z(oXAGk8g_BLi9AybO*Jgf@IYtr?|gRCbJ$Y^Lf(N*oL!0+O@+;NeJyLMItf_iDMXy zE+A3o77+OdG5unGd9F@gd^W`ju@H+b@98{mS>MRoPOEC>WG$a4Y%vCF0~tNs7-o4n zCbf7Gu6fJqzO;LUR#;ZII7d$van-j0?PCXBlW>^;_ppF;l@>b(($f<hjhUjyao(e@ zcDNO~5s0aRAu<SFp?K-NbjPDEKw8XHlW&r{yP8yBJw`xdOZe}~VwIZ3GDea&Nj{pR z^&|f!4_6|QCMPYvL0Qs}<Y4am%Y&hn42b6|-rR=f3P%>4%;ygc!;kL*7JL};<kz&h z99QRqXVv-tS?2RgZFQ;N{ks}op2L-H1b;BRk{FS_rAcGn*r5#Ujf8Q$ILlzvz}%s} zVtPrzSjopTA7jyEGx<?mb-a)*o5{0R-(v<*IN0hUo4R*88Wg|XCm+z0g1lXW?$MEZ zRp-x&bBynAn%aAteUM*eajyE<8^1?un=$N^tSDVSme2@+_(Bl}z>&Vehg~f2MYl8S z^vHn`E~@Zv2X351-0&@+BZ9ZvAt>YZHEMyXTaDVFYSav@Q1KH%3t?V+2C4Xo9nG3{ zs$$R@n6vtptG3lt{MAynKu+;S>k=bYqr}C>OcV5>uwGNn6$)Rc2?fK5e5Loh+~E9| zWifh(aUa-T;PLSA?|=IG_{;9shesDjKONuxrg!-FZ;rqG;<rDc)xgo_@t3_XdIPD= znDZ!cqwmwtlocsbs(x3@I9eEzezvPN_HrH4004TW<TZ~fBMjS|VnVb|&ogK(>SwH* zX}E$ZyGB&vbgUMq({LiGS@5!|iAQV|fW;#9e<BH1qdr!|JaueZi4I>z)a5t8r1$we zJ0(Buvjs-MoxtO>YUD&3_#!1w^wgMXb8g}rQWVv6^6R(X5Fd6W!~vCbUjw)B&bW9l zk~a9>C}!Nt?eKbDvz{|Bj+{m$CWBoZt%Pjh($3S@h=Z^<RIS2+MenIj!-WJ(g<yl- z^}V56d3TY`Pjd>mK#3oh^HKhS{G1H)j8U18@Z}BbOZ2cXIN)lU0lGIf(YJ+#?gx4o zklJtrYD^eAsHcLbldjs<R-ry_skbI}P;4ajP{dus2ES_TPW<UjT1iuzoo^=FC{z80 zh5FXo6Vs)x0ci4}X~KH9B}HYZKxhodbIAH^L(t&{RV$uZb^8KP`W{y+lEp`X%?v~w zjua~3Fuk>kNTmJ2d3b-8)qJQ4Ex_NXp7UrA?K})aWxi58t4`8^i#C4iyAQYFC7hL3 z+(~7^&*Fa+j^$zw^x8yFOX+cjNjzZ6ZkwT2?gz51K<ChlpSTbc3jVF|xht<Y6qSpp zShMgUwA~2I<&@YzV`m1}IT~V+`GbqiV%AC(YLwYEY5RV%W0fHS3^Cy-O21i=E2*yi z`h5<X|Ah1eUDpof-kbEo<~>^IN_d;+>e3C@NdrY$K=KF%A~i2YPwSd9(*=hxT%xA0 zX4#0?NFd-pQ9z6YuIKr;{Iim;z)qi0_<{lsw>tTiBu&Y$RdtTMSVD&jMU>~ePqa6> zEFmk1K~2aE8ZeOTzb6#SoC6uaS&R1SHY#gbVXO}LQ=esHe8iPOf$^B4&T*U`IP$$= zU^tWKq!&PFc3@dL!=!^}*K_!Z_Zs0A;jP^U{NA*TpYS)v1?|u+hqVrMts9<J*@7B@ z*YsPw%t_M%oa(n#^{yrrXo^+cqsQXdjnRlRD4{`(wGUv$<|vyDxA>OmGD5nuVp8@o zpJ1e^re`gmDeNoEj**dblV#6BIwH=AmZ}tn(tR{;2A<Pq%+0{IZ#;3SjcYk){uBJ8 zKGioW@YhERs;0lUWIjTnIGK%5kJ^5U3{?!<dBen0)WHQTK~%vOW#HDT?mLuG8NmZe zW84u9J(Hij?ZfsN+EzhHXIf=#tI$#kz8vfP&;H5i<o+_Ts7L*ZaPJ>uHkULd7M}z& zQcOpT)6fGij#ZGg=%|ZTV{Xap(ry`Mae_o(zb6VnsyB-sy>b5Usk961bzk_r$W^fb zBJ8f5F-i;Uy|Hm>_-11HEh(fUWhM`s0cD^_cq=e9s|&bWm|@6370uJ!vc2&Nl~(q+ zLtDz19NLVrh(4s#Vc7@9hV(>)HcplyukxO{<NJk`;h7?s+@_%urTB?9a5Eb#an!q( z4qd=P+uyzo^2{Adks+sG@_KwpIVGIb+UNnVnkH`_-6^+Z`{V*PSDKn3!`!HD4BXK| zkR7l{QtT@MbTDBPWls;wx2)D8TR8E2c`dKSfISdR=PGisRp~uFIIwRAdqx;*G(qoj zrG=#{u=Nqvy&1$Dgn^4)Kjwuq4KnINmiHD5Wdhd12Q)oL$f}-228u6s@qYi|=b4&L zlqD8jgiHk0;2Ojnu8YWuj~roF#icgI?3uJJ*0t^ZnHD3_b6a}$62a&bKs6VdS2p-5 z5gsZ|$XQ;-`%~h!U<yu-U>f&E9u48`Y}XCEM`zi5Z_(Y7U`1bh@t)0B`|PgoQvMsi zyoqW2$i@qC0izE&A)7-fd_IoZvYQ%CI4EvHW}=PE7*xaK8aM#+_OUXC7XeWqR<Xm0 zoHAyedP<mN47UvvS*p9835CiAxUdSmBV1k!83WylQO<b4u|7jy!-IyYv|@aH_YGr0 z%jEAI_v~P4I|f4ycZUkd%9hA<qa3?DDA;1OI>qb_mq)eM*q!b*Z|2foehv5Hfgs#Y zcHXgmn>-qMTx8?1T5NTR_5?Ks7#~*{52?c{QATc8n+e73eb@+x!+sW}I|4mxpHLPd zP4UgvL=eMy_9CO-8;@%`{J0bG_6^Tk88W~rqHrF>)ECB;J~9#Koou_Y4ch1i7`jy1 zwBXZZnw?4(Q?Zedd?z}5eyHe-j}4X3{vpppgK-&MJAxP<hki^e67<bmkGhg&fyHi< z5>xG7<g_E~v*;_u!Xpspe=B6|dCZEd<oqi{UF^c!T!#@!t#sClos(rKT5K9y>k{7O zg*I<tHm~)PiEKX=9hzxk`zY7mkO%pq9st#=6BSNWV!_xf3s*3g2H~NBD9>h8?c`qa zQhZEocQ(<`T$#wRovRyB6#tE-H(&oO{_~?>V-<$mcot6;J(6pKV`bfVDdH!|s>ncx z9GPlYQtb$+qP7HkR>{>fz9r78>YegeWnC8aKuiJy$ApXEYb3Y2q7%VY;+OPS!7@)& z$(zuq=eV5bC>xdM@<iO&mA9>zNnzU^dRQ3cNk*b(e7W4ANhN?K!oL`mRvnn;mH74P z>3B}Mje}U^1R@qvEz(%oSloqTWnkTLr?AgWa3wEZt^%)D(L0cPan9GA;mif%&o<z# zgk1x4ry6v!4a^7ADSQ3(f?)F4loS7QFO8;Ha1OUi_S2JqvB}UXj&+MhPGcr`+63O6 zUelqkxnQOtzZ2D!wyj#57McK4W~<lvCsIO(NuNj$xq(k5UXB8}fdq6Yh%rQbog)wg z?3IUw%6j?FI4rFAqV=p$1N!ejE9`LBJ}R)rb&d+&Bz!U$<%oE<{`MPn^amXycB}sp z$4Knh(5D7|Tjj(138WR?8CPWa)`%g%uQiqZJw(Rsp?YyS{p9^Kq5v3cZXfEYeecLX z{`>b0k8|x!GxCD?tifL8({s&ZDU0&+e5&c9Rm5TNa~s@bvwQTcH#k+>1f8rxd^v&J z#E+=w<!I^t{_y)9XZ0CukSjYr+}r%W$9~6QuboY_0LUV}eRdKsLNkUdD1h61ZFIm8 zF9rKum7P=qs?0tlHG72dHmP$(DR@$jN9b^(WeTcy%hQyH%nR4K4OM0zIsud7qAf&X zP7q2FmNHKD>A^~egf%mY;Xj_MUCb{-h7<>M$XadxL<ouI4RlgK0b$n$dp7x!PRnYZ zU(G>d%L@FRAgwJ8Mc8Via`Y0}M!t9To=|yg1K!)K>+_K9$!~ix87a^N$B~+aT(yqZ z<FKLm7+(#qeGQmRPEq6+>cG>>YZYiKs$!p*<_Tj|93Y6gMDvKD!*2%6<kAy|bsQ^n zjN-VI)l5qcF6zAjm$1O0+WyCFIjPs=+5_RA^H;ICby`{Vwd7#>=(4&l6X&&**cTq- z-4r)Qg<vT~4X53!4FH<vX(GTDi4lW~>~#Ahyrmg4%$uIzxoJ6dBX}>{C@|%Wn%@!Y z*;s=8^BHm8xCEMyY2jTc2ivEEoKv_30H>G#40tPTg|>|KKpVnS7rZ8DkzGVai8w}_ zJ?SjP+hF7~Q`8GRP^S^dqruc#{GGE9)|_4<rY}~B|2sK9*NaSuXW+Gti;KfnYrB%i z^Tf$<)}t^6gL?Hft!-k071MgQ(~&Dkgm}V%`cpN3m(3~gDGG)+ek|XWK*KRJA|;Q@ z=ksd5!JO~27k?#BB9yKp+<!o*zu4!tv?3IT)9VxBcY9(~*!5VlRmxlcc9T4|S0gvU zAsp%Jpd_hRKNTgF4a6EK`3AfC!%^~$notW$vR%d>hmtL5h;3}xF>csvYjNCysc%^I z?P03VOPO`Y89im+jg|;m*TJT)hfXvK&RZPz)oVkuy&1bp`d36mqXE(b_OKi0Mtc|{ zpE@4`$rH63y*!KRcd$xRC+;nY0Tn9fs73N3SD5G>fY&(al>UI)ZPi%@_Vs>@JAIL> zyr_!%1-d}nQDVlQvkc=Dzpkpq%@xvnTtI$*h8}O2MbkWlqG~@LV$@T_511E3S(xX4 z%-YYm;m^7F(&Xn~eQEe#fBAh|dg8z6eG5~RlACR-`rStf%WX<XpS7@n%YIf0FgC4z zemvlIuVig^wFy`#?rh!xqDaJA<*SfL2i}Z0OV|aDiN01}<yI{)2Wnc6!ei0Ty}aE2 z=cn-#&ZP6Nwz%5r$}F_nx$7-=^n|xdYwc?q=A;8-j?#X<zo|YM0Whs4Iqa#Uy<x4? z|MdGSx7m~#n1TCjr7VnP{PC4x_GOn{eT!^4P=7C|<%s%Bu(l`Z=LEJi+Jv?p`x@Yu zvg^b9HB0Up-kwk@Vk9jDCoY|$c77@rXP=XvNwYFC9MXCaJ}?uI1|niFJ6;9Wk>T_k zI%huHYylCRbYq7<I?qKVOfireXTJzY@zdvoC3&xXG9Y=N4LIWKs{lxDoXqx_?<>J} z6&f0tnczHP<cCrBnap!Dd@Vlb)=lIcGY!#Q)~MRKVh#4D(|?I&fN@@bCE9t|C>o=y zzX_Z0=~(>&+xeG(DUGxhsw*r6ELkQ>+&3`m_WH6^UA+}-4Exo@`p5F3xhN->EZR4L ztt8I8y*5q!7<?^~?q#XS&6;rIIuXe6ht~U`mlkF{_$hMDH#--`+lyBn*l?o<b=_iY z9at$~(d$j0sx;<KZ{uw8Jg-qxY@O>?;SZN(-#MPJ^#-R68$}xnG_Jko&2(gwV8kR8 zz6Ex}aQvwxIEhF_os<7luLr30d#)kUr{0u)i~<kM7S-wLl=CaOa_vO#wF<-gIUpqZ zmFoj(eY?7q26dkSRL*ZAfYlo+zXDcOc`aC}{;!Qt10P-uw*!iS=KK!m5tov>gn<sK z$>etcTMa!1?38<4bz{bWcP5$^u`(D2t6t7HeqLZ5;{b8X1rEB}<IYyo(Kvd3?q4>r zaU~^Mc7lPDn^q>`lHl-0l1kBR+pTRPhAWb-+q>W+peXwiOz)|KB@GS}ds%B1_XfiR zwFNNI-qx-H&R(w$B?1ZhH2zz*EzilyHKwc(f+#4D*!jP^L9s}i9o&ZZ8_u;q8YP9p zOtcz#hjCXPMY?&Mge?yfHK`Rw;A@#Tw8cPV&6MImY^>gZZbUV~vYywY2|CYeJkjc# z#xSoO7-@KAI9C%@i-=?lini-ME{3KF9M`w@1N*iFQ?@?MDwQ@~hcLXXPV^!7oFGE8 zjYNte1UR)tRn685ha8C;d;KuSpFm<cRIh`%7q`F~?I2B&`;93O0ristB}^HVr)YA_ z&BZ1Wn!C0zkC=-in%F^`wo+T~<-&rY5Bt9lu%v=_jaDN#XY1bq;HqqxsK$Z3f@@_H zADo=5LeNe-tNvqo^0^mfGFh=IjZ8wHusqJe{-3%|lgZ~=sAc&nOZ8@6oStI9<v{<z zF+DE@qH{A}lM$%N?{Pcp8;5&KB(>umeHs(TEne+^5(jD1dO7Lvn4GmKgB^~;Tmik$ zi4T=UsDHFaD_yCXJ~+c@S!>$4)lm4;0f)6$U-r=uyE86;nanObCQeZ};%|%b`j&ZT z#W?@;5o7J^jktu{cXZST7}~U6#}R^pp!(R(5l!fRGGAb_T1py$@y*a?h=QqRp`U}P zg9->sfpSVzEfw)0tbBz`151yCRmFF$K+=I#x>U3!gJBG2ob=tWT=_3cm_b9YL(_@! zB)`M~!t;M&!IvY;X<J_t5R@m2c`Tp(_(i*nQ~C%G9^ARj<H82+2o_U#*m##Fx4G8s zWcwOW^31$e><}vV`zB3ItllU2FWs$c44zV`T|IUz_WOp8EnGSB%_!WT6C<MKt1Y2| zENi>YV#IBER9GMz2#VIY)D|O`*A!?|=#IP&q%FLno}Eq*t;glogpQP)GE9=C4U(IA zvQ%&^9jk-2@f4mET8~^SmGp8EUl-2v5XzKRM01KS#k9@n!tr=5t3nwGK7Czm287tc zOnvi;U}+S0;llg?hhfTx;vWl43ic-QJqaC=`oS+$GD&sAr!H)$HzUhgwQOqHaW28a zyY8b$!e8<r)CyV6kq6+VO&E`8-OS&yYOzPts?O`hN?lWY(V7@gIa@T@qWx<t3~(@! z)t4`;cV<I<prbn3xF>)hrfU@(DvS$79z=E}BV29a%i>~@kJ?aD<dJCjV{wBj_Az5y z7`e(<b$GFpya<QRb%%W&++42P(#@NVz)WF0-jAQATzRciL{27TtR1n<HbSrp<-o== zy_yZC`DB5fT%OPRWL=J!J8VfE!h><SB4uzYWu&uDj|pnHp_Z+pr|nPF^wWrJhzp6b zDiyV)l+xZ!7oOFo;1_C3kjvP(8qq)d)AL>P;R7F5m;7f|>CnwyE8<lrB0A-fgzj)I zJ~)QIZ@9DV+OPZ62>j?953YR^Q_}aOJIxnQ(7A%7vIP`)4PbQ$3<H&pq6NDap>cjt zxKAi^JL&Qm`t@jDO{d@COAgZCKdHu->UA&K6j1d?)GWR<jb2KlfQyYb-@v<Olkm3D zBD`B+jW09BaSxLZsaW!1NP$Z)t9<M}CJW~_9&Yp@Wu(A{Fq+a3h+`jr(2E&gVer+A zFJBb=7*ki8T<3UosBhljs9KV6+y?5D2*_4IyNFn(Y4>zY<OR5Xj@Gr3gWB7voDn^^ z%}}fHZOdWWlQ;aw?N+Yia%oX0rDzJde*dGX_bRMTWQUuM8BLf$@U-bdhRL+Fm}Q`{ z0%-`gBvP{(hn7Sa?X!w?c_p}P{HWF(N&Z|-D#o=EF#_EkFGrF@s4-L9wWdf^M)7Dm zT?c)EO(PA3(I#aGhy3}tiTHk~H)-&SV~1~)a_XqdH0xe$hV*9mx)`t}Om`gA)TFV9 zoT8ht(zdi`rc;H@sKPZd7y1`^E>srkY;H$VRmqQa^-;}SpsTZUMPailRTsAuB<tdw zaGjQ}*3wWlhZ{+a%4nmLqkfu>sgN!Pg1?_tzZ4~f?YTF-)MslaG`y~2%ITS!=^%|| zh)T|E-L_Bi)1oX*qHv_GNZ!17y(^}Tn&B4Nz+$e_HnWLCIDim)OkIqHD2bWH5SHD) zU3E|L9Zekk?~++D2KDwdi!Et1*GaXwek#rX2Qn^Nd4Nf|h#6h)rpdiDxo+A;{FhO4 zAi2t{EK5?CaSp+`dA6~T>y+#fF@UE1#*YWWC9;34d;(?&JwQ{JgsQgR%!@Q8uEEYz zy7!RlzP_Xs#L^>&7A8$_<!JCwZes}Vx@;o?FK#Cry$!_}H2rK%h<g;QIp?-pIv5rA z%^Wb^>$jVp{kE09%H!Znf~LWOlI%l-j7B^nqd+qU96H9=J2bD3lOYK$Le<vFhBZhd zVkdgfA^YW~?t&E+IGU8M(U{d@QK)o5-1?ZrC@Ee^X>|^<?6FOHAz}@xs%@-Lrok`U z#V!2(5tkD=%SV;A47<b_<jc8UFPD@6`!^j++(2~0)(cLfe)LFB%@=a0IN9D*+Qc)^ zAW3Jq!FY?lDVZL<hb#hL7Q$e=YUvo-@UH>4pKw8{hPfcbs9)^4<cUqe%n%x@9LmZZ zP(NYeNc_Fa5vvm=Hab*eIaaIZg>0j^-+G<HYXFj!qV(djt$_j}1pACQU`2FmAwg8s zrWcb7glkFSp@XXzlzS(@w*mZ`3*trUYq^TqnB-v+6^u$GQ{g1#v3mw*n{WnM%C(E- z*P$uCk%y@&o`}1$_Npr++}yU$kgS$$6Tnc`iOdNH-seVO3a5C$E!K~=-I7}aIUYL| zX<Rw9(Tic!t&>t{nOtcN*{q`fQV1}ZfBBni8<nt9WN4PJ?cUtJa5xXQfb}1_g7v@P z64voGG)}#64D%M>aBH~HyY@n$|E{4Df6NM$jmR$720!_s;XsY(`wv-%rsk;hqq{U$ zAwqFG$|Jgy#*GhFFA3(#EvjYx$1V%@@)?%J4)&kCG}!O8m&Ocs-Q|HHkSmna5M3Y6 zCL!`?fVB&P@Xvv<8Tv{%YX(xq^0?+ku#jd~vQGfB_yB$~m{C$sf;;1YSxx?M_)1qR z;p@w(9k=z;25~JWFxPwoW3H2z0=H`PXcYESy=Mu!Ri)tpPP}R0^M@C|Mikgd$zxLq z+H4%=RmycQ3|2$az9P~p<vNv&9g~vt0CD|PT61;~R&(sJ@wKN>w*waet`vzXxy9tp zbXPie$cB4J$gjI{O@%kcRh=Y@d4?H|iMp3ADXQJ!7kP3{iCPU>k}tLWytrU%M;D~W zWQuZkMa~%Ja<vD+Z|yRKnNXAl-n-|No^O-zC>_pQwbg7^U?Q2EyS<i6j!qx!t)RBQ z2yPP6bYKY+5o6eE5@|kp1wQ495pt@0*TXk<ciTW2xk}#mhqAOk;vhbm+>sHSy*l+j z!G?!{@MAkDluge+hhe6%1jN)6UaV%GP0?#JY~%v1_~`nNW28UBq6Z@_|FzaW&ZMus z^7Tqy-Bb}n;_XjEg^+)*|2PKzbI^e1X#eF=!h+@#P$F_ih@-{tW{^@*A^rc1(tj_b zbTucm9uH&!>~j=+i-Vm%hBxwXC(ap3k@ff@B5*4WJ3I?RQbQV3c=klFq$=T-oH57E zwQciPUUt{C<Iv-59pS)BGYx3oeua@PZ`t&_Ht1!@fjZ>c+7)v+uamM^cv-B~N3U!J zcrh==xun1F#@5U!E^+_a3ezcemM5+0hR3d5`xB7YCK^|0W_^vc@^UL;{A?QPtAyW5 z<8muV>8sN5nu=aV;G2Ov6iml}FfuKxAF&`5YeT4Jqfok~gtumWEW9|D9_4xHvf&>6 zHi}Nn<RB!HDDWA74Cy~Sn(#%g4SNJM-vQMB!B&}#Z>+|XrQemj?len;=YILVUyu?^ zetn%h;GXqFY;rg_*r4?e8(rQw&pw#^-cHBvOmY#aOlmbWmxbcr=@99D29T`}UrqSG z(9uC<iD*rgl=8_|{F<*f7AzSZ#+|KC@4iE^13K{$=#&*+GzT+wOklC*;3-?lsIK1- zp8K<iZm{dj<)%G5+fbl(C=i`;kmtvnvKI`zed>`WyjlCrtbx^{xgUJ_wgzqw!?v6Z z$u5aFy}_3`FlF$1TrD=s3QdvF)qcw)hQjPOoyoMy79HG59U9AXdTv0<q<QfHRn4+d z;pLQQ&QhlXvNMii>B@9D@nkj~K4m&l_hqi~YgL`AM9}<F9IBv)Y&tv3x-yYR7@|Z* z^kuTW1*mpA>GV1t52BXEQdEmbI_c!DDq!HJGUgx*0uPVfn}npu-HA0B*}V;ux3#%h z3<&A+nu2@}C_zl!e_KN(;8D;k*uF{V`8AveWP^pfWS)HYmmj`Mz5~9mtn>a&$~HZ_ zoD-AS1?s&0@ZrPFJ6qd3$^PuD`T$?&vwpIN7FbvY&BN+^{yrZ|>(bINIa@4d!@=O< z;-YUZETigtFy-&uQOT<Y3{GqLkt%c(vDi%O4Vr>+geUm1tU2!ka80n>PY(`Eezsx( z*Pj}Vug`(UL^!F;ZSx#$toahTT%Z*p63o6##TuoFF&P6Ab-{4LnlU2K`~0Q*4=f4) zE$7pp#n{_3%!2oby<7<XGt_E6-IbRg@h`48kDxX^${Nz_x}B41KE{T(G0|5wEiks% zxI?w13V?1(d`1VqnC4(iP#j2S1^2h;91ik%kxc;x^Df-q%me47BL8WD48uJF1Nur= z5MUDS_V3Y>vCT+#!yv3e)QyyEpZpt|(MdT5bAii`*D_#F&$EEW@%cQwv$GRWIry-N zU$*!?8RMLuyv|SeKg<9&19&*9zdY)~Ki$Kv&4<Ugd+;+|`FPYDoEGFO0?YPl4(z#W zulsliFX3PKAGLb4(LMb8(FWGspt`-^?57TX>fonN@CiOZPo}$`d{O23g=*W5i5AKY zh#MP1nIZq&g`c~R2d7jRjci}zCe{^he=*?M;Srjm3vOPHD)jyN4oK7zOa0@cd-;Ox zGJ!xAoH`3Lca-5{fl`C~=~+f7d9-}K|NJ?hC}wHNA5eY@mnWuDddY97hOq{HLPN>F zy7zKF^akOTeWAZ}9W(4r32JmZM@JjU(a}){{@I2950hO?y8#D)H>I8mOtyQonZ(>{ zH<HZUhwq_R{IEF2gV+b*ZOo0*tk@`oHN)1NA(^uZ{x<*6rJG-xz$M|-WoNWy&Y*+~ z^Ng#2?pa8TUX%;`lETs0>n|$FM8AFChyfhmr9=tIV+vsnu-rmu!tY(Q`Q1u3;VQV* zxX^U|gr#r{^Pc=TH9t-o#$Gf;mOoMuZyaUlDE0a;PZFk(e6pj}@Z3r&q20ugF!K1w z7F@c|ZA!~7Rv-Y-ybD8uQ771)*uQgs<YffZr@NirN$>Vd<<M^a+sHt$E!D`Mo<HB( zdj4ESHlS^d<MHCeP8&KQo{kCeW{G0Tlj&)$^$JijBgZ2Gnp>$fsX87Qoz{dgbGF~c zLs{BA&*3g7Yd~%V=x2>bb2-jRBRrwWpUkU^8odBmh;^1>VNChdPhKosyVldHWZad0 zXwr1<(+ZQ3dO!JbKCQJolAO7&v6I}i$1Fy60*5HDnuB>h1qK?1z$WcgX-QZdQE2*Y zhyusyfdZvvWyn~c`H*2E2fugj@AgCVF`g>or2?yrJX*=zzC|QnI6|U-7>1(ba}*yH zR?%oQR@HTbpReU`5HXU8<0Prwi+Uf4Q9e$Q<9TZMBSrc99^<rY8`s4TM%65Dt@CqD zpWy^?;Vf0gTHyh^@b9GfkV=+R6vF;zRg_+^#|4Tph{XkZSS=P6++wEWplba@aTGM| zLv9am2Al96sTH@ZvtQm?po6NP*)ebfXRbTeDt&2bm%d%mGS48|G=FMon?GLBI63~t zn#K<;4Nu7dcxAJ=3MUnM7az7QhHVlGK~ZzWY}&hBEGHfI4~5|{B=b!AiE(dKGBD3c z-vyy`<1gSC+uUZOY7cedQwc#M0Kt<zF=2Xe99!s}fD?HOZCZwcM3B>bk*|wxt)*Mg zsI`0>ZnRd2uDC!!4ia+1MIXdEaDf~NNgBZkLNr${Y~(CdQU0Y1pi@*0HCjxxHZO`X zs<`GkNA~GUAA?})XXR6~``_i4-c~m<Cz%d>KDO!S1YP}v&TaV0&9HdN=LrQzwdCpw z45gw5NBLpvxS3j(MENa<s^*ipHq5+?NBex4w=R>rGh0=XxmM#*k3QxsJ!t{D)W0Jl z;xxh3-)S=PlxMf}+GM>epxmf&a_t(Ut7-r*Y6^Rh<XId$RLPDx94=x!zd32V8O1kE z7Jq#be?1De(jeipw8@PTmq~H>k+&m1P}nPYk?GL&g%rX+e_bxmzwsA~ZVGtScR@_- ziA^zsmwA9X!TkejHb(g@zs@LmSUf~>J*<FW6{y+gy~VT07bDZW$MlV<FY1a5!ot7H z^V!e!6f-uHm`GCJ!LFg`2-SJ9kdW5OWh*y;NWJ<V(pu1{43Z1tWfqRF9`H?<ga=+C zdJW{O!ReB4`#2pPTyz*m-NU2K(Z=rZxQFA|_+on_Y|-d?7ISY6EmUUnY6SZMxMg!! z1jdX0xkLZn#ZcRG`sa=k(aKmTjU{~1MAZWVmvo@FY3(T*c{Ly9f;B>VY7Vyc%d%qk zX&95AGkc@6L3>bxp+l303;hOOAE8751DJ*z1U|s1af0&qZqGXtEC&jxTU`L>IWK05 zpP`&u3}TJx!;jQ9e0AeFJgSf8N9FPDfrOz{<bTk8o4wC|dw<g7>cc_NU*z?oYg_9z zF=%6BH<o_BG1B*^KaaCTMq@=DX7G1>92V!<X?`?-&)4m&Nj)Xf1?<HiUw_A<R=z9^ z%=Jn9jKx#|IQU6%>Y%Gxe%JTX0MUM9+l|HrL9mk*7@b~|zQ1B|FG@jifEt6${7{rf zNaQVA1Bt{bR@;86yAf(tSi-N@eYpkyZQ`Hp=R_IQ@>|+2RP2Az&3Kpo9h!@(*$XvA zs=Q3bRoTH<PB8yTKF?JgI%28t@`m#Bwh<j29Ug5Qb#{kLuxLnp9`sb94VE_^ZTxoB zVOb;tBTm*FK~XaY3Z&XL%cAE_LIyeZJPxUAj1%PaWr;-}Lnsiy6^gQ1iMfUzZXeqb z1R_rYe1B1WS6$@ur<pS@aon6~<j(3wG`ZqKFUjjsHlvtuzbs+GFmk$VAKl+UIahAV z8!0yW^dlrmT_>EBl4Y0GCYIQwB3p?q;B%dNMd8%RHYY$`^b+OGjm#p5KB|>aa`+U9 zpOx(aBfC6-HSBKp(q#L-3i<ETD*`!?5>Ge#jnd3AWC%@(3IU6Mmc1`9?1+ic{DC+w z807#MN3mA|JeKrWEUz(*T|t3yC|wi!c*AtHfrNbE`XS-}Z%2cpFMm7w@@Oz%q9-|~ z)yRFnSdYFEEt%!>j2RJ$+LL^>wM8~~c}DR!PO7O%^Ht2X$jqCMvxb^Lf14LM-_{IN z`4hC<(L*!q-@!gQZh$IAoo$u`U>)D^3N2VpDaraKe}=|U7)x7X1Y5$0%?Np4?>}qw z%u62KL_VC%sbHnAB#ZlY|8F;Mtit7pbTZN?Q1O}rO%Sty+18j-ATmxZ!qhxYp`|}x zuahdy$IVOFa$~9D80E)?eGs7+CHDcktuuo=sAxilQDQmDkR>{O6O-2vp{-;8^7yfF zU(q5=r{E-J8daNGoS3}WXQYJ<fq>IA*GkGZ_?Eo^N8X0cR2nbBm+_62MQG($7om|v zip;Vx@(VPW=GSw$ofT#D;~k?j#qil$ZlIo-RdCO;8`ROnVRw>Q1$Z?@SaZn~0Vx}w z;9uvO$t86xm*gFHo{x*=dBRb=?N0XYds4p1wm?tY+diquj39*Aw;{F5f&NdKJSsjQ zGiDMTJm>2fzkjq5)hKU#^Yvi%jqUrON??e|61G`gFDWJq25VnV$4JyqXwS_XQ$OtJ z;h|Xx!eG_p!x}3h_;H1}w!*5i;~EPSzKT>9Dm+qCY;V=zf#}|d*=4uAQUNTb0szX~ zbv-fu74r6mazJbZUwX+Rj0Y*p*a6@wl2|#t^augU`#sxEQij?<MRvgBew!*vLO;cH z3Aqo^n8L!xE3K@uUF&$WqBvI5)~W{PUppO7y%37}ZM&l8Rp}Fy!s5H4UZfIcS~qjU ze&y4_Xp5QP?*=%I<s2@D0jh106;Y}k&uUAHuGTxJYHtvlb>I><LdO-H7+nEwKcb6@ zDj_MEhGb-Qn|XxWNrzS5+ygxBDkdYEr72j6q9*0Mn0!Xo)Gf#N+00u2cxL6dT7k}& zoyG!SIZW*>zXR93n5gvQRo$p@e#Y)vWv&B9uFR&*MkClf5^s$+tQTd;5CmRoGjKZ$ zugTMCbwau3xMdg6J&?T{ac8i30OsaI4L|Aij9J{dtG1#?!qM}YNcUG1-zyy~laiZm zKM^h#hTv=Y%8H$F{f$Al3g2=BnB{g1{wMD#qr9(cXAjDj+3On#j;r&*n|Yr9luh5| zb8RQ+zy0^J6|_?mi^06iPH=TGh9u_fg>Qs-&t82`u_ocRQ|1(*3zP2l<7RK@f8|<^ zSqxrqpT5PQU#&~|R$j6=gu5A6&PY(3>~U*-aoFgxIbQNH5dn#OMkhV_*0j9yS3hce zXFOW~;=sEsM+@V;r+}!^+Z*qdkttryJ$DubATLo0OjvTwywpy1oP7qTLR=FEl~nag zsyDAHu4cI*e8cW~&`61%LcFLP-`DuCGz<$(|EX=#If_UyCtJpM7(s8qAb1oN<P@7a zj#Pa{;tB1y#-CGh&DBBpTugh|%?LN<P$gwBg`32*fEo9uJlDAs6XxsC4(2$tjSoJD z=g?~t=-Os5SKV@6Vioo4)}sJ$<ek9PVsWz6Ny@LA@<M*!y!sF@mNU<@TnF$q4w>rI zXbs-fh}fhjvg?9ANjN80Qz<O$Ect6}p7DvsXBrZG9r?>cx*x>jlJYPAPRvU=j7S^- zuUtp0V0R)iM5e-{2v%rCs}hxm(9y{3Kz8lr=k@0pDUZxIjrB6|#1x^wv0Y>I$L-(k zvCN=sJI8OfuDyI~4>e{+5y9G4NL$*{M5k!5Zk_8S8Zm~yhvBh_96!~0QZ7&mKuyZ& zS14Cwj-M~ZAGId*l3BA6upKU<Ky8w9kzYP_h}<L`GFJrCy55MBY=Wj~CY62AWiX$T z9d+EP;-Rk`BhB-o<HG-R8qW2mjooX4#rmgT1sWC5>N9}G>ox!ne)|;gpg`0@r|D;Y zHH2*Mch>4YLRf$27_QHmzs}0jTr=hN#lICl{t9UBi+!1#VXkNM;(fNrTNrIB+sf0@ zS7c{z-mveX+v$MfL2caBTrRz0R(HTdNId4%p0@O@J2v)@VZ?!(HX93$4>P~uoBhAN zdA;}a4atA-`RRABUhbo}89hDQ|8D;cKHj0nH?M!(7uy<oe!lnJ0lpyF0lhhRv-kSV z&##_8KiGf69(iyAy`tnJ9aZ4ztCw%~UcB6YZOc662+=6=reVE&<`>G#aioar2)^rX zBu~eqAh(9>AfvZHK-g!WUmj8B4HIVT`8+#4r%Q|<X{H+W+X^;47hrIdrm|b6NhJ;a z3@`U#FQbgUi{MQY`Wmeb1zYRVQmm>>T|dcz(Ew^8Ew~Y>^P6Kl5J;flipKVkuwJJv zm#r}}v*yrfy4M^S)M*TBbvrGCLT7+%R_EPCt<%WW$~S&;=wazG=Lnk|1}HAvr>(#^ z8<dup%{brD7EN8h|J|@c(39$1dEryo5i?ubF@S|J*rIO)pEbdX+m+jO05^-Us-dS6 zATNSKX|knT!xv=`G#dlrsjzlNhBcIee^pYm=<=Q;LQtNlY<@|5sP3Xik-mM5+Lkm$ zOP1IIrb#}EuMT{vA}c{OX-+-O`#vRv!B8*qp2-^qc;UjDBI4W1yyb#6%nBJVCp^kG zuYRT<2A>0ebRla$$Dvb?aN0Pk5e-d;9%=RibM$-JUayyYgpj(T7X)Cek2}}w1AhSI zR`n5q*WGKvE9fP}Mb;+T-C(G@#Ky_Hd<aL77*4f$Hd=%=&8Tbxa>mED!L%y#E9(<a z5UE`Nb2ayA0_#RJ7Ml!ljV;8~%3-!&(C()ak2H(Sbaw}){te9O=a;XZ?V}~m(`S2c z_RJD>{qB9LahDA{+Y8+5v8tp|;;-7Go^Snb=vs@hXH*9$7(|65-|5U;U90Xu>N6k> z9ZiG&eMJSUbsW^bdDJ>wL;jkhlRP_aY{&`mD1>sa9)xS~`(iwv;*pxOw;A~nNS4Sl zX^f3NW26W@2dk`E8$f00MOD&+qPq*0b{gku?8JaUAI$?qYgnr01YCtfHG|`Zpr}$t z#a;v9RH`UsBSY0e`0pxPgf&+#4AvF2&Y?2s?r2W(D};MBT)dIsHI8wl0TVgu`VAVT zf}MHvgSsreaZC&k0A)S?qlJ+11<0pj5-A830`7j48s^G_!La454++&UcJ6aL6m=vI zqfCG)=Cu^E12-%?#swUEW<H;vSLGhsXu=IJ=&|4O^`^DU|0vmje&7pi!V;F+gXhnu zz>5*cbHeuS$gvuYRH8~K3(Z>6Y!jZWMq%sXE2V<aQj!Pt>jsw+t6;^Wwo50p+ErPA zxExS=X<cpl&CN>qryIIK{M%PDuV9q)JshCz)pHN`#_ePA&qe*zEOmg#-Ij|$l-Hy) zEOHNMvY(Ny)WXf!Vec6X*h}49o|u<UG+vmOPw8ShIxk;Wl@a3a$=@d~9$=}`;F2jP zC5V$@Y?2*Y%}&%d6rfw^WDog*6QZlh6KRrELA6<B_&#Nu!>kMv4a4}UKKbO~IrgMc zSDLgX8V#VG!k&{jHe0}4T-kzb2r`rV51Ul2^c$OI50}lsS+gLr3|PPizQvj?3RFNt zZX8fj`Rlg2o7+^GAsSKZ^Jki?$34q3);SD%%<Gt`@bAe}V}@lXg)jC@W=5e~(wJA~ zNuL|XKswND>MyxX^k|{E=dZYJ)LTL?>!&x&#(I)d=S5Mo|KLc|nI|4~p(Is`e?fJf zTTmM$4;u&-CyJz)a<YdgLI=Glb<cYqiSsg!Q@4)FJ+*7S=Qtexa{IQN_}FyWpmR~Y zF-Z6HGb0YH?|gl{c@p4_`)W5=vbPrAv?GGXB55_){MW*jz4dYB$>+tDC!c^TPkuM9 zJpIFH%%ob*fo11KB|~CbzImRD12%qvBcqxEC*`3|&GZ46&72iz)8(QhW8lqtlv79# zDr~gHWZG~QLMbe1QaLFXLuEAOna%S}F*V~0I3=A|#|81Rb;pFqB$e5f2*_uz$h=W~ z^weV$z2jY>->&7V_5u_Rxv4!uWcn3iGxu##*|ruIZUhyj0?m5dUdZ-6X{X2h*^KYW z8smFn#`ol^@jYqQYmCowh<uoP)#4{L*DGCXEsSjGCAPDz@2$Pj{CbTI8f-vQE57xc zcSKJ`fws#^eSsVzO2+DuN(r&(T_N`_S4g?57V&vQOkcK&<SSni_+mmq1AHEoGZeEX z&iQC_a3418YMentj4az}3<|JmH2lDK)LiO*0AE0$zhcWyD!-@{MZvr5tf~tYsVFbW zjfhPn<~bViOSCKsLj?W1IY>*wPOG_`FY86XUi-5lO426Z)>xU3A~r}=F>g7<+C}ZU z-8$ATS6y*9Vgc+~S*pFU5;_COU{Oz(*&Hap2({Qi?<5!EDx{cLNsO`Y)}k^i!H0ud ziPT09p>8eSn1-<N1yX-A9@`c6u>vt@iA^hZD0XkR$);Ph8WDv?RF~1XM|yHIPiTRg zx=mOYFW91(@^8nxs!UYi(SFvgn!G>J*!9?o#m_ubHB>1m@z1k-hS7e}tHPHusSmRh zoyr$y&x*+;O_XsbG{iq@D3Z^-lsRh)0YW8(8TSEfY&#m7gaSI-p|xqSW+4}v%yttj zJ>ze)$o3>dFgwI>?BRK1N6AZe;DN3?!bsg0e)6K*w;Nz@olkSkfB%f)KyR7Pz8Y%F zY$DjA=40`tA(>{p+DszQxM}2<FU3UoDmv?WQM=k}!TfI6{n@IUn`+pC&{v-vu4g6i zbG7AHd#`diu?KiYJUpj)GB?DtBA;jT(b=VBHMz*m;mwr9n9*ANsb?)y#?2WY73^GO zEn)8_TzeL&7DFx%%Cp^Y{<Ee$F+edx<?3#XpcsT}p=nLpphWuf>=Y;xMxi@lc^(?% zS_|C|lYIWtnfGGAv(gbRXbRyWs!W+Hwut+0g$0erim?uWowSnte73kulefsU%$*VV zM5;$9<|;9$Pb;wzzxOxRd=nL2HTxmK#f-!hz}JnZ60f3_N;ibxNhmAFer%o-ieg}5 zVAO4!*6I3$qg|e0(Y~$TU3sEAA+YJcmi}!dqlKL~uo@`MMDCLufh;YQwPh`_p?~FS zYZ%7!b{iOs(pN^zC4j)iY6MC%$=CuHK5XTiM-iJ447#TxaA;*CNA(O<VZQdP?6cPX zS+>Z!4&ft_TV7TR%45XwL>GWG(@Vi*3@u5~Kbfg<{v^bk$5<(}&1vTD!v%O0Zmw1f z_T@=T)rlzYDc_uJ8{$6cfS_ux7fVyn+%IU@DPABa`QjqaOUL{USo@3uA&xwX3*AsS zt<9l|jG|mz4_&O_3&jGZrvg%*1Woalp>sH9LpGl;VNuQKQ3K0l*1{a&(++9Vq7T~5 z&5<#OFP%?-59Qy5TWwpn4dc8+$E<kEITGdGV8Z5bVhDw2OGyXSi}8oHv*oj$C#7CJ zij8CLN6k^Hq)ciV8>?9Me0~R}A-)l8X{g%O7%L^)@swmoQ1okMr$rmgEi9dZN~-8h z0q}fuW@<$drN5ezi~3#JXf~!2A`Ka%u0ttGhJb0UADFCrLcI1p8msl0_NiyB;aD8{ z<|K00-?`UczLl%DaxY)8cCAZy{SEJ3Z;0Hi-tbg}_Ivry-SXe%6Sw0d1Kqv;mN#?p zHoez0mzEnIlqAvWlYEpd0S_)P4=v1Md}+k~7)W+;bM@I~S~3&#`fHqB|MExPRcNlv z(j$=nj3--g$#TfE;*2X(jrGQw*V+Pw8^BwIf2BQOtvOe213T~4hotNlZPIMdO{u?` zctt#9Ua=qAj}}$TVPSJul<nKWF5<N|Md|MbwI#!@-A4K6urvPy_MJbgIoS~f`-|Ng z;}?mm<kxf^RBpy-PB{L-xujwT$YvavmE{ryEA#M|c~(jt%pTyOgsdV$Fe(AF4$U+P z_L6NA;Ia`U6m0a8CgKJZNOhg7F4PKzXL_z0k6ub(MVgMZ>ou=-5EnB8Hs_2=2zf&R z&yFL;w%t&GZH#7}Njp(Mlvw)n_4&KVno6+-tLGvcH`dws&j=+!A+no$<2r7Z#$R%4 zD;VOTRlrKi;_x4XWP4Nq0a62Nuf6&!z}#ruqb_=0KGh4bvC&MMqB(l1U7Jj-C2zQL zb4Nv9L_s3t#XIS*qAQ<|P_VDzA4Mm0>(?R^{@F{zXq<kZLL$NetxqAEX#2@@V3n!V zXQ2a)4n98(XaMqm9tmJPh#)~xBXtM~!s5f?uN?fe%r9OVF>#ty?B`*ggh`h&ZX*W0 zwC%-~`;w<)2o2}UxWT*`aN^0e)pGDW1G~LdvUWXjbi<Mklp3M(9Cb8k;^nujn?TIF z#UD}Vm%7e)!uHn~l0TlCSEw%>V9_c_HU8<+cbS#gB@kL8B4}Zm6!ALO!0@xwSzK%| z>W%TJ;doqk%Sc*wRuqYycXX5tNJla%4lnT7@0V@_=(($}G^;f-VNO7f_xWPK;h=vm zN(_vsJHEsqoG^zpbbRdft0mlC-bjLS&aWsr#sNjeUx*A(3zWa%#d5*n2SXns6Ij7> z7~<FpzI%`<sJwx=nDYK1YI}2)%MZ1p4MRCN1X``Sa0|wb)%2j9bcYh^!MW59CE9~_ zfE^}xZ8twG;e;7kw;|=YJ+!d_Qs=xq6u<nm=`%hI0uy*e=sr30qYbELRSWhh4II#i zIwXJx+o9ErNFC!{HdGGk!6$<*!-x;NS)`_^)iCaB&fz#b&);F-32XvcX#crk==7Uf z*31?09#hUPYCP?R%4?VB7r5~a8;*Uh3qr7=a<=2VtakSe)lPKz%1sO@*hrFf8l!AZ z(Zcz~zDXEa119G+MrOvK%^2qpcKm!!5jLewOu$2t!BzMZ)NvX64N`FxqjwnnO+t3g z=GCHFzyW&m1_y7kFKqJ9W>_a{O;FT*O<6cVj*ZGk4PHCn^?tbk3gTzH*6;pZ;^s(} zh?8Q0Ht0i&5QCp|f(Y|*OUK$FU|dSd4T*o*Uy;Yz0FS;SSuRHFCv`TJuN{i#Jq6o* zC$V@r$c#KAiqJ(fJI}|agOrkPx~F+g2daI6$?6x2d5sw@YM0;m@Xud=bF_hpSMG1& zzhCWd9xb1J_5AtKa-UPOJb%9b{P?#+c>92!pFMg0{1_jf^5b((kAmT)fO3S*fBns$ ze{Zw%>>}3c#!*KK<g}pf^Pm6JJ<K+L<qXxkkAM5Kew4(}Sv@KWhAo}E+jkxe6M(~= zt-YtPR@-;C<Z*kC9=GXnYy06Hdc0%4?$hI4dAxI<9`BjQtqr1I+jn=&n{6s^pIf{0 zl*@l5U+-?w;{)mIK0iJ*UmxP*y)F5=b4MD#cSqiQ^^6LbzP2CG<9+kU)lFa9G|hWv z*4tdy^mWHHzGLBV7Ypoco5y?fC|%!qMy>4#9JcQely>f!iO{Tf%)svMna1y%xp3oV z;$IO|cOII@2OB1Y8Sx+&Np7~}4UP1&mYt&w3@7|&Oog=z{1}=skV(~oQrFrnG({<y z?*Hq@7dA6rg*g?MaP7C=EeWN*6lWUp^WW%fVEcc%`*4?HL3O^S{-z6g{DvM+&Eucx zF*~2hGjBF}`KO2XcRM%T)OgQQ3`dOYh#`5&et+)GIoR4}+B5)Y^=s+&lpnv5M;ZWj zD$fiac(Gv$%&Hn+!1UaZY`!`a1HkdPtW5$1Nj<E>gO!xeifeQiR_H=*7}Ik)so^i( zPFRH`obx`1QRr@ri}#$V0*dtu3^e@hoA1BF%NDWC?&QSpL~WRXz?d7h3K`O2zFTIs zg&TOXL|IOjEG{s(@nsXltQR*RwsShcdIr**h^||3iuZXoE<U&^7U*tF3Ob}lsp;X7 zPTfv5&3#6)s?%SS9W#}<;?y>V+o8WOo9!*@#mrMNWA$co^F}k<df{hT$B^82oJSEF zv9HW`R7jq5Ghb!O_X@KrWaBYqmBx*z0BG~&s{MHg-8uVZh7(3s`!i*b=YA;ftQP^C z=SOu(D~GlGPyFtf9IEDCd{1>z<Fb7BGDz`bIm>{X3qk2(JeJGz6LjU{Xza2Yckie~ zG8`5dQ(<_gF{a;*U=HrHovpMysb}fVc3R{gM$>fXPC7yX*v{Q_hFo#Fb1!8Fo^)p? zy~IEF)06r8lWd;ue3jO4F-UhFq|0-t`Y;^<qm}{ysp%}O=Hp4abCOOo*x%{SC@m`} zJx=Sh%XBAC=lN;6GfB_05wvxhj`8s<olTeZIdoH`^>TJ6-Fb_D@1{HN(rg5`R@?kE zJugOcX!bnC=+o&=2`|QD?4g1=j0+gi4C`*EJHOyi&eNTFI_II(=>)D7+xOC)1^<GM zmh|iHJ=??kwD@HSH_-I{R=RhJLV@)DcDl#IxPK?z8x`|WdjD>^2MiS4FYez<_Ye^G zchWsX;`ILgbZ>uJz>lxer#vKS`~HJ;Us`;a?n{eVy3Z}1r2Ev)D19M?#_0<wl&3Ga z&?J39g-+A`H{YiB&(fDX3e!W8zLLss(^pdYUHXbEPt#X2=JWIwHB+XG;v87B`&Igi zvR0<|XX%g9!Y}EM9`Nta(;vB^I{lHVFVg>#K9=d5Z(qHBncjb&*1zK9zuHPOZs)7* zG~-fV-GSA_2EMwRW;~Lw?xh(vC0%^AlV$|OukNQ=PVIb^ju?nvJxFtD@nM=vi&>g; zizjK0?R+n?^C3n`SR1r;)#OwxkNo~CfUPro`#OBqa&R#N$GT1n-1X~jKE(@Kh+ zrxn#NQ#dXPd{d<rgU@s^OPA8pFX>WRnx{){sZN(vf016wr)9c0tLA0;)%)}kKaGlX zQdSe#GwI%Rc9x}ekv_>6nQ6a%oBky`KZp14(r5V;KGf56e^wW8YfbC(^#5Ynx=i=+ zPnEtoqvu)rqQbwwr2jjc&EUs8{VqE{8N;tS{eEd1U!*UWu!qvW!ESt?zM>rmn6j1r zP^63P^z~VlF7BoW#VHJ6aW8$7!SHv|AEo=n{q%=3C<xe(e;%Yiz~H6n#Y1Q=KZR;% zX+{%U6zK^LZt*rfr5P>W0ZqUeEv9L1nmkW`r9x#&f1rPw(PEYsm4nLSm-HP?Y%vGw zLlc9W{W*+ok(Ti9GW`GpdY@J@qvcjQE7Ik5I)@o8?*NctMw4`Tmw%<pd+8#xU|H^@ zOBv7demaA>Ede+2&w~`+r^|=XFwSjx#>1;G&(mc=mCk@xLSOIG2S9U9P&)Tu`+j<s zPp8GqwEtkcNN01{j_~bm`h)yhrWNKrNFUs}hm;DI`N4xKy~vAvK7*fUDP?4WUo}wH z48A_R1Jlm{DIYwX0*vzs4#RXYIt9SY=jnqHjEH{}KppAF+jPu7-lb>sV+?r6-+)F> z_vi;y;~!9se?T?-VS31+HhnnVN`Vi^aH^+wkXSF^$K5plfcbqMobIIT-0<M^s}vJI zWbo@jS^#ecKOW+lLBCGYvVcF66jN*2PEOANJ<s8N0o1=-*6^!Lr`1J9P5+YODLH~) z3#<lUI$fqkIl%_cfGh!dd2sd>{2jyJ2XIKhA2`J_C<q8STDlcEJAr!8<k`EF5^3Fo zpEV!{bY1MgxrZ$k4^mudsQea=RRH_j?KJ;oiEI7#UOL4WJ1MTvJ3z4I3H-f_=M((3 zXHLoQ@8fqY_!SnwA3$>OV1!>K5+9`052icmjMn~qC#~_|dr&<{r=uJw<b&#AI+tHr zI-LMB0duQPOh0pZGkXYFfMbWPGRGeeb0}W@nm&Xn)H6Vy8h+kQN7LmA{@MXdh4sUq z_krYPz<OqI(9j{50i`5DeX?b`IT&TQyH2*#T7FgOe<4*nzn>BTg!)WLA8g%8^AhON zgDt>}bNcZxMSE}hIZA)MDBr@5G5o;4c{-gtWZs&j^C>LF*4wlkBk_H(^)5Y^UsXD- z@z8&;HB0C6>zA}X;a_z+9rLe6I+tI|^n`zHZ^2GDJ<T0bZ*Qm1_|1duQw0Ax!gzZI zePmn(a87;#!;>%P72Nvn-su@RNpMlJal%(-4CjlEzIcfz^m(3@waX|rM|1;bF!>wY zR6HiwW)ovc(>NA%oIk;p_GUEC8Qr?*LbIr(Y~L^Wq^hPcppTTv&Sn3YOfycCMAN!7 zuEEqEhH$WH??xhm?ca>2IrD^NV`{)fGq<Bxxylx#9>)%RMG4h386|13kCTQ#YM2Bv zBqbUH-agRyH0~C7Q8HHmiA0v(Y_9k?SaE_1B?u-zc5>x20OI6OR3g9wdqwn;4+4Qd zMXzeCU|`FAv%H~LSTXdwvbrz}V<K%7Hp6SC7O9#$FDdE$0&|{>Ng7NcY0hWB)14G> ziM-_QaM<X?_5p77P%5iUI-eh5_t$-1Iy;GW+}xW^KLtHM0gt$+0F{CmWgWaK(tDQ; z)e{f?AqcaQM8F*}pBEz!J#aziO-jIR8W_Nm(47&ZG}Lfiq&&cMm!4wc*n~usFuV-4 zF?b6N=!qo43A=Ay$(LO6UzpO!4F1W~24j#er;8#vxx|#5lDrz{LwR-!0$GOp`*bR6 ze(5rwpUs^!+;(Vn)A{qC5TUzWDmN10%if~9)k`*$tq&+0?*Xv3KHS3}x0A5kwv>Cy zpSM12V<PpQ7NGd<G0`m`!)T7dHS@{4gD`xJy<rw!sMqJ&8-C~QI|Ix8PuUkiGF1yF z+cFi%F?I)?S+)SCcCLR90VXg+H&<$V5e&{9OJ#pb7Huo@+P(STaQx@jBJU>OPgW+u zfk>?*`mr1k=GBF{)1itA;>sqSU4dMuXc~a6K8Hr*=tb!d(c=T?M~>gnvTurMR;!88 zP}W|KY65X8RKFi@^}0BtGqaOue_2dP!(Hc#5T6WyKFaP-l#L8-Kxl645X%FBLM_Q0 z*@{##;i)Sf$21qU++p)xIhI4Cc~txnsChlyTupa1_6qu%m?Qp7pDyb~bx!kbpQSYc zP|%6*aNlO|H3J5QM3|GxG8>K)Fp}Qed`EAJ^78wq&g$Z(OXVx-Yg&8@@WIjT!D*VH z=A-9=uoL0N-R9UE+6&fj5u0H0jtTzgiAx64j^aY#<1D8{O9$E|mH<uNITc5M#6iz$ zZDPl9Y*m8MS*}fuD>~J%t=L>yd1_}GuL*@Bw9;w<BZqy;(WvMUmW9;^Jm3djq<?(# zTpigliaE|j#d`HgOs5%_zv9T_LSvQEoM{ukUwPl~NP{*rP`e+6Y)P;pv{L>n{f>4! z?ezYl`VJYIr$8^dJx&GxLFIur=uh_5tdKKpu-$1For<>aw*`@Ctqzs8BC#Y6ma|y} zOfCF@vjP^ZF?RH0`|uq8YYuYrkzqh>#$kbDOvA|BE%LOs<!^9MsqnM<%b(%hUFfnG zPakcJIS!>f5!YCsW=&#SG0>_X!nz(eP8#)A>AK-%Pcs?58J9byu9y0Z@+}{n<@w^f zDjWN$iDTdXy%H2t=u<MrqTn~Aoy{owH*!WFfP$1Zfj7c|1vQfb2Asf3V&uV#GY$%Z zaen7H)kof>HFa?a)F264JkeTMsol^k4PQUYr`cu1{wq!B3vI9sWY0Lp--f~|Tfvx8 zpdZl!p;#-6gz?jANgfVcsm%U>tcuAfA%*k!1CIGkan5GnrUf#am!E*@XuojdhAOPS z_w{QiyJI%LWl`88<4yG~@RvH9s<i<@7Lg4=>L-_PGRmjg?VLgJPVaE**!LMV9^HQ0 zP8>maFk$v_!j6Q{12ALCF>FV8lf<$Nk*Dx@f>r<(i|2s3hea-+(%4{J?4-g^@pEc9 zpC&)fr@|*0r1OeCw>)$(2Kz%yl|JOCp&T<NU(r-PpI7tsTAE}4j9_{Ly=eHQ3lm9$ z0j7R0%Ex6|l<!goxcHwVN~CPY9`NTgq;WR=0LM0z7Hf8?USOy*ER-f_$zs16GZrth zbg{YVJc3Ng!{WFbcso<G`0o;XxwEU@a%b@N@L0bVIN8?$_syTLm<Jd7<K}VqljniQ zeOXK<e7~&7T>7W{<bM|nXEIIEU2VixT;zULB2KVO293bp0YXU{Y?rsGel;C)TON2W z=+)D+Wl0b!v-ibmhK}<<<>q^*NDj`k#ptX%;L1mX?$P+m-asHA#P8OvuGbLU0QB?W z_HpucvUB%-m~;zZT1)CyC~Gzdhv;M3jE(eGQwqvN?7~p_M|smnqvgEzW{OR9v7*}| zx^*v~lP=cn>7+?NK^3+_<DMMXMR{eOp?gUWDJ5<yth(v;7|c}>VaJux8G^p^Z@A5_ zH?BCpXfQgKokyVfQ#F5=k@Y?eSP+Kr#3(jU?VHarf{bvJ6z`4EhK^>ciO6I!D4En3 zulxr2G;h>ak!;-QOF}hLh)CK6bHFr~>v=WjPQHT?(4p=2FfC`8gxMq=GhNl%gi*at zRT<v!>Z5G=G^s8qGYdBy+4?tJCBFqA1tys`wc&m3(<}1+dK`Z}3|<4}mvdJqXXlnN zO8*7rk{Z*Ugf@OLRyn>64c`rNxZ}2oCvZ>OfFEqr0Ku3p{Usm0t7;$3IHYEI*+eae z6?JU&sj>AJe=)z*dDr(wqrA3Ou)t=#UQUe|dvP|eE=ZdAVU&~XO_7(U2M5fB6tx_y z(kLAqrX5+-K5;F5^V)zk1iPh(LBWr3)&Lz%y7>n$Y5a@R(u8MktV;kEy)4Mn7$=0E zVV6D4MrZlKaxy7CAe*2<e%#W0<{^ALR&hrcxiPmlGa15>l-^Xd2Vd~GWQ#P~Gbd{# z6ub1$s1o=u`aF#{J~=`Avt@l2mJ3>maYEjC%Z>QOf{3H;QgdNW09GgAFkHxbec(6J zT>4FZn>G1YVtY|xTrUZC+ZwiJ!9JE<yPJ$Sqb1{6tRw4a?4LKWj>t35^l-Du{%lim zI!jvZ$~*X346BKf&GRXzg*KPRj{CMCXXvDZqMrfmD)kA8VbWQW#!l{5w{NRvv-+|e znPk=OHQXABSi9Hm>?Y^i#`$jLpwD3%0LNsUFY?jC5ISVg)!|8SuaT1zVhPO9I}D_1 zEe_5yQgK*j&5=v9LL2;Y1BL$7Hk<&rJTA^GndSi>wUP8)U6ghJ%^w$gH<nM4_)tUc zljm^kPpS_-wQuDm0%+7W0{^RLuZGEMa_nXCq`2%&mIPC}38BpA60;;MF^$VP%0)}# z+2BOHF+P=&`MjERH)OOML4bO?dbXn^eebxult}WmM*|?*e-!65;|)YOq`<e)S3_#F z9cA*_yLD6R=1atF94+A`7aE{Aa{!pHKqJ#l)oGJ^QhV0x85c%vkTZZ3%nasY@9^XU zDaeF>*ah->f--B=q6B36-M^J!3}=N>Z5ChQmI3yGG%qk^xCxZSY&p$X^a6ANmU~|0 z?@=Kwj7_~l0%o8_pGD({zme@3qx+0hsffoB@`FyZW9tu_ol*_cDzw-~h5_pV)>r3w zG47-Z{i4Qj5Ab-_>ZB%rUG&u%7nsCNb(M`!B)d=VX*O&08<*)BFa)wZ689Cq{yNP) zSsvA>&i~I6NQw7>96*T|ts52gk#<QZ!KXL#JpU=1zC&4J@QFNvn|(MZQ}t!PeBTr~ zHYJf!8Kx(b<SD1g7b!E=aL;k0PZKxX)a00PUZ^mLG!da@*bC80B>rbW<?_;~)yQ28 z_)E)h;sb_Ou`dc}>~x+xzgT=o;p$PG+gJFo%Z(NFi+y+xL+KZ}ysHaDZ4NY1&0iy> z9{k<9iKdTxx4#$^QWoxLi~L}gjdJH=`uD@+XmK<@Dv!VXVt~iB%09nX&h{3I`L|W| zuEu1r0;i^YHZ!F}9{VoOXB31(OJMu>_GgNRUUQKj=TodjOoDngtTn}Xu#5LaK0Qx4 zoO((S))EQZ2T<gn#hxjjt6ML}2Z<N!ql~JhiJ$9HH6wwro4*<Z;1Ue$aO>EYY~jm3 z0;Ss-XNznT&~p>dKCVLbd;DF$;j@QhN1R6Ht|u+mrBxk~b%85DuUtGJ0=l<uH_h=q zv>^*y;O}Vy8Me288OCrS$ZjFySxpiFIw}GyG67QBKpGbCq+K=h;7E7jqM#FpP(d5P z+?g5i0O}f26=LNC@)6K`(i4MA?cE1}cN~(Bj0U0laQqh8wD>hAx?(q4pERBPj>l=S zje_31<OTKghwpXR9dD_lP_*lB7#jDYp5q0;+ob|YqpCDT#WmH^jpYpBff`y;Y|;3U ziYNl&VA=vu4YAJ;F1p=oL^fR@0^4b>g<jsoU2N8pB43x){G0|l)|#vjqQ%N;3M_&l ztJ1^-ud?G)`XzFM)x{+Ytc`fZ)y>;5z#+ZeT~)*eb8Ttg`N_UCGjdkk>TY4DOO`Cr z6zpbd=8HEi*fqCGFQk)*8dbPCU?z*w3g(np_Xa@Lq}z-Di|3((p$Qrn6cU=;Xi*8r zTrG!8!TUd5YK4g+<1$Q*)2A}aDc|9KD&7^uzMfZn!OgHNAE2yy%oii^%r>gv{!P-u z5%20EwA|EsIm^LnC7B6X{1LBXiFpFv7%t{y%Zo~~LbCWQJqCMG^}VLd=svn}S|dCA z1|$FE#;%@JYZlwh_)u{h;|VZ^4LZD^A(L}5tw!&Ra#R9;aI9OL2VE|A&6|q?WAwtm z<Lbh`L~&y+F6cH&?h<K?$=}KWb{FIC8PRVMvqb0isBiAB^zEBR$pc&Ar22p_r(q4Y z3gfmOB^yr<4z{1ts|_rn`%-=TT%m|WLS_-+)l>b$C2pU!{6?!~LIpQe*fDK37apDE z=b2`3_>DidT92si{zK%Uj@cQuFi2^mB(p_r<@qZaUWFs-xs{(39{_=UaO4IOwi;aG z1w4;w@Qz`39NTPOeYnJ^XzpX5e%f|5qZ9D89JI{hFIEY$wFy{MP55t6=JiC^>*9da z8hwFBT;D`$dX`TzARu)^N^eZRZW?k2gw_Q>yCJv8A)_Gli3v};y_+m&wsE8ycEPC4 z7;t1ElU&gn7?_(W>YaF}+E+ld%4!ia8z^d;t*^sJqC2n_!MJ$@8iSXT771WAdKa3x zS;O-;ILhZVN*003SgENihBq*PmXYaTRq8ZFS!D5n$nl?c?%lg@#r>*`wN0^dP8WF6 zbC{x}#?vWT>7&eTIYqg_0y!UJvSB2b=OmEv3>XS=(Ylydq=Ugkm$Gp<+Ggun%sIZu z#3Pf8Qz!!@;If_<tD@9oDdI500h#Gyfnc_`Zgsgwl+5E19&Up}I}&W^I1-rr)~#qA zqG})In6>gO8(&N=A76Z-*lx#lo6(}N6vkX3aW`U^y-si_7LvcghM=m=q0#3r>_=wy zF@Efj!yJ;S4^gC{XOpBXLlhmR*32{C%ygJjI7a|}A?b5cVw4V@7p!}uz%cg)J67zA z+vEjjIqP<^lM}dJ&lklAjebaGlr6^vY^1DwpVbMwmfpD0F?`3QI2~oIu!El{9-hD? z;WV-((I5$)&ravna+aKD^LGjKyG+=szRcdcqSbOSTap_56hjInwd9nmm*-IL(iKE) ze}XX#s!mTCL|>3av}Y@Cc{!If%ZQTQ4b_k_wsxRG<Tf*6vt>^}PV6z+Wfx_PD6`$N zqsnUz!19WO85G8E=o1voNSe<){7@VZ)kvAKxvAy&xb_oI8-fs}KrNnF-x4OnmUwi4 zF5KJ1t++whV5eA;20-zBsf139S(z-KeLcMIvv-)-5%F;+sj~^%n*q?Piv%OH*x~5@ zs1Ih}LQrZ_p%)XAow3UhFCWUpy5=z3;}1-)wPmvM0<i267w!t6v54(3P5c&Ry}UBL z5Y=@2=qCN3*Fk3S79SjPrp9d0M481C#i~#E2!a3ceMy|JG2$v&BH42yOP;;>Yd_&Q z&UG>^V0B<Z66=|i^l<iZ&!<(Aom67mWD{?5US%_o7QY_kAA;jp*6?G3-|SgyLQ8qK z3eP|0HBr-$p$T?|=S$^rx_un#&!#)WWg}`KaIS#&`y#&}9g~2YuMaJA{woyz0Sf!f z%THA0BUW`cA#MjrGNzkUy@WiB@pAjCEkZB&lm|9zI<AusX>yq+7j!V6d7v{RQs9H0 z6$I&$g#g-@_+vNtnsf{QJm&KVe-3fPyKa}mlfC_LJT7j-oMHC<^Vqv62?`{{c?$fk z8x2F<!UBUvp_#~ZNxJiTG_TM`fVGYuJNtn~*GJ9D-y|aqEVGQL&lM@`IF-J1rT?p~ z^qXqNg)g`;#ZCLE7z4~z+0nFs$<S*qeWpr(o70YK6zBJjv0ky)VVyH_nZ-Sl8P0lS zwocp5gK9no8fMvgzri}0l@N47|2cW{;+a89HGp|_9%5!CnEBcpW|RHb2rHPHCI)x? zjSl6ayjtTFoK>hV00d$5VNT7^X2+>PG4=k3s&=0UyWF<}c$AMZ^n!-^IClPZX>kKv z>Em?d=h-^zN?nhEvnknxv}(CHwXE*}1ylQ<xxQ^Hi(_7IWwC|Ti+Z7#jl{B~LFioI zJ`{t2vz9VvwD~&9j}EP^iw{7kMEgP)9+>DTm+1BbwaX2&a$$`dIx}=e!mG`uwK}>m zq9dIp^i#SyTiMN7(2a+)fScB#>4IFDObAHs&eF2Hg^t<UXOY^Dw&mBPYjUkTxeUGJ zMA7KtZA4;-a8uK&nvosh^7M?jcge89sct<72G_nbNv}kC>UbBt^D=*I{B&_~JTqrl zhhmg1*rqXC7?Yt18DU<?8?@}g0Et*?g1NrfhXO{+cXJyGh1$={v5Q0Egb@qVsJQF% zFygUsEZcUKv;++wOakdT$HeObG?FI+M1Uq}=Rez&^JTURbYL@pTX?}+G~KjC(EX65 z5!iePZ9UA7%tu<bXs$RzO!V;{ZjPtupMlo};yZ~84M`O@g|j4i5Q=Y5XIM;RS<pO+ z!0HhthF#<KWu}qpG%)(MZ>!eP8Y#<ndROlP<HqigxK7Br-`LKs*dI7a5efaFSS;w7 z$*senr3mn^z{~o-88KTB(IBi3zdryk_vZ8L@?%1OaG{w*T?;+yEATTlOVM_qn&N-W zrWo^_)Jv=pxGB0heac$@u^ZAXI^~#OaQvWY7@7l(?FlLpX9f|<E=vpuNS1=;UXXA` zB|I;>zI@r<nlWif=gF&Q|J5N8xL3wyAxT)M=8o^5=Glywlq5A79~e$x)^)(L(mj<q z(Ex@aKu;=%kHsvqHTbflB?a;!Dhdt+CR#7KZ4`{Llss!UE8^$?A7CE6pn1m}m_%Qy zIioW*39o!TsnMK<Q+Sj-wBw<;-;HEEx9mLlu1&wWXHQ@2<1Nh&k&}(W9UeAZa1?9< zb*<GlTZOcrKFt@r2v$Efn_}qn^ecGx2Kx)F3=k<1ViYCHHLc=<Hh4k%JM-vRgI>lw zB?neuQd)MtAnzTd&uk3r*m{%2dPYjwGvto?Z2}n6TFYUBHm>W@s8*idms}$&j|Mz= zdZPTm8S}J=-X$Ie1w{`;@hCWO9<fg@UyRkgjWihhbY{Jp<@3y*e*o#sNy3fa^Cd$d zoIWk$i)Seb&OGm1B2{&camfMRWA>v$-{W^K+6B**qOFhFeo2d`H6!6qMVe=6@!|Gy zTbynI$_gYcjS&SO+%(6$b|<A`BjVWj5*mmdiqxi2xlPa>Kr-ak-VM^n;?|>DPT~9m z<rNT~#*eobvUo4;%rF{yfWK;b>)`H7(tx%ct`WBHXPoeX75b`^MdkeK^sZPN8wTe0 ztj`b7$p6Uo`N5mr?_VQq@AIrtV4LKv(;)d%F+s*AdHW06D0_>?u&5i-w;CybMi80; zKR8Y9T7EKluEJ4a&W1l_+sUkt-mMz~w}!qK<7J(bk&_XKpI0?T$i$>$re%O@o^$Xv z8%79eRDsdo>M8+}2epAXUF1`YyoHAV_g9r{Muhe!)BJ;NFm@a<)Z)JTwZ@EK-ps_~ z_W|La0#r-rHa3Eda@hm^rcO7x9~9+EE}O(qc%kB5<wjv@8KZrAVx4L2nbh-T45P!( z&a6ueryE#cItMbMH`evk%GLJuttA*<-OjAj3vKV+!nBOCo@EUObn?*VQvalp<0uHV z!x?Dn316`5wk0j{Dus^ARh3_Cj<Ojis#0-t$n;*fXl^pnw6&_bN*k2IooFTTUc=JG zQ1WJ=4ezQMTD(MV$@tHAMZI8QuD&KS$3hqLB=awp=4*eAy{q=D<AJQd+-Zh3iH;N( zwa@7_h%nip`bH#%@ioIFc?7x&Gv|buB3=fzv0BI3<E3SC2v_Y2$)ON9G?rAnrHLQv zT~L)-!~yq0dq#S?`jV#-=|paD&N1x3p8_-Co+SZw6Sz~*j<KEhVpmJ^(~p29d2j}) z3Hczru^A__kbVtg%5Br$*oFmcn=q-QK>I~Zh@&0tHGmF_W1PP>TVL(d?t#&nJO$Ab zUepw{Q~;(I)k0mkX=S1idiXXhswAUQtpGz+A18<Kd<=IzlW*zz6b9Qx<8N{Uw5GBw z3&#&8zbQWUTxi=ZpW(>MaWU}-4UzabT_H~|%D1IW)cljpCn`X{S6wLwa%S=cd0**^ z3Ky}?QXSQ&r8vd7)?=U{j>l{byz(lGHz>MBA=%0=yg82P;z>CekYn^eweS!Wh|=*8 zqK$F}#=;TIPnW?!<*H;y(1q2C6Has?b3KrDm(8n8WLndxRW5iMyk;O=wrL4M;mWCE zCS9LVmNk^MQfUGW#qVgj)|)joD@lyODR5L$KMfBJ)2>}Z7{NKlaYlOPNiyVwx<F$h ziJ;@yuoi|2A#3?418%^2qwc&WHxg$=&^WdlUv`o8n03<RAB$pvjz*nxIA-u?=OcVM zz@tXi%5YY=#i3bstl7O_T(AhUQd<2~fVGD03Ee~HORv3VA3Ej_K+0NQ+~5bydRB`Q zmy?Y=cBU&412Yt0k<_JW%v5)|S(%fUHy&o^iRCDxry-asgdsKH#TuikaT%TI9(RfD z+bbW5FL+C~#bZa7{McsH4$V^_))uvxP5TTMu283Qk1HY%M<~^`=nytCU_YRcBw1$5 zW>Q#-{1D-h2;y`rTA<il5v9tbBdsz(D%&9OA<<a9$({GH%Lq4uwS(K6RmQlm0+Aih z=QM7kwykechr=xz_jdt1wnMiK*cg1#pxw?tKgtax-0bn@?HCbL$)YizD(b*JH$pNi zst^%C5T!D*y~rkw(w6O2IIP!u;!a!+6mP+A)N<2`9r&kcR*UO{S&TGxNK2@(@(Fot zV_=Q{mo|rKRMJw@NN{pg)vEtgu<>E?b(Wxy<D-o~ZG3}x`Sl?Crft(WvP7dEVK6q1 zm`?e?Ym(zE^sPOyI69zxl}xKqX61rwptVHH=w7kEh)#Dh++jEy*<+O5*=;J+>vejK z9fEb&*d@5ttL5TboH^XII_Rn`)_>;p?MIlKRosjvBqCl~pdiu^KD(6mieB{3vij9U z`2&SiTU=t{9$p#f;~_j9$DD}0uSv(=8r}U*4+;&^akv;@<Pk+1p*_yQpu4WEo{m7` z-*fiFDy6cER=9lY7uB5gIRxiwj8Q4F8U?Op@?!rX8lBY?N&IAaszN*z^W;Adk~s#@ z@;xwMf`nl(wGBJ9jo{8?Cx{tv;omcP_<CTLfIl@=XR2m0-~z1&u(AA1Ccp~vEn>N7 zn!Krv+fI(2OA{+70gcNM0O2TX-!VHkbA>ale{}wjww^Ozad>aaE8Gvz9jmhwEg9@9 z4OU7gR94tPclI%A_3rZi-oQ4!GU4#MD%O~0?raZU-e4@T+fWmWUf2y%8K_%X1&$;h zd)CJmEEkolVcem5Fa~n9$Xjl{m{J1Q%%o<D;l`XATIaS)vqEL<L|<u<2g)1Pl6*@N z03bHmn~}K_4T^EycELmcb^;0zapnF>zGr}z_!-E*d>3ysl$zmzg(L#4b;vQrl=1Q- zksHj|92MqBFq?|uF}{KUG%&GjV1omcb{f~lp#9HvZ4`WHk-uN(w#WlqOXePm+3g@& zg7>J9nL!92=@eK|<W$um$sZa@ER7+uqh!;uN7)x<JKa>FDuN1BgQCB*MC2T?M~N3n zvr8{cKaqWH(lWt2Px5&ek57J$feW<IbxVl^`Tk3jX0kw4Y$%T4qR7RaokpKop(hl; zl&f;;gkC&mX3qe=*9@CR(D6TOx<sE{<|*_8#y5+Kb_TiG;)}zr;|TRSz#yk4W+l61 zG9!yor96I-8Fe~NM;KxbJ#a?wG#zCUxSYcFp^k1Iv`Cf6K?g%4o>IuqP2iLPkE3ck zHg#Ty5~9pl4{~5l)U-eksZn!&{WWd`M9ft!Zmgvy7x}9yXtD}%)VCIbK}(P|fd3iQ zcLt*Cs_(*8!aM35dCGvwL`J?MV3@fIw9_6tPN6<m4~5loTr1S<=+HrucF0-Ze8H}+ z6l2GaF=Y8q?ZVpUpe;XhoB%^5+9J8I!J_iBU1>>SuSf(&*gV1r4^YQVp3s6669w8f zpNgwCPIJp>+bb(HH=Y$drdFE^*)0cdmqR@!ORXYfGpVQMhqpPx8|>2%IR77c-`d^A zaU}X#{1qd{Cjcx6kZdQLfTFaLOgq}OC9NdKyO(Bs2EdS<2*e;WfGDoT{q48w)m{CV z0VpfEdvbje5i`^8uCA_k&Ae*uOCt^&?T{fYwE~BOg`lX`sR;l@A;<+YmJlKOlnowK zjwC-f(%t?~Uk^NI;Cz@(!#rpPss8}^T0|kH+%qL*5L%&~E~<PT8lh2GG`Rfu*Msc- z7v{F0XhPp$6?0eg%#7&aAZ4;;t`Sybf$oSl;gR=v4E=#>O4-<^?;T5Rarh0vmI>;) z>!N77yomHop~%Bw0_L?^NE63`%<U-KtU%~H+#TaThteR^CM^~i6NTEFSaXxSB-}Fn zJ#L3xtvh~+k@AF)GKeze`K&IAW$!w9W$-*c$z9R7%i?1OrZ14#Hb7(hmdk_7{KM`I z$6Tn)#mHK!wcMgqC0g?FV)58Inr}ZpzvlE%hvA4v0dL_3q&FfVoCd8_F^tQQ^#%*= zKxIC1Js#|NwgV(`+h#Z*WcOof=DC%Vjo=*j%YhdUVbDckJG7?qJ)hoS+pHSwAB6AJ zFn1!BUHOkBlU)OMNsC-ITpElF^F?z-Tm;!A+=B`9dT4h^>FAvN#BYs_aXN7;*_!Do ze*zBPMPb;H@+S4q&}o8__%k)u$gVR)r5LZ*8?HY>M{~Cgf^j94-%f2u9z0cDo|OjS z{h3@x&#UU~&=20F?AshdRdF(V?x6b-37Je$uC|}KST?u3j@gt($NaRhJDd$xYvlcN z3c%_|%_5TLz=|uOj3JWXFHFdKy7F^B3e_4j{oWY;2&i_v{=9A<@?p`Tb*klS*)iuY z6o2b8!h;@<78ht%G<2`vgp*cYy~JK8)Tf`hv;_xVR+&TrOyI)iBavbAkH&@_6d+wZ ztpuRLNFPrG^5F+>MlcNV$Mq?3*6#FRq`w|!V!wilAhuxX!ewpK`3SVe)S*m5k%u=M zr-$w$+E6R;l4dj-3k9;xl9VYnJ{NpsMWZc~2;>|__Teb1A%3vuaImuvm;+2hg(G8{ z7B8g8kCc2tOt(ZyKM(a2EM9Q^ZWA#iX^gX08e>k*oZu2^wHEx&392N*>1jYN%*#0_ zGtqpnO)g<6LT*lM4gF4(cZlCbtD{KQ<?1HYcEi$@%0Z6XF2va2Sl>^rcbl`c(zn~0 zyWQ-iEFaw12PrqvcP+PZpmSEbV4(z3dTtvA+3h^!-A)KGYz*j*qmfUWY5^Ms!BRkN zU0NJY(sdMu+xKCR1Jv>_qlhtHM3LATs%o}}L+Oy*@tN{RoH$qZq)Moxq~8i&d+TZi z>i!w$nE;xzExO8MSuwp>X)EB)Wf6y|D#Ext+&0+fxY1YihvIvX>$xbcoreTQ6FaoA zn=lSfcd!;07D|2@=yGwN_&h0FeaN$dR-Fb^&F($L*dh>uhF!%FySU6fkc>2MAi&`I zJYQn84a$Ivah+TsX$a4$5`OAw`a8ua2WLtS44}0&_vo|$hY1&W6E?XK9V`~FDdZW= z%1+!IJN(L4?CH6gkDv9S7zsyu0t_7VrAK3M#wirosI@(t<;E?)AC<T*Dwo?C8&8q~ zV)2Tx$Rw<24iwIj7U$Vf7=zUGiva-^bmAd+=o}%4GBcq+2<6OiU4uVcExCzkg~!sb zoCu0M^QKyH^c)ECMK&|p?}ypH@OaSCmmy-U&=2(m@DD+q7Et$2)=w;q3Lz%ot6o8_ zNk7CFyyXqJ;?@BpbT)1#5wvaI#7&!*L1_M8-cK?LO?7qc`KEX<u6(Ik5A1!0bcXu* zwmYxEr`R<3J(x&&Md(46>z-YTbUB{66bpu(s6Y=}<{J9`{~e}%HyE7{C2rd3ayOWE zIF;BZJOqN^ihc>foI>JND}u@;36&%72@b=A(V%KNz2Ip|&0ZAsS;0w^NKm;nSg@EI zbd<y0O3WJAlSsla4ns+aDbbf9d$xAXW*q7pT!QYN7w@SX6hR}`XI{~On-OG?ZgjdM z7LL2NFiH(Y4#!JgXp?bWEHF2HHpOgLDx!Xh!f@#y(j>FN*Kfcp{k5;n#cF}A=(MWm zMLoH{dT(&vqJ(9eAG8I0q`#&Jcwd|CS2jNRTJlJH&HuvfXFacn-nAtV+*}lqz!ONw zi)l$I0fsG>6xDL(j5LTbP!WuE82R}LI68Gjyf`Rg;7VZVE8N5lmL<(LS<+5!8pqtV zS_`Lks_>Q|4Gx(%EFE-QFNb!Y<s4Ir$4%^-t?rjkY#%%9&`6!(HTe@8EEPnWb(g#6 z;);iW?e1GV(snpSU~YmxXf#UFLjyTy=TIB=Ry*@_Lv}>@hSV*z&B`n5k7Fnih(SOC z6bx*H1dt^3#8tqUAgr3ZES+a6b_TY`HZ(b~^5$Z}jt^bxL#>8EtoT~eD(IRc^@(W! zzp#EXH;ZIAM@wn<>6lmLB=B_g?$cCxSU2nE*)}kL7=dn|jB$N9^Hlt@_RM1hVP1L{ zGs$m2&2z9v3OdA9U7lI5sjlRbQk2t|M!f{368TR_3Q%B<#we)EoBRypx?q6x-hl1N zSSA4K6=j1bTY~RBQ#k3Kz*N^s$q2BFw#~K6leA68g1j+c+lMUDf}#Kwm;R2ql(oDb zE<Z`Q_Uh9}4!EHK`DZFUG1t>0ce@9bP?0F-x>aue4D*6EV>qVao#c{CFM~Yj8755; zv9gLo?ISX1)HIUDV~~aPhgaW0Beo+9*wn5@`wj=0yYllZgQ?3I#_+a-+^*T@aZxVE zRlYtS!w*>aNE;S)8FmwzLf8~VTZG`hdJLe*@OvZ!2ftqsF-XeF!N+xMZD^$b=F_b8 z(0hYE+j<mmQ*mW=Q9*|A8(dO1yP6yv{;JE#!}v0PN^PE0_#swy6XOi&o?!7N7;{eq z{-zy{fzTWFbTEI_7px-W(`C%OTXJ^0ER+<=OU<6TBZH#e^~mYADW4R3Fk+7FVfKq* zKPFyk?O{efSEiL~KaSZSC^0p<{g8*H#tpL5t|`O*pwsxOuI8H=SQ_7_AWVioV>brV zl+FK)F^J0dE})sAU#rDC4og)w%?3|jU4Vp4V9H|4YKc9#-X-68qqC9YOh8PxIa^#w zup-+bIX)TK9oZd_EGJQZEq+I%u^Z!O+m6lPvCTw1%F{tF`^vbSfB4N>b-4<yxR<<V zT|VdQ4pQ5O@o5qCZjJ4Lv3Yhi^geQdzn#w3^Lh~#u6Dg_DEw-h-{s73-#7|uzsiJq zD*l1bG0E6MFH2e#s{v9&3cgZSXHeOGn&3`<&yY@S1}V|VK2l@rQaD>Xl!W<-lnQkN zW*7NHcm{g5QTTq)VNNGWw#7y3#<0weBL54)nMGPSwHw1Uxk)j~o!NH#%^-58qB(qW zFDkt=pUS1`lK_5tgdYk0dR(0cKo#6_2G-Tt*@Byt?>mI_rU2V*syn#G1Bpo+dtr)h zJq|bUMxfknKm*cpx0)p439!X%%~NqUN~G1>B_vws%wcC_zU|xMWm;nlCAHcx)EnHz zWY=a1#?|R*YVFnDx9EN~0z#=2RA^h;V-OXbXyoFm=s`pk$Wb)*8@0xvuyAUyiM1P2 ztrT|G5UxtLI1*ahY@FnCa+T0Fg||M#@0@ttT0wH4?kz^X=hbD0>o3JtHvh7K9!u`e zOGE$XSNqxnCXghXW_P_#$R9YkKX$%Oa97SHBNU2l%~LWgvbP6Ns-IesKb7<1@3120 z<-GXEtqAnic0<twZ|-0VZ32!jJtsDJyM48>?#+Tbs^q1n_T0K@!*CHZ-eB>|=1<tf zc9i~X9)$EJB+OkfB8Y?Uc3|YTdFa@VG`i$6rf@G>DDaTbKq2cbt7XyaOn9+bmVbjA za?Tn>_J!Rv#pz~20lCkLWl`rk@|$&SI$d1pz`4AxlB|wbDVTA-FpT&7iY-P``$A)S zHcwxOE5no<=GbCker8UmL>r-{&EEkQuXn|Y3J<})f!v?>+muE>*!8d*A;Zxz$*@m< zFZ#E6B#%&5{WCb9Nx3_Mt0{-|ojW^vR_JJUTB(|%;?aZ)E8zO0BpSAIRadhD$kUN* zQoiJC^oLj9v1S%5t*lmdhzea)?^?#Ld=Ch3JsV|DaZ|Zf><_p;&PUo}+8hTg`n%aR z<A`{vs?)CMMBd`wASzMPjG3|w=$fCzbQuEx-5^Raj{yS&CGC?F<GeA-mvK4DzNKq6 zISwKb6*lPHc28B1I;p(BvElJLueHr4QbqV`WH8yE@^=LVR58eqScM>6#ep9c)$&0u z$_E*%4MFS&p&l9z-L;m8_qelWRlHyhJcNV>=@x&|kr?9A!LT4Yuhb_Ar1B8LSmcP5 zExSK0&dg?rqz~(G=&`G6V}No_nXPP?Or#fJ57+0e5|2tprRhDG);1>5!N*L<+%FK+ zxL>><1T(_!%L}ufEG0!^WV3v`tS*=0L!K3N4N>ZsnHyGVGh-WIl#`!lD{lR>e(!<# z@US<)uvvX?4(8J2HGl}di*i=<?+;jT_@?4{guB7`-mSrPi@yu@=b|fa@tdzU>*T3y zF|U0A#oGeGrOnqVA4*`h%4W8z_f#+@L7XpKF+cy4hZHrk&_nGL+T-zb1_AV{b;lT0 z$VS&n(oM<S;jFcJv4A|;-+W`kf1x>4CGBNjj(!j1TC-+b$vM*d7#XZS%gg^JOVz!O z7}X#v-?t6!1LlAMJ)#tTwxda=fR=!<FEk#cB{owg*xHeb(2%vfnNLy+l>OaqZ*QnA zUP=1$o)_xorphF!mTV2X-rd3J`xJNg7Wj=XaNKePD461dF+o7vE#8JNZg7jc5xT3q zYY=>&w;Zu3tl&+2h~zp@SKY5Zl1qIii8csM9|}m^)eLCCHGb$_a{;~3cALRvcDAhQ zA_zxs*9;-k+;^aEOI~^V$vbb~={7lZl8ATQEi*(uvqQ~wWEwQI%e<ITPENt$9`|Oy zF0WXW3AIX~ftrn(tvP7F&7s;s3TII5mP7|4hKEc8SkAVcV4kIxH|V){?EpN|`w0~@ zEsf|!a^e&ivTfq>HB9mn&;P;0{okf0Pc5V;zb0c;nLia}NsSD>dj+UUyaM!ItpL4v zyjZ--F9QP{4rr>dMSe<N8sP17TGRz-k2@$2GJbjtm0Cox7%ol8VyQ-|pV2OtiY<-# zlU{{m^e&my?Gg^*rcv6_Y|c{-dD1l{uW>6AMV0d=VZ{b|Vu~p73#WsaQ?to*gn)Th z>?ou%V6g$iN-WvEULsR=RWT|XH;Tb}+*{`kLw53>!5n*es?sS#Ij)%wV;RIJw;2ap zJVY@hQL|kS>I`Ug{sUWu1IDROF848oct%gTR&}9)o}xRrGe=KqJ69Be{<)u<f$NZ2 z;Ig1e>~ye94V_>@LXK}gP+$ZmaZs@Hn?>97gKVPc6eCLM7@Laoc3dq^QGD&lK@krp zlQtFZ4Xl9<#DW9V=aGZn)9jP+9=oy#&;@J`pwzbw(+jPgDH~g=hpXsvoVs)Z9KRo- z2aPD*6|R$arlL%e-PM_yBlk1HWrJ3l!LTh?06jp$ziA?2fS1%WdBnJV6%UeER%ZZ^ zMeTIg26cPeSp<(2lChNQMtja<@^GGg`rtsbyQv1L?5@EQ6Cu>2i2eFRGS>m1>Sr6} z1aa8AcYD)#QXbN6riVH&g-*&N`FfX>YDh&^Q+}MZ1KD&@&E9I$VF!`gI8Fr=K}+#! zb;bMA$brL_oZr8=no76=AoX<=IEcQX;W3N>pz>inmlU_p(Oukc*+nhziValE05@eq zk#3|+MpLXh=@J{fp9)AyD?^!t5<vY;xfFRC(u-gn+h8)qQw$QKCG?PW0qM{4ss?&U z6x`q>yJ<vs1-STCzC42<!e`|y1@e%|?<w~8n7eBM|6Bt<=KqU_+2&C_y+PgRSUe4i z+9N_I3s%OzAl;dWCpSq35=2r5eH(_^ibDjj1a@WlI`j&dGC0UrG+Q)P&2dq_gIIJ` zBpmxJB8Kj~I&rdP9MP&tXE{dmTT=oe;rpqog5Ze3*U&vR2GdoutB2vMZ=Y!G4tolU zMi8C(in`HmZLPs=*VUiI9WcbD_1P4n7C>h#{Gr}3<dyl@zd!t9_~oF5=lN4&6ws7v z<2T=YbMM|a-)PGVQ%gY#jiB8X3(NP({@8STAr+FWGv%ufm(r#RWre6Og8{u5n5l`g z8t1rANx+iV+GcqZ+kozn=}6oL*};Ny?=sH9uk0I{8?dW1eV0iK%$Ik|9!ig@4OAT4 z6sya$qop<6GZR*hdV!H1z3wv7OWNn*y}Mb4mo7YY=Dr+qPV$2=l1IT21;TvUZQ&QL zy%=3vlIGC@9`Zt(Ylx^)9pp>r<kOiK>CW;)g1g=@z4{?Kq`3>c@TgjRDn0d@muWCs zgJ=mlRzVwf>m>8g`v`35DOo6A%{DfnjWK@U(WtUDQJ#ZDYlBXk2ubqEDe6>|$COaH zC8|(hsRoiXIk$}pfN~Vz1{Y!|j49M46*Dd&Y1^n1@pzin{O}mINrw(es7hMEmi-#9 zle$|8VQFCvM52n9Tc6jJp`zc<iWQ@U?Aejd-R>w{fUy@({_W`Ln`BbZFhu6HcH9s# zGV-7<@wFE+%5(@?Qsl@m{j*Dh*|d!ahV=5yvlq{Mn9GLOOjD{o=}9qx6nGOs{ug_t zOtSkFPK$!nxq1O-CjJ|<I{)u0x*yj}UUK9WTtjy4Fa@W@EZ<-NXLs5AVOKE`4v=P? zw#GultK#hF{mN|L_`y%(N5?;1PJX(3awmKA;qdsU{gdOrn1Am4wEyAor=I!UGrxQA z<q`^gcsM>Q53EYm@wudqcj9(SkGl?sV9n@aN=v_{LCsOzXgTxikU<b~ivT|nAv%Dl zk4QsIN!O8MqTmOhqOO7QMN<N8__a-&S~f>ehoxx0low|c>{^1nDcd$In7*Oy<!CQy zmGVo6Gjc*yfG-eW<(qYN0YPuj)oIPCDs#*hdza=DQWrZ|!^sN83qqD~IG0GODjl_5 z)*L#Q_HKwNriR&NzIa>I5`%17KLwL42(m=*z{x%^D3-Hdu(z$2rBF*G!^z&%Me!rP z5DBL*RvpM0-~~N&YillPVw;=Ud2x|TI!Ss0Jo3C+;sS^#9_7FwJKjBVnUXWWPS8u? ziGe7Pz%+7KBfh%t+h3r{Dw|eko5n|WZrTo`Z7}g)zRvF&u)K?v6jq~@M&(kc9(Fzb zJ78WPPKcU+U|=~LKNKky2bI^neV9J^mLf^GB@E_7zbVd}8kL)7Lp0@+S1MP|lEect znAO7v)7lK@!Fcr$;1OOxMs@p|9?Vy1UInZ-x52d51kf!8vpaVV?5l8*+$tq<GpE+j zlUn0$OsnecMP9%4f=<>X)N=P5O)$sThx_;UA3|z8Zd_G7%tBF)78Bl*pwmoa5QQlp znalQaR?C*UO2_4i-P?oYGVa5#eK;U)Wfk1fY`uj}EuEyM2~%LpO0xZwib|%BO7@4) zX3T3nYz&fSo9UbBtw84F%*0&7?hs<?p4(XbH58|7k8+S((8tKDgTa<jkP0Qp6Gj*c z6*m3BAR*ck^!I=hsCVXTby6w1B3PbfLx&+ErwBf-=;N2q#6pYO%-`kZBA+gb5v8N= z!PNmdC72RC1u8`1!I7s?W3HU+jkyKCe|nT*!uAUZ=hB{(?v<qPaS7#Ke2-(gj%Sj( zcHugyQT?SaVB2_KZrprP)a$+}IcnB<jhP)OW89r=f4Fb{wVz&K@Te$JqiJjsdB{TV zer`HX58<LO&^#W6Z~B~%m*&~GshT<r(8}e!cpry3T#BCB;7E|mvuZA}@KEv@G~!bo zaQ(4b_&FQwEFk8la$(|<Q=t$Hn!dmwIdey%D5`<%?U{C<VFMtdcl4TltwB44D(Bp` zrXWT!P@9WsQD0}z+Gp=55j(?)n`~fy1upQOf}O$_Tvl3_Kq`%-ViJAmsjZZba$2k} zi(+Y&6R7XXzH#x3r~&JP;!=Ivkce70Aqh+2AWH-0uFI#h2UGlaJbifoi!bpS^nKX5 z)EI6`DQVtu;iNg4n^`1jb_wq})S3?43H91U)cEnpSMlIG727ik6iOV$1^4LUg}V1C z6)Wu%H0>0?PS+aAzx~j}x>_Z65OH_qsW|y7#j~@$f@adG(PbTm!R%TES-z$R5t<=~ zi_;+-o1xhdYZv+Bmrp_LTFza#xOG7RS<Gn#gE%DTNL$ND8=^LjYYZyKmiWHK@m&JB zi~Oyr(-h05;Ld<uy#%v0%)gq8B}NI^O=~jvbD=(q8a!5)RkqsHtEy2}e`a{*N~*ch zw&MZLH(*SdI2seKngO8WEq-4Jz=u!&^x`FgJ5ho7^$Vc|O&#x`v^V5vNZqC-G+P?S zQCsmT3r_$c)a3<)Clum(e#VN^j&Vd?`@Pv-plxK@Lpu}0VOdQ+Q|nF#O&nJXH)7jv zHZ^9rDdtbE3=y<!e0?>lc<SO^S#6qU4HS?D<*k^h7*Z<r-WMFbe);%02adv~fi&`) z)s`>Pq<YuhoTy>^!9o+Zk4T%e)|SCtOcoSmpRSnhO$0%)iD9hTd|Pf9yT?+)kmrN+ zfNvjWf7Aw#yAr-@ow3rVZ(YL2dp=`&%2$JOm;=m^vj&^adtJ!u<(0UuSyZE9`(^tE z#^D4Q0N;0=U`$&Q2|BM1WUH#>;wr-lp^m}9D%zO>w2oXe#n}iup!1va0nX@gs*d|U zsDA-PV4t*Ja<AujW~baLfGBLtMKS-5W%&3Uat8tbMUmG4yO+%qSf_p{jX*Vm*RWan z_$6u#FabyUlq%NCvyZi`78!MUpdRio+DpJXlhF^V$1Nv|s13bb48GrpPe(h>IZ$l! zn-^cdz&JXHG9l;P0tm&^Fq^769dZ=y8KCTN>M=6tw?Yq9=3@>q=SA&Ixk}A*wuM&7 z0Gz}?!U85+7iSRA2z>ZD7QjHj_%How{o%a+fQqyarrzMQaTzeBWNWc)_xF^I2U{)g zV8v$@2#zQO2xJ0B*|L0FfP*6}kJ+Kkl59I_N~LDlEmvQyD%+7*>fIF*^%6F4w4C>) z$FACTR9x8%2ka$B29MPF44FZa*g3TajG8zTHRuF2b`VbIM&mJj=lyU(H(U?Zgc<L) zX_0AhydSF^tRWITAMj@%&h0g18X62;#ki-7az0<^o-n+7iujFt@r(K0@L4idJR7&L zie2fn`Dzd)(o*MPPuJnJLeOYkAX9J<x2Mlqw0Kri>hVA3%**)N{M0Bal0hr)D0axw ztb82@%F@ylpZA*@E<J6ODh4j&A5D?!QuO}hdY8SSKZ+ZJmS`NnY%uqwMif{GXeT2Z zr@q<6{4bhoKA#7Xf@h0z_V(sR6zEltYzlT!&1Rdr`TH1CxY5{w%p~7}oti`><d86+ z_e>Z}z``rulQu~7C|gY@oa&hDZOVqyd9#b9$5cQS@*owmX0Ju6OvMbPYBMRALH6z2 z)aX)o4^;@F;!>=2REk~_Xxb2a41N@sbb6Ht#_56<+8E{>yd6z67`lPHk`R(ed<Cyf zzXO-%3=>6|9*?khQgj}-Zo^4J+>33{;Ppx+Y9mrGrMsex1xCEyapAm6NX%OBOr-Vn z6N+^?BW{+T4u?=%vW?x@AdkFx@j_`Nu#Z?^e`hQ}$T>WyAo`SXgQ8Soikx~8tYjFM z=BQFT^F-h>l-Ykw+%k%GvGt(0>RWd_<iF;C)9}(qeCM<M%B4l1Gt7{10q%SvImJcu zj<Py^AA5>Rm-5A(<ZX+9ND;z?#&yjKc<Np08p|{H(!Y&>?6hd~@&3txz9NL0ulQHK zesMAg93vTT@CI=ELuqShtNALa2nQwFN<diB%(`wtIyf!j*V*V%wmoe*T^F%}BE%tW z*aK{yt>Zj2C71YeSC;}R&$U}_{o>u45l^KuDlF%bu=yQ|nsrfaMO_!I=h*a+FpTAW zftrc(YE#CZcw2&~z&!}6J%_v~y%^b^G1qX!g(gW46@c}bU(gDoDe??((bfzNwMqcl zTEqwfs{4U;T98@Qwg#yDG=Ce<VUKn6Y9JzR@Ywr(%ieQoX<*+)!4KO3kwWkaLO$=8 z%k!cx*ZaZPqxDEn!?2Ev<TMnAJ?iW?dz3CTvCBu>A8#gUZQ8dKQ?WT~!dK=I^bG_j z63BN?1eXV-Eo3Pnju9H**N2g9jg3=Jtw}Gz7)AErf=Xj~XdR7dk{10D2?cc$*y-z{ zS=ZGS8PS!T3f(zQTEz&cp5ZWKJm+Ueph0;{A)TAFJ2f_|yq)nmtuKzqZOGe3qz(q< z)l@44c@C)BErhJPbwX<Wliz3`d+X>B;QF>cOq~B$=vV^kr2qc!g^HhTS7xMQCqRYQ zlC>-fM9=AyFk>PTWvp}oQeyvQQD2x12I_BKEX}R8&#BOwqR4*p`!B!voh<Wf90_m? zp-)KsrLW0*Av07&dilu*Pf`BzbXw<UYGDYT%Lb(#FHR$4J34MWAl_1~sc`~3q<lOj zj$AP|4m<Bt`Zy;{xW&}P-afx6Pv^y{Sx|_Z4(DQXvGVOG>L5BBcG&YxG$t7Y0;&VU z4X5I{LzNIuiTQ?ChhDjI;8GbjuHPk^HlO{5?F%U3-?_gr-^x>X_!(TJUVE8Umm<wG zL_k${yATqoXA3*JU2hwS=Zp7{J_*4Ww6*3&cRnxZ*+_0{WwRIf0|+@8IRtR$E&i#R zRV|xfR)b`;cT65ptq{pIq^4_}7EA#d=YAzwa~6H@+#Fzdp^_sMRku^Q_Ehb`Soi3j zpa2Y%J%b{7V&(>`wGPqBXb<lLxDF`MB>gtHWmVMcD~dV>Z&0@)R!R_8Mw;I9&6+5J z%n>WYAZ=51DS;DJ%ySH&;(0RdwTCz7bRQf9&INeJ`^rmVaVS<~_^NLcSsbWxRu0V@ zgTG+`d0nO8!5$iLqu6w|*nmb3qzjYmug#dpImWRRAoaT#zn<0QY7Hqy%pv@1V``cW z0dt+;eTHvenaN`gI?#C4*>~T*{4V>hoPn9b2)=_KEEzZS4KsZIkAM8*-7oIl|6O*p zI<MZFuk~t_J%#{nPzE@4v{aaL>)g^LJ72F?lkxcS@^U0=J2PWl(0A%+NpxljxUHr9 zOcmOLWjB*MTU1knG|||+S`_pWd#5O$xYZ<0FeFQJwVa*T)w0?&WA)o+vM`YHZ~42N z7E7|Su)UrLB1NnSYe*7KgLOa=&iMw<AZ`&fXaiBwAj}We*m6D|(;`z(VV@&jz<*^( zRRFK|aZkg%%Pj+5x7=6|+8h!CIp<qiIw`xbO-gqj$iQbh161C?5I{eTGwPT+aY0uV zGC;mI>=N;|>W+_4+r;~}=jO&^w6Y>9(|o$_4XV(+-?!a&7W-niVqbcbiKhJ@n_^S= zL8eSG^B);)_TZ56gweZUY49P#D0hC1f5v;1pS!;=$R$K7`@`&b@0RyjaMk`$eK4nV zF-Gaw{@#glW0Ar`%7=q@4y->RPK`$o=mUCTO7<Lh7-kR(!oGqBK%Dlr_O}Y}G-&5P zemMH!=xfX}4foe~FCKsW?D@Cm`M!O|&tDApgvA09@|SCT{u?YX`gPG~*T?*+AcUZF z{FN&UwvnM=QuG6l%aY_&_UQ7FnU}Sp4;JL*T5T|D4^ky-Ymf#&j{Udg4r@;wW^;ja z1~KlGF3wi<kJYnS<&AxFnotU1@D{XG;N~^LbTS>O2_I-jAyv}Qw(Xe@Ul8bs1Eot) zbrc|NLfG7KDcyQDU~>#S$fS_VJ<%`cnx)pxp%~O~iNT%`Y-Z<Zs!VBsZ4MuDGjy4J zn5L7Fd3=r?42DFrqZxl*G=}H{%bmM?;Z5%0Md%_xR5jW7Q2^1VBFl4g%a;bP0Rd)c z))gg%YgX0TUVT_TqHVbslAa)(8suOYI}+@`Cxd=m93=IwzyD2c?y|Yuc9RTD#9h8F zN7DWX+XF^TXb4kcghSW_)&-!=lQ{}>Wzwul=GoDxX#g!~JIc!1?tXReE1sD6ts{W~ zdW5;ue=-ndAhu0X%S&ty#hwt_0W9^|By=S82u`#m2jvpG7)c!Mz6-g@sV6a+ApxHX zNm59bNFs*ARFPPob43=CC9<5`XD=V*Ukxe2HEe;Vp6!r+3_~v3gvkkbhFn>Vq@gFy z{{Fp;;oD}^!ZkDdQ`Lm2_H01Hs6~kjs^cCf&rzIJ3tAl0;r&1cPwQe#raRCIw(%OX zN;sxQZJ6a}((!EVnT0C8Fa<Kw2cRNh#bM@@%^BDVYeEc$z7Qim$0YUuYZrUAA8P23 zfb>9j;&88)&RAw*Tf#b!72C3q)P3MZLb9&mJNS57st!`AOu=@K7Cz<AX`M2^HgnsW zq4Hxgyg=15zAsRQM%`+FaXI<4SW^<_9cFav<4X7!@b@_Ydwc<tYpYM*dzl3Ef}Jsb zrO>pEO@R^7z-ZoS5c1n{1qjf~qlnPN1Z`re0cpmI-E`dQs(155esnDhDvhU?)LYB; zrIhr}@k;viN|HNh$v^kMo`$)xeT(f+>!@)PKxo0T{xHj+M-e5=Qdm!*Hp;^>uwKH9 z;uh?A3IlUK@X8kyN>nA9W4L?V2Ld9p1M|j!WW$>VCDQq2ex(-L9D+p-mkX_lnc$u? z@=X!keu~WYA{>uF3(i~1vR}QE;7!~DOFw3nCw`O?FFd+E0u;rPbnwX&G%w)d^7lu* zZXIOel%eTlV~-R|GvKk48Tb$0_M4uH(8>#LH|%K6Vi4dmf7O9NL1F8muw&N?n?4D) zJh2f?AIBM=o5Z4im&o62aTSS&!0@NgF_Y|=8A%jZ@mlC;yk*0QXCTf15DFOHnePiW z=|(XS=PtD>7`bqkazzwN5Ja`+jOOY4yTO(?A{%%t#x*oc+R7k*^hbgTE(a<NKMj0z z!v;@QLkG{X3t_672LU5ydVQTbk2>wIVmRUUiLQ`Fg%4~!+rt>19e>3yMlRNmedSsG z39H(P6It$Hv0_SUq0wOq8@3@s89~clc!`n;UAa;i>63R$2W4cffxxOIM@hUpR}*fm zpM!+ExFzyGsf}C?1gmU3n$GQzKdf|~XS~X+FhLSNG0BH69RjUPCs^UJmE<^nCP|t) z_N5yF54L1`d1gtKrDFPVh^XMRugZ0LM7L=~&z^tlh7=Qk=Ch218-!30>WvoVB$6e! z(v-T%yLWAqTUSK|#USx7YQh-?h^4sV)YcRLdwRt_t20VN&znhA^g!e`asDYSVY^J% z&nr**>XO`h8zHcQNf|%`YCaGi=0P~sgQbhO0Y6l3>L7Qam7Vd5n^YQE=u_wPg%Kv` z%Uz2Q>ggF?$71+U^lo)z`om51WQO#8vHU(?=4ZZ+EPVgZq9bclhsCtwg;|}|Vsln5 z(UqzK@f)0ryVa5?9rL0DDt&pjF{_lVaM#n?D!rOX&4MnF&?@*!haEHvx<aU3h?EGP z#z2omX$(R$BU05P^&$)fnd;UHlKtB^5cXlSl6L^)9&D}ZYF)9|?w7VG6^`P}QRXC= z2_x!eF1B+NmaoG+^D%B^DlmmeUS#*)05HhO8NEc9xX$n`Kn4K`gND-Y)tMC%d*S%B z`Gzysu&G^Xy?o;YZLX=mkEFNQe8%?ej7jDNVA5haD~l#Q2(;P@qg}QSiepK}!_qy) zL*t5uLL$Hktm;JH<DD#PFX4g0-Kr%t_}?~$r1;J>@G{5n&uu{P+5(Vph`QCNjtof! zQG-B2IR<e=m)@p;Di9uR0bv<UqppsX@=<hfG(2b2<3O0ggL~r-_G;*w)a1IX)}fEP z<-OZbTk^NRO&3Mt;C7fjPgiyMbKL9>v)&MlncSN@@aDkLT|{%@ikscM$eMTNW`U(! zR0iwvtDj#V!F_Wp>T-lJUtXN{{cc9hX4<Ul{=H%L#eljT0D*Q_`5ddYNme_E9GAEC zDjgmA9i{RG(fnI4c2sWT2?Eqf=LcFJLs!i>?37jCT^@Upi2-9KFzNyQS2xmZ6)2W- zby~*eNls+)#B}4%9KbHZpuSvkXDm#9Z0n#gy9hR^OW^ks=LKWMRGu{$Z;D&;<1uoK z{GL2Bg)n+kG;11DZ;0T4CI{}V4!$}cW|nWlV&;M{?|bM|)YE}@RT(NqMyhgP*`VQ1 z#bQxqKUVc(ep|A3nc~;#C;hk%^NPJH&Pog$%8TX<V&I-7i16o6v#|pJ!wk?gnNhc| zNZ9MMWw|af(vt-E^7|;w_r6SgG~(^zF`ApJcNe>qrYPhQO#tLVr2d4QVj|C#2t?N^ z43`<Y+LO}k2?FIX(|4Danjx`6A^<E&r%>O0<sA65Uj*_dsTL>R)3q1h3yZr8k%Xn` zi<+gP0p2(WKj}-^HB2!4L%mRKPYqfB12Cdyc$y+1)%P51OhD~T?k1tH!W^tl!dw0q z%7Z+~xako+V>s<<Q^We0dXQi1)GJ2M*9S@T28Xl2YZWw|)zZZ&Mb#r3t8P{rEoDDg zm<AEQj}n*40~Y#+B3dlTAv;LGi0Sp_#k*ort;hfzOqjFmF>+=w9<Z6MYNdD1E;h?E zI9`-EnT_X`&899SdM~3NH62VDv;j4ZAr{XurZ4M<2*}~m1bHiENa1dQBNjDt3tE3_ zyJ*R=jjf}hvL=Wea$abe5$fgol9LCQhl5w^#k7|MAKt-e2a)THET?7LD0_^j5DVn6 ze4gC|b+{}$tD#iZi6ro=0XrdM@i4hMtRqrlN-aE~H`ZRi^NM#p-O2XHVE@6j+Y{$7 zA#7QT(1g(f>#lZ9og^<`lX#}y<4^D9%wqR`llC6A{q+E4THh%|AN=ym}55mB2 zotVW+)y%!?UL@<wi>sAT1idlnCC2lz#vk;4Y|nG=(_fLcb7=1C#Fd!kXSq-}`eGyl zrGVp*P4CpOYG;ED9x167C=j5Fuhli^iNN*!Xnk9BVV$1{52pUAPN%!cB<$BE9ds3R z#k}adxj~Hs9lr+mk?M`)+8T00L&svPpP|wrrSm0uvRXYYb#zG!0=6VwQsbFcFI?-+ z<wynp1`m|feCykjp1S(|4d%<;U^V+j)=R&myFKU)(3s`2#>l;K04ndxWIPTTE*gW! z!y*-75EF1vJu<QjeWnzjb%<RMD`=1#aD(t-kvHpSYD6jrf)Z)@3mL<7Y){pFL!cfY zY{rXVajl$7yjgqLhegG{Anzckf!tJg1uI+DA4Imyf>e&rOUxI_JX<87*k3G!b$VX| zE-MI<53Z-=*a{+M$b3T@VH@1k(8Qo0#!!#sba@Jb7s}&URpxBeX4MQMur|#>lEE6T zx|w)mH4qHT4$|e4GoAhLY%g)67`T_L75JsVP(410LT=L-=vGoHs>^U{!+y@QcV)9d z?KUOsSccx0C`J#`;#@;H9igA(t{Bssre}T4hTNWd(U?m_JsS34o&Q+Q*XR8EPX!3$ zN8aANWNr$mINZmf%`;){#HQHHEAbqHS<cZge`@eG_!ik)(`7&4i~+E(3^J5hla?P; zmkX#^lfI|o+q(snXmFv!M+bw-r993WSIP3>%we-BP|nc9)}Q7u!nBF?mZH=EwEqOl z>RxPn@E=&Bn)~?sD{izm)L%;jNE4E?dGD(w3IhU{UsZsI`@#$^7@7RXBlIN(FqwYT z5RS84gL{5Y9L0omNtFc~%1L&d`UL;|0{6#+jBuyb`yRO^!VBo52l7j^;pX`bK3}KW zIZ1YGPV{Da;f2F35(}dihy!eihrEr#M9V@#M_}}@*)^)7l1=eyQdBPXG4Im^$cM8S zK}>)VPLaGw!vCUqUi;<j_iO9h;(!t$&@i1F@}Oq28_->YuVb+M-n@Ng%5DS9uKmVU z!&2B&@7IDTBR!9U`9xqVH&J8OCk?b4kazUbs={=QOTdzo><{<uB|o1d;+$l^Z~4ww zkU1!=0LrWTbWt@eqxM$1H^YKS;5xY(bXgy#-Q6jlbEFNeCf4u%sZ_*#V>Z^I5$|-2 zh@DehE3sp;x74aG-<fN!#aU5Ss@1Vf3V{0eBs2(d(cT&<hg3RIpDO8D=v>X8Zr|3y zHN1GHYmCqAOb{?kLnD#Z4|R|C2cD`J6<E*Nxt;hjmaUM;hO*K&ehQZnh8^tpvK~>@ z9b@NU(@RVhqMg;Fc?c1{O9mM~R5Aoa&K~eUIf6x2-nrxPYBmuG7K0ecp?A28a?t7> z?&2BnLi_9Z8q!l@VBdy$Zp_TohzcHloAJ_*U%RBUropZbRNgjmvhm#C!*$~BQwt?+ zg3%g;VYygs%zcW}lI%zja0Q$-Ua~VgmKT2Bg{QR*9m;$^`I4XK4Ge+?0KWAkAY942 zUC&jpYyz0a(&PzF!ZzDB78_ZJ280=oN$z5PeTo73;ftjG0glf0ksMvwJb_$Ks;ezM z>FLB7qY{%3BKDxGQvcmflkR|Ao53oI=Oj?IHB!m8Bv?W0r`}+<wzop5aDNz@<qeVu z3JHHX7*cvP&RO6#g5E!+%tl_FKX9EV^(4gFn6*l3dMowDjCs<!K|PpKOU-X!Mjcgg z##GlIO*lFzp^xgsJGlJSKRlE8JlTE}j-5nUmsbeDbRtlXvX<SA>Co%&|6DdJO(Mzj zKNWd20-5txx(C){1oID>b)qrgi@7auf#|8<`)TvVy?ayk!^c#V)0vdPAo#tUip+W~ zPWpBel7tjA`G0<V{SwSoxUT~r-QhT9=e37?%rnqRP&33}II3ptmp9Kk*L+4vzWPvq znDx#K>_eK%)Om;QCp-)QNvJZxj^PP9n_!nW1kG7)dKo{3e_dcA1*P$qe?E)Pi)y}E z6xQSumqZB$%|OF<B=EB0JZR~>TFk|{1<Ilud1cs6QaEu^nq9a8tUvM>J_*sOy-OI0 zItD_0aHqku50$b*JX!W+Xu99BcESAu7n1)O-UNrpAFNA9L5GB{ZK&qm+3k_RuJ=Bg z?!d*1>5g!S&z1{V^8}USh6!D1WQE;AM_XG@wcEZ#A3k&rFX{|sQmVv|1M)lT-FXEu zo+(P!5Ty>!ReU#EWiSxM5OO%J>eBQoapzzQq!M}Ov-<1}zwG0(0FpvN-Zh)rP6mM6 zdXTqxaEXLG2aeFgt>BU#p%<-pSjggK)utx%(C?%9v0R^TYlvSE&xHe$d<iXmc)G4| za?)&D1`xMZQO#Jrq#Duw?b3$QA*ouy!Uu_z{vnHRM!M6|`^~5wkT)oSbvcg)(H88s z%!3f+$mjIQqoa$diHK?IID=H`rf1LA@(!P%LEH1dD+_@m+YzFSFME{r=vObBWIaqo z(c7&d;^+(^lP?xw6%Bt0bYV!Zd-w8ty}`$#i;p==YVAM%Fxf`Zr)kH&BM7tKLlEPD zJ2UTSxcIl2D~hk*fE!L#F&9{LS`+2eBFA6N#Fmu39n7qIzg<q7)qxH4m?%$E=)RkS z#c%03j{bYAvlMqtJC~TJhaY%D6tZhynKjWsjw?wFg9!s`QvtltLS@(*{6C!QUb;1# zTMW#25UR-DKm%m!O}UkHvg8tkWI5#3OL0^!_rVQ1u)ox8knGcAz5M<r(NP&DN+I%} zq{+Edc_Py$Ed(CcP~_aiBktT+>D4_9mBBFmg*R=RHEG>OsFhy-Nz1<6kP!t=1=AB# zY&*q*`fvYP9S&!rSjw~0;xYpVzH)tKEg{hK1s0+!@TFU+R&A0i5^##jV{jNSkZ<au z_z|;*N1u|sWs)!T*i7tan7M|Bnd3bDitX-+?IK2>4Na9u9YIqokamP6JZAO`^QbXi zb#^ppm*y^EmyHneZ`ziFB!yUsUAFO}!Kk+nRc%ea@-57fag${Z_B^*GD*M1*E>ibi zNN>2tj<F2J$eOwN`v}<qlOg6fM47cxhK&uqG!cTyK#A>^+Czh2ULDwT;Y3t=Ac+5D z#^;Ce5Q&Os^bA?=(-y&y&iz$5p6yo2PrG6sb&NTPzX9XY!5(U0z!PyBgEaDoS)5yb zC^3d?2=c=)%{&#+!N<9beq{@Jt=MP!47O+unn+>uFROCtTBoN>$B4J$g@)d{WCVXg zaa%^pmstV9R}0x+vYne+^AmH$z*ECjuc{4((F3mzs-&9XM8`#qHazf8PAQ&q(#vy{ z!wZotH5`$U8tV7f^J7bh(z{}QGF+c0-u7HpkEK3<Dse3uA}=WeayrPl4Q`3l$w_D^ z92w%$0Rt#KdXJZCLt8P%G~AN2*2ZlB<2eX|%8_ykI)l^#x1&x@!Uu!a=(!~HE~rzs zHH7PYB=v-7;)>+7fu=pw22~Z?NH=IDRz1aVBV@(T$3@4N!LDgJwQ2ZL7(z<$UDk~( zf^^D3OOzzBG1TUPug+7}4=OJ)<!<tiA*3Kx=k4KPI)ky@V}cG4Ow0-}CcYm9`1~&4 zY0S$2&#Nh@gDZB@Ay9f#@~}a|0K_aodi>!SqUor}_)QXUIh|hP1?b-fjsSrKjR=hB zHO*P{q!}L^x8+_E932K(j5{?;^)sg~Y6o=mJzEfFup>&sF&ASQgQPX!)Joiy25&n( zim2cWFrw5rwt81W13NbKS!~V0E5(vK_zmWfL6$6A0oJ#6!04F;egAdS*bK0g7wX~y z;>7X=f=PTvAGz@qjwfHIw+qvpKvto#?M&tSGtVnMxCnhwBhOQFz?QkK<kkXJa>N%Q z?<>@Cp^`oGA)iyvII~fAiV1fhTau+1x=&|hNkvQs;^PTq#L4R`5^?`bV-@fjVxIa0 z3_fQ=D!67IWj!S-Los0>CGKfp<ss|tBt=X#kL_^nWuOuHTHA`;QYR>N__9MiE>3&} ziLT)AsF|M(^*Ri6vORmK0?f~u$<%7<6KIyJsGFi6=kK;ufn0i0XVB`+Ln&H_w4Wk# zOvgmDkQ6`(+;0|`LVZu`IQ*<MI;VMX_klj`spS&-1C?*fCsc!KinCBx=gC3W_zAmo zk3Pz%<Bi?>+A{KhEY^ITM;^QEJOh8!uRTYS^s;8bjT>fl3%C2&uYNKJ`a}dAqEuw2 z1S8|6YCjQ;3+U-7R(i}If?@hui(J&}m+Yv#C{Br#+)Ev6$0)~HbrOP0YqojVvN*Cj zF}_j*b{q*<9u1O~T4c}01-ImOQ?n%rQfj(-v>!29e-53~^+C|i;ZsZ#VaSo;2sL|h zl<^7!4prZ1ZEKIZ=>P=w6i*no(=sV&#ame!DaaBC_7+8cib==1Kti#m0u;I-xXC$T zJUZ|angrg)TZQ&J!y!DLUBn<fQe(&_>OpIlh;Q~TQJ<9#k%nnjKIwL{iG9s!!uGmv zrEQnXwYOY!3X%&S;YS=qDoX5YP|BvoLHU~F&-jqoCEQ_h55+em(u}1#n7qMs8pe&0 zl2poGFJZz|l+s`WftcohrEn&2q;@KBBD5;Hwt_6EsKd1-tJKxTLK+B_0kRsAF6?&4 zC5Q)oL4T=HqsLAYr>b8)NHvsXwS#q3#sDcKq3`nq4damykqLyO{@lJi^xAcSN!7-= z-*<K40~au~eGuM^+NhJHu|_<I_QmvuVyoOs`<?4n?<HtcT^fibJW|0VJ+T!@fPBbk zfuKkb^J^d{reJRjJK;h&`3_Cn+sdv<w^FrVGF9tO*u8kry|deo$qj+(hA<Udxu>{? zNwx)vPO?t?ImtRu=OpuzYF;NUtLGpzh9Dd13u}6X)Qku+(fJPL1m>S+!|nuR1-hta zxs(2Hy~~38YboPs&HeEv%KZ@z_A+l=JAOVAd(GMJ?N^;^Vu<8WzG{kjaO>DIKE0^L z2ue{#_stNgU3doPVP;cQQfQV&RLi4_)%r@ZxqP2fU@0=7!YI*Z0N)t`ahR3OV=z{F z?qtHs{PGR#&C_DB=%;ehiqv8Jm;RftKfL+Vho_HUzIpcI`QS6oo8vi<`82rpTzOKH zc@GYRuVA2Fy|5!RZ;r9xG@)Famw{4ghms=tTsElTN2(dK*T{{;;veBvsH0;fpC6Ho z28A_1LH14zAM6V&yg5>ck0-D8mGmO^vtoSjM>gzm<v|s!nwo7~39hvC2WRIEGOg7O zQ?#as%0Ie9Xtq@7iWASSY+jlLMe8*u$4voNh(N8(J$SFzo_!pHTwqqQ3Q65yTgODA zV`ix(#zGS;<n9<qV*@!hFz?xNPC{FVAZFA1a#V_H2~jA3@CVgRx%9HpvYZXg(g2s> zp#`x6Rz=Y&1u;DbYCm@c^X$p1@w4y0^%oC@E5?7XiiJUy?~48ck1?VS&&<gk8i*9o zu<?u7p!3l1NCXTdUmeetqym2js%<An^c!(Vi9y!3u=PmlAg2aj6AP>4$xmKc$uuro zui-pvW(&+W-T+xf5j<z#7PGfiHr<>}vfupv_kXx&I{|x=N%mm%@WHfx_~F5L_0aS- zg9MrI@&mkumnw=X3`i)Z=fTO(dQV>U$TrZTRCuJBB0}z`7EGPMStt;Eo;+^1Dxo2u zZJX=Yt+W-8s;lhKJJ)SN{hjDwvs{;p?6LsZG;8XP#w8}#<Ks~gwBm}7r}enJIAh$@ zg0Jlu(;z4#|9GSf`S(DC10Z5YzeGI}1+NfCL(7`+<}%a<n9{?$h~5#q?Wf!eS`cc4 zOF@_fG69WmAVvzLpU5*J08>{?tZj|xMy*T_07~ga6a?{-rW>1B7NrA}I%cUif^ltx z;>OROzx?41gcAz(g0X}1=17n=#~nWEC)+n7!i)YgsdMoHaLlP0<T=H-2mN!2H7!cQ zpeW^%Nm+<$i3Tpq>QXsn3oQs681<e;1W~cAhr4QHF!#c?4b^%~M-q+|{=jo(uDl+G zfwr*SW8HbB1S;KCiD{5}8Yybiu1E(_Ijwxk0L<f$5)dKgDYNt9A|GKmDZh+pk32e9 z@U03r7h8D82wQ`d5-x9_-NUZADXX=3m@#cdiXhS%dk%M!tdUT)%jb(!h)NdPKIX&h zk2(=+c)=6b!7x^}GV`g?;TRy2qKwT(XBGa?;YQ^e7!Mam=~2AYBS9wgg!IE0T{0l5 z_eFkY?jE`UEYd-oqgUD;#bpSwN;OwGvBD$STC;h8H%|@%46d+I61>8@Bfwb>X>p5N zaN!AI%z#AMfAjdscSrl3-2^;}UDQ{sOoUBBwWCIBTa<<hJigD@=c9{q*}v_Bwmuxu zatimm?bIA3@Mp))oun|P+P7|A%prs%F_6F)U3cZzoNjpWmd*knP>Bs!6%Bkp&)-4B z;wv&eWlJ%%$jme07q;vPtn}?M0s`~t{@F)nT@6|5fgmiO<C{Eo3B9zHM=!*Dqg&ol z5dKNBFxN&aD)EQMv1`ka9XQ;bNVVWPRcJQU3i^l95p#MyHVu<>9^(201f8b+z2o!9 z9GXeG2{nyYda#SW+i~_p&N<s54BSY(LI@j#lY=$68F7bD97(8JR?6d&mYP9ItV!rL z=VtnHvligS+XU|tqWjD>CIU`RE!r+9%J$7_VcPTCEjN#w17tkAm010oZJPYZ0_Lh8 zLK2-v)R`J|F_CBBx`5Rhbjh)VcXyjDS$Uytvk>M)V0hBKh$i+@;8kcMXSnm}!}kxy z(}xerhab$3@}VvAgjjVd@`20vMZE0ehJZgqNdT}}Wz#?;C<=Ef*;cy<p)Uj4R2|Bs zSVmb_=u6beH3-QA$Onu><H9S_0$L(QVN-93%7<nNWRXZ}kz6M%Co2_|+kLS{t`3OL z^M&E5&tS9-u{<DA$zdyUCqx0I=nRDibH3;dj^KhHpkyp<Y1xVUH=)f=4%8LPsuv)R z@%(yJX+umMw&1Fu85LpkA`{UgU%tfM(E-dAk|!HBpXA$tigfnL>Wn92wOLWKNStm* zV%6T`9$fU&{q3Zfok)Qe2|NO@nn5d+D_`7QkOC3rVpME>7)T}?;s*`p?~mc2p8)vo zg`oZ3d^%R&B6=QY>T%yYp7Ysu<zRAUDCtwA*DTgboQ$GhU*n_<l;oA;HVwz!1D4uw z*N*dkZ8`5F;Ji=zk<uvPv}zZE3?l*+Rjip(W<dzu5zdaQ3}RbFnyl*_4;LmI!Bifo z=mx<!p<{m)Xv>0L_1G20^)#lg2^|~^m6vE+e*xFM!F!h#dkj)S5HN9XJhzbIZyN}v zjEYInE<#?>a<-@4r)Ja|Y9yOIt*<nMvr}2#XQzu=G?!d&)L!L_?kbU{a~)|qWpdt3 z#(TGvzo<9-K)HE;h{JG^XK)^7Q`}q3s7p;`OFRYHvm@?THWX@M4j>@P@nOCJKZ$%@ zsFcS~DhO~}6Lzkvh29y5Ho)YSiA_!dXHSpohDWF$=u7_|$#d;j^I~f(J3Tg}_Je`Z z_M}JC9Ko`?0i~a@@L*fuyTD3BR{iqJnObj~C=j}jZI7_m*i*-qw*E1ys4~8}4xAx{ zWkTx!IbUEj*?4jth4Rr8tuDz^N^;)N5~8Ic&>{k+o)YXSwe^fZwLe>w1_=Ihn9+~_ z0`1bwIh7Wo^Fpsd=#|{+3M=!4*c$xwjp>*WSlBA!mKtNcKzZOuRX`3J$-o8Lkk-LS zlQmK6{LJc#Ao7ERd+-NBnlM>ggW*6#_NHRSh^$UnUW_9`*C6rqU03K{15kv@3>^9^ zDAFHDSW_yGe@9JKulx3#=Z4YdG36qv$)`=9WH$Nxem(-7<z2VXxf$+yZT8B(WA<R0 ztUnFwPm}d^HZSvKip$~FmWCej$J_vLG+5&J-ifq+C$n$N00!AO`+|A_5v03IXr(*0 zKYir{hm8Yq%m52yeQ|HbgZdaPLmOm_0rKamg9HIygKO&BVy&a4@fqQyP-h0yF0=RJ zD{Vj1aZ3SQKr;xk7T&$P=lSMhTGZD(_y5fP(_rGNo|ns<-FDe6vbD;8W&gFkiUjAm z2Ds1UiC7Sr4xqG}391ZK@9wH=tO<}>k@!YSPgP%STW|-W3?$bq^kE<#X!Iq^c5J)6 z(JStwy<iJ)Ipjik#o`o(JA-+V+UsKvBckqDm#W^l3NdY@yxi^Z{Kb(#xNa<Qne_OB zwo?c)YP<uBewwqHK8iGeov)JQeMcu9Z#y62UNd#Vx-LgWxfMv8L&Nu!L3Cgb?TRUD z=7jBMLheg-wePEE{dvbS*ERs>u3kwg1Qst%xFj*JV(H5cCE7N115~f9uW^UYK)}ID z3b*JN4m1n3yN1CF8KI*?sO&&)oo*5a2D*BBj++{!6L4?;f5<rxATq-lXT>|XL*`|( zf<q5N*(p%$7x@yXZ6eg`YIAn3C{bOtEn<vY)F2>f9681nO~e<~A!XF3qvg9eCH>dt z^1Je5!MN(f%+wiXSOx((jPOl4KpesW`PM7A&)~<)93p6mhjg4SKH?w6rcH>|6*K_S z!D&&*3i<}KN&DTTO|JCewawnqn3mX%1dYBtlU!w52%d#ZCd2dyA090(f~fs85hy|T zjCuiP*_1iuGgq4x0?iL#5yh(t$n1%^yA003>`1n-4RN7b)d9<7?E?&CGX%udAZ5Tq zN*!?bu9r|jl|3#`FyWgt?}hr;nt<!jSfRvWsr1_lI=rRY8i>8EVlqfOLfx2c^F+JZ zY*s5ss|owQZ;vOz);=9iVXykVY8jO1f%T2s9z#z$!!Ujg8K&In%$`C*nC$y%(-c3f zvVSkG%)j3lGPFsgk7mPeBu4QRK|GaL*0BYIdnn-s6)8(lE;bOT9U`b)RCCDG<D|r< zIEz4`yx|7GqXFeQi)vXAn6trJ!#O#)V+W#k`e=)>JQGt49vCE1PPuAK+$56TSH9;! zP*(d81Wp95Wb96${RzBs&a;5M3W!ZwT;^ARgbZD%aXZ?_1-s6Qg?zPIT)}O@O{hpV zVpzfmj1B!EB{9I<W;M^(D%J}ozsB{aWAB_yMr$TQdTvNP;O}p@$<X?|6+^+jPO!s! zcv{v)zxP_EL~z;j<;GkWwbBf7F4rxeqi08KJviN*f&PfZsnB|A$*jB`Ga_l@L+fK0 ziRyt;r@nr)>M2TWg$cFj+NBPC$v)<qonhuWZkJsoD|;T)=~Qj@!l?7RtQw06P}Uw? z?`9x#xGc>;{^yH(_bxEDky$uYw?U93T8(mPga3FS<Bv1!JRYm1@y)f+a%hR0^L=j3 zfc`-C;V{d@=Fv(^;zI-cl(5>B<A!irr-04i5I|5P*hv@oX~gJ{=Zi6=?mm>{k7mTr zmYAq13#MxEFd<??gp3Gkz_TixB-mxJ(B4@CC9|d8?z+ES(_|TnME{FZTVj|+*RqXQ zKp&PC>(BeYH2#bxc%NM>HqQdlH@F9wvbd%Y_D}5*x`2CQvqIqp9{Y7Ur7(mBZ#Cw6 z@*#$=nbg%n0z)&euZz=svsi;N4^yJJH3JJF0A4kQImSW2?td(%{|*jwRt<|PTSf$4 z7%OO~Y#id7v!OR>MBOPc@Pc5GJ7GJTJ2-ThfM--d4t%5dXWxHo!`j}$DS#Z~2y4G7 zFACF<%_A8eq4f4ywYs25&%?64!gaX4LiB#k%mU;`-+;MzwNyj`oi}rdU{cK~@;#8| zKxbZc8SY_A%vuRfp$_D7S9i@1&j2|<7(W$n2kBl+tQzMdR})G{=*#P~#-;4WCos!G z9;V8o2@(5LH<5Fj124s>LvwzTYR0WGV)G-~H5Ah4z(rAbj}Qy@)Nk(p;g7%n-M{<` zYW|${0meoGvmrz0!;%6XoU_piatWO4m2#N#ov%Q$v{}DVYv{%bI$%3mqz#&pVH5!+ z{;a4BRm>dZIT%BzQ}}Jc{<zM60OK4TMkwe&2P8}2eKbsSivx{+Z<V1oFjU!S&mx{X z_DE|Gy!B(Wc`?v2GLTOmBlVKRtSTCl7uPI1<RSZ7v7^uc<imsV;>;OzBrTv2H+Wl= zzAw7tH|^=2VW2}k-|%G^x)8lo@Q|pG<PsiCp^Vsxuq_Co7eOQ$gvv{+rk$k{al}M} zfJgR_POjOPU#<`A>rs*LPrwguHvCIcx@$_w9e#8B;8Av0-N6kb51+3u7AWBeB~Jg$ zvL>{rzc7deObMEGIWw2xinfIESVEq6WaZEnS8PD%;QWkCUUgx>3Q}$R*}a2gP6Fq} zr4>8Da*rt5f3vPD2zr8c&Zb6FT@+w~&yn>7rjpVt+YEk#3k*j6<>;%V0L$)iYw{<9 zjn~ENRX!^yCzBcV_%FxVPwSuRpOz<|e>NUsM$GRp#XEDNz25+3-<xD#4)JM5Db~!3 zKky5P8EPKCqQ_Nfe*X*oo>wzy&%C&Q&%QydcK5W-&$ylY_eK4z{XPvFSt!TPJwLLW z!gLa6%}`%TOfUIfY=l<yV57)xP!x=CfJH;hiH10*V5&in!ypu#RPa66gxdVkT7Q#a zH#>(C+Y8<9Ioxw>$8qAz?1PV*OMJ!1NriKCT~y0LHILFHyC})@GG45=D2h%HK1F9O z@dM@<_(0=2Mr3C43j;NHkLZAxC?QJ)t~(GnTXT`{FK_GzE^r?G82Qog+@$DzVp^$r zb>*qC@&28e(bAmW%?!PK;drAW#AU0u>e`tUtZGkZi$`~-IGtpV53#(H>RFUwn1`Y^ zNDLq9Vg(p>xfTOvT-(s>f@}*h=%&k<OB5pqIb`2!d`FTJPKwJ=wGIt9v1Bd@E!2e^ zd>CDzTNmAjys+dLTUYCfyZXhKVxz@*<1z8%yh=8#I`D&mdyn20oQzL^V>vGbrJ=(Y z#ijMK4asya=ac9W77hY*a;5Ze!)O+X#@>JzG`oWk4Si<lLvD5MD13f1X-#Tt2(eSx zH?skLuHfLzEM2M$&(II*bIKORtMG<O;5S!CYZ=WK+}okYmVwd3xB<%tplz`t5O$e` z47gnZ>~`2bsMFtv!sbfb$K;~>gM*ArGW}MmCLF|SQH&PVSwGdvfNFo6uAS}|GxuV( zSBcpqfC;|swTI`m$zbRaLU<L(78ojal&*&}cU&SpQpFI?sLD72ZuA8@0s;?62RKCr zvw;m4<RoUAsEz>|i#58KgHD*O22Gc~ISrwd*Vp_hhcpnCCdMEIgAZ|8;4;{6aLD_C zy2UV6Ui=9JQQR_4m<?)_WVBy~SS7#0bifU9dZ!9|c}c!#y<tQ+VD0fhAmM?7R|ykm z0|5EqM_`5}K@lQKWwAXsWca#ppD3`g^JxKf6MYQ)gxEhstDCqxEN&KM<mK}ATvlWm zsAUd<T@ICVUSb&o50%ggJ}$0YDqf?rS+r^$E0eC&x*o~p*ljgz3Eo2jXE$ZvM<?{X z^dpDS(2#rl1^Ss}>V!<_&voc>5^TO3!Crb{eK3zeN2nVgQGZ>Lmf<{KEUHUVVX4s8 zNYE15gZGAwosusa6(N6~DOv!PI@J0ag_ta1L(h~c;1R50kcf42ZodUEloAYTuCt@z zn||^V$4}d@T|)<$dt!AZq*rD5ixSW(Q&5c8u(e5AKcKN0ss0Wveb`4#LYs^~k?=xv zx1cwV3IEAYZUWz0f!kATRpbY5i7no;4Rzoy*RB$qxR;7T3-aBYp>ng2^~uW0>_N6T z@G{>^Azj`a9TgOYr((F*t2J777}zORYXb->vNTs6S=`?%=RFl!!4CRZjh}`E$AgcS z*Ni=5_AMQ@gQ!hBD_-3bHJy<@{eDaaXu+q2^;SBoBP=J#1b54|NgvHYsUajY%5SlR zd*e}ESUf>?{aEKK@AM)TT~=@o6=bIl8h*Vr_51M8O65!oPZ)f+2Lv9}`QW-;WGT*z zxj7~`xt69l`IX2=_``O>^M~bSv<5W&%c`C?z%UCrYKwr@_-#>eEwlqOqua7n8|)~J zgXo)GBYNBci@1RF9B)pCorYy|(g_a5Y>9eG$7i!T5}>9@dM|vm6<fVuhrEF15rS2I z6)qv#{434-mc`Re$6OeE+m6AXYT8sWPEgz9n<ypR*2TAy1_hwB8S)N(lZeTdGQS<= z>hoFdjoLPfi4DN)$Mg4!C<tJB$P20uPa_@$n`<hh<PjcFY9z2>!9rOOaqm_J);c~_ zB6G9mMy${+>a%-zdM4DU8lKt)y#adZbr07&Acx0@Od3VdkXZ`(gjS~!&$9)L1vxRt zm;`4kb2FI&)#(_Um3wRzE%>K{8rH{y-s~h*AWN8!k}aTnE^nNLBx`O5Z=?nIJyO`r zVJX>h8ia)q4Vboq2WC;R0F`<b_x5ae8uSkK_Tnrh0dze>M2packOkUk7FEq$^zDxY zxG1l#!3vkwfO-frB>R*EM5=W&K%_c5jk&AMx;UkLBd>~6!w`VYmxLYxc>(}oK%T!{ z!YbBJ(4w_BWmkGD0zoaj8mGI_RU#X&%a1xW)Ve-3^d>kpLpx7D^);R&mUn;5;jw@y z%?oIL_z+0@yk6PeidP=+dUVxvUqUL)jz-#U6dKWoI$eEYy&CF3b6xq&jv%^l>zQtw zn?2@T_t(~$c{glwX2H-E&6S#XFtc#YQb<R`OE=m9)j62A2;G{LtUC9x$BV_@Zdt>0 zm?D>gEIdJR3Orr!f(-csvAr7}93~o6AU*6RkyV0Bmnm#JwVbJtlv>6eW-e(F3aJ#A zaYC_>1aXBs=x1-=wp|CjhZuKcH#9a&lE^cIOlytJu*DtO6B60FG=xg}sphh$IQj&> zkz|xM#~b=VQ-(Xug2gGdK5APzsb5PHI5&f+>r%22dQ!!NOwr3+SV|}m|3u?cgkdAZ zq_IOx<zELpn%7=T4`IFSbaA`qh?p^%^FKwSVK6KNlP-#WlW-Y{sbmSD`%8Iorp+}q zZ9+xT#&I^b4j`v72~aqvF5(+M+8Q{X=9_hO0lu>aCa=g8y+CprV#(6TrBZ9W`S!Jl zr;a26O+g(a>7wg6#V}3h3l*|^i4cT|yn5?IbR94UI$Ht_G_B4yjh${7n%39U9`|hK zSFF}M3F6U~%S3o_)7QTj#VS}>vZet`vTXcNbt~VGEuxKsz4{^CqK>9j_4XpK-|`&; z_F{;zopO=-&hho({{8)j5T!_|3c|VXpfnIwxnEN>2nSw(M;lHam4_J35pFz;y!hg@ zuUDC7(i?<<snSc)5#kY7hRt%CHVFAcWbCG!4_kxNg2qD43N_pkB2P6Rw2u*ZZifa& zDx(0Y1P5D&kqmVfVfRG97%|-o#iC?SM7|`5Um-53M1&%4Z3&VmMuX?M3ttL2)P?&2 z<LgrhnwPqn;|$yun;;^$e2d>TaWQi;A8#n#^P<^>Re5gjb%U00UKG^Zw%<xppy<{N zSD`B<#ZlSW`i!g0DzJ5xSaRr4Ax{y-TGkgW>MZMP4O-e`?_l*C+Q=YHiWMmtIo&(i z{&XLfU>^<E_I*PdYi^C&5Otj>dJ@L&Wcd^c5foli@>43w8eCl;xR}V7^Jor3Jvesf ztkMXE;pKBd^FaSlWj0J!)`Wre4w>b#O3+}I`_|v#@!V6x=~O#b<H;M0G?k3NYFa%; z6jkX`gy(Q9&nIcOdgf5HZ!{VE-q1w#HAR3{Myl@3Kb4s(O)EoRogB=-eG}7!9VpcZ z4Nx&~gOr2p@9&BuHkPM_E1N$<AC&8}2aYT~gVdM3!2qjghI$8)621gvLf%7G<g*&} ztaa+vz96kA9gkO=MFG8qy}Tr&T<Sz3?DRVAU)8*KvVf)Xfe$x2W@E4&-!U6sS^HQ+ z2tCbBb<~Ouv-#%Y;>utSF=L}5Zwm@oPN94Fd6*TZqJ0YwLvTL=VXl3NkMMf6phGV2 z@!61nOX8*F13$x=^0VIcF){rR9OFv%ljcK58S5X>UrKz}$5MbWdRY$wgQ6x_+c`ej zn9W9800PPd+5e)~nZw@JBRqkt5i7&$e>KEEzXL>!KkkAJ5BRxJ)5^p#%vJb0?mV(* z1cxm{8c@-`GigK$o9ffnoh_<qzObfNX04`@v4UgqqiF8D&cV-)UmLhsRG0Pv=kr8W z<5w^JT8M=02*It~;eP2{cuSpZsziF<m3mRnF;S@XCqVm%CdfaP14O*349NBI=MWeo z?dvQ`eX=-cQSD>ZF10?e1X#$Bxu6U;ooMd{-{9neGgYy+TcjF?PQYQRvi*UlEmsew z#QuI{3g+5Mn1iW~2+-{+2dRrW8y}j#X)fQc%9peT=$c^{#jS=K5EKEg{nU7F*^fLP ze)fe9R>=%Pi4i(L+kp==uL?^CiT$7^mo_KYvSjmJ&B91-DaF790EV&`b2Tkz`MMvU z5+1m+C1HgN9xkLkj+X=yzc^bZDm(Fj)9-dL3`^tdNd*5aZ{r2=nsloqh<P9`=$azY zM-eSCqVpJ>LYmt%gE94)xyiD7Kpib%+s?Rtp;oZK2kCPgF|J9Q9NVzwS3TDC#F}Qe zmB;NM$(dI(a?4~I^oIsq$xKUgo(mJ7a;F}{2@0GZ{BPRl!NFw4cJ63|YUnm4&j`WS zF8)54rOhC{_1of#oq^^h#8NRBpjlsmOJY8yEbQxYy#T9X?)d1PZ*YY!jbOUATHh^~ zWB5~T*2rR_M`o&b!|6>SAV#&EE;e-rXKgtv7W88U?!fk!M72>){_M%S#L$cISNZFk zr;Ru~?q_#!Cro$q=|XDF>->!W0PP{az)hHb8|wL8!N03__BBThFu$u6{MnG5uN@VL zc-Zb9t&~*nMO|0W40^4bzvXfTZtLbRk$Kh9?83adT+%Pt&xU?(pet|(<v+z7<RkXM z@QAs3K|@p>qboNzjK5Kq%fHceo`2Fb#q*ngU7i=XC#!se>&zPif6z{PxvHx(9;;c5 z#IgfmLMP3vt}v-wQxtD;jo=40qJN>3+x$4MF5%CboQ}<}&Ge$gFPmmXyS6Sb3idm$ zmhY;Cp#|dpFY^-kiv2yvhYh?1g*wGtO*U_qJ1&|6vcL*$?Hf#q6U7pL+f*QwDBops zh-Oe2(y&-#WRC3oes=yvcK&5{{#ADVyX^e;*|{M&5HJ_n3Qj7AD%dP&P&_1|n4(ch z#Lyyx$eO=H$$>$57+D>VdqAKCqt5c_w9cm4bY5lfW3yfZjc90J)6pCRD~oJ?3UXib zzbW{_8xE#MzW3rRBQPzOP4;$b;dy_NPfaZ#qL!7}*K)NMiSysG2ErPxGJehb*<1it zLhgxN{W7zi5EI8X38yzVJbt!8n^qK0Wa3BXtrPI^v=BtcLx9yzLUtIEu-a?qwjoiF zU=<1_Y)g|MZKS|HZ<)=%rqK}~jx&4<Xyd=Z&eMYDc{!gKz^@dG1;%C0)^)yY76zpE zCEBQ(i5`nTLmr1Y`{ir_W;-Qr?K&?PfYtLwb!Ncy4BW5JiyTOt)2ae|cYbDYtJy9V z?=16o(s8h8y6=c3knT70vVzOt9R|a`xB#&sASduF%}^$7&=ugB%^KipWtbiql3fpr zP2gx}mj+(nnTb?cy_sGa2re^&4-KN`AzlX%@s&F=o8<zUL6bYpVx_iTzI8%CfB*f( zVgh#~UxT+&Y>vC$a)a&+SB*k3NDGoT#c2fzGfT4(@B{jMYf!;@|K`h`>Y7IdOm#o? zeV9}r-*T+j{(f{&1~wdzo$!+se%znY<q70N*$~OFtPqPd`!@mOs0$Z7<{PxX-w8Eh zn|B<7yrno+kF@W^648SCT<#95sk$8`0vr8`8Tk{^Psl{xV18yCbaVhhMLh84#n&$; z+4n#wxKW_6TFZW`@MC#O!g|iW23#ezM~M1?Sn9(HJsf5a60O2(%d(C}pp=3&#d8Yo zZ3d&1r$w`d-+;(4b`yaZl{4@5Y4!JUMuLUR$|3T}-IXPOh}0Ddmm9)oxVdfdX{|m( z+c<{0fXGAjS+Q1Mp)>onhO5%t40#5RNL?fPX)vw0yi>Jdlu#R)D-fC9E&jGKl!kzc zp>gWQ>kp@Z%Y*$;^RsGI%yl8029#=Qv*gXyat2xzNEQO+<5qELO>sl1gVoupE|I|? zD=PnKBLphb@;<ezsIl|BIk)68*D*+<$?-*XdWz{{%&#T?SeY;9<y?LuS*Y4uRjY<0 z(V2S#5|?XAb6wTcFpV#9Byplb+0ECPxk-Sio8_pB+E1Tjg0zUt1Ilhi<Q7s^C~pH= z2uLTPcS=KwZIBp4YG_d)2V#gXp^J!8A_C3OW&7=jnKsE%qfioRwGFt!0|eohYS0W2 zqX1hEuNS4-_{~C&koVd=SO?RVKIXP2uBED+2dAa&Sai+xZ)%FIg@9HyG_4c`@}mH1 zqHV~A%9S%gC(`_C&}M86aV~(!EgSgvvYbO$&;nE<YGOnzOA~lzy^<~6BCRd8@Bp^7 zPlPotDR6nD+B5%LY??Kik5QjIROCR~`!}tiP+GN5&w_5mec0lnd?nwamVjK>I}DHT z+AJK#M{mGw4n*EN?7Bj{Kq@2pu0Xhg`$(q|)R082t`YUGfrQQ0oNsd<QpZRbLni67 zM+R4zTKn0=K;^)7A}!$tm~)7|m~vhT`%w*!I&<9%xUco)u&(WE2-Bm#%(*8#{B?DS ze~BV*+Cas$&|Zn~JYt=;`T!HSF*9%}yUU0^%UJ-pSy!MjK!@65iLpo|_7{T0vSR&P zAs1a+Kg<RrtWxZ$IRRu6d<gYv`~qAhRK_~ypYCIB7zj5jJg(kUkew<3o!2-Ge?%BV zle2D^pE7Uw&2xvJYU=jRf%go|biy)bZr;QHIUMdqxy&v$i**SqckF&;Xq*B<t8>^b z^TS-~U@C^U7NVbZv7+-$T6a9g%=!wpNA5jd;2Tdz&4L{4ZMXX<U5*cuCNd}O`$7zV zJVJjpyvZYtK_}e&p>wJ5pS;pdT2P^Se(^F`A(B?uSbrgk6Ul=dvKEMOo69o@_Yn>z zI{$g3+;W3>0G3k*9UKFF#R{>RBs^I5O8QbX?IZeINw3<)8rb}$(6ICfTy>hh07Aha z>y<8jTAp>2MRH>pE*~o!ddJY-H8SoUWDMh56dFLWEw?8XN3nohpN8IR8uCyEM-t#f z4K0S$C7=Y9S>mNbx5uKYR_;7sYyc=Y8&l)mo!NAA3f>X(Xw%kpK6{%r)ux^mdW}#3 zk{s5y@dU$=o--0_?mPgNsL1^TBD}Z|zY(g3=pDxUa5W<xq$^-=Q2s4s$K^_RdDGcq z<1Af8q&}_irBAL95G1@(vM3g0c_OP$=sUN#0_n|=Mi1cGt(3pI3e@!~5EZ$vD9Uzt zCYc+dsAAbVUS>~y9Fdg<4jlTCo2<?aa1qEzHPsS{)cE@JuHE)Qinz_v^?>C%YoPc} z6^DDy+<YL(I4?m(V^-~AbJ4vtB$iCC4FDyf4Lvy)`@wZ@4iIsbGl<Dh04M1qYEu@M zl499tflG)wztZB2Un4QJN>s&U!|~Vv_X%=Cv=DU@lET8aw--^=e_>7><c$MG9T*=0 ziwXa*n8U0p3^A`~=a5qf!f(x|SB5Ss&z2d{(%Cs#s=iD2WmyucL*j?d8kToJXt1nF zRF3XeraSrie8=1Yu?kU@DN+95ixD@6GF7^-dHynOTou+u07)3}W4s{U^J1P5D=!RJ zJ};WtO;*zJgtj)m;mQWO&7DA_qTf6=l3aie2s?|~B?&T%k`aFc?P!P=IPuAW2$jt2 zVY*pIv)POUVG&Ctg&$%u2*^)XBG^zAL%MI0HIM`f0!`1>Q4x|mBmt{hfc}ltEG0oq zOCu{n^|a{i=k2^!2cR+#IwwIL6XVhPlCT@<7+iX>iu<+ftPn#q0@AS68_4p4A<NBZ zQ1@qkuS{(V1KIQp_cv;o8B}VHioyxQf2z|{v>r^Xx8{6rT6Znd)f-f)JIlAuj(Fbu zJs3i^R$f*>Zc7^p0g88YG!q>6NAm*N9d^oG^(X1t3JPwpY$AKzy^63f%L*hbF+Sx6 zr-qUP05E4$29K&%l#jo|e{&RHcix=8>$*9=+Qx`z<Rl7dRupSy%wF|rwC0t?;D6`U z0whMs+XpNlPzD@h7c*rR@iX36gnI{SZ{UKh-kXu<7q|czBI<Nw4)d%oKuL-5@Qx@5 z)O-Ro^Sqj=Rpk`p6IQqnQO!9dmFF-+USdcTAy@diV9|!}5{Y?)@UjZyjIg4~+5b<7 zMl#%14??4YU!w21PR*Dyd#w5*4PP&3F1R4>iq*99(`9dv)`g*eqqEntUQ8UiO@A86 zgu+-{mg(h*6CW^SMqntM0wPNTp72>4P{74&z&0n|c>Foer#A;D%8X_Hz4YLB8|1Yz zD0wO}O1H9z`k`m9wGm&5w!IOS3ua0H*?_Y$GgsN1!Wl{u@$5fezmD3bYSI>|@xFUD zAp<QGSK!Eqc!!MS<b7!n-iz<NN`Jx-`ecp3g_M}V6w5Ofw2QjmkQdN`Z>?r+_70RA zguKCX5Lzv>X*`%R;wXoZV8}}?XlUlfMqbr16zP)+)}>5RCD35jBYV`Ivj(PsQ*0I3 z`@F~T<~*xOn*w_I4gx7~PaORXZgCU>T6Hmx+(H&V8_vX<HDU|L<_)fqeHyK+A0V*P zQ$ytS2k`BJT==t|S=nCpNNnq+&GGRtI~jw;I$OvGA40ve&3;JB*d5AO)VI3_^JPDT zlvk1DCD4vV_8pPzV#*$-dy`@c478`H)t!?`w=#K#N0z)Exk3>48zrHyaTUO)z<YG2 zo{bp6JD)vi2mKjf7?5Vu49<UV<C1x=r&Wb^CHR0{J|({%=?1lVUX^9FM8{e0C7AGG z^4BM*eSNV!0`m*62waX&qSoN;GgPgr*V4JUY1h?-`oIg=&^2|WSJ`*V!f3DBCjo84 zm<^L$zA7y7N(WID{3fT)VFYZO9J<~>t9`0Clqx?nsFTmgkEP8y2eWaJ<Op_-sj`aZ zeOn_B$+E!KxiTo62RXEWi=%cLbGXCeJg<vHAF2i&;$R}Z%-l!GZ$4hYl45mk8>MCF z$BQDtsKRmjK|9mw*U9aUKm&1nY8oEO8TzlokuzROc&FO2;9H9t+!i|L3Uxv;NvU>t zvH4G^kh2@a2%g$Hno?<aE`bKUm#0@h1H}rrA__*?;Z!owO7prXcsgJqxr%HdIOIPo z1l9Ze`16yVou$G%ZX)Uq3>qS|jce!OtnRv8lxq*^Dj6I|_l$#f>7U&YT@#XzY;8`y zJM%yzBrzuR5uNIubE38@1s-@{Pr-z_v)LhI9WfRq>p(I)WUEyg0ZlKBp3{SXvOmwL zur~~=bq3oIV3Y)Z8C++T(C4BQuDR#b1<=wl6#W?u#=U-Vf+*Z_#)Dv4vS8uCd95vU z+3F6tnI7pjdT8!Mw=kLZlHechDp90QV^z0OdW2JQ)Bf2V6<ik<OS8l!69FaJ6j_-p z8BaL%AF`(z#9lzTii}l+EzDS3^_o@NS<MNmOGHsZGe}&L>6w^<KVuvQZ>3R7FYu#5 zif=H2y<W?;jw9H5Bd5m$)qch-<Uf-k)z2_MsOk?8O81h)0QR1`?9&}W$)AzR@H$8s zGoc($ETiBkBLBzR1v{qf;FbBOwT1W1j6>ZHn;nyS2NXS|jbVV?X)1|X)J%OuW*U0j za8_$Lx^R*g*=8X^N)RQI37ADUC|Q)V#m8PXWlfvKZGm;wnNuM3(xjN(wul<**f+BO z^roy$>Zf2vR(jUOWK55CP;S^X^wT8?%TZtZH?&Pd8@2pG5IeFm>N+Jd5Pf93(Q<FV zPPIU#q#5jhrnDivf$N~C82#RZpT=g;B$2q2^^X7Y@Z|G{FzK^0Oo+*h8SpKahWIxp zY7YDmz%Kd&lUpNkYsH!Q;>ASxJeL>-2A37tc=UNb9%)LHS%^0k56!d}B&Jcr{tFD+ zl(2a<#{J_*cRoKEjL*#2N1xp{yr-GYXFX5ChB=g)fKU#o2c8Be0BfS`uNx9K022@S zomBd0$exP1aOycF<;drpT$ZGEMgFcd$QHGCm|PB1)T|05bhWP_y2;C~_220yMSB+| zFlECm2jAVrkiwi5j#DE)L;Ck?bB62(7fiwZdSf_v-%&W}4rw;~w0u8g*8-{@`)h=6 z*q_*N-W&;=8Y`TGzDfesKmN^~pYEOv9`%p^^3(C{pT;M52K`5qpT_iTp3J95lm6{T zgP)G!-HCbilPUk%cxc^Bqc(3-lRsVFnM}+-ACCWWIC)?yVpGTPd(a<!K5(s^=gmt3 z$i_8v{Q09hCu7Ilq_)QS`Ff!RM3BLL(<J2;U}73kF@JQly|)IghrNMfdu$Y=-oL6K zNeNd(ub^_QJV@6N@7%U(_&p3?_8kxmK=->jq04B&KBL8g7$G+w>o;0}<7lyfAIf!9 zj;jql4-E^8Maeep5Z!i<iuc9LU$^7Jx{9(JDAo?sIiQWm41({2Lj|5qF6m+l8`wvN z3|}ALml$ie)WK5Uzp&rkaZ#VYw4ddKs*k^Oc{WsB7J~p4C*?C%xGSnbyZhF;HtB$! z=!OCmUCQG6b97R?z~S1R|M+v-!&<^f=^?y?q>DiiFIspNzDsrj1a`ksvH4|;BT()k z4F}SzIvp;I<L%v~ue+(fC|GJ|Zwl&;zao$Q-t8@INwS2t;X`m44GgH1pp#6pQbafU z)>4BBPrMom9$N5KE|*zHF}1lOUkyv+dlfXS1uV3mQWSzBiJAtf^-u_pQwr_*iB{l% z4Sd+;Gw0mo>6+|)=($`o6s3rfST3ILP|)J993wU?;D^Fr9-i{=BtlZs&T;PWQyYrn z0eh#J-@T#yWie9X?-5dRB-3Pq)Y7D<Q|m-%?n~XG6G{m<yL>==tjJQ+y_5}jBLUic z*jM21wqIItC_eSk#q!wNkP9F1+y+oki!`cThx){MfXk|*Wy!Il7&^OVdN-J<N~xq` zA=o^Nw_1*fWI>`RJn=EH^9s@=Me!0-^YI14w?fqCPoTX<ge?z)xhHl<no8}me2X@@ zy&W&Pk)v;u369j>vkdsp=@d);im|45CMM1u^Pg;=Kev>cK7ZO}_EhvECx42Scb>aF zdswpRnEr!s`Z;H?DXF(67H#()d6>v0^opSNDY|h3Zg%lDnSX42AdcvG3Iu6S%oa=} zbyIs}zeSsbQx#`~!-%s@qM_F29qQ8MgXCUv3+nKD6o?TBJrti%{K$D#U;xQ{0sN_< zeBQH8Rjt|W6n;wVW->fWG%*i^QZ4iS=;5gCIo&{&<j5UJs|%54^UEA%Qk+N}eEjQd z1D=nH9Jn3vNWcAU=F#v5e*aa&Z-S|c*r;|!D#<$eQ(;qpW;1Qp<r+562_!bNbBG%} z9g_%3O~mmP31ZS?I@IhAf`ZMlD|zCICW$NqUINx6+L^5bHlgFpsWA+aM0?wL(G~6J z1C28QAeVF$VsJ|AlvR_-IeRI#k};i{V!d5XQ~2uKc-V>u+amZ;j`B(|H;h6(550Kt zzCDe?V)7y3GXEIFUaX9S@Vj7(rUG1(Jj_N`(t@j}o^reI>$;Wb%KM<@H2*Vr)F0g$ ze5Pb9$wtVt-|V=klF9j<q-~c41>jzog_fMeO4Upkgs5pp31Pj`Hjkn&E}pqI-SS6C zq8ha~fTEOs+KLuH4jr!r@dsE(m}!zqdvrcsv;Wf@>MU}6+`0H8j<5-d!sq2XTXY!< zD*R|?7F_HL+qztIks*VtBSlr}y=SK+1YK4XqJ%=B^DxZ@A^5=kWWbB$X1MS{%y2~B z9H7A->QIq^<A_as9OIO%;1y9pr~&2K-KPwTzI_4>s_<m&Zg39Tf&J4$HNBv+gI+;0 zG(cM$``#ipW+dE~NOrJON!xW1>Ihu<^qMe!a9aK~`r41tFrD)Z@vh-9aUt_!gjFmq z{5woZH`O}nIPe0NTvcJVVClkwgYfzbF=Gtr_BxP&b3x!?L76IEEf_|5h?2FODM9~J zu0Z(yX&j#uTZ|;yAS8b@0ExCI2N%?dfsUO|u^R{?Oi3re@5%;T;~+u7p0;2Kj66;} z>}TcQ!H6|h^uFH+Df&~^2r-kac*Jbz9B`4?Bq_4>$eA%62EIR#tLLj?uY(b``7|te zIaGSmMtgKt0_@Y1NL;;%K}FXQ0k)-AImvGModk!3T59cQUVfr2qE5jfG=O8Qt0a3N zC*l?JMOK!IANX<h2Q7g!gD}oPQXX~UJ@hrqN_z;7kVd5#4j43l&&Mw^P1Z4LLeN^I zKChV6rDpKDTGz;DcwA@cXxC85v6oEg;3g1Mb9rmkP=!L~R0bXyofv*VxZ*X{Vlu_e z&{PApl_Y4#S<?jw^NvF)F)jhc>c>#3(G8S{>Ke;F+Jd>pC7sGa6b`%7#uC2wvgG~8 zFpcEi=+X>%$kMqn?k5mqk65`eSQCs(?_>fdvfEm6NLCwa+Z^Pv6_VH`gD(cRo%lQ- zzP)!6Tv~hX4i};r!#Y^00r1V`1%v?_N+we#tWCMY{e4Wu<I>r1P}H2#N{qO9o137# zI7<rrj#*OGGmZAFn5x&iJ_&O=(Q?y;b%m5Y>1>?U{$8-SWN;$EfRqUh8giiNM(!K2 z)MDOYmV26&Z3Y!V@)(aO@n5&9g{}jbLWLJiv3)|TM7&F|u$iOHkhUQbgP67n1fxtU z%GBtRTY%mT%PPnP?m;((_1|p>T{^F}k@zcR{V84*#S(Y5TxMU5?&G)5y>Tf+n%430 zW#<o5hJ#5<^o<vZ0oqWk<*;Ku*;XN<+OHFliJ`Tq4mBRh5Nu(hiHrHq(XiN<rJ7e0 zx60;>Ujo86yfn}RC_p?185NuOObfavQUmPWsTRkZ#fNHfGQ6{qpS{q}NP_YPku@TN z+TfDH{S-Hh_QEX~)jPoO!5!dm-|=g3XdT7>j0osWgC==%5~+giGvXMus-))<toATb zsQDn1ydCDJ;6xbKd(YoR{Cs@drfdR#n-8C#XyYbHGo<`JlzRYLo6vF-bw<_$KCc2n zp80EgHZ|?{L2t}|1_MogSxtc9I=^rJT+^3p$*_j@iaOvuyhP8%7s3`%Iv~tLmI&K_ zaI-nG>kyisK{5=v*wfi4|Ljb>w++oNt+VX-rfSM+9JlE2I{s(cNPUMHJPVB4Tjt=| zzJJUt*pB^1+rVb>yY7Rts_)te<^L1RL6Q#U83ms+V`n>T9pFAa-Y0C)-2^$Z#1%`e z4}0x!?6}r0^z>}&?Q>Hm<vUKz6REXLOH0RYKD9&_-n4Y<9a9TLbi2(DeXN5KWUonm zGRaoM^ZR$te?K(HYRKeLdIjEuro^9o6`~&6S0ZKCymd9IQ!849CBeXDoHoz1$z?8t zuB;kd5J&Ax;u}%lcun+3x>v^UsC#LWes<d-1$_)M${!FZ+Mc|E#d!Apw=IkDI&x6B z@nWR<j~65EsC_Y#UK2Ym2Do{$Q;uPa&fH2oSd<Uj79sZfx%nzY9e1on++W9HBwdnr zTMa*xt6A2KAzh}0W_j859a6TP<@KBbGoW_;+<XPFWLk+`<SF;`1*dDZtNZ5bVfN=| zUmv~b2Dj&dKgx}lxh>(WUf!^i_O(s8$9&AfqD?*c<ftVkS%X=v(;9emNOA-*ku!39 zDS77TaDbBP#A1El=^}LFrPEqZG@4W6R^yD<vwIxvtGm_3>4s}<n7Fzi$LfrtDcMBI zD@iy=nQC9YIs!O+{q)tdmv34?@yE#B@Wv~uhtdv?aYyY-mh^$#5%aOPjiVOcpnL&^ zOdhy`!p|-on57f^VcJUD4A`E?;U-bTkVyHVbEYiTGwemv%+{95GzeXj_e=xKC3=#a zLO?(ix-M-9k#1W0weR_JbIcqrOpK2sfAuz8>=*3Vm^j<DbJ7t>IdHA0NTzryHcKR- zR$ju{tg7cMsBn_$)Kck`lz!G+FZb(_im8t&U&Z`vl&(aBlUnoyifwdeZq4@nCYry@ zT4k#A;>fu5A-+A>COx}2Bdk^dVG6=Xy|i@NX&&tD+kGzf+u!=?puw-)SW2F~l(+>3 z_MAjoFh8xp&9}E>XC<qz3_~`zWn<9@`$as$R=~KyCVTE27P8Y@n$GX5HWMDj1`Bh^ z)nrwWQm9!OD_K>RY^o9DMio7W*4m1}vv%6CjRdQMhK9<H1KJ6b!kt7pxs@@tGC)Z5 zA-ZGhd&tT%ryo+LoPOW(LHP*j^2#iMZTYNa<_;;_!`2{Kdxst`IrBuy^;q#5Rl5## zn7BlHiG1h3;@JLL1nk4(uR+1#<t7#Qjy2<hG|i;TjL<8HZ&Sz3A6|5RS_q7#zTAO| zT`WR-nU=Ni6$9I^?H&8k^YOcAzqcd%t^}m8KW!fBj6)w<vg=ZifD}+9{x>bMfS~l{ z6#HVE11IT_RX-mp(_oEgW1oTG2yhJaOferNXF5B)aA-XkMzw?-6avkLN~=icL0Xb# z3($u0`83!De#P{fdBJeOc-or240bN;6Hrm`>c)H16zhMwy$SVk|A@T_`=n?(9eZ;F z3)>d>OCpMp3iY*#*;9yTZAJ#g*2wlXh&Dn~K5$c>C*Uu_9MQW@2()UQ$ip6FBfhm9 zg+1HUg@#67f0TsAi33M0eg6ag`9h#DeU6{{im4>5*wO#lpG<hJKu`elPM_YVPPG-j zI@puK%GkJYT$4e)s18TNK8kjUwl|aPugzGJ%d^Ub)6eJcaSQ6vUmH{JbIfb+y`)t4 zuS_pFu$pi|*4cO8zWgrxuACLirWoyE#Jbg0jiHnKvq5(MkAM8*-7oIl|6O*pI<MZF zuk~sKai20Q141zpD{$-F(gc%iO~&KP%gYfDcQmUm#tZsR9W99@GYi>Tex?fT!4jL9 z70m(?WnJX&@6L<W`h0Ty#W4Hh34g_5V6X<tzq=y1#6ySCIW{POTtSk=f6L$HugOXP z;1lc)(ci<+)Md3XNa&s51X5|CfsR3;z@j&!?AaO-8+4d2F7vBKS|EDk9R~uyCt6Z+ z&_Mxtj%fr|G$xeEJeWRwuzL7lZ2pW_4{h_N?WSVe9EYQ!Pe0TaN-o6V=d@gVCZDGc z*MWs7YtrF7krBmw#2aY!zsP~rw0t#(5s{q%fE!uZ>i@DwiecOS1gXg(Hwpi-t>eVe zA0Q(E8iWf_p=Dzjr_rK1>-U~=4UYC=4g;6G_Syw4`Au5=`th5`TiS$AL6e4~$}hXx z1x<!DJIs2o@=JJvO6fi@RoEoO)<H-QkhpgB_8M#V$fPc)mhR8orIXkIrmg)WQ<__E zX>V0VgWtCFFQ2&)cdY)r!bCea*we488TjBPb`^eHOYlj0|F47<(vXY=AekFjqkcL1 z3Na3`5s<5bu&$47_lMc>-mTyx_6J#i{P#!8b-6B!#`|JW+hY8tsus=u-ifkfp+<(8 zR2pVj2+4LdhXsUmNH0h5aG=7DTBZ(+zbVqvsg)@L>Op5pmu8YP*X3s;MxB^^9Geoc zWb?M9kRLi!a-R8-Y{@=!S|En4s~O7fRgBYBUA{B;!HaJS$kYJboBYg+aq907F2=Q> zvml5n3=eW?ubJy@Q@ACrdki&*cZ0jpJpn8%R=M;mKi^zTi~5>Y?HMjF{)=QIEoD<+ z`UD_+w9bPx9Eh0hitl-BpS1md+57VDHjX6EzsXNgV)ttR7I=Wv35wG4wDsDS^d#AC zEy>mc0gyx+1h6PTq{iZR-;66WA}b33WxJ=xyFFuwRh9P<85zefUM6Nuuw1>tbQn6e zy`^xkb=9(f@7f+tQQ+68(~?jaLX+Vy-2oZjrx4kQSxKoUnQKjIFRKK|6^aH|hG*5| zdoNDb5%6bs^?$ck|7&CQ>B;KHljg}9K>q;tPk#USpDQPo=co4puIEK_#XX*Wvr_v4 zA1lZIJgJ<1b5f~&LG-Fx?VB$r>t9@^+Vk~`sKzz7*Li|=cpvPjvB7?^9H$!G5p)6Q ziU4C;6RC|9ldL8<OT?aA>tJG!;N=4&WLv^%SzX;$P@!lu77E~uNc2rsUC-tza2mx) z^0Foi4#46yto;6cWh{(Nc(hVnvo|FB*|^*K#hUGV!y)YV9MoeWmv;g__GEcc?Bn*Z z-)A&Dw{yI?pl}~`Vi)9;rY(q!A8=9-2*%MjK=Y4?#Vk^Uw1eppA1y?T(4Z2yC)b3+ z#tpoaG}50^DLm$F<0df}4o4uqSpd@&@2k`}*{tCYmn<MsS8E;s+>hIN@8+Y%@XYR& zVX_ud2D4rrQ5<bbfdS^Ous?xsIEyI&7?e%NIY%zoc@>^Ynn^M<p?QQk9QA~KsLX}S zgPv+bU}(Pg4e$uZ^a4i84SE4ZKf3!`p{YJq%<Y1d%DmFbE*GUHnPxjxe_dN!yREGu zmtL*78w899Tp`F>RPCm4Pc1nF;U^q|dFzI<M3Mn~r{#!99D^#tposeeMu_HyK*GUv z`2%MHf!7E_99Y@!d-(*l7_?0X;>8Zd_wtu)VS6ZUC3G{2UgxQE%q;|WpF%r3gzoO; z;ndnzAlG<@scX2gx+s?pi)eejv-~IO6J`y700EMGH>rFO&5gyb(O7)!K%rj|{71+? z_`I7aLYc%wr#oU3$-rA>Eq&y^^g8>@FKqbAI$gZ1?s%Sbjo!ex-n`RQx^bRBti2z{ z-mH-rRlxwM<l}Z7U~B70kwXZTdWgGOr@({k0E3GQ@9IB}dx4>-R{!NL@n1fj)#&4w zD_oGxb+>+?Xp{J#cw1a&f3bi?Nt`NkQkp2>4S1M)7c=xk2lh~$Ug4Z!7Fb6P0TM(I zio={(j`lA`f5cpe`>gawNPHpbv3q~IMt<9l<PMCxY&ePoW`S=TMxpV6O4!rSwc)us z%TcG+2m5be=TQhdQnIb(fP~eH+McaujqR)lrMW`gUt0OaZsyd1UT{$qLQ5VDO7}(L zuR({t4m94wZ9xebJVI=1l}8#>OzBOVsjab+OaYNPg68)S@l$e5{p9!cCjM^ebs;EU zM5@NUD}@|+lAlaB-2YbLpT^PYePB(O)hMyo`uD?Y@mk+DFz}cRY>pJc%3jdxCT~On z(t*PX8p!`{A((810_8ByNWlUbWJL@PA71)J^pi-5yq2C)j*z>#bldde5|<8oC`67y z!BZGY_}kyIdj*mWZ?XS)D!e|gBIqyppx)Cgr-$|wC`m(EwYfsrmZ<kW`|M#$a5j5_ zqT<nRuvFKIG;y{n;B=Zrl)<I#SK8t2SaXa%`?FQXngFDsa$XH-B<TFr*myl8D65Th zGs)k(Yzw|pPGD5Ncd?DeHdgExb^3mdDO@cx1R6RDRuM1u-XKdQsg>4f=_A@!!=ahM zsX-@3Gn<b4dB&!b=nIJ}+r93EB^{q=%o#${JQs{EKp&~pk5H)bcX!1J=9UNL3uL2? zo0bO%+>I4p=?^G7hMjlqrnHaYs5{w@Z(q7|{{Kw7?l#3~sS2VF?(_ceYBU_U9anW9 zybreHJwZlN?cNwr)Fb9df%$`h`0@SG>Ju(&Y|5Vwx_P@b>Y7rOV}5i>(<+9vbC!km zS*F2+!~7%62975Tw>i{9**Ft?z~daAtgrVLsM@ZN0-_db&42_-oDN}79VZi@L==#k z|4smH%l>F=(wU;-i<qcLk;CqrahD@UFbH-otx)kGBH@Yw`mVlc3Osqm{e5qBwR(JV za(#00^XWG)YOAZyYhM6V8?i;NyhH($o}3(`nEV8gCPJQ*lT-KqDj%c?xei|MzyI*& zQ0E9~`J+#La)N-*?wCATfA;+Jel2^UGakQKR~5Z^sqz6ZG-L>$V}VKqL7szf38YIW zE~l3-eT9GtBupq`s&S<SVN9ilFzT|01DlOZ>hZ~S^JJB=t@Ceo+<#Q{$qF>dRk?Cn z`=)jxZQz#`eCb*Ooj%C{4ZHS2SP2DW9HIpAebU0*!pbRnA>jr7>x6nb3W&NbuO$P1 z07IgREE?-`nTFNTt?<rKRk;c9*`aEdciUvslDZM<<dov0cx&d|0DXzk$z$=xb^>qT z4xIhQ!j(JA8qrmk91QsQ#(VTLxmXhi<!Ku-)NpC8GJ}W$D@2(aSFOyKayovVN|3-u zw*iKt8iT(+I<1w6Fg@2Q(TNOO8&IJRS)U0+Hd|?~7~}tdoF258sG`QO%cLQVZ5P~9 zr_h;2;3#Se1o+&YR2@%Q0O_=C=0R%2=b614Qsk*^ZI726s>gn)ibC5z@nC6riX=`; zrFBR1f@hGiIC3-#9Ftge0<LRt{exGb{n5^Ktbig=$Jh>J)y%!{dA8x-9mls^b^EsA z#%8RDB!6qBUc#5rCr1~nU1M(;2#7Y@r8*P~V`WiZ)~cW~$E`DM8h~-C2ZH9v&i>pE zj%LAT0P3nB?NnEV;x){o@~<UeGSgR|vV4(suDR7vfPm<_$;3(v;?zcba;k4m#hd7k zk>EuaQt`d#i|J|u@6_HJIX2lJ1m}O5^yPrn`qE~&L_9oBZj3nG%y^V4sD|+kCqwco z=nS)bs4tDl>vj4B)R)M@8uIqR2>^FsXc@aQdJAl@3J)64d3Z$SqNBx*R^n2M-nnqa ziIqZoG!8_!;DS#}Eo!Mq2u0-bXd6g^?PA^n9CnnIzbA6WK+;i0B_hUrDG_m$xd<n? z9K$bz{rx}%AuuNXe0fjS1f%I^jVSC_EyN(tA{6T)CGZjiJr1TW1JBDy+E$WNBFpiJ z{Bd?I!|~ERM1&q_^j*p?<VnD>71dU)=TvY8|N7TyuX7t=YwMCKj!1okI|<9{S(jVH zVou&$eM#Gigc@OdpwY#BE{!mLJ8Qx`^wgXg<0W4{Wdi;FwR6V#=S`ZOlY3Q>#_B<= zl}}1~dKaGG#V5Fkw!P34f9)Knk-Cf1?ZYd~n{S~J<rD5BIxINj>GIut7pBh)xfQ9} zjxH<2^;ZCh$BLdrFWCWCiABrBu5&40$rvk~PtSd@4_AQNJsVz3&6ro!R`6>iusN8% zVwfdAl(bS?{k~nMqS7t3K}s6P=+!jSP)DUJhP6<WGWYmMMCY-2VvQ7<6G)H(rH@vZ zn}VLovMw{*q%H~X0c61Y4*SS|Xa#}M|0u*<r+0qdMHM3f^C2wTRSSalpk+9j5Tp4o zh=Ovu{uOU|Rj+eLkU<+QkS<AT0r<p8BPuIKxbGS6jZ?o<HG8gNc==)z;*NRqgW(-r zAq&ej5^TgBdXVNz%i0hslPWMtRM<l65I#aR>Z+<oA;@{iLISRTsjhkjtGT6y1Pg7z zX!oh*`vwr%>5@Mju<4^{U<tchZy5vke9zq1+(kHj4O_>nm;D&-=z8Pg^<AH4pOi^P zGqT>ejqe=ui9%`=i_V!zVNk;hgS4dGqd|&66J-N$oKHglL>~{YbGWOcew*#cJc=G? z%7NB{P-l)P=XpYuQ-ScMCIrkZJ&aogogO(tfAp1;1~mwTHtN|H*Ld7Jzf+wA1xE!h zEN0sbBkOe$ToRmY3zxIy%h7rYDv9mM7B1_7FN@U{Y&O-C6D7p_i)5~MqDx*;B;sK$ z9aeNlTer;?4cBUs3W`lc2A_-OA@htwHjHVA3{hkm5>~4<46*x7+l2&(W41R9?oELU zF)RsG#dfMb?VUZV4u)4n&nols&*E7%*LRAdn!0WB12Gxia}SteLLBR{*Afe{9E0qJ zqvZ%(2uaVX%wMpvIpp>rK?7uE#@zskknk_}CYItf37&34>lyfL^t|Q%I|Em$HvE`) z#Q4>{loZc6(Vd;3{4%KiYMq}Vw-YF3JRDA5kpUeQ=*>1S8_yX%>e;&cyMlSjyj6Ua zi+ij1EGcglXj0KvrOby#Ile65#PSNQ1I3la=Z$??*eWo#608@UT<RHv!G^c=TxXAA z^&TF#XIZ8DVY!P{dKmsci&eS+M98EqWRhOTt$Ku3F%<AfS*eECVAIQ1NUxAQP)dHa z8%M64Z_pm;dtIs(`5RSaKF^DyayV;xtMs4=cAN5}m@XDyf-xO{hF8AMoL+hA-0;QS z11BT7RF>0&9*wDrc|q{Jbtv}@zvCFMw6P}Ls}cQ$PFeJ4&zsA};B8R;0Hald=sUbE zpiU-CgY({5A5D7)E-_R@r+BJB73!}t8P_MB`sA{X(ChAxZp%HMyYa1K9yabB6andi zE-Xf?V>5tB0#-9*Du8Z^<-*;y_Q>rFFevP{n<d9!;newvumcqcc0i;F6C4jbuLGt< z9D+|k_FbWFQLq96S#HR*#>T|xao`>?$!s5<pj?VDwh2f|!KAj>uT8xI<nNx_&x7E~ z_x($wv;-a#h{kkqJ$57-@}Kv{`6MpbwauMHlMJySWVxtBNP<Gy5WefG*LSPbz5dx9 z@awOE%Y1!)-eYq%xdfY8JjPM+ws&gCL}8m%`n`%abp~+0WP3=X9Cdd|Qqm-@!E)!j z3X2>$fxXZc8_LPnq7YF_`h7;N-HyNEtjED=bzj|i<;J=iHf8u$s!uaAPA>xp-SrI% zJyw_fA8Gm}#B><P<<K}<B1qVz6=f^-+wR08Qh+HjuRUTRr!G&Q!06!!G*IRwXXt^Q zBDm2IE}Y{^mqRQXJa?cZ7V_i%^>}A$sJ62JZ+4H#fJRZPs+GlKOs4pM`y2J{UW)u3 zt6Zns0cee1^DN1{2n0LIF3b$ZR{br<DpO4b1OEu5Ee~>|hTaKpyTC1y5q%3{3$sA6 zH$j4(gZOX+i@{xEdSdh`MUE-6F;dz00b<78KBA0pQxLch*C?^}!S9ubAB-h0968!B z3YkCK@HBR(Et%cI8}21ugfTEpwWgawhBoj){H<I~@MmyWCLo4>_Z$SN9WTds86E9c zP4c%}xW+na9}Oy9b9L-*GI}j8AJrdTL(+#H*_UX+r<~<8dfwAL7vZ?7qcs}Ay;(}C zl}j*vRVsUdG~hUR#=@^)YzH0z*vsv}d%y||5BF4t?0(ib-B!I7E<ykZUq!SwG*Wuy zlc~O|wgt8%>V;iYQff-%<(HzHMPxXtF<YYM%MxP6poL``31*`l$gBB$!8+SaRVq(e z1u4Y5$VSD7(g8gI1<NFF4g%Q}pkq`(FeWGhA(LyrTMmFvayHJ^5us$+#wiQ!QqX#% zIRgre4yOrA3Pp(g7Ua_O(vvrpGFWL<&c>C(>|lSZH8yXkMq$W;6i*+Yie5?>%hmw6 z1dIVTlr!na@7G^{PtlVQZVpe!p0e}u#|1S{GbJ&PF><tZThkK$?0Q_a>;jZD?N`vG zHua&FU^ICD4D8m4bZQBHAZCC5fTo#s9he`P-B`0x+GuPl@*Xkigc}+D0Zpj8<1moU za>d4bH`7qsNaD%*Ed*@x!ONePXOjJxDXmjDR&-HFrKe!6ioZ}kbqjQia;u(2G{kl2 zXU9sl9P`=<-RgnfNEw?UVxn2Z)W1kg7}#%3%;9CpUMn0vnp3PT5P~@XE=~uri#16L zFOh_mf~)52jhaMZ3?ph?qm6I{KHuVKD;XuYSPi6T$6Un7l!+4FUy>6Y!JgwlSm)}{ z8Uy(XJ2%J)dg7f3{BwwyH5~*H7HX9Ca+eBOG9#1MC;K`rp)rnikR8(a$?kir5k*hz z6c-DN_;CwW3Jq7`=v33SAqcm7c7R1?$fGj}x25`|heTP<8N(1eHbGQnJr4^blpdmZ z8<dn9jg;LG2A02*!g58V!4@r08cDy3M0h@80c`l21mi5EOl+_m7zSt^!@UkTI;6%r z6A>lBIdW(OcT)E9OS%-~J~a2RJuN_)8-N3rjkh|uglG<{6^Q3jsoPDF>zI<+H_Wl( z9tqsLmDPB@9g;6;7%39j2xGp@NhG#ajHX~(XFpja+cFqN8d-q0rGbwisHLB`VQBZ| z4?U$a2}8ceU1GorEK#Pf2<;eJp1=v`T2k@XaAZp2=)tJ-j!|@`KuqqLy;4Z&a`&yt zFCWWcQ~3t!SoX<n5L1;q?**PCxWHnl53@ClZQH+hU+h`}7r+$$vo=W7%>QY-Bx?Te zyHx~FB9=9j9e76IV2m82LoNXrkxCkLN{LN1(@VC{!lDhSFT9x@%ipKBGdAp8{G3?t z9Mr_H?Zyi2ZrshmK)7@lMT%IX2K=|7=@it4t?@;!A`QS31AQa)xd7;9<{V)l9F2-d zTD}1L`POxtMh>n%t=>Rr4-DiYFh6x{nGGU=1XKo86j)4q9H-g`EExA+pV(CetP$Kb zp`^1&{RGmy5Ee!}M|xI;#`;BY)d*?dh~31YijIwdiGxnDL^qU)YVzIG>tg5`Uv}F^ zy)WwAU~o`1@XGU`IKewK&tA8=RM3;^w*^%xNc1D^7pc6f0b_?OODQM~YTj@bNfXzb zxR-7<x9YeS0VYei+*-}q*DL8%bWcue!fnrY<<)}+%3kvQ_=p->>_2LKaU@^hKWl{) zSyOrP#vi?7ZZQH;=v*;Ck!TZB>lBfOj<b`=$@pY&dVd{LCRQIJ#rR}@rF4k}Y10wN z;ZkyqMm0l`2J6P1YHwvg^Qu0NSZ^sC*$80<1c2*j!Yh9RE>CW(dnVag_o6rOl6Vee zM3a#Zo09k0=y`UNp>fXYb9lP(V#RQJk9${DQ@1$=(_fZUcl=i^v)0f=EV#z2Aci1y z2k2HT-SD_P{=vJpmC&k6rIwUa6`JKGoWE<UlGM($DG7k#CC9#v!4QiT#s2ivUb-&F zn~>6_`mO=*;FkgKNVt610Tosk3kjEklvK<wMLIDIA+TQ4L0+c07VZ;E2?lz349J38 z2{<FMtsijo(KW9cepZm%0>{wGsNyw(OZU!ZsH^XJc|*a)v=$jimn>|YBaBVRHcXJt zMj(}xrUcNlU^bK)n!yCw;dU|;wX~deenjADn;G-5T-OvvTtR6~2_bbXIb0w|Qr40n zA)d{R#z+Am$)+6y{gPQ&Wu->&VrtYG`r1u*g7SKKu1cjveDfrEb47W-QBqYd&a*Tm z5>Um%LDJ!${b50Y56$+3L7A{NukQbPMV=1s*U<=Nj&xRP0aUR52^X$O&^`tQjIRoI zs{Aec-qC`fzT{S*I+2qtN_+!c8SC`XkOJ2LhC~76C3TddKmk@7tI+|-1<W{>jp2!F zOVU%swvL<Y5^v8!VbTMxd#DK|!mZs<@Z;%4_Ls*GA8fJj8+wxQz5N<tuSeryXA1Ej zfj#v3eZO;&oPc$r;AD%D6gVBbt&w|~z%@9x;hHhZHr?o=VUB!JbX`p`e)*()OKR5F z$7_yxAhfowTqT7>+@1xdLVqR{-h$$sS@+6}1i;i+ep^$m2ZmStrLy~Xk$Okf$_11o zEu!th?x1scgJ$>4h4u!c>BJC3B!I)|#J$(h0%V5A6wu@fwDBIRS_NVdhiasTiHh}f z42uymSxU?(lOkuv9$d%4SW<VIW`L3<!AXn`r>-T1Z#qlL_ok3Hm8kC7Iv#SzqrqnT z{v~-8fjC8EkYWi`$$jkOvo2t9fb<_2I7!TQK}o2mX2~4Sfq$xTL(77B1cp~^LBgS0 z`3vT%)UyY*njv(&5V`DGK|Pk@V`p3If*tW~p+7^ykpa=T2gxwE#t&|mfWp#iZhQdF zNJ%09)!O2#nu`Ri{sbH9zZVp^sfri5*2IeQgCSV$LG)ad*%F^BD%0hpYomqy)bzwm zGQ6*Vd)an;wz)ZUiSONW|88roxi^NQbg8u=n_ZS)X^fgV3y|`;<~^CY1ZTudnN<O$ ze4H$LX%;_aYcG$h;+MapW_tDWqcBOSt_#|_yF+Yv`vcDR+nT#rfSkDLl!95~??E1C zK)m7OD`ki$J+&xIUMTgV1dxfu>&*Z@1B+Ufq2v&L2-UD@;1xPrUa_meAi9ppNVc@_ zuSEbYHbt(1w{Up2mlL~zlh-s@l)v&L7wYfuCiJi}&-E924#^w}nht&$46g@30y;xL zBojSaZ=#PE#}A&h&ibDnXJ;YGjO~_*OzbbwT0|18UPD42jd0=SsKw@kcC@wvWxfpg zL5g@fySC<-Cj{Ap%~pU2epO<%V6&Y@&?KS*dZnOA@)+2n)PzBDo+^Nn;{DKG5u;Hl z-p^B34Zb40G*S_#Nr;OgiW45a>ab<LUs;`Fo1>F1n&C2vQ#QxAAzFirt~Yh3MQ?2> z-8BRjIN4M7*5H7fWMml$mQ>GrR~PP2eHE}IONkY(lUA#GUorw%Z-7?IEj=V708Bu$ zzu_gKJ+uJZ0o$V}_AZRyoI<RR!fonUO@|&^Dqi&ssb*(5x#kDE-9MOO&tFk@V(F3# znTaa7(a`b&!$Q5V4JR~6ORwz(w?t}TcJm~<(=RT_4rPEV)8KOk2m`G)+P<MhJzMxg zPu&LKh*#I$fMsVfdS;+ol*lc%6A6m)iKTMll)B*#N(wGmF_ztR)#nhT0DR^#zNDIS z&XKDOd_3G`0!yY)x3avOI#E0a80-mHkfdITaI}$MjG8lh#LDFZDg3HAiErn_GnH&K zxcDr*&kE|8-+P<Q6Au0-Z!#lLT6B{|nf|PsjJo;f++-;rGTdzBt*+!B%ke~YvJT?f zG_$`ve6abzfBz;agkS!;E%!SdY^e>iyy$L$ZLqw+blswb%`8r@d(#8i+rnJlzlX^) zplZ75jQB^4FpBe4+e#2dVF&0>qgJPL7_rA*sI`DAR<W{FiIJN^xDaPn#8la;C{arV z0{FBxDzk1qZWzArwmx;Oz33;@(8BGEf;-d0&I<glJdY426L#n%>NiSb_0a@UvMznv z!8L}TEK^QL1ZSp0M+xCiJ9ZT4&mifCS5!xpQlPX+h3Ry`bY5YxEGs=V=hNC(v>-xT zg&TCjFG51pvqpo<F(@vGWar&6Kt1Ncy1WPK*qziP2u)k~gp3K-J8ktvEWez9CXQtm zR%u1(YN{80Y7-C?QBg^E4lGOBtFL?3jpJu<9byC^j(851323-!%oB3COVfA2s_cAT zE|~N1;<siX=-!WT9Ecf*Ez7~8X`if1JW+@Yowf@eC&6#0|CvBhl#xpArC`fuM0pfc za0Vz!d0XT~MU_^c$GZB2p}b$y`Al8DVuK=B30YAx=K@AyMN`Zbog4U6Pl@v5^WJIf z56R8KxSH-v1*^_RnJOSyHP^E~+w=!Z=ImM4k36U$!Ex_Y8?CdkX-S}-Qm>&x-Q^b5 z#dh$#Bn+lwBZ{?XeuK!%8lmM$@tZH<R10Dkn$glJP0#7vNu4#TMQV$Kd(NYK?x!|b zlgr?q!|0y(;SW8}OEx()N#@*-iJkbQYoPLk68fO5%Kb<_I~zX-YeZvz=*iHxj_Der zKJ@4A+1~+de}I9Nvc0z<5durN62Ybx<k+KO4qP+({~>e9ZXT{RBA{a@Ya~4!PQ5?8 z=(XYAM$Qa0vs5q{KA2EFzjV8!>};$W0UQOHS3t}Fl=1^v#mecWyCufadpX9<WZdcj zm;dq18w(ZvfU4j=9XpR0e+Al1dfkb!cZn79ueWmzijyEkbF7L3Iucyez0<wBJJ9bd zkGhUF-?2zBWxVRfnqfBKXbDcFx#P$CeF}fAo4<z1cCtn&=!a>J;JYKRiMei#J9&WC zK$jv!#kua~{;m!xWvJJY5Co%hOV$79jbJ0^kce6ttRatRo&-8k)GNUPYQPdPZ%q2& zn}BiOLwBJY-bu&9Yp~qKNYD`@2roL&EkX%WJ1vykMbiPeT%QexzW}Cnu7Qt96#l7) z+t9~k>3&LGBPGhJd!=ZQEEB*iaDPUM74ZAN7@(p-s@JsCX9mUfio2f;RuIDg3Q8Jw zl1++~Rf$ByVg?3Q1YtDH#m3fnHeNBzdW2kV<zZa<fJXal%y0&otTct+h?Zugwi|l^ z%Ou3kj2lzLTu>`gg^^4(vCvkYKO96of48xXLu>#Y?k0Nra;>u@LJ5v+jyMBcJJDwn zrCkS8Gsv>{)=c%nU?8zRBCUi_+e`}{0v#HHM@^?=G)<i@+*4sUxD~=ka}ay8?Cx7Y z!!Nmn+Z!J@EpgRTC>ir_*fH)#=_Pw><`sMP#jgb8;4KMz?D5S<a&O>HKy}K}jU2E{ zo<Hj`&2|5-pDA1uC^H`t%?YTXl;dxMvwXCj$P>;aCPy(PijbOO&=ZwEqzQICHi>4d zbiMK2zex2p!Jidbc6n(jh4Er9+IE-fmiQASZKjx77Te2Z0=L34VFJK`RK?6^2HQxU zhs+{k^cF|s+LuEzIm|Hv83a$C4*K1ky%C9-%2re~(%t~&0G*GNc?E%WZh(L8P5K^` zzq7VHBcf?kM#PsD{Cj(yIwYUXp%vIOuRH~k`p!Qv%QOg_P$HH_nzu;c+O#U(AwsR? z$kzdVlMCQUC9*1k?DMh_BGsCiNMqF$G&h~0J@nrdu<ne^c?Py#Er#gh)9Rg-px<T@ zM&S0WRcN?%E#V2r2l>Mg7<IKaZ<!#{>m3&f@$i_F;#{<Q{78mU_@@dW1EqXYtum*b zZEoEpL_A-7ao1Jn8|N+2a8XfjYj|~?RLLYVr1$Z2D%)Bp(PnnK4g9n(*k4=Q=C<mG z0gRC(?QuH<4-%mmi^uib&}*?z;5WyWZz{%)DNZhN$-}E--;mQd7+=8vW3e`*EvhIq zVWI)QPn&#aBk@F-FMSrNS-g*t0}|(wP2*csB9+1}hAahZf3t2%Jb}#G)4Rh!)bkz( zfy5oL=6@ddCKhNuy!o@D%)39P?Ad+|oh8rzNei6dr)WLcZViBm$5iMh184KQ?zrbx z(|@@^7!tN*2nR3&KApxhh4PM-CsE!hPxV&_lmG_82=E?&-OJ(OgKq#89<T*Q{;E%C z@0o_$pu|8?S+I=~lZE=U5FR|GPl3T74ko=xubVG~?k<TJgma&X#ZFDS3lKYZdQlX1 z|Biqa=7FCF&~wCdV59+@fBBb83FT=QxRiR<9klU8g<P-MZ)6^-ITfIN;OR~HMpY?b z?I`6(wv7b1aykc9qh@3y)+*$p*1HTcwRnfcmq%`dLjEp%|NIft13Lsoj9b@^B-$jd z2rM`Zhwdg{$UeHZU$x-EkgY(%6&x}_vOuj3B84moIV9%1#nuOMRnDjFOOV<<8)d!D z&Pr?L`5I;7tg>)0m%NL>JCL!(BY$WtKG&l3y8xeiOIEiExWj8C2woRK^=JonC`ubZ z&wz}jHTWDCxknM&Z&^U$3#CWb=!rK&g&4_f{nM3j&t!edg|08($%I}cy!5r6>DYx5 zSca~odO03@fuRaGV+@Vt?grnFbs~tctc8-={Z0ZiQ)ZN&oeY$m3Clr~WPG1e5UC{3 zDvW`ox<hWuUN4$Z7|qlY>9CTDP1Ut#m3oLLS<fmvD-|IP)es$$@h#o=m2^LX<uGip zu!nq8;(-M->&o*=N{^dN>Q+pp5c!=d^phR_LTd6KIqSjPxP(%4L&*9-C*0wirVw2U z-*|WWu)aLg;F&K^es8UR^PjT2W{ol!Efu!adPUT<mFJb(3|jF&a?vQi?DPtmaM-QH z62YABJoFQ>w2qN2rT5^$=BYhA1X@3ycCBH;wfh6$pqQ9+^tzkp;yBABG({btDKDry zO(9-rQL??r0HRwaseb&1yLXI%+K%DV>1oO4!;E(vTM_i)SV4Y0F0<T9^^%s>RmA(C z;@ZfoW=20beqYqn)l~`im#wb;Q9Y#!OkZdEFq+=3u7-}fCeH2Xo0m}^U))>~%d@kB z8*n9iQPR;-Z&7kO>aG2T0r9zUEav!I%62e&Kt|_9Aa7YXx-q$X_2PM@R(8fFN>IsT zI+?0mQQp}z!rqth(&He88LY073E`Z-VW_zTJ>IiDOwHQkCWZz0ydw7~M{-~U9LcGa zEy=gtygSJ`<c&LBfNq{mAxJI|O$bSG-6G?SY}}o4zze=pCx-)sAQROSd{+H1eGp^r zY@@7o0gcepZG!O|I_5*97M*lc!ku3}$UR7AhokYu1w;QPsKdP;=vfH`COX7rW5512 z><y}J%)L%!{bcah_2BXC125iLs1+nNTCio`{y!kx@>7p<<UtiE+93g4GGgQuAsJdl zp$PUPmR%L4PJU#owKZRBbw=<)Etew9OOQ*EU@9eW3N<V)bP9P=f+rD4mBb-5awkeF zaRqTLm&%otl<*F+CDp&*B41i4Rv(Aylh$#hzTX&}&&V=aeCb77|F$@LcaNFJ8GQ5U z4~rJ-Cnp&W!0e=Q9N0f{(^zSf6g4-%05<;>^&zYUpFc);mGgiPYLtuP*>Hvw)NMzh zE)lkCphM+B1}@RB0|Z3@j&nX>C!~;^0No?zaetBP($ZElS>@6aAI}(~IKUZlR1CPp zSa=91w5`HvKbcdmgq99P7Ylqd9=5wV$Jr*b;EKbqkLMIW>IJ=cJ)2d@LEyZW8XI$p zmEhB}3JjsIAIuvA42nIcaZ`#QF>YP>v28TU3dRW7gQSzP()MdL{B^7UON{czieOXF z0Nvmc7k0*Lr5+)l=EF1!&Qz#FiCuVEf`ow==&{FjJQYrzO})I3G~k86Uq8``%!lI% zS#x`cV`UkovF^F1px!1`vR^4;RYA4NmjLC#-$}^469=o%!Oy^_!~oJK{6?r4`6Cq~ zZb@}bLGYXR;C-Y~xfU~h3$bmsm*<(S#qwBfb{6{hdh8g)nNnJVt}&w!W!=9huEvsI z4qjgDQfO3-;3#T`&H!TgQcBWmWc9EVaql)m=G)p#+seC(w+pZ&aRe2=z|BZSJ+1vu z9WdE$s^AiX0;WQ!XVLVZsR!@tnwDPPlb6QpW<CuyL^MG~7a^mekKAyy%~YH6HYL&^ z8fGAxj5n3%n@sd2#E@g_@PTq~$o<h0!V?wXb?+%P<si_{sMn^Qo~Sn(r#g*x6-j8- zx4-62+i_RF|9_>8uC&5y<`DyqH?nD;0t>x&HT|%EnEl-QrI+o#c?qrnQ1}(-t~=dH ztJfzN7-rSMKQFr+UQ6`yiEl)Sg@>COdp9lKMeXcGS5f%rdh+AMHKceK^{jv5nkt4K z#ZO6-io%UJ{s#Ae(%Z0pe>nJ5W~`xK17p4ZzpwL=y-G`G>mdq8J=oFIvtZ&88e7i@ zuZJ1~X+E(9NIioZyd4NcMDa!-@K7i03V8(&+msZR&rT+-S#y67=8xw^R=it<yTf4I zmX%X&Q1bFHYcw#hODj8X4JIuJ5{&4y>^Q}aID$qyxgKWX8WnkbWj#luuE77J(?eu? z@V#?YpuCYjxn+3S>vXyUK*#L#@=?F_xe25WAt8MzZH}|y$N|QFgHA$B?l!pi_CKRY zb$FiTp9gKM0IzUJ^6(yqezdUQ9r;+xUV`feYWiJQTM*$Wzif5f-hfg~2M{TEH0rj{ zzcmzyb-1mKU{xH?DA<;>03Ljs)*M4gRiF26AWrwFFYbsT7mOg5sOxUgK4*u!D6SC; zT@D#C-X*vuS9$Of$eY<Ss9Qp=z@Kb)pX)E)M+#rDki<j_c+a!CH}=lMK}d3j(e)a2 z{$mr*W}m&6?~V1%L4jFY*mv=M@wU8Nt`4DK%#jJI!IjPl<!I+-xP1IU!H7h8Ha$Ba zNv*pEr?PKv*${D-=@l%XJc!AdzW#19G9`gqNJa)B0)}IEy5qmf4u+n=p9ey)c0b8> zg#!arqIC5D8jff8d<hzr7#4@iDPlD;;36uxEymh9{Ss8O!$rWkL-9aFzQyn9*{>3_ zP9a1Pp#}u83%qCM#7FdiDWZq!F-~;l8MvJt|MU6jeNPk-b{k(kKR%gmZfxwGOpgwa zj!y4CJ2_d0^q^r8)D{BihPO;o$br?9E4o2ePEPU{)k=0hP-0dRe5usj+e&R`<@lc~ zr}tMXzGO%_9JkzUR+<KO@)XZrp;%(21&R)}o`x#wS>>W9wgqg32j>f(8#r>o{UaVX zR9gt#Lr`*T7o&=@wx)$+f90Af!fY|{pk)^nE<<mMdd_yIj<XwPeYYU{<nK!*<8c#w z=`uT4JK$2Xl7UZPz;#iMjyZw;`FehQ>5s5hKOa&RTsqR(crf*F`%>s5_l`CpF<kKi zU}57+t`c36ft!yz(O5~hU0duXT&25{HdYITQ%wr=odKtXB(<=;<U)-|4WEb8EN^}4 z8sY9}-22p;be9*=nc0~Q{-*ixN^2BxlSuD^4ApO9M|0lOn(_CEu#>s6KnlPK+8tTd z+L}L*L-Z@C$}#yNiqEs^$+f$Z!;bzYwQ%smbB+bX(XHOME?&Aj#tmsw-9HFC@I5<v z5DEe44ZM6w#oH>OTg!|aFHnz6wfGgsKq{1H#6a%~pQ`~T<*jmtHp49&16d;Mu?qQG z<-WkFX+~}h0{!{c`STKoqnH>DXdEy)Kh<b?&<2QR?qL?ZV6WKYV@cjP4ek(XN)T$^ z*JN+lHd(M?hd|?p_^m2u68DTJ*xD3?Y2v@u^642}!m1mbBU{yL0%&+Kt!j=i7A3<b zowB7C@7+kQ^^&n?q2p!W^ZBBU<zS%cn$R1dwQbd(LK4*yxUkiRR?fdEjgd)`neynE zB@R*|yGb}JE%|_$Eopik-9{pDipYP$Axe0<Uhs0O+!7DE=PkG`15XA7Qj~+|!TH@= z6fX-C0>59rKps?}&D60eC7@FC#pc{Q*-T4s^j)l&5)x<=pfgOoE>$0<icp%wFu#Sk zjRmEs0D(Bd?2dDHDQTV2QpM1q5D`@944x=*)Ik5_lvtj(qLiaQmp(K6>J0xoAA>HA zXPt6~Q(j1_-ULS2aiW2zwYZRY+2Ud>j2}|zz+#Ns_3#AFow!!RcZf|wav;Kn0LOMx zuE8?CLa^~}w}VS~&LB%@TZ&@%wIj?z;JQEES-KsD2-sY&lYxS!<39Hu7o1<E?mYzC zpbvGE>|J{}>XxScn8W8f?car`d|4aEre<09h?j^rlSPwQtj|*|l-N!Xqy@Pgyv~Bm zL)ae5NMTh8Rg}NPPH=-DT-WBfFSvxJp@kuvZm*%2_EdE3e5G2Yu$~ap0^us!vb!BK zN0nZ833;#Q&1<Z6acTeyL9+Y}e+Ac^!rPEyK+NcG%<mvk6<(n^06mg|wVo9eUkXn_ zFP&l?`YR$PRSQeauWF@sw(|VnGH16%a`4u!h>RuTncF}w-SPHpZ4Kei-Q&A(rJJ+C zXF4s<-O+a<orP84oro24_sKY-mS+iOa@7~je||a1Yd}VNZWvY_>t20v@8n%={Xz#! zN%)Wc)|n7k84aVe@To<CJ5uzt5a{<eo?FWXJfQrTf)<^!a7_SnP$5KshF~r~9ocv( zRt6T2lpPC=cQqJth^;%Xyaju00Na<7AT}n3r}wz)bkWwhXs1zJ1q5P29ij6UtwG!Y zL_wi783%d@gUs?6lp+A{Emq_%@fb-f61{xp;OW4^zxhapS&u9@@Wx;^;`%rL$}e3H z-A&`hmD1dN_>k>e-KTEe=TEEfZ9~5B{lkI*uUEnJ{e*1&PmaHwoSvMnu0E%|s$5}0 zhJPMoINfi)@V|fMZCy-wl7Cah;%hIe?(dWJll9sQ_s6q)p+2fU|Hge-Kl#Rfggh?S zm#WISy86W@#Eg)l=Kkf@tY7rft%1gHPUz!v&RT`ezWBn;laKP2Uda=Dk=orWX`X+A zX8ctXx!bQM#|k{;Mf_$>Xrc#mh>mGojw_nSVfv^SJR-dDUNLxkyg@pA^+Hv&mt}zn zYaDD0eFd$kD3nxyLI<;Z630>UP`j-U5yA#juqrw%sAckrOpAiN0$mym*YPzBl{+Tj zmISu=VIjIiC#&ls1TCN-#K%rlabe_LwGggZ9Av;e|GwFz_hIX}B;YVJ!<gVJ>&Atj zt`i(r5>{f#ON=LU5St9WlVJAAascip6Ox-svY8Z61^xPCj*s}zq+!Eb-0SmdMO>9g z2(n?16t**y(0H2t;Fb7bdwHQK(vGAVLTNU;=4DfDbc?VVhIM9BSI|OqCDGC?{f=V2 zDR2?f{^_8bw_Da+k_B7U#)CU^2sc;#CIUkNCVCwsMgChZ__0mQPWE^v%M(q4&($b~ z$3$w0Jy}7vs=5NHS0tox#F^D*(W44NcGc$XJ;1?6RNbzZHNSs-@VY5*ZKP)Iw-Cv} zA|g4O{SmVI=#t!=@)?`<>%;z6;UAH{{?%7NVuhULkeeZm(jHIy2x6W5=6Ycb#5}U4 zS3`T`O3KmiRbp&Jf~1@gCA$n7ExzRusnph`v#%IXV#NrHjI5|`<wSKy*P|SKcMJ); zHzP--hsC6@7(=pgH+T2(O5HG%DN*kXNpH!-&ye%_Rj)2*$ajvWXZ>C~BXxORifB>r z|3I|gmIB2Qcygslhwol7U+^V!oQmV4W_g`xm<W8)6vcPs&9)1cCM^weo&`32C_tOQ zBVltR-5p5CR1(xBN>sq2??w*UVSKsnmI!)4tuvj70+GO@!Ot&eL=D%nK`*~_#Yi~Y z$n-=HPH+Q($5E1!jOv$-*~C8khD~c_Eip!~SyIZb7Sb<ij32+Mg2V>W+;Y2a<(0R$ zFiniUS%+G1Ja+tP7Yr+W<m};j0P5u_h+S=^ySHJG_vH^g=`tNdMmWC2#n@-PGmU^+ zV5Z^Ctc-q_th^ZI{WmT@E?gF&3E2_*6IqM;fBS+gm4*KYuFR;d|HGDN)cSahMxWz_ zTI!E>HXdHXx&vjN_Dw@;gy5i-Kqyi^V|oN!LCRIk7aMztrOdHFf|l)$FQ#+_8jfhR z(0dr1sYf8m#p4DItGt(t0Thx-B7YzwE-d;Yg8g6}7Joe(_B#jgFO07?DD{f%0Oub< zmyi0xG3;K7DGLF{jVTA;!&@S{l3gkVc!L<y074FYql5rsS7N{08k5^xiz^w9x??mx zS@V4P;o#F+4{ZTS1pwt(aaf&R)*b&`sim&DK~GQdjf^pfjc0?+K!jWbm=p$%s-8e5 z9)4qw5#71d1tRd!b`(?t1C5|&PRyJf1#Cg=3S44CSe@h@#~~BeU&9bd_V;2jipM-g zOn@aihG?oJX~B2zdjIub{Vtk)e!fQ|>lTPKad_><L;TRz;0sO?&O^8#!TU7|sSLv) z>9quCpQ4Yq1`MEun@%XO3}hQ@7}8}`S5|7u#cDUg<sLGadWhh2F6ineiU1!{ps%)- zgFQ4mjkupz65VF+^}&aVh`_LLnw4gT{%WW75?4Iv3<f4(mLEkZRe0G0i@eDzkts9i zl)t&@PJTOXopD%F4*xv1y&)SiWtSD>0!vr!NmuM05_M<X&O$)b2-7=Czg>tn@Ag1p zY+-GR6*<6n)4WO`GcY^59(qK7qDHLGb0w(#)#3MTvqzAK?hq~YzS0~bNigg({RGAm zK<g^o%EuDO7(~hPHewX{4KOPLv4UIyundaywtF=bn&}*L0G*E*pNb-!5a_Ml+Hb~P zQNc%Hq6Wi{WJ+s`Rb+#Q1$~Ey16L9|%2rjJ7F81*n;F@g+gMxbP$kD{l;&Y=?g)Ab zgiscKFoJL5<hbvz-T6EAG_O`OVPeYczQeEwHznURdkC>niE;x^Se5wU2~^ycqCCeF zjS!&+*t_jH(x~El!p<5Due0gEEnQd+U_l8cU_ek@LqG^U>`(okQ*pi`wOG`?U@@yd z$o7vC>qn(YKvQBX`U~?tbkt(er6p^~<(avN-gfiJkfKrm&!Dz9f+*tc7o&7{e3i7B zeNAB#(}%)7UNgZew7y6WLK@-)uO@_b?3oA%%HX4*gbPS6W?1Te4}kH5))}M+TUIz* zk!OU<i-a$AwV;tSx<~{QTLOJNLpYw%bb@xiU`LBSAHm?4dC<19r$iUCOE#MoKLBye zLWe9^g2oeT$POq(%+jnXL|U8n{S7IG5~5N0DK%8N2N=Sb7elcbwX8W7uJ}#NE3?cw zTr#Y|8<<j}^xVA@=%D{Ue{|KD{HFP{_k+nI)0Hz&{EX?+$BZgXUo#308IGkQ<7LNK zbgPw6K*bytx3-!<iN3a;P(pb{1*r!6NsK?IOq|&KKP(4isKLcWOyu3nqSHak1687s z@PfltgzM3CVy)dvH?f%D&H`$q8MpgW@-=lKb+PY$scgr@dc5iF$m@(xWv%F&MZ@~9 z_0n~v0HoME;heOuZtB~g%465}jNNuI>=qyf%Y~X9T_i{yTzSvk1r4bq;z~IV|5I1{ zjG!zbYkhLm1;`&P!z*`+x-*kS9l<YG{4vr#y7Azbdg{gr!CzP3fpAZH;g3&NjhN+v zOo9xjeX2Ed{W{wH{@tMo=b(K(+(z#aO@pW)==87sJs`B%TmMB2<Tn62u;bk_06woy z=K6eZtkX@a?zZW<BaGg6W5l&(VB%gkF@4B{b2`c(U^rc`>nPxAjdB!ti9=k7f`xt@ z+(PhCbacBjg^)FFidc~-pVy=$3Y$$IeZUr<irz2@R~{WcmNgxtvUGYm8c0ZJSlm7O zKCI$x83_Pdu$pNCuFk^O+32n>55@BeBkdymfFpglUNsH@Ue>u^?xNTq4k<ESOQm;P zVmS`pB%I-)BtoSsE*Woul8%?;;~j^#o=Xcl!!F{2Q{3pm=O9-=d9!#@plYbgG4MPV zqly}b%s1D1*~<650KrF(@meV0f15rW5Ea+V8n@dKyaTK><dsoQi{AOXqL<Y=4xN=Z z+l+-QTcK?O76Y)aUo~&KV_;I?uG1U9shD?L<MyTZu#?@OW<zbWXFI-0vCGd7t;yxu zxtrW^Rp+>`GOTBt>WYS;hr+sL6L#{E8(u*dX$7NDE9_*|zhkVM^}~L@z`6Z?$ou6z zpj=^k<`vX#SNjmFI~;W0412&P5!(HWtnv>2ct6B{5GWJegof_NF(6}%IwZXzDCu>A z`RB!b<8GYfu;cj~U%eJos;Lt<pGLvtz~_9XavBQQ;{k7^gp+nH;)vX)Kt?=Op~3dG zLilKkd@#gdew|(ib`js3^{OdrEZLche2a>Q>m`|)3wS8+QiE^;S5u_fVJo&K;Rf6` z0W)W;0}he49VPT+Scz)=S~CIIxOx+t+l+FtOf63ix9*=?{a=Di0+eat0VuaXVh16` zWpAPgy<?ehU%=)X!J4g0$&!wN0sM6yBOc<=_K^IA!+}XJHmi#=X;g(v3#D;vs0Rlc zHV;CqyT3sw1A|LP0fJ6Y1V9X>Nc)y2PjFm?u6)h@;}>BE;<2@13~<Z}s8;;QRv_Xs znMMVB5Rjji9koHCs>Ah(T$Fls|GwTudNJT;iuVxF2YX`694^mXm4DpQfdo?e*Dam@ zoC#k2qi0yVTWVq&_{gUJOIXdOVmayTr+;s)Es(g!|Gc%2>Kq)k3C6&t8RJ`loARmG zbUP;OEq>g6^D<(i@xAtx?sX}t=JO!k-~vL(IgU?01M^4neE!DdI55Aizmu!cTjGfM z>t@}1No*^=%dn>InjApYInJP8X#axP&LSEVZ4!2UIiTOcK}Y>q0~Zjti1cICt(2yJ zQ(&Df9A1F|&XQcO9~s53`Ef9V*~|Cky<*hABfD3;J`VdKxknyR?U$ORN)X}Tmhf#3 z94<~73RjT>kQAbD(nYxKR1MEi-o5}3go&pQuW2ve$LREPM!~N(_MpbyUDX#h@tDUi zZmjg}j{7Y)ym|md2zNAzHu~CA7!_?3{q4xG@Fx}P!xxk7_^Q`}dc_kf|Bc=#J7E8X z4}7rT3<yId+`b?1V^7^=@{qF8G*nKjs+$|aZm9c}hOU>k7Mu&q>mo)})ret1bhUHp z^qo(0oIWaNJV-AT2$S+LXsXu$lIH_?DyTjQ;;B@uW!<CREYLgCJsX*jM%CJVN}N(y zC-2z<V9THaE;hM-ac(HwRikaa%iQsc(>Tm&02oa663u~`a}Eqa3(xg)2H+3ZyLj*y z84kbaRESr#52Mh+LQ{6aUX8r|h5dwEUyE4|GLunvQq<id#u&&DU=;$Yor1}X>U+ME z#ZzsmLvDl078<-N1(c>J_Q+k{Y?|%TpwH1%=7pfSX1|pBdMq~Eq4cmH!Em`ZoaPJd z$><ok%jzv`PPI^9q5uoTEE2AbIx#^>(TJonayul834Pm~v85H=`Mox^Ez$%xz58x2 zBV~8n>%V0e7x!mjFaJ;7r+40Kg}qP=689Acyltp<-J6U*hl?WaUn(_R1r1Xb-2yQK zT+}eRfq4+Ah;X7I{GKk)sLrxB2&vrBf1`vo?q)$CkAqh3`0xPm=xL1TN+*}&;WfCs zkfOK6wvQ_wL`sTmwFQ|XkWE-aL!ba)+A!*l!7~>%X}%WLn&jQ?6{?L1#*on>`Pv$q z1S=B*Rg(=Upig>>_g2<%O!B0=4wkIwZG;A{Yu<DPz{Mtx+JIsg6)*^}`x$BlbGzOo z7$|mc)&|q7GgzNH+3IHF!Q+k12TwMhYRkB9Sv4Rx9mDzq+z<Pd;~nChfUD?Lb<<dj z0p^~Lz{$>zd;?QgqFC1u5~aml;Zo((CG`!y87jP=j`dtvY>PE6(K=&*Dec>w*+83A znKXGc^38(vr#gY&2Dk0A@$i@KK>PTIf>Y({VpVy;q$ZkioMsYC`k9thphx<hcZ#K( zKWs$OM_&gK-MG67x~HB@#EjehcElLQq^6wK%q2FZ3m`>qlKcyikM7MjVjJQE5rpn| zJY<B#qVPpuNAUxw8}$~_F*lUYFI-5+47^knf~YMi!24RHf){Of>5F3?h;9cg(dt>y zIQCe}*cFt2tF%&HY+hxBc6=;@fp)nkihq)Hn+qZ?%;qkttQ+!2K8VkrD(QH+5{aj? zs6g5-N9GcHRJ@`Fy^M}j&jUbMT)lv!ZcgaiB92Nde4nH0lf1k<xYm@gLamW<nT7B& zGG#$+RHC5XF6ek_vF?TYS`-xet9G4}h}_U8V0p;08PcX+l0GS}&5)7=j{YmX;L%Pg zfL?*c%NYk{QNSn5%6%SZdsFcWEaJjr*pfV?4xlK|(k*}Tk;sV#wJ;}!4AGq=EooCy zTqzf*Rl3w!l&H|GU)z&$pODe~PBx=1J*#fiYPV%_;vf~3uqsHa>^Y#xl|K>;$*Plu zxR+A0v9?*;<8D6ef9gu}xXF59lVv&(rp`?uRXohz5?s+9>Xi>}A=_E$ma`tP@ZkKU zNQ0s@!NOjY)owmJH=!^U7z72P9n>@@)Yt_Z_ds$wq6oG;y8@O@(Sm#tTA<{YGBfH5 z;Q9Y9F#mNtr@!x>Pw20=N>EuUXY}2Yyjr}bRmL((TrxJO^O<G!poU|a|F%h%P=!Y8 zM9K1K!T5bwE-hV(gp@@DG+)1G?qZqYmoI*}{K23bO`>n3;qgQCB3tE}MZZ!@yEhbC zp$WD>a$qOZ4Nk3savK18^mA<JlvzMja+3MJjp+qswlqlFM%piHK$^l46EB8+(l*%j z04-^C#2hqU1X1~FDX0NLKdhwt(|G=R%*&~K>Gv7ct5}&rQ^Agzx!_<K>%}6h1Vc%V z8@*sernDhS34#`7>XUnt4<Zp-4&F@#+bKn_iB{Ly(9bvEuz$5(phx9&D4`!g@ZK>g z<DgW$>hfBoZ$_P0t+d3iz{pp4t=qA{Sk$5ak@m#oc`X~!4-tEdV6*577+b<E7vyws zlZLT$R3U!1CQ3qHyT-{+x}ltxVvY1|qPh~Xm=cc$#0W>Px+3AM%Agm-n$+C{xuqP5 zWC;RiX&KBN!;siQXhiQou}Gy(b(i`t=0-joyy6UMqjGPyH-Vv-=cUtNZ)hk{*y%@- z9HDh4j7DE7R1Hl`P7D=CtvM~qQ5T#hWqhTEq&4`i^$GnKL%+az7M0Z$AKELt&k^*T zf^a<R^gccR@@yUc3EAGU9eI!~AP#p6Lk95f7Q;lAQnV)W-b=&~G@jJu<e28oFNY%* zlG!l}f(#0A@ceIoxdG3k?Pnapz#qm!LsGiE?YoVqr1NJXS^?Ma+ArKZSp<{opm<}s zE)S3eC#Oh&jvsaaOstiQT*a&Reuqs_y5(*Y=9<_VL@8Hh-pgW{x37p3o?qtWwom7k zNj{MxqM8PCk^))wWH%&GCG_U-ipo~Qt;JxytF1E;8D;z#9E&Mpa>1NITp)VhJT@MK z9dn+5u)?M=1i7KEm+!|t0+WuT8!#K`jYZ7rC%2$yqvsGVcG)mzGFUs|z@l(ywmoH< z{$l4!>4LYX6#as*4rmQ#+f6Qay_`ndNczw}LL_}+e2pGXC@Q<|xlQAxm@+ovVkH$0 z@=3Sl;{{R8(HuFF(#-zyaC7UCB5h2;fWd0Yc)EYSz`xuIiXRk`eBm^H=#9$74qaOF zq7_&)H>{|MCPg3udifp<qF02eQ%7<dx+fH`Qg+6K_LAdbtU<D!m`_t@6WU(MMJ=kv zhdQd+jFvO@PMN`#8J$<hA;GNXSG=}Q&B46!tVE)`w6@ZcJ8QpWo8<2VF(HjtPg)E( zbE|7fLeRsxBa(RXVkLnQI#z}HV48fHSl|XGN%b|1Yb_)RbDAJ0K{vp0);efjM_wQ8 z;drcYH&BfQ<i-<iZ&XL6z8(NQdE(>VFl>ji$Btbw0^9A{f?;APON*nRsUrjl%GT2- zBDj$&P>G^K$(1D~8Tz?>?&rtNru_=?x3ECX((|(AqLz~=>BYeDjwLs8264wpUk@sf z;kgxaYK|jZX!YBg@+k6y3vTc<iHNDvc2m>OM05G6*S%g&Ztz=yKRdh`4Rcus<YA~3 zA-M8(S-L8^66hAo#JmsJU7Y<e=;2R)*ZzI<^yiDgc@FB1E)Fs59UvThbOI!)+iHLB ze%{AB6Y!-|2p#wad!Jo^4y%Wu|437|mUO%0v5X>PLYPStInuqr1*_Bud%OF8fA?m0 z|FD@o0U5->;rEB{-NS=N`1JbcSMKi(`1|nH`@^@*tg!_T-ya^mZ)RJM;qSLEzx@s# zp27o`wYTdMZf(Nz``x`}hF^Ys<K8_%H`A+O2hf(rZ``c7DOO&*Q4~Ljtlc}GxZ#1T zd>18E{-M>E4<rQdPFn7n%dFDQAzxnmDN&tqS8;V9BEHMy?n9q}-i;{dT6WmE=wfh3 zoT=UZ<l8Zj%Ab3K&hR=9aVwdW<{7v6J~!5Fe}*RG9wI!^RjchT7G3EANI!g6fnkxp zGUVgkooe|6NjlZ0zWrIl;1WVsp1N|Jhp=HXBxC~ORrnZA)ZLjmP8uOs5*C2QUkbt8 zV6R_a0z?}GWyAQN?P)$4UU6P&4wgKmh*}Ik)*W2*27+>zPe<q%NoFm5j9%IzmJ&@3 zroBFb=y0hRc5Ozm-FU)F9eLw~5qa@MXMQAGe0|XEw?5B|gA0|u;+vbLTtEHYhpWY6 zID)Mt_Tg(mn`iioBa{N{_>^nu6x++Gpp)G1WYkF$NU~mxo4Xxcm~lBcZlkUrzP%jg zpy$Uq`>xv`fw+mEXjz2h^rDV2Tz_!)o9@BzdT{uOHQHDUuoeGcnezuz(Lc=72Tt=d z|NEV*6i}h0Zj@?tJ5ug-uLFp?mtEMxb?;?M5KJLTo_hwH2e2IQP7piZ9RtFuzdXcv z2?E8&e?7|@4XLVimW%VJ`x6SAqUsgj-~&}~=nakHD1F?ecgX$xOf6S$zQayz`>0(U zy7~;H4LE&fS4s@)yxoGsd(uWQST#MM)D=xPMz6oguBQD-Z`AL>RDL#3oo?TqCRqH9 zdHPIH6N6@Uys`GM4qgcx;Cyt73ISK@al^fVFYqtD%_VUI6LZ>Yc*|*5DKQ~F4CD*F zm$C;^IF=)CbAHSJ&o8-z29?k_)vP0+tnI&hhX<miYjpzU>zLbv3LJ{sXg8z#NTS@$ zZw(NE`GT+t7a+U}@-*{%jMc+7Aj@pzLIvE<DvmOKS_`nkJd?jN2JuoQ7)-b&2GC61 zZU60TIPL(BWMgy#uuZ*AcGhpTf6)nUR&xwE*381+>bpyQfeY2$Q;t9&AYX77HM7T~ zoA8ddRP^${R#8{x8nNO2C(y~a{D<vop`Xo5cjq6g-kJu@Ew6WVaa_Q2J_Y>d%qF}X zC(@~E-F^bc%^4#}t)}4HP(IpyfQ3jGWP`2#FS0E?mLQ#VJ&08AaVzGH4J|&b3vZeW zEd%7oE*vX31W_-FcTImfErf{W4%Mjf-(q^t^I<eRU<QHh$NCw9#f{CV)$UC`H?y^e zVK~ki!L-#MUAC&6War^V?Kdxs)k{2B%GSighY!=scYJZys&3Tr|JEKqti`)zb=>Oo zrj8D6>D8-tP<YuM_J{7B8w|bKO#F2<5^j&Lp0}=gefKGE4f0h$bvlm{(Bf%q>T0n3 zRkXx~LIJBUe1z#+l?~T;pz~d|#*Wi!W)I!mHa7H^kz?3!uRk<zXHXC`NsTZ`9%ozy zEq^P^vfAxmDWx)PsNq<}bro=Za@zbT3n~O04|#SN2n8-hc*MSb7kMBuPKq%U07EP< zhj7IJ5G3ISc_>KLtO{}fbw@7hj@nkDvRrTAK=$yvDtHw`y^~vQ1shUXpmkjo(-aQ- zIXUG5=~*<#_(4&1-_1l=Q)(e{W+GD4#-4a=|AUWj$4CJ`?)Y*Hb?##jYKHC~mcRQD z5La6LHp*=9WLT%Ai4n@N3Yh%0yghd0@E_SKGk4qm`v>*?gM3dEo--OTRs#GO75+`c zR~~PkI=VqzAyz`okqjS-8Mb_e?|iMVx^Vaqx8&}^5dHaDRBjKmQSYYP&vj$y-)HXI z3-@1>o^AE~M@VxSI5@TNk*_s~tSc{n_!gsO#9N4F<D*-<ANAy+#Sxi{3mT06x|7}e z>F;Zi(4s1lV70J6%9hLpdvkuvi&K=E1@dUO=r8*iVxZ*?%FvqJ!)d4nYKtI8%&N3J zYT5J5KYa+YP(LepL{w?|zM;#52wP=tDGBFTH)*VHWPuEeRBXkpKaM(pB76bc*zW-b zU?%RdTD*r*gP2jHThDT+U6$UmLf;KF3D-+!t@bH1#K4QGWd=z>`(~K00oV!+|8|`1 z!;Ea7CEJJXRBiT|LKWI~O}1)@E40tWoF6D>abWFrmIk%oJ$D0W=_1+m3`h3;2eyI| z=AeSw%!(d$o!qF6Xk7sR^S4Rws+(_Tz*%aF5igB@C_D}Ah@dG;*nZF4AgFyQD`&0k zE_j2<&qU3*8OrzGk4<9DRbXT)_OkBUOxmWO9bu=!qWx|9@L};jY|ZP#cT8@D@Gja5 zH;uLvAABdibDiMAVk+ehsVT$|!h7}=;5ESQ<=mYbps&6d+T&1N{MYhuzn8;LUHR=X zS<J`1TrH6dklW3wA63+jnf-l+B2oS%ZI&_T2FtdzkR$WAN@}mTrZVHfYR1B@krW?% z@N&aI-7}IMX^a8Hq=*A=LpnF1zq)@fz;(b#u$V%M3`xi%%{EuPWGd7kN4Eu*t2^l6 zI-<I(Ui@zh2<U#s!10|+^v0cNI!3NO)off?a;Sot^tdM!d;mbUZ1BIBxxjQ3br_EC zd%{-`IBG9PY}DkTzBU<t4~)>hTQwk|!uT8po*=omB&MqlCK}rna9(1y=VvZaNNNsL zIZm?H(T_06Fe<zNyjC)NrxGf%Bx>Pwm<}M4c~!{{9nrV~F(w!(RO$(~o64V^c?wj= zE}vRp4UH)B-j0@B>g~wI>(mQ2ZeI3u^YrMmw;&SobtWz#A)8vRf@2*rLCTk{U0F<z z!^m+0O)1p)+(VJ9Tg#=K==<Hh?+-mZV(!Q^_2MmPk5w++t5TxUnMY8Jpjp_h+t8bm zg<g?(w(Mv!BMqNG+(hW=KEaV!6F0%AyVP<l?MmeDbgWWH^eZEjS69XW;6z2RRGJ>X z6RA3^vNoSTm%UC`)l7}1b@o<?pRuA`83TYztv|I;&<d*u)XZ4dvUNS<;c`r*?wdL- zWrr)yWGDE3-Nau%=&zrdr);A)uoO>M_bH;e?IXj%9n3i9APA62l1BEnd{QHxBnt4* zptao^33siA6nWP6WR18$xMAVrn9q8A=zHG~J^YfBDWK1KHk^Q_j`O-hx2E`mJSLoO zOHt5S91`?(cNg&9RqLX=j*U-TS%ED1(eXs73(;HDN&I~;pL89YD;6!f0F{4xS>LDp zooU08oF5P?xQ8nxM?A2}khO_cQrQjiC%u^^M7-Y3z6rOAyl4TJ>LV$$d-(yy?RA%8 zSjO7(4nwR&YA~;nyJS6>jthv}j6QfL2)&VE3=hVwi>ivdLIM>nWiiHVM!sUc{H!ix zu%s39Z_<62Oebt6n-;+ZRt&_xbGKe4fl>3!4v{<DM{mM)Y43ufje`H(G&QwxcV$X@ zyn$jHtr?UYpPPmxg)EII%LlQ9+BVjUivKQW*0+l}!WJyy(?d1UIae6qM3f{tIa-|# z%EnVymxP+2VlpR>9m(w_n`gs|DIm#LTK#^=U%Y0;D8$UyqW+@?=0EO8MxMakejPDs zPsh23J1LYl9nfxUomm{wMP(iSwvk*Bc*`()WBDQy^9@-FwbDsq9wa3UmZV|0^b*kV zkP;k@>gQLomUD8K^OlRVm%56t;V<XqFJ&+-&`;q0_}F**p{m9j)^YDsMXibonv7JM zv^|U>sp3~by!e~6_@#caGAIaSh}xwBoF^D7V_gYEoU&8UNViuQ?Vg&5pN!EbF|squ zT?*$z#KSF&kA_$#H|~^%3nl8n(OSx|@5_p0)4|OQ7)IRId>xEYh~Y>*@%ik%ks18( zHELU2-MoqKb!f^{&5?O8nRfp<v2>^zKFM^DGui5Q*&p7Y3!mXtg~(o0s)i-RMQvwH zd^WZ-QO|8u5<$`CQB(3!x$dGVW)I+Jv;E64_#J@k39)tn{eFmsZ|BoKU=}sAzdU-p z`7lfi*|3B;@#9@e=<WRY-R(2V)&~8F4j8H`ffIi?dI^CxdhV78ckk9ki{dJH{2FwG za1CHKE3(yRZm1AUjyVd{w-q@m3L8cD2Lsz<PaD-2X)>KM)x}tnn&Y@bA?zYfnE>=% z)(Rd^)dhK$WSQTIvSG6p213ivw6G<4DWiEbVxqL-GY?#IrBO-THsj*M{gDJY(PYfK z4Mz72tHY(1E_^UE$^l?D;AZq@hRmHy;a@@9(xgp^RSJ}C2GzSwix)|jqQ+M1b8$D| zQe}J4q8D|KJcM445C6}!)vxNv^IFho!a8<_X;2%RE$FB<>*hTS7$T=SC`75p_;g9d z7x^Ec9Vx|di%d{30H%&C6ar)cd_D&%@)9&7g9VFgx({-)S@AqrvQ=19XrxT-^U<{g zpX##;mqms^?coR_@{*)>e=_dhZ?At^mOG*j=2~L9lr&VT)D&TL8T~X~UEE<;@J<Ws z2Cs~aXrrk(+I171%9_?q1+Oa{$VHa}J^O1lysE+NCU^Wz6=ilW*a8D>lY%YA<+xIF z<Wyh5&C(6!SvijvJdhLs1u!CvXNd!Eli1CMJkB+?PNLe>9z!`moKBYvAk$c`$z_}- zz5G&j3>b0WSn&xpa!pXjR9^n@ZAFRTBT=8Kumt}%+IXq6!4e^g$cr?ZOi+lb!*_0m z*tvkof@`nJ;N>Frb+s}ac;1XkDp9bIK<N&Zs|>nwUCzRl6AgKVY&wIFEBedZ0);K( zwr5L6!(3X~9*zfuj{yJvL;m;x*QP#}`j7A@TfmG^7(!*2${a~R$wj#2MaycI*?{`Z zm59Palk3B*Tpu`>V^h4;@Thk&9b*td3LQvYk<dUL$CM$79xQg=a_$}bl~hz7y&MNE z42EW=zTx_jWQ5co;?$nG;^d7}wb#K;L~2<LQ&P*GWlvx^h3_BK_Ye48#}~DNF3Q2% zO<}v;rp}l`z%vki_Zcno%8hB;9VTvMmuIOZ=j%erULm2s&}Jhgl0j=oQYIE$4y<Qn zSFc=e(bJljZ&F1e8>hH36LcxMC3H1Ch^`Qx5~QydhFR{e5y2Ex?;zxQd6*^>G>OLD zWImxVCtbp&gGZzmOuC}pZm0Pdw1}h%?-?QE49$7DTwHDyGv)ezL-E$@bqF)*^?8wp z=BOkg<Wq9AXX5g6EhdIJ9E#{lm-vR7zz`KYc^OJ8CM069I=Ez=R+QAni^0@MF`KWS zF`U#)eOy^>;3D-#mx$8)7S)B+T5fBl6g%iCW>W2ND_ZN$x)$MAxfdZ8aTY$z9=imm zN7Wc4=>t{^ajckdi5QTUPVWUzs=7Db_Wtnd%C)3gp@6%Jo`OYjomMFSBjh6q8|~ex zi+yNYT47A6+3P*hb(h{(g3G-U;;zkbzqccmaKjHXQ*^*j-TP*BKU|PPz_S*>+n>d8 zVBmVCP=Z?78@CBB%<%DSxr<MwH|R|&aZpYnr(v{MmZr_1P_OHGJ3Mc}v(vkxqta6^ z4yZ1+1xSdt=-7$r&%Gl3DI-8j(W2n8A_Ev9x0)tdsVEmiU8>Ymr;`+-dN@aLS3Hnm z!Iev#($_H$FFxp<pJzGzf^=w%*e>U8u}&$JG|dG-olmCc=gU@N38-3)hBk|OrQBD2 zKX5exTe{vEL-d3pVkyDQyNg$&k<9EEnl>guKk3OZxUBL5!NrlAkj!TAsDu*Pr+|*q z!ITvii_y?nt2f|A*Z*0?mGs4(bzi=FTl?$!8bo8QN_LI=;0?!x^UCd_s%NPa(!@4+ zJ#gIyCc%wITlR4<I{~-y?#-w>$lc=7Aq|pZ1Rc+y%z`C~PY_9Wl_!K(DTOtEmB*_- zH391Q1(|w>cbbuYEiIvgE<$HvmG663U3cl>fZRorGjqJL=+L>MR%QnO=LvwG*HY2= zlI>GWJ&I5ussUvytFS`nHAO8S^je22P96pMLmApxw+uTA9LWhj89}SU2YhtQ$<N)h zzxO7f%y_t^>wA6hx`}o;NI0O*PU|zFLji;uW+yatalk`^9JtS74hrtT_p#}PTl|H_ z<!jMGr_pi8l;K15!k9NJiS-`c74ZUbIUY_X{ch*SNFMCS2rXAhQ7x`}q$b`8^$N_K z6o^qm!mOLXld5PPtc5m_0Ln$%gdYe=A_I~OaB^ksF7rXa!<nSMj*1Xg7pw;{K~nAb zrTck0%D6+&<L)4RG6OF-1eSvh6JuV0s`Deml+G=&vp!&Aw65JU!T^Im95RT{=Htf3 za>C9wGESdmkGNDiG;=2a*az3PDL`aeRzgMEgEYeFoDbX69M-w-89|ku_lGS^FmdPO z@Z4<&LILqWYE+o2T1raQ?Axl+kHt!$><SY36?Poe84o`TX|-3fgb5Adk);^Fxprv! zg7r20ljch`ti7@vYid8qdQs-ljLbCaMR9C18fQ!rZ`o!+O;lfw*~zB8a@6ULiKE?= zVJENnyP>lnGRD!=AhPh|p9+NKh?i)qpFx*<?x?^a@Hi!-aqp9xg9K&?q+fIS%aM=V zN5CdIjhPEn@<A6cX2u%+3CmqyBS8T+(VhY^42VS}`XpiLZW#hA2(h{sfJf{O^$sEv zr%SuB#ohDC-IrvsL|5IpRL?FJD)PK~;a;T+8;X1c0XN1MASuUDS%c_BRf)I6WTmVk zFYoAO1lFHD!@?xUN7lQ4-#8b#Z^yk;XjK%*LPftWxbAvER-qRlT=;M3#=Y`>D4|=i zBhty@)K16a&(-t69r_}}sj!XVI(I&>2+7i{0a()YKUaZ4t5fH&>}sPH<Xj~S9{Hy3 z)o7R6gqhubaci|Idns<B=vA;h?47A!N;7Ly(SF&DO}{UJ%+kJU^8SK1Er2L+KkzqT z3%FYa<c9j1R4qQ!#%an9x+7sm=+pIm_}zDP_27UouvvvKe?HKxt6^svAR2Q*mO{Az ziW-60BZSztj6?1kAHQ>_IFzV`Qz6P)okao=6lFB^K$CzSbGSoT2HsYnJ83U)Twv{M zc6yRWM{0&6h${m~RRFZw9godRU7(;^S{N%StDd>M^~@$M2eEoTp3cUwde3HbUkiUl zdH2RP<=&Xy1AMIg0&nQsOA6HoF9I-=Pk9A$%>af#dB0c8#pl&Z-X8Zx6L!0UMc@XY zRjE-?yOZHnul;fWXdSZ(>0Mp$Vv!QEOE7F1!%g9nWB1$*c-rX=S#mAKzh_gt(sIeF zf>Yb6aoOyPwK#=gE99fBDkULdd4<VKpCi)kPrqfK3t@b9T4ve{Q&26K3oQhe;SVZx zD%fe^j(qu&!RpXYIJ){pQY0hdoLf6uF9(v0Ev(=|@yd@GX~UC-P}>BQ@9vHGFGnv^ zUy7zvdg#g<xd1Rpau+6Z7yV!DhiEux#LL^}7t*~2dXQXC{L&GjHOGHW+mr=OZ<yHb zeSS|;nQG-5V>0Cqq-h_V*1XPz3!@Lo$;W{at;nsYe$X0c)(EKH&Rvc3#;jO}BuZ@6 zcmev_liM1NnaY=Nk<W?CX%<Qr+A3u>O%0k{HhtgeZMs*@(*E9&E4t_cE~K}lF$|G; z`=?@te&idgtRBMY1-U4&K;)K)y+@JJB6nIC$F(qGN&X}n>(U!;5h&5#alyX{eHs<v z2#<bYl9~2KJww~-4Tw1e9+3Fwm~2-zyu0p3aMj(o-A>7I7|8%JTY~!~%1sEtAbbJm zO8g)-s&Dj)K65M7SA0Vsxnb%fd8*f!mGO=G%5LiED>sJ~Y5T#4QF#}lD1{GTuY>~} zUWJ>Q$)hr{U+PY#UWtL3)&fSKiy5-}`b~gPTCl2R)0H*x9^KH_=I}j1LeX>+hO<E~ z%$tT@R>cjt!Oh<xU)xQ3{M+BccaWfl&+w$bvM+8(z%O(f?x#;OW}~VE<wvxJ*Nogz z6$p<Hb=B8~ez3jr=`mCxQ2+4e8SlcY-asvg#+u-#sxoB(f(HVOcYFe#ftCC024OrQ zRSS>GGgA$0F0;`MmlqcSBmdmw=M6ZYnTW?VYDBi0727&v$cxjq*R{niG9-)jXXcPB zHmY|X67OFgHTO<K0^tj*3$0pR3+_JKA0`P=@o!;;-o1R<igwt??D|}gZ8~mbfjOPK zA?$3dHlnN3oV8<f$C+o3@|>FIjA2>L{9>axWF(9E#|Lvdv9YrJ@u5hE#hm$h@em<0 zDhZyM1T>dA#fPYfK&<7vErAxgqQqL_2S;a<PEeBB(aGENXE1ZMaL_d6#9{sy7DQ7> zB}*`1nwvr^=-v0oh|s_E<}EP;{D;U2-9l{2illck(oHq$cjT8rLa}~$<1Qs=f_~W= zYnHk2;m?Y@pO7Gul@jpJT^WVU2QOTNg@&PBGb4zJSi}f_lPt|A0RVC{;OZMZb4be+ zD_)$&BsY%Uz=Q6%HSudg4cc_jYr`#jIKEhaGd*+Ty#C{>mj}D=ch?WPuAAMCn>zI9 zBnYOp$<1WhTN3qXt&wF$7%0&1V~~JziT3j2{=3!9tnny2gD77ZbyznXWch$i^0s?% zcryahuyTAd-PqdLScQKc9l75JPqtR^pU3$7gdU!{--k~d@bGZ&0DmFz!+m<SzlpyO z=;0y$LjFe$EcsDmcLfn~SK#5n9=>}B1w4AZ0lx>2@YTUS{vP4O;RF1AOb<`+cb6WZ z0goFE_}#(^9zWQH-(4)`@!m$L?eQVj_V{Sa{XS`6f+vlq_={hjY~q*AhxG6mf1lC= z)br#aJv`il-$NXnryJ1Ur(3)DyB}(M`T)n{>4PWu3;CZuq*o82<fo4|@!=8F`Sc0& z;OX8z{vN_F4d>JS2l$KG4=~>$<vZL8b?t6o;$3XZ?iQ4?OV#f_z*i3*)58<|-J=I6 zbN3-sy!#l3Zuc=gz@+Uyq5MxU|DNjDF12hI=XQ6WO5Vqkv6;Knz}-XW*xm*dxra^K z+d9NwnCv}j-rj=;_zU^=9zMd~$Dyh{8lycNqdjcO9*)l5{s#VHJ{*?)4S2J^bqE>u zAK=4-NA&One|PBtvg|*^Dc*nhDAcu2b?swa`#2x_I3N4Cy!UZk@9#gt-+fGq)$bor zSqJ!q`o52SKft~pV6P9TzXuN<gc=X9EeE(74yg76to>kr7k{DNg9G|-@Bn`w;V*nR z+-l%2ZnQ&Oe}^>9hYz5}!#(`IN8k6JhI$Y8_UIk-?r<Ns^&$4<sDTehxG9dd9^&s~ z{KYqqu@gs+q5PvKxMq%?Jiy;a^ni(<9N@!KHIqkAaqApmokuW=jg3u6)^H>Te>dsj zG5$WKhh6;TWQXwk@CiOVe2Tw^`0xk|z_z)6!T>imV8yuKhxp|QR{G=sexJhc)<Z0L z3#d=yaRVFhxbXmfsWp$c@ZljnJlulc$Mo<RA8>HpKMzBlkM|zaJE-9?cJ%Q+cIWW{ z<~e{5Pc~o*+&}oR3%z-|3FGPh*~H(+^za0Jx9}AW%F``Jd>XqA{Jz_G5^COU;1}3M z?ia^t_aO}0E)LM{qfPw9!PtGY55JGM@Zm8%z%cCYVJmjA`Ma>!8hdyoxPPGeds}LJ z_qHD47n~>D<BdI_H;uhV*u6a*rM)MVAGTCuZx_dJZ}%boKB0%F_)B?qq2|5ANBB$M z51*<!59#|6emR0N_cviXHukr+@b?itz(U$Tz^eBTHt`o{YyWTqe>dsj3I0Nv`$rG( z7wg<VQgt5eV=)Iu5Ak=O9^7zkZfwAV`{w|Du{QV5KK>ry1Jvez8~D3PuO8s<Lwq=b z@B7%D&HbZ>uXOVO=412V5X;2cwl+3_hPi(Z@b{1&@C$A)_m7*2-A8bE?><7B?*7@t z-v{(?0KZQU@!=^ZJECN&>fI-Bj=0}P_`3(ccqY1k@D-d%yHBuXyH8*WcAsv-sJnll z{HI8UcAq}PFF5<|A1Lza-WL8+;=QN%8;+LUr-yEYcX#p3b^jc~?^XjJU=O(8hx7o= z*nO~tzx(j}7=QOR@OKjv?LENX$Mo<7e-G&aI_{3KQ1R~JK7N6Pu)BK%#qVKT_F#eR z;-Wj+Yq$m-9pZLy{~W>ZCOyC;93A1fx_^#NSC$FtUkk|$kJ-L7S2Kp*huA?o*$RQ~ zBmQ^$at)X~hzhqmsczKZ()IWedR1C>jx3Gamq|T?sk<3B=IbpY1PP>I5TQT(zhn=A zo<hMM!lQMfasW+mB^VMIZ9^Il6YdHJM~&W9uMZYCV7`6u`Umtj65p${DWcSLhTR<O za1kP5ay<m}CyXMQ`?#F_eCS#^?q+=$u50ov1?YITT&?5~9E0s0J1&(g=^7(4yIX~; zHY3aA{BCv@Z&Y963s{>IH2B_OGK6sGDq4M%aZ{A<er>@D#qlARa)_Lbk0qD4#JWvI zGD9Q6MQlIdgBvPP3gv|l*pT9<w5^FsP*C=$Z;9Kdu_|#b524WNnY68*g~rq)d!@Qk z*VXN{Sec<DEIRzldP0%u%_O{8R9dl#@s$gv7>FQ*ZmfA#0>l7h4u!Nf))_}&d5u2Y zGm1d-><YuI6aA3<D3;}p6uJQBw_suzx?0rFVj{Nq^v$Vp>92->Y{?~Yq8aT}p=+SE zqcKF{?XIF34EzDHY${UrEL)tk{f-Zd489J$G(xQ8I)ybG_CNVVVbusqNpzz93=Mt< z?RDqQ*ouKKF&g{&@yYmPa5BkG*X4W~C&bs^^*WvIAQVR~mKcOK*hIE<$a?s+W<x5Y zf^X<!)`t`nTA4JCZj82rOjdP((u1N7j$XhaMRh(+VIWTlW10!gL`VW)G1{13)dFdc zhdyNVDH|=6q___$7BwLe#e*5zi|)kGyRg~wYFmF$!yJ;JwRAl@>$;N-K{d(SO#;4s z*K*qt4!vO?PIUGs`qUlgc;cZnijOMFAn_}cU>x8-vG+Da*<3Qc*c&U@j<c~c;Gr;# z5QdOmuMMx=BzTZS8aovFLG*I+<YgCL`ZzetN9HSRB*f&YxU1?$Yoo#m!_<e$!aGW% zwWP}?&zfTty5q?n4rUc9t#cu4EsO5K45mY$H_R6R!=d+$TBO_sdK(1otmt>SN>EQI zyJ{M_mk`V*RN-T66g9t*|8=?sh@Y(;u?q?cTwV;FWY!zxgl6l7O3k(EIB)p;JU}4K z9uJlGc;htTX*)Z+G^~6)wL#e4n8yG(_*i+bVH<de;}wpXi-vi#W<nGtyMxZl!8t_K zK+utL+lBHD&oX<6%?iX;ps}F60T8u?S68dk`Ek(uKU3%w9@T`*6f7))4WFt;K(CAA z9L>}0<pe3zsECzA$zncE6t=4AcLc%_U<Xt_3}$HzND?EmFEW2R*AlFA*m)GkT^~+{ zI$ClV&MZEEo<)b6^(`Pz@|lVho1Krf!jM>+pqy&mk->)wCCu@%qb;oP_-QG;`|}9~ zPY8EoDadO|vewD;=H}+hS>~=t-J22Im|V`4vlYBN$>PV5udw35p$|Tu4R3x+uj9o) z?1|9()b+=v1L|K$1)Irx3$r2UEM6)&)Rye55*m`GdsL=aaYiU<#Yrt9rm3Z-_T9Xp zfsqsdjhUmP0d*D~m_KY>(%qi3!xmg6i!YM@uAx8>za)~6vS>F9>6-6{J72j?DdJa_ zr=HnQG#1s!HOa0~)gUpTpW7xpM@%BH!-a|PBgyvX`gZlT?JjcwNRG|GbL?hq6=0xd zU4w&Z^Sxl{|GO>`EHSxRG;{XfJBAxyJ7{xO#ve9-^G?=qrTfi;s>t!&aS7F`C8b^( z3?LQ{nM~wxg0H>J|GoKB@%x^8szLFv-`;(h{1I!RoZKeY1$+VV_7aNeM<7~9S#stE z8X?6+dW~QpBELTS%(x>YlmX_+F<!JR)}Smb?|-2S=XeT{cIkz?cebvwUt#=iRsP^( zg%r!ConD=F$G38z(cTP=LJ-aJ+`Hp(>+`J<Y`h+^54vF{Tab|A3|)puTUgk-5~|FR zT$^hFJ1%LD7COs~`w<;~-v2MU9Ewb9$A<AK`Fgt?S9s{%r0-JQ^PMzrQrZHOp$)PG znBrVzvrU@}`Q8y-SNL{#x0}nt%+f+Eqj)k=a}qKSBc2FDd#^C_v3z5eKyDGO$V{O? zo|^xkdKlm-f-i{spzgn^Lip-ilo<L(=udd^1!=8YnWd)+n$3q5oIYZbQ-BgWBE<#& zGj*JW5u~))3w4dintE*%Tvw1LE)iAa`{!l1NNSdl)?vE;b=93*4m%-@yq98$>g}hB zSQo4j{L)0Ffybo?yS2Vt-n3yv7#C|S<tnt4Y3}RA%3Kf9_o(SS!e#Alv5*3Ab=+0E zMO7H>X}Z}=KjL<a&h(bc6>^>|a-H0eFhf&HoHfD);X|V6><5%T0fyeRKk1G7T~2@2 zom_Xj11^@-St9RF_t9?CxT}1y;Xg2T*7q!Q(3aASN-ga!IGb~r0P3M<2YPw-iO9-2 z>*pvEE`>@<cg0hpxEFiFVZYlN++v06<m%7WhM2~_LWo^37*2Hee96sF$=7wNMaY#1 z6g@zU)AImP05ylx=nv^*T)*ulvkuL`Mf|2-c0us<-_k!<bKJ8-fb!r!;$H2OEq<QZ zYiK4hAT+vo7ow%cb+6xdD-%KJuoNhS%eA~K(@s|ynMb(w=FYr1G>A_|dCLsv49key z=%m~)bVu3=1b1!bINKQxrY4ZP3(c~F9Q#hpB61jJLQc{SEf0#>L4PAEH4L$v(JR-W z9NO}EI3<%5e+^)HY#4GtKa~>9?E$dVV5&sR2?hJarL+-F)AR|8S6eIveGjNVZgdft z78`HrBcyMtB5$K>(LS=9xftz)8N*RQU`7!Z^MR(WK-^$!u41kz@u3A4IAr+)D+23I zRm}Gs>H5rdw?D7lP-kel8<<(fHUKd0kpP08o?BAnWRnW}qLRKwuxWQ0cP3-=N8M4D z|CBN3HZMBjhv?S*72^%D6XVf#@4jlRdFKPEbO(OBYdB8Y=e<dB`0-2P;*W*VE*)Z| zwLfU6y*QvSywqkjt_75d;;=>-A|zd<n+D}3S^Mucu6$=n4J>{7j~rQU_3t~heptB# zllv>pSKV>?%T;UqOTm0qfB5s7ukyOYSe1Cv=h@AuHMwNOV6=pCpI9JB{3DWDGxpv_ z^!+8?wyx;VZ9ydCF04#4FwOChX<tqUzmPR-6Y@Oc`_C6(L#wst$9On@!M*u~*3l^! ze-v=TFl#nC-Z))9gCEN5{;Gp@>9f)EXJ^k_U)s;s&z?V9A3YDLAwZZ*<rk<+`sJB> znNB7Y0t$pgUpQ64AU21=Y0tKel_iz3jXmRUVmIlRA59VCs$SKz)IO815Qrq7pb<~4 zXgw<d-);Fk?^S7lwVbUatX3s!1ubVQDI-}3@mWb3$(j#hYg>Hj?z84)!fv-xf~Iyb zykav~w1o}eYDQ{BMy)d~C?Tk6WJC$C3U-uSU$CPzCXxf#4Sfi8@CFH+qJz)|V^9_Y zS}C7(sJU7+JQPwISE5qJVl7>M(NfUMY-4yS1?<iR9iPs_kO~su1ZdPC2H>JTdc7Hz zU}8V)y{!Z}H3CfSFw&HOQ6_qju=3(OXlWBb<&8j<k}yQo@oB+cH4Hc`7*-Tc*l5ri z;YjpG`3eDX_)kQA?+vH<J9nW5AaN~6W*NPt^&<KZ1&dlN8h%x5B&yd_M5*KM;8l^s z@%&T{f2)vjy)A0UgVNg>n7Dq(UPTO(>;(aVL|f!+Fuj5SI2yMuP&$UY0h6!{T~Bms zkKwfTc$dP`bOfyv>UA}BeIU;oug7gw2mZ?#sT<rZVeXdV)^QbT^_Q)AS5i?EqtL_r zbAH^j7DH6Z{rhv4>qgBC74^J7VQj&?UW$5XcHCDEp8`C=tgDH6j8H7_e0$?~j+c|} zRlFo5lt+oeo&tMk6*~PZF=!HhHXU1=48I><cgOpVm8%x0qePiL#-N6!OV*`0t;9Vc z%9{T;aK}MaFyCa-BP{4Z`^m(bu-oT?8{Q4n(ANnoE1*jcW|0$aR74$%2S~|0s(zOl zmlu_#$Z(>eITEz#WHc3v{Y;-BzUF16CCO%}mZ0h09iU9Hv^-lUs+)tOouK?_MWcc5 z^4-YNI@0af8g3^mC{Sh2q9#?4Nv)8sKXf<F4aB5)7{+B0Ls`*5vGhp$LdBBPuMU_* zwqCV6T8-%TvR`1?PT775>1}dF$oOSF=~cs=gw%#h3meBw0+e&r8ihg<S5&XlOb{mu z&tPaB77r0z#z0fn{x$3ks+IK$(uq1y5<SZC#$g8BR3fn(k%&eoWa9V}(pygRO&?9U z9)8{&MPyW?&mt!0jZ+<;;wugrf3|qu)fayn4-FhS(1sb>a5FY~Z`GMM@k`sC;lLPu z-yLAnnJ-HmDx6A4tKp`KyVTSYRN2p>FZZSL5VbXID{`qZ+t+KTbt&6PlC9ZAI_lhC z5lcC*IzKY03T#JgVtojydW|imH}IWh=^6-EnaPPcrx$V`O>Q(rYGB`*^BBR#<AVGV zaWACz?ZBuho&=7WusL#&kNUky)op)EhsNl8B45`l_Kd>s!4RX7z2Gd3QwZ_xiF0%S zD%KM!N^qW<b^pZSLD#FtC)X#dC)JbM>HXTtarJm(^(p*yx{kpcncw#((>+~CJOFAf zVlrqkTnL0U3!yLNV^;YKe5)kcSwj&`CtP0S1ailaaj=f#P4}v?Q4>sIg|{m+*EY!N z>FLw^sK5rOb&TDjGuNNUfj#KNW+yfBcPSjav$7P&WX6IwBGVFMmRXe452o;AJd_cH z04WN+Fgt6pq|i&Qyn<PbBJxqU-8=7fI|<8+j0^MTGFa&HQc;*Kvzfhhe-N1u+8JLt z8K<l*|4v$1W$QAQYNc=)6Y>+i&FEh(H}xX{;?6|ZLFGstXmUqT7wbp(t;k|qy42!8 zvo^D}!1(f>T6};xLp;gJah8$rsYFC5668=`JcxJEJ9uR@Dj*Ug6GoSlHbcMfgl_>N zOX<T8twHOeYry&vpZ=_HeH2JISHS~iumdoJ6?j8f$!LI*SPY3Vj<6UG2cL?OHr@}1 zGXNEQtc{WcQeoNmfC^Ct|6s(<u7&jsTNFp|s9Q06B!dq8ae1VV1><!XHKQ0>1Lc4d zBN|`F_k%%RyUR{<OrYCpb|u9u^KB+6@g%1xFD!<4QuwW^=Ut&jAQBuD+b=O_XTkV7 zs<-M34Xj*e7^2((L3GdC5rq}g!}8+`!UusdT_}b&hR;EeEL32-g{Q>;Z2llpE0es* zknD|A&q<{ONF~T>LJe2L4org~>SAP{BIXxLm$a0!lE<*I-ohPpQ{Gg_w?4nb$c1MR zj}{~GuvuNkK}gYTW(Z$yB69Cdkb*EIt_<yNDCl>NRza+YR*srvnj--eT{CE4q|8=0 z$--$tv7>Lp`9f1rhatxZsqcq-`lO<8qzs)?HX~ArXyot-A}d2uvqXmH>4iaAP>qKH z?|JdJ+7RvVFpg)dW{*TvGQB1FCcN#d$?q58JIWj0!NP*Q&x@;Ks&L(Un_QJ=W<Aa6 zfgS1U*%j9TCohb+?xMB<n4pF(tQu|iKe(vF&t^UAb?V*+w<D5}uHdf#tcc^k|Mr)g zqr;=4?Mj_O2r-m^5go9^R_71b5RgPp5zuCXJtL8huXS7P%PNp92|Ek|i?oo4ZUqu9 zWp_e{X}4N|i|eWzztuC4M7di6T^ag)70=eh5WZcu<pBg()Z$ctIiC-^!kU2)=vjnV z@KN0;iYgh5*t6g5_dQhx><FpZr-x}j9CY3Q&Qvv5Fao8LT_e36I|cxh31n{eBCFsZ z6}Z?!yxDEv7X|V%xH#r~ZfX0&wQ|b+4_GfIA&Dv~r`j(%T$cuXpu!+GjH5ynW%g|d zF}t7uw_IH6V*yC-x#>;ii%?GsZEMn7+Yc2Q*$;yhzL7QOdEzWFD#~#MhRThaZ&~G? zpBFdVmD*{!Z@Q1QtexJ>GC@DI?c)1rjgCoV6t7UXt-j}DS+7V6buvW3)etc`;OYVn zipq@Q*ITYamqwK%v6-=ec|qBQ8de{#ShXDM%S*-eXtVR0<h-&%-L`-hG0YALXZ5BL z`;(3NOL;3S2qGg9m0eo08YU$_uxe-<NXym{X`LedwF=f9)Y85X)Dp)l@HP&jj^ja! z1iRLZ^kkt8sYYXlR)ruIOH?i3l*v=j*e+~0+SIKZ&=04#?)HrC!O~U2pMq+|o|N}# zEz}~)k2AWhmacKUVtwJZS=vb?E8pMp1_mOa+7-7)G$K%n^*5F~dd|kfb~iGe2oME< z+kkrya|6n6+LzZw(^y@ab=Bq;N%|C-0cK&h^RHGL9CQ<Rti%3Q@<4=qy!I_$fYF9U z5*{}0oWOyxr!r)TY?Feez?`y_hqPMDCCcS^k#f^Zwz)oyN}|r?k@g`>LvG6`t1?n0 z{C?FHk1Hi1mAOQ?EkpBBBNivoXFv=9HDQXmDQ)U{07Y{XKp#e4uxzd%DPPE6fh}nU zc{?MTnZn)zY~8kYJx>mo=PX^H2F&eLUjFcHB}V1>6}~pLF0xt5Sl<@#5kk`(W886R z9CsPlkV<1NNHC6eKZk)_blV1Kf|#eaBfd7FIEUN6(;x&#Tf@YZtQ3EK&zV^5p6d1u z`GX~GMkC&6CUPn?j6v>}y5NcR8%hMfYAlZiL-iLS15w1oGKaDFZ^}qS>ZM=DAipe* zg)X#wyrA3;Gl^3KR(RRr_x^%uvYMj?)6wM;Zk!U@t9gmgIoklrxysSxHbysme{nrL zyczY~1$&&4v_^Ud6r(d8^~oZ~Z9RCQVDca<8l-Bmg2d>Hl0u(1iOmdU`W3P?8GrVa z5arzfJII#<m`-v^W?Vs!^%mfp+}lwrpLD-_|HJpy%Cmgb8f5-X3$wJdBFE{9yRPr7 z!2Q9Ew7YtJ#9CJ9QcfRu2;Ik(|I6OHcQ=t-d!T>gPtlO%ND9KTnPif&fjI_Dh7}%j zftk5kKv=TWwmV2_M=fD|z~BAWepT&VRV~TPOmgm7$vS7Sx~uD5yY}<9@4;`7;N6cq z1E}|2$M;%w74CG?Q8wc7+GslOCL#=hpg4SmP~$^PE<-Ul)3e1zf#|BtSla+xh)8>U zh;bMot4PoqR|I`J0=&z5rn0V}XZYak-rM4+9Mw}dPWRv~dWnY~vciNRK=2;Ne$y2! zKtlmP%kLMC1Qe;M>5^>bs&axE=}USR<<8FuG}-O=e!9}P0y`S+-D}*DFI;UmDOX%; zdl45Sa1U{W`D4%Q*u!FqW|GC}95AY9!IW6e=QXHLi%AJ9b~2;r7^@=*x1`+lMtE>7 zpn;^GM2AgXE^_3$g8UO-7IG=?Z~gr1BJSapnFZAwF97~JH#;Emef2=mHlampv`GY_ z$!HyNL|adM%X!bA_V9`TR&knu=JT!9fz9U*z^9Jc)}6f~Y-~_F?x|fZdc{57(wC@t z>_wslGpwuCXr5gQJy%*0+-JW`w@IJ2s^iq}Rz>b7s;pnUFUzyNV)xR5q44WV_V11? z)}$@BT4lCngwty+wbrU(J7Y}_qWDiO%u1^t+T{SZO#;-x0x@igW;q&_O>?}QD0qSY zSOtDjt3YI+QHB8@d=wi59HYsaI%Qe4F|8WlyYQ;D$Q(duKN-z6I)1SVPI~dWMMM48 zoi<U@84dTGeG1v_8mjXoEBJQ7<JUW0DeWfxQ8gP!SSnkIo{r|Ak{Yx(uX}p$F8+J# zR-~$)2M5L$l^FG>dJBGe{DszB#iDc~v5Oj!zkMzBy^S<NZk$h%n*!dJXTu%ZBM8TD zmL#ru<7;GAQMyN?;EXhI)vPPC+t2G8do7)ki}vUAYxfHMN)?T1$6l6;2*xM3MNq;v zD(nb9Jaz|5Rj3+OJXbm+%PQ=7bH11ahcmW3KCV9MLq?Z-(AfJkzs<K7vXAtckCYih zAP|J)f%WJE-An4AZo_YN@~Dj<-O~=Gr*UANOd+<2d=edYtA4u<EvU2Ldc;EricxOW z9}qjqQ7=M-=Dw|SH&uxlvIo4LqI<@Tm&<xrXHNwIPJR3_zxw~~;jI`=OaC>>vF$kQ z4z<#GedUazJ-Lw4Fb2uv1>)cr!^uQ;tVhRbxRkOJ)1N2v@{FfR9q?A8ah{H7@<y{7 zh**(WQCy3F6wn<&=BY=I2JWuxbb6^(rI#5Sj|(yh;d%1+h3nRFh_Dt`p@FPGAY&nu z>UcOzEed>sk<eZJ2as}z5(yMuD>3#CK8<in+yUJdAW4Rb&^x+-<frULIfnua1U_5> zE;p5c&<iKI7RQcZUd}~YmypY=kQ}W$hT=2~uA-l_<bdpQEDC0V+zDHSe1WFr`~+F5 zsS{xxFWwNY&~q4=&%;EnK&MX3r8XN6tq>XlmBe|8Z8WpWb=V0W^!;#*`D_8G6Qk=n zmo8=l7>l3RkrSfb;*m?tSHCmsun4VGm{RJzo}=T8yBv?*=Zo#)Wj&u?^ts!VfXa>H zAIk>(d5(vph2|>YB!cM>rh>xGKA3F|FT#UdiLVeC_Hg!L8+SlLp8N+{gCf2io}D=w z^3aJ*UEki1!J9o=WGJGPMr*Ex^@JI^uy0GRA<ZdSy|%K>)>`s*j`Y5E+eXJ*dj;gd zcucYl1iyz|EOb^;eP&f={_2J4w79&mh%?H1;)VdqCBLp!Y3^uM!p--cqj_N+Xzt$F zy-^JAb#lsee{G};3HbdQ4Rw&Ov>yS;8E3Wd#*!ySr0}3gzUB(Gq9?StA&?bGN&22W zbCp?WWq6=as=v5Jw>4~gz}{`tTGkZ<);5yP@EP5FRfEWb-Dtd8U(+_5*K!UVhBI4b zK3Zu%iUrYtY?1I0S}sJT4D3<;P~8imt%fWNLAhhKjAF}hWHz>XBRv6^_&`w7YFBMt zKN!(Og(lVQ)>E2Jk?gSt1JJWkqCn9HTE<<--G0k!kb~_qMRrmpT(mB|Jqn%{MO7Km zKK>MTwg1o<VwDoWe{`j#^Ye(Vf4OBs$3W#HXuo(J76PLhSFDtBDoFciO2tUt31)YI zeYD_<LH9<Wdq#C7ppT^Q5{GZbvau+KvI7Yn&w{8a)F}Wo6XdDUY3Z&C)UkC|HoFmu z<ObazY+Z{(Gi=9K15#<PCpHC>=jO}r51w`Ws}^5R)XlQ1r}VHBAy!4byJ|>^*DLE_ z6!Y-^dKe0F*hAKu8T$=yGKkr(n?^WZ2pOpy*Mhb1*k_0x16%5q>&4Rths96T`>Htj z{xPySm^0O}(Zgy&$y8ZJX+YcnHr?%Pa5rE0-mM6P@rx5<KDjmjOS!;2u}XP7x!?hL z#7&MxAeC!TqRth*A5NSw)?KetCX-Qs_1JHX#qnK@qHy5dt9e=eG@QJT0&D1%+`IC1 zRDdmQ?FCx$q-NuTHc865B5cS6?}S11i+B|MBJQ?Lp&E5e=UfdjK|ZzzbOny|1jPaP zyH!*F2!8BK7|`QG_nf%om9afv6tffdV_US2Aaz}05RLqj7>ap$T)K@qit;P`<Zin9 z{L%@Svx5FcRVt{rtwF(uVr*wSKs)%7_jy4-Lxd2^tvYg}HRfnup-pZMK}Yg8-cIt9 zR117$=}5zA3zm~4@F<w|ToZj5Y+qI0=U#^>B-hVlF#I?|fgBV3-lotb3`pW9Fll$8 zHvdHR_^xWfzvt<>%PsonM^U)f-CPhDFxJOC|IH}c=aQQ_dW>KBAxi$wXEhpw2{V;* zdu{~>P8=Ihp_ev9i&_pGJGU7h!qC%8;&#GScQ&sVHF-|i;N++5xS{r(qpeLXiSQDO zq=(-0X-lA*$GFqx$Z*VRDippEsAAM~RUTCsm7l5YKnD{a)#Hnt?Gx;I*v%)w;E;#) z^nq3qsC%|t$Q9DyVcE{dgh}QU`JR8LD8QcCN-G~OLWphB<-HhXB*{gn4g@-{kbeW7 z2`eRd$N{aMz@qO=6ahK%ha*8&)bT~P=RJ!3moevWG2zyjPF9;rvh~aHN}Uyuf$wMI z5yQ?c$3X$RY=lqH1gr$eil#vgD{aBRkYr;9nXct6>%;kpN{Z7EZzAj$Dh{>2mH=%8 z>yu1-bI0IKC#_NP$*8KCsS@=+RAHO#{Q#Jrrj22eimCXf43amK#}@I;8Y_kkfcC-) zxJmf3ra#fB_XsSbbJ<gd^H5A3FIcM$j+Hn<y0b7nJDg0@<JP?a1nCBCOR7qJ?3N5Z zKKDriDRZ%YasY00j;CUDH#)hvmG07x`urIKaY!p~s)0Mt)&tr<Qu4v4&;uBiSRC;g zZ#b%4ez`U}u=Uipjk?Z!4Vq9mTJ3~4>d9aH9C!Lyv7$hxRfaR^L{6$$uW=m(-vMwN zK*uLM9j=e=I`i4ZU4cgD8V47HPLf5~yG?QTd`2OeZ}w9&WsC>76!cmK+6k;6r*zN0 zOzMp$od8F;;<_6@2$Uc?jKzT!<{iCO&0D2WcI+(PmF~s{fEst|KR{+PG(IfPpat)K zIiz&=fHaKJ!BR!#lZcZ*3*6wCkRL|NX5sEHUxlM5Ku7*)ld7<0n+zrQUm)d~*E4_H zg~Ln?>kLgX)d%<h3^ZjqMII4M0&v}**2@#h%pmg_Yp~JzF-+aJ+MRIQ5l=3>XXcO> zfUDFQx%rWT_f4;`Oiyt4`8{U+u>T6CKRkfs5X*qbn8S?#+i3?4{{E&JxINq~x^W9$ zH<~%xouU(M=E0lh=5IHz$x{SVkr0N*Gct?N+4gTFp#JWPGnsVuW)U&n;ZN=;Qw3Kt z>R$_4X(K31FLYP;Q(oX@X|J7C{&ZZ+HZZKi*@e1Xn{ZbNyLtp!h|q34rj|HFULAmx zp^!^wJLZX1uXGL4l9-FRCHyd?DybTRx~Ha2MYAzD8=jPH{Be$Z5$-}39yh-43mA$4 z{T>kphG3m`9ivn+MADmLT%J+h=7PM$kn7pL5{tw#ZNejgW^fHdL(Z=anSgEIhl^ES zg=?4#<sR6%(>OtHc5?5fLY!#s4ESkB@fuBz*WfSY2wZ{bz?CLcs&PG%_aG4pwgoW` zjy)--XL;7ab4GZ-U+N1!We&2Jenc1iv12m$uyW)NT+o^R(SD)Q<p<htB#K}~v-%xA zZH!Qo;VE8bNPvOVr0!T!pzr<Q6Ra-Nr^EMhg4nr%y$F0^ok4<++N>p`6=&?gPd!E; zbn7PEVHgGg-v002VLdnQy%R6~;Jp3N&G>>Y4XOv_c<;L)V~GvscX31f*MAjp6dk|P z<}3F4K(cZ?tR?}+WPAZ+go8S88W64v#r%prFofH{9zq@rU?RAyN?t&JfYCNe=lTLw zL^?LnW9SVIKViJsAkOurfx%J0#`>0H?*K?<kNi6}{c*7zP6S`sb4umMs_`K$-xQMS zrrC-jOj_!(AvW4WebrY&Eqbl)V&L_Po4Bq2BXGUqUi+|h_Y#$6BW_u8fckcWUkA_< zQ&z%jI^*ht3O2$@4Id0&+IkeH7EzAOyg+>`aS^;DY;BG(9X+9yT1Eqxr4ApzjtZGT zD$pz;Lzw%&`S1+4HbV6boscS?I>%_iz-wtJ@peQaagvR@!zhzY)hI=Xs&#!o6TL`F zfmAiJWxdhT^kv~Y<)f3#gNkv>t6y@lMKF12_d-hIE()HhngN;WF(Bm)8}39Jn4<+E zT`Lnpp`bu+Lf)N48r6q~9zZr9)YGXe-R)2f9Zo0R#}FnJ+Y(=|aZHX6Ius`|<m#KC z-ZS(cz2?T20t&N#lX-N1lr_am0>$WtaIDBX$11Bk0%E_of_=40c18KKPOpu?hURQ# zmqwKFclgi0yj!pB)fzigod#cWIB%X8p`2UHJ#*2jq3m}-XG98DNS26h%D%F|xI=U0 zxJ9+c`Q)-FU2a295_~R#<H8FQUURGGaA#WWIii3`tSqEP)ad~w`Yh7<G06pJ%xGfb zY0-KvPHm~MYlo97F`PKJhXNF3f-C#vjPL^V#WU{$zG+x)5-iv+JZb=_{GoU|c?f=0 zHlQ#ZUMDZwJw$f`_c#~ltKSD5vv{fMiNFvIE*Qm|hFC%Ufz7gwdL4gsHE$L*qHis6 z=CY%FAnqW<qVbl)qtH~m`^_x$MHj;fA%V}GmGkI`_}FQm>=V^AO|vW;+R*50dol^p z9!fawqk;+rL=+6qtESW~o`aN>SsXK!?4QjGm7QhrNp4BnkRXZyC#+{!xuMy4H?0Z# z5fHrdVH~;+9T;e<PFeSGY|M^H5Vg$P(_y2~>U-LY@H!G70Grq0k>l1qrmJlQ*Gdbh zxTby>75j+2O|F!9e94HiZu^<3jWJdXqI0|kEAAI?+S}-Mfr7vI-GW&&|F_*NhjvO< z-7A<__{(n<H>ds*iNXsvx<9_;PMEh-eG^A4pM^fIqCtp&;!AEy=S|&fsJv|f&W&nM zgX?wfKY#eQBr07MhRnZ6HDF4^^PCHK^p;*GGosZD`&*F@Jr{`AHtM_~aq8XAAaJIe zs!B!NLO<^nI{*sge>-wk?1kTXLbh@_+K8Acwu*$=nQtLr|AE;355(?&g6V(BV0tyW zy|v)Fo|mnf*gq@*+A^PKkMw^~9{#g2+c&0tx7UjAuxd}P3f@T!rO>G++I+$}DuEDf zB1*nQuWm}fZfAld)8V{cvgfK{Lt~TV#9vLafjxVQEH^5S!DCAp)rDA1+o-+VR-V+m z;YXK?HxR1JMGU>PrwfF3Mh!Z<!ME#Y<V)W}m=564<iU`Wk<a+TIdS!SBXR5LAuV(8 ziG*>U%!g;EVvVx??3<Z1G1MkoN`>Nd&N`3<+E_K=MdF+&3dI&tz-JIZc2`7$$WgIR z!I!LteBjp5)dB}>%sUAaxL*{H9HY_rGzqMC1P&KpC_og#t=dw00K-hm_P`jmjPI^} z5TSo+7!P6BGvWTTM7bZFB2A_t_i^4iGA_kQQ@1qe32uu4OhE{mhV2_dPPa7Lu~vYz zxq;HMDzDF#C9T|&cMvuCmzV)=lhV_;tB9x=X;=6_@19aj-T7}+tQ1)eFnW6e>DT5l zGi8a9@^snYLNo+rla6xYr!VjA0CQ^l3e;)5nuZsB#f^WWau$Y9G6Hyln;$vYMHqY0 zXPd$BF$!P0Z@>*+I_0M|vyo(KQr3$7vgdMRDFsKALW`?txm&;y3~DlWi+iJXL+$H; zzp*_lu#guVOr%O=#h++al$yHI(gv-(Qn=HO#Jg;(MU|oyuSS!i8qqE%Y?DVC4nB8@ z!83(wOmc*44b1iHGT7h?77>yaiaoxcL1X6xGx933p)zguo^lfVS%)k;kEJq+g3DJb zW|wl3KaLcaf=n6)r>I>WhjkR+CXdjk)y%x_#g!+8x526jaTDIM@6W#)xeItcLUtZc z@}h$93<z9N`zz*=aARcVGVM$8-%VNS;KqM0tNHt83Rhu0KfypX{OVl=yBgg+^B<1u z#fQ2YV^rkrot@pm&Q}BU{lDer<rda)i(0-_&2CNW|8dOiaG)3S1;knU#dJe&JA>Mk z1$SZzUXE_5+>KqLm8|>_W2i0W7Y~RK-Ut48IKN<Ocv_#k3hSktW1KZtk&`p38R{4C zi5ymCv==RS_)N%buJ)wDl{Wsrl%w}GVTU$s!I529lpjas8R?&omBWyZiFY+DYLDYG zT(I{d*{#RHqz*jdZ@&Ken;rkzec8IqoKKfXThSK>Oz+}_qcCxrn%Zy`UKGR0`S7Bl z&gi~?DhpzWPK1B<!$Iu}I%Kl`d<ZPajHlqd#w1$RtR$D30eMpm?oX=O`v61dsQg(u zM_)T|qaqIoMtI?My0vST?bdEq+3175R%Z!qaR>C|{|7e)<PCv{v$TP;t{LgTetZ~K z6O6dR$zYWjR|TFfcx#mzQJgs29=wK`A|nOyGRM#oOzfm?7WM|Z4irUL@Pv!k*di($ zNxpF4irtO(0i4o~w8jIsiWB2@cfqFVIbsVckzy~bbn3BOeM?m_f{BGwQ2f4z9m#zi zLop;S9tzDZr`xw+B)C^mG!LPJqIra+I|uCtDTXORdk9PC@x}GJrI;c*n8Sk6<NO^g zgtg$L$exrz)m`m-YWP!Y+6~(e7xw|Cpt`5M0dr{Pw*4HApZP?sI>wn~p5yJ@wnH>* zP)cAarh|!Vip)$N;>SL=-gtTs!QppW4l4XdS!+Ic<5KKM?->g0Bf#O}%wgojWk^o! zYM?1aLzcqT5L1P`x7+C_cmEDQC}yBxS5Ze-aFito4)4nh-T=9rK0f@$yIgYiLfm$v zdOmjrCl|#9L2S{qxsxoVIb1d$Ank62^O6BH$XGH&UCen&j(e2d!Bt33wBk!E=Nf*) z>PD#%%>}GtbMShprg+@}-nJ78!ZisC${V<R;VDbYu3C95KSr?b*j`Arx(?$X)=XMr z&{}vAj=<(LjvW(SRVn?#AP)7)`jtHs5_~NBz?tM7h8aS~V<s=+e*!kDdNf+jgTb4F zwWD)DNdy$Kr#EKv-OaT=pVQ^z>jSUPVPlp^3&1vsL^MB+8YDBubYO*8<mcn@aZnKq z7a?F+F(c(n2Sxi5P`ei3^gd0!Of0<WH&Q6Eo|ZPGF)~S;dk)##om5|?pDX7NlHy1= zN;4<-M)?u!@zuhxwFvms#vMazFJB$Jc=hhp^LO|Mv)pMbtVM8*`8*Eobsj!@2sOHY z*43xa;LG9ha9)XvFwnXO?#P4d>&(%r@`INaNiTPPTDfyP8oKMWQQR_u`-mPwZGXh% zUp9REf<~`8acuhpBWD+~dt$xQ=@1FxQ3(eEs~v;Z6bda_du;`Jvj{oHBC~*Zby9$| z7W4ixO-WCDNUXFur7L5NISfnyty-HVBfGNf2_t?X^S#<|;7Hv0a6V3zJIQ2MjTFXc zNyun{KTKf16(ezX@kcA<Nm0Ri$uXfxK?5CV3f{9m5wXb!L+2DaZXI^B>z2ru{^K>b z(lf^~f_$NUz`=B~JSl#&`{zG=_0`VTDPy{ylY3I0vQ=N%%JID1h~weIpqLt+b;+vA z<LR0Qz+0Us#+7By?1RaKLPfe7KW%$Brjul_(>BZBft+FESwnj(GCD@)N(Aa;-NlGF zB#7CMc=w}U=fdkK1vV8qJiIU$pwpCn9k_BiJwPq#OCtB%^o4-{4647_tEg|?h|J_s zMVVlz)E_Yg1ZRv_xqE?DvZ6rQvx#FA@rO7^`hxP@2JcqG-Fb#(1>wZ4VZ;>@E39l{ zl9Q=qAr!w=o{U*J!7B>7jOh@lCn+h8$_4nQ5Y&a6hx@MV!EAi^aiNVt){QF9J`{IT zk1tu!xZ)fnsgNG+Xca9|aVI2pYYTI0a|^RN>*yQh_Z2nyc0Wds&S2F=$zEhZh4v)F zXItowknY{yCQ!2aswEO0K!8wKiq!TN%fN6>F$prF_Z27(h+!;}!uB?jD5!vdqmTek zMNo1v$QkI|pB1958~|GGe}YuZ`Vjz&d#Jq!yhYyo0c1e2^2UDSQS9ygo7(gxRC$O4 zBGjZsI{pEv&n5=OXnnLYM$om|_9Y=sH9djru$hnciVj@X+b7krd$On&knjc{(GLrv z!VM^v21LFrC$qn$%{by+qh*Ze5)+7(*vNkOWQ}nn10~}nKlX{Nr&I7@1nn?fks5;e z$Wie%J}fQv5w*vXjqzY*pIZ9!Wf(mkr~^09jFdn>3(im(KcY3hnwK}N9F_ipd^3GX zNSzZ$Z7Q1g)!8BF4nWSPyMc(Wu;p5V3<8u-j-Ufc+EO$#d^$ePh8y$U<7I$vlZ2~q zk+-IOP0_c(x((g5d_CO;)8WNYNh)-5J+-Xgbm%_+P&H_e8=klcZWkLUk#Q8O^1x>7 zPNG#(9QCX#xP@qsF5XR@#kIb{YAD!+z@4H4K15MKjn0c1oS2C}f+I+f6{3Pf;2Sxh zjsrX`P#-ipbv$+pqhxi^3AbeMlMP#=d7xJQCsXSR=10^vt&C5W=}Fj;EtP};J<4zb z6iToU_L?<|ayX{Inc!?>L(9N!r2LLty{OY+dQ>&c#WEL3Z9U^7XrI_ffu2;S%nQ1( z9=3nu$L`0-n*;dgMq#NKUZ$E(-N|zIq@%YG6n^H&EqgK!1InQv@sQ_1O%H0l$$2Z% z>zrboJcrYPulcxM!kHa8$?`pLT!_mwL0~Ay&Lc<l$jP&h>W|xP8!tn(^ge9O{gkOm z5jrhNg*}%LiwqHtdlv|z^(sps4bsYOO)C;@+aney@{CAVrq5==B6`h{<gML~YPVIb z?s7C@36Ik>rH!bV=r>D+TVN9?Z}SxQ$7I@)GAHm~N#CPjA-?C??&Rrn3e&~lTuCHV zFy{P;l^nim0U=v1d_Zfkbn!Ua!mhL-Ji0#Y#g}6>z2i+e#uOZlVuLu&aLSQv(@i~I zi7DX>e5P_&>@`!Td=iHcxj79lzsHI6-2t}23#Vj<$393Fk>0)!<4P;x$EpfY<|h?I z!JJbS$O&+EI5?%MQ$yT7TQ;ZuyTm@A>f^3NHJhmxo=XZaVMiY;#Gm%~w*pA577hED zjUlFQkx;<}%UoaDdOkl(oY%sRT)D`mS!8@zS<A51v}`cR+}TWktSKBed)2VMFVE}K zK1R1S+{dJY#oqzbk}g{IRzhEo7eS9ora!UIqGH%zwBu?XP|s$fhf~?{v`QEQ|00G# z9$}*z-YK79Pj$2<orWqA>|M6eei1Vl>8EjST9jG*#I&>>3fQLo;HYK%sT)?`<=PdT zJk!0L9ZZ*qZET^9UU7$gb7=$lAg3=A76V-Y#o=7cgK&ZaM7&oSfUwHVp&rYaGJ>aQ zUl0p<Z+Cl{6Op$<9eylF%SG9sq6;&Wd)srWp2E}G44e>h2J+WpbSluoL1RUwo#^eD zKVJv6MZUrkIL=BVR(bj6hn(k(Vn2rSljZ6d8Yd5V#eN3cPYM+eUcL-Jypr3U&&Vn! zi+UNl^uSL|MH&=FEkmHWC^lVWQ#UtdV?5wPIEnAFzG(SP-#6Q~sd!3X@(0a+WJrqI zfIMc=wn^Rt4mv05j%(*v3F3|GatF>R)zVR!5rTRay3W^4x$R*&Vpf58q$a+mMX>>9 zfxhJt90{fg9%s85;6i}<!pZVmRmRS~nwW;MZBo>bWJ$d1Yps}4tb_-#I%^|cqdYEO zk(O>LP$yb~*HZMYE=ssfczFGmX~J9VmFjmg7E{+Xd5VOzUwoROHq7>PuLzrz$Gazg zTn630NgSEkQDHcME+ah*pI?S=<5gbwX%egvr?ZT@r*UO0wSz6yED)w2`k=N;Je*Cp z2`+8>fOG~)h68Jzw=la`T4le+3=;Np7Wpy(s}nnU<o0tg4uraxRL!Dv0!*`(Vx<$a zz9dT)I#d0cFNlZqbG08akjGX=8qFQI;ib-&>)#gY3;h$0GFI%iDP++kcRhx>@Tp&^ zneR%JAn$Q@=t<=kiJk=`zU_}qm8*b$_|WA6hBDl>tv1XPy?8uZ)IV0`xwV-%#(7em z%wE;6>N7QE7yaUcEBn1;m-}nNC^Pb6`1o((&+jC~!ruzy-HZzT1QX*aBM$ZgVi|Y( z#YOmlROna@-AHhau>wHW&AfK&r+<58gI|n~0FG*k(2pnOF=D*$@VZ>Ilymc@i$#6Q zd_X^Pnv72$_ll2hxO>ILW$cb3*@)a-C7KH~R<$|eAkw{G+298uAB3eq4F>+AZ5jvE zxfNZp`!nZD`^VTf2B6Ho^6LSMt#-rqMR7}h$Dg=&H)T)p^!v>Qov_8tS&WMREmNF+ zyUE)RGWSJsCv0t4cId(FKf2Q%p56>QUP<I_mAi&*rQf>WZUeYchp|8#krRoH{q-;8 zn{Xn3<R{%Ismf2)OeB&E#pZ=+w^OTUO8(xyFt5JTuTH%mw;rCWcH>FQ_1Di^7s<jV z^A^KBqJsct;yf^**tj|V-+n=V{Ed5oR|Ly+K@>!o2B-obJ(|~3ibakq>C+Vx2Jx^S zLHs}<%_f#PcF<!cAPT%>f=e&kv`s<P7czm&>KQ7VnSL}+hiCc{Y#b9b9g<1b7L<E& zTn87CS7LVAYEOR-#1|5wb#1Eio@n>48|}DP!<op5IET-QhzXm{CrYnQP4-rvA{pEL z7lX%7|1x;|?E4>H1syP?$;Oy03``o8lS!k-o=oj)!#2D{x1_<}yRRO8e)U~XvL=`^ zy-lZr{ojp7&(4NfkATqiq7#8Y8=zlZUt(K`J?w4aO=gwie8|ThjdqlGx}KnOCU~tW zP!F96j}-596Sf+;cfpkMUw0r319qEi<|J{odV?z!sZ4+2&9~EAORkGZ_e;$~*sWFq zL&Pop23ru&j$p5NG^{41t2qV$21piRkQd0toF*>|KK-obL5dRl^qXt{ZjR}-^JS)s zYz#ZCD8M{fR1BL+pdFL^xJWM{YII&-q<p>vHEXYLe3l?;a1~vjhE8R3eHj9pua?J^ z4?f)vDwS*e{Qp!o*B^8$R@CdbYX<C<!Iwe2z-75YX4SKK^<lUuTe7U`d27vYstaXO zoUTeW+Ll2y$pX42?I-LVFU08nfL^I*6B%;gha2d*#3EzfTTpf==nY9kOmCaT1)#yP z?vmA_Xu+4LGuERQyd6nb3+at~289Z|j$osKH?<Q95H>HbzU9i=aux1^4?wf<$pocs z(7|rEeRSI$E4PQnE58yE=t$xpUS-ooQ%Wh1X%wq+`NUK8QD*2};t9md1x-Q<9%-hG zx>(!@J@{p~saNBW(25(xM0Z%#5W*6dAA!117&yZc)Uy(FRkZH7L1<yOsZOrhpPy@O zX(c6RHzEjz76oE03lRu|8+-tU$>hL^_N4z=U{UGWAeQJUr*>nsu5gOzd!rskof*p@ z<}-CR;WMko#;Xad^Gmb6sGrp5<@|x8uU)NEd|2zl;%8e84XlDN>k76RD#VoU&yTyE zckcGP&e2@dHvH<~Hy!)T07XE$zo!sSUaEJJrA;wqJTtFn$TE7VjAld_Tk(<%hFlq^ zSlOtS?2a@<h}O7?NznTeBsAIvA?XN4e<4fZcIZZ%QFfJUMhHhhmE@J!ZvV#9jrNZ= zpc*p9)cTWbS+1SB&~%~Oee8(dyf`hi3Ows@@!?j1S%QyrEYfor`zh088dV4`{-E|6 zd<Z^v&(CMy&+D^t4m_%n3a-(L+{IdGi+H6owPfq2dG|>69MtH9Gso(2Rd<UUKEvOQ z)TPJh>@VZCa6~Y)VKJ_bF^lwqDpu`5A9y>v&5v)d&<-czXsT&7k-6V83VA&j*#s@# zmf%Vjx3Rwgdjp>BrVA3U=<R4lZ<`g}ZC}ybYgRNf{v5b_<Us%$d?ukl%Vz2t+X}#P zW-mu%b=T3==+W(7Z{4*9AewY5ZP+T1FZa7C@w;wH&D{B7`q^VwpOwXLtK#c=D`;I2 zM+cH2KS9rPnhliBHz;|Vgob@eUd>Htw(lx(!|`-6_#Qm`%5yC;s7L>&qy>+=6vTxS zusaPga_o#o-3a3YuQ{Wihzy4mm#_za`&j}_T+<+`7pd9Y7CEXXV*pBBD`~hD*yf6| zLWWwQNWN&3AFd)UWV%ix4*BMRT=Zpb4hhg{>a)aebIy4v$z@!Hm~&U`gpb^6ysZ8w zR6-{h?+x=LRO(YE^80s9_=NnZ_yzQq5>LX}k7|qT4SZB68So`nC79X#sic`VHSzax zUpvQcV7HEk?q0Yk@bAWrlKwg;3miR#4^S;~YwVbbIcY#T#Z4p~nEUtEVm_QTF!O+w z#{twQ=w^M3ACUA!|J<4n$JG*DLcu$l>TXVl<NDkT?geLU0<{c?#f0kZWwNH^)OAOt zj31}c?+%LG{n3%b?gyXWfTz(t*yg;S-NEm=Z_aP_1}A;UH>`W`fPgJf%{HiJ*jt5L z3laTr%Ixeje-QE`-)PWjN4Nu@u32K7@%MtDr@Op=z3%_I-q0B<m9LHdc)j!14}h6_ z&bCRq!q1=OHxCE$L_>BeocVA}jBi_)8Rji-`sP-d(k#M;4gmuwk8oR5P91W^0(!kX zab|YWy!RVSg<*XN-gZIvoIc)k;N@FUeVN`XiDhlqL)l-W`+PHBvHzl{Slf9n825bh zK3|7^Lf8saWV%Tu^>Bvcaa*x?945M-uZKr;RdvirF+oe%l-h~>L)9!n`gA*V%WenT zgHM9|zgKjIM@>ChVn(@1dA!&wZtZ-0<o-wA9l^+SzaC$7dnOTLsM2>3GE{LUmk^&1 zG_ycT%5X(Pl8QjqKl{kyJ`4oZ#pQJHJES1)x^>?^KHLL?h`o1$3`=`G?q#1SITY=v zpp2xF!P!T#nb>!b1R8lp$6j>fJ8u_#{>gQKJi_!fvfZ3bsztX`bhMVi9E-UKN_G_K zj#sX(6u=ZN5zJf)R}9ZKfewjO;uD{eAf-N|yN4HH*#za3DCFaN3e^k))zs(t$<gpl z^ZPg5*MIN5z1eqv?!4*oG}<GO9cH>%$zTHr6eZG@?6sgqKvYA%;<1B$FEq?5h??^d zcwkR_{_y!;@u>Ppp<726?$ZUM3e1-?z_L=>8FAcO)ZdjKc_>!%gERD-WBgyI1u@(B zIrwR%xzyNbG`^z=c$@z38s857Z|(R%Y9%w<IcdR$lhJZQDM!lW&<o<km~kwp!`Tu5 zf0CK<e3vl`4a(`~-~Beb%ZO2o&bAGa(j(9@fr6$OI*ag;NQ2-e`M70NBuEk-P3qx7 zt~;Ow1J}E#YmR*E?(8@!;eisQ3M$})hM3^oEIMZ&J1aNQ4dNAVz=<?Br()9~C-WHr zf$Z%Rx6eNAcNAx23u3*l-Mx-i%(-9mLGD&U8*R(g6m<dks9UGVGVhUJJ7t4bc|GIX zgSpU9k(Gx(k!v2yHhW6WL1Ww11my3W2yQHD{=v@?j=%o@fpF|*em<|zHo#1_`*V9U zp%y2pRiwqYIf3?IZmncsMH9!f<i*2!`u{A;`GpmLT^0R8zUddg^|G*IWES7gYXG;w z_R%raeOOHv=)mGW+@>FWk(=RBA~m}c^S!OAOSjUg`!h(+r`$%|tkRnzi-_e!$jp{? zm7Mwxd+{V+mV8&SCwwM+ztsoaVLGwYHgPA}I@RQcAzp(&`GW2V6~G2F^K-+U)Ehb& zKsAgWMFc&S0cVh$7>%PPeUc<e5#WdA*cSJW15|-hSV<MXgvW6#E2`XJfyKN+m7|^_ zEqnbg;}c(+#{W@QGp>IZzZ6C7Z@c(I2pExee7Gx&akq2lXnqg=zvCalN6Hf+NYgkB zH%HzJ6Rio)*yhx9JMK#+u&tr`M-pk7#Vt0Gabmb4X$TL6{3FwZJ#tH9=3n!%VJWVu zX-Y$ip&Z>i-XWs5Z;83umwS32Uy+<Y@~Q$w&dtOBQ~FNykn`%1qMV(8#sVjUGZ_)x zt{R{F&TT_fXW@lSs1TsbbgR7>x_<Qo_X7=-i;)l1N}|HRm?_Q|Xm#c`xf=jDdbD&~ zit=y;&npJS@4#Ys?l#;%#iTv~cMd>}3AxUT@e)nV6<P}2j5HWiK#(>^%afCf;;1|w zx{WvY7nr@Y{5IIq2sEJR%_7JIt<$_bfwtz|&h%omY!>yD-T|r*eqR)%E81gCQJ<fZ zR%fsHgsl4>3Jb_gUt)nvuRmVb16;JEdHg)Re*HKz{wl$JGr4Pn>uK_8m6uEEB$HQR z>&Hgt9X%(;!799cr~4{avR@>QG`b(`R?`<PexJBHq*rLFro-1bL34xvRWs5y^HCD0 z{p~F@LE~<c(r#mhy`&AxvWm2RmyQY-hYVZ8)scaj>tV?#I=zb;+Z=fEsP5EopUMFS z|Asy}&XUp|BPO<d)HGp>yT>7Q174ke8riQ`#h`*$5f-YNA00^;^Y`Ss%g<2d!-eoZ zVY!}v^;z*cD#sA5AtkUItof(6@4zwd-I4#sXOxOFOyS$d&whOT^6~vAhwmPIcklvK z^lz4r4j(=0;M=DU4&NQTdiCPni$l=n{Jq=EN1spU<?&}chrQnpu-K!6CoiD@1w+A; zS1*2m2N(etG{zJ-gaLu@5N+7_SID0Si;I4bUa1kipp~f__#2(MLx9j0hPln(+sDoQ z`efP2#46LEYhtzS5O4FWL5Mo-2(W(&KkzB|efp>H1D`VDrLO~jT9&LrS&RK&gEq@M zw8SAWtZDb}o}p_)Vo1FnHkzAE-$ZZ{M|Ra}Dc+_$o9i9UcsZG9#~^M6Jfy$-{OVzg zhjgyG$4K6_yYHtc%NOd!{@#83^e-D%n?$@uv4dQDHaIrK>e&F<T<39zdGm7Gb&Hv^ z>%-A1f;R2Eb0qB@0`zs#>iPO+1whx=&Nrsl{8cBjMSZph7ZUvMQwTfkEXMuCX{R4< z%MNH^s?l(A0H1ZBNPX71B(H_H{Vi4Jv>J~A#P7?hrLXffAJvNmFqvOgGkqP`j1`k! zJyY#*b+UBaGvar3`XQa#9+N7uYJi#^D!K(VLBaA7ynjxzyqgRlWOOOG1`J$>YNvnJ zKi%!0-tM1%)j$11|MZXj)35tDvi@S;A6Fmx%SpeU^e0uPFLlUx#kB_Pk~m~nD|SZQ zYvhY+c3RG>#hxOz=vIS!29J~b(zV4O`cA9fR@0L{($egdge5ozMO;TZlACzPb1xu# z^Yy=YW~kj?V{WdzW4J5p_KcnW)f4Y-H^<puz@CRbcOXQ6?iiUTxXnAm<)Ze_UZ4h$ zA718~+hC<Pu0GuXb1LvloIR}Sf6d{e-u!PkebkfO<U?Ml>iFVcfBv}PpFKThNFXzZ zp#<@70eQn9yCZ6aaJx)8er6*vF-#x`-9MGQf6=$-GX3Z%sn>Lg1o%v+%ITMN2rYE5 z39#Z^kE+!@^7wwanTi^O6?^F2XIugQvFmN&q;<%~YYvyMYPq@>;9T;)1f1vP$?2E$ z1kD%x{o2k@YpZ(%p>V7cXzzyT41R~U7-$#LuQk-JRR50MR!whCA!KHK1HrcY;ES7r zZ2~O$s&=5vBlMzDO{ni1#8g_d6|qd)*YA)zXX*&PDL|yKR41(lFRp(s>jiY<h!1{v z=;|S4OgHr1{6T7#N6lznoh?ismPg^e`#M+ROiGLpk|Vr=-<?a|FR&W=<*=i1JMgFJ zm3s?r2eN+SvOL=h;_bC-^$c~(X@pzG9ay5`@H3K(V|0h(=>q&%=1qi+1CLUlp!em4 z#yl}@K3JVAVBBI1gv*xh5e-^8)qbxW^@%R`%W1#r!>;Ks`*cwIZk62spY_Mbvp!6E zzZp)?`tOg%eb@c|$Q`6Uh}ivq_Q&O<U(FhS>DVckR@KDITzqt!aU5MUxV_%VD_uOS zR{OP_+1{_&Yq?+WK7Xq=1xCci+rsus?UG!Jzu%xauAS>^ubyb(mWnDtUq%ucy+WAW z@mSC0Eft-!;&it-y<MDsRh<5zIQ?UB`gP$hX|UPN%ccQa1O6T_3P7N7i`ii(oWYxB z(Bg#?1XePe2^FAU_QVHEM%;5qJ5+F_gYLMmJko!``;5fyM)KG4;;0_Z$1hLo`C_yT zg0%qa)EGB_{)vs0!8sa(mzjLl?M%zX@FwsL$W*)=m(2)%+-L9QwlCmb=WE}8^O(4R z6<@(U9IkEu;Sc^I4|9g>)g$(ilmWoWZ?+^h0(4nbaktprcmLeETYT;Qy?N7voJJiO zVoH;n;JZ-u(K-2bhw8u2VhQiV&MB68tKo`TD*IDsbxmiTxB1!N@Bh5!d*Cfs*YM4n z8hF!lE#j2>{qks{<6&FV3b2#v(FHkwKqmId#H*I8<6>6R8wlzYpud(>0eKWY{Mx6N z!e3|%a<9t|rE58k%{-XThZh5h(9*v+Oc0E2e4fH7qa^Yn5}2GjeaNO(x#?psN-*fw zw^A2d<oD!vnAtFe)P9q;DRY^dB<c26CKzpCCJZA&IYk54OV%(nS%K%zWPD>gTMy3I zrF`XQo_}+c8_X7zD}om`x{p&XV^=BW_kq-IN3I{!Y5_?Y*pbk~Ga_Dknj2g>mm895 zytGA6Y*OKoSGW#(geeJ*XGs6KGNIvAt8p|=sk!zTSAb;(F@W+xjr@F9Gq9E7Bw;w} zc+A-eeN-oi!=*|I75SM90Ez4?x1nCsUp}HvIU*-RGKsNXmJ7T;Lyju+?W23Lo&}sW zIS%Om2Lph_;B<dgm@ZCoL!s`J6Gw7FB}T!3?R4VU-BU)m3`IjKE%+*wQ;~Q)bnGkW zj?rkMxIOc}xGv7`-2HrX9*q)=&~p>@Cm+MzzN#@UkhGR~`hQXL#2bY6L3<uI1c6_s zrL>b$P0^Xv?xM_f<tgNM=Dmb|ywmEVr+~r?++?<C;;8E+Gg+!jYkEYr-_?SEf2Wz( zsEF?IOPqP}#fR$zljfz7qShIotPb(%_l^5f(Px3nyE({#6zWqN+^*<%j00lG{SPyt zCs(8Q%UPb{e<`Uq)HPI|v%iJ)<&pX@1d3=i?@~KleDnEMIl%dc*<;e3m1E*d1glbq zj|cyDs_u#FE#a=IXc@IR;k|UzFn~MA0IFJ;v>JXes_1p~cANEkHb0+%VzuQnz^oZz zxFyx64-HLhe6Nf;N!#EMcig|(7gp4Q)^kt2&=OYChnk7mKX}#89B&u}q;(_*BwH23 z=P)bb7hb)A2whrmOx@jhtY_r0<=OoMRxHIsw)(aGtrl!AZHf$#l$l4-M?Pt_X@+)Q zW-U}j3OO*DP+SG?w+~=XrmDcC(1%U*VZ0dq_<O^Xtmr|qsyOJM+Zli}>a8S#2WO7D zO43@7`OOq-0}rv1pjmQs5}lhiAd#Ul{36T$UZNf<@Vx*$TObyJL`N!LG|nL^l$<jC zVciIpvS>w{Q4$RUppaLcBH|F+K)eGsnM_TFq?41EM7M$JEIK%OI@&KH&J*d`&f7j@ z^F{X%&h%V04}1zt#}3UxA|mdRDv;(MD<zu=QGBoY^CWwUJ(w;6U$t*iu~<qyU2Kaw zF_2sRG*T_{WJEz5#6eFtil2-_BFhk2#Tz07_^~=O3mmO7|H686jwjH_!GEUUix|=% zVMGpv=@L_3gA*8iGq?|WT?pVQiDS3Z)9Bb_pJUEF`*Ao)U|Vo7f?Kd}v+mF*Iz!Mz z>0FnPA~C{}>HCJ-;P?E*Zy5cV*YsX>_I<0X!!}LiX1;DSMK*@BOoKP$_{}m3+{~b1 zo4_dY#HHw>X0Nz&cJKA@&fx5x`{V5q{88MxM^E4KV|;23;BX9fOb;ISs{WBO;Q1$B zhwncD$UgrXu<#H~4>S50jH5PyPbjzV+2$h3AOl|Bw;i1zVCf?JvX@7TH0Yi96gHqp z%=b(>E9Iz^%_=ps3DH6&yFiGjSDZvg9+=d(5nyGmwJhe#0j`J6k-?#CLrkz4;$2B? z#aTBoW0$*+{->PRAW%avUnO4c)yx7@N>f7?=qZV_WIp6eH{`n4VHTMXi~WG5jFZut z`;fc{QL;<(9$I8Z&fX&#mD`e%A<RU1eu#Ch+LimEyw06S-$q;KTY0Sa&YnC>c7&XG zjiZT0RXWaI4l$e4rwE#WxvkyA(q)1dY`AZsr|(2m)W}Y*$)CuUD8Wf!T6~6d5dOk& z-%;XSN&?7MPzNo~#3pGn5K3i1I1V5NT6W*}r4u9rse<Psx%c@a4+j<ii{a?gL>NrG z#%u#-gnpu0{IyEhVaRTA;D<Xh!n_fp9W)F(e!4A12TYqH0VK-6A<0N+l9}6Qz2Fj- zA1J?_@t2V4rC&H&A3OB=dn5A>Qd7jGL*{N?7UL8e1Ibb8(8Uyye+>p5fv1d1j`WT< zQVg8cB66jE%yIIss}28Jx}n>ez)swN?S8|5-LgJ%EDB5)@3t@y$MYcpkH}_GbQty7 z7*vh4!Odt+WwogJWFd6dtT^%qOzSzT=J220u&FvnPAF8fV>h|VEO1T1wjgSYs-D!X z=cV)=tb{s=j6T0QyN3#*HGs(~pNa{1HsgJK>~o(AJpr9usyURmZhQE+G^OnkmTmPM ztnJQ&A<lsN5G_Tgj4Trh5JP<*@>lSkcw8*coHSh%aNnf-sQMo7J5a>7?WUj+B@OC- z{g-t2dO8Kh{oMn0;tLFq=xQ?KDXN+s=9XyfV6Z%w5%tXxV7tibLP>M*ec>vYq{4vS zgYhY|rd^+`M&`bM;_g9|k9_(iWekrDA0Vu*Fn%a_J@0<ViMS9+lCdLA9;J>i*(ri} zAJ#Wi1iCII^qR~_c6v;9q9mnLG8?eb632T}eRf%6Qx$RE%S6fEmhs4^JTjS>2-#p! z&6cHHk*ME*%*K9=aj76=52z@$iFU6d0(AmVVDfO#wCQ?=+gQ%bgs#|$@myc#2o+!< z!Ua~16@9N7jXn8m(+4@+fo0qL>??Y5?RxjRVG!Fhvinc6nFjog-BxULI-EanzYZ3V znHEZa{m0vX`o?x94G>XpGb?-DCIq!dAEDX(1-g~VZpIrRI^sXceeKgdWcLj6sgrtE zc0IF<;auv##0*n4a{`j2Gq4p}ol=gNMt#m)t+s>#L|U2az|R#09?IQ<U}<$j5?;io ztYj;Yq(WR*ED-nla_ALFfCXvU=;q8Od|QqsE|8^x1ob7pPuNbP*NCO!{`A+mnng%y zHzP1BtbwOv{VkRzb{FxXq2O}@qb^WP(QX7VHF{<Y(FF0{gh@M!gC4OUil3JNv`v`T z#9;!45}WY6_Y-BB#4Mlu%~o`GQiZ6!pDWcBbuVnh*35!y#GY(^j=M$YK&v}8y@oEY zxX+@mOb=r>jDVsG@XE`xt*gueij>fY2kyREcq6Zdzw~c2a^VP`n}g(chZ@@I<c^LW z{sgd8FVBXf(oj((l`*_)&mJ(>{>_`&l!ev=Iim5Ic@1XSa(+@WvRh`57^_<#-TWEj zOtg2qtwUVT|6rpwDP0&Vl5`|1n5eFp)b-hl86q);Y6Q%Iz`gLHMC^SKYe<t83{~o~ zL3RME$P5Z!^n&aI{5sDnpA;?lz&x9~ii<`!RdV#Oup-hV91sF0zLRWC5U(8SQSu)* zw40tl*+tklR)a>nDI6n~&!dB*Odu@4Ql1^s&OqiOlCW{k=O|K6my<;WZVcz5^BNMB zzwq$RO1^Uyds(=t-L?3^U5M-$101WX=g#Twy*mT<9}jZsIQ#Q@IT=eqSGliEmYMoV zVx91@=h#O|K<p+5o!J(_0HbM7q*9LfAJ`Ro>MYb)B%JHD$)b>{`ytWX@gy40u%~eH z(@jlEXQS+Z!yp*vcoxtQI$km+$80%0D)Ac2s5^uS#K4!#fOk{LHX%tlL6i2;0L#YQ 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�ej&SqpXWW2ph#t_{XOXkz7|<( zM_m>mW9`eC<Bk>ZrT7?0eMGgKmT@cHS>BBuzO>O8!+ZZo#o!RM2XH1gT*vGijo9I6 zh9{@L!O$5BIYVhsHVl5oYcvR)OWlGC!G102D}7txfuoCZI6W^Gm6I1?gu{tD`oW;? z$ar=L!T_#JRPV*XKiq_zvn|5cq(2V>k7=ofifdns6jtupg4}?`njA(c&B&qQyA5PH zAd^35sFtC7zz#mDsfmI1^U#VYuGVuC(GxW~o?^k@1M2mdl|Gc>I5}>iZv@lY)xnQl z$4=bNe>)x5Ps@+x<g@$x@znnPpggLk=E<w_)Uo0DmY7kvPh{4*igN~6cvQqUAF9*$ zm{L2o(c#0cHn*~wAfxer9A*G)Rs6y2Le0i@m=U%woCk*o>`K)<Di4Q?$^0dy`&OFE z1g(I3WF`@jB59e8-pqfc3o{=|HK;+{Gi~hqFGAUFv`BsgEDxHQ_>wu0@%e=H{`T;4 zvN!^V6glbOtLUA@hAVunL-|fkCQ+><#gOa%a$*e%n6EdsD?;0TbeZ*J6^*hiW36cY z@tK{VH^)x2H1nf$Pjh_f#;yO3=cMi3vg!H1u<{QgVQIr;xR*IyrW7Bw&}}9syw3<< z)b0}I4s$2H)w9OBTbUL4rDq_EPvXzIzb@PzjgLCWK>~^hni4oPhMs#XkSWjDrMT8s zY#z9AZ|2U(f4VQ7@z`F^$-KMXNjXA=93IBlv-+^*_!&H3oE((1+$ltz#8X_<h)zU? zHKNl9z#P1R)cqZ>rJ^$`8Ado2%)u1=x0>R(azf{n^jzF!xZHr4J&rcoKNr>P1F-NP zuujalHOsy%v&Ko>8^wHDNsfL<7uiUHsuAs@_W4?}g`Nz-7aMG1^XkM=XH%ANpV=;M z{^{TU@cTdh@lw>y^A$uQp=V9ZhmJg&>R;t53jQ0rT3nQZ>FX&4iy-#U^s+uIJQZJv zGRY$MKaDbR(ElZrY3J*UDKn-+CweyKvaSgdLS<N|oFO`Qt$!Fsl@Z;!nfG9SEI{W! zAleDdk`qRxE9j9e9D)|n(&ESry;-oB8y0-U@ymXm#?gl5?+f^sG&?5QvynSazjz3~ zAD;AQ%*7$QQ8}4p2w4ret4G(v5AkA<6^%aagzyf0id=X|uCo;tB;aInFa*yqyE#lH zORxO~u{b(C<E<Z6_gCjV=+V9>Vsu`lPwtp#h>Tx-7<Z63LVuf4?FYZk4vU2I(4Tk+ zZC9+|KuKNb!;da@17=(TSmVkxyp$Jvyv)`cVg-4xPETvJ>F7)15<x=BugQwR>;$Go z<j4FmI14UupKa}JySO05BjQ=Pnjz*cx1`Z>T~q*G=iE*@{>z=+dN;uFeTG5<#m~>a z>b|gYklq*<*#I%UC;i8x<(KHcJuSa_{~?o-zO`SJXmzAfo^Z7T;p3k`|5}_b4kp#8 zpq&ncN{ZI*{J3&=bNsNnm~Cr~5o#P0X>&Uj*pq^Pqq|h{C~Z;p!FGOM6CzkRy|(pH z7QNK(<W)lN+u2=Uifi)P&JrCKk5_X$Szo0H9TYDKQo=7ptfhO7c8DeS<KT?AsL%<) zi<Ls0@SOD5Q7{tQOmlU_oEn8NwXm=?uJCcx9JwJq1Gd(khKPRQRH8K|)CVe&HZ!k} zjwbBU)FrPRJt?6TDyWMT_llp*)xOwPv!ETZz*PS57%U&-Zl(`ltPf_!t`eNQXGG-8 z@PMCF*_}+#ZPX^W7a9S}=9}8LBOfyE<lvyJ)kfaDwPAKn*ZY!?GQ}Od;EXsl#v4b2 z2bB}e&Y)}u^|g&#`?9Hyrq94Sn<#ZV+lEOBrZ;uV&2wG2uMdyhSt($q*sj(T_aaSl z)TCDFK!eYyJq%1RK;oT;i+K-hnZ1{Qo~oOPL`yQ;j8YvH_-Iy>a;yTZ+^J4>1+bNq zfR6^lk>BI`=)cmsm3@Fka>ApBlqiMp^Bk^>zrnKg>g{6#`hYG~Gw^SnmB1&(kq0ni z<rEoeVd~f&Ban)$o`3;(_wjaPoMuQGLn2tr2iT567~oS0+@A1N2cuNn{27VnF`8t< zaQ*1~FoKRX4C5sjlc#fcR{|F!C)_k{ZHwVSy_kcG?&(22oVl@#&|3+v>IWtIY<zT$ z!uNbP`77lAH(DWU`M#m8u{jEaFrN*l%>;BR?1HiR|JI9{w+>58naH`65<&VWw@~SK zzt}9UNjopm1`mcOEc9?bn_T;U1`h{+D?XHGG|UDfdEE*$61Umkq}m4b0PL41!%^@O zp#ix62LBUi{oS>}Q4b&%ZvFP=pRRS{+$^5y%>g|h{XAu7Ica9v{h3^UU9)sa+;$g2 zP`q}|O<a%P@8YQFHvOcUe$e}ao@914YHpYMh0_w17^vFjC??VNC;d5vfur;3eHF#4 z!hbpPi9iEYfW1vwW5_g|E?jvNhO=pt7^n#Vhpy`I%%}%s+0i>MSWnBT<E2Q%o&TU( z5IEH1-w(mkG?TwDoJjt7;*M+i{k)#8Vs^ucW8g}#Y!(L;Sk?Wbj!WZW5C`qr4-+WW zJ3O>byp1{5&k4iiB}E@3Qzv?328BQeGA#5)G&J-m=}D`3wSW>DbT6;oDa@O6nL1by zP(Qp>VGtBHk_J0dm`dNIkvc+a_+!N;K-G~ZfWzu12~KcVH(YUYrg%HWeAnd|oX>mo z>_vF8VqxJs7?BS@$lsj@w(KC1W#bN=&T4S4YB;L^JCq(^;H1x7+0^1tiis!?i5Tos z(w2mU%v9VGAC)v25YGZq4`l=g6)t(~(BHswC5|HmHv1UTsv$p4Xf@Yd)o^?Wot-=_ zNgQd0h4cU-zPFfkRNyOD_k<887myt3WsG3z9d)sLl}a>@d!A;KoSJ#=hWs>8_Tb0v z4|_MS|6%|0%g^^8J$m){_3O_sUp@BL^3V_Oj;!3$V_{N4uhH8McUGw1lVSK$sW6&} z$4&|TVodIV6F_>qbGL&=y|>_u1`d5a&@Fv%*P>ayI6CgR<GP$ta(4IofPO9624<I9 zZOWH+*EQ;P&!nF9egLVMe?O_+vb(9z^eMfsWxHohp43Zd^>y{Ha;-+u@Zc&uB%i<@ z{sFa{u(==B(~sqh>@NivV2Yd9|42z>&L(&}(3iuzcZ!=J*U?|M?-YLw0-UrBViLJm zb$w(hynGL>zsF|ZV|@uCzoPoMyfQmC8bL=@PT`!?%RPFAs8UY;GZ0TEoY_>y5iP5# zkGORgk@(dUj!kW&*yN<jQ7zoGfIIwkQP0ba>|_roWF-HDqMeAU;5|097Ga6TQ#Vd? z1QvnQPTa+ZlnNo!KZ?g(aWR(l4nAfQG!QOk^5o}{d<*VF=UZURw@<jS^{&rq5VUH* z$=BX|>|O7trY$6oBCUoWAgXFczVXO&F!B@|A?yl$czLjpt7+te-v}+tI+b)OA_*pF z%R9K_E1%n0q4zMBN9F1Kc<ref)r%>42C~E0l{L=bJh+z+@X~P^Hwo?$KXUCFJTYC! zfXz&G!b_&`peFNMy;o#iz_U}b)@&plNg2ioc(p5^+O^uXz`izK(So36KlN((37qaP zJOsZJJK#<HUc1%rwCrL-lxi<;g{x}R7Tj6eBOwff=75K2jBga{y7&Q|ownfjzgC0k zG^DL|Aj_^3!(J@r@b3yKzrtongI-iv^X;^n_hdeV(Gao(6(}a4OCyF7sv{@n)0fH( zz0dEJ(6TEw*c)E|*T3yw`*u*F+PAA(5mDK+i}5zQ(|OnQ_NE0sNqtvx*Pspop|lp( z_oFSXMswn~J6uQQ_&o%nyvI`!{gN7ra3w|8CkPP(u6sO$ORLD{walEm>P$*^<)ILK zS72OyRG^bee2G5Aim{d4PQ%#bF0jMX)5%%4<35|JZQu@V8hy=vSlC?CwfJ|X0{&A_ z1{n}EUltU7n>bOM3Y}2vMO3z7g>x7pB;C2S`E*y;CL)H(eGO6~DQOhDeF;Y9ZikAz zcY--^11E+{&^#mx>hPmt8}yK4h+XRJ_^iiq>(~6%51&aV-EGgOG3~Gh2o)Z)`2_O% zbWqEJ-vCXF{(#Yix=SPPT%E63<jZHn`Embb_!DF_^4mhD3FYLysJ|$F-oWkRq|tP% zsi>)FJW)fz>cRLTieJE}Ix1zf6^=vqyBF{CHPdJF)yoY)XSTKom|3Kvm1_4`;zKv| zRBYuU#Abe|XVt$TaA@*sF)7=v5(e!dKG6g2L+AGKtQg$w<WDRL9=l(S+rM)>Y^ao5 zqpR^Va|GL9v}ojT?q1?NTXU2d+!@cV-krnoZn&41?meInT*m=DDlfb|wVLGRqUdls zI<9Bx{4wxScM^E1umyfTo|T7UF*MpvYI9A^(y*hh0j~jGs=+YJDOzJFe!H3$Z(lu? zNVN{&5W1J7J_e*tcgVs00jx8w^XOe!BOnW_<Uq6N_BLR%^n*#a4+HQpK=6lOlTHC} ztp9fFhVC3|+7K)cEG(enZbH7?5k|m*GaF_Fq_?g|{z8MFqq~fc?+M2~Pa0TfLWh)s zA=cbN`w`GNm=xhyM6emOFn}sUX5DHt+M4Hc6<ZH3R@k=;pP<I?PbMw5TgEIknO`tX zfFigQCd6a-L?CTh%pVK-10M`1J{szW-oSrV_P~G^d1X23PsB?>j(RN0T#Oh+vaCN* z*gOfAv3eL|z{Nw!w*$d4#p!~TP`)rl8J`4|E{0<v4paliCP#q%;<Z*d`xZT>ph4!0 zkxK+bg0n<d&9-mALR#G(;Gbl=bHyS+D}JrlDGzNWgbr&`&C3&Yb8$~d55bYfh@uY@ z8Lp(bka$CESGsNz4AN%qct{SvO#&0zR2$r5aG>hJBXAJR9ik=>%o2DsL9wQ`5FFy= zFYUpsPq`7|qDTWLDXPr$jERNq3}cABN5)YDe1qS<&?qSS9YbRWbBwbkUt6R+mgj>V z*tO`Ia7@8BP2(Aw(F7dSr66G&R}9!!0P0F2kMv!*V|11g=2n3H%0q`GCQ5tXUd)<$ z_LNb0+VQ+%Np8)ybOSjd>3R9-5hH1|%Ovqs#4?mSugeF3cC*%@jW(%bQV+)_gaBji zfNS7>ehiwQzm#YFf3Q)=v2{lWvkES2j^K_N^aNTPxh^<Kk6O4cx#BURdq@f2o5koD zoFzu{+2lG}B@49LfPKW%O!;vxXKBD-J(!{84MRI0%zBK^7v8VT8gT`VvJh&Gu=srs z-^={jH`ks(B52;0XQ2pZeN#_9maKmSn8HjxiHyokUV)#RKV>3QebpeC8RWNv*Sph) zs#89lN@y!Nu0R<tJ4z2IS7nbbTGiC2u~^aY7T#G#CNYQ4de+u&Gxin)WWPAJq(*Jd z?^R#%M$YcADy6N;SCT;E#+CWft(&`-&2!tI*Kbcx#qAU?jXMPi1-FZTFMfjnBEL_m zPP%BnU^}e8r$Ik-??VpI>=$?((P!^P4=y?y*&C0U12kYQq+?4O9tV@|(_L-KttBay z#g2Wt8x(jALSNJq$F|_?aqI-5J3l&c&9NQ#a3|e?YOtJkn81NUOP>5JiP#o)k|Nm& zgom-b4X6(WBg!kv5F-W=L*UGx)HR{#2KcVV2P%u_Gb&bIyIJ)*V9ho@X(;P}IH3t# zgBABQB0t$<rg&Zpn#(f;kVtYRJdcX`V?R!Q@kt?LD?DYkNF?8~`4+6-HnJRiA2MSn ziZva89Oe4hNJ(P}OM+LzW|wgzqctVsC5!?E!NylRK<Tj3z7lu^VFPG0yUJmxcwU;D zPFF+Yp%_g22=C8WJd%;=B18!zv+sTWY5SJXXdCEl=68ALTDlevRJbOAKzafPj$;Fp z`jg`@fAS84<I1s$;hEkcAZEOL^%(r+z<JQ!byyw!&STS8bM3B*lGwA5`V{;e_2a-p z)S@K&-tiLm)eZqJm{uK`n!j%se+sLIL)Q5HCKIT1hh`3LI5<z8cQbJ1(rXd83sarD zES>5+4wMc<GFf0@j~b~L2SFKo2%!>X6kFa^L2A^UTAhsJ$`Y)3+6YWy`c}V;V3*OW z6%jJY2wGaoyglDof%v<`vsya@co*bz6Vw1s-ieiFr3ZSer{pCaAy-(>2#B)?4t#kp zNNw70jNon@Q=O!-cR>@+zLPqZnry<yF$w}de=<D9!>DO9j{8ucD24)iz&NDA?=eC& zVEm*me~%pm5MS{6O=GD1C0w?o6DBz1GEOkrhFYCr*x1^l&I^#Vthw`MQW!D0H#NpJ zL4<`R<UoqM#N<benQSa58er>vHftg2qglm>3h`D9X1Fyw1De8Lt}AI;BsTxAZS(#7 zc}0a6+2YC~Yt{;7l6B0nod-`}Jp9XF-@bVBxU-e<D)?%ix@%eu7L#5*=|mhD>;L9A zJY-%66P!WE+(LQ@74VpcAIde}m3;fO<7Y3|#_AScJni_<1UVG|DH&F)(|SCRtH9FZ zp(B2f%iJvWyo$x<hTIU;9_H)jn$ylO&t{8ji?0A#bW(3b27{)pBi@C}eGro>PlhMe z<SbaudIiRB^g7B}X763+-R3?%caPKX(EL6OdMjBcd}7xr8>^Kp4+Lqg7oG*byODF` zx^*4x`MNA`Tnr-<F%#du+STZo{O7L~67!hzp#w9oAeXJXiulML1JO%Q>O+_jH%U)f zeUEsSF_<MxWZ#v`!dS{IM*x-zu+jib;v=8@JA()b=@9%Q_=E8ok%hcO<ItUAv#A%e z5hMYt=k=(b6vM^*xSmz>GqfV@P7iA`C!M-+Kw5|5xOSWq!?kARgd!47hwdIujv)2y ztT=?bKYoR+ftwPFLK%^v6OSH0x&QX*oA)nYyn6E*EX0m5JBRaA$DVH8gn-}<ES~%8 zPdEHukP7K{zxyrzeKM>j^BPM3p5b8;$AL(|t-xXgRy5RqxG7aB>k+L1S4PU!vki^j z0LznuYFNxB*c4l51OU9hk;6RkfR7%6#6PLA2v!?x1f7m+y6ZmC^92JWrsJ<*d!`Wc z1GmrK&MNxx-qk>^1D&IUNzlj^<u~$}lh8ol{LMez9rb6l$8)RNpN-qEgsZ)tV{S1p z4+LsKyA#=|VTA^`OrXJoWCs&oeyaZ@02*x<w0ynh10=Jbmy@ELkNQ3_RCn*)r+3%) zuWfC2_kMgg*#G&~`PQJKpbZ!v^n38*yXL!Z2H|0d_H|<=qP|n${G^E=NQwB8NAXJN z7|VxDLxVww{I_m+&VJC;lf|4V9xZ9p8g~RZY<wtbb1)=4w#{R*?MkzfpDgMJkA&8= zD@$`vmcH+2ADqZ>n-tsp1AK)#j^%*|DD(yHXFLZX6O!Jw%pzgQe6xOE4+c<X!-G`P zvV6CF@7>_tAf0-l$Q%{9?kCUs*n@4^q+LmnLH-7P&rm!bQ>F#!GrHM%A35qo$Ib&% z#=LfG_|kp1E4}R%vSX}lL2V2i1%7jH|GTa3p8Mxs|GTXL`EUA4vQB=X+@i)SwH1~s zw?fN$ws&)XixzS3)_#&zh!WJmsndNpgQLGGj_MNQabC~M;YW9C<rQ|fI51&><!(}b zbd)=s;$b+PjgH+~Hv{BmZcev6I{~8gveNh8qnrddrSFIHEyu_~?f-uOs^hni@8`pC z2C!d<+Jt9E@%{Jc!Eg+xEaL3^qjA3>@zzh1atfUL_k=|=_^xaw{N_5ox<M~^34ZL} z+wR`Gy7%Mu_xsnj;UC8nzWd%S$&cIb2KT<{1E<)!=Sl%xx*t%!E9JJf?}gu6_rBk{ zC-q=e?`>~)-;LqLR=3-IH*gR3esr(!d-uM9O7Hsg%Y6pkx|g57b#m=@t_f_5N^L<~ z@8Ium@H_6WZ@PVK*ig&{JDrA8Se@w~dqrjQ1<z?6_Nsl4ini{Y2c-GAN^Zb8gyzbp zjMwzt7OwF3-*>ibX5GWRkNaFpp%J5fp6FbGX<S8G4s`GR-VfDYP4-8e?H9|7{9zjL zLP=;u9%UOrL4|UX9rlqs-;rE8xch7mYn&e6yP5`^G>Yv|n9Ax#>Ai0h{*0zK99Nx= zN#EFdG{p1S(YfyC#8;g-KtF)>44?qK2eBP1GCbMO8UgEd$=C-7<qT2_Hh@&aNv@!N z2J)(b%OD;VN*HQba>7R7wUV7&g#bpywbg9~s;G^iBp})bJVM7B`rqB#ayzm6?$foc zd*AX_!|Hy+ygh|vjbSWJm_lj>{@J^+zvG_=S(abkR4-Ay<>$A;wtQ6{EWk&F7PD<_ z>7lzP!+}S@BRzvc#&L!*wl@i}=$qw_XLxpi*DlWaC=MQ4;`M2#a?3Wag|PDQWN>gp zV-Q}<@sDvQU>XLVDgr>6H1SIJmL14kts3}!7+%#r0BM+INBS!SWP-0;F%-EBPC{~} zQnU0FWq0(zJ1Ehu&aLkN{)MINAJ0#yQJ^$BazG-9?`++Ux=uFLobHm)66y|QobAPO zA0}2yyCAfoHo{_7<@Z4k(#)JL<^g;S77N9o{$MlG=%N_!c@7rzQr7}56F-YYg{t+# z^RRiIL+X-g(SWXMTsygaIzTq51V#^+xnTZ=!T&+PG3@s$oM&9jy^!Bqo}XgtTnc}) zYOQOTo|KTkxh?e`1;TV9%;w`6fw`S8<fbGAocy&Y?nHG2k7oil$pzx8Fl+Rp?k55( zrL_b>u3<~5OcZ?T4m1u4vgV6EWL~^KhhNIK28wJBHeq1y1sPW$0wOK7Sj5AeFVx_O zPGoRMWhiEP4%jP17+2#HU8ABdf`O4wakG$d^&VX_xPZm>gNFPy(6_{1!f8|ANK@i$ z9%E<;)n9^fDlYNmj8m?HUyX6b`4y)153om`*XgAaQnnvfKee&k`+A(e6w5XIl~}If z!kXn?gd=_hRxIQ1c2=`oDQj77k7wWC#FsHl;Ksr*Q#QlP2)o#o>sQTd$4Otzs-udS zdrk&;R66nNq?%&3H3Wcxl{%`x{TtQ^^7|o`15>WCtpXoa4GL&Q@j$5i)su(U|M0ut z|BjcG!J8TZ!7b>oL&ePrw}c49Xz5(DZ>IqSE0o7&2E-`Wp~G?;ZzJ@%PZ$@7R?(io zlOj(S*HQKw9ao2k<t(?+^nBTk5)%b)I`==ngK_trfN8*Pl}2r|H;yk$*Jvs!rbOm9 zNU6Fj*%KOBJ1jC^3Cux<FO<5%oK_mai3;LPBpiaVnK}XgLZ=o^szJ9Hvvzyt^ZUWK zMb`lz7WH{>U<q&Wr0J?d*}U9Z*1>i>)fNt}ST#!MIo8=K&ZhSe;ft_kac3|uRLq&Y z^4zC@UA90<<9n+CT*2P^R<?`oIMAJ55#4kk+5xn@;N$%gdx^HV8V~SJ$L*qCF$wwT z1UCqqX+#Of*G=V-af9^5n5lDD=^;r7GIdB(KVT&Q_J?mf=A95cHOsDecc}l7Qyk`` zt!N-}`xh_XqAG5?0TtD?YsOMo#f<^QLB+jlA7np#<$h~_I5lOJlOk^J=r<YH{OlNR zuQdc+X89O&+rQ)xR8?>>j|4(kJ|#;nSrI2y>c&9E%nh(6d2O@rE*rUqZ4>KF8qL|& zxU!!g`KA+!uld=_`FL@`s7OwfT+W58fh(3G+qn=ca(_84WOeun7n<fe>E)fZ*pQQe z4w&`0fA;ploQQ1bB~p^%Kc4r@!K-laZXf_#)aX4>Kar>S3TC6!F$u3xL6sOJH9B5Q zKZGnvGzvec51OVv1Pbb(E}G-+hpkK|BJNl1KliMh9RVch#EG+HE)C!GbdG%u_c56+ zAn&_iI4Y{^*VEKHK3#J^Bya+CQnfE_k$uQ941Ufx`%MMsKXnpN3IV#?s06~gWztdh z`@!F0dT{O9&hpkUtNG$I0O=eU&!y?X_3O)8;Q8hr=o@#HaGmKv$op|v42FY)!3d^k zu;E$5?K|PyOp35#eaIp<!%PVOa9b+Sli>=X0+Akg4Zyirsajy08Ndy6Nt^m&>-MSJ z!Gn<fq%6lFFA0Cq8vZ~pkr@PkR`yr?q4{h$0nKUKr{?IyE+33fdHkq<sgwt{7uP^b zk-c$Cry^GAGbTVX?Zt%b<E#zwDr7RUFJ{?{HFQa8y#b^88}Covjy}!ahrysxJW`20 zP{s_5kG`|5eLsEMTEEsyRn1w|Zm<Qgeiwrh;wG;&toIFm&6z?H*_@h9pn+?wxA9{o z^I<3N4u$1A>h(tSiP)&3KjCdF?i1g)ws5Swu4;S3My8Ir!f+?Iz2(!}Su#NyUP%?8 zy26ymR!J%tMHPSVp8sCZQY96wUW#je<7+CVl=1~vO8zF@KB@p2X~<m#4KZMHeKed8 z$@L<=QlefGTqMMknVmhL^tc?=<I*+r&|PusDLCRmJ%##;g@X(9VC=pG9u+(L*Md#5 z+PguF8Rmcs+YC1RkZmBGK-#BbzCvim*h@^13Lk-ct1G`jc^mwA2^SngA|9YQY@$a! zsYhYdWG<U{xPS1X0=$9pQ+a@&a1Rll9n~XK$RSi7D4m4kE{h{^U2rY?{S&w`o8zyF zCx$MCPdlJ8+U_Xt2I?^s1Q!LI4z>Sm3B6$l$lb9X@GklZ<U8d!F>mr4{J8hy_Wm`r zWWO8SL-&_!-r0h`u$6R)e`(jod*AH$zx#GTzK!bn;N81@YL;K>Jf!sc+x+MJ_mIbQ z;+*105`NuG&ThB(7xp(qI7;nt=pX$0d=6p2)x0`m=R<hXa2^3S#tK6y9i3OKouw{5 zDTi>ZHrw#WcbuSP3}EWz%<rm(^ppMf_!tZrSom4>6Q}R~u6VRKIXMdz=;2F*0+^ra zhO~b$d$Hl4u2tHL`q{MnB#2AcAb6fvqxdua$QIY0cF#y${;%a5*^(`r%i~}8J-}0P z3j=<h6(Ny$hdq2xZnv-j5PiS?h>6f~6)SLnQ_I#1CI?{Lj;%sS>{;<2_3;#9$g87` zD@5YHbE+enQ9^iri+3O`bD?DhIzQA;%I0xWLMBS#uWtac0_lJ#&^SkC$L#NkCrC>C zZ(e?aZRT6#Je)%(6AmYnGr*23#TWsT%_&_xPtpsZZc?unQ{7kTsyfS|VmQg=38U7) z-@TAQItizP=5a)NDkxHu1}t+-J1Hns>1~kh-~h!(Hg25*WYz7E8}{YB;zG4+$HX;O z4=ag*jl9S#2k7D50;TAKl4+340T{@Dp07mdzRHl3oOnV(TI$;5G(-~Ns}C{s5cDh% z!T=~0?kjvRIIL%!{K2j8MgTJ@F)c<@oYjkfIjz|nDnkIJ1oiiZ73%&`*yA(&7^k;6 zoJP5Ha#2lYv&~OVg$n5VJ;(sEqvS%r9qGp&d}-fDj=`RuE?qd=i2I%mVwo{q#kro= zU9^78E5cettp@Frt~-4k_i<Z}kr-*mk*%ahl?ljkwouzq(LcBb>h0(QfVC5!WBk`g z!_#f{;nU7WU_pZ+k?lQdiLC-5go3sK%SFKRc(3t#pxQ@0R_q^Z8r7{2T&#FoTTonr zS-ewhLZ1}UA~a8nCfiakq1jGKjG_gzy}hD(>gj?1b^^k5G@P3;CZ3*uE~kL*BWyY( zAPciYkJ9O(=d05}n9<^A;!KdbAEzQAWV*uALsh1|39nXn2yxk~ax!L&h0c3PKf(LJ z^f-7?8UW*D+hV#Zm1N+x+le1JTdo0dzbYBN3>fm^p6}9rK(Vord{8X93**$852>=M zNj``&GoMIMYQpJVI@|nQ%`g1unOq-usGC{Le4GWfAg8I1dm+wUqL{Gd5r4xL6Tzkn z(dJPFlvF}l(+7~~Nk{H!2#*fO)EGnq7>s8)8@%^r-v_bj3JE`;zV!qYwlAX^N*RD} z<;mL&Bcw`d=g>F(G-eJMYA~ajOlym97JGZwr;7=OgfC`+FN-Z6nJmfR8@#H<)zkkL zCi{4bkh_9MCS0Bm{!g5WwEXE*x2Ox=A%V~{Z2&BTD2RE8qoS3rD7RF*c)O#nko>@0 zAo<w^uaJ)crs`4EoT3I}rZ1D3SHIR!HUwV=foV7%4`!TN2$G{!V2SvM;2G{7g4=}s zp@NqXCgbc=bFj8}Z*x+Co1-(%sLXg`=ruBxXh(sn!!F2;H5UyREyRZQJ957Z!V5EH zSdxfp(%ly8MCJRA?R7?OY5}HFi*-QD^`z{(9(OySRqAZ*oYRFhX#-{}wDL2lxo+P2 zEtPM%vqoLK)a{kB{ye62k_#&=#k1il1TJqL)}w`6!N~%Wn7E$+><0gG(znrvVtg>6 zA15{F6##k?e=SbwUnB|qh3u5zQYil&XTgJ}fcyGT-w|eZ<cw^aRM!>49|Ze`KPM1_ z0$xnz1QN61r`^A&Gr(wZKM-I26kDGHQmqqy7sYrsJVLNF`~|!M{>85G_u%iNvH|r6 zz8gC>Uhsd0M^5fPIB_(}g~0`=ZYn%8u~qe;#PsI=&jopk&+EnLn9AZ$S85ZZ4vWqP zWsmb02}OS^0{3ty^@@XPI_5AuIQ|GOA6IuL%4P|S?+FOS(LJgq9WlKHcc%E>#jZG5 zd}$OQW!_cMTRs)92sEm@x}1LON~^x_7=zIhw~1m0P2wKRfO0k>*m-$dII=914cX{K zZDD?};PYidGw+>a5^!Q3;l35SQc4`BFV+OFGKhr5`*7Ax()&;n!@wQ^!|3<>=gRZY zFB=vk0YRlU2kM~^<XJ;LKRuPE9ZE0^%QOMVLa70Je1|&jmlvP*<u2x>XrJl85&Th! z$+ifknBqF?X|Q-v16WK%AN2?*0thBGU(&h&i0Bc8OY@z99q-Q2<L;zt8Wp!hA3L29 zBPMxJ>3^VE`%)>6u4L-w@=sH_s^KCpsRE|g4BN>|<oeUiygr4i%<w26u3}@+i)CL` z#a_Ewr|W)q_XNCJ9iwXPK(55Hp5)4}-KAu45w@b)SZ98p2rpY_Qqscf^gGlF-cliu z6puP!OCe?}dDX>@shW_T35FMD=SnXCACMAl{$uifnG2chcU9bn0a9Gk6u$0X66_bj zDi)jWh%Pr3@`j{Xhvx=plbMe%07SBtUS45Zi%RAjFHS;OuKnPRz&RjSu8)SY%Wa%) zoMH$HrQO;+^gS=cxtG$CAfhC*0PpUMzzr}GP!XO++s956%!5iuFYFn-XgG<6>Aqz) z%X^=9N0TDw=E!_dL4LjAG?uc_7tJH^t~^BR>5?OqPC2>&IH?7I_1)PHC1I~3RE|4f z`Kkc7L)WM1bd_m456kgTeuyF&(mn%y3QRe5x*m-dv!*Qy0s)$X_s8MHiFcJg?3-i3 z(swIximK{<@wSmHm#`N`i34~z;2(1M0~_9!1wi<haGj8IJtT)AdVs5g`#;cD$nXXI z#l6Z(0Ic*1Td*fXVKn5dOaN6tGzfZ&z%ODFRh*=qCrY7AB|-joJ>K@cG)Dm@u2Frx zazz`~x?yBg$XHu&Bw10$!iKOl1&bSFO2(F=q$6cWS<bgv?1)+Sl4|7Y$EB1E%<Gv; zh)hZ|T;22o{l&C7t`6s6E%IJIzC3!@C52n~i^%YnztAD_H8{-SVUESzTPCJ2rb}4K zy%t_#D}BL+4o9dTr6O*#<J~dow>-~2Z{@ftI9Ox~y<Vlgxh1U-zs*$5GLhsUw^rJ~ zIGBVfIS_M^W5q_aYWTm!){NyHm>Vgs_HB~By6CE*f&y3?Rt8kPY0bnC|MXdtIRAm~ znku`WWbtY@0^~%)cxZuS{Lo_7tXY8g3wy-#BoS4H%-x-?@hw#uc~oBV`W+iPwH?Ra zakY=a5}rGmuA0U5AM*aU$JLe?z@nGO7y_}Sa&}!w_^(t6WzN$~S9&g^k+#snbR8m? z+SN~(uU-dZiAV@>`KJX_S!<4V)@1LO5Fe=`NXo;-ygmT~5;|%S-_?@aRE!70ok5w= z<i*cX`M(0_*AqZT<yRI#M`fE3YL$u0gw>y+nQat%wDB<U7I*IlbVuWf90%1tgtiW4 zVGbizVVmgTDqU1TIKuorZdb<Z;uk*cCRN6qUWjovtrdoe2Itpj=yE-spbmGhMw|^o z#mo~E7-Gz#<oLJY(Me{QliU5XBhOIzLupCr@54h%AEHX2`!f9FpTSZ9gKZc(MgaEO z*D+S=62C(nJ_=VlnAM*EOpw=CrcfaHe9Z52#w1y~q<$5BNCehmK)$utvyzIsKgIVA zTFx1zPuYQ_b6TAimfNF9Ypcy(y7>E%eKUOEB1TRyLJb}enP}stdh}~GY94`6bA0Az zmQN?|r>5M~hO&nocb<PLf$M*&F{yyNnkt(n7&P4;YQRhl+0opmnlmTRAWahn`yp0U zjt7-)435rWF&UnLGr}Q6-?>{ZLE?((^K@2ybS-7fps<R4Ub3tyQ7<!?5clJp&aKdw z2i15Ags>X*Qog?w%<{GTV0R0i-2}^$8;dMr=%~l8XUcX&Pa+-@d;?_#L4X<try~Gi zrO8kE2er770}H^pesKWg3yy>`LTspbhW`b&LY<UP&+Goi%G1U7EQlwX4doX5TqerG zle(Fd4eVztxVAwbwf_!(09IS39nT%Asv@2+QsNm^$KTH*Pb)cZ_{J41RF3_;b_c?n z`UO<$hFex>63|7vzSUk)_I29X^Gu7_)|(m{RxO_R#-{D<sL!HhA5GC1PNaGeeS=## z$<><r3Tl`tAIV?J@)RQQ+)*P?KRi{jT&{ZdKAKLvd?bSZin^>|N@g1dFfQFjuFpEz z1n+q3S9fWDuiLoN>V6z9SJi$u@f^<IMMwjcc7W#@^c-tU^cCemDFjU|95E%N=+*w{ zWU9Zgb5P&{`slPze|@JX`IsYOOK{y0M&~_uc%uB_MYW9IPMD~6_m@y6=lK#l#~2@& z=p_=C=O2)KA#(ny5B@>Khx^R^)qh`RnsB=)^Qy(6hz){Z{n-Y`I*f1AclB*60`^E) zFs{Y1pP7h{EHgsTuImuB`8>#s%0icWZ9bQGMz&#Dxl!|xt77^7=lE&ZTe>TJus8tW z?M=IoPf7qPH~zox@8RAi<O1L6ahH~%U1Dqz4J0Uroy0pTPYE=Fz52L_&q3>l09Uz# z5>e@(;CMsF$?!9v#o!1}4`UobZ^fizfW1sI+YuVx>PNmUeyDy_4`|h>-{65#Gk8Jc zaZRYiRWWIKFhMG(<rklwLcN!BjL$nR0<hby?gq**%}FJaVHmxj|16ibA6{bS?ftKv z_x}%e-g=ts`xQF2%zlDFZuOTmkfEsmwe0;*w(Pk-Tj^$9a!GB1EsRI4onIJ?=!L_h znv-7Ns`{%&4wFmh`?Dl-32swiA17z{z01%IZO~Eq#Z#Rs(6^QWrX*qt#cf<#{f)hP zD#ZC;t_)9lw4Dv`S~aU)l^%dIE~p%hRXzEuUU>IwRhOa?o@tD8wzxlK{B%?+<tE+P zp$_}`(`uvAwLGcjbJ+FkDK_I-Zr5<eC8Il|)q=*CNqyCf-!XE)8j%;=d{5CvuV5g6 z5S8KYq3$v#*&(emPSO`+9^t!anrDoFH#KDKdNw>eV96!OHO=u5L8Te8v}h{kz9&d( zfTO!O@|<E;9+r-+jlhtvI`sITi{Yd@bfR_$LvUgO?(lM~a`{xQjS>n=DBloGO9xA0 z2QUPW`UV-rO+9#kMl1i9ZHQaXw*|p&uE)e|dYmPI12rL2_=XA08`2Gh=3x^)$}bMg zi?zQ$gw&lf3*@#|HI&cuU`s)}4#flqUpa{U2jbWamifVZZm69q_#*NlDBd{lGcVlU z2S<+w?!O75YG^tQ;C~&F4rV&_NhFX+hlsGwfB12&o*kM^XpCvdyC0xS!w2+d&<Q}6 z45ej~xM5dPWt67i7XOK%{)DPP8I&&aMXMO$&z(o1hT^ygtx!bvcCi<j!hQl7Y3(kG zweohgVh10y7G)!2c>$j1jyjB!r#}Q3!DkT@aAH?T9kNhXX%t8@QK8D%)*Wh+<3l!L zFBR2>PqPTmj9*rWmX;B^jmT`&Q*fvy0n?IqnnI&=V%<O%XfIM7&B#-ju*6!0U~;HK zd@%&<ks)#`SAiA=<aZWhxbNzy^ML7sj7}ZSCq2nYT7#NbFA=!3jR;c8qe+Viq&_6P zQj;7dAqeU&CH~|_gd(KzScY3+`g*Z~R5?FOA|UG^dpu;yGf|J!6HZM^I;?(7H0#ie z5ZqE~Igewur;<@MIs}-JlxINK#!(PE2=*rIKfKy=zxJ)QBLXnd`GAD?$e3kf<O9(J zM1TRTK$E^;6cqtB^@6kHHf`UHknePx8sSIs>1{vp#x)yzz|pI*DJBHAq{TY=wb5XC zAQ!tC{~T?`B^rgJ{LWdiWsbtOi0^pxFK-WTjXg5}kW23%387x#?iOxnzPEHQ`Z8Z7 zJ@m`m(14woj_}QF={yMY_w%u2CWhjGq1Iek>szJ<X+j5-lN!W$V65$a5%V+8QL=Ln zy}QKZV`osqXx^aD5oLHrx09ue*PHwS?$J+E%4*@w(gm`v0WnKV5=o$qxM7hY=JbLB zK<_u%qP$6U*_Z$U(m-LLo`-;bkL&8HA*f|`rnxCUEdD#qSFG5M7_|Luf9pav-D>a} zgVSq+^Pr#oS}ykjv{YZ8mXN9AI<Cm<j3Afdkr(dr;Vx0V7(0tX`7!W*R+9@8U<Vu( z4`077Ce;T-{(v}rh?~cm`MZ~iP~+zQ!`VOpWy)~@sHp0|M`q=C!A`=E>sxl$sGi{z z3|aLE{^)=;BJG7saXAGXPvj>j0G&A+YP+-oig@i4lc+9i6O_ZG1mmIp{SE4F)q_4E zjj1Pl!})x+pFH{Q4jwY;i~nqUakcHmk8Ll$&AiyYjjZslc{Z)*-P>Wjcel)2w5gaU z01Ry&)Z?-F8#cXukej>Wu6mk-^{DzndwJJ@uv2qx0i>-lY8iZl3}X`z-x}0jZ0e-X zFK0Cn8YP2+t2^=Qq1)uuKNlrQ+lO+Q?H9Xqx*50$^p|FT9cZvgKuaUrswi57dZm@% zcqTe9%>ozGe^v|Yg@#InbM7Gi0eb`?b3AZ==sb6wvL;w>GH&SplET^_k6w1M?VuK- zr@Nfs1H1|=gbZ+nSYy${_E3&Y9EMQ3;Nm_knM7jurvLsuU($U_-taYY8iHaHJ7j9O zR&Uz7I`m7|5Bij(TO6aIN&~3AZ#(vjP~}()Kmee!qbSED<UM}(-TpPs>WXQQ-@S8x zQ_|T!6?oV8Pxjt@e~%uzNAAau@4kKa-PQlxzjtTLKYq7QWw*P1s5YpGo^6s`$&s6+ z$R%_==qx5BKp&O?B))w||JnPoyS0Dq-PULNu?0Wh?P1^cesulY-~aC2{^z~U=KkJ~ z?myqbug~<x{etrQpWTSuqvGzh|Lk?$3+VK<&wK9A{jKi1=DVKzA0^xEe||Un{BFAS z9b}NDRhgHs(Y$<z5_Nxe|NE9+KCCB<AtQLJ{-nB-Dqq@lEWXy7sugiApH?k*k475w z2cUlv2%=TvB4yQ;7=g3p5{!Samc^q`I?hvpW6w$Xq?))>+yvjn!FbC;39P12`h;7| zdlG30A9F!`*FlvaY(4@7xg)S3R{{o|*2u&i-yL(etFg)9GEQ`tOM67y-}kE;uib%% zB>ZtNSQOM<i5^|yzX70)UEDa1vENy97R9qt>aXKi8Q7xK0;y~02v<4?*)ep;T&nZU z1+*o(w$_-k`%b=4#MUcDC#P&5XeGSWGa~95c*B~Gd+HA-?Qe%f2q8?uecP40N($X# zTLub`QHyhD)4k@lA-J%m*mt3vhj-@@K@yfsjsL_N-A%xV;tyPNzc;sheR@S-q*rZi zT~)oj+TO_@+dE0gUeYSxsw$iSl>YEJJg@<8ipb27rl8ft@v>Qz<2u8OP>Ed6h39Ig z<{XQHH0rLnJB!@e_HJwIGyFTKDCYoQR-@2e%yTa!r8u2WvD`w3fY9wGvsWbXoC&`} zdAI|F2{qzbzY+?9m~6|1q$$}7AU1~z|5n^u(zp}3)1tcBC40!1F^u6ng++Nt>xuGh zIJ|g`)H;&eT2ns6%tl>a2#7Jc*r9S2k2hWr{ei8uY0saaPVh$pY<dOd;f|dA=1GLY za6Il(9pif&J-Wipvd=ob%;g=yd=qX`v>b@?xlbN`1%Dxgr56m4wq*=H;X)9FFxP_2 zD)cx#{jpWp2;41I${)2<=2otZJq@YgZ*v9J89=3ex8I||?fu^W`a`a!VGvaAkNaCH zR^r)k_JQ&NVHvudoHpfRTvL|Oa_0Uy8IpgHS`#XA#~lXJ?2aiwqyVNM{9%IyxR3=N z!!;B*N{_w&y873@CJFGqA||~b0!cQWpkrd>yAuMN_&hBhnB|Hal*k?=s1u=VZVKsz z1TCh3mnSu+wE0;Gk61)!Nz?LMACivUBWe#hTzq@FL7=C=IB_W17EK<)DCE6h(MS5& ziVUMCm}jkt*hR>#Bcl_Xl>nqgm{~MNkD?W2U?ftabc>z4opjz9L4`Sx6sH(F{tK8s zCr`WE*~&5u-+gK>Ub+yVFNdeKalUU_*l{4gz5R>1llhqw>axmsR{G^Mw^*Si({9y& zNEOeeg@PZD9s{mB!y}Mu=cX5tF_X0yVbtF3m$V=CVR+X=wI84lkPkj7pC@PQ*g?p4 zP>ITsIw}(qyR6}Jb)Vz%>CR_B6?o(RX;cX~xZM9H>Hssc3Dh`%G;Z$2s9sFxO22YN z(?IwQ&MlTic5?YU0|B<<$*Ilci+lW)Mz>->Kv>Vi(?QR$^8`5(Hf00-aqYP6vf~EI z=?@!y6XI!6pW15zqMclwjC|qv_!DtZC6Nhq#w?DJht$xYFLdPK)t!`|oXMh^E0$+Z z9L4rzarheJ9r^pHR0|PtS6D18JoJjxY(Y=K@+p9d)Y`-M#A58=V}`p7+yvL)kZIx& z6KnB6g(MDvCJra?L$OH~!MX6>VYQzXt97UFD~A)EpEmAj7JCKiK^%w5Z%3r$(@@3- zOp0W)3vLol1{nLq;-sWSgAG~;l+XqcfT}LG?cM4CFrelftdqL_0H%+j<Y4tNC}FX% z??m5vGFFY7wvQpG7Marx?UR$6+=P&qc;EsEWvDLu6f63vYKW~t+D#ck(0tGy#Xf(H z<lMpNYmNia<&mK0nQLqqZ<MkQBJ<PZ$ekMb4Dg4E(YEb8!Y1%UqF?Szf>}YilYDDJ z3|DNVHG?@X@&g--;X@hJ53Rx0_aoK=mR`wDXNO|<35SoaN7$7vX9f?44Q@~^j#A5V z2GK6guv}s{nsr|&v2`Hm2#yp|CSj^A=EGVNfZ`ip#;4lYl<T+VPC4e3ms)+t!I~@c zBnxdj-NL=_zC-14TEMBAJkUUcpg9qoN!yOEOc7w9o*cO4+B;ax=k;`7jZYK~@lhNx z9VV#6j*{h=Ov>&k{K+y$N|6!14J-<mRkJrueR2>cM2Ik586K#+q>o;Etryml(_&E9 zN5_zT6~Df*w7+Zhc57K4^}vcu)0Yvrd~c#Qb(iS2aU)4T_Lj_fKuW?rEXppXwJh!` zvIty;&3)k_7L5~Ss-KW8j;h&cF>%D`t(@MB7g(S|-G1}p(Ti=YeNtYf>@k5;-U;3o z+Q<{1Fkrk1?@c$^>%;rvN_!V{1PQI1{E_DAuPV|*Zeb%o#GX#VBGv|f3G!Z2C{05; z591pGO|qh<AQ&5DY?4+@=$W@9J9D}J|FN8%Ir-|O0*abLqUKM<KmH2Yc8gE->_gUX zqp43ywK9#X<3#Rp)j)^FUB*ytb2JDw+guGoiT3OpCNxBQC#>O{fGzYqrE<7P)>#40 z=!a^BFd>io$8mADckosm680c-hx=uPR@C?{K8Hr}5&Mt^V=22XQ)mT<V`0q_8Zbf^ zCZb}YpC6%Z@Hw{Rr5-A<?bu=75x$;<6n<fGFKM7<eF2GZk*)xxGw(P(9FJQKw3?sG z`Oz3RUC?vV)8Kw!$9I1`ZjgWZFKX37%Sd@#uJt9uB3F*;(2NB=Kchxhi>?yx7#MTv zX6PDknVL2Lf+v_N3LL~H>{?1LE6{I$X4vQ%YSvhWSqk@F-{~Pk*mHg<`tzC^6V02I zaA1=#NIND_RLhqE;l$E9-=bOV9F}G#+(1?wgXFzGn_nbihUi@6b1ktyFnWBl5W~)I zY$kw4PJ)Xmy2FL*kxz~aiE_w4XPsz-41L+%0!~qtq)vNyVLDqzUp8W334Ni0K`<M< z*O6C=9me>!mO28G#4DQX+A*&Z4oSkd^<tZ9ibb_@YJ@fR8^UCKtQ1>^BA)QI!4d)O z4{vg4xe6;;yq<-}GHdy}Fnn%>`^xLg2j*ToMyr2tcJWo_BLorAyn)9H0qQ~w&zF0~ z7y_VcYjjD*yPfixQ8rBq4<yRXOlA}k64ahxQK!0_8J(zhDM~c>;>nXYf=2rNez1jZ znQV@l6@iT3C_Vj<ub${U9}?DvPd8o^4i?n(QgXQDKEgM5PvRTK2t@sjZxhKC^ZY{M ze8fIMW@-G@nov8Kxh+3CQQEO&PXfs~UqE;9zd#TuFAd}PDJc!i#!C>)TBO#c&sW9v zpq<poJwH?QQ96!jCxrCBx#@d`P?b6|O>rCy<rRTMA02L9ax+@~bM<uADvpGYi-^y) z2R&S1(#n78qe3aQ#68S=VO+mi+#_un0fckm?c`anxMmd-(NsPrjGDwOCfE`+YqD6* zSwWpp)Xt_1rv<lyA#zYeUizJ{BkaK^w2IO~TX3QdNEu61r~oWh2Yq?9@U-}k;m6_Y z(X2Y1iyhBLHX4~pseqTyD~o>7Or*Zga4#i>g0Y)98snx~w<b-3$eM^gkv;7JPbZk7 z5;eEn1nQZn>mA9WP|wNK*5Y>T9cD=?Xu9XKV0QHgUrN^<la6fd-Iaa5epBC`uoIeY z+=pAw@aXv2*vR@q3g#G?<k49zG-<T7=_yk!HAw(xRa+pXxB}qQz@-OM*ykpl3tU?E zB~s*85}}BnuX{9P$g$5&bhj?%2_R{B6P%VLED;qKdD(I_X-Kbe;aEg#gKz5#M<(JY zG{sGtG)i;t#y+0{?pMyCwt*9&&5Q+CxWSR!<2*W496>G@)y(bA)dF9>VZ&@3BsTG< zxGnA6?cPRD&ASE#N+ughEr~;XsY4|>@O7{%CfrLkwGM@~!Q_`eOklNqa4kvyU|z>_ z3!#`H{Uh{xX!$OTbY<vxnw?!cMl8w4jvNP1uDoC_DhHdaTYFe`HN3D`1X919Lml?5 z#ONC;?ggL!<~K$9LFMKyuAFTOrkr3BQoa*GAfu^+8jNK|j2`kQp%Etd2+9N{vm#cL zIJu{toKf!bO_WM+;(u@9e}Bs)9mF43Va=#oKad~<wGef`-!GmmCi4n<7siNAn8b$2 z)MzftUnYjS{^TQX6B^~PeaoeT@XnIx%`K(IXs6N^A`OrDia=Ll6|wK3URSFrSUb`x zD4{Ou(TivKgAwX}`TSBl=?N$S6)3|m7ax%6SNn`u+Fc)-0QI&*K7T-KsrSihfowP) zuX{MM*49h)Us-9p)(N?c*mMvI`t?pk|GCvlH_0^#2a6=s!f@K@Xx({a-6?+L7nw}e zov$^YOqTHgML@d0lwK?YHYHy246mMQ6NA<+%O%od+Z>?h5H;qrT>a8G%?#80B0Y{2 ztM*NO%>^6`iU?F0KjG78pZALE*NZ;`{2;>Hy7?W|?%sJ&PU=rN=-qHvPt+*Xd76BI z$(*_gcL(tS&t)#dO+&tjn<IA~eAomTYP4wP^$98X@!iY1nZE)wTXQLSW0Gpgp^3|W zJak_{Fbr6R(rcedAaf179*K%pu6Bs{H!DYF^|4e~pY$zq)OAJ2SQ|fbP-@^_5-7_G zoX#ly0S(e8&N1Z>)QHFVAFmBi)dir6+Yv&+5><%Y!c*JN;xH}K!ek^7T9r1y;;%%q zOVEHXM6&|!o8u&i+{znra;BkveR5-PHUwLLeNvH9FJRevx(ZOWA;q*%hd{q3?F9JP zs4_EsH=-2OG--By5Mm}5&wubQF+DFwBhHYAZ)TLElRP}}mlDKsoZs~+;`OoHl$pzG zi%1qJ*j?qXJ1%I^3VZ7h<%eoqUV13UuJYF%3bc6Hp;ML%<MAcN2<?28J3V&j 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 literal 0 HcmV?d00001 diff --git a/public/assets/tinymce-3c6fcceddcfff921cf167b4a7a9f8d6e5f41120414e0180765d28407dbdfb42d.js b/public/assets/tinymce-3c6fcceddcfff921cf167b4a7a9f8d6e5f41120414e0180765d28407dbdfb42d.js new file mode 100644 index 000000000..538771fcb --- /dev/null +++ b/public/assets/tinymce-3c6fcceddcfff921cf167b4a7a9f8d6e5f41120414e0180765d28407dbdfb42d.js @@ -0,0 +1,21 @@ +(function() { + $(document).on('turbolinks:load', function() { + return tinyMCE.init({ + schema: 'html5', + menubar: false, + language: 'fr_FR', + selector: 'textarea.description', + content_css: '/assets/application-2fb50a7174d540a1e61def8f3733ef9b16048a46d710d6b766260ee4589d4840.css', + entity_encoding: 'raw', + add_unload_trigger: true, + browser_spellcheck: true, + toolbar: [' bold italic strikethrough | bullist numlist outdent indent | alignleft aligncenter alignright alignjustify | link image media insertdatetime charmap table | undo redo | searchreplace | code visualblocks preview fullscreen'], + plugins: 'lists, advlist, autolink, link, image, charmap, paste, print, preview, table, fullscreen, searchreplace, media, insertdatetime, visualblocks, visualchars, wordcount, contextmenu, code' + }); + }); + + $(document).on('turbolinks:before-cache', function() { + return tinymce.remove(); + }); + +}).call(this); diff --git a/public/assets/tinymce-3c6fcceddcfff921cf167b4a7a9f8d6e5f41120414e0180765d28407dbdfb42d.js.gz b/public/assets/tinymce-3c6fcceddcfff921cf167b4a7a9f8d6e5f41120414e0180765d28407dbdfb42d.js.gz new file mode 100644 index 0000000000000000000000000000000000000000..1839571e37dd74606ed2dcbf25826ac51b82f15d GIT binary patch literal 552 zcmV+@0@wW?iwFRXeAQP11BFvdZ`&{ozV}z~Fu)0*rb(MPX?Gm9+b+8fLqJQktwoj$ ziAq|m{qLjgCR=;hE)pM~$d3=r>g+Y!;AeCAbp`NYW`fQgd7dxCSa6P2aMmBvg9~U1 z1@9gJL=un(w*Kksr_T%PEzc$oK+-LB_y9%Ao!b=Z)hzLIh4BGubcxPZhrY?!kihG> z|MKkuPvl5*5PZS($QTJ1hLVo9ADCQlI(Qc5d!3R%Z!jg|bc22Gti}O(eOp(XC2m*S zwb`tfxT11psNU6g+q*le@2ge0T<>sQn(b<7%4%Ddx8;&(z1iKH^=`dfNa#yCNoDzI zPhJOOeIqF&o-STAW}p4gv^_`LG$iyn=1a9z45vhKpL%jm+N2L}{TzZDd-S~k8G!-I zD0M)RXb0jphTOF93{`f{CI+9o@eY}dFazty>lx%#;~mvJNm{HFCs}y4ujZdQv8|s3 zKTI2JCxehV8H*B0c(OqzwjF_PF?QGkW93Nj*_$9sAjh*z3Zrf#^$zvmlg<zvZOZ5> z7xW=PAL(f6Bx~fHOpwSIKh7ohE;o`)8aY&wl=Sd8NFrn&w@|@!j`Y--ih>>!i{3}; zS)FsJiK6-|mwL-kO%<wlC8{@+&)Seolv9XChdksN_wA8~ZB}Ec#aPJ8{NvSh{`*5! qREJ2{8fE(b`B<H%MWikqY4#`h%Y32Hxf!=MiT)dsu~$CJ0{{Tu%Me-s literal 0 HcmV?d00001 -- GitLab