diff --git a/auto/gui.files.go b/auto/gui.files.go index 2afbf6440..a5af9cb83 100644 --- a/auto/gui.files.go +++ b/auto/gui.files.go @@ -18,7 +18,7 @@ func init() { bs, _ = ioutil.ReadAll(gr) Assets["angular.min.js"] = bs - bs, _ = hex.DecodeString("1f8b080000096e8800ffec3c7f73dbb692fffb53a0bab4a21c997292bedebb284e2771d2f7fc92389ed8e9dd8cebce502224b1a648953f62eb6c7ff7db0540123f292a4e72efcd3c4d1b4bc062b1582c16bb8b0546237298aed659345f14c43b1c90c7fb8f7e24ff082ed30979996673122421402445164dca22cd72e2e594926241c9e1fbe3b30f472f3f9ebdff704a66514c07fe0ea07b11c784a1cb4946739a7da2a14f3ee694a4336816e5244fcb6c4ac9340d29819ff3f413cd121a92c91a3a23ef8ecef6f2621d53c41547539ae4d85d509029d44e2899a5259014258c86b74787af8f4f5fb3eefd9d9dd1ee1f791c25059964e915f4fd9414594987d05752444949abdfabb8ccf17ffe9bec8ea0e53c4e27414c1e3c25b320ce012848e6651c64e23702edf44bf892032fa6457fbcb3f329c848be4ea630ac644e0eaa16fe320dcb987afdbaae3f24e71783316b5066f124003407a40ffc61786a381f089d45736f5642419426c47bb0288ad549967e8a429a0dc8cd0e818f52e8877416947191fbd77936fb3b0da0ec3858b20efe67eff0f4c32f7b67e9254da0a30d6d0fd3f432a2555ba5e5dd4027b3c8d238a699d73fad4a0f8b2c86814ab4e7d374058c645d56b4230b5619fdf42a28b09bfd715d3aa7c5fb37508453d294228f82ace00c66330194b08130ec484a4259873900dcdc8db54a60a759be5c1fbdc231f695d2042412919c5f58901c253850853c51bfcad2229da6f1e102e61fe4b8265382a159866bc7c00d6b29798d7526352044343649cfe82ab58c148bb302981ab8ea4e80e911bdb27331a1347cd1709155e1a79f2dfb4f49ff158599950bc32813e5c483ef03b916c5042b915f72799196d305567c5c8530f9a2ea4e27e368ea2022a34b5015563accaa8a8830bd4ae23408ad84047941b328bfac49617f40ef9cc2124fe639a89b599a513249d33827312c0f2829a08d3a8545c180617259f94d1402eeb711204f00112c0910ab692638424e84b8100e415e8421c8784e73002cd62bd051fd825e17fdbba184ed5d707d4a93f0cd64954bf8de97c53cc595f10117d3db6819810e7f13bd1ce5830659522e273453d17d0004417294c0503e05f1a98492d790aa0ab4fd46546205dab189ca2d109e0459009a25fe40ff2c61edcbe3052e10183328842464c36e405a10422bbe3435ee21b65f60df20bc9633b1857df2e4a6d3207e912427b0ae248cac98bc8a4030604f5b1351dd425b85e875124c621aba713568501855247f633b97150bafea86e614f5ec4bbe71ca428bc5a42977b6ff78929c9814f0128295ad8d3f984d5f2469b25ea6650ee6438013c4f418df4e2d882e5495362fa353fbd2142b4e66d3c7a34dcb7158ed44dc665089573986d85e94609e80d1310dd85ef851e1dd468427419e5fa559d88e54821288574d492bb5676fe5558ac6d9dfcfce4ec08a838d083ad2f8db86ecc5c9d11bba9627ede488f0128122584597f05b9ba4da4a805dffb49c4e41f1d3d01b485a3f9a11ef3b6613c8a5d2044749547883b15ae5f5ff23a105f0e0926dabfd01eea341ecf51760eff43568d3e26876a48a84c6fed8928ca6613b11089b2fca0277aa76489b29a4127d6732f79700549cc959f7b0325a9459e262877d425c5cbf9904d3cb304b572007d01f482ec80548c3240db25018d6778e49691b606dd8cc601c0b04ae8d4e99366678fa80d0ab8cee87a43fcad7b0d09740638e7297e792b50d7649a00f4e15d0b14d0438462003db4b240fb8dde7d9a913c8ab0992db35dfdf4ffe80edd3079ee59e6c010e7c58abaf83e942421e853a7a9c315c86e07ac956e579145e9083033039c195a2b308bcafbede143f60091d53d836c88c16d305ba68cc1e32e0ec7c665dfd8cd41ef4a18026e8f17dfc7074982e5769027a0c09ee3a0b1ac7a561684cb73191fd2614bd38136b0bf123187b0e247de941e0b460bd2ff093e7c6b8aa2a178a6fccf6add9ef9a86ba7cf38459d7837dcc9213d8795da37399a4e80fa12b0acedf9537182a1005fa721ec2ecd52eeb808cc8a3fdfd7d15320ac5b6567d240f17daab03c34d16e60043182e96b3bd8f49c822c8df5f25e033ac6856acd9d439a6a88a71589682515280716ac7829d32f98b12b09681fc7741b1f097c1b5b73f247f25bb9c970ce22879b92e687e96166061ee59fc71030a9957840e89a8f1a665b1a96b7002baf4ad80393bbf23604f4d17c4a32ed61a4cd9ef3a040be09d43caf1638d69e89bcaa6c5c0630d9dd7811ea1b0777737ded1430ae0181465ae6cbe58ac5b1ab6fd07e136ee40dc1001f334b94cd036926d01a50713354c14f89ab0c6bec32e9c984f8b74b5829ead985970afe06bb88f9ad4d20dab6f5a57e0eceff9fe855fa41fa183ec10a606b6fe87bc02e665921799f7683056c7219a1f901e060ac034eb91db5bd2941e8531ede963e1d50fa19a78bd864a8c7f9cd06c0afa1e5c2731310f49effb41cf3a5ac112694096193f8cc1bff8fa131e25b3f42bcc76885e7ef6c5265b99b17e0473e3ec592cc4becba86ed0e47ce29d985659b40cc08db761b2b04f9b435528befa44c23ee91ab185bd3cfecef435c3bfdf0dab3285ab6901a30208d82dac72820b8b7731b20148348c75beb2dd6816a760cf433776b58811648b5ac4e2c399e26921b5a8e601ceb2798906fe31fc3d7a75a10a1d02da0c7d2cf7d1ca8b29eb169908acb06d6ab56a5d912265f64fbfa3b55cab4e2ea8c4c3c5a2f70cbbd0f7031d638bd6e9b3f8141b7ead8d2d9cc5c8f0bf065fd3cb6df9295cd96d98b6046b2f7773cb54d6ffb4ec32f563279e99ca7023cfdcba11c78ab1bf6fcc314118639a083db6e9f69f5be65b62f9ffdb103425d0ba4fb987f22bdd380d488c4a291334e97ccf41a68010eeb58dbeafc99e3882bdf75777df1be619b6db103b36b8a30e1747b0449f861d67caa79b80212ea81c91427aab6e93869584631d2bfe060e51e0f5639acc8b05985ce49163c4b57dd03250810d6c65a73088f3e88dd220ac1551dbd144e9f55c164a3dcfd0bda3b10cd2324655622aeb1f7cda9fec460426491cdb06ae4f71c225416be6691326f1a52b53bc92bb5cacd1a095459bf8d385399d3943c3a890ce74ec9c198dc054bba42420188f461b05daaeebea8a5bcbd5fb55e56157791b08e829a7febe00929d6e1d815f9f5d61b8c856fd02b6b7159836e43958b5364c78b8d34a0600c80df1c840f0a16bac9d9ddcd8d99a079f60f710991215530d699be2a222ff387d7fece7ec783c9a69544a1462837455b073fc054b49c99f929b3e26128102dc3b03996407f0ab552c4eb3467fe469d2bfbbd3a31bab3437627dd0178c0d081ab24e6c910e23cae18a1b02ae114b16d826246acf0c61013bb94c334c2c217ecb4c7416f0bccce09f744979fad194a79fa87356a7a47c570917fdb30ce2dc2ee54353b807e4f6d6183effb4a304891daa12aee925419bce5e4c485bd0e925c294ecd837ab8e7dc922c0940c9a102ad65b9a9130cad977c30e6d5ba73ffc605dc6f53a7d66713fa569b2376266eebed58665f1dcfb10848a636b72f61ee996b193d3550e13b98ae298601a0e3a86135a4b1008a13832d4186d4ebbcf0f98593446110051e11e889949a59eccda07f10294c81a68be22752a4e8cc913f17ac7d2872af10ead2bc9ffb805895b6d1b12efa4c0e77907c2f6576c4e13eab4c8fc1c5466e1f587a8f88395a4acae254beeda0715bd045380691a1b158dd2578e1e77da37991e9e4bf75c3161261f4ebda51c5fab13eb382fdff6f8d8b16308cc7d73ebb5a6f6c98af6f42ac2a3812b3a59a12aaa97092c99849d08ef982b4193624ddc79fea34003d61892dcd7a6a86555998b474766b8d12a6e98d2b36849d3b2f09aadde5c9157e069a4573e2e2404f1a55eaaaf5a3743a6fe1cd2d69a23c9a964ff6adba1488bf82c91b2cb829469d1c168b0a5666c2b94771dc5ce327eb477adee9ee6fe5468cb2c03eb4ab478e0d36b5019a177035353353248c12e807dafaf41bf58d9a8809dd278c6cf4435cf5b71bccdf13684f9757e15e83272503b4775b1ff471a25a0de8865b922f06ba024cdfc0720c72719235af17870ca2ab67d01d33832dd6d85f1d05b14fe29a519e58bf4aa6fc715841b90d966f146e617e6b3ae936009f4df7598496d8959a7d20ef3ed191dd298167423b38d1e8d4429d9d4d258b239d3c9c6876e2114abff5bad0fc912929702afeda02918a44e87a4685946016e2c3cab40c913b29ff6b23a7654ada1d62a3a0cf61e03d6076d4e8069a5583ca656a9a9022587e82d86694287241aef6c29547550c9322a03aad68a7ae407781b0753ea8dc80868e9437775c95e5552a46fd3abeac4b832e28c1e6aa560d3a0f735129149a666e0592b2ca58144e499ba247830102a1e3eb41d09c8b0e7d1851cb05559d4e273558d9b118f0d5041b9e934e06792d1e0b2c35101cfbd014c8ea5c347bc2af38567eeaa0e15e2e7e0c17a55943ec8e8e7aef4aecb222d1634ab70b96c27391eee546d9d351b6efd1b031c5590b275b94660afe8daed33242fd1d808c233364433e9787a200fde2d449611831fda3e0f95829266bd993d7df10bc13342be12981458cded562566faa03fd95134786690291baeb02ff5d1c168721aeb3b4e1ba5631ad3207b5d2522b55a49f2c52985ce73956a714cb1471e5d30b2363a08acdd8851e2b0e36659046675bc36a7352f3299d4665bde5e789b886bab08e7cc88867febad645a2bd3a17e8a827583414b301ef0383cfb55da45602a383553d9e9dae07d8eed5c1bd14289b8385d1ba90d884bcc920baa39bb31ed67195cd83e4686b561fc6ceaeabcd22f17e63503cd68b5a012078568cd3701423b808f2175a6c47a798467b046a2988d54068977a0a49e6cfba7b3ed1b4a57d0e2613b6d78a56b99fb97006c93be4dd8dbeb6f6fc95f3ed7ad4501ede8e760b75fc0cf0127d010fb8df27ea3c8d45390decf77ffbefd90d158691d33bfe6bb4a3798e80a3986892e1058c5c580aacdacf30bb34e5dc0924d60aee15ac3f3d37274beac586c46b1bdbba4d21607bc2fbb1d220d821b04375ccb3c1584b4e4d237663ef3b8edf46a89a9358c455f9846008755348a39867e7504c871f6872604d71a0063b666f5a84e100366a0a914a25e30116a89d72a87746e5846daa1c11b55c3d91298b47636f4a613c1bdf2aa0d9744f1cbe548a0dce7b8cc2326e8aead797b877b01ee4baeade74a420cbb16ac0ed73273eeb19873a09bf28847317d6b9b46cb8cf1a48482c1c01186e5e8984f66319c59258b42f686c471d6c167b15d9377525b5f265c25844a9116cbaea9e42b7d2371a105bf22aaf069aa8a0adaac3554162461bae437f0bd27fb43f2e4b123369b44852b61c17edc2f92beb6bd1a51ddd2b2dd8dd8d0e396770d2ba6d9ef134a10e2010b9671603ade1b881219145b1255bfa5e124ca7564b9e1505304ae94c0bf33f062e03a6efc5c1bbc2df26203ae9ed5c0bfef8295e75e1d4e042c81d7d3ab65d35e1dbd7c56efc837188dc8514b1a4442238c1490a0c2936042049dc698dd656e8080ed8a92ab2029f0703fc82fd9133a650e18e0f792274d4d176934a53e795916080de658bf606d6ce83047a09c239a25094b5cb104576514c478ce58ae86244f110bfc40d4ec7d197205445b91013105460ed8434194cca20c5cce4f1130de27ffbda089780688638972bc6497533b61f86a518d0f4097f88c07344ff0f9a08c2ce09f9c04f37488d4094ed8f0b0f725f0fc73c7a8c5fd8d91f82b5288eb229d964ba0c7e71436c15defe7a7f0dfefb7feeef8b77c77d034825fbf1dc03fdef9efe38bdd81bffb6070fb3bfc3b827de7c1a39ee5ae1adb2e1a04ce0b6b2a29405caf697480d7849a3b8f782b68bc0caef740c858d593fdddc73fee3ef949cf65c18f3327bb22eea1c49267722f7b84e3dc65a7c47604f8c16db3bcdf0df29ad84d26e0f64a73bb5431fb716f4b9a58073ab81ad89604e579a04e37fcb84ef9f861a3a7ea566a3c1f0a97d1db209ba396c10588cb32c6dfb0b869e5ad72fa88d869375b191649514c2bc35c633af17ea391d3a9be1461785c7c4c794284f32e56b59fb18493b76910da1228f81b0c08f1392ebb4bde7a23c4c96f93f7ecb7c919b55b8a2327b4cd96d0066b0f9de9d9e2f523560a3bd9d3749a63327bc52de603f2e3fe7ffd34d6eaa20c5ce134436bf4d14f4ffefaa3e60e338cfe2f7130cfc90f809fe37ad8b41b0c98ff6ea9705cebe30f59199ea3d99940a9e07723ed86b1218e23dd442c7f3e6b839b5b5fed417da907fdf4c32a58f65914b65f48b486eb7be29d860ac3e709aa5367d616dd06c10b2669e90e8ee3ca64109db244e4e764c06caadecdf254a278b215665bb12da3ee583274bd604826151dd2458080a5e4f3bbb2cd55000c300b80891540bf6e21d03c13e003dbeccb1a53148966cf4533c1821d092b8fa431bcc699b08697b76b30f3a6cfeba6c01d89372cf0e0e04de0378b1ebbb62e82f6de1b04cf6504260de85ec4155e7655473a90882d1111e55069799e55012041861096ea468dd92173e497728fb11493d19247967267318fb92c312164208f3ae67e95c452958a58a502f6df688939e220c94392940a3161348f8a1c5f909a5681479c127c2cceb8072cd0ef57b4b03f1c013990afe8b2af713ae75f8209eb7a806f40d4358ff6abf810f64cd4f72680463059396675689c4c85c772c422a609c816b6dae1644f386deccfed2d7922761b7643a22cb87bdceb0d3181f9b43a7fbb5ae0bb741eafafce309f11f8c2d759c310deaa229e53828923a9208751e2e7f890aaf758d264a2eb87070283008191732e802b2e2a78ef43822303962834d51136652d081025958571ac7940541c26f793005a04eab3a1d57c0b6cd2fb46c9aa2c8684ddf5b70805ab865e7f89ae69e8d522a7b46a74aef6a26945d0244a02f64c5e577a74bdc80a99e0d6bad3b591ee13e78b001ccb73d0f28f7f24bbf21fe32881418e0e2ca0635bafed5c7a3c407fb04ffe166d435a179aee41ccbb6ec4b452718feedfd8bb979f05c8f04de24a1eb04d7f939c2d29be22fc4f2467eccd04e94f0b3775d0fbc8d936947521e93e62d689965622eed1fbe55710323033d903a49f23630af1d69b998e4e83f82a58e7c7fcb1d36f21dfd6474664f23bb1e90458fc85c9b5112b5f38665741828c990782cf2c6d7374fedbe8b7df2e46fa311187051b827da9cd8203f2c4c11969f456eef47cdf1fa1b7c41172134046bef778204ec246bdcd5b276cf47878f6afc945e735f64d4c6468ce15ae3dbad8c42bcc2f4beeb7326d0ffb31d026f0fcbdc82a765113322725fa44bd7eca225e3c31a48d2e990cfe10fe53d23f948eef45e7e2a5fdbab800d3349fc66568d430bf563fe41717cf00f781f82a757127a1a54be8aec077669f71e14127f6a0872fecf64832df63f181839e1ad73b17387d706b7acf9f8d58cbe7d52be06d6c2a93e8cf929dfb4a4c6ae3d19f2534c6c79fe7ef9012691471945c3e6d7030360c098d9743121445060ed1b4c8625d28b1cc7f00d296d32cf7cb245f4433e92617bef0fe6b10dbf346d853535d4e9aab0f3f3002f558c6211e03311b1ab86d05e69401677f45a8a8586bdc62d92c63a3a91498924fafeb815cb41087a16404e771e49c0471468370fd59e4b170aa9bbecd344439e108bf28778c122163357fd43677467a67ab38b309c5584914fe5b9e37cf98caae7681b653c0d27a51f7b3a8763dba2f703544678ce8c5672fac78a3dfcf83bdff7dbcf79f17377f797cf760e47c45f43e23df38fa4ec85d0b9161ff7a0be4ff000000ffff010000ffff690c297809670000") + bs, _ = hex.DecodeString("1f8b080000096e8800ffec3ded72db3892fffd14185d6644d9326527b3737b719ca9c4c9ec7a93382e7fcc5d95e3a9a24448e29822157ec4d6d97ef7eb064012200092b293dc6ed5ba666c0968341a8d46a3bbd140462372102f5749309b67c4391890a73bbb3f937f7857f198bc8e9319f1221f20a22c09c67916272971524a4936a7e4e0e3d1d9c9e1ebf3b38f27a7641a8474e06e00ba57614818ba942434a5c917eabbe43ca5249e42b32025699c27134a26b14f097c9dc55f6812519f8c57d019f97078b69d66ab9022ae3098d028c5eebc8c4ca0764cc934ce81a4206234bc3f3c787b74fa9675ef6e6c8c36ff4cc320cac83889afa1efe7244b723a84bea22c88725a7c5f86798afff3ef6473042d67613cf642f2e439997a610a405e34cb432f11df1168a39fc387147831c9fa7b1b1b5fbc84a4ab6802c38a6664bf68e12e623f0fa9d32febfa43727139d8630df2241c7b80669ff4813f0c4f09e702a1d360e64c732808e288384fe659b63c4ee22f814f9301b9dd20f0a314ba3e9d7a7998a5ee4d9a4cff4e3d283bf216ac83ffd93e383df96dfb2cbea21174d4d2f6208eaf025ab4555ade0fea6466491c863471faa745e9419684305089f674122f8191accb827664c132a15fde781976b3b35796ce68f6f11d14e19454a5c8232fc93883d94c00256c200c3b921251d6610a00b7f77bb54a60a75ebe581dbec131f695d2082412915c5c1a901c463850853c51bf4ce22c9ec4e1c11ce61fe4b8245382a149826b47c30d6b297a8b753a35204434d4494fe832368c148b930c98ead9ea8e81e901bd3692972f6709c8cd61348d4573852f94faaf2a16b32afce9278bfe73d27f4361dae5423f48443971e0f340ae4519c24a64a65c9ec5f9648e15e74b1f244354ddd7c9389c588848e802f488910ebdaa20c28fafa330f67c23215e9ad12448af4a52d81f504aa7b0fea3590aba681a27948ce3384c49086b074a3268a3ce6f9631609879567e1bf880fb7d00c8234004eb05646e92088e9063214b84439057be0f0b20a5290066ab2528b07e466fb2fefd50c2f6c1bb39a591ff6ebc4c257c1ff36c16e3b239c195f63e5804a0e0df05af47e9a04216e58b314d54742780c08b0e2318ca172f3c9550f21a5254c156d08a4a2c4f333651b906c2632ff140ed8427f4730e8a411e2f7081c098415b443e1b7605d280105af1755be31e62fb0d3615c26b39131bd8274f6e3cf1c25751740c8b4ec2c88ac99b00040336bc1511d50db41588de46de38a4be1d578506855145f237b6ad19b1f0aa6e684e5109bfe6bbaa2cb4584caa726bfbf3e3e858a7809710ac6c6c7ca2377d15c5d16a11e729d8161e4e1053727caf3520ba5455da2c0f4ecd4b53ac38994de7876dcb71586c53dca05089573986d85ee560bb804532f1d84679aef0ae15e1b197a6d771e2372395a004e26555d248edd97b7995a2e5f6f7b3b36330f16097828e6afc6d42f6eaf8f01d5dc993767c48788940e12d832bf85e9ba4d2840093e0349f4c40f153df19485a3f9812e7076630c8a5d20407519039833db5cae9ff474433e0c115db73fb03dc64bdd0e9cfc118ead7a07573a4da910a122ae3644d32aa86cd44206c3acf33dca99a214d76924af4bdcedcdf3c50713a67edc34a689627918d1de609b171fd76ec4daefc245e821c407f20b92017200de3d84b7c6175df5b26a56980a5d5338571cc11b8b44865da9855ea0242a7b0c8b7487f94ae60a12f80c614e52e4d25531cec12af3e385540f74c22c0310219d85e2279c08d42c74c9d405e4c90dcaefafc71fc276c9f2ef02c7564f370e0c25a7deb4de612f2c0afa3c719c365087e996c725e04fe25d9df077b14fc2c3a0dc035ebd79be20f58424714b60d32a5d9648efe1bb3873438339f5957bf22b5fb7d28a011ba83e7278707f1621947a0c790e0aeb350e3b8348c1ad34d4c64df0945174fc7da40fc08c69e02495f7b10382d58ef0afce4a536aea2ca86e23bb37d6df6dba6a12c6f9f30e37a308f59f2103baf6bf43ca3189d25f453c133bc76064305224347cf4198edd29f1d9011d9ddd9d95121035f6c6bc58fe4fe427b7560b8c9c21c607cc3c672b6f73109997be9c7eb087c86254db2159b3acb14150110c352d04a32304ecd58b053267f4104d63290ffc1cbe6eec2bb717686e4af6493f392411c46af57194dcfe20c2ccc6d83b3ae4121f332df221125de38cfdaba0627a04bdf0a98b5f37b02f6d4644e1c6a63adc6949dae433000de5ba41c7f8c018ffaa6d2b6187820a2f33aa8872fccddd5e205a85ec031c8f254d97cb1b86e6998f61f846bdd81b82102e6697415a16d24db024a0f3a6a9828f035618dfd805d58319f66f172093d1b31b3c85fc6d7701f35a9a11b565fb52ec0d9df8b9d4b378bcfa183e400a606b6fe2d5e01f3324eb3c4d91deca9e310cdf7490f0305609af5c8dd1da94a0ffd90f6ea63e1d55b504d9c5e4525c63f8e6932017d0fae9398982dd2fb71d0338e56b0441a9061c60f42f02fbefd8407d134fe06b3eda3979f7cb5c95666ac1fc0dc587b160bb16f33aa2b34299f782ba665122c3c70e34d980cecabcda12a14df7c22619fb48dd8c05e1e9c67fa9ae1dfe9865599c2e52483510104ec164639c185c5bb189900241af6ea7c65bbd1348cc19e876ecc6a11c3cb06b588c50753c5d3426a51cd039c61f3120ddc23f87bf8e652153a043419fa58eea2951752d62d32115861dad44ad5ba2459ccec9f7e476bb9549d5c5089838ba5de33ec423f0eea181bb44e9fc5a7d8f04b6d6ce02c4686ff35f81a5fadcb4fe1caaec3b405587ba99d5bbab2fea76597ae1f3bf14c5786ad3cb3eb461c2bc6febe33c704618c6922f4d8a4db7f6d986f89e5ff6f43a82981c67dca3e94df69eb3420312aa54cd0a4c33f0b990242b8d726fabe257bc200f6dedfed7db7cc336cb73e76ac71471d2e8e60813e0d3beb948f3e01439851392285f416dd46152b09c7baa7f81b384481d70d6934cbe66072915dcb884bfba061a0021bd8ca56611087d5add220ac1551dbd144e9f56c164a39cfd0bda5b10cd2304655620aeb1f7cda5fcc460466501c99065e9fe2884b42ad99539b30892f5d99e2e4dce5628d068d2c6ae34f17e674e60cf5834c3ad3317366340253ed8a128f603c1a6d1468bb2aab0b6e2d961f9785875d247520a0a3a404b8024876baeb08dcf2ec0ac345a6ea57b0bd2dc1b4212fc1aa3561c2c39d463200406e884706820f5d63edece4c6ccd6d4fb02bb8748a32898aa49db041715f9c7e9c7233765c7e3c1b446a54421368897193bc79fb37c95f439b9ed63961128c0ed3390497600bf5c86e2346bf4671a47fdfbfb7a746319a75aac0ffa82b1014143d68929d2a145396c7143c03562c902eb8444cd69232c602797d50c134388df30139d053ccd13f8152f28cf4d9af0dc1475ceca7c951f0ae1a29f732f4ccd523ed4857b40eeeeb4e1f39f669420b14355c26b7a49d056672f66abcde9e40a617276ec9b14c7be64ee614a068d0815eb2d4e881fa4ecb3668736add39f7e322ee3729dbe30b89fd234991b313377c768c3b278ee630842c5b13639dbbb75cbd8cae922c1895c076148300d071dc3312d250884501c19d618ad4fbbcb0f98593446110051611f889e66a59ecc9a07f10a94c80a68be26652a4e88c913e16ac3d0872af116ad2bc9ff5e0312bbdad624de4a81cbf30e84edafd89c3ad46996b829a8cccce90f51f17b4b4959dd4896dc8d0b2a7a01a600d334262a2aa5af1c3d6e346f323d3c97eed962c24c3eac7a4b39be562756c500103cc711e07a276559cf0efe3af65744c44db9360c52a93fb7a78cca7032bfee41b5656f1298fbfa266fcc309455fae975808710d774bc44a5572e48589c113b7b9694a7635e2fb585c5d330051ab0fb90e47e4d181ad6afbe4cebc834875dc50dc273162c689c674e6554e86bff1a7c9af8dac5258b20aed44bf1b1d6cd90295a8b5c37a66a722ad96f55764576a43d93c02ea0e7ace903e4332f1a7e37f114a3349a3aba0d6f5daddd8728210922d850309f1b15b5f0bea58177c895e89a5463b3ad448ecd83f493999f52da4e070bd494e7b3eec4de77d42c86f1a3f3648c1dd47ce9026d9e2460aa8b164f5c7a03fb8fefdcc2ea2b1a69a46017c0beb737b05935a87901764ac3293f60af857194288e3ede8a30b74cd6838d91ec979e7659ecfe190711ec95c4a09111f82d501227ee135055c709235a719f71ca0ab67d053f2bd063370ae3a1b7c0ff2ce5aca5f3f8ba6fc6e5f92dc84cb3782bf30b93a35791b700faef3bcc644d8b1aa7d20cf3fd19edd39066b495d95a8f9a2a91edf61a4bdad3e64c7ce8168f3306538af52199d5f252e0b51d340583acd321eda52c3d056d079ea2a2249d995307581dcb7ba8a1ae557418ec23065c1fb43e01bac96b70bf1ba5a688ba1d60e8c18f233a24c1dec69a425546280da3d2a04aad580f23026f436f429d1119012d7de8ae2cd92e4ab2f87d7c5da41f141e81d643a9144c1af4b11e073249d70c3c058ae5c79080bc5097048f2c43c5d696e97c4986bd082ee5e8bfcaa20607be685c8d784f031594eba60ffe8c13ea5d753877e2895c80c9b274f88897793a77f45dd5a242dc344e32a738f2f112fad095de7559c460b625052e9bed241fae58555b67cd865b7fab455744bc1b976b00f64a5dbb3d40f2a21a1b4178f634d18c3a1e45c983b70b9161c45e1836cf43a1a0a459af66afbef885e069e707129814a54fcd56251aed189ce8281a3ccd4c970ddb190275d187ac1264cbdb74add23109a997bc2db2da1aad24f98a9e42e7854ab538f3da26bb978cac560781b51b314a2c76dc3409c0ac0e57fab4a65922935a6dcbeb0b6f15be6f14e19419d1f0bbdc4a26a5321dd68fe4b06e306838d9013c9630d132ee2230059c9af66e756df072d07aae8d68a184efacae8dd406c42564992ac59cddeaf6b30c2e6c1f2d5d5f337edababa28f4cba57e67a566b41a50895367b4e6ab68b319c0c5f319a6c47a698007fa5ad6a18954068917eaa49e1a42077adb77942ea1c556336d783f7091ba57006c92be36eccdf57777e42f0f756b51403bfa39d8ed57f073c009d4c4be55de6f15997a0ed2fb70f7effb0f198d95c631f30be5cbb8c54457c8d14c7481c0282e1a5469665d5cea75ea02966c027d0d971a9ea75ea0f365c462328acddd4585b6d8e77d99ed106910dc20b8e55ae6b920a4e1624665e6338fdb4c6f2dcbb98431e80bdd08e0b08a46d1c7d02fce9339cefe5087e05a0360f4d6ac1ed50962c074469542d40b3ac25a16bfcaa13a370c23edd0e09daae14cd970b57626f4ba13c1bdf2a20d9744f1cde648a0dca7b8cc0326e8b6ad797d877b0eee4b5a5bcf858468762d581db66566dd633181a56eca231ec5f42d6d9ac2281369568e949d321858c2b01c1df3c90c8633ab6451c8de90580ecef82c366bf24e6aebeb84ab845029d262d83595e4b7ef242e34e3f78d153e4d5451419bb5844abcc88f17fc3907e7d9ce903c7b6a89cd464166cb7e31e78e88338c75efd91457fe4c176d5a7a5cf3e26ac134f3e55409423c95c2d25774c7bb8528918eb32651e5ab2d56a26ce7df2d27e42270a504fead81170dd751e5e79ae04d91171370f1800bfefde02d1dfbeab02260d9e04ebd5a36edd5d1cb891f96e495d1881c36e4d44434c04801f10a3c1166d7d04988a982fa0608d8ae29b9f6a20c3345bcf48a1deee5296080ef0b9e813799c7c184bae4759e21349863fd8cb531a1c384937c866816c4cf137e68084acc0bf128395f0e491a2316f882a8d94b46e41a8836220362328c1cb027a928990609b89c5f0260bc4bfe7b4e23f1e014c712a4786333a566c2f07dac121f802ef04d18681ee143550999c3af9478b37888d4094e98f0b0c74af0d87343abc5fd8d91f83b5288eb229ee40ba0c7e51456c15de7d7e7f0df1f77eee6dea774735035826f9ff6e19773f1c7dee5e6c0dd7c32b8fb037e8f60df79b2db335c7c64db4585c07afb5125050f79ab46fb78e7acba408b57ccf616decd360819ab7ab6b3f9f4e7cd67bfd413a3f0c79ae05f10b725b1e485dccb36e138375922801901fee0b6993fee398292d83613707da5b95edea1f9b8b721e7b0031d5c0dac4b82f210d5dabb5853124243a7eafb556b3fb460c422076e6c2e36d386e727ad3eb65d1df3b4405400efbd6486fa1155072a9410bf835aa2859fcd395ba447b4db47ac529571c528d40c4da6cd1f371a39abf06b118607dd479467eb58af24163b31cb867a1fc3341ab27bf8532408f19060834d6a7b23c4c91f55e8991f5560d4ae29d39cd0262ba8365873d0cffa969bc24ef67c63cda59abee1b6fe3ef979e7bf7ed9abd5050938f1718276f4ee2fcffefa73cd916718dddf426f96929f003fc7b555b51b0c58e4c15061b9ddcadf73d37c5ebd338152c16f47da0d63451c47da462c7f45aec5412f6fb8a1a6af872bebc76cb0ec93c06fbe976b3c68e889e74a0a0c0f1354abb62f6dd116c1f3c6716e0febe3ca64109df25be45795c0e02b9e8f7354a2782620a602b28da7ec5832d11d6f48c6051dd27d188fdd4ce157c6ab1b31181a1700632340fdd69140f342800f4cb32f6b4c51249abd14cd040b3624ac3c06c8f06aa7d935bcbc5d8599377d593605ee48bc6121130b6f3cb75af4d8b5711134f75e21782923d06940c7282cf0b21b6bd28e1c1a6239ca71d8e222294257820c212cc5c532bd43168258c83d865234a996f6b2903b0b79b46881a92c0379d421f7082596aa54842a15b0ff060bbc2a01923c2451ae10e307b3204bf121b5491132c529c13713b5ebf002fd4e410bfbc311907df9a63afb18c633fec11bb3ae07f8144a59b3bb5344b6b067a23ebb023482b1cd31ab43e3642a3c96632d218d40b6b0d506277bcc69637feeeec833b1dbb08b4279c61dfb5e6f88e9a1a7c5c9e1f51c9f6774787d71fafa82c007bece2a86f05605f19c124c798905398c1237c5c7869da79226135d6fed0b0c020446ceb910448ea8e0bd0f098e0c58a2d054c60695b5204094241cc6b1ea915d710cde8f3c68e1a94feb16f32db049cf7c45cb3c1b12f6e48541285835f4fa5b70437da71439a555a5736baffe16048d83c863af4576a5a7ae17592113dc5277da36d21d627d18836379095afee9cf6453fea31d8230c8d1be0174cfd46b33979e0ed093ed93bf05eb90d685a64710f3a11b318d543ca2fb77e6eee5d731127cb7bb90076cd36f93b305c597b6ff89e48c3d1d22fd69e0661df43172b60e655d487a8c9875a2a5918847f47ef50d840ccc4cf60eef43644c21de7841d9d2a9175e7babf488bff9fb3de4dbf8d68e4c7e27361d038bbf32b92662e57bf7ec9e929730f340f099259c8e2e3e8d3e7dba1cd50fb8382cd810ec436916ec936716ce48a33772a7e7baee08bd258e909b0032f2eda703718637eab56f9db0d1e3b1dfbf2617adaf39b43191a1b950b8b67bd9c62bcc8c8b1eb7324def5b32d02a64fea3c887b651e3332725f8429d7ecc225e3ca5a5892e990cfe8f453c27fd0329f140742efe358ab23803d3349d84b9afd530bfb69e9e20ee5f02ee7df151eae25e424b17d05d86cf2dbfe0c2834eec7e0f1f9aee9168b6cde203fb3d35ae772170bae0d6f45ebe18b1962f8bc7f09bd89447c1e79c9d584b4c6ae2d1e71c1ae31be8b30f4889348a3088ae9e5738181b8684868b21f1b22c0187689225615d28b1cc7d02d296d22475f3289d0753e99a21fe2b08bf7ba139e385bdb8d6e58cbcf8e1475da01ef3d0c7032c664303b78dc09c32e0ecef081564ab1ab7581ece9ed6540a4cc9e7eee5402e1b88c3503282f338724abc30a19ebf7a10792c9c6aa7af9d06bcd8c8107e55ee682542c64afea86deeb5c4d4467166138ab192c0ffb73cb7cf98caae66813653c0129251f7b3a87639baaf70a9a5ce18d18bcb1e1a72467f5c78dbfffb74fb3f2f6ffff2f4fec9c8fa98ee6346de3afa4ec86d0b9161ff760be4ff000000ffff010000ffff1bbddbc82d6a0000") gr, _ = gzip.NewReader(bytes.NewBuffer(bs)) bs, _ = ioutil.ReadAll(gr) Assets["app.js"] = bs @@ -63,7 +63,7 @@ func init() { bs, _ = ioutil.ReadAll(gr) Assets["favicon.png"] = bs - bs, _ = hex.DecodeString("1f8b080000096e8800ffec3dfb5bdb4892bfe7afe878e712b2876c4832b37b047c472033cb3c927c90ecdcde7c73f7b5a5b6dd41522bdd2dc0cbb07ffb5555eb6dc9360612e6f14382a57ed5bbabaa1fda7d78f8e6e0dd3fdebe62531b85c307bb0f3defc160c00e5432d37232b56ce3e0097bbab5fd9c7dcb4fd588bd547ac2781c408dd86a394aadd2866d1821989d0a76f0e6f5bbe3a397efdfbd393e6163198a277dec6e3f0c197567981646e83311f4d97b23981a4333699851a9f605f35520183c4ed499d0b108d8680683b11f8ede79c6ce42817d85d217b1c1e1b8653e948e041bab14409231c1f0fdd1c1abd727af68f8fe03cf03ac103916f278b2d713718fc5138f27c95ecfcc621f868f27f4ca478c54180abdd73bc94b0eac0e7bcc0fb9317b3dac142a7edac32e050f860f18db8d84e5cc9f726d84ddeba576ecfdb557164cad4d3cf13195677bbdfff6deef7b072a4ab895a35040b730a288a1d5d1ab3d114c44a55dcc23b1d73b93e23c51da56aa9ecbc04ef702710664f0e86113109756f2d0333e0fc5de767f6baea340185fcbc44a1557fa9aabc6533b557aae4628e353605c08148362eba796491f7b9a6a31deeb8df9193ef61320e4f00136b0d28662581091fdc22e2f91cfaf81bfaf61a48d275757bb0357ab18c0753652ca1aab7932f08d19144ffd48c67d78d3cbe04069305321ac83909e999d2580841517161b5309632315ccd825fd642ce1410000792365ad8a76d85fb6928b1759d91890f6c63c92e16c87f5fe26c23361a5cfd96b918ade262b5e6cb27d0dd4de6486c7c603699663d7c5d503fa9386ff3efdb21831e27a2263cfaa64876df7bf1451ad6e1f81f522152b93705080cb36587e1071a836d90f2ae63efc05cd330a047293f50e406da4d000e239405874d3188283b0a17407a837c1d092e85a3d44d1992f457a75978e8121dda545cfc1c29e5b4b8b9e83820a23a503a11ded621537f00ad54435c8bcc3b65ed4395d7943dd785f960c4f9491a8113b2853a09367cd01a4b15eacbc510a46c11643d16b12380f05ce81d6680888856914176d02699290032f650cb22ebc51a8fcd31c0e106da7c9208fb97c148243661344a72c1871ff74a2d1e2e1284a03f893d1c6d3675f6db2a7cfb7f0bfed272fea14d43c90a9d961cf2ac8e7f4d94e2ed8f3f27d4ec8a7f0fa69fefaaa89178859dc0f38188e869c87620cd06e95825e436f7bab7c4d92cf433941fa23922f96d32a27706e88e7e98bbc600f65845693c7b64513608e289a9d4fa5151ee90c363d074353b306e7c251fff9d6566b4fc19c6171f83f05b3b20c8aa06f221e865e8d8a9d00658dff2b1281e46c23e217194dfff2d55f928b274507995ec12c9b809900911eba3755ed2b2a3336f833c83eccb5967156d85a06339945b32dfa93fe4e5197fd1988a2c1ca8c606265c914286d40a91820a1ce19b26aa4053f35380f870a9a6b9168056d4210c18181191226f47369a7d51e9d3c993efbf3a078dd20820632e55cb92ac47177402a0833f1c04dc50f7609439a7fc08b61ef5402aaa2193a00f82ee667c53ccecfb0c4fd41f392ff0cc498a7214cb7e00708aa27279c264d3797ec06b2e804e7480e48ebac0c6721d08afa18de4883b3d41beeca689297a0ddea31a37d9cc63c7cf2b69ffe95664fe666f7deb3a730b792ecb9df83212b26d35d129bbcb3a90cc0807a1730dbd5c777134b6a058cfe0b100b8a86adb3307537cc6ae498a461058f9c3a959fa4b005e23483e70d02ad92409dc7955228e7d9f4fea75eb31ed07f32416f0815217ba8f652c36a12ce92293a1bacf8e5913de6c0b51c89472232c98b5781b48fe211fcda1d153c0319a47a23f8c76b009618178045224e6b58109ec30217e735823f7a0a9e53101c8b446d3c5901e069103460dd0f0286cd613e527a86a0ed0e60a49587468eae3434a07f2e449354383c76d13970411a79260394f86b800706cb9e3883625682d15793067c79f36b1246ae4e978f1a438fe6b053b06b4787774215334d2d0ad94ad0a9f1780e34d7fc9a148169c1726d57149531549f36063e763ddc094df848a5abc106165f5b4f44899d354519fb68836e779086157b55292d4b76070036c51303b0736edae8b0f8ae3ece335f4b6d2c4c18e79b4cc5e18c4188741e333966b1f085315ccf5eb08c6aec9ceb1827d66c4ecaba070a4820c543e87f2c2747319afac24c42c7e504530326f4a200668eaa15ae94034944c8e87f2f1bb66e919b7591a801d5da9d3eab9750a0d61be658bc16221001ccbbcf8605c5babbc559b9694593e1bb2946fb886faa698665536e209417e05bf2338cfc21c88c15f8253e38e6dc62c2a08c27a314499e81832e485689e2ff589cd7bbeeef0e92ba282c051a8391cacc9e5503982c40eac24cf750f069646306ff3c13d19fcc936009c40ed96c79377ae8c068005a95931074652c2f7a2dbcaabfa83d561eb29f73122f2669085e140868439e6b929bf7870dcb298e8228b681ae177acc4fca1e5aa5fcab4542ee613094f4980c90b0d9085298c5e29ea9c6e5253639c0820dfcd53f3a04af8878058f825bd727fab4f8f77b001bb9d649ee862ad5ea41cd0ecd6a54237fa9e60e011d429e98dc4b4ac08fc1f4cc9f6af8e62e16be04c4be90105b5f0032f3dd377cd5654e0a7354ea1f4a2d7c62df2f8c32416fb99d5e5d2debbed4015671575d9f2796dbb44afaba235a15563e474db440754e34453c634e2e1a55aad41991139815949e1b6d15cbd6acd88cc6da79e122c26a13d6488f64cf109ec9043dfa965eb01f1701b59561a9ee2ac2c2e9724b6479d331ab2834fa49d0c98211825a6892451099641d1d524230e8047ed00dfdcd117321aaa712113710fc9a4a6e8259a133374230f71122f052c39f3292fddc97f1190f65973cac8c7fe61f78464e9a0478a5b55a17ff76603f27a37d154150d70c7fd0af986a15cb7f92bb70036eb758b3cf85ea2454a36640f30dbce3612dd2bc0dc64ea8dbaf65280c4c0c3c3ce733f33a8d46425f5d316961e84dd6d1e8e5cc52a3918c39aac8cbcf47b0a98a9af4fa5ef97740ae107bbd26b5a8cd3d22961faa34f030020d156f6633de80ebaec6e4aeaf45b1eefabcc30ec61091388a0ed9563dcc56e718ae142a993b492d7c293b59992dd8a4852b739e4a0505a2ec322cf6f6008de1563eee167bd9e51615fd7e3651c0ec7c43007ee006a2a79b2a4e67fd0615897ec7e071bf81f0bb37fc8730cb88d5e8e061a387d7eafe523b85a94af8a7a2a97347935869c1de0a1d4963601633774f7337260e69d6277bad93fb4c795ac068c9339fb8858d1fa59dae393f50cf86d2c74892b5dd0628e90a00a08856815ac2aab988895eb7c76fede10befc881245a4660127b1d49e112e115b220e09afb326c49f17758db4ea0021e4f84eeb51a0ff6e8115b7566c11d2a5a06a2656659aec449dbac9975c80ea608a26945ac5d3ddac2de35923dd5540d66ce2b491ae2fead656962e87cb5f44cb12057c9c760eb83f10453323fe5cb591b4f7ebe3f4919875e9e8dc1270fe15c25af5df541c1dd88f395ba0c67320d37cc8394f02cc9800081ff4882cc2741e632b1fb3fb0f75686378b1ecd0c5ca6a80f7fee87836fb939350d4c0fdebebf3d4cfd248549df078d69b8dbf0184314ad79b8b37d75f56ff734c639cc5eb3636ec59a94804162e12329cd4f8fadb23c7c8c599251823210091073ffea0a9f363aea1ec5147cbcc3c7aad83cf9dc446b9de0de2777423095dad52906a1e9ed932cf72532c90690f7e35881a72ede7cc71eeeb114ecd758c69d266b65e2e246b4a9d2cd1c5d3e1a3bc19db5eb65eb963aedf9ba2eee56a28626f5717db3b708fbdef00dede15a3532981ba4e1ad3dec18643c5e6594cf694d9b99f3bf0b6dd6b7a167aef57d0e14d68d0ac89bcbdd9d9b0606377697575a4124686905b174d3ba3c5665a742238ee63e2d23b678ac375d3f6cee346ae9a3d5bf5d7731117bc8d2ef5567f98e16139b24fa6331b156b84ada50c6cdb4e17e100072eb25ae9c00600f35f6ff16179a3a24fd77e1266708f7d182ba35c5a5be5fb3c9efd9696ed26215dfb9d9e64e5ce87be65f21ced0c38df5eb0f47eb36f292e54f979b1cd4b79ce12bdaa660daf7550a2c731bb7faa1882776ea72b9f76f83e56b65a52f6eb4b1b2ea7602e2e87256f04736d376ffcb4b78db7f2723011a0cbea0d8e9fd6d278a76209ebbbadac90f05808736d652c44138732e2b3622529346dcfda6ca8ab3d7bebfb22ad4b4d3d109c26abbaa9bfec79bef3eed76ca9a4c179b8b8b032bf8fa259d535ced1c4bbee5347b042045901d74acbaca0fe6057dee204bd7f18ffa898f8ae9c9aa905397d91b3cf9ba3300148daf526d44bf386ddb8f851df486276982e7a3d8807dad741acd6fda5e690803634ca49da6a33e385d039f87d174500c35d002186670b5e17b907263d9b17bb1e6680b10f2a1ff89d2b341a0fc149dbfece0d061f5f16e9094c6a488e2cbb4ed8cc42d8c00cc7207b40f5a4e892cde3f4f8b49100b2a7dea2c11aeb081e3908b731151b93aa4bf85febbaa631e8816b9a5422f903c5493560bee2a6467993bacb8ab839619348f8774120effcf334f35059f3eaf376b0bbb979a1d7101851149437dc35dad9b83c20373735bcdce4c9f77989936dce6a689dda43e54b9adde08b083b89f7e24183af49b0cd885090b3a94cf59a215b82c111de2633390087604b4d5c03a567a8cfd5ae7c7e058cea0ef47531186b2385de9204f56b69635b3e9b692d3fe773a0cd02a4fbaa8701fa449c6637507b2d43c1bd0207d4e814f223cd2b092e67df696cc2c9baa30b86ddee7879f3a389f1fadba0f7ccf93e4b7cffaea99b03a4772eae04d13a1b0e29370bf3cbd03c393f1e8df16bb8f0e3b182d838f6b4c15ae332fbc1d6edf01671b67116b8d695bc611b872568ea5ef0e4e3d8a026ea62faae9d4725b443da37a63fe57aa9c835233fc0f5df2c63516f4886bbb48a0cbcb68e6f6f7371d663c149d6f85842a052f5d4b77f09f41250ffc92681473083fddb9e98f7a90f7da1b5c03a1960864a5435d45b4416973f00071935dd6e94a47b82275d6dc5c7c102a74439b01c775b5832402e3f94ecf2a0ff6ef9daae08983a93adfeb3d4410c18abcba8028756ec6ceb5a83ca55c15e246572bf584598b96aed6d087b1d251765900feec65f7e8a022be229e2c58e3c106f9ae288a62e9ede56330a51e79ca8ff1f683bca37e4cf9b7fe17d9310adcabd6521a486d67f34b36bb211f8910ef6f70c081b20d9d2d3904571ecbe65ac838c12398d9c2eb1c5d4b445171f335918a12137ad99d4a0dfbd0abdcd443b8d3a63bd0fb54e382140296a51bf1ba9f8fa9c40d9684b58783c8003489c06b5d56c9d33e1d92b0c06e51ba740e8616cb456325798fe0de24ce58b52de054b7bcb630cc31f3975fda989968821de0c2e3b2b1e317fae7641f1939e66d3760f548c0872c3bc00e66cba9b372c5b40649ddf5d909e26de8462f9c45f02774aae8a62830121b92b6e7064ffa6d29cc1cb50e2d1efe380587c05d8c02d1039ecbc54137d9a91009c21a491896eef1da15d1902e028b492be1c99df105cca03d70bf06bac16d9256a97ef7fa5ec7fb25cc20b5eb1722b740c5ea2c0126e05965807614f2f8b41bae95c62791784d82be1c0412058035072550c2d0c1e950a953a7347d7664f1bc661a064450f6e553bab08cfb2845b80c08fcf1714d91f8866737c06f84322717316dcb329b2eec3373023312d42813990edc1bd9c2f6dc70bb715c68cb7824324b868ecf625b968400fa944ef4edf5fea6a27cc34c66beb0ab36e3b592b5e26ee366bb556ab51427ee9e80d858981d91e6993dce95d80f53e3f8834b7dcd33ecb74540eed65c317bb49fffbc06158319904dfa4416708b70452368b3e378a2c5b97848ea72d075e95dc07a62f535e9fe8a6c272ed0726644026a60417d5aeece29670599ec60a632df975b808fe991850d33f2e40dc172274293cfc053ab3009e433ca278214cedc658822ef7e058eef0eb0af4fe0ff164b49959355fc4c64d7abd4995f31575f14e753af9f8c3f81fedbd2f1f7cd5f2f216af73bd082e733e38908c7bd259053dad15d1b81372354490e5a00e1fcca77dac0ec9a36b7f01e5217378f3af0ecc6f2a8036bfd16a28eea41b65b893dba3abcbd08044fa52c8d40aa4b9f6de56d4ba06df55689644a80faf8b311c9b4947644323476650273d5f1729ada5504ad3318b5cde29a824a3829d5e7b46cc1c6340cdb1c7bf35b253a829e25f3d8b13b37548970d2587e4c718317e816544f38fa60f15e6ff0bf3f71ef9ffbdeff6c79ffe1fd5fffe7cbedcdaf9e5f7d31e89cf808cfd5c213aada3cd9d7e04411a2b4949521ca095e08023471b929b06163b778c08a3b4a667df643e6d4e37b032c40bfdedd66e79c1dda88d8e93eaf02ac73a11d29c9fe9097acabd2518416aed62d0c578d18ba44b90d9055e386d521c984e6ba8014c196bbd7a5cac68daf9e97d102b93c2178274fda0386cd3c5aa00001b98cff7631a13904d1dd1dd0af5a7f71385b80f79c13e45eb66f91b99949c2cb6c161925577e0db3840d6a86095f5cc734510775e3f4afc161699e7203e4eaad69828a0b4a4a4bf409ec8a2366976571a5a56dc167f49eebe6244f0ad0e508e8d103c842f7d98f122c0a08b3af05f9f672cca42d03638106bccf5009ac04aa56626127a8ff2ac4d4e55652dc33cb4dae1c78fd35da3657b938d0447d61ae885eafadca0ef5a566a5228c73fa9c20b556372dababd82afbb9d6f230be5addc168c5a0da231e8f1fa98b2e99ecd43e2a751ae894a6e8a94371ca0b03aa179bb9bb0fdac75ea0faed16ad4bdddc8964ccd4251a223a1fa57cac5584a28c67875904ae2faa4799ea03d38c57ea352be489379773a324d279a63e06cfe6154a676c1e9f6673f57c7cba00917bcfccda35046cfe36854fc050cc0d64c3b191b48ebf59fe959d632a15537a38dfa2f5c918997d4621665fefbfa32f1e386bd4923d5800d575b8d3584830e8f821a078ff01a5b0bad247cd816a1ca99e9459724ca60ec9ad30df40548c3a4403d286e77cb7736fee1476fb1195db94851382c65d658900a10ed21511ee531915438f09d96b30bafde56fc41a1b89bb1d508fb2addfb402c148b1ca379fcc2e63022940cee1e65acce14609ae613940e88a749e39107d63f3d7b9dfe1eea3733a0fec46ff2f40c7db2580e8ab28e5dec35bf290d115594acf555c69d7f03b21922e67ba5a634577ba6cd21be2ff394b171a9baa3b5de9c06d12aa3c2f709c5d34b358e65c2785af164908d9b7ef3a36afd2b0cd8bae96379611dd297b98cc41ca4a890451c565b94d9c85dca773d6f160abc32ef461e764a0095c0158199a66851859de46e03c0f2bb06e3998ff50a983895631b965b8d10d9ca358e430afe96bafe16c371700ca15f0ae25d95a7ff3ebb3e5e4d2b64a8b53522dcf869bfe283a42375156821049d3d64490fb39a2a3a07196dcc1c06b4636d2c70d82e065e25758ce04f195081b71eb4f214c83982c9c15ad314de47a78d049914fbd00925df95fcf1356c4e78f05109c346eb8e0b1f27715ee72c123ff0441d79ed3acf8dead76b42d41949f53b8e5b5874f9907a8460df9f76ac058158ce8f44cf3eb2a5cc53e0a27ae4e3fc61cd9639c45e74adcbcf378a10febdc94cbcbbc31de734bb7dd64cff40136cc0e2df078338705e5a9d1d12217a5ac8acfd9cd0399b362a3e44de28e7196fdfdbcd837e9f478bb62b7566a8e940a1753accbeb9fa3d922ba74c7066ba0be4e24f0a902ad0e719fa4f2e4ee24beb52c01d0ce950e7ea5faf0cdfba3dfa32e5c07ed3523e245a2c613792a664b88308fed46f19d982587efece06ccbfbabb7fddc83913c18ca0c9e3dfbb2377c6ff8840eac3d592c69abed6b47019ea7256a49cfeb756c13cd06b8fea7436abea6b0fb6f8fbe13b30d373c7843df885868dee6da2ce5d5dab9fdcfbddfe85a9f91fad53ad4d7754d49c629f4d2b6c33d4d3ffb3999b54f45edd3d705f76315cf22959a0cdb63c21664e13f6fe6c4560f34b9ddb4be9e2598634bab54c52f14e36a48c06538a3edb4d5c05773ff94361402cb93905b5412b3496d9991ffcc76cbf22429921ad0c5b858ccd4381c5d79066a8e1dbbd47e80272c8bc59844ab88e0a24db89408ced8c4275c560e5bd58f5a35d0e3938916135a14c56da518a0f9d93a523a023d83709b9f018e746b106ecbe68d23c208e6dc41ee0585687abb60bb96da95290d47b2b75ae0c791eb1f55aa14b03de04b8a4bc7d973556e5a742e011a545244e500e58d09eefd2132ea17f6c1b8ebd7f2af2742fb4f6017ab77eee51f4d8337897d7fbc9e4da45bbbd73589e5dd7c45bceee33d7c2b02d36a13f106f01b1f89a2ef93b9d5b0ced3e658e55e19c5958f08573eaf009608a876e338bef3cab0ec8ab0e605628dd6ba1a9c8c312cc9c98b1a154b78cb411ff1e53e1d11df18cfdd7d57dec4537e15770519babcc45e8f702fd24ffc670c312a972717e3b9b2f92b7c7054222a3ad363dac4efa214f71b2f37e260f7e9757bebeabe6f774fc93cf8995919f74f602ea0ab6768047aaaddf54b8037c7695e2e34776fd0eff1d0237de5b143b5e92b92bf4ecdce3e5e79238766ba5df9ee7e3177552e0ccd672ca85869a507950508701b0e54327302fdc8879f2fd8d3adede72037c36ff9a91ab1974a4ff02bbac536bfb1423f8dc61c416388c8253059699c5e863bf589bf332fb8ec4ef9b416bee1bd26fb5c83d0bd946284f7de36bef889e571a061f23f4ce3298f5a2b683b4d35dbbfc094c5f1ab1fd9893f8d6460dbeabe14313b91c154b5f6f412bff40cc0bc9dca5026a671074be3eba39d4c5d0ded6fc12419dc4e885b28f156997970be054bcd0ea588da09e3a084e81cf0c5bb0ab569ab753c031d3f49c3509ef1d651fe2e849500088f792ce2ebe0dc789c13c0cac512b11fa6b40fa22667468ded391d56d48c82015ac5c433916abcb38878cd9cc24485e0c9f441a2076e11f21bc5de6a35d13c8a70a0efa134455f079dd94dd6a6194f59d66e3fb55310fa7e1bade69ce991b4a3d43f1596c63ee51a2c51accc004ce4051899c68b45a31ff258820003102a81e041ac0800ee36e84f949a84826efd490626863065e64d1490a2f8dd3df236e17de22a5e17fdca75438e05034a75fadc9f822d2c7f0f429d7683f00cc88e08b0a3d8bff6b81fd20fe900b328a18c2490bcfedc3de87376008c8925ee3bfdde06d71e1782a4c06a445b9c89301801b11b6f16707b1334528362065ca7ec9d96f82be6d705e14c427c140f3e720d78571e3a065e47be516f42ae3f984cb7f6ddf3b727ddc86d79445dc7d2cdd5788a78093b022f07dc559e1076bde1cbfc7981f4bac1de41480d76b46db4a609ebbac5e4b7ee76e14fe3432c60ddfd1b196771c344ff835b72a5d261b3e2878fa9d033ef697fabff6c79ed8287830f66503274693b303f8d0a802bddbb096e8e8d8085ff0f0000ffff010000ffff0db4f8d9e88a0000") + bs, _ = hex.DecodeString("1f8b080000096e8800ffec3dfb7bdb3692bfe7af40b4bdc4d933253b49bb7b8ead3bc74e5bf791e4b393ededf5ebdd0791908498241800b4ad75bd7ffbcd0cf81629c9b29d78dbfe9058245e338379e3c1dd87876f0edefdfded2b36b551387cb0fbd0f31e0c06ec4025332d2753cb360e9eb0a75bdbcfd977fc548dd84ba5278cc701d488ad96a3d42a6dd8861182d9a960076f5ebf3b3e7af9fedd9be3133696a178d2c7eef6c3905177866961843e13419fbd3782a93134938619956a5f305f0582c1e3449d091d8b808d663018fbf1e89d67ec2c14d857287d111b1c8e5be643e948b0b14a012419130c3f1c1dbc7a7df28a86ef3ff03cc00a9163218f277b3d11f7583cf17892ecf5cc2cf661f87842af7cc44885a1d07bbd93bce4c0eab0c7fc901bb3d7c34aa1e2a73dec52f060f880b1dd4858cefc29d746d8bd5e6ac7de5f7b65c1d4dac4131f5379b6d7fb6feffdbe77a0a2845b390a05740b238a185a1dbdda13c14454dac53c127bbd3329ce13a56da5eab90cec742f106740068f1e36017169250f3de3f350ec6df7b7e63a0a84f1b54cac5471a5afb96a3cb553a5e76a84323e85890b8162506cfdd432e9634f532dc67bbd313fc3c77e02841c3ec00656da500c0b22b25fd9e525cef36b98dfd730d2c693ababdd81ab550ce03a1b29658dd53c19f8c60c8aa77e24e33ebce96570203798a910d64148cfccce1240c28a0b8b8da984b1910a66ec927e3296f0200080bc91b256453bec2f5bc9c58bac6c0c487b631ec970b6c37adf8af04c58e973f65aa4a2b7c98a179b6c5f03b53799e1b1f1809be5d87571f580fea4e1bf4fbf2c468cb89ec8d8b32ad961dbfd2f4554abdb4760bd48c5ca241c04e0b20d961f451caa4df6a38ab90f7f41f28c0286dc64bd03101b293480780e1016dd3486e0c06cc8dd01ca4d30b4c4ba560f9175e64b915edda5639890eed2a2e76061cfada545cf41418591d281d08e76b18a1b78856aa21a64de615b2fea335d7943dd785f96139e282351227690a74026cf9a034863bd5879a31494822d86a2d7c4701e329c03add110100bd3282eda04d2242187b99431f0baf046a1f24f733880b59d24033fe6fc51300ea94d609db260c4fdd389468d87a3280de04f461b4f9f7db5c99e3edfc2ffb69fbca85350f340a666873dab209fd3673bb960cfcbf739219fc2eba7f9ebab265ec066713fe0a0381a7c1e8a3140bb55327a0dbdedadf235713e0fe504e98f48be584eab9cc0b9229ea72fce057b2823d49a3cb62d920036a268763e9556782433d8f41c144d4d1b9c0b47fde75b5bad3d05738ac5e1ff14d4ca322882be8978187a352a76029435feaf480492b38d885f6434fdcb577f492e9e141d64720556360135012c3d746faad25754666cf067e07db0b5967156e85a0696cca2da16fd497fa7a8cbfe0c44d1a0654660585932054a1b102a0648a873865335d2829f1ab4c3a182e65a245a419b10587060c04282413f97765aedd1f193e9b33f0f8ad70d226820533e2b57053bee0e4804c1120f9c297eb04b1892fd012f86bd5309888a66e800e0bb989f15769c9f6189fb83ea25ff1988314f4330b7e00708aa27279c8ca6b325bb812c3a411bc901699d95a11502a9a88fe18d34384bbde1ae8c267909eaad1e33da4733e6e193b7fdf4af643d99b3eebd674fc1b612efb9df83212b8ce92eb14dded95406a040bd0bb076f5f19d6149ad80d17f056241d1b0d50a5377c3ac468e491a56f0c8a953f949025b204e161c5d2809063c4d26a06ec4513c56fd589c57e84315c163b42ace4cb57b28fcab918df301f027fc2b67c47907ce510317f0b41868e30990b78af9249c2553744858f1cbf3a7e24cc3df34e9e5a83e1291495ebc779d201f5f5e56410783208c450239202bb80e4259c73c1b38d02a09d4795c479867a0ffa9d7ac079c3799a01f882a207ba8f6f22a90f6513c0228774705d7811459c46104ff786da072ce8a012211a7356808de610153959ca0c08e45a25622e734081a74dc0f0286cdc1a22a3d43d0ea645a3634f2e44a4303fae7c291a0313c76d13970411a792603e4c96b80072ad79e38956856e3363569c09737bf2661e4ea74f9a831786a0e3b05cd7c7478275431d3d42293ad049d1a8fe74073cdaf4911306c966bbb22ab8ca1fab431f0b1ebe14e68c2472a5d0d36b059da7a224aecacc9cad8471b74bb83346cd74265c9ee00c0a68868008ad419be0e9be5eaa3a5fc5a6a63c1e49d6f321587330641de79cce498c5c217c6703d7bc132aab173ae63740d32ab9a759fa9fe87d0ff584e8e62345685ba838e4b13590326f4a2006c5fd58e54ca81242264f4bf970d5bd7accdba48d4806aed4e9fd54b28d4ec0d732c5e0b1188003c8767c38262dddda25fd1d4a2c9f0dd14f315886faac94760536ed84808f08ef919e62e204c8e1578563e8416604d827e69c4599422c93370d089ca2a510603cc66bdebfeee20a9b3c252a0319c6ad8de15ac2f9a5c13552d2f4b20fac9ecfdddc861d3becef14908b2329617bd96b9aabfa83d561eb29f731c2f2669087e203068839f6b9c9bf7870d4b13476120db40e7117dfe27650fad5cfed52226f7309c4b7a4c0648d86c0429cc6276cf44e3f2129b1c60c106feea1f1d825f4773058f825bd7277ae5f8f707001b67ad93dc0d51aad5839a1d92d5a8467e4fcdad013a843c31b9b793801f8309a63fd5f0cd5d257c09887d21e3405c0032f3dd37bced654e0a7354ea1f4a2d7c9abe5f19e5b2de723bbdba5ad67d2903ace270bb3e4f2cb76995f47557bacaac7c8e9aa881ea33d164f16c7272d6a852a53e1139815941e9b9d156d16ccd8acd78b27d2e5c4c5b6dc21a099eec19024c99604cd2d20bf6e362b8b6322cd55d4558385dae892c6f3a661581463f093a593042500baeb21828e3aca3434a69069dc00fbaa1bf39622ec8f65422e206825f53c94d302b64e64608e63e42045e6af87346b25ffa323ee3a1ece28795f1cffc03cfc8499300afb456ebe2df0eece79c685f4510d435c31ff42ba610dfca7f90bb7083d96ed1669f0bd549a846cd80e61b78c7c35aa4791b133ba16ebf96a13060187878ce67e6751a8d84beba62d2c2d09baca3d1cb99a5462319731491979f8f60531535e9f583f2ef805c21f67a4d6a519b7b442c3f5469e061041a2adecc66bc01d75d8dc95d5f8b62ddf579871e8c212271141db2ad7a98adce315c2944b24885cdcf4bd9c9cad3824d5a6665ce53a9a040945d86c5de1ea031dccac7dd622fbbdca2a2dfcfc60ab8bed060801fb981e8e9a682d359bf4145a2df3178dc6f20fcee0dff2ecc3262353a78d8e8e1b5babfd44ec15409ff543465ee68122b2dd85ba123690c583173f7347763e290667db2d73ab9cf94a725188f8773de835b9af949dae99af6817a36943e4692aced36404957000045b48ed51256cd454cf4ba3d7e6b0f5f78470e24d1320295d8b6fa8049e112e115b220e09afb326c3aa7d04b87b6ed042ae0f144e85eabf2608f1eb1552d0beeb1d132102d9665b910276d5633eb901d4c1144d38a58bb78b485bd6b247baaa91acc9c57923434fbb796a589a1f3d5d233c50256251f83ad0fc6134cc9fc9c2fc86d3cf9e5fe24651c7a7936069f3c847395bc76d507057723ced71a339c4935dc300f52c2b324030204fe2309329f0499cbc4eeffc8de5b19de2c7a34337099a23efcb91f0ebee5e6d434303d78fbfef630f593148cbe0f12d370b7e13186285af37067fbeaeadfee698c7398bd66c7dc8a35290183c4c247529a9f1f5b6579f818b324a304792012c0e6fed5153e6d74d43d8a29f878878f55b679f2b989d66ae0de2777423095dad52906a1e9ed932cf72532ce0690f7e35881a72ede7ccf1eeeb114f4d758c69d2a6b65e2e256baa9d2cd1c5d3e1a3bc1bdc1eb65eb963aedf9ba2eeeb7a28626f5717db3b708fbdef00ded425b3532981ba4e1ad3dec18643c5e6594cfa94d9b99f3bf096dd6d7a167aef57d0e14d68d0ac89bcbdd9d9b0606377697575a4124686905b174d3ba3c5665a742238ee63e2d23b678ac375d3f6cee346ae9a3d5bf5d7731117bc8d2ef5567f98e16139b24fa6331b156b84ada50c6cdb4e17e100072eb25ae1c03600fb5e9ff2d2e347570faefc24dce10eea306756b8a4b7dbf6693dfb3d3dca4c52abe73b3cd9db8d0f7ccbf429ca1871bcbd71f8ed66de425cb9f2e3739a86f39c357b44dc1b4efab1458e6366ef543114fecd4e572efdf06cbd7ca4a5fdc686365d5ed04c4d1e5ace08fd34c07162e2fe16dff9d8c044830f88262a7f7ed4e14ed403c7775b5931f6b000f6daca5888370e65c566c44a42689b8fb4d951567af7d7f6595a969a7a36384d5765537fd8f37df7fdaed94359e2e361717476ef0f54b3a69b9da499c7ccb69f608408a203baa5975951fcc33fadc519cae032cf5332b15d5935521a72ed3377876776700281a5fa5da887e715eb81f0b3be80d4fd2044f78b101fb5ae9349adfb4bdd21006c698483b4d477d70ba063e0fa3e9a0186aa0054c98c1d5861fe8480a3b762fd61c6d01423ef43f517a3608949fa2f3971d7d3aac3ede0d92d29814517c99b69d91b8851160b2dc11f3839653228bf7cfd36212c4824a9f3a4d842b6ce038e4ec5c4454ae0ec96f21ffaeea9807a2856fa9d00b240fd5a45583bb0ad969ec0e2deeeaa06606c9e3219de5c3fff3cc534dc0a7cfebcddac2eea56a475c406144dc50df7057ebe6a0f0c09c6dabe999e9f30e35d386db9c99d84dea4395dbea8d003d88fbe94782a143bfc960ba306141d70a709668052e4b44c710d90c38821d016d354c1d2b3dc67eadf363702c67d0f7a3a90843599c0f7590272b6bcb9ada745bc969ff3b1d0668e5275d54b80fdc24e3b1ba035e6a9e0da8b5c62d89390dbe25906ad995db66a3ea702fa1f2d5157b4baa964d5518dcf6fce707a03a663f3f5e751fe63e4f94dffef457cf85d5453aa70ede97110a2b3e89fa284ff0c0f0a440fab735dd47871d132d838f6b980bd79917dece6cdfc1cc36ce23d61ad3d68c2370e7ac1c4bdf1d9e7a1405dc4c5f5453aae5d68827b72bf7952ae720d40cff43b7bc7119073de2fa2e12e8f2329ab93dfe4da7198f76e7db21a14a3197aea5bbbe8041250f7c936814730841dde9ef8f7a90f7da1b5c03a1962864a5835d45c441a973f00271a35dd6e94ac7b82275d6dc607c102a7445e7cf485f4f3a882330a6eff4aef280ffde890a9e3a98aaf3bdde430411b4c8ab0b8854e7ac762e45e549e52a1337ba5aa927cc5cb474b5863c8c958eb22b0ff0672fbb0d0805f115cdc982751e6c90ef8ca24896de5e3e0655ea91b7fc18ef70c83beac79483eb7f911da5c0fd6a2da581d47636bf6cb31bf29108f1160a071c08dbd0e9924370e7b16cae858c133c86992dbeced1b5441405375f17a90831a197dd0cd5d00fbdca7d43843b6dbc03b94f352e4a216059ca112f2dfa984adc6449587b38880c409208bcd6a5953cf5d3c1090bf416a54ce76068d15c345692f708ee4de29455db224e75db6bcb84b9c9fcf5d7b6c94c34c10e70e191d9d8cd17fae8a41f1939e76df778f588c1872c3bc40e6acb89b372c5b40e49ddf5d909e26de85e32b422f8133a5574df1528890d495b748327fdb634668e5a87140f7f9a8243e0ae77810802cfe6e2a09bec548804618d240c4bb791ed8a6848d799c52495f0e4cef90266d01e66bf06ba9174ef84ea77aff175bc5f32192476fd82e51688587d4a6012f0bc32403b0a797cda0dd74ae3134bbc26465f0e02b102c09a83122861e8f074a8d4a9139a3e3bb27866330d032228fbf2295dbbc67de4225c0a84f9f1715d91e60dcf6f80df08658e2f62da9a65365de867e6186624a851c6321db8373286edf9e176e5b85097f148649a0c1d9fc5ba2c0901f4299deadbeb7daba27cd34ca6beb0ab36e5b592b6e26ef366bb566ad51427eeae80d858b08e48f34c1fe742ec87a971f383cb7dcd73ecb74540eed65d3183b49fffbc06158319904dfa4416708b70552368d3e378aac5b97848ea72d075e95dc07a62f535e9fe8a74272ed2726644026260417c5a6e002aad824c76305b99efcd2dc0c714c9c2861979f286a0b913a1c967e0a9559808f219e514810b67ee4a479177bfc28cef0eb0af4fe0ff16cb4995d355fc4c6457acd427bfa2aebe28cea85e3f217f02fdb7a5e4ef9bbf5e42d4ee77a006cf2de38908c7bd259053ead15d1d81b72354490e5200e1fccaf7da80754d9bdb780fa98b9b471d787e6379d481b57e0b5147f530dbadc41e5d1dde5e04822753964620d5e5cfb6f2b665d0b67aab443225407dfcd988645a4a3b22191abb62c05c75bca0a6761d41ab05a3b6595c5350098d52dda6658b36a6a1d8e6a637bf59a223e85962c78eddd9a14a8493c6f2638a9bbc40b6a07ac2d1078bf77a83fffd997bffd8f7fe67cbfb0feffffabf5c6e6f7ef5fcea8b41a7e1233c570b4fa86af3745f63268a10a5a5ac0c514ef05210a089cb4d810e1bbb050456dc5332ebb31f33a71edf1b9802f4ebdd9d7cced9a1cd889deef32ac03a17da9192f40f79c9baca1d4568e16addc270d588a18b95db0059356e581d928c69ae0b48116cb9bb5daad3b8f1d5f3325a20972704efe4497bc0b099470b1420e02ce3bf5d4c680e81757707f4abd65f1cce16e03de704b997eddb646ea692f0429b454ac9955f432d61839a62c217d7514dd4415d39fd737058aaa75c01b97a6baaa0e2929252137d02bde288d9a5595c69a95bf019bde7ba3ac993027441027af400b2d07df693048d02ccec6b41bebd1c3369cbc058a002ef3314022b81aa9558d831ea3f0b3675b99514f7cd72930b075ee28dbacd552e0e35515f982ba2d76b8bb2437da95aa930e39c3c2748add555cbea22b6ca9eaeb53c8caf5677305a31a8f68847e447eaa28b273ba58f4a9d043aa1297aea109cf2d280eae566eefe83f6b117887ebb46eb1237772a193375898688ce472e1f6b15212be3f96116e1cdac2aaea4fa4035e3b57acd0a79e2cde5dc2889749e898fc1f37985d0199bc7a799ad9e8f4f172072ef27b37615019bbf51e1134c28e606b2e1d8485a37bf59fe959d632a15537a686f51fb6413997d0c22665fefbfa3ef36386dd4923d5800d57566a7b19060d0f14340f10e044a6175a58f9a03d566a47a5a66c951993a24b732f906a26294211a90363de73b9e7b7327b1db8fa9dc262f9c1034ee3a4b04086590ae89701ffca8287a4cc85e63a2db5ffe46b4b191b8db01e528dbfe4d2b108c04ab7cf3c9f4322690029c39dc608b39dc28c1352c07085df4ce3307a26f6cfe3af73bdc9d744ee661bad1ff0bd0f1760920fab64bb9fff0963c64744596d2731557da35fc5e88a4cb99aed658d19d2e9bf486f87f3ea50b954dd59dae74e03609559e1738ce2e9a59cc73ae93c2578b2484ecdb771d9b5769d8e64557cb1bcb88eea43d1873e0b29223815571596e13ad90fb00d03a1e6c75d8853eec1c0f34812b002b43d3ac1023cbdb089ce76185a95b0ee6df55ea60a2554c6e196e7403e7281639cc6bfada6b38dbcd05807205bc6b49b6d6dffcfa6c695cda5669d124d5f26cb83594a22374136525089164b62682dccf111d078db3e40e065e33d2913e6e10042f13bf257326685e89b011b7fe14c23488c9c259d11ad344ae87079d14f9d40b20d9b5fff53c61857dfe580041a371c3058f95bfad70970b1ef96708baf69c66c5f76eb5a36d09a2fca4c22daf3d7cca3c40356ac8bfba03caaa98884ecf34bfb2c255ec2373e2eaf463cc913d462b3a57e2eccee3853eac73532e2ff3c678d72ddd78933dd367e4303bb4c0e3cd1c16e4a746478b5c94b22a3e67b70f64ce8a8d9237893bca59f6f7cb62dfa4d3e3ed8add5aa939522a5c4cb12eaf7f8e668be8d21d1bac81fa3a91c0a70ab43ad87d92ca93bbe3f8d6b204403b573af81795876fde1ffd1e65e13a68af19112f62359ec853315b4284796c378a6fc52c39806707675bde5fbdede71e8ce4c15066f0ecd997bde17bc3277468edc9624e5b6d5f3b32f03c2d514a7a5eaf639b6836c0f53f1f52f33585dd7f7bf4bd986db8e1c11bfa46c442f336d766e95cad9ddbffdcfb8daef529a97f5987fabaae29f138855eda76b8a7e9673f27b3f6a9a87dfa46e27eace259a45293617b4cd8022ffce7cd9cd8ea8126b79bd6d7b304736c6995aaf89d655c0d09b80c67b49db61af86aee9fd2864298f224e41685c46c525b66e43fb2ddb23c498aa40674312e1633350e47d79e819863c72eb51fe029cb623126d12a22b868132e2582b369e2132e2b87adea47ad1ae8f1c9448b092d8ae2b6520cd0fc6c1d291d819c41b8cdcf0047ba3908b765f3c631610473ee30f7824254bd5db05d4becca948623d95b2df013cff50f2b550ad81ecc4b8a4bc7d973956f5a642e011a545244e500e5ad09eefd214ed4afec837157b0e5df8084f69f402f56efddcb3f9c066f12fbfe783d9d483777afab12cbfbf98a78ddc7bbf85604a65527e22de0373e1245df2873ab619d27ceb1cabd528a2b1f13ae7c6201341150edc6717ce7b561d93561cd4bc41aad753538196358929317252a96f096833ce2cb7d3a26be319ebbffaebc8da7fcb6ef0a3c747989bd1ee15ea49ff92f1862542e502ec67365f3d7f8e0a8445474a6c7b489df4529ee375e70c441efd3ebf6d6d57ddfeeae9279f033b532ee9f802da0eb6768047aaaddf74b8037c7695e30347777d0eff1d0237de9b143b4e94b92ff9a929d7dc0f2460ecd747b589eca2e6c57e5d2d0dc6241c54a2b3da82c4080db70a0929963e8473efc7cc19e6e6d3f07be197ec74fd588bd547a825fd22db6f98d15fa6934e6081a43442e61929546f332dca91bfecebce0b27be5d35af886779bec730d4cf7528a11de7ddbf8ea2796c78106e37f98c6531eb556d0769a6ab67f81298be3573fb1137f1ac9c0b6d57d2962762283a96aede9257eaf1a80793b95a14c4ce31e96c617483b277535b4bf039564703b216ea1c49b65e6c1f90e34353b94226a278c8312a273c017ef2bd4a6add6f10c64fc240d4379c65b47f99b105602203ce6b188af8373e3718e014b2696b11fa6b40fa2c667468ded391d56d48c82015ac5c433916abcb38878cd9cc24485e0c9f481a3076e11f21bc5de6a35d13c8a70a01fa034455f079dd94dd626194f59d66e3fb55360fa7e1bade69ce991b4a3d43f1596c63ee51a3451accc0054e4052899c68b45a31ff258020303102a81e041ac0800ee36e84f949a84826efe490626863065e64d1490a2f8dd3df236e17de22a5e17fdca95436e0a0694eaf4b93f055d58fe1e843aed06e119901d116047b17fed713fa41fd20166514219492079fdb97bd0e7ec00262696b8eff4071b5c7b5c089202ab116d7126c26004c46ebc5930db9b20911a0433e03a65efb4c45f31bf2e086712e2a378f0916bc0bbf2d031f03afc8d721372fdc164b2b5ef9ebf3be9466ecb23eaba29dd5c6d4e112f6147e0e580bbca13c2ae377c993f2fe05e37d83b08a9418fb68dd654615db798fcd6dd2efc697c8805acbb7f239b59dc30d1ffe0965ca974d8acf8e1632af4cc7bdadfea3f5b5ebb98c3c10733282774693b503f8d0a802bddbd096e8e8d600aff1f0000ffff010000ffffb2006b74ae8b0000") gr, _ = gzip.NewReader(bytes.NewBuffer(bs)) bs, _ = ioutil.ReadAll(gr) Assets["index.html"] = bs diff --git a/cmd/syncthing/gui.go b/cmd/syncthing/gui.go index fd26ddb79..0f510928f 100644 --- a/cmd/syncthing/gui.go +++ b/cmd/syncthing/gui.go @@ -102,6 +102,7 @@ func startGUI(cfg config.GUIConfiguration, assetDir string, m *model.Model) erro getRestMux.HandleFunc("/rest/discovery", restGetDiscovery) getRestMux.HandleFunc("/rest/report", withModel(m, restGetReport)) getRestMux.HandleFunc("/rest/events", restGetEvents) + getRestMux.HandleFunc("/rest/upgrade", restGetUpgrade) // The POST handlers postRestMux := http.NewServeMux() @@ -113,6 +114,7 @@ func startGUI(cfg config.GUIConfiguration, assetDir string, m *model.Model) erro postRestMux.HandleFunc("/rest/error/clear", restClearErrors) postRestMux.HandleFunc("/rest/discovery/hint", restPostDiscoveryHint) postRestMux.HandleFunc("/rest/model/override", withModel(m, restPostOverride)) + postRestMux.HandleFunc("/rest/upgrade", restPostUpgrade) // A handler that splits requests between the two above and disables // caching @@ -427,6 +429,32 @@ func restGetEvents(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(eventSub.Since(since, nil)) } +func restGetUpgrade(w http.ResponseWriter, r *http.Request) { + rel, err := currentRelease() + if err != nil { + http.Error(w, err.Error(), 500) + return + } + res := make(map[string]interface{}) + res["running"] = Version + res["latest"] = rel.Tag + res["newer"] = compareVersions(rel.Tag, Version) == 1 + + w.Header().Set("Content-Type", "application/json; charset=utf-8") + json.NewEncoder(w).Encode(res) +} + +func restPostUpgrade(w http.ResponseWriter, r *http.Request) { + err := upgrade() + if err != nil { + l.Warnln(err) + http.Error(w, err.Error(), 500) + return + } + + restPostRestart(w, r) +} + func getQR(w http.ResponseWriter, r *http.Request) { r.ParseForm() text := r.FormValue("text") diff --git a/cmd/syncthing/upgrade_common.go b/cmd/syncthing/upgrade_common.go new file mode 100644 index 000000000..4cd3523e3 --- /dev/null +++ b/cmd/syncthing/upgrade_common.go @@ -0,0 +1,33 @@ +package main + +import ( + "bytes" + "strconv" + "strings" +) + +type githubRelease struct { + Tag string `json:"tag_name"` + Prelease bool `json:"prerelease"` + Assets []githubAsset `json:"assets"` +} + +type githubAsset struct { + URL string `json:"url"` + Name string `json:"name"` +} + +func compareVersions(a, b string) int { + return bytes.Compare(versionParts(a), versionParts(b)) +} + +func versionParts(v string) []byte { + parts := strings.Split(v, "-") + fields := strings.Split(parts[0], ".") + res := make([]byte, len(fields)) + for i, s := range fields { + v, _ := strconv.Atoi(s) + res[i] = byte(v) + } + return res +} diff --git a/cmd/syncthing/upgrade_supported.go b/cmd/syncthing/upgrade_supported.go index bf28ff59b..63a84f972 100644 --- a/cmd/syncthing/upgrade_supported.go +++ b/cmd/syncthing/upgrade_supported.go @@ -2,7 +2,7 @@ // All rights reserved. Use of this source code is governed by an MIT-style // license that can be found in the LICENSE file. -// +build !solaris,!windows +// +build !solaris,!windows,!noupgrade package main @@ -19,24 +19,11 @@ import ( "path" "path/filepath" "runtime" - "strconv" "strings" - "bytes" "bitbucket.org/kardianos/osext" ) -type githubRelease struct { - Tag string `json:"tag_name"` - Prelease bool `json:"prerelease"` - Assets []githubAsset `json:"assets"` -} - -type githubAsset struct { - URL string `json:"url"` - Name string `json:"name"` -} - var GoArchExtra string // "", "v5", "v6", "v7" func upgrade() error { @@ -49,20 +36,11 @@ func upgrade() error { return err } - resp, err := http.Get("https://api.github.com/repos/calmh/syncthing/releases?per_page=1") + rel, err := currentRelease() if err != nil { return err } - var rels []githubRelease - json.NewDecoder(resp.Body).Decode(&rels) - resp.Body.Close() - - if len(rels) != 1 { - return fmt.Errorf("Unexpected number of releases: %d", len(rels)) - } - rel := rels[0] - switch compareVersions(rel.Tag, Version) { case -1: l.Okf("Current version %s is newer than latest release %s. Not upgrading.", Version, rel.Tag) @@ -102,8 +80,23 @@ func upgrade() error { } } - l.Warnf("Found no asset for %q", expectedRelease) - return nil + return fmt.Errorf("Found no asset for %q", expectedRelease) +} + +func currentRelease() (githubRelease, error) { + resp, err := http.Get("https://api.github.com/repos/calmh/syncthing/releases?per_page=1") + if err != nil { + return githubRelease{}, err + } + + var rels []githubRelease + json.NewDecoder(resp.Body).Decode(&rels) + resp.Body.Close() + + if len(rels) != 1 { + return githubRelease{}, fmt.Errorf("Unexpected number of releases: %d", len(rels)) + } + return rels[0], nil } func readTarGZ(url string, dir string) (string, error) { @@ -159,18 +152,3 @@ func readTarGZ(url string, dir string) (string, error) { return "", fmt.Errorf("No upgrade found") } - -func compareVersions(a, b string) int { - return bytes.Compare(versionParts(a), versionParts(b)) -} - -func versionParts(v string) []byte { - parts := strings.Split(v, "-") - fields := strings.Split(parts[0], ".") - res := make([]byte, len(fields)) - for i, s := range fields { - v, _ := strconv.Atoi(s) - res[i] = byte(v) - } - return res -} diff --git a/cmd/syncthing/upgrade_unsupp.go b/cmd/syncthing/upgrade_unsupp.go index 777c5f1de..c015feb37 100644 --- a/cmd/syncthing/upgrade_unsupp.go +++ b/cmd/syncthing/upgrade_unsupp.go @@ -1,9 +1,15 @@ -// +build windows solaris +// +build windows solaris noupgrade package main import "errors" +var errUpgradeUnsupported = errors.New("Automatic upgrade not supported") + func upgrade() error { - return errors.New("Upgrade currently unsupported on Windows") + return errUpgradeUnsupported +} + +func currentRelease() (githubRelease, error) { + return githubRelease{}, errUpgradeUnsupported } diff --git a/gui/app.js b/gui/app.js index 0996f5d58..75ed53397 100644 --- a/gui/app.js +++ b/gui/app.js @@ -32,6 +32,7 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) { $scope.repos = {}; $scope.reportData = {}; $scope.reportPreview = false; + $scope.upgradeInfo = {}; $scope.needActions = { 'rm': 'Del', @@ -336,6 +337,8 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) { $scope.restart = function () { restarting = true; + $scope.restartingHeader = "Restarting" + $scope.restartingBody = "Syncthing is restarting." $('#restarting').modal({backdrop: 'static', keyboard: false}); $http.post(urlbase + '/restart'); $scope.configInSync = true; @@ -356,6 +359,18 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) { } }; + $scope.upgrade = function () { + $scope.restartingHeader = "Upgrading" + $scope.restartingBody = "Syncthing is upgrading." + $('#restarting').modal({backdrop: 'static', keyboard: false}); + $http.post(urlbase + '/upgrade').success(function () { + restarting = true; + $scope.restartingBody = "Syncthing is restarting into the new version." + }).error(function () { + $('#restarting').modal('hide'); + }); + }; + $scope.shutdown = function () { restarting = true; $http.post(urlbase + '/shutdown').success(function () { @@ -606,6 +621,12 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) { $http.get(urlbase + '/report').success(function (data) { $scope.reportData = data; }); + + $http.get(urlbase + '/upgrade').success(function (data) { + $scope.upgradeInfo = data; + }).error(function () { + $scope.upgradeInfo = {}; + }); }; $scope.acceptUR = function () { diff --git a/gui/index.html b/gui/index.html index 526809ea0..bd5e3e2b9 100644 --- a/gui/index.html +++ b/gui/index.html @@ -96,6 +96,9 @@
Syncthing