From 6c13df1affa425ae81e07d954af6666b4da7b895 Mon Sep 17 00:00:00 2001 From: robert Date: Thu, 20 Apr 2023 09:59:27 +0300 Subject: [PATCH] MQTT: support for properties feature added --- examples/device-dashboard/net.c | 15 +- examples/device-dashboard/packed_fs.c | 2005 ++++++++------------ examples/mqtt-client-aws-iot/main.c | 13 +- examples/mqtt-client/main.c | 21 +- examples/mqtt-over-ws-client/main.c | 19 +- examples/mqtt-server/main.c | 7 +- examples/uart-bridge/net.c | 16 +- examples/zephyr/mqtt-aws-client/src/main.c | 13 +- mongoose.c | 342 +++- mongoose.h | 103 +- src/mqtt.c | 340 +++- src/mqtt.h | 103 +- test/unit_test.c | 84 +- 13 files changed, 1740 insertions(+), 1341 deletions(-) diff --git a/examples/device-dashboard/net.c b/examples/device-dashboard/net.c index c2b44c70..7a9a4fb2 100644 --- a/examples/device-dashboard/net.c +++ b/examples/device-dashboard/net.c @@ -132,7 +132,12 @@ static void mqtt_fn(struct mg_connection *c, int ev, void *ev_data, void *fnd) { } else if (ev == MG_EV_MQTT_OPEN) { s_connected = true; c->is_hexdumping = 1; - mg_mqtt_sub(s_mqtt, mg_str(s_config.sub), 2); + struct mg_mqtt_opts sub_opts; + memset(&sub_opts, 0, sizeof(sub_opts)); + sub_opts.topic = mg_str(s_config.sub); + sub_opts.qos = 2; + + mg_mqtt_sub(s_mqtt, &sub_opts); send_notification(c->mgr, "{%m:%m,%m:null}", mg_print_esc, 0, "name", mg_print_esc, 0, "config", mg_print_esc, 0, "data"); MG_INFO(("MQTT connected, server %s", MQTT_SERVER)); @@ -249,7 +254,13 @@ void device_dashboard_fn(struct mg_connection *c, int ev, void *ev_data, char buf[256]; if (s_connected && mg_http_get_var(&hm->body, "message", buf, sizeof(buf)) > 0) { - mg_mqtt_pub(s_mqtt, mg_str(s_config.pub), mg_str(buf), 1, false); + struct mg_mqtt_opts pub_opts; + memset(&pub_opts, 0, sizeof(pub_opts)); + pub_opts.topic = mg_str(s_config.pub); + pub_opts.message = mg_str(buf); + pub_opts.qos = 2, pub_opts.retain = false; + + mg_mqtt_pub(s_mqtt, &pub_opts); } mg_http_reply(c, 200, "", "ok\n"); } else if (mg_http_match_uri(hm, "/api/watch")) { diff --git a/examples/device-dashboard/packed_fs.c b/examples/device-dashboard/packed_fs.c index a973594e..a1f59d85 100644 --- a/examples/device-dashboard/packed_fs.c +++ b/examples/device-dashboard/packed_fs.c @@ -3,7 +3,333 @@ #include static const unsigned char v1[] = { - 31, 139, 8, 8, 255, 98, 56, 100, 0, 3, 105, 110, // .....b8d..in + 31, 139, 8, 8, 35, 203, 64, 100, 0, 3, 117, 115, // ....#.@d..us + 101, 114, 46, 112, 110, 103, 0, 1, 16, 15, 239, 240, // er.png...... + 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, // .PNG........ + 73, 72, 68, 82, 0, 0, 0, 128, 0, 0, 0, 128, // IHDR........ + 8, 6, 0, 0, 0, 195, 62, 97, 203, 0, 0, 0, // ......>a.... + 4, 115, 66, 73, 84, 8, 8, 8, 8, 124, 8, 100, // .sBIT....|.d + 136, 0, 0, 0, 9, 112, 72, 89, 115, 0, 0, 30, // .....pHYs... + 140, 0, 0, 30, 140, 1, 53, 120, 124, 169, 0, 0, // ......5x|... + 0, 25, 116, 69, 88, 116, 83, 111, 102, 116, 119, 97, // ..tEXtSoftwa + 114, 101, 0, 119, 119, 119, 46, 105, 110, 107, 115, 99, // re.www.inksc + 97, 112, 101, 46, 111, 114, 103, 155, 238, 60, 26, 0, // ape.org..<.. + 0, 14, 141, 73, 68, 65, 84, 120, 218, 237, 157, 125, // ...IDATx...} + 112, 20, 229, 29, 199, 97, 100, 232, 76, 117, 232, 63, // p....ad.Lu.? + 117, 250, 15, 163, 157, 206, 104, 197, 247, 42, 173, 56, // u.....h..*.8 + 19, 234, 12, 180, 82, 35, 32, 160, 132, 18, 94, 242, // ....R# ...^. + 102, 18, 18, 67, 184, 75, 46, 111, 151, 203, 93, 238, // f..C.K.o..]. + 37, 151, 219, 187, 203, 27, 16, 224, 242, 166, 80, 17, // %.........P. + 9, 18, 4, 5, 35, 90, 130, 32, 146, 8, 113, 152, // ....#Z. ..q. + 193, 106, 153, 90, 108, 173, 213, 42, 104, 71, 163, 130, // .j.Zl..*hG.. + 81, 242, 235, 243, 219, 238, 198, 75, 184, 75, 238, 246, // Q......K.K.. + 158, 221, 125, 118, 111, 255, 248, 206, 56, 2, 123, 191, // ..}vo...8.{. + 223, 247, 251, 185, 219, 231, 217, 125, 246, 217, 41, 0, // .......}..). + 48, 69, 111, 186, 169, 199, 55, 131, 104, 54, 209, 170, // 0Eo...7.h6.. + 187, 158, 171, 247, 154, 186, 108, 131, 142, 192, 250, 79, // ......l....O + 157, 174, 252, 175, 92, 213, 217, 195, 181, 165, 171, 175, // ............ + 88, 11, 211, 192, 156, 181, 24, 214, 175, 89, 8, 150, // X........Y.. + 156, 165, 96, 45, 88, 62, 82, 107, 74, 191, 226, 173, // ..`-X>RkJ... + 205, 251, 198, 209, 108, 254, 40, 191, 171, 186, 255, 190, // ....l.(..... + 110, 175, 31, 143, 33, 28, 107, 134, 30, 189, 210, 67, // n...!.k....C + 216, 215, 18, 45, 32, 226, 136, 250, 136, 62, 186, 127, // ...- ....>.. + 167, 19, 138, 55, 150, 130, 179, 58, 27, 74, 178, 150, // ...7...:.J.. + 192, 19, 171, 30, 150, 36, 132, 195, 97, 74, 135, 234, // .....$..aJ.. + 102, 51, 204, 221, 93, 7, 120, 108, 225, 51, 56, 225, // f3..].xl.38. + 51, 175, 53, 0, 80, 62, 240, 233, 68, 243, 136, 60, // 3.5.P>..D..< + 68, 39, 136, 134, 137, 48, 28, 88, 183, 195, 14, 238, // D'...0.X.... + 170, 76, 201, 129, 79, 164, 226, 53, 139, 192, 83, 147, // .L..O..5..S. + 3, 185, 157, 86, 184, 69, 248, 60, 225, 179, 177, 6, // ...V.E.<.... + 183, 80, 211, 116, 3, 0, 249, 130, 159, 67, 212, 74, // .P.t.....C.J + 244, 217, 77, 63, 4, 192, 107, 77, 187, 21, 156, 101, // ..M?..kM...e + 107, 100, 9, 62, 146, 170, 159, 72, 131, 188, 14, 43, // kd.>...H...+ + 140, 175, 67, 168, 13, 107, 156, 99, 0, 64, 39, 244, // ..C..k.c.@'. + 27, 137, 108, 68, 231, 34, 152, 13, 139, 119, 214, 130, // ..lD."...w.. + 205, 156, 174, 88, 240, 227, 229, 182, 102, 195, 31, 158, // ...X....f... + 113, 69, 2, 1, 132, 154, 177, 246, 27, 13, 0, 226, // qE.......... + 15, 30, 7, 93, 61, 68, 35, 145, 204, 253, 37, 81, // ...]=D#...%Q + 93, 171, 5, 76, 25, 139, 85, 11, 95, 212, 134, 140, // ]..L..U._... + 69, 96, 15, 20, 195, 173, 61, 222, 104, 32, 140, 8, // E`....=.h .. + 189, 204, 54, 0, 152, 60, 248, 185, 68, 189, 81, 140, // ..6..<..D.Q. + 228, 245, 235, 221, 110, 242, 205, 203, 82, 61, 248, 241, // ....n...R=.. + 114, 149, 103, 192, 125, 221, 117, 48, 81, 237, 66, 111, // r.g.}.u0Q.Bo + 115, 13, 0, 174, 14, 126, 62, 209, 177, 73, 204, 131, // s....~>..I.. + 212, 237, 118, 176, 228, 46, 99, 46, 252, 240, 177, 193, // ..v...c..... + 195, 207, 56, 39, 131, 0, 132, 94, 231, 39, 61, 0, // ..8'...^.'=. + 196, 132, 153, 68, 123, 98, 48, 12, 214, 144, 243, 61, // ...D{b0....= + 206, 215, 89, 13, 95, 148, 37, 103, 9, 100, 62, 105, // ..Y._.%g.d>i + 139, 5, 2, 16, 122, 159, 153, 116, 0, 144, 166, 167, // ....z..t.... + 17, 149, 18, 13, 197, 98, 212, 202, 167, 93, 80, 166, // .....b...]P. + 129, 240, 195, 199, 5, 171, 159, 178, 199, 10, 193, 144, // ............ + 224, 197, 180, 164, 0, 128, 52, 154, 66, 116, 54, 70, // ......4.Bt6F + 115, 224, 193, 63, 57, 160, 236, 113, 237, 132, 47, 10, // s..?9..q../. + 129, 77, 141, 62, 67, 136, 36, 244, 36, 69, 183, 0, // .M.>C.$.$E.. + 144, 230, 174, 33, 242, 70, 27, 217, 71, 210, 189, 187, // ...!.F..G... + 61, 80, 158, 247, 168, 230, 194, 15, 31, 19, 220, 223, // =P.......... + 237, 141, 7, 130, 17, 193, 163, 107, 116, 5, 128, 112, // .......kt..p + 174, 63, 30, 135, 17, 112, 51, 145, 199, 158, 163, 217, // .?...p3..... + 240, 69, 225, 5, 170, 219, 247, 214, 199, 3, 1, 8, // .E.......... + 94, 205, 212, 5, 0, 164, 145, 84, 162, 139, 113, 26, // ^......T..q. + 0, 174, 182, 74, 205, 135, 47, 202, 214, 104, 142, 23, // ...J../..h.. + 0, 16, 60, 75, 213, 44, 0, 164, 248, 169, 68, 190, // ..9.......;. + 241, 236, 166, 244, 68, 0, 0, 193, 219, 235, 153, 4, // ....D....... + 128, 20, 118, 67, 180, 187, 118, 177, 42, 135, 156, 39, // ..vC..v.*..' + 99, 49, 82, 41, 237, 110, 40, 158, 48, 252, 112, 253, // c1R).n(.0.p. + 253, 80, 16, 26, 202, 39, 63, 117, 165, 237, 112, 36, // .P...'?u..p$ + 10, 1, 122, 124, 3, 83, 0, 8, 223, 252, 115, 9, // ..z|.S....s. + 54, 6, 245, 206, 60, 102, 194, 223, 219, 108, 142, 57, // 6....^_.... + 57, 255, 84, 162, 77, 221, 189, 187, 142, 95, 130, 197, // 9.T.M...._.. + 66, 248, 47, 135, 42, 36, 133, 47, 234, 235, 55, 219, // B./.*$./..7. + 160, 203, 179, 46, 226, 177, 77, 153, 143, 192, 189, 207, // ......M..... + 121, 105, 64, 112, 138, 198, 152, 128, 198, 104, 255, 48, // yi@p.....h.0 + 133, 102, 32, 63, 134, 121, 127, 45, 249, 102, 53, 85, // .f ?.y.-.f5U + 102, 192, 166, 234, 108, 216, 230, 200, 133, 14, 87, 62, // f...l.....W> + 116, 56, 243, 193, 74, 233, 106, 97, 197, 227, 75, 225, // t8..J.ja..K. + 196, 211, 142, 132, 194, 15, 215, 159, 59, 172, 17, 161, // ........;... + 46, 219, 92, 70, 3, 0, 113, 96, 56, 93, 21, 0, // ...F..q`8].. + 132, 121, 254, 46, 74, 141, 128, 187, 174, 32, 98, 40, // .y..J.... b( + 229, 57, 75, 225, 217, 96, 49, 156, 127, 169, 97, 66, // .9K..`1...aB + 179, 255, 249, 114, 19, 255, 205, 109, 169, 202, 140, 107, // ...r...m...k + 100, 142, 170, 204, 91, 6, 135, 67, 149, 240, 245, 64, // d...[..C...@ + 136, 90, 248, 162, 206, 189, 192, 241, 199, 31, 187, 146, // .Z.......... + 40, 139, 22, 0, 226, 20, 113, 170, 26, 0, 248, 104, // (.....q....h + 53, 129, 43, 124, 106, 158, 72, 27, 99, 82, 77, 193, // 5.+|j.H.cRM. + 114, 24, 236, 118, 195, 229, 211, 237, 113, 155, 254, 85, // r..v....q..U + 127, 27, 188, 185, 203, 9, 237, 174, 60, 176, 100, 95, // ........<.d_ + 125, 65, 169, 120, 237, 34, 112, 21, 175, 132, 182, 218, // }A.x."p..... + 92, 56, 210, 105, 133, 111, 200, 79, 54, 237, 224, 195, // .8.i.o.O6... + 117, 241, 88, 43, 4, 44, 63, 172, 89, 44, 207, 93, // u.X+.,?.Y,.] + 70, 19, 0, 148, 79, 81, 0, 132, 203, 187, 35, 180, // F...OQ....#. + 26, 88, 209, 93, 55, 38, 160, 96, 217, 90, 248, 252, // .X.]7&.`.Z.. + 245, 86, 106, 1, 124, 121, 114, 27, 124, 248, 74, 19, // .Vj.|yr.|.J. + 188, 187, 159, 131, 143, 143, 108, 132, 111, 199, 205, 235, // ......l.o... + 149, 16, 66, 233, 43, 89, 61, 218, 35, 94, 237, 164, // ..B.+Y=.#^.. + 8, 192, 136, 212, 203, 198, 82, 111, 236, 92, 164, 73, // ......Ro...I + 176, 169, 203, 54, 106, 204, 83, 228, 84, 112, 233, 205, // ...6j.S.Tp.. + 118, 197, 3, 82, 66, 8, 181, 67, 252, 165, 11, 85, // v..RB..C...U + 209, 254, 21, 184, 40, 229, 6, 146, 148, 91, 186, 199, // ....(....[.. + 41, 23, 14, 190, 87, 91, 96, 179, 45, 7, 14, 110, // )...W[`.-..n + 41, 211, 101, 240, 225, 250, 79, 223, 70, 126, 76, 224, // ).e...O.F~L. + 224, 138, 104, 3, 32, 222, 69, 188, 70, 78, 0, 188, // ..h. .E.FN.. + 50, 20, 13, 93, 71, 55, 203, 126, 30, 102, 73, 239, // 2..]G7.~.fI. + 247, 54, 128, 215, 153, 39, 7, 0, 40, 175, 44, 0, // .6...'..(.,. + 8, 43, 121, 70, 228, 40, 250, 197, 227, 91, 146, 38, // .+yF.(...[.& + 124, 81, 7, 122, 155, 228, 2, 96, 36, 158, 149, 69, // |Q.z...`$..E + 241, 172, 225, 59, 43, 83, 193, 48, 240, 198, 182, 164, // ...;+S.0.... + 3, 224, 216, 137, 173, 114, 1, 32, 46, 47, 155, 70, // .....r. ./.F + 19, 128, 82, 25, 139, 133, 243, 73, 244, 243, 47, 106, // ..R....I../j + 128, 204, 76, 228, 244, 20, 51, 163, 2, 128, 48, 234, // ..L...3...0. + 31, 50, 0, 160, 171, 51, 253, 33, 185, 1, 24, 138, // .2...3.!.... + 101, 86, 16, 11, 0, 123, 100, 46, 20, 6, 79, 38, // eV...{d...O& + 223, 41, 224, 221, 1, 217, 1, 224, 159, 59, 72, 8, // .).......;H. + 0, 225, 137, 29, 217, 11, 125, 149, 156, 15, 147, 13, // ......}..... + 128, 83, 242, 159, 2, 68, 205, 79, 4, 128, 99, 74, // .S...D.O..cJ + 20, 185, 231, 88, 107, 242, 205, 2, 200, 204, 71, 33, // ...Xk.....G! + 0, 142, 73, 2, 64, 120, 80, 83, 145, 34, 219, 142, // ..I.@xPS.".. + 110, 78, 58, 0, 66, 125, 155, 148, 2, 0, 38, 122, // nN:.B}....&z + 32, 117, 34, 0, 122, 149, 42, 176, 246, 213, 150, 164, // u".z.*..... + 3, 0, 123, 86, 16, 128, 222, 184, 0, 16, 158, 207, // ..{V........ + 87, 172, 192, 180, 131, 13, 73, 7, 64, 94, 111, 163, // W.....I.@^o. + 146, 0, 64, 180, 253, 9, 162, 1, 208, 163, 100, 113, // ..@.......dq + 119, 236, 227, 224, 114, 146, 1, 176, 240, 197, 160, 210, // w...r....... + 0, 244, 196, 4, 128, 176, 45, 203, 136, 194, 197, 193, // ......-..... + 95, 7, 146, 231, 90, 192, 215, 131, 29, 112, 59, 129, // _...Z....p;. + 94, 97, 143, 71, 34, 109, 87, 19, 9, 0, 155, 210, // ^a.G"mW..... + 225, 163, 246, 38, 209, 76, 224, 228, 27, 219, 64, 13, // ...&.L....@. + 143, 49, 219, 88, 0, 56, 167, 70, 113, 206, 36, 26, // .1.X.8.Fq.$. + 8, 54, 31, 217, 164, 22, 0, 231, 38, 4, 64, 216, // .6......&.@. + 138, 77, 149, 226, 230, 29, 8, 36, 13, 0, 233, 135, // .M.....$.... + 26, 212, 2, 0, 198, 111, 97, 55, 30, 128, 86, 21, // .....oa7..V. + 11, 131, 191, 244, 135, 116, 31, 254, 87, 228, 252, 127, // .....t..W... + 155, 242, 231, 255, 112, 109, 137, 8, 128, 176, 196, 251, // ....pm...... + 51, 53, 1, 104, 33, 63, 141, 122, 7, 224, 117, 245, // 35.h!?.z..u. + 206, 255, 225, 155, 89, 78, 143, 4, 192, 60, 149, 11, // ....YN...<.. + 131, 69, 100, 106, 164, 119, 0, 188, 202, 94, 0, 138, // .Edj.w...^.. + 166, 121, 145, 0, 240, 48, 80, 24, 188, 175, 227, 91, // .y...0P....[ + 195, 151, 6, 59, 225, 190, 253, 126, 22, 0, 240, 68, // ...;...~...D + 2, 224, 4, 11, 0, 180, 246, 233, 247, 52, 112, 232, // .........4p. + 245, 45, 44, 132, 143, 58, 49, 6, 0, 97, 203, 245, // .-,..:1..a.. + 97, 22, 138, 75, 33, 223, 16, 252, 166, 232, 17, 128, // a..K!....... + 156, 151, 26, 89, 1, 96, 88, 220, 234, 94, 4, 96, // ...Y.`X..^.` + 1, 35, 133, 241, 218, 167, 195, 69, 162, 31, 158, 106, // .#.....E...j + 15, 223, 102, 158, 5, 45, 8, 7, 128, 99, 9, 128, // ..f..-...c.. + 37, 58, 28, 12, 110, 238, 219, 196, 82, 248, 40, 46, // %:..n...R.(. + 28, 128, 62, 198, 138, 131, 126, 29, 173, 20, 30, 34, // ..>...~...." + 115, 255, 148, 3, 126, 214, 0, 232, 11, 7, 224, 35, // s...~......# + 214, 0, 200, 239, 109, 210, 13, 0, 173, 236, 125, 251, // ....m.....}. + 249, 215, 223, 240, 0, 8, 47, 88, 98, 177, 64, 254, // ....../Xb.@. + 166, 137, 214, 195, 255, 148, 156, 251, 127, 245, 60, 7, // ..........<. + 140, 122, 60, 67, 241, 197, 31, 241, 8, 239, 153, 95, // .z../.. + 127, 180, 228, 66, 0, 118, 50, 94, 36, 84, 191, 210, // ...B.v2^$T.. + 172, 185, 240, 119, 189, 214, 202, 122, 248, 168, 157, 8, // ...w...z.... + 192, 65, 13, 20, 170, 169, 39, 136, 241, 182, 246, 29, // .A....'..... + 251, 56, 45, 0, 112, 112, 138, 28, 27, 62, 200, 161, // .8-.pp...>.. + 187, 200, 169, 64, 11, 235, 6, 191, 56, 221, 1, 15, // ...@....8... + 190, 16, 208, 66, 248, 252, 134, 18, 8, 192, 25, 141, // ...B........ + 20, 11, 191, 39, 198, 254, 247, 116, 7, 211, 0, 152, // ...'...t.... + 95, 110, 210, 74, 248, 168, 51, 8, 192, 121, 13, 21, // _n.J..3..y.. + 12, 235, 200, 192, 106, 152, 209, 240, 219, 143, 110, 214, // ....j.....n. + 82, 248, 168, 243, 8, 192, 5, 141, 21, 13, 86, 50, // R.........V2 + 40, 100, 237, 250, 64, 211, 145, 141, 90, 11, 31, 117, // (d..@...Z..u + 1, 1, 248, 86, 131, 133, 67, 110, 111, 35, 127, 141, // ...V..Cno#.. + 93, 237, 224, 191, 37, 194, 89, 138, 22, 61, 196, 236, // ]...%.Y..=.. + 53, 11, 0, 106, 217, 193, 32, 124, 114, 74, 189, 107, // 5..j.. |rJ.k + 4, 248, 128, 71, 97, 111, 147, 86, 195, 31, 5, 224, // ...Gao.V.... + 130, 134, 27, 128, 249, 100, 96, 120, 90, 133, 13, 38, // .....d`xZ..& + 240, 249, 126, 4, 80, 203, 222, 137, 167, 128, 243, 26, // ..~.P....... + 111, 130, 87, 1, 249, 38, 158, 83, 96, 154, 248, 55, // o.W..&.S`..7 + 242, 25, 26, 255, 214, 95, 53, 8, 60, 163, 147, 102, // ....._5.<..f + 248, 21, 55, 85, 228, 124, 252, 177, 12, 167, 5, 188, // ..7U.|...... + 28, 109, 123, 165, 5, 110, 217, 231, 211, 75, 248, 163, // .m{..n...K.. + 211, 192, 227, 58, 106, 136, 215, 156, 253, 126, 126, 23, // ...:j....~~. + 46, 90, 225, 191, 117, 50, 4, 115, 217, 91, 208, 65, // .Z..u2.s.[.A + 237, 66, 208, 65, 29, 54, 6, 11, 94, 160, 247, 168, // .B.A.6..^... + 217, 162, 23, 131, 122, 12, 127, 244, 82, 240, 78, 157, // ....z...R.N. + 54, 7, 255, 160, 240, 140, 1, 30, 67, 175, 254, 136, // 6.......C... + 55, 131, 92, 122, 109, 240, 109, 10, 207, 26, 190, 221, // 7..zm.m..... + 31, 210, 51, 0, 46, 230, 23, 132, 72, 213, 61, 207, // ..3.....H.=. + 115, 252, 141, 25, 26, 55, 119, 238, 121, 158, 211, 43, // s....7w.y..+ + 0, 171, 152, 94, 18, 150, 208, 43, 104, 40, 238, 55, // ...^...+h(.7 + 224, 102, 123, 89, 87, 194, 75, 194, 102, 232, 169, 169, // .f{YW.K.f... + 7, 14, 4, 248, 85, 184, 159, 83, 188, 107, 136, 199, // ....U..S.k.. + 194, 99, 226, 177, 117, 6, 192, 12, 213, 151, 133, 63, // .c..u......? + 176, 155, 131, 194, 173, 126, 176, 4, 57, 40, 243, 248, // .....~..9(.. + 160, 164, 218, 11, 69, 37, 30, 200, 90, 231, 130, 244, // ....E%..Z... + 28, 39, 172, 140, 162, 154, 234, 122, 248, 172, 191, 157, // .'.....z.... + 191, 28, 27, 46, 57, 239, 20, 14, 11, 151, 127, 195, // ....9....... + 133, 53, 96, 45, 209, 234, 196, 30, 176, 23, 236, 9, // .5`-........ + 123, 195, 30, 177, 87, 236, 25, 123, 87, 125, 89, 184, // {...W..{W}Y. + 210, 15, 134, 204, 218, 235, 131, 21, 219, 73, 224, 13, // .........I.. + 28, 20, 149, 214, 193, 242, 204, 90, 201, 178, 89, 235, // .......Z..Y. + 97, 104, 64, 189, 27, 66, 248, 217, 88, 67, 34, 61, // ah@..B..XC"= + 160, 7, 232, 5, 122, 130, 222, 168, 245, 96, 136, 236, // ....z....`.. + 143, 134, 205, 34, 66, 234, 243, 139, 221, 9, 25, 198, // ..."B....... + 10, 4, 52, 194, 31, 47, 244, 6, 61, 154, 165, 194, // ..4../..=... + 163, 97, 11, 228, 12, 190, 96, 27, 253, 224, 213, 132, // .a....`..... + 64, 142, 240, 199, 131, 128, 158, 201, 12, 194, 2, 217, // @........... + 31, 15, 95, 246, 180, 31, 10, 54, 120, 100, 51, 74, // .._....6xd3J + 13, 8, 228, 14, 63, 92, 232, 29, 122, 40, 251, 227, // ....?...z(.. + 225, 114, 108, 16, 177, 190, 213, 207, 15, 130, 148, 48, // .rl........0 + 74, 41, 8, 148, 12, 95, 20, 122, 136, 94, 202, 186, // J)..._.z.^.. + 65, 4, 205, 45, 98, 238, 121, 142, 140, 230, 93, 62, // A..-b.y...]> + 69, 77, 82, 2, 2, 53, 194, 15, 23, 122, 138, 222, // EMR..5...z.. + 202, 185, 69, 76, 194, 155, 68, 165, 224, 148, 206, 228, // ..EL..D..... + 81, 205, 36, 185, 32, 80, 59, 124, 81, 232, 109, 10, // Q.$. P;|Q.m. + 157, 169, 227, 60, 234, 219, 196, 205, 222, 227, 75, 120, // ...<......Kx + 90, 199, 34, 4, 172, 132, 31, 62, 109, 68, 175, 169, // Z."....>mD.. + 111, 19, 151, 200, 70, 145, 119, 146, 159, 38, 83, 165, // o...F.w..&S. + 151, 25, 147, 104, 65, 192, 90, 248, 162, 208, 235, 59, // ...hA.Z....; + 165, 159, 14, 182, 80, 221, 42, 22, 167, 42, 165, 118, // ....P.*..*.v + 246, 76, 74, 20, 2, 86, 195, 23, 133, 158, 75, 156, // .LJ..V....K. + 38, 206, 161, 186, 89, 116, 73, 19, 199, 172, 73, 82, // &...YtI...IR + 33, 96, 61, 124, 81, 232, 61, 213, 205, 162, 227, 221, // !`=|Q.=..... + 46, 254, 161, 103, 56, 197, 167, 122, 114, 67, 160, 149, // ...g8..zrC.. + 240, 197, 41, 34, 102, 64, 123, 187, 248, 152, 94, 24, // ..)"f@{...^. + 113, 51, 145, 185, 202, 171, 9, 163, 98, 133, 64, 75, // q3......b.@K + 225, 139, 194, 12, 110, 166, 249, 194, 136, 88, 95, 25, // ....n....X_. + 131, 215, 172, 181, 100, 212, 100, 16, 104, 49, 252, 209, // ....d.d.h1.. + 233, 225, 214, 152, 46, 20, 245, 80, 123, 105, 212, 29, // .......P{i.. + 123, 57, 254, 22, 167, 22, 205, 138, 4, 129, 150, 195, // {9.......... + 71, 97, 22, 152, 9, 181, 151, 70, 77, 246, 218, 184, // Ga.....FM... + 130, 144, 95, 179, 102, 141, 135, 64, 235, 225, 143, 222, // .._.f..@.... + 55, 8, 249, 233, 189, 54, 110, 178, 23, 71, 154, 42, // 7....6n..G.* + 234, 52, 111, 152, 8, 129, 30, 194, 231, 175, 13, 144, // .4o......... + 76, 168, 190, 56, 50, 218, 171, 99, 23, 237, 244, 235, // L..82..c.... + 194, 48, 61, 10, 179, 161, 246, 234, 216, 104, 47, 143, // .0=......h/. + 46, 227, 124, 134, 217, 140, 10, 179, 161, 250, 242, 232, // ..|......... + 72, 175, 143, 207, 43, 114, 27, 102, 51, 42, 204, 134, // H...+r.f3*.. + 234, 235, 227, 5, 0, 102, 18, 13, 225, 1, 239, 239, // .....f...... + 230, 12, 163, 25, 23, 102, 36, 132, 143, 153, 205, 76, // .....f$....L + 24, 0, 1, 130, 82, 60, 232, 218, 46, 227, 252, 207, // ....R<...... + 186, 48, 35, 1, 128, 210, 88, 178, 141, 21, 128, 105, // .0#...X....i + 68, 103, 75, 154, 141, 95, 0, 230, 239, 15, 52, 243, // DgK.._....4. + 191, 0, 103, 49, 51, 106, 0, 8, 16, 164, 88, 28, // ..g13j....X. + 245, 134, 201, 140, 11, 51, 194, 172, 98, 205, 53, 102, // .....3..b.5f + 0, 80, 53, 126, 238, 3, 195, 100, 182, 133, 25, 197, // .P5~...d.... + 147, 105, 92, 0, 152, 182, 7, 126, 84, 106, 245, 126, // .i.....~Tj.~ + 103, 24, 205, 232, 26, 1, 146, 13, 102, 36, 27, 0, // g.......f$.. + 40, 203, 147, 193, 223, 230, 26, 83, 65, 230, 132, 153, // (......SA... + 96, 54, 241, 230, 25, 55, 0, 168, 202, 182, 64, 179, // `6...7....@. + 212, 117, 0, 143, 173, 173, 129, 37, 233, 21, 99, 180, // .u.....%..c. + 60, 211, 145, 132, 161, 57, 174, 242, 1, 189, 145, 186, // <....9...... + 46, 0, 51, 145, 146, 165, 36, 0, 80, 214, 22, 255, // ..3...$.P... + 59, 82, 138, 125, 100, 101, 57, 204, 75, 205, 28, 163, // ;R.}de9.K... + 71, 37, 54, 174, 101, 97, 207, 227, 125, 64, 111, 164, // G%6.ea..}@o. + 28, 11, 179, 144, 154, 163, 100, 0, 200, 72, 115, 106, // ......d..Hsj + 149, 203, 55, 100, 0, 160, 46, 0, 152, 1, 102, 161, // ..7d......f. + 56, 0, 40, 95, 71, 195, 207, 74, 171, 226, 27, 20, // 8.(_G..J.... + 26, 0, 208, 3, 0, 189, 199, 12, 18, 201, 48, 33, // ..........0! + 0, 248, 83, 65, 87, 240, 231, 230, 74, 239, 247, 6, // ..SAW...J... + 0, 202, 2, 128, 158, 163, 247, 137, 230, 151, 48, 0, // ..........0. + 168, 162, 237, 129, 91, 77, 21, 222, 43, 6, 0, 202, // ....[M..+... + 0, 128, 94, 163, 231, 52, 178, 163, 2, 0, 42, 111, // ..^..4....*o + 71, 224, 55, 27, 202, 235, 174, 24, 0, 200, 11, 0, // G.7......... + 122, 140, 94, 211, 202, 141, 26, 0, 168, 210, 39, 131, // z.^.......'. + 119, 111, 40, 155, 24, 2, 3, 0, 233, 0, 160, 183, // wo(......... + 232, 49, 205, 204, 168, 2, 128, 242, 182, 55, 220, 102, // .1.......7.f + 42, 175, 251, 222, 0, 128, 46, 0, 232, 41, 122, 75, // *........)zK + 59, 47, 234, 0, 160, 156, 157, 193, 159, 90, 221, 190, // ;/.......Z.. + 47, 13, 0, 232, 0, 128, 94, 162, 167, 114, 100, 37, // /.....^..rd% + 11, 0, 226, 117, 2, 188, 64, 241, 199, 108, 167, 1, // ...u..@..l.. + 128, 68, 0, 208, 59, 244, 48, 145, 121, 190, 106, 0, // .D..;.0.y.j. + 136, 170, 10, 5, 54, 229, 20, 186, 13, 0, 226, 4, // ....6....... + 0, 61, 67, 239, 228, 206, 71, 118, 0, 248, 107, 5, // .=C...Gv..k. + 29, 193, 7, 205, 21, 255, 31, 23, 24, 0, 76, 14, // ..........L. + 0, 122, 133, 158, 41, 145, 141, 34, 0, 160, 26, 219, // .z..)..".... + 27, 126, 82, 195, 113, 255, 94, 154, 110, 0, 16, 13, // .~R.q.^.n... + 0, 244, 6, 61, 66, 175, 148, 202, 69, 49, 0, 68, // ...=B...E1.D + 21, 214, 215, 6, 83, 151, 229, 27, 0, 140, 3, 0, // ....S....... + 61, 65, 111, 148, 206, 67, 113, 0, 80, 169, 53, 222, // =Ao..Cq.P.5. + 31, 103, 172, 183, 252, 107, 254, 194, 172, 164, 7, 0, // .g...k...... + 61, 64, 47, 208, 19, 53, 178, 80, 5, 128, 209, 171, // =@/..5.P.... + 135, 30, 123, 218, 163, 171, 139, 190, 75, 86, 0, 176, // ..{.....KV.. + 119, 244, 64, 205, 12, 84, 5, 64, 148, 125, 107, 160, // w.@..T.@.}k. + 181, 164, 42, 121, 150, 154, 97, 175, 216, 51, 11, 222, // ..*y..a..3.. + 51, 1, 128, 40, 91, 40, 224, 43, 183, 215, 95, 78, // 3..([(.+.._N + 203, 210, 95, 232, 216, 19, 246, 134, 61, 178, 228, 57, // .._.....=..9 + 83, 0, 136, 42, 239, 8, 174, 175, 242, 248, 134, 180, // S..*........ + 178, 253, 204, 100, 203, 181, 72, 47, 95, 98, 79, 44, // ...d..H/_bO, + 122, 205, 36, 0, 163, 107, 15, 59, 131, 15, 217, 125, // z.$..k.;...} + 220, 7, 90, 124, 30, 17, 107, 198, 218, 177, 7, 150, // ..Z|..k..... + 61, 102, 26, 128, 49, 207, 36, 132, 2, 78, 155, 159, // =f..1.$..N.. + 251, 152, 133, 157, 72, 39, 218, 201, 19, 107, 196, 90, // ....H'...k.Z + 181, 226, 171, 102, 0, 8, 223, 209, 212, 220, 25, 176, // ...f........ + 214, 4, 253, 231, 139, 45, 117, 87, 212, 14, 29, 107, // .....-uW...k + 192, 90, 176, 166, 240, 29, 56, 13, 0, 20, 18, 215, // .Z....8..... + 22, 188, 221, 190, 37, 208, 110, 107, 244, 191, 87, 233, // ....%.nk..W. + 244, 93, 34, 223, 194, 17, 57, 6, 145, 120, 76, 60, // .]"...9..xL< + 54, 126, 6, 126, 22, 126, 38, 126, 182, 214, 253, 211, // 6~.~.~&~.... + 60, 0, 145, 84, 214, 21, 248, 133, 115, 107, 192, 235, // <..T....sk.. + 108, 244, 247, 215, 248, 184, 15, 173, 30, 223, 23, 21, // l........... + 181, 245, 151, 44, 213, 222, 97, 83, 121, 221, 21, 12, // ...,..aSy... + 50, 187, 208, 53, 250, 94, 31, 252, 111, 252, 127, 248, // 2..5.^..o... + 103, 248, 119, 240, 239, 226, 191, 193, 127, 139, 199, 192, // g.w......... + 99, 225, 49, 245, 232, 213, 255, 0, 58, 21, 99, 155, // c.1.....:.c. + 126, 121, 49, 188, 0, 0, 0, 0, 73, 69, 78, 68, // ~y1.....IEND + 174, 66, 96, 130, 199, 98, 29, 214, 16, 15, 0, 0, 0 // .B`..b...... +}; +static const unsigned char v2[] = { + 31, 139, 8, 8, 35, 203, 64, 100, 0, 3, 105, 110, // ....#.@d..in 100, 101, 120, 46, 104, 116, 109, 108, 0, 93, 144, 177, // dex.html.].. 78, 196, 48, 12, 134, 247, 123, 138, 144, 153, 180, 176, // N.0...{..... 49, 36, 149, 208, 245, 6, 38, 24, 64, 130, 49, 77, // 1$....&.@.1M @@ -27,400 +353,481 @@ static const unsigned char v1[] = { 47, 244, 6, 21, 115, 235, 205, 228, 31, 137, 226, 92, // /...s....... 130, 117, 1, 0, 0, 0 // .u... }; -static const unsigned char v2[] = { - 31, 139, 8, 8, 255, 98, 56, 100, 0, 3, 109, 97, // .....b8d..ma - 105, 110, 46, 106, 115, 46, 111, 114, 105, 103, 0, 189, // in.js.orig.. - 91, 121, 115, 219, 200, 177, 255, 223, 159, 98, 150, 207, // [ys......b.. - 89, 130, 49, 9, 30, 178, 188, 126, 148, 201, 148, 227, // Y.1....~.... - 221, 122, 235, 148, 237, 56, 43, 111, 146, 45, 149, 42, // .z...8+o.-.* - 2, 129, 33, 137, 8, 4, 16, 96, 120, 69, 198, 119, // ..!....`xE.w - 127, 191, 238, 25, 0, 3, 138, 58, 214, 222, 68, 118, // .......:..Dv - 145, 192, 28, 61, 61, 125, 119, 207, 176, 189, 206, 165, // ...==}w..... - 200, 85, 22, 250, 170, 125, 246, 36, 92, 165, 73, 166, // .U...}.$..I. - 196, 205, 155, 4, 15, 177, 140, 85, 87, 44, 241, 95, // .......UW,._ - 173, 162, 174, 200, 100, 28, 200, 172, 43, 48, 225, 135, // ....d...+0.. - 249, 92, 250, 138, 31, 207, 149, 167, 36, 63, 253, 36, // ........$?.$ - 231, 133, 152, 103, 201, 74, 180, 221, 126, 154, 73, 207, // ...g.J..~.I. - 87, 238, 42, 140, 221, 127, 230, 0, 252, 196, 79, 226, // W.*.......O. - 92, 137, 247, 222, 238, 189, 164, 197, 242, 239, 61, 229, // ..........=. - 125, 76, 194, 88, 229, 98, 34, 78, 7, 24, 209, 239, // }L.X.b"N.... - 139, 79, 203, 48, 23, 57, 144, 136, 164, 72, 215, 179, // .O.0.9...H.. - 40, 204, 151, 253, 124, 61, 203, 253, 44, 156, 73, 129, // (...|=..,.I. - 62, 44, 19, 8, 149, 136, 212, 203, 115, 17, 39, 42, // >,......s.'* - 156, 135, 190, 167, 66, 192, 22, 106, 233, 41, 177, 149, // ....B..j.).. - 153, 36, 64, 153, 244, 101, 184, 193, 88, 198, 71, 45, // .$@..e..X.G- - 177, 69, 153, 109, 8, 123, 76, 246, 162, 72, 248, 203, // .E.m.{L..H.. - 48, 10, 132, 95, 110, 51, 23, 201, 156, 135, 121, 105, // 0.._n3....yi - 234, 62, 217, 120, 153, 248, 184, 158, 157, 175, 103, 192, // .>.x......g. - 205, 153, 175, 99, 159, 150, 112, 58, 226, 230, 137, 16, // ...c..p:.... - 212, 185, 244, 226, 32, 146, 25, 161, 126, 83, 116, 69, // .... ...~StE - 24, 224, 1, 91, 16, 88, 87, 173, 179, 152, 199, 9, // ...[.XW..... - 81, 97, 62, 22, 21, 140, 121, 220, 49, 189, 162, 130, // Qa>...y.1... - 114, 17, 6, 207, 158, 93, 2, 196, 60, 62, 227, 174, // r....]..<>.. - 162, 203, 95, 235, 248, 24, 132, 48, 168, 33, 4, 50, // .._....0.!.2 - 146, 74, 218, 128, 46, 27, 16, 12, 13, 173, 217, 1, // .J.......... - 200, 94, 207, 159, 39, 153, 112, 104, 67, 215, 34, 140, // .^..'.phC.". - 43, 48, 157, 26, 224, 245, 165, 158, 97, 160, 226, 179, // +0......a... - 56, 123, 82, 116, 156, 78, 197, 209, 15, 222, 6, 152, // 8{Rt.N...... - 167, 89, 146, 130, 26, 83, 22, 149, 171, 39, 175, 130, // .Y...S...'.. - 112, 3, 161, 218, 71, 114, 210, 154, 121, 254, 245, 34, // p...Gr..y.." - 75, 214, 113, 48, 22, 255, 115, 114, 114, 114, 6, 230, // K.q0..srrr.. - 5, 65, 24, 47, 198, 98, 224, 158, 202, 213, 25, 184, // .A./.b...... - 16, 37, 25, 58, 231, 243, 249, 89, 107, 138, 53, 120, // .%.:...Yk.5x - 186, 31, 129, 199, 147, 22, 86, 81, 94, 24, 203, 76, // ......VQ^..L - 4, 189, 121, 36, 119, 60, 192, 12, 49, 43, 80, 243, // ..y$w<..1+P. - 88, 12, 241, 207, 91, 171, 228, 76, 4, 97, 158, 70, // X...[..L.a.F - 222, 30, 187, 70, 199, 25, 216, 29, 46, 226, 94, 168, // ...F......^. - 228, 42, 31, 11, 31, 204, 150, 217, 153, 129, 2, 56, // .*.........8 - 179, 233, 47, 201, 26, 236, 206, 146, 96, 237, 171, 87, // ../.....`..W - 253, 153, 129, 223, 199, 2, 183, 151, 122, 4, 104, 161, // ........z.h. - 209, 25, 224, 159, 70, 167, 94, 43, 79, 189, 120, 250, // ....F.^+O.x. - 46, 89, 44, 32, 152, 160, 183, 151, 143, 95, 245, 185, // .Y, ....._.. - 205, 30, 80, 46, 85, 83, 201, 208, 169, 53, 125, 21, // ..P.US...5}. - 174, 22, 34, 207, 252, 73, 11, 122, 144, 185, 105, 188, // .."..I.z..i. - 104, 137, 165, 12, 23, 75, 53, 105, 141, 70, 45, 209, // h....K5i.F-. - 159, 30, 129, 55, 125, 122, 195, 220, 113, 105, 78, 113, // ...7}z..qiNq - 48, 192, 43, 201, 60, 83, 113, 75, 36, 177, 31, 133, // 0.+.i-.J. - 113, 191, 191, 74, 226, 69, 146, 228, 210, 221, 230, 125, // q..J.E.....} - 5, 209, 205, 66, 47, 202, 251, 212, 219, 211, 214, 179, // ...B/....... - 223, 154, 46, 247, 179, 12, 230, 78, 191, 19, 47, 197, // .......N../. - 118, 25, 250, 75, 0, 4, 159, 54, 97, 32, 115, 144, // v..K...6a s. - 83, 45, 65, 39, 152, 101, 159, 209, 14, 246, 177, 183, // S-A'.e...... - 194, 51, 105, 50, 84, 196, 21, 226, 92, 119, 206, 195, // .3i2T....w.. - 72, 230, 93, 17, 133, 215, 82, 188, 57, 63, 239, 255, // H.]...R.9?.. - 233, 188, 255, 227, 167, 247, 239, 0, 11, 102, 41, 92, // .........f). - 121, 11, 234, 245, 50, 201, 27, 199, 88, 82, 26, 108, // y...2...XR.l - 175, 182, 230, 98, 22, 198, 94, 182, 119, 159, 148, 68, // ...b..^.w..D - 253, 249, 45, 121, 136, 156, 135, 252, 244, 195, 249, 39, // ..-y.......' - 241, 250, 227, 91, 193, 238, 100, 69, 202, 25, 136, 217, // ...[..dE.... - 158, 251, 52, 61, 186, 26, 119, 177, 79, 214, 194, 135, // ..4=..w.O... - 226, 201, 29, 240, 140, 37, 128, 105, 242, 139, 87, 62, // .....%.i..W> - 136, 63, 245, 215, 89, 244, 170, 207, 143, 132, 201, 10, // .?..Y....... - 123, 234, 69, 24, 39, 214, 42, 140, 66, 181, 31, 179, // {.E.'.*.B... - 12, 167, 154, 193, 36, 195, 245, 52, 209, 91, 11, 47, // ....$..4.[./ - 0, 208, 49, 57, 172, 129, 136, 18, 223, 139, 150, 73, // ..19.......I - 174, 198, 47, 7, 131, 65, 223, 75, 67, 192, 141, 231, // ../..A.KC... - 225, 162, 191, 144, 170, 92, 163, 86, 140, 47, 5, 150, // .......V./.. - 75, 37, 122, 129, 104, 195, 252, 79, 86, 139, 62, 52, // K%z.h..OV.>4 - 33, 244, 219, 191, 1, 248, 149, 204, 115, 112, 5, 240, // !.......sp.. - 193, 86, 90, 192, 52, 76, 150, 50, 138, 146, 195, 21, // .VZ.4L.2.... - 44, 121, 47, 41, 206, 100, 230, 217, 7, 190, 155, 184, // ,y/).d...... - 74, 10, 80, 105, 3, 124, 185, 23, 239, 85, 184, 146, // J.Pi.|...U.. - 174, 248, 96, 143, 37, 209, 205, 72, 0, 98, 8, 57, // ..`.%..H.b.9 - 201, 192, 223, 228, 236, 60, 241, 175, 177, 101, 204, 249, // .....<...e.. - 249, 167, 183, 134, 107, 140, 240, 214, 83, 254, 178, 68, // ....k...S..D - 203, 203, 197, 159, 206, 255, 252, 129, 131, 157, 120, 1, // ..........x. - 69, 215, 3, 111, 90, 16, 79, 217, 26, 139, 150, 235, // E..oZ.O..... - 182, 186, 162, 69, 254, 14, 111, 174, 235, 22, 102, 102, // ...E..o...ff - 73, 171, 79, 208, 39, 61, 103, 155, 3, 27, 209, 235, // I.O.'=g..... - 193, 192, 47, 73, 226, 178, 33, 19, 109, 136, 38, 176, // ../I..!.m.&. - 32, 134, 89, 18, 91, 210, 168, 35, 52, 180, 81, 178, // .Y.[..#4.Q. - 76, 96, 90, 26, 64, 203, 14, 106, 51, 8, 127, 1, // L`Z.@..j3... - 229, 158, 212, 46, 156, 13, 162, 246, 225, 122, 196, 5, // .........z.. - 97, 208, 5, 73, 212, 207, 120, 160, 64, 162, 140, 203, // a..I..x.@... - 156, 118, 155, 93, 183, 25, 71, 56, 242, 184, 143, 120, // .v.]..G8...x - 184, 123, 92, 100, 86, 148, 240, 236, 165, 167, 152, 75, // .{.dV......K - 160, 237, 84, 158, 64, 136, 54, 239, 134, 135, 182, 187, // ..T.@.6..... - 86, 251, 205, 82, 122, 176, 67, 32, 239, 205, 107, 80, // V..Rz.C ..kP - 7, 70, 228, 223, 204, 184, 177, 104, 255, 209, 203, 161, // .F.....h.... - 245, 109, 241, 76, 204, 84, 226, 57, 132, 53, 158, 219, // .m.L.T.9.5.. - 99, 106, 33, 212, 58, 69, 209, 177, 32, 185, 208, 212, // cj!.:E.. ... - 216, 201, 200, 244, 103, 8, 34, 41, 0, 187, 171, 91, // ....g.")...[ - 124, 251, 173, 168, 92, 86, 136, 214, 230, 72, 159, 104, // |....V...H.h - 238, 200, 140, 7, 227, 171, 99, 133, 106, 183, 189, 10, // ......c.j... - 123, 10, 178, 21, 108, 80, 91, 181, 201, 223, 245, 182, // {...lP[..... - 97, 160, 16, 77, 61, 127, 57, 72, 225, 253, 43, 39, // a..M=.9H..+' - 96, 28, 189, 237, 120, 78, 143, 59, 158, 58, 188, 57, // `...xN.;.:.9 - 244, 242, 35, 154, 80, 6, 55, 181, 163, 41, 189, 208, // ..#.P.7..).. - 139, 23, 47, 224, 100, 14, 29, 139, 17, 14, 237, 95, // ../.d......_ - 14, 99, 149, 218, 71, 157, 26, 31, 85, 122, 253, 48, // .c..G...Uz.0 - 78, 215, 74, 168, 125, 42, 39, 109, 37, 119, 170, 45, // N.J.}*'m%w.- - 16, 212, 248, 114, 153, 68, 216, 240, 164, 253, 1, 250, // ...r.D...... - 208, 46, 161, 152, 45, 15, 7, 131, 223, 157, 181, 42, // ....-......* - 162, 38, 49, 195, 64, 164, 192, 66, 82, 202, 158, 35, // .&1.@..BR..# - 55, 174, 194, 178, 82, 185, 27, 47, 90, 203, 78, 33, // 7...R../Z.N! - 248, 27, 227, 56, 250, 64, 132, 114, 95, 116, 245, 40, // ...8.@.r_t.( - 140, 91, 36, 42, 112, 123, 65, 171, 129, 117, 235, 99, // .[$*p{A..u.c - 213, 252, 107, 49, 167, 153, 247, 96, 78, 235, 21, 214, // ..k1...`N... - 124, 31, 209, 241, 130, 58, 88, 214, 30, 187, 167, 225, // |....:X..... - 193, 142, 102, 107, 165, 224, 164, 237, 240, 235, 8, 222, // ..fk........ - 71, 226, 168, 10, 19, 196, 162, 222, 12, 94, 17, 152, // G........^.. - 124, 195, 186, 244, 249, 179, 248, 134, 145, 181, 2, 57, // |..........9 - 141, 227, 180, 18, 20, 189, 236, 189, 24, 55, 2, 31, // .........7.. - 91, 166, 71, 28, 132, 154, 245, 255, 138, 216, 55, 208, // [.G.......7. - 166, 2, 186, 110, 57, 142, 174, 109, 16, 245, 203, 136, // ...n9..m.... - 95, 70, 247, 135, 125, 69, 29, 249, 189, 97, 55, 182, // _F..}E...a7. - 206, 216, 112, 60, 96, 250, 178, 72, 91, 190, 44, 106, // ..p<`..H[.,j - 24, 52, 109, 13, 180, 63, 116, 201, 187, 129, 56, 7, // .4m..?t...8. - 198, 112, 61, 211, 182, 112, 61, 187, 123, 38, 6, 221, // .p=..p=.{&.. - 158, 153, 155, 153, 231, 247, 205, 204, 173, 153, 28, 81, // ...........Q - 152, 164, 217, 65, 26, 9, 177, 51, 25, 34, 35, 126, // ...A...3."#~ - 11, 89, 147, 110, 105, 228, 110, 33, 84, 247, 158, 31, // .Y.ni.n!T... - 246, 230, 166, 23, 57, 233, 133, 221, 113, 169, 145, 208, // ....9...q... - 248, 175, 83, 184, 56, 73, 153, 45, 57, 190, 46, 201, // ..S.8I.-9... - 57, 163, 164, 77, 124, 251, 32, 144, 104, 119, 171, 108, // 9..M|. .hw.l - 241, 190, 191, 149, 132, 173, 135, 140, 182, 83, 120, 187, // .........Sx. - 134, 67, 184, 235, 111, 150, 4, 200, 163, 174, 158, 222, // .C..o....... - 16, 22, 5, 233, 99, 76, 78, 17, 30, 188, 42, 62, // ....cLN...*> - 56, 132, 90, 113, 245, 32, 176, 162, 115, 220, 196, 219, // 8.Zq. ..s... - 251, 37, 25, 48, 46, 205, 180, 56, 109, 180, 97, 123, // .%.0...8m.a{ - 37, 193, 237, 209, 41, 167, 254, 205, 209, 104, 195, 232, // %...)....h.. - 146, 1, 246, 232, 252, 200, 232, 156, 71, 107, 134, 152, // ........Gk.. - 225, 73, 36, 201, 63, 105, 150, 117, 141, 236, 106, 49, // .I$.?i.u..j1 - 132, 36, 221, 239, 148, 234, 84, 135, 220, 195, 201, 209, // .$....T..... - 228, 218, 31, 156, 60, 63, 121, 222, 204, 167, 237, 100, // .... - 78, 149, 233, 70, 145, 2, 25, 213, 118, 187, 117, 151, // N..F....v.u. - 225, 70, 174, 254, 5, 215, 182, 234, 7, 114, 149, 228, // .F.......r.. - 253, 173, 156, 229, 156, 2, 246, 128, 36, 252, 70, 223, // ........$.F. - 176, 231, 71, 12, 124, 255, 23, 202, 16, 117, 183, 192, // ..G.|....u.. - 64, 161, 135, 112, 233, 2, 105, 39, 39, 163, 38, 141, // @..p..i''.&. - 173, 243, 208, 210, 90, 223, 146, 14, 67, 163, 85, 190, // ....Z...C.U. - 48, 75, 88, 185, 237, 181, 148, 105, 46, 60, 145, 34, // 0KX....i.<." - 251, 9, 115, 42, 117, 8, 147, 12, 82, 20, 99, 10, // ..s*u...R.c. - 23, 190, 177, 184, 200, 47, 44, 211, 232, 50, 172, 55, // ...../,..2.7 - 204, 214, 6, 22, 86, 24, 68, 89, 47, 121, 14, 111, // ....V.DY/y.o - 225, 41, 93, 4, 231, 202, 78, 153, 10, 32, 8, 83, // .)]...N.. .S - 217, 158, 225, 176, 120, 152, 250, 209, 138, 42, 67, 135, // ....x....*C. - 185, 53, 182, 156, 204, 120, 101, 61, 22, 107, 82, 253, // .5...xe=.kR. - 8, 195, 51, 145, 164, 50, 150, 1, 195, 169, 97, 215, // ..3..2....a. - 132, 56, 78, 5, 100, 232, 210, 4, 129, 216, 57, 16, // .8N.d.....9. - 78, 178, 220, 228, 250, 82, 175, 110, 252, 151, 174, 99, // N....R.n...c - 145, 206, 240, 186, 134, 116, 26, 107, 123, 183, 92, 154, // .....t.k{... - 137, 200, 193, 230, 82, 131, 138, 19, 101, 177, 227, 88, // ....R...e..X - 212, 248, 94, 115, 17, 158, 120, 85, 149, 11, 31, 204, // ..^s..xU.... - 46, 26, 26, 252, 175, 36, 111, 77, 241, 49, 22, 79, // .....$oM.1.O - 111, 86, 174, 145, 10, 23, 13, 133, 168, 21, 184, 49, // oV.........1 - 131, 181, 187, 53, 213, 74, 222, 152, 197, 77, 119, 206, // ...5.J...Mw. - 227, 34, 195, 148, 62, 155, 179, 168, 165, 170, 209, 30, // ."..>....... - 86, 2, 222, 151, 98, 122, 111, 68, 92, 10, 51, 135, // V...bzoD..3. - 168, 229, 148, 70, 156, 122, 113, 105, 71, 179, 106, 167, // ...F.zqiG.j. - 120, 232, 167, 157, 186, 93, 18, 184, 51, 114, 213, 147, // x....]..3r.. - 249, 224, 67, 159, 148, 184, 213, 89, 69, 125, 96, 2, // ..C....YE}`. - 1, 169, 207, 26, 194, 185, 160, 6, 151, 194, 61, 49, // ..........=1 - 153, 84, 197, 163, 118, 199, 70, 212, 217, 209, 26, 59, // .T..v.F....; - 138, 91, 17, 210, 57, 23, 52, 131, 136, 114, 217, 41, // .[..9.4..r.) - 207, 32, 204, 183, 137, 148, 204, 226, 214, 81, 9, 29, // . .......Q.. - 144, 148, 49, 112, 35, 238, 37, 85, 95, 85, 50, 162, // ..1p#.%U_U2. - 109, 163, 29, 243, 218, 213, 173, 71, 68, 189, 191, 46, // m......GD... - 226, 53, 209, 110, 89, 48, 59, 26, 237, 130, 19, 15, // .5.nY0;..... - 69, 187, 136, 116, 235, 178, 135, 102, 26, 49, 202, 226, // E..t...f.1.. - 39, 153, 28, 42, 190, 174, 243, 178, 118, 94, 38, 7, // '..*....v^&. - 198, 24, 193, 118, 252, 65, 180, 171, 151, 182, 192, 22, // ...v.A...... - 96, 238, 235, 134, 175, 142, 67, 79, 6, 254, 224, 249, // `.....CO.... - 224, 161, 56, 148, 205, 95, 41, 172, 118, 236, 169, 77, // ..8.._).v..M - 138, 101, 29, 133, 222, 207, 152, 14, 107, 158, 222, 212, // .e......k... - 27, 44, 204, 105, 205, 81, 7, 174, 207, 69, 40, 141, // .,.i.Q...E(. - 38, 87, 68, 149, 194, 121, 148, 108, 199, 166, 84, 115, // &WD..y.l..Ts - 120, 4, 213, 170, 188, 159, 46, 250, 104, 28, 160, 153, // x.......h... - 6, 63, 119, 229, 165, 78, 37, 60, 48, 46, 142, 17, // .?w..N%<0... - 88, 200, 137, 105, 46, 58, 157, 226, 203, 162, 137, 199, // X..i.:...... - 7, 19, 102, 169, 99, 225, 68, 163, 22, 66, 177, 5, // ..f.c.D..B.. - 155, 218, 52, 195, 12, 193, 7, 83, 174, 235, 222, 31, // ..4....S.... - 104, 148, 65, 6, 196, 176, 17, 100, 88, 122, 83, 186, // h.A....dXzS. - 252, 35, 33, 6, 73, 226, 29, 33, 198, 35, 92, 104, // .#!.I..!.#.h - 73, 90, 204, 205, 185, 22, 168, 61, 92, 93, 171, 23, // IZ.....=.].. - 155, 208, 227, 146, 62, 157, 97, 200, 216, 238, 33, 252, // ....>.a...!. - 224, 192, 16, 81, 37, 12, 143, 186, 108, 233, 225, 42, // ...Q%...l..* - 49, 53, 184, 226, 53, 60, 102, 67, 238, 232, 156, 196, // 15..5U......y - 201, 187, 170, 111, 87, 245, 157, 150, 179, 73, 116, 170, // ...oW....It. - 126, 126, 65, 239, 197, 101, 5, 124, 197, 117, 125, 3, // ~~A..e.|.u}. - 154, 94, 208, 61, 168, 123, 189, 157, 213, 139, 23, 244, // .^.=.{...... - 190, 247, 212, 18, 198, 111, 231, 122, 105, 26, 237, 157, // .....o.zi... - 120, 29, 69, 93, 94, 134, 45, 98, 74, 202, 159, 94, // x.E]^.-bJ..^ - 12, 141, 119, 38, 40, 59, 123, 141, 157, 89, 67, 67, // ..w&(;{..YCC - 9, 227, 123, 161, 12, 26, 80, 44, 92, 118, 191, 6, // ..{...P,.v.. - 23, 13, 69, 51, 239, 151, 158, 183, 131, 106, 18, 157, // ..E3.....j.. - 4, 157, 216, 229, 108, 19, 35, 111, 38, 163, 188, 162, // ....l.#o&... - 183, 199, 149, 48, 185, 21, 175, 179, 204, 219, 59, 134, // ...0......;. - 226, 207, 196, 176, 211, 113, 231, 97, 20, 57, 131, 14, // .....q.a.9.. - 195, 119, 254, 209, 21, 33, 71, 64, 97, 231, 140, 193, // .w...!G@a... - 135, 113, 64, 167, 170, 53, 231, 0, 41, 100, 239, 32, // .q@..5..)d. - 122, 196, 215, 158, 112, 248, 105, 200, 175, 29, 241, 123, // z...p.i....{ - 244, 246, 13, 135, 207, 106, 73, 211, 144, 228, 174, 157, // .....jI..... - 139, 95, 42, 88, 155, 18, 150, 195, 156, 232, 49, 239, // ._*X......1. - 14, 64, 84, 131, 169, 178, 181, 175, 99, 94, 62, 156, // .@T.....c^>. - 220, 13, 97, 157, 183, 195, 66, 236, 233, 97, 95, 136, // ..a...B..a_. - 221, 136, 26, 240, 62, 210, 239, 101, 4, 11, 80, 173, // ....>..e..P. - 62, 89, 165, 18, 154, 34, 130, 236, 187, 98, 211, 169, // >Y..."...b.. - 65, 82, 154, 42, 118, 147, 129, 216, 211, 100, 80, 231, // AR.*v....dP. - 180, 2, 192, 228, 108, 193, 49, 111, 224, 143, 105, 28, // ....l.1o..i. - 71, 172, 188, 173, 191, 63, 76, 127, 74, 7, 231, 43, // G....?L.J..+ - 90, 114, 29, 135, 28, 251, 49, 47, 190, 167, 8, 148, // Zr....1/.... - 91, 126, 79, 78, 106, 0, 94, 168, 228, 237, 249, 159, // [~ONj.^..... - 207, 249, 236, 206, 233, 112, 180, 169, 50, 103, 8, 181, // .....p..2g.. - 56, 173, 165, 230, 144, 153, 187, 47, 101, 230, 174, 102, // 8....../e..f - 38, 52, 247, 153, 112, 182, 96, 193, 150, 24, 185, 173, // &4..p.`..... - 24, 185, 59, 100, 228, 1, 51, 255, 94, 193, 170, 152, // ..;d..3.^... - 105, 118, 235, 176, 94, 0, 234, 78, 243, 118, 103, 241, // iv..^..N.vg. - 86, 67, 181, 182, 68, 204, 221, 213, 156, 72, 161, 4, // VC..D....H.. - 34, 152, 180, 222, 35, 58, 217, 21, 221, 167, 55, 75, // "...#:....7K - 240, 248, 93, 245, 194, 162, 86, 180, 238, 226, 238, 78, // ..]...V....N - 115, 119, 103, 184, 107, 220, 121, 131, 199, 128, 4, 32, // swg.k.y.... - 67, 48, 152, 120, 77, 0, 71, 143, 225, 245, 167, 204, // C0.xM.G..... - 139, 243, 121, 146, 173, 180, 17, 74, 245, 213, 46, 143, // ..y....J.... - 216, 160, 143, 237, 253, 4, 161, 85, 24, 131, 2, 37, // .......U...% - 235, 73, 195, 55, 53, 137, 55, 21, 37, 250, 194, 105, // .I.75.7.%..i - 146, 6, 202, 63, 36, 2, 53, 216, 80, 25, 189, 125, // ...?$.5.P..} - 9, 167, 214, 187, 77, 165, 49, 4, 171, 161, 66, 21, // ....M.1...B. - 44, 91, 55, 43, 88, 148, 208, 52, 77, 202, 5, 155, // ,[7+X..4M... - 29, 142, 109, 157, 96, 231, 104, 11, 211, 21, 118, 235, // ..m.`.h...v. - 222, 209, 54, 240, 210, 130, 67, 108, 11, 2, 55, 146, // ..6...Cl..7. - 241, 66, 45, 207, 52, 141, 94, 83, 68, 22, 37, 74, // .B-.4.^SD.%J - 199, 19, 68, 38, 47, 23, 204, 209, 169, 144, 250, 142, // ..D&/....... - 130, 153, 63, 147, 136, 23, 7, 12, 34, 66, 184, 126, // ..?....."B.~ - 69, 220, 14, 2, 44, 141, 255, 196, 103, 253, 60, 188, // E...,...g.<. - 44, 174, 16, 190, 163, 119, 208, 29, 84, 60, 230, 185, // ,....w..T<.. - 152, 202, 147, 96, 1, 106, 177, 184, 210, 162, 254, 54, // ...`.j.....6 - 14, 85, 232, 69, 154, 71, 102, 18, 149, 65, 170, 213, // .U.E.Gf..A.. - 222, 233, 213, 232, 13, 146, 80, 174, 89, 2, 161, 21, // ......P.Y... - 223, 221, 6, 109, 0, 233, 152, 165, 130, 5, 18, 84, // ...m.......T - 148, 228, 89, 68, 191, 130, 191, 9, 251, 14, 128, 145, // ..YD........ - 127, 186, 149, 114, 228, 155, 5, 2, 41, 185, 253, 99, // ...r....)..c - 178, 155, 180, 232, 46, 21, 219, 46, 44, 87, 152, 180, // ........,W.. - 157, 2, 89, 45, 191, 46, 27, 153, 27, 58, 215, 79, // ..Y-.....:.O - 174, 37, 242, 13, 207, 243, 206, 232, 114, 73, 52, 70, // .%......rI4F - 0, 29, 203, 51, 161, 195, 86, 151, 165, 247, 246, 192, // ...3..V..... - 250, 238, 210, 240, 132, 142, 117, 205, 104, 182, 90, 214, // ......u.h.Z. - 96, 223, 247, 155, 80, 117, 79, 143, 2, 63, 22, 243, // `...PuO..?.. - 49, 252, 112, 57, 89, 83, 97, 182, 176, 0, 232, 73, // 1.p9YSa....I - 26, 64, 182, 152, 121, 206, 104, 48, 232, 142, 70, 167, // .@..y.h0..F. - 221, 209, 233, 105, 151, 46, 18, 157, 118, 26, 147, 237, // ...i....v... - 181, 71, 167, 71, 118, 132, 36, 160, 36, 2, 108, 178, // .G.Gv.$.$.l. - 17, 89, 54, 51, 240, 8, 228, 199, 156, 176, 163, 115, // .Y63.......s - 146, 91, 221, 202, 116, 83, 92, 184, 177, 134, 237, 236, // .[..tS...... - 97, 48, 61, 100, 64, 173, 110, 86, 12, 45, 209, 96, // a0=d@.nV.-.` - 237, 193, 96, 101, 6, 83, 156, 162, 97, 82, 102, 217, // ..`e.S..aRf. - 102, 76, 75, 163, 245, 244, 134, 133, 147, 24, 169, 55, // fLK........7 - 233, 254, 19, 50, 232, 180, 69, 187, 67, 109, 16, 194, // ...2..E.Cm.. - 218, 116, 149, 36, 108, 153, 36, 226, 0, 198, 224, 40, // .t.$l.$....( - 144, 131, 217, 60, 23, 116, 218, 44, 14, 79, 24, 193, // ...<.t.,.O.. - 50, 117, 127, 29, 133, 54, 203, 133, 17, 186, 169, 122, // 2u...6.....z - 172, 126, 242, 31, 41, 140, 124, 195, 133, 17, 190, 33, // .~..).|....! - 219, 238, 24, 157, 56, 43, 11, 173, 26, 151, 187, 75, // ....8+.....K - 36, 46, 146, 74, 56, 49, 167, 119, 236, 154, 237, 215, // $..J81.w.... - 20, 80, 172, 144, 12, 161, 235, 42, 204, 249, 126, 212, // .P.....*..~. - 228, 248, 117, 222, 158, 176, 228, 132, 0, 241, 6, 205, // ..u......... - 156, 169, 24, 116, 74, 80, 150, 9, 37, 127, 239, 34, // ...tJP..%.." - 219, 117, 200, 96, 179, 195, 135, 71, 48, 115, 190, 186, // .u.`...G0s.. - 30, 33, 253, 147, 135, 138, 17, 132, 190, 22, 138, 99, // .!.........c - 167, 96, 15, 84, 15, 42, 161, 43, 19, 249, 167, 55, // .`.T.*.+...7 - 200, 160, 138, 242, 106, 230, 232, 249, 64, 103, 99, 147, // ....j...@gc. - 23, 131, 1, 59, 33, 138, 163, 64, 130, 201, 104, 192, // ...;!..@..h. - 164, 32, 151, 139, 175, 130, 233, 54, 209, 106, 246, 216, // . .....6.j.. - 212, 153, 202, 196, 44, 203, 228, 87, 114, 68, 89, 27, // ....,..WrDY. - 78, 136, 243, 36, 19, 165, 0, 199, 170, 153, 194, 62, // N..$.......> - 50, 65, 213, 130, 252, 58, 77, 127, 155, 187, 71, 186, // 2A...:M...G. - 8, 197, 35, 245, 169, 99, 99, 236, 77, 97, 87, 234, // ..#..cc.MaW. - 22, 82, 233, 225, 20, 171, 88, 113, 202, 145, 19, 234, // .R....Xq.... - 133, 62, 161, 190, 251, 210, 81, 251, 75, 47, 21, 85, // .>....Q.K/.U - 136, 222, 123, 155, 200, 62, 215, 165, 99, 103, 123, 27, // ..{..>..cg{. - 209, 225, 205, 173, 117, 169, 244, 65, 226, 115, 194, 15, // ....u..A.s.. - 29, 78, 174, 67, 42, 71, 94, 121, 62, 162, 207, 252, // .N.C*G^y>... - 31, 10, 6, 63, 166, 83, 22, 151, 159, 138, 51, 50, // ...?.S....32 - 123, 147, 254, 25, 221, 62, 162, 194, 225, 9, 100, 232, // {....>....d. - 170, 186, 0, 192, 119, 110, 214, 124, 179, 183, 169, 213, // ....wn.|.... - 21, 5, 29, 173, 202, 77, 172, 146, 181, 170, 42, 160, // .....M....*. - 143, 67, 232, 16, 141, 67, 28, 12, 175, 139, 50, 26, // .C...C....2. - 252, 27, 209, 136, 175, 151, 55, 46, 250, 185, 226, 117, // ......7....u - 46, 242, 132, 138, 46, 116, 82, 98, 247, 81, 168, 8, // .....tRb.Q.. - 225, 205, 187, 250, 110, 63, 95, 97, 213, 176, 204, 73, // ....n?_a...I - 135, 85, 164, 169, 175, 237, 87, 187, 98, 81, 182, 105, // .U....W.bQ.i - 93, 146, 154, 110, 183, 83, 44, 182, 69, 88, 158, 108, // ]..n.S,.EX.l - 93, 186, 145, 167, 15, 24, 32, 202, 138, 238, 23, 71, // ]..... ....G - 46, 63, 193, 62, 184, 153, 228, 42, 154, 211, 166, 195, // .?.>...*.... - 38, 136, 85, 123, 155, 183, 13, 93, 9, 140, 10, 3, // &.U{...].... - 228, 239, 57, 221, 49, 156, 152, 233, 207, 68, 187, 223, // ..9.1....D.. - 167, 251, 107, 145, 75, 215, 252, 248, 189, 210, 172, 118, // ..k.K......v - 53, 51, 147, 229, 181, 192, 35, 24, 234, 33, 91, 138, // 53....#..![. - 153, 40, 115, 169, 238, 51, 58, 188, 84, 167, 180, 254, // .(s..3:.T... - 219, 220, 77, 98, 58, 157, 41, 149, 162, 33, 123, 64, // ..Mb:.)..!{@ - 85, 212, 37, 220, 230, 164, 186, 232, 93, 173, 45, 55, // U.%.....].-7 - 29, 171, 192, 173, 178, 125, 163, 220, 77, 248, 192, 200, // .....}..M... - 96, 2, 93, 152, 116, 83, 47, 203, 37, 21, 247, 172, // `.].tS/.%... - 159, 2, 232, 63, 227, 60, 204, 207, 12, 216, 173, 217, // ...?.<...... - 221, 247, 120, 182, 3, 220, 123, 83, 144, 187, 57, 29, // ..x...{S..9. - 73, 7, 243, 212, 145, 157, 6, 114, 141, 153, 111, 227, // I......r..o. - 13, 223, 67, 194, 238, 249, 58, 244, 24, 96, 42, 68, // ..C...:..`*D - 89, 122, 100, 142, 204, 83, 245, 204, 129, 38, 95, 220, // Yzd..S...&_. - 173, 151, 48, 79, 69, 131, 92, 126, 148, 228, 242, 56, // ..0OE..~...8 - 163, 176, 122, 36, 189, 236, 83, 184, 146, 208, 33, 71, // ..z$..S...!G - 25, 79, 105, 168, 200, 78, 159, 74, 161, 166, 187, 226, // .Oi..N.J.... - 122, 87, 187, 180, 122, 232, 33, 231, 26, 245, 247, 106, // zW..z.!....j - 156, 65, 171, 40, 53, 219, 12, 177, 85, 250, 120, 12, // .A.(5...U.x. - 130, 109, 191, 129, 202, 64, 83, 176, 27, 73, 247, 98, // .m...@S..I.b - 195, 152, 234, 163, 192, 235, 137, 197, 182, 218, 227, 51, // ...........3 - 179, 167, 162, 113, 60, 163, 237, 71, 155, 174, 86, 90, // ...q<..G..VZ - 214, 196, 32, 103, 91, 98, 115, 7, 244, 209, 70, 248, // .. g[bs...F. - 94, 19, 108, 117, 222, 190, 202, 169, 59, 89, 183, 172, // ^.lu....;Y.. - 198, 134, 61, 182, 12, 210, 97, 16, 67, 210, 200, 23, // ..=...a.C... - 229, 58, 141, 112, 2, 222, 250, 157, 190, 200, 199, 11, // .:.p........ - 218, 247, 250, 174, 142, 36, 38, 79, 111, 62, 120, 155, // .....$&Oo>x. - 130, 207, 37, 171, 91, 141, 218, 164, 234, 153, 244, 131, // ..%.[....... - 9, 142, 58, 143, 253, 134, 229, 214, 175, 91, 178, 100, // ..:......[.d - 107, 255, 160, 165, 26, 31, 81, 188, 210, 123, 209, 154, // k.....Q..{.. - 98, 61, 250, 29, 68, 193, 191, 237, 104, 94, 215, 59, // b=..D...h^.; - 58, 152, 99, 152, 199, 141, 54, 20, 212, 155, 96, 150, // :.c...6...`. - 243, 1, 46, 115, 124, 233, 188, 105, 30, 199, 222, 104, // ...s|..i...h - 1, 40, 76, 142, 242, 40, 92, 202, 51, 189, 194, 156, // .(L..(..3... - 237, 78, 158, 150, 80, 108, 252, 142, 197, 30, 198, 88, // .N..Pl.....X - 39, 113, 148, 120, 65, 101, 239, 244, 15, 208, 156, 165, // 'q.xAe...... - 131, 160, 4, 105, 70, 229, 179, 232, 108, 13, 44, 254, // ...iF...l.,. - 127, 21, 173, 12, 91, 202, 54, 0, 0, 0 // ....[.6.. -}; static const unsigned char v3[] = { - 31, 139, 8, 8, 255, 98, 56, 100, 0, 3, 112, 114, // .....b8d..pr + 31, 139, 8, 8, 35, 203, 64, 100, 0, 3, 109, 97, // ....#.@d..ma + 105, 110, 46, 106, 115, 0, 189, 91, 123, 119, 219, 184, // in.js..[{w.. + 177, 255, 63, 159, 2, 171, 235, 91, 81, 181, 68, 73, // ..?....[Q.DI + 118, 156, 205, 149, 35, 245, 164, 217, 237, 221, 244, 36, // v...#......$ + 217, 116, 157, 109, 187, 199, 199, 167, 166, 72, 72, 98, // .t.m.....HHb + 77, 145, 92, 18, 122, 213, 225, 119, 191, 191, 25, 128, // M...z..w.... + 36, 40, 203, 143, 108, 218, 235, 228, 72, 36, 48, 24, // $(..l...H$0. + 12, 102, 6, 243, 2, 212, 94, 229, 82, 228, 42, 11, // .f....^.R.*. + 125, 213, 62, 127, 22, 46, 211, 36, 83, 226, 246, 77, // }.>....$S..M + 130, 135, 88, 198, 170, 43, 22, 248, 175, 150, 81, 87, // ..X..+....QW + 100, 50, 14, 100, 214, 21, 24, 240, 253, 108, 38, 125, // d2.d.....l&} + 197, 143, 23, 202, 83, 146, 159, 126, 146, 179, 66, 204, // ....S..~..B. + 178, 100, 41, 218, 110, 63, 205, 164, 231, 43, 119, 25, // .d).n?...+w. + 198, 238, 63, 115, 32, 126, 182, 246, 50, 17, 200, 181, // ..?s ~..2... + 23, 4, 153, 24, 139, 22, 125, 203, 60, 31, 209, 116, // ......}.<..t + 45, 116, 251, 73, 156, 43, 241, 222, 219, 190, 151, 68, // -t.I.+.....D + 75, 254, 157, 167, 188, 143, 73, 24, 171, 28, 208, 103, // K.....I....g + 3, 64, 244, 251, 226, 211, 34, 204, 69, 14, 26, 35, // .@....".E..# + 41, 210, 213, 52, 10, 243, 69, 63, 95, 77, 115, 63, // )..4..E?_Ms? + 11, 167, 82, 160, 15, 84, 4, 66, 37, 34, 245, 242, // ..R..T.B%".. + 92, 196, 137, 10, 103, 161, 239, 169, 16, 184, 133, 90, // ....g......Z + 120, 74, 108, 100, 38, 9, 81, 38, 125, 25, 174, 1, // xJld&.Q&}... + 203, 228, 170, 5, 56, 32, 179, 53, 45, 14, 131, 189, // ....8 .5-... + 40, 18, 254, 34, 140, 2, 225, 151, 92, 200, 69, 50, // (.."......E2 + 99, 48, 47, 77, 93, 94, 202, 199, 213, 244, 98, 53, // c0/M]^....b5 + 5, 109, 206, 108, 21, 251, 52, 133, 211, 17, 183, 207, // .m.l..4..... + 132, 160, 206, 133, 23, 7, 145, 204, 136, 244, 219, 162, // ............ + 43, 194, 0, 15, 88, 130, 192, 188, 106, 149, 197, 12, // +...X...j... + 39, 68, 69, 249, 72, 84, 56, 102, 113, 199, 244, 138, // 'DE.HT8fq... + 10, 203, 101, 24, 28, 31, 95, 1, 197, 44, 62, 231, // ..e..._..,>. + 174, 162, 203, 95, 171, 248, 16, 134, 48, 168, 49, 4, // ..._....0.1. + 50, 146, 74, 218, 136, 174, 26, 24, 12, 15, 173, 209, // 2.J......... + 1, 216, 94, 143, 159, 37, 153, 112, 104, 65, 55, 34, // ..^..%.phA7" + 140, 43, 52, 157, 26, 225, 205, 149, 30, 97, 176, 226, // .+4......a.. + 179, 56, 127, 86, 116, 156, 78, 37, 209, 15, 222, 26, // .8.Vt.N%.... + 148, 167, 89, 146, 130, 27, 19, 214, 164, 235, 103, 175, // ..Y.......g. + 130, 112, 13, 157, 219, 69, 114, 220, 154, 122, 254, 205, // .p...Er..z.. + 60, 75, 86, 113, 48, 18, 255, 117, 122, 122, 122, 14, // .,.Lv... + 37, 158, 105, 39, 99, 139, 184, 66, 92, 232, 206, 89, // %.i'c..B...Y + 24, 201, 188, 43, 162, 240, 70, 138, 55, 23, 23, 253, // ...+..F.7... + 63, 95, 244, 127, 248, 244, 254, 29, 112, 193, 44, 133, // ?_......p.,. + 75, 111, 78, 189, 94, 38, 121, 225, 128, 165, 77, 131, // KoN.^&y...M. + 229, 213, 214, 92, 76, 195, 216, 203, 118, 238, 179, 146, // ....L...v... + 169, 63, 191, 37, 15, 145, 51, 200, 79, 223, 95, 124, // .?.%..3.O._| + 18, 175, 63, 190, 21, 236, 78, 150, 180, 57, 3, 49, // ..?...N..9.1 + 221, 113, 159, 230, 71, 87, 211, 46, 118, 201, 74, 248, // .q..GW..v.J. + 216, 120, 114, 11, 58, 99, 9, 100, 154, 253, 226, 149, // .xr.:c.d.... + 15, 230, 79, 252, 85, 22, 189, 234, 243, 35, 81, 178, // ..O.U....#Q. + 196, 154, 122, 17, 224, 196, 74, 133, 81, 168, 118, 35, // ..z...J.Q.v# + 214, 225, 84, 11, 152, 116, 184, 30, 38, 122, 43, 225, // ..T..t..&z+. + 5, 64, 58, 34, 135, 53, 16, 71, 183, 198, 67, 22, // .@:".5.G..C. + 125, 47, 13, 129, 51, 158, 133, 243, 254, 92, 170, 18, // }/..3....... + 127, 189, 41, 126, 11, 162, 92, 42, 209, 11, 68, 27, // ..)~...*..D. + 102, 127, 188, 156, 247, 177, 3, 66, 191, 253, 149, 168, // f......B.... + 151, 112, 226, 144, 4, 112, 67, 148, 132, 220, 52, 140, // .p...pC...4. + 23, 50, 138, 146, 125, 236, 150, 142, 151, 92, 102, 214, // .2..}.....f. + 242, 232, 61, 127, 77, 146, 36, 165, 175, 118, 0, 252, // ..=.M.$..v.. + 183, 23, 239, 84, 184, 148, 174, 248, 96, 195, 146, 186, // ...T....`... + 102, 36, 244, 24, 138, 77, 114, 255, 155, 156, 94, 36, // f$...Mr...^$ + 254, 13, 150, 139, 49, 63, 255, 244, 214, 72, 138, 9, // ....1?...H.. + 222, 120, 202, 95, 148, 100, 121, 185, 248, 243, 197, 143, // .x._.dy..... + 31, 56, 254, 137, 231, 216, 220, 26, 240, 182, 5, 149, // .8.......... + 148, 173, 145, 104, 185, 110, 171, 43, 90, 228, 227, 240, // ...h.n.+Z... + 230, 186, 110, 97, 70, 150, 124, 250, 132, 61, 164, 199, // ..naF.|..=.. + 108, 114, 80, 35, 122, 61, 24, 245, 5, 105, 89, 54, // lrP#z=...iY6 + 100, 134, 13, 209, 4, 246, 199, 48, 69, 98, 67, 187, // d......0EbC. + 104, 143, 127, 54, 57, 150, 201, 75, 75, 131, 103, 217, // h..69..KK.g. + 61, 109, 246, 224, 31, 176, 153, 199, 181, 203, 102, 3, // =m........f. + 168, 125, 182, 134, 184, 164, 217, 187, 96, 135, 250, 25, // .}......`... + 15, 20, 56, 148, 97, 154, 211, 110, 179, 171, 54, 112, // ..8.a..n..6p + 68, 31, 195, 125, 196, 195, 253, 112, 145, 153, 81, 194, // D..}...p..Q. + 147, 151, 158, 97, 38, 65, 182, 83, 89, 126, 33, 218, // ...a&A.SY~!. + 188, 26, 6, 109, 119, 173, 246, 219, 133, 244, 96, 119, // ...mw.....`w + 192, 218, 219, 215, 224, 12, 140, 198, 191, 88, 104, 35, // .........Xh# + 209, 254, 163, 151, 99, 151, 183, 197, 177, 152, 170, 196, // ....c....... + 115, 136, 106, 60, 183, 71, 212, 66, 164, 117, 138, 162, // s.j<.G.B.u.. + 99, 97, 114, 177, 51, 99, 39, 35, 83, 159, 33, 166, // car.3c'#S.!. + 164, 128, 235, 190, 110, 241, 187, 223, 137, 202, 69, 133, // ....n.....E. + 104, 109, 66, 250, 196, 115, 71, 102, 12, 140, 175, 142, // hmB..sGf.... + 21, 154, 221, 245, 34, 236, 25, 200, 54, 176, 1, 109, // ...."...6..m + 213, 38, 126, 219, 219, 132, 129, 66, 244, 244, 252, 229, // .&~....B.... + 32, 133, 183, 175, 140, 190, 113, 236, 182, 163, 57, 59, // .....q...9; + 236, 104, 234, 112, 102, 223, 171, 159, 208, 128, 50, 152, // .h.pf.....2. + 169, 29, 75, 233, 117, 94, 188, 120, 1, 167, 178, 239, // ..K.u^.x.... + 72, 140, 114, 104, 127, 178, 31, 155, 212, 62, 233, 204, // H.rh.....>.. + 248, 164, 210, 203, 135, 113, 186, 82, 66, 237, 82, 57, // .....q.RB.R9 + 110, 43, 185, 85, 109, 129, 32, 198, 151, 139, 36, 194, // n+.Um. ...$. + 130, 199, 237, 15, 216, 11, 237, 18, 139, 89, 242, 112, // .........Y.p + 48, 248, 239, 243, 86, 197, 212, 36, 102, 28, 136, 12, // 0...V..$f... + 88, 73, 74, 221, 115, 228, 218, 85, 152, 86, 42, 119, // XIJ.s..U.V*w + 237, 69, 43, 217, 41, 4, 127, 3, 142, 163, 13, 68, // .E+.)......D + 36, 15, 69, 83, 79, 162, 184, 69, 170, 2, 55, 23, // $.ESO..E..7. + 180, 26, 84, 183, 62, 86, 205, 95, 74, 57, 141, 124, // ..T.>V._J9.| + 128, 114, 154, 175, 176, 198, 251, 136, 134, 231, 212, 193, // .r.......... + 186, 246, 212, 53, 13, 247, 86, 52, 93, 41, 5, 167, // ...5..V4]).. + 108, 135, 91, 7, 232, 62, 16, 55, 85, 148, 32, 246, // l.[..>.7U. . + 244, 166, 240, 130, 160, 228, 27, 222, 75, 159, 63, 139, // ........K.?. + 111, 152, 88, 43, 112, 211, 52, 78, 42, 69, 209, 211, // o.X+p.4N*E.. + 62, 72, 113, 35, 208, 177, 117, 250, 132, 131, 78, 51, // >Hq#..u...N3 + 255, 95, 17, 235, 6, 218, 84, 96, 175, 91, 14, 163, // ._....T`.[.. + 107, 27, 67, 253, 114, 194, 47, 39, 15, 135, 121, 69, // k.C.r./'..yE + 29, 233, 189, 97, 247, 181, 202, 216, 112, 60, 98, 250, // ...a....p + 125, 50, 1, 122, 35, 191, 109, 24, 117, 114, 67, 173, // }2.z#.m.urC. + 59, 9, 124, 211, 116, 139, 218, 153, 100, 81, 97, 91, // ;.|.t...dQa[ + 226, 74, 196, 133, 5, 124, 200, 71, 97, 179, 221, 53, // .J...|.Ga..5 + 244, 165, 1, 63, 96, 146, 27, 54, 214, 76, 106, 44, // ...?`..6.Lj, + 235, 157, 57, 239, 205, 134, 15, 228, 190, 63, 243, 96, // ..9......?.` + 219, 28, 55, 194, 241, 39, 242, 94, 60, 206, 252, 139, // ..7..'.^<... + 170, 90, 198, 209, 255, 215, 9, 160, 100, 63, 116, 245, // .Z......d?t. + 0, 251, 169, 245, 33, 55, 75, 214, 234, 55, 51, 191, // ....!7K..73. + 156, 178, 193, 124, 107, 198, 255, 127, 230, 63, 206, 251, // ...|k....?.. + 143, 186, 218, 246, 239, 224, 124, 205, 251, 244, 32, 239, // ......|... . + 83, 155, 247, 135, 131, 156, 175, 225, 126, 122, 136, 251, // S.......~z.. + 233, 127, 132, 251, 154, 160, 95, 76, 10, 78, 181, 234, // ......_L.N.. + 70, 93, 2, 9, 213, 102, 179, 113, 23, 225, 90, 46, // F]...f.q..Z. + 127, 133, 119, 91, 246, 3, 185, 76, 242, 254, 70, 78, // ..w[...L..FN + 115, 206, 0, 123, 32, 18, 174, 163, 111, 196, 243, 3, // s..{ ...o... + 0, 223, 255, 133, 18, 68, 221, 45, 0, 40, 52, 8, // .....D.-.(4. + 87, 43, 144, 117, 114, 46, 106, 178, 216, 58, 13, 45, // W+.ur.j..:.- + 173, 245, 29, 237, 48, 60, 90, 230, 115, 51, 133, 149, // ....06 + 151, 26, 85, 156, 40, 75, 28, 135, 2, 199, 247, 90, // ..U.(K.....Z + 138, 112, 198, 203, 170, 66, 248, 104, 130, 209, 216, 193, // .p...B.h.... + 191, 38, 121, 107, 130, 143, 145, 56, 186, 93, 186, 70, // .&yk...8.].F + 43, 92, 52, 20, 162, 222, 192, 141, 17, 188, 187, 91, // +.4........[ + 19, 189, 201, 27, 163, 184, 233, 222, 113, 92, 99, 152, // ........q.c. + 208, 103, 115, 20, 181, 84, 101, 217, 253, 98, 192, 251, // .gs..Te..b.. + 82, 77, 31, 12, 138, 75, 101, 230, 40, 181, 28, 210, // RM...Ke.(... + 8, 85, 47, 175, 236, 128, 86, 109, 21, 131, 126, 218, // .U/...Vm..~. + 170, 187, 85, 129, 123, 131, 87, 61, 152, 207, 58, 244, // ..U.{.W=..:. + 225, 136, 91, 29, 79, 212, 103, 36, 80, 144, 250, 120, // ..[.O.g$P..x + 33, 156, 9, 106, 112, 41, 226, 19, 227, 113, 85, 59, // !..jp)...qU; + 106, 119, 108, 66, 157, 45, 205, 177, 165, 208, 21, 81, // jwlB.-.....Q + 157, 115, 73, 35, 136, 41, 87, 157, 242, 216, 193, 124, // .sI#.)W....| + 155, 72, 201, 76, 110, 157, 142, 208, 153, 72, 25, 6, // .H.Ln....H.. + 55, 66, 95, 218, 234, 203, 74, 71, 180, 109, 180, 195, // 7B_...JG.m.. + 94, 187, 184, 245, 132, 192, 247, 203, 130, 94, 19, 240, // ^........^.. + 150, 245, 178, 131, 1, 47, 36, 241, 88, 192, 139, 96, // ...../$.X..` + 183, 174, 124, 104, 161, 145, 160, 44, 121, 194, 222, 42, // ..|h...,y..* + 218, 251, 99, 209, 50, 214, 71, 34, 43, 198, 246, 182, // ..c.2.G"+... + 83, 130, 26, 156, 96, 168, 60, 187, 34, 173, 250, 166, // S...`.<."... + 28, 252, 7, 209, 182, 235, 210, 11, 143, 206, 215, 180, // ............ + 193, 42, 133, 235, 81, 181, 179, 45, 70, 13, 188, 110, // .*..Q..-F..n + 53, 37, 161, 168, 94, 8, 172, 13, 151, 82, 55, 124, // 5%..^....R7| + 117, 172, 123, 58, 240, 7, 207, 7, 143, 197, 186, 76, // u.{:.......L + 113, 185, 33, 236, 248, 86, 155, 45, 203, 2, 11, 205, // q.!..V.-.... + 132, 17, 157, 1, 29, 221, 214, 92, 41, 204, 33, 208, // ........).!. + 193, 32, 65, 31, 183, 80, 182, 78, 238, 142, 138, 145, // . A..P.N.... + 179, 40, 217, 140, 76, 69, 104, 255, 100, 171, 85, 121, // .(..LEh.d.Uy + 88, 93, 91, 210, 52, 96, 247, 27, 250, 220, 165, 151, // X][.4`...... + 58, 149, 130, 194, 128, 57, 102, 83, 64, 23, 77, 115, // :....9fS@.Ms + 209, 233, 20, 191, 45, 98, 121, 122, 192, 98, 166, 58, // ....-byz.b.: + 20, 178, 52, 74, 46, 20, 191, 176, 57, 79, 233, 104, // ..4J....9O.h + 87, 240, 121, 151, 235, 186, 15, 7, 51, 101, 32, 3, // W.y.....3e . + 85, 111, 4, 50, 214, 222, 44, 26, 193, 135, 209, 200, // Uo.2..,..... + 50, 214, 56, 16, 219, 208, 22, 184, 39, 182, 121, 130, // 2.8.....'.y. + 239, 46, 249, 141, 177, 57, 215, 33, 181, 107, 173, 207, // .....9.!.k.. + 5, 196, 58, 244, 248, 248, 128, 206, 75, 100, 108, 247, // ..:.....Kdl. + 16, 209, 240, 156, 8, 229, 18, 198, 71, 93, 182, 74, // ........G].J + 113, 117, 154, 26, 92, 241, 26, 174, 186, 161, 140, 116, // qu.........t + 38, 227, 213, 135, 194, 129, 142, 19, 141, 101, 51, 199, // &........e3. + 213, 123, 231, 19, 119, 3, 128, 61, 191, 78, 148, 214, // .{..w..=.N.. + 101, 230, 251, 188, 37, 146, 209, 239, 183, 169, 222, 164, // e...%....... + 224, 217, 138, 14, 67, 242, 17, 53, 107, 119, 68, 37, // ....C..5kwD% + 119, 44, 32, 36, 15, 34, 221, 185, 43, 46, 197, 229, // w, $."..+... + 240, 197, 217, 243, 211, 23, 195, 211, 179, 147, 174, 24, // ............ + 254, 207, 85, 215, 106, 57, 69, 203, 75, 180, 64, 244, // ..U.j9E.K.@. + 226, 138, 176, 112, 5, 171, 107, 142, 34, 187, 98, 167, // ...p..k.".b. + 16, 54, 2, 213, 214, 124, 239, 16, 35, 208, 167, 183, // .6...|..#... + 69, 27, 63, 111, 241, 108, 60, 220, 197, 95, 255, 247, // E.?o.l<.._.. + 30, 231, 6, 196, 214, 223, 166, 108, 57, 238, 29, 250, // .......l9... + 59, 46, 187, 63, 151, 3, 22, 67, 107, 244, 231, 70, // ;..?...Ck..F + 183, 141, 226, 248, 110, 247, 103, 123, 160, 249, 88, 212, // ....n.g{..X. + 16, 155, 225, 30, 196, 230, 228, 203, 240, 107, 242, 78, // .........k.N + 14, 80, 247, 208, 218, 240, 17, 81, 60, 91, 30, 137, // .P.....Q<[.. + 186, 37, 215, 171, 134, 146, 255, 32, 112, 44, 78, 7, // .%..... p,N. + 93, 34, 108, 44, 240, 189, 160, 134, 151, 93, 154, 115, // ]"l,.....].s + 12, 209, 157, 27, 84, 90, 78, 213, 112, 243, 250, 249, // ....TZN.p... + 179, 120, 94, 202, 174, 234, 219, 86, 125, 103, 229, 104, // .x^....V}g.h + 82, 157, 170, 159, 95, 208, 123, 121, 85, 33, 95, 242, // R..._.{yU!_. + 153, 130, 65, 77, 47, 232, 30, 212, 189, 222, 214, 234, // ..AM/....... + 197, 11, 122, 223, 123, 106, 1, 139, 184, 117, 189, 52, // ..z.{j...u.4 + 141, 118, 78, 188, 138, 162, 46, 79, 195, 102, 50, 165, // .vN....O.f2. + 205, 159, 94, 14, 77, 88, 64, 88, 182, 246, 28, 91, // ..^.MX@X...[ + 51, 135, 198, 18, 198, 15, 98, 25, 52, 176, 88, 180, // 3.....b.4.X. + 108, 191, 132, 22, 141, 69, 11, 239, 151, 158, 183, 197, // l....E...... + 214, 36, 62, 9, 58, 29, 204, 217, 80, 70, 222, 84, // .$>.:...PF.T + 70, 121, 197, 111, 143, 171, 112, 114, 35, 94, 103, 153, // Fy.o..pr#^g. + 183, 115, 12, 199, 143, 197, 176, 211, 113, 103, 97, 20, // .s......qga. + 57, 131, 14, 227, 119, 254, 209, 21, 33, 135, 94, 97, // 9...w...!.^a + 231, 156, 209, 135, 113, 64, 39, 184, 181, 228, 128, 41, // ....q@'....) + 100, 151, 33, 122, 36, 215, 158, 112, 248, 105, 200, 175, // d.!z$..p.i.. + 29, 241, 123, 244, 246, 141, 132, 207, 107, 77, 211, 152, // ..{.....kM.. + 228, 182, 157, 139, 95, 42, 92, 235, 18, 151, 195, 146, // ...._*...... + 232, 177, 236, 246, 80, 84, 192, 84, 85, 219, 213, 193, // ....PT.TU... + 54, 31, 132, 110, 135, 176, 206, 155, 97, 33, 118, 244, // 6..n....a!v. + 176, 43, 196, 246, 132, 26, 240, 126, 162, 223, 203, 208, // .+.....~.... + 25, 168, 90, 125, 178, 74, 37, 54, 69, 12, 217, 117, // ..Z}.J%6E..u + 197, 186, 83, 163, 164, 252, 88, 108, 199, 3, 177, 163, // ..S...Xl.... + 193, 224, 206, 89, 133, 128, 217, 217, 130, 183, 94, 195, // ...Y......^. + 73, 19, 28, 135, 202, 188, 172, 191, 63, 206, 127, 202, // I.......?... + 67, 103, 75, 154, 114, 21, 135, 28, 116, 178, 44, 190, // CgK.r...t.,. + 163, 208, 151, 91, 126, 79, 158, 107, 0, 89, 168, 228, // ...[~O.k.Y.. + 237, 197, 143, 23, 124, 102, 232, 116, 56, 204, 85, 153, // ....|f.t8.U. + 51, 196, 182, 56, 171, 181, 102, 95, 152, 219, 223, 42, // 3..8..f_...* + 204, 109, 45, 76, 236, 220, 99, 225, 108, 32, 130, 13, // .m-L..c.l .. + 9, 114, 83, 9, 114, 187, 47, 200, 61, 97, 254, 189, // .rS.r./.=a.. + 194, 85, 9, 211, 172, 214, 225, 125, 1, 172, 91, 45, // .U.....}..[- + 219, 173, 37, 91, 141, 213, 90, 18, 9, 119, 91, 75, // ..%[..Z..w[K + 34, 197, 38, 16, 193, 184, 245, 30, 33, 203, 182, 232, // ".&.....!... + 30, 221, 46, 32, 227, 119, 213, 11, 171, 90, 209, 186, // ... .w...Z.. + 79, 186, 91, 45, 221, 173, 145, 174, 113, 231, 13, 25, // O.[-....q... + 3, 19, 144, 12, 33, 96, 146, 53, 33, 60, 121, 138, // ....!`.5!.... + 160, 123, 114, 114, 214, 61, 57, 59, 235, 210, 165, 165, // .{rr.=9;.... + 179, 78, 99, 176, 61, 247, 201, 217, 129, 21, 33, 51, // .Nc.=.....!3 + 40, 153, 0, 155, 108, 84, 150, 205, 12, 60, 2, 249, // (...lT...<.. + 49, 39, 236, 232, 68, 229, 78, 183, 50, 221, 20, 23, // 1'..D.N.2... + 174, 45, 176, 173, 13, 6, 211, 67, 6, 212, 234, 230, // .-.....C.... + 141, 161, 53, 26, 162, 221, 3, 86, 6, 152, 226, 20, // ..5....V.... + 141, 147, 210, 205, 54, 83, 90, 26, 173, 163, 91, 86, // ....6SZ...[V + 78, 18, 164, 94, 164, 251, 79, 232, 160, 211, 22, 237, // N..^..O..... + 14, 181, 65, 9, 107, 211, 85, 178, 176, 101, 146, 136, // ..A.k.U..e.. + 61, 28, 131, 131, 72, 246, 70, 243, 88, 240, 105, 61, // =...H.F.X.i= + 223, 63, 221, 132, 200, 212, 195, 5, 28, 90, 44, 87, // .?.......Z,W + 100, 232, 86, 236, 161, 194, 205, 127, 164, 34, 243, 13, // d.V......".. + 87, 100, 248, 54, 110, 187, 99, 246, 196, 121, 89, 225, // Wd.6n.c..yY. + 213, 180, 220, 95, 155, 113, 145, 105, 194, 137, 57, 189, // ..._.q.i..9. + 67, 87, 122, 191, 166, 114, 99, 133, 100, 8, 93, 151, // CWz..rc.d.]. + 97, 158, 235, 218, 198, 193, 171, 195, 61, 97, 233, 9, // a.......=a.. + 33, 226, 5, 154, 49, 19, 49, 232, 148, 168, 44, 19, // !...1.1...,. + 74, 254, 222, 69, 10, 236, 144, 193, 102, 135, 15, 143, // J..E....f... + 96, 198, 124, 117, 145, 66, 250, 167, 143, 85, 40, 136, // `.|u.B...U(. + 124, 173, 20, 135, 142, 223, 30, 41, 41, 84, 74, 87, // |......))TJW + 102, 247, 71, 183, 200, 160, 138, 242, 26, 232, 201, 243, // f.G......... + 129, 206, 198, 198, 47, 6, 3, 118, 66, 20, 71, 129, // ..../..vB.G. + 5, 227, 147, 1, 179, 130, 92, 46, 190, 10, 230, 219, // ............ + 88, 111, 179, 167, 166, 206, 84, 159, 102, 93, 38, 191, // Xo....T.f]&. + 146, 35, 202, 90, 115, 66, 156, 39, 153, 40, 21, 56, // .#.ZsB.'.(.8 + 86, 205, 20, 246, 137, 9, 170, 86, 228, 215, 105, 250, // V......V..i. + 239, 185, 247, 164, 43, 83, 12, 169, 143, 59, 27, 176, // ....+S...;.. + 183, 133, 93, 34, 156, 75, 165, 193, 41, 86, 177, 226, // ..]".K..)V.. + 148, 3, 167, 227, 115, 125, 58, 126, 255, 133, 167, 246, // ....s}:~.... + 111, 189, 208, 84, 17, 250, 224, 77, 38, 251, 64, 153, // o..T...M&.@. + 142, 188, 171, 220, 227, 111, 4, 197, 151, 185, 27, 87, // .....o.....W + 236, 92, 241, 58, 23, 121, 66, 101, 7, 58, 164, 176, // ...:.yBe.:.. + 251, 40, 88, 130, 248, 144, 156, 243, 77, 122, 190, 48, // .(X.....Mz.0 + 170, 113, 153, 67, 6, 171, 76, 81, 95, 146, 175, 152, // .q.C..LQ_... + 198, 194, 180, 101, 85, 90, 24, 186, 75, 78, 209, 200, // ...eUZ..KN.. + 6, 129, 105, 178, 1, 165, 190, 169, 237, 67, 152, 138, // ..i......C.. + 110, 243, 70, 46, 63, 97, 135, 184, 153, 228, 226, 146, // n.F.?a...... + 211, 166, 115, 30, 48, 182, 189, 201, 219, 198, 94, 16, // ..s.0.....^. + 26, 21, 6, 200, 96, 115, 186, 221, 55, 54, 195, 143, // ....`s..76.. + 69, 187, 223, 167, 219, 99, 145, 187, 72, 64, 198, 177, // E....c..H@.. + 185, 149, 198, 228, 180, 171, 145, 153, 44, 47, 228, 29, // ........,/.. + 160, 80, 131, 108, 40, 106, 160, 216, 189, 186, 73, 232, // .P.l(j....I. + 240, 84, 157, 210, 254, 81, 85, 35, 119, 147, 152, 206, // .T...QU#w... + 70, 74, 205, 104, 8, 0, 212, 138, 186, 184, 89, 141, // FJ.h......Y. + 227, 65, 117, 201, 185, 154, 94, 174, 59, 86, 121, 89, // .Au...^.;VyY + 101, 187, 70, 177, 153, 72, 194, 78, 195, 0, 186, 173, // e.F..H.N.... + 232, 166, 94, 150, 75, 170, 112, 89, 119, 239, 245, 159, // ..^.K.pYw... + 177, 160, 230, 94, 63, 219, 118, 187, 155, 50, 130, 251, // ...^?.v..2.. + 45, 252, 30, 249, 189, 9, 152, 222, 196, 128, 224, 155, // -........... + 37, 235, 200, 78, 131, 190, 198, 200, 183, 241, 154, 239, // %..N........ + 2, 129, 1, 124, 5, 121, 4, 52, 21, 173, 76, 131, // ...|.y.4..L. + 204, 145, 129, 169, 158, 41, 234, 241, 101, 217, 122, 10, // .....)..e.z. + 243, 84, 52, 56, 230, 71, 73, 46, 15, 139, 11, 179, // .T48.GI..... + 71, 210, 203, 62, 133, 75, 153, 172, 148, 163, 140, 199, // G..>.K...... + 48, 140, 100, 231, 71, 37, 65, 211, 93, 201, 190, 171, // 0.d.G%A.]... + 77, 123, 13, 186, 47, 188, 70, 113, 186, 130, 51, 100, // M{../.Fq..3d + 21, 165, 223, 50, 32, 142, 246, 82, 150, 221, 136, 246, // ...2 ..R.... + 175, 105, 174, 74, 146, 131, 196, 231, 10, 27, 156, 102, // .i.J.......f + 114, 19, 210, 170, 174, 61, 31, 233, 94, 254, 15, 133, // r....=..^... + 8, 43, 166, 243, 84, 151, 159, 138, 115, 113, 33, 253, // .+..T...sq!. + 85, 38, 187, 226, 7, 108, 129, 31, 227, 104, 135, 22, // U&...l...h.. + 112, 244, 34, 84, 114, 252, 206, 219, 146, 245, 135, 41, // p."Tr......) + 239, 211, 181, 172, 109, 143, 14, 17, 78, 97, 214, 175, // ....m...Na.. + 171, 251, 64, 124, 5, 111, 197, 23, 251, 205, 2, 72, // ..@|.o.....H + 250, 229, 166, 67, 108, 231, 101, 176, 185, 58, 125, 165, // ...Cl.e..:}. + 84, 22, 185, 8, 157, 194, 192, 247, 145, 58, 220, 214, // T........:.. + 170, 254, 118, 38, 126, 93, 241, 117, 113, 6, 164, 187, // ..v&~].uq... + 232, 127, 32, 168, 46, 153, 242, 24, 43, 34, 227, 81, // .. .....+".Q + 170, 59, 153, 136, 234, 248, 213, 21, 127, 34, 243, 47, // .;......."./ + 167, 171, 185, 62, 209, 44, 144, 93, 64, 148, 37, 114, // ...>.,.]@.%r + 222, 154, 224, 30, 205, 242, 230, 192, 248, 110, 89, 251, // .........nY. + 212, 108, 245, 224, 64, 230, 153, 151, 46, 202, 155, 54, // .l..@......6 + 207, 106, 157, 49, 126, 185, 50, 216, 7, 101, 2, 29, // .j.1~.2..e.. + 168, 78, 122, 158, 38, 142, 47, 23, 194, 190, 4, 140, // .Nz.&./..... + 243, 41, 30, 56, 59, 163, 213, 195, 172, 194, 154, 66, // .).8;......B + 215, 37, 221, 90, 14, 99, 170, 34, 67, 107, 159, 89, // .%.Z.c."Ck.Y + 251, 186, 142, 139, 216, 26, 76, 68, 227, 244, 76, 47, // ......LD..L/ + 187, 77, 151, 95, 45, 38, 24, 201, 219, 254, 202, 220, // .M._-&...... + 210, 125, 178, 171, 122, 208, 81, 89, 157, 119, 47, 219, // .}..z.QY.w/. + 54, 29, 148, 197, 144, 253, 168, 142, 20, 147, 111, 45, // 6.........o- + 118, 26, 241, 21, 194, 151, 119, 250, 86, 37, 227, 182, // v.....w.V%.. + 47, 89, 94, 31, 200, 212, 142, 110, 63, 120, 235, 130, // /Y^....n?x.. + 79, 136, 171, 43, 166, 90, 232, 122, 36, 253, 90, 133, // O..+.Z.z$.Z. + 195, 240, 67, 63, 32, 186, 243, 211, 162, 44, 217, 216, // ..C? ....,.. + 191, 38, 170, 224, 35, 10, 224, 122, 47, 90, 19, 204, // .&..#..z/Z.. + 71, 63, 66, 41, 248, 135, 53, 205, 187, 147, 7, 129, // G?B)..5..... + 57, 168, 123, 26, 180, 225, 160, 94, 4, 75, 151, 143, // 9.{....^.K.. + 210, 89, 184, 11, 231, 77, 243, 96, 252, 86, 203, 186, // .Y...M.`.V.. + 48, 73, 219, 147, 104, 41, 79, 87, 11, 115, 202, 62, // 0I..h)OW.s.> + 62, 42, 177, 216, 244, 29, 10, 198, 140, 239, 78, 226, // >*........N. + 40, 241, 130, 202, 247, 233, 31, 7, 58, 11, 7, 81, // (.......:..Q + 26, 242, 174, 106, 87, 209, 41, 39, 68, 252, 127, 231, // ...jW.)'D... + 89, 87, 40, 102, 56, 0, 0, 0 // YW(f8.. +}; +static const unsigned char v4[] = { + 31, 139, 8, 8, 35, 203, 64, 100, 0, 3, 115, 116, // ....#.@d..st + 121, 108, 101, 46, 99, 115, 115, 0, 117, 84, 203, 110, // yle.css.uT.n + 219, 48, 16, 188, 251, 43, 88, 4, 5, 218, 32, 82, // .0...+X... R + 44, 41, 178, 99, 249, 210, 91, 63, 162, 232, 129, 18, // ,).c..[?.... + 87, 54, 17, 138, 84, 73, 58, 118, 90, 248, 223, 187, // W6..TI:vZ... + 164, 30, 164, 226, 228, 98, 75, 187, 163, 125, 204, 12, // .....bK..}.. + 121, 79, 254, 145, 90, 93, 18, 195, 255, 114, 121, 168, // yO..Z]...ry. + 240, 89, 51, 208, 9, 134, 246, 228, 186, 58, 218, 78, // .Y3......:.N + 60, 96, 140, 189, 33, 172, 163, 250, 192, 101, 69, 214, // <`..!....eE. + 123, 210, 83, 198, 60, 28, 159, 143, 192, 15, 71, 91, // {.S.<.....G[ + 145, 108, 189, 254, 186, 39, 173, 146, 238, 121, 211, 95, // .l...'...y._ + 136, 161, 210, 36, 6, 52, 111, 93, 41, 3, 2, 26, // ...$.4o])... + 251, 64, 184, 236, 79, 248, 39, 104, 13, 162, 170, 106, // .@..O.'h...j + 104, 149, 134, 7, 98, 225, 98, 169, 6, 138, 109, 212, // h...b.b...m. + 201, 10, 46, 161, 34, 82, 73, 216, 15, 195, 29, 41, // ...."RI....) + 83, 231, 202, 5, 200, 23, 222, 245, 74, 91, 42, 237, // S.......J[*. + 126, 28, 22, 219, 185, 110, 74, 112, 70, 238, 154, 166, // ~....nJpF... + 89, 64, 174, 171, 70, 49, 108, 208, 107, 192, 218, 141, // Y@..F1l.k... + 18, 10, 241, 119, 197, 182, 24, 70, 77, 90, 218, 113, // ...w...FMZ.q + 241, 86, 145, 78, 73, 101, 122, 218, 192, 24, 63, 143, // .V.NIez...?. + 91, 213, 74, 96, 139, 49, 136, 36, 225, 92, 166, 163, // [.J`.1.$.... + 66, 184, 88, 77, 155, 151, 131, 86, 39, 201, 176, 36, // B.XM...V'..$ + 99, 44, 230, 37, 205, 160, 195, 223, 2, 186, 105, 204, // c,.%......i. + 68, 83, 198, 79, 198, 229, 114, 23, 189, 174, 166, 165, // DS.O..r..... + 103, 82, 82, 252, 92, 73, 156, 51, 234, 150, 149, 253, // gRR..I.3.... + 229, 179, 77, 23, 13, 203, 161, 40, 86, 163, 213, 43, // ..M....(V..+ + 55, 220, 2, 115, 143, 180, 177, 252, 53, 222, 189, 44, // 7..s....5.., + 189, 30, 115, 175, 197, 22, 0, 72, 0, 233, 184, 76, // ..s....H...L + 206, 156, 217, 99, 69, 118, 88, 21, 193, 181, 69, 232, // ...cEvX...E. + 138, 44, 193, 126, 130, 155, 229, 162, 149, 189, 63, 166, // .,.~......?. + 190, 109, 139, 125, 155, 147, 54, 238, 173, 87, 92, 90, // .m.}..6..W.Z + 228, 16, 75, 50, 110, 122, 65, 81, 2, 46, 157, 238, // ..K2nzAQ.... + 73, 45, 84, 243, 178, 216, 108, 131, 84, 122, 202, 62, // I-T...l.Tz.> + 82, 102, 53, 76, 247, 11, 203, 208, 90, 0, 251, 237, // Rf5L....Z... + 44, 132, 66, 114, 251, 230, 89, 9, 61, 233, 201, 42, // ,.Br..Y.=..* + 183, 139, 233, 148, 178, 71, 132, 89, 141, 14, 229, 150, // .....G.Y.... + 43, 52, 53, 74, 74, 210, 220, 120, 102, 26, 108, 67, // +45JJ..xf.lC + 113, 20, 29, 155, 158, 228, 107, 39, 196, 72, 139, 175, // q.....k'.H.. + 229, 176, 44, 105, 5, 92, 16, 56, 175, 225, 222, 199, // ..,i...8.... + 148, 55, 108, 148, 26, 28, 237, 6, 246, 244, 248, 163, // .7l......... + 119, 163, 171, 55, 18, 98, 60, 203, 192, 102, 80, 68, // w..7.b<..fPD + 241, 40, 117, 42, 213, 89, 211, 30, 17, 231, 35, 202, // .(u*.Y....#. + 157, 120, 255, 186, 46, 46, 234, 1, 157, 57, 188, 87, // .x.......9.W + 152, 65, 59, 139, 38, 160, 69, 34, 203, 208, 187, 220, // .A;.&.E".... + 177, 91, 79, 69, 102, 220, 185, 35, 62, 81, 226, 29, // .[OEf..#>Q.. + 238, 219, 24, 60, 217, 220, 155, 41, 208, 149, 141, 51, // ...<...)...3 + 90, 213, 243, 6, 173, 205, 168, 69, 107, 166, 127, 148, // Z......Ek... + 65, 88, 220, 35, 247, 7, 165, 252, 240, 160, 60, 185, // AX.#......<. + 232, 80, 51, 209, 131, 236, 35, 212, 149, 30, 106, 45, // .P3...#...j- + 253, 219, 210, 208, 245, 125, 178, 133, 33, 233, 70, 121, // .....}..!.Fy + 159, 163, 224, 79, 197, 234, 241, 158, 252, 212, 72, 197, // ...O......H. + 253, 163, 83, 224, 124, 43, 172, 251, 77, 28, 193, 21, // ..S.|+..M... + 153, 105, 70, 139, 127, 126, 63, 170, 87, 208, 173, 192, // .iF..~?.W... + 235, 43, 152, 6, 241, 73, 150, 59, 221, 6, 55, 13, // .+...I.;..7. + 87, 231, 148, 200, 66, 98, 151, 165, 155, 77, 148, 90, // W...Bb...M.Z + 135, 212, 115, 145, 22, 69, 72, 237, 66, 102, 91, 134, // ..s..EH.Bf[. + 240, 115, 8, 111, 54, 139, 90, 219, 144, 41, 159, 23, // .s.o6.Z..).. + 165, 54, 81, 38, 154, 171, 12, 225, 167, 229, 88, 79, // .6Q&......XO + 33, 83, 44, 167, 42, 66, 38, 143, 166, 138, 87, 95, // !S,.*B&...W_ + 78, 21, 237, 62, 15, 245, 163, 3, 198, 41, 249, 22, // N..>.....).. + 221, 74, 89, 145, 225, 105, 252, 142, 224, 15, 15, 235, // .JY..i...... + 64, 244, 132, 205, 183, 254, 228, 94, 227, 82, 244, 50, // @......^.R.2 + 95, 112, 249, 84, 201, 201, 61, 74, 185, 212, 5, 63, // _p.T..=J...? + 252, 15, 225, 232, 67, 124, 39, 7, 0, 0, 0 // ....C|'... +}; +static const unsigned char v5[] = { + 31, 139, 8, 8, 35, 203, 64, 100, 0, 3, 112, 114, // ....#.@d..pr 101, 97, 99, 116, 46, 109, 105, 110, 46, 106, 115, 0, // eact.min.js. 157, 91, 123, 119, 219, 182, 146, 255, 127, 63, 69, 164, // .[{w.....?E. 211, 163, 18, 43, 68, 177, 147, 182, 187, 75, 5, 213, // ...+D....K.. @@ -865,805 +1272,6 @@ static const unsigned char v3[] = { 14, 139, 221, 126, 250, 31, 255, 11, 22, 19, 178, 116, // ...~.......t 138, 51, 0, 0, 0 // .3.. }; -static const unsigned char v4[] = { - 31, 139, 8, 8, 255, 98, 56, 100, 0, 3, 115, 116, // .....b8d..st - 121, 108, 101, 46, 99, 115, 115, 0, 117, 84, 203, 110, // yle.css.uT.n - 219, 48, 16, 188, 251, 43, 88, 4, 5, 218, 32, 82, // .0...+X... R - 44, 41, 178, 99, 249, 210, 91, 63, 162, 232, 129, 18, // ,).c..[?.... - 87, 54, 17, 138, 84, 73, 58, 118, 90, 248, 223, 187, // W6..TI:vZ... - 164, 30, 164, 226, 228, 98, 75, 187, 163, 125, 204, 12, // .....bK..}.. - 121, 79, 254, 145, 90, 93, 18, 195, 255, 114, 121, 168, // yO..Z]...ry. - 240, 89, 51, 208, 9, 134, 246, 228, 186, 58, 218, 78, // .Y3......:.N - 60, 96, 140, 189, 33, 172, 163, 250, 192, 101, 69, 214, // <`..!....eE. - 123, 210, 83, 198, 60, 28, 159, 143, 192, 15, 71, 91, // {.S.<.....G[ - 145, 108, 189, 254, 186, 39, 173, 146, 238, 121, 211, 95, // .l...'...y._ - 136, 161, 210, 36, 6, 52, 111, 93, 41, 3, 2, 26, // ...$.4o])... - 251, 64, 184, 236, 79, 248, 39, 104, 13, 162, 170, 106, // .@..O.'h...j - 104, 149, 134, 7, 98, 225, 98, 169, 6, 138, 109, 212, // h...b.b...m. - 201, 10, 46, 161, 34, 82, 73, 216, 15, 195, 29, 41, // ...."RI....) - 83, 231, 202, 5, 200, 23, 222, 245, 74, 91, 42, 237, // S.......J[*. - 126, 28, 22, 219, 185, 110, 74, 112, 70, 238, 154, 166, // ~....nJpF... - 89, 64, 174, 171, 70, 49, 108, 208, 107, 192, 218, 141, // Y@..F1l.k... - 18, 10, 241, 119, 197, 182, 24, 70, 77, 90, 218, 113, // ...w...FMZ.q - 241, 86, 145, 78, 73, 101, 122, 218, 192, 24, 63, 143, // .V.NIez...?. - 91, 213, 74, 96, 139, 49, 136, 36, 225, 92, 166, 163, // [.J`.1.$.... - 66, 184, 88, 77, 155, 151, 131, 86, 39, 201, 176, 36, // B.XM...V'..$ - 99, 44, 230, 37, 205, 160, 195, 223, 2, 186, 105, 204, // c,.%......i. - 68, 83, 198, 79, 198, 229, 114, 23, 189, 174, 166, 165, // DS.O..r..... - 103, 82, 82, 252, 92, 73, 156, 51, 234, 150, 149, 253, // gRR..I.3.... - 229, 179, 77, 23, 13, 203, 161, 40, 86, 163, 213, 43, // ..M....(V..+ - 55, 220, 2, 115, 143, 180, 177, 252, 53, 222, 189, 44, // 7..s....5.., - 189, 30, 115, 175, 197, 22, 0, 72, 0, 233, 184, 76, // ..s....H...L - 206, 156, 217, 99, 69, 118, 88, 21, 193, 181, 69, 232, // ...cEvX...E. - 138, 44, 193, 126, 130, 155, 229, 162, 149, 189, 63, 166, // .,.~......?. - 190, 109, 139, 125, 155, 147, 54, 238, 173, 87, 92, 90, // .m.}..6..W.Z - 228, 16, 75, 50, 110, 122, 65, 81, 2, 46, 157, 238, // ..K2nzAQ.... - 73, 45, 84, 243, 178, 216, 108, 131, 84, 122, 202, 62, // I-T...l.Tz.> - 82, 102, 53, 76, 247, 11, 203, 208, 90, 0, 251, 237, // Rf5L....Z... - 44, 132, 66, 114, 251, 230, 89, 9, 61, 233, 201, 42, // ,.Br..Y.=..* - 183, 139, 233, 148, 178, 71, 132, 89, 141, 14, 229, 150, // .....G.Y.... - 43, 52, 53, 74, 74, 210, 220, 120, 102, 26, 108, 67, // +45JJ..xf.lC - 113, 20, 29, 155, 158, 228, 107, 39, 196, 72, 139, 175, // q.....k'.H.. - 229, 176, 44, 105, 5, 92, 16, 56, 175, 225, 222, 199, // ..,i...8.... - 148, 55, 108, 148, 26, 28, 237, 6, 246, 244, 248, 163, // .7l......... - 119, 163, 171, 55, 18, 98, 60, 203, 192, 102, 80, 68, // w..7.b<..fPD - 241, 40, 117, 42, 213, 89, 211, 30, 17, 231, 35, 202, // .(u*.Y....#. - 157, 120, 255, 186, 46, 46, 234, 1, 157, 57, 188, 87, // .x.......9.W - 152, 65, 59, 139, 38, 160, 69, 34, 203, 208, 187, 220, // .A;.&.E".... - 177, 91, 79, 69, 102, 220, 185, 35, 62, 81, 226, 29, // .[OEf..#>Q.. - 238, 219, 24, 60, 217, 220, 155, 41, 208, 149, 141, 51, // ...<...)...3 - 90, 213, 243, 6, 173, 205, 168, 69, 107, 166, 127, 148, // Z......Ek... - 65, 88, 220, 35, 247, 7, 165, 252, 240, 160, 60, 185, // AX.#......<. - 232, 80, 51, 209, 131, 236, 35, 212, 149, 30, 106, 45, // .P3...#...j- - 253, 219, 210, 208, 245, 125, 178, 133, 33, 233, 70, 121, // .....}..!.Fy - 159, 163, 224, 79, 197, 234, 241, 158, 252, 212, 72, 197, // ...O......H. - 253, 163, 83, 224, 124, 43, 172, 251, 77, 28, 193, 21, // ..S.|+..M... - 153, 105, 70, 139, 127, 126, 63, 170, 87, 208, 173, 192, // .iF..~?.W... - 235, 43, 152, 6, 241, 73, 150, 59, 221, 6, 55, 13, // .+...I.;..7. - 87, 231, 148, 200, 66, 98, 151, 165, 155, 77, 148, 90, // W...Bb...M.Z - 135, 212, 115, 145, 22, 69, 72, 237, 66, 102, 91, 134, // ..s..EH.Bf[. - 240, 115, 8, 111, 54, 139, 90, 219, 144, 41, 159, 23, // .s.o6.Z..).. - 165, 54, 81, 38, 154, 171, 12, 225, 167, 229, 88, 79, // .6Q&......XO - 33, 83, 44, 167, 42, 66, 38, 143, 166, 138, 87, 95, // !S,.*B&...W_ - 78, 21, 237, 62, 15, 245, 163, 3, 198, 41, 249, 22, // N..>.....).. - 221, 74, 89, 145, 225, 105, 252, 142, 224, 15, 15, 235, // .JY..i...... - 64, 244, 132, 205, 183, 254, 228, 94, 227, 82, 244, 50, // @......^.R.2 - 95, 112, 249, 84, 201, 201, 61, 74, 185, 212, 5, 63, // _p.T..=J...? - 252, 15, 225, 232, 67, 124, 39, 7, 0, 0, 0 // ....C|'... -}; -static const unsigned char v5[] = { - 31, 139, 8, 8, 255, 98, 56, 100, 0, 3, 117, 115, // .....b8d..us - 101, 114, 46, 112, 110, 103, 0, 1, 16, 15, 239, 240, // er.png...... - 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, // .PNG........ - 73, 72, 68, 82, 0, 0, 0, 128, 0, 0, 0, 128, // IHDR........ - 8, 6, 0, 0, 0, 195, 62, 97, 203, 0, 0, 0, // ......>a.... - 4, 115, 66, 73, 84, 8, 8, 8, 8, 124, 8, 100, // .sBIT....|.d - 136, 0, 0, 0, 9, 112, 72, 89, 115, 0, 0, 30, // .....pHYs... - 140, 0, 0, 30, 140, 1, 53, 120, 124, 169, 0, 0, // ......5x|... - 0, 25, 116, 69, 88, 116, 83, 111, 102, 116, 119, 97, // ..tEXtSoftwa - 114, 101, 0, 119, 119, 119, 46, 105, 110, 107, 115, 99, // re.www.inksc - 97, 112, 101, 46, 111, 114, 103, 155, 238, 60, 26, 0, // ape.org..<.. - 0, 14, 141, 73, 68, 65, 84, 120, 218, 237, 157, 125, // ...IDATx...} - 112, 20, 229, 29, 199, 97, 100, 232, 76, 117, 232, 63, // p....ad.Lu.? - 117, 250, 15, 163, 157, 206, 104, 197, 247, 42, 173, 56, // u.....h..*.8 - 19, 234, 12, 180, 82, 35, 32, 160, 132, 18, 94, 242, // ....R# ...^. - 102, 18, 18, 67, 184, 75, 46, 111, 151, 203, 93, 238, // f..C.K.o..]. - 37, 151, 219, 187, 203, 27, 16, 224, 242, 166, 80, 17, // %.........P. - 9, 18, 4, 5, 35, 90, 130, 32, 146, 8, 113, 152, // ....#Z. ..q. - 193, 106, 153, 90, 108, 173, 213, 42, 104, 71, 163, 130, // .j.Zl..*hG.. - 81, 242, 235, 243, 219, 238, 198, 75, 184, 75, 238, 246, // Q......K.K.. - 158, 221, 125, 118, 111, 255, 248, 206, 56, 2, 123, 191, // ..}vo...8.{. - 223, 247, 251, 185, 219, 231, 217, 125, 246, 217, 41, 0, // .......}..). - 48, 69, 111, 186, 169, 199, 55, 131, 104, 54, 209, 170, // 0Eo...7.h6.. - 187, 158, 171, 247, 154, 186, 108, 131, 142, 192, 250, 79, // ......l....O - 157, 174, 252, 175, 92, 213, 217, 195, 181, 165, 171, 175, // ............ - 88, 11, 211, 192, 156, 181, 24, 214, 175, 89, 8, 150, // X........Y.. - 156, 165, 96, 45, 88, 62, 82, 107, 74, 191, 226, 173, // ..`-X>RkJ... - 205, 251, 198, 209, 108, 254, 40, 191, 171, 186, 255, 190, // ....l.(..... - 110, 175, 31, 143, 33, 28, 107, 134, 30, 189, 210, 67, // n...!.k....C - 216, 215, 18, 45, 32, 226, 136, 250, 136, 62, 186, 127, // ...- ....>.. - 167, 19, 138, 55, 150, 130, 179, 58, 27, 74, 178, 150, // ...7...:.J.. - 192, 19, 171, 30, 150, 36, 132, 195, 97, 74, 135, 234, // .....$..aJ.. - 102, 51, 204, 221, 93, 7, 120, 108, 225, 51, 56, 225, // f3..].xl.38. - 51, 175, 53, 0, 80, 62, 240, 233, 68, 243, 136, 60, // 3.5.P>..D..< - 68, 39, 136, 134, 137, 48, 28, 88, 183, 195, 14, 238, // D'...0.X.... - 170, 76, 201, 129, 79, 164, 226, 53, 139, 192, 83, 147, // .L..O..5..S. - 3, 185, 157, 86, 184, 69, 248, 60, 225, 179, 177, 6, // ...V.E.<.... - 183, 80, 211, 116, 3, 0, 249, 130, 159, 67, 212, 74, // .P.t.....C.J - 244, 217, 77, 63, 4, 192, 107, 77, 187, 21, 156, 101, // ..M?..kM...e - 107, 100, 9, 62, 146, 170, 159, 72, 131, 188, 14, 43, // kd.>...H...+ - 140, 175, 67, 168, 13, 107, 156, 99, 0, 64, 39, 244, // ..C..k.c.@'. - 27, 137, 108, 68, 231, 34, 152, 13, 139, 119, 214, 130, // ..lD."...w.. - 205, 156, 174, 88, 240, 227, 229, 182, 102, 195, 31, 158, // ...X....f... - 113, 69, 2, 1, 132, 154, 177, 246, 27, 13, 0, 226, // qE.......... - 15, 30, 7, 93, 61, 68, 35, 145, 204, 253, 37, 81, // ...]=D#...%Q - 93, 171, 5, 76, 25, 139, 85, 11, 95, 212, 134, 140, // ]..L..U._... - 69, 96, 15, 20, 195, 173, 61, 222, 104, 32, 140, 8, // E`....=.h .. - 189, 204, 54, 0, 152, 60, 248, 185, 68, 189, 81, 140, // ..6..<..D.Q. - 228, 245, 235, 221, 110, 242, 205, 203, 82, 61, 248, 241, // ....n...R=.. - 114, 149, 103, 192, 125, 221, 117, 48, 81, 237, 66, 111, // r.g.}.u0Q.Bo - 115, 13, 0, 174, 14, 126, 62, 209, 177, 73, 204, 131, // s....~>..I.. - 212, 237, 118, 176, 228, 46, 99, 46, 252, 240, 177, 193, // ..v...c..... - 195, 207, 56, 39, 131, 0, 132, 94, 231, 39, 61, 0, // ..8'...^.'=. - 196, 132, 153, 68, 123, 98, 48, 12, 214, 144, 243, 61, // ...D{b0....= - 206, 215, 89, 13, 95, 148, 37, 103, 9, 100, 62, 105, // ..Y._.%g.d>i - 139, 5, 2, 16, 122, 159, 153, 116, 0, 144, 166, 167, // ....z..t.... - 17, 149, 18, 13, 197, 98, 212, 202, 167, 93, 80, 166, // .....b...]P. - 129, 240, 195, 199, 5, 171, 159, 178, 199, 10, 193, 144, // ............ - 224, 197, 180, 164, 0, 128, 52, 154, 66, 116, 54, 70, // ......4.Bt6F - 115, 224, 193, 63, 57, 160, 236, 113, 237, 132, 47, 10, // s..?9..q../. - 129, 77, 141, 62, 67, 136, 36, 244, 36, 69, 183, 0, // .M.>C.$.$E.. - 144, 230, 174, 33, 242, 70, 27, 217, 71, 210, 189, 187, // ...!.F..G... - 61, 80, 158, 247, 168, 230, 194, 15, 31, 19, 220, 223, // =P.......... - 237, 141, 7, 130, 17, 193, 163, 107, 116, 5, 128, 112, // .......kt..p - 174, 63, 30, 135, 17, 112, 51, 145, 199, 158, 163, 217, // .?...p3..... - 240, 69, 225, 5, 170, 219, 247, 214, 199, 3, 1, 8, // .E.......... - 94, 205, 212, 5, 0, 164, 145, 84, 162, 139, 113, 26, // ^......T..q. - 0, 174, 182, 74, 205, 135, 47, 202, 214, 104, 142, 23, // ...J../..h.. - 0, 16, 60, 75, 213, 44, 0, 164, 248, 169, 68, 190, // ..9.......;. - 241, 236, 166, 244, 68, 0, 0, 193, 219, 235, 153, 4, // ....D....... - 128, 20, 118, 67, 180, 187, 118, 177, 42, 135, 156, 39, // ..vC..v.*..' - 99, 49, 82, 41, 237, 110, 40, 158, 48, 252, 112, 253, // c1R).n(.0.p. - 253, 80, 16, 26, 202, 39, 63, 117, 165, 237, 112, 36, // .P...'?u..p$ - 10, 1, 122, 124, 3, 83, 0, 8, 223, 252, 115, 9, // ..z|.S....s. - 54, 6, 245, 206, 60, 102, 194, 223, 219, 108, 142, 57, // 6....^_.... - 57, 255, 84, 162, 77, 221, 189, 187, 142, 95, 130, 197, // 9.T.M...._.. - 66, 248, 47, 135, 42, 36, 133, 47, 234, 235, 55, 219, // B./.*$./..7. - 160, 203, 179, 46, 226, 177, 77, 153, 143, 192, 189, 207, // ......M..... - 121, 105, 64, 112, 138, 198, 152, 128, 198, 104, 255, 48, // yi@p.....h.0 - 133, 102, 32, 63, 134, 121, 127, 45, 249, 102, 53, 85, // .f ?.y.-.f5U - 102, 192, 166, 234, 108, 216, 230, 200, 133, 14, 87, 62, // f...l.....W> - 116, 56, 243, 193, 74, 233, 106, 97, 197, 227, 75, 225, // t8..J.ja..K. - 196, 211, 142, 132, 194, 15, 215, 159, 59, 172, 17, 161, // ........;... - 46, 219, 92, 70, 3, 0, 113, 96, 56, 93, 21, 0, // ...F..q`8].. - 132, 121, 254, 46, 74, 141, 128, 187, 174, 32, 98, 40, // .y..J.... b( - 229, 57, 75, 225, 217, 96, 49, 156, 127, 169, 97, 66, // .9K..`1...aB - 179, 255, 249, 114, 19, 255, 205, 109, 169, 202, 140, 107, // ...r...m...k - 100, 142, 170, 204, 91, 6, 135, 67, 149, 240, 245, 64, // d...[..C...@ - 136, 90, 248, 162, 206, 189, 192, 241, 199, 31, 187, 146, // .Z.......... - 40, 139, 22, 0, 226, 20, 113, 170, 26, 0, 248, 104, // (.....q....h - 53, 129, 43, 124, 106, 158, 72, 27, 99, 82, 77, 193, // 5.+|j.H.cRM. - 114, 24, 236, 118, 195, 229, 211, 237, 113, 155, 254, 85, // r..v....q..U - 127, 27, 188, 185, 203, 9, 237, 174, 60, 176, 100, 95, // ........<.d_ - 125, 65, 169, 120, 237, 34, 112, 21, 175, 132, 182, 218, // }A.x."p..... - 92, 56, 210, 105, 133, 111, 200, 79, 54, 237, 224, 195, // .8.i.o.O6... - 117, 241, 88, 43, 4, 44, 63, 172, 89, 44, 207, 93, // u.X+.,?.Y,.] - 70, 19, 0, 148, 79, 81, 0, 132, 203, 187, 35, 180, // F...OQ....#. - 26, 88, 209, 93, 55, 38, 160, 96, 217, 90, 248, 252, // .X.]7&.`.Z.. - 245, 86, 106, 1, 124, 121, 114, 27, 124, 248, 74, 19, // .Vj.|yr.|.J. - 188, 187, 159, 131, 143, 143, 108, 132, 111, 199, 205, 235, // ......l.o... - 149, 16, 66, 233, 43, 89, 61, 218, 35, 94, 237, 164, // ..B.+Y=.#^.. - 8, 192, 136, 212, 203, 198, 82, 111, 236, 92, 164, 73, // ......Ro...I - 176, 169, 203, 54, 106, 204, 83, 228, 84, 112, 233, 205, // ...6j.S.Tp.. - 118, 197, 3, 82, 66, 8, 181, 67, 252, 165, 11, 85, // v..RB..C...U - 209, 254, 21, 184, 40, 229, 6, 146, 148, 91, 186, 199, // ....(....[.. - 41, 23, 14, 190, 87, 91, 96, 179, 45, 7, 14, 110, // )...W[`.-..n - 41, 211, 101, 240, 225, 250, 79, 223, 70, 126, 76, 224, // ).e...O.F~L. - 224, 138, 104, 3, 32, 222, 69, 188, 70, 78, 0, 188, // ..h. .E.FN.. - 50, 20, 13, 93, 71, 55, 203, 126, 30, 102, 73, 239, // 2..]G7.~.fI. - 247, 54, 128, 215, 153, 39, 7, 0, 40, 175, 44, 0, // .6...'..(.,. - 8, 43, 121, 70, 228, 40, 250, 197, 227, 91, 146, 38, // .+yF.(...[.& - 124, 81, 7, 122, 155, 228, 2, 96, 36, 158, 149, 69, // |Q.z...`$..E - 241, 172, 225, 59, 43, 83, 193, 48, 240, 198, 182, 164, // ...;+S.0.... - 3, 224, 216, 137, 173, 114, 1, 32, 46, 47, 155, 70, // .....r. ./.F - 19, 128, 82, 25, 139, 133, 243, 73, 244, 243, 47, 106, // ..R....I../j - 128, 204, 76, 228, 244, 20, 51, 163, 2, 128, 48, 234, // ..L...3...0. - 31, 50, 0, 160, 171, 51, 253, 33, 185, 1, 24, 138, // .2...3.!.... - 101, 86, 16, 11, 0, 123, 100, 46, 20, 6, 79, 38, // eV...{d...O& - 223, 41, 224, 221, 1, 217, 1, 224, 159, 59, 72, 8, // .).......;H. - 0, 225, 137, 29, 217, 11, 125, 149, 156, 15, 147, 13, // ......}..... - 128, 83, 242, 159, 2, 68, 205, 79, 4, 128, 99, 74, // .S...D.O..cJ - 20, 185, 231, 88, 107, 242, 205, 2, 200, 204, 71, 33, // ...Xk.....G! - 0, 142, 73, 2, 64, 120, 80, 83, 145, 34, 219, 142, // ..I.@xPS.".. - 110, 78, 58, 0, 66, 125, 155, 148, 2, 0, 38, 122, // nN:.B}....&z - 32, 117, 34, 0, 122, 149, 42, 176, 246, 213, 150, 164, // u".z.*..... - 3, 0, 123, 86, 16, 128, 222, 184, 0, 16, 158, 207, // ..{V........ - 87, 172, 192, 180, 131, 13, 73, 7, 64, 94, 111, 163, // W.....I.@^o. - 146, 0, 64, 180, 253, 9, 162, 1, 208, 163, 100, 113, // ..@.......dq - 119, 236, 227, 224, 114, 146, 1, 176, 240, 197, 160, 210, // w...r....... - 0, 244, 196, 4, 128, 176, 45, 203, 136, 194, 197, 193, // ......-..... - 95, 7, 146, 231, 90, 192, 215, 131, 29, 112, 59, 129, // _...Z....p;. - 94, 97, 143, 71, 34, 109, 87, 19, 9, 0, 155, 210, // ^a.G"mW..... - 225, 163, 246, 38, 209, 76, 224, 228, 27, 219, 64, 13, // ...&.L....@. - 143, 49, 219, 88, 0, 56, 167, 70, 113, 206, 36, 26, // .1.X.8.Fq.$. - 8, 54, 31, 217, 164, 22, 0, 231, 38, 4, 64, 216, // .6......&.@. - 138, 77, 149, 226, 230, 29, 8, 36, 13, 0, 233, 135, // .M.....$.... - 26, 212, 2, 0, 198, 111, 97, 55, 30, 128, 86, 21, // .....oa7..V. - 11, 131, 191, 244, 135, 116, 31, 254, 87, 228, 252, 127, // .....t..W... - 155, 242, 231, 255, 112, 109, 137, 8, 128, 176, 196, 251, // ....pm...... - 51, 53, 1, 104, 33, 63, 141, 122, 7, 224, 117, 245, // 35.h!?.z..u. - 206, 255, 225, 155, 89, 78, 143, 4, 192, 60, 149, 11, // ....YN...<.. - 131, 69, 100, 106, 164, 119, 0, 188, 202, 94, 0, 138, // .Edj.w...^.. - 166, 121, 145, 0, 240, 48, 80, 24, 188, 175, 227, 91, // .y...0P....[ - 195, 151, 6, 59, 225, 190, 253, 126, 22, 0, 240, 68, // ...;...~...D - 2, 224, 4, 11, 0, 180, 246, 233, 247, 52, 112, 232, // .........4p. - 245, 45, 44, 132, 143, 58, 49, 6, 0, 97, 203, 245, // .-,..:1..a.. - 97, 22, 138, 75, 33, 223, 16, 252, 166, 232, 17, 128, // a..K!....... - 156, 151, 26, 89, 1, 96, 88, 220, 234, 94, 4, 96, // ...Y.`X..^.` - 1, 35, 133, 241, 218, 167, 195, 69, 162, 31, 158, 106, // .#.....E...j - 15, 223, 102, 158, 5, 45, 8, 7, 128, 99, 9, 128, // ..f..-...c.. - 37, 58, 28, 12, 110, 238, 219, 196, 82, 248, 40, 46, // %:..n...R.(. - 28, 128, 62, 198, 138, 131, 126, 29, 173, 20, 30, 34, // ..>...~...." - 115, 255, 148, 3, 126, 214, 0, 232, 11, 7, 224, 35, // s...~......# - 214, 0, 200, 239, 109, 210, 13, 0, 173, 236, 125, 251, // ....m.....}. - 249, 215, 223, 240, 0, 8, 47, 88, 98, 177, 64, 254, // ....../Xb.@. - 166, 137, 214, 195, 255, 148, 156, 251, 127, 245, 60, 7, // ..........<. - 140, 122, 60, 67, 241, 197, 31, 241, 8, 239, 153, 95, // .z../.. - 127, 180, 228, 66, 0, 118, 50, 94, 36, 84, 191, 210, // ...B.v2^$T.. - 172, 185, 240, 119, 189, 214, 202, 122, 248, 168, 157, 8, // ...w...z.... - 192, 65, 13, 20, 170, 169, 39, 136, 241, 182, 246, 29, // .A....'..... - 251, 56, 45, 0, 112, 112, 138, 28, 27, 62, 200, 161, // .8-.pp...>.. - 187, 200, 169, 64, 11, 235, 6, 191, 56, 221, 1, 15, // ...@....8... - 190, 16, 208, 66, 248, 252, 134, 18, 8, 192, 25, 141, // ...B........ - 20, 11, 191, 39, 198, 254, 247, 116, 7, 211, 0, 152, // ...'...t.... - 95, 110, 210, 74, 248, 168, 51, 8, 192, 121, 13, 21, // _n.J..3..y.. - 12, 235, 200, 192, 106, 152, 209, 240, 219, 143, 110, 214, // ....j.....n. - 82, 248, 168, 243, 8, 192, 5, 141, 21, 13, 86, 50, // R.........V2 - 40, 100, 237, 250, 64, 211, 145, 141, 90, 11, 31, 117, // (d..@...Z..u - 1, 1, 248, 86, 131, 133, 67, 110, 111, 35, 127, 141, // ...V..Cno#.. - 93, 237, 224, 191, 37, 194, 89, 138, 22, 61, 196, 236, // ]...%.Y..=.. - 53, 11, 0, 106, 217, 193, 32, 124, 114, 74, 189, 107, // 5..j.. |rJ.k - 4, 248, 128, 71, 97, 111, 147, 86, 195, 31, 5, 224, // ...Gao.V.... - 130, 134, 27, 128, 249, 100, 96, 120, 90, 133, 13, 38, // .....d`xZ..& - 240, 249, 126, 4, 80, 203, 222, 137, 167, 128, 243, 26, // ..~.P....... - 111, 130, 87, 1, 249, 38, 158, 83, 96, 154, 248, 55, // o.W..&.S`..7 - 242, 25, 26, 255, 214, 95, 53, 8, 60, 163, 147, 102, // ....._5.<..f - 248, 21, 55, 85, 228, 124, 252, 177, 12, 167, 5, 188, // ..7U.|...... - 28, 109, 123, 165, 5, 110, 217, 231, 211, 75, 248, 163, // .m{..n...K.. - 211, 192, 227, 58, 106, 136, 215, 156, 253, 126, 126, 23, // ...:j....~~. - 46, 90, 225, 191, 117, 50, 4, 115, 217, 91, 208, 65, // .Z..u2.s.[.A - 237, 66, 208, 65, 29, 54, 6, 11, 94, 160, 247, 168, // .B.A.6..^... - 217, 162, 23, 131, 122, 12, 127, 244, 82, 240, 78, 157, // ....z...R.N. - 54, 7, 255, 160, 240, 140, 1, 30, 67, 175, 254, 136, // 6.......C... - 55, 131, 92, 122, 109, 240, 109, 10, 207, 26, 190, 221, // 7..zm.m..... - 31, 210, 51, 0, 46, 230, 23, 132, 72, 213, 61, 207, // ..3.....H.=. - 115, 252, 141, 25, 26, 55, 119, 238, 121, 158, 211, 43, // s....7w.y..+ - 0, 171, 152, 94, 18, 150, 208, 43, 104, 40, 238, 55, // ...^...+h(.7 - 224, 102, 123, 89, 87, 194, 75, 194, 102, 232, 169, 169, // .f{YW.K.f... - 7, 14, 4, 248, 85, 184, 159, 83, 188, 107, 136, 199, // ....U..S.k.. - 194, 99, 226, 177, 117, 6, 192, 12, 213, 151, 133, 63, // .c..u......? - 176, 155, 131, 194, 173, 126, 176, 4, 57, 40, 243, 248, // .....~..9(.. - 160, 164, 218, 11, 69, 37, 30, 200, 90, 231, 130, 244, // ....E%..Z... - 28, 39, 172, 140, 162, 154, 234, 122, 248, 172, 191, 157, // .'.....z.... - 191, 28, 27, 46, 57, 239, 20, 14, 11, 151, 127, 195, // ....9....... - 133, 53, 96, 45, 209, 234, 196, 30, 176, 23, 236, 9, // .5`-........ - 123, 195, 30, 177, 87, 236, 25, 123, 87, 125, 89, 184, // {...W..{W}Y. - 210, 15, 134, 204, 218, 235, 131, 21, 219, 73, 224, 13, // .........I.. - 28, 20, 149, 214, 193, 242, 204, 90, 201, 178, 89, 235, // .......Z..Y. - 97, 104, 64, 189, 27, 66, 248, 217, 88, 67, 34, 61, // ah@..B..XC"= - 160, 7, 232, 5, 122, 130, 222, 168, 245, 96, 136, 236, // ....z....`.. - 143, 134, 205, 34, 66, 234, 243, 139, 221, 9, 25, 198, // ..."B....... - 10, 4, 52, 194, 31, 47, 244, 6, 61, 154, 165, 194, // ..4../..=... - 163, 97, 11, 228, 12, 190, 96, 27, 253, 224, 213, 132, // .a....`..... - 64, 142, 240, 199, 131, 128, 158, 201, 12, 194, 2, 217, // @........... - 31, 15, 95, 246, 180, 31, 10, 54, 120, 100, 51, 74, // .._....6xd3J - 13, 8, 228, 14, 63, 92, 232, 29, 122, 40, 251, 227, // ....?...z(.. - 225, 114, 108, 16, 177, 190, 213, 207, 15, 130, 148, 48, // .rl........0 - 74, 41, 8, 148, 12, 95, 20, 122, 136, 94, 202, 186, // J)..._.z.^.. - 65, 4, 205, 45, 98, 238, 121, 142, 140, 230, 93, 62, // A..-b.y...]> - 69, 77, 82, 2, 2, 53, 194, 15, 23, 122, 138, 222, // EMR..5...z.. - 202, 185, 69, 76, 194, 155, 68, 165, 224, 148, 206, 228, // ..EL..D..... - 81, 205, 36, 185, 32, 80, 59, 124, 81, 232, 109, 10, // Q.$. P;|Q.m. - 157, 169, 227, 60, 234, 219, 196, 205, 222, 227, 75, 120, // ...<......Kx - 90, 199, 34, 4, 172, 132, 31, 62, 109, 68, 175, 169, // Z."....>mD.. - 111, 19, 151, 200, 70, 145, 119, 146, 159, 38, 83, 165, // o...F.w..&S. - 151, 25, 147, 104, 65, 192, 90, 248, 162, 208, 235, 59, // ...hA.Z....; - 165, 159, 14, 182, 80, 221, 42, 22, 167, 42, 165, 118, // ....P.*..*.v - 246, 76, 74, 20, 2, 86, 195, 23, 133, 158, 75, 156, // .LJ..V....K. - 38, 206, 161, 186, 89, 116, 73, 19, 199, 172, 73, 82, // &...YtI...IR - 33, 96, 61, 124, 81, 232, 61, 213, 205, 162, 227, 221, // !`=|Q.=..... - 46, 254, 161, 103, 56, 197, 167, 122, 114, 67, 160, 149, // ...g8..zrC.. - 240, 197, 41, 34, 102, 64, 123, 187, 248, 152, 94, 24, // ..)"f@{...^. - 113, 51, 145, 185, 202, 171, 9, 163, 98, 133, 64, 75, // q3......b.@K - 225, 139, 194, 12, 110, 166, 249, 194, 136, 88, 95, 25, // ....n....X_. - 131, 215, 172, 181, 100, 212, 100, 16, 104, 49, 252, 209, // ....d.d.h1.. - 233, 225, 214, 152, 46, 20, 245, 80, 123, 105, 212, 29, // .......P{i.. - 123, 57, 254, 22, 167, 22, 205, 138, 4, 129, 150, 195, // {9.......... - 71, 97, 22, 152, 9, 181, 151, 70, 77, 246, 218, 184, // Ga.....FM... - 130, 144, 95, 179, 102, 141, 135, 64, 235, 225, 143, 222, // .._.f..@.... - 55, 8, 249, 233, 189, 54, 110, 178, 23, 71, 154, 42, // 7....6n..G.* - 234, 52, 111, 152, 8, 129, 30, 194, 231, 175, 13, 144, // .4o......... - 76, 168, 190, 56, 50, 218, 171, 99, 23, 237, 244, 235, // L..82..c.... - 194, 48, 61, 10, 179, 161, 246, 234, 216, 104, 47, 143, // .0=......h/. - 46, 227, 124, 134, 217, 140, 10, 179, 161, 250, 242, 232, // ..|......... - 72, 175, 143, 207, 43, 114, 27, 102, 51, 42, 204, 134, // H...+r.f3*.. - 234, 235, 227, 5, 0, 102, 18, 13, 225, 1, 239, 239, // .....f...... - 230, 12, 163, 25, 23, 102, 36, 132, 143, 153, 205, 76, // .....f$....L - 24, 0, 1, 130, 82, 60, 232, 218, 46, 227, 252, 207, // ....R<...... - 186, 48, 35, 1, 128, 210, 88, 178, 141, 21, 128, 105, // .0#...X....i - 68, 103, 75, 154, 141, 95, 0, 230, 239, 15, 52, 243, // DgK.._....4. - 191, 0, 103, 49, 51, 106, 0, 8, 16, 164, 88, 28, // ..g13j....X. - 245, 134, 201, 140, 11, 51, 194, 172, 98, 205, 53, 102, // .....3..b.5f - 0, 80, 53, 126, 238, 3, 195, 100, 182, 133, 25, 197, // .P5~...d.... - 147, 105, 92, 0, 152, 182, 7, 126, 84, 106, 245, 126, // .i.....~Tj.~ - 103, 24, 205, 232, 26, 1, 146, 13, 102, 36, 27, 0, // g.......f$.. - 40, 203, 147, 193, 223, 230, 26, 83, 65, 230, 132, 153, // (......SA... - 96, 54, 241, 230, 25, 55, 0, 168, 202, 182, 64, 179, // `6...7....@. - 212, 117, 0, 143, 173, 173, 129, 37, 233, 21, 99, 180, // .u.....%..c. - 60, 211, 145, 132, 161, 57, 174, 242, 1, 189, 145, 186, // <....9...... - 46, 0, 51, 145, 146, 165, 36, 0, 80, 214, 22, 255, // ..3...$.P... - 59, 82, 138, 125, 100, 101, 57, 204, 75, 205, 28, 163, // ;R.}de9.K... - 71, 37, 54, 174, 101, 97, 207, 227, 125, 64, 111, 164, // G%6.ea..}@o. - 28, 11, 179, 144, 154, 163, 100, 0, 200, 72, 115, 106, // ......d..Hsj - 149, 203, 55, 100, 0, 160, 46, 0, 152, 1, 102, 161, // ..7d......f. - 56, 0, 40, 95, 71, 195, 207, 74, 171, 226, 27, 20, // 8.(_G..J.... - 26, 0, 208, 3, 0, 189, 199, 12, 18, 201, 48, 33, // ..........0! - 0, 248, 83, 65, 87, 240, 231, 230, 74, 239, 247, 6, // ..SAW...J... - 0, 202, 2, 128, 158, 163, 247, 137, 230, 151, 48, 0, // ..........0. - 168, 162, 237, 129, 91, 77, 21, 222, 43, 6, 0, 202, // ....[M..+... - 0, 128, 94, 163, 231, 52, 178, 163, 2, 0, 42, 111, // ..^..4....*o - 71, 224, 55, 27, 202, 235, 174, 24, 0, 200, 11, 0, // G.7......... - 122, 140, 94, 211, 202, 141, 26, 0, 168, 210, 39, 131, // z.^.......'. - 119, 111, 40, 155, 24, 2, 3, 0, 233, 0, 160, 183, // wo(......... - 232, 49, 205, 204, 168, 2, 128, 242, 182, 55, 220, 102, // .1.......7.f - 42, 175, 251, 222, 0, 128, 46, 0, 232, 41, 122, 75, // *........)zK - 59, 47, 234, 0, 160, 156, 157, 193, 159, 90, 221, 190, // ;/.......Z.. - 47, 13, 0, 232, 0, 128, 94, 162, 167, 114, 100, 37, // /.....^..rd% - 11, 0, 226, 117, 2, 188, 64, 241, 199, 108, 167, 1, // ...u..@..l.. - 128, 68, 0, 208, 59, 244, 48, 145, 121, 190, 106, 0, // .D..;.0.y.j. - 136, 170, 10, 5, 54, 229, 20, 186, 13, 0, 226, 4, // ....6....... - 0, 61, 67, 239, 228, 206, 71, 118, 0, 248, 107, 5, // .=C...Gv..k. - 29, 193, 7, 205, 21, 255, 31, 23, 24, 0, 76, 14, // ..........L. - 0, 122, 133, 158, 41, 145, 141, 34, 0, 160, 26, 219, // .z..)..".... - 27, 126, 82, 195, 113, 255, 94, 154, 110, 0, 16, 13, // .~R.q.^.n... - 0, 244, 6, 61, 66, 175, 148, 202, 69, 49, 0, 68, // ...=B...E1.D - 21, 214, 215, 6, 83, 151, 229, 27, 0, 140, 3, 0, // ....S....... - 61, 65, 111, 148, 206, 67, 113, 0, 80, 169, 53, 222, // =Ao..Cq.P.5. - 31, 103, 172, 183, 252, 107, 254, 194, 172, 164, 7, 0, // .g...k...... - 61, 64, 47, 208, 19, 53, 178, 80, 5, 128, 209, 171, // =@/..5.P.... - 135, 30, 123, 218, 163, 171, 139, 190, 75, 86, 0, 176, // ..{.....KV.. - 119, 244, 64, 205, 12, 84, 5, 64, 148, 125, 107, 160, // w.@..T.@.}k. - 181, 164, 42, 121, 150, 154, 97, 175, 216, 51, 11, 222, // ..*y..a..3.. - 51, 1, 128, 40, 91, 40, 224, 43, 183, 215, 95, 78, // 3..([(.+.._N - 203, 210, 95, 232, 216, 19, 246, 134, 61, 178, 228, 57, // .._.....=..9 - 83, 0, 136, 42, 239, 8, 174, 175, 242, 248, 134, 180, // S..*........ - 178, 253, 204, 100, 203, 181, 72, 47, 95, 98, 79, 44, // ...d..H/_bO, - 122, 205, 36, 0, 163, 107, 15, 59, 131, 15, 217, 125, // z.$..k.;...} - 220, 7, 90, 124, 30, 17, 107, 198, 218, 177, 7, 150, // ..Z|..k..... - 61, 102, 26, 128, 49, 207, 36, 132, 2, 78, 155, 159, // =f..1.$..N.. - 251, 152, 133, 157, 72, 39, 218, 201, 19, 107, 196, 90, // ....H'...k.Z - 181, 226, 171, 102, 0, 8, 223, 209, 212, 220, 25, 176, // ...f........ - 214, 4, 253, 231, 139, 45, 117, 87, 212, 14, 29, 107, // .....-uW...k - 192, 90, 176, 166, 240, 29, 56, 13, 0, 20, 18, 215, // .Z....8..... - 22, 188, 221, 190, 37, 208, 110, 107, 244, 191, 87, 233, // ....%.nk..W. - 244, 93, 34, 223, 194, 17, 57, 6, 145, 120, 76, 60, // .]"...9..xL< - 54, 126, 6, 126, 22, 126, 38, 126, 182, 214, 253, 211, // 6~.~.~&~.... - 60, 0, 145, 84, 214, 21, 248, 133, 115, 107, 192, 235, // <..T....sk.. - 108, 244, 247, 215, 248, 184, 15, 173, 30, 223, 23, 21, // l........... - 181, 245, 151, 44, 213, 222, 97, 83, 121, 221, 21, 12, // ...,..aSy... - 50, 187, 208, 53, 250, 94, 31, 252, 111, 252, 127, 248, // 2..5.^..o... - 103, 248, 119, 240, 239, 226, 191, 193, 127, 139, 199, 192, // g.w......... - 99, 225, 49, 245, 232, 213, 255, 0, 58, 21, 99, 155, // c.1.....:.c. - 126, 121, 49, 188, 0, 0, 0, 0, 73, 69, 78, 68, // ~y1.....IEND - 174, 66, 96, 130, 199, 98, 29, 214, 16, 15, 0, 0, 0 // .B`..b...... -}; -static const unsigned char v6[] = { - 31, 139, 8, 8, 255, 98, 56, 100, 0, 3, 109, 97, // .....b8d..ma - 105, 110, 46, 106, 115, 0, 189, 91, 123, 119, 219, 184, // in.js..[{w.. - 177, 255, 63, 159, 2, 171, 235, 91, 81, 181, 68, 73, // ..?....[Q.DI - 118, 156, 205, 149, 35, 245, 164, 217, 237, 221, 244, 36, // v...#......$ - 217, 116, 157, 109, 187, 199, 199, 167, 166, 72, 72, 98, // .t.m.....HHb - 77, 145, 92, 18, 122, 213, 225, 119, 191, 191, 25, 128, // M...z..w.... - 36, 40, 203, 143, 108, 218, 235, 228, 72, 36, 48, 24, // $(..l...H$0. - 12, 102, 6, 243, 2, 212, 94, 229, 82, 228, 42, 11, // .f....^.R.*. - 125, 213, 62, 127, 22, 46, 211, 36, 83, 226, 246, 77, // }.>....$S..M - 130, 135, 88, 198, 170, 43, 22, 248, 175, 150, 81, 87, // ..X..+....QW - 100, 50, 14, 100, 214, 21, 24, 240, 253, 108, 38, 125, // d2.d.....l&} - 197, 143, 23, 202, 83, 146, 159, 126, 146, 179, 66, 204, // ....S..~..B. - 178, 100, 41, 218, 110, 63, 205, 164, 231, 43, 119, 25, // .d).n?...+w. - 198, 238, 63, 115, 32, 126, 182, 246, 50, 17, 200, 181, // ..?s ~..2... - 23, 4, 153, 24, 139, 22, 125, 203, 60, 31, 209, 116, // ......}.<..t - 45, 116, 251, 73, 156, 43, 241, 222, 219, 190, 151, 68, // -t.I.+.....D - 75, 254, 157, 167, 188, 143, 73, 24, 171, 28, 208, 103, // K.....I....g - 3, 64, 244, 251, 226, 211, 34, 204, 69, 14, 26, 35, // .@....".E..# - 41, 210, 213, 52, 10, 243, 69, 63, 95, 77, 115, 63, // )..4..E?_Ms? - 11, 167, 82, 160, 15, 84, 4, 66, 37, 34, 245, 242, // ..R..T.B%".. - 92, 196, 137, 10, 103, 161, 239, 169, 16, 184, 133, 90, // ....g......Z - 120, 74, 108, 100, 38, 9, 81, 38, 125, 25, 174, 1, // xJld&.Q&}... - 203, 228, 170, 5, 56, 32, 179, 53, 45, 14, 131, 189, // ....8 .5-... - 40, 18, 254, 34, 140, 2, 225, 151, 92, 200, 69, 50, // (.."......E2 - 99, 48, 47, 77, 93, 94, 202, 199, 213, 244, 98, 53, // c0/M]^....b5 - 5, 109, 206, 108, 21, 251, 52, 133, 211, 17, 183, 207, // .m.l..4..... - 132, 160, 206, 133, 23, 7, 145, 204, 136, 244, 219, 162, // ............ - 43, 194, 0, 15, 88, 130, 192, 188, 106, 149, 197, 12, // +...X...j... - 39, 68, 69, 249, 72, 84, 56, 102, 113, 199, 244, 138, // 'DE.HT8fq... - 10, 203, 101, 24, 28, 31, 95, 1, 197, 44, 62, 231, // ..e..._..,>. - 174, 162, 203, 95, 171, 248, 16, 134, 48, 168, 49, 4, // ..._....0.1. - 50, 146, 74, 218, 136, 174, 26, 24, 12, 15, 173, 209, // 2.J......... - 1, 216, 94, 143, 159, 37, 153, 112, 104, 65, 55, 34, // ..^..%.phA7" - 140, 43, 52, 157, 26, 225, 205, 149, 30, 97, 176, 226, // .+4......a.. - 179, 56, 127, 86, 116, 156, 78, 37, 209, 15, 222, 26, // .8.Vt.N%.... - 148, 167, 89, 146, 130, 27, 19, 214, 164, 235, 103, 175, // ..Y.......g. - 130, 112, 13, 157, 219, 69, 114, 220, 154, 122, 254, 205, // .p...Er..z.. - 60, 75, 86, 113, 48, 18, 255, 117, 122, 122, 122, 14, // .,.Lv... - 37, 158, 105, 39, 99, 139, 184, 66, 92, 232, 206, 89, // %.i'c..B...Y - 24, 201, 188, 43, 162, 240, 70, 138, 55, 23, 23, 253, // ...+..F.7... - 63, 95, 244, 127, 248, 244, 254, 29, 112, 193, 44, 133, // ?_......p.,. - 75, 111, 78, 189, 94, 38, 121, 225, 128, 165, 77, 131, // KoN.^&y...M. - 229, 213, 214, 92, 76, 195, 216, 203, 118, 238, 179, 146, // ....L...v... - 169, 63, 191, 37, 15, 145, 51, 200, 79, 223, 95, 124, // .?.%..3.O._| - 18, 175, 63, 190, 21, 236, 78, 150, 180, 57, 3, 49, // ..?...N..9.1 - 221, 113, 159, 230, 71, 87, 211, 46, 118, 201, 74, 248, // .q..GW..v.J. - 216, 120, 114, 11, 58, 99, 9, 100, 154, 253, 226, 149, // .xr.:c.d.... - 15, 230, 79, 252, 85, 22, 189, 234, 243, 35, 81, 178, // ..O.U....#Q. - 196, 154, 122, 17, 224, 196, 74, 133, 81, 168, 118, 35, // ..z...J.Q.v# - 214, 225, 84, 11, 152, 116, 184, 30, 38, 122, 43, 225, // ..T..t..&z+. - 5, 64, 58, 34, 135, 53, 16, 71, 183, 198, 67, 22, // .@:".5.G..C. - 125, 47, 13, 129, 51, 158, 133, 243, 254, 92, 170, 18, // }/..3....... - 127, 189, 41, 126, 11, 162, 92, 42, 209, 11, 68, 27, // ..)~...*..D. - 102, 127, 188, 156, 247, 177, 3, 66, 191, 253, 149, 168, // f......B.... - 151, 112, 226, 144, 4, 112, 67, 148, 132, 220, 52, 140, // .p...pC...4. - 23, 50, 138, 146, 125, 236, 150, 142, 151, 92, 102, 214, // .2..}.....f. - 242, 232, 61, 127, 77, 146, 36, 165, 175, 118, 0, 252, // ..=.M.$..v.. - 183, 23, 239, 84, 184, 148, 174, 248, 96, 195, 146, 186, // ...T....`... - 102, 36, 244, 24, 138, 77, 114, 255, 155, 156, 94, 36, // f$...Mr...^$ - 254, 13, 150, 139, 49, 63, 255, 244, 214, 72, 138, 9, // ....1?...H.. - 222, 120, 202, 95, 148, 100, 121, 185, 248, 243, 197, 143, // .x._.dy..... - 31, 56, 254, 137, 231, 216, 220, 26, 240, 182, 5, 149, // .8.......... - 148, 173, 145, 104, 185, 110, 171, 43, 90, 228, 227, 240, // ...h.n.+Z... - 230, 186, 110, 97, 70, 150, 124, 250, 132, 61, 164, 199, // ..naF.|..=.. - 108, 114, 80, 35, 122, 61, 24, 245, 5, 105, 89, 54, // lrP#z=...iY6 - 100, 134, 13, 209, 4, 246, 199, 48, 69, 98, 67, 187, // d......0EbC. - 104, 143, 127, 54, 57, 150, 201, 75, 75, 131, 103, 217, // h..69..KK.g. - 61, 109, 246, 224, 31, 176, 153, 199, 181, 203, 102, 3, // =m........f. - 168, 125, 182, 134, 184, 164, 217, 187, 96, 135, 250, 25, // .}......`... - 15, 20, 56, 148, 97, 154, 211, 110, 179, 171, 54, 112, // ..8.a..n..6p - 68, 31, 195, 125, 196, 195, 253, 112, 145, 153, 81, 194, // D..}...p..Q. - 147, 151, 158, 97, 38, 65, 182, 83, 89, 126, 33, 218, // ...a&A.SY~!. - 188, 26, 6, 109, 119, 173, 246, 219, 133, 244, 96, 119, // ...mw.....`w - 192, 218, 219, 215, 224, 12, 140, 198, 191, 88, 104, 35, // .........Xh# - 209, 254, 163, 151, 99, 151, 183, 197, 177, 152, 170, 196, // ....c....... - 115, 136, 106, 60, 183, 71, 212, 66, 164, 117, 138, 162, // s.j<.G.B.u.. - 99, 97, 114, 177, 51, 99, 39, 35, 83, 159, 33, 166, // car.3c'#S.!. - 164, 128, 235, 190, 110, 241, 187, 223, 137, 202, 69, 133, // ....n.....E. - 104, 109, 66, 250, 196, 115, 71, 102, 12, 140, 175, 142, // hmB..sGf.... - 21, 154, 221, 245, 34, 236, 25, 200, 54, 176, 1, 109, // ...."...6..m - 213, 38, 126, 219, 219, 132, 129, 66, 244, 244, 252, 229, // .&~....B.... - 32, 133, 183, 175, 140, 190, 113, 236, 182, 163, 57, 59, // .....q...9; - 236, 104, 234, 112, 102, 223, 171, 159, 208, 128, 50, 152, // .h.pf.....2. - 169, 29, 75, 233, 117, 94, 188, 120, 1, 167, 178, 239, // ..K.u^.x.... - 72, 140, 114, 104, 127, 178, 31, 155, 212, 62, 233, 204, // H.rh.....>.. - 248, 164, 210, 203, 135, 113, 186, 82, 66, 237, 82, 57, // .....q.RB.R9 - 110, 43, 185, 85, 109, 129, 32, 198, 151, 139, 36, 194, // n+.Um. ...$. - 130, 199, 237, 15, 216, 11, 237, 18, 139, 89, 242, 112, // .........Y.p - 48, 248, 239, 243, 86, 197, 212, 36, 102, 28, 136, 12, // 0...V..$f... - 88, 73, 74, 221, 115, 228, 218, 85, 152, 86, 42, 119, // XIJ.s..U.V*w - 237, 69, 43, 217, 41, 4, 127, 3, 142, 163, 13, 68, // .E+.)......D - 36, 15, 69, 83, 79, 162, 184, 69, 170, 2, 55, 23, // $.ESO..E..7. - 180, 26, 84, 183, 62, 86, 205, 95, 74, 57, 141, 124, // ..T.>V._J9.| - 128, 114, 154, 175, 176, 198, 251, 136, 134, 231, 212, 193, // .r.......... - 186, 246, 212, 53, 13, 247, 86, 52, 93, 41, 5, 167, // ...5..V4]).. - 108, 135, 91, 7, 232, 62, 16, 55, 85, 148, 32, 246, // l.[..>.7U. . - 244, 166, 240, 130, 160, 228, 27, 222, 75, 159, 63, 139, // ........K.?. - 111, 152, 88, 43, 112, 211, 52, 78, 42, 69, 209, 211, // o.X+p.4N*E.. - 62, 72, 113, 35, 208, 177, 117, 250, 132, 131, 78, 51, // >Hq#..u...N3 - 255, 95, 17, 235, 6, 218, 84, 96, 175, 91, 14, 163, // ._....T`.[.. - 107, 27, 67, 253, 114, 194, 47, 39, 15, 135, 121, 69, // k.C.r./'..yE - 29, 233, 189, 97, 247, 181, 202, 216, 112, 60, 98, 250, // ...a....p - 125, 50, 1, 122, 35, 191, 109, 24, 117, 114, 67, 173, // }2.z#.m.urC. - 59, 9, 124, 211, 116, 139, 218, 153, 100, 81, 97, 91, // ;.|.t...dQa[ - 226, 74, 196, 133, 5, 124, 200, 71, 97, 179, 221, 53, // .J...|.Ga..5 - 244, 165, 1, 63, 96, 146, 27, 54, 214, 76, 106, 44, // ...?`..6.Lj, - 235, 157, 57, 239, 205, 134, 15, 228, 190, 63, 243, 96, // ..9......?.` - 219, 28, 55, 194, 241, 39, 242, 94, 60, 206, 252, 139, // ..7..'.^<... - 170, 90, 198, 209, 255, 215, 9, 160, 100, 63, 116, 245, // .Z......d?t. - 0, 251, 169, 245, 33, 55, 75, 214, 234, 55, 51, 191, // ....!7K..73. - 156, 178, 193, 124, 107, 198, 255, 127, 230, 63, 206, 251, // ...|k....?.. - 143, 186, 218, 246, 239, 224, 124, 205, 251, 244, 32, 239, // ......|... . - 83, 155, 247, 135, 131, 156, 175, 225, 126, 122, 136, 251, // S.......~z.. - 233, 127, 132, 251, 154, 160, 95, 76, 10, 78, 181, 234, // ......_L.N.. - 70, 93, 2, 9, 213, 102, 179, 113, 23, 225, 90, 46, // F]...f.q..Z. - 127, 133, 119, 91, 246, 3, 185, 76, 242, 254, 70, 78, // ..w[...L..FN - 115, 206, 0, 123, 32, 18, 174, 163, 111, 196, 243, 3, // s..{ ...o... - 0, 223, 255, 133, 18, 68, 221, 45, 0, 40, 52, 8, // .....D.-.(4. - 87, 43, 144, 117, 114, 46, 106, 178, 216, 58, 13, 45, // W+.ur.j..:.- - 173, 245, 29, 237, 48, 60, 90, 230, 115, 51, 133, 149, // ....06 - 151, 26, 85, 156, 40, 75, 28, 135, 2, 199, 247, 90, // ..U.(K.....Z - 138, 112, 198, 203, 170, 66, 248, 104, 130, 209, 216, 193, // .p...B.h.... - 191, 38, 121, 107, 130, 143, 145, 56, 186, 93, 186, 70, // .&yk...8.].F - 43, 92, 52, 20, 162, 222, 192, 141, 17, 188, 187, 91, // +.4........[ - 19, 189, 201, 27, 163, 184, 233, 222, 113, 92, 99, 152, // ........q.c. - 208, 103, 115, 20, 181, 84, 101, 217, 253, 98, 192, 251, // .gs..Te..b.. - 82, 77, 31, 12, 138, 75, 101, 230, 40, 181, 28, 210, // RM...Ke.(... - 8, 85, 47, 175, 236, 128, 86, 109, 21, 131, 126, 218, // .U/...Vm..~. - 170, 187, 85, 129, 123, 131, 87, 61, 152, 207, 58, 244, // ..U.{.W=..:. - 225, 136, 91, 29, 79, 212, 103, 36, 80, 144, 250, 120, // ..[.O.g$P..x - 33, 156, 9, 106, 112, 41, 226, 19, 227, 113, 85, 59, // !..jp)...qU; - 106, 119, 108, 66, 157, 45, 205, 177, 165, 208, 21, 81, // jwlB.-.....Q - 157, 115, 73, 35, 136, 41, 87, 157, 242, 216, 193, 124, // .sI#.)W....| - 155, 72, 201, 76, 110, 157, 142, 208, 153, 72, 25, 6, // .H.Ln....H.. - 55, 66, 95, 218, 234, 203, 74, 71, 180, 109, 180, 195, // 7B_...JG.m.. - 94, 187, 184, 245, 132, 192, 247, 203, 130, 94, 19, 240, // ^........^.. - 150, 245, 178, 131, 1, 47, 36, 241, 88, 192, 139, 96, // ...../$.X..` - 183, 174, 124, 104, 161, 145, 160, 44, 121, 194, 222, 42, // ..|h...,y..* - 218, 251, 99, 209, 50, 214, 71, 34, 43, 198, 246, 182, // ..c.2.G"+... - 83, 130, 26, 156, 96, 168, 60, 187, 34, 173, 250, 166, // S...`.<."... - 28, 252, 7, 209, 182, 235, 210, 11, 143, 206, 215, 180, // ............ - 193, 42, 133, 235, 81, 181, 179, 45, 70, 13, 188, 110, // .*..Q..-F..n - 53, 37, 161, 168, 94, 8, 172, 13, 151, 82, 55, 124, // 5%..^....R7| - 117, 172, 123, 58, 240, 7, 207, 7, 143, 197, 186, 76, // u.{:.......L - 113, 185, 33, 236, 248, 86, 155, 45, 203, 2, 11, 205, // q.!..V.-.... - 132, 17, 157, 1, 29, 221, 214, 92, 41, 204, 33, 208, // ........).!. - 193, 32, 65, 31, 183, 80, 182, 78, 238, 142, 138, 145, // . A..P.N.... - 179, 40, 217, 140, 76, 69, 104, 255, 100, 171, 85, 121, // .(..LEh.d.Uy - 88, 93, 91, 210, 52, 96, 247, 27, 250, 220, 165, 151, // X][.4`...... - 58, 149, 130, 194, 128, 57, 102, 83, 64, 23, 77, 115, // :....9fS@.Ms - 209, 233, 20, 191, 45, 98, 121, 122, 192, 98, 166, 58, // ....-byz.b.: - 20, 178, 52, 74, 46, 20, 191, 176, 57, 79, 233, 104, // ..4J....9O.h - 87, 240, 121, 151, 235, 186, 15, 7, 51, 101, 32, 3, // W.y.....3e . - 85, 111, 4, 50, 214, 222, 44, 26, 193, 135, 209, 200, // Uo.2..,..... - 50, 214, 56, 16, 219, 208, 22, 184, 39, 182, 121, 130, // 2.8.....'.y. - 239, 46, 249, 141, 177, 57, 215, 33, 181, 107, 173, 207, // .....9.!.k.. - 5, 196, 58, 244, 248, 248, 128, 206, 75, 100, 108, 247, // ..:.....Kdl. - 16, 209, 240, 156, 8, 229, 18, 198, 71, 93, 182, 74, // ........G].J - 113, 117, 154, 26, 92, 241, 26, 174, 186, 161, 140, 116, // qu.........t - 38, 227, 213, 135, 194, 129, 142, 19, 141, 101, 51, 199, // &........e3. - 213, 123, 231, 19, 119, 3, 128, 61, 191, 78, 148, 214, // .{..w..=.N.. - 101, 230, 251, 188, 37, 146, 209, 239, 183, 169, 222, 164, // e...%....... - 224, 217, 138, 14, 67, 242, 17, 53, 107, 119, 68, 37, // ....C..5kwD% - 119, 44, 32, 36, 15, 34, 221, 185, 43, 46, 197, 229, // w, $."..+... - 240, 197, 217, 243, 211, 23, 195, 211, 179, 147, 174, 24, // ............ - 254, 207, 85, 215, 106, 57, 69, 203, 75, 180, 64, 244, // ..U.j9E.K.@. - 226, 138, 176, 112, 5, 171, 107, 142, 34, 187, 98, 167, // ...p..k.".b. - 16, 54, 2, 213, 214, 124, 239, 16, 35, 208, 167, 183, // .6...|..#... - 69, 27, 63, 111, 241, 108, 60, 220, 197, 95, 255, 247, // E.?o.l<.._.. - 30, 231, 6, 196, 214, 223, 166, 108, 57, 238, 29, 250, // .......l9... - 59, 46, 187, 63, 151, 3, 22, 67, 107, 244, 231, 70, // ;..?...Ck..F - 183, 141, 226, 248, 110, 247, 103, 123, 160, 249, 88, 212, // ....n.g{..X. - 16, 155, 225, 30, 196, 230, 228, 203, 240, 107, 242, 78, // .........k.N - 14, 80, 247, 208, 218, 240, 17, 81, 60, 91, 30, 137, // .P.....Q<[.. - 186, 37, 215, 171, 134, 146, 255, 32, 112, 44, 78, 7, // .%..... p,N. - 93, 34, 108, 44, 240, 189, 160, 134, 151, 93, 154, 115, // ]"l,.....].s - 12, 209, 157, 27, 84, 90, 78, 213, 112, 243, 250, 249, // ....TZN.p... - 179, 120, 94, 202, 174, 234, 219, 86, 125, 103, 229, 104, // .x^....V}g.h - 82, 157, 170, 159, 95, 208, 123, 121, 85, 33, 95, 242, // R..._.{yU!_. - 153, 130, 65, 77, 47, 232, 30, 212, 189, 222, 214, 234, // ..AM/....... - 197, 11, 122, 223, 123, 106, 1, 139, 184, 117, 189, 52, // ..z.{j...u.4 - 141, 118, 78, 188, 138, 162, 46, 79, 195, 102, 50, 165, // .vN....O.f2. - 205, 159, 94, 14, 77, 88, 64, 88, 182, 246, 28, 91, // ..^.MX@X...[ - 51, 135, 198, 18, 198, 15, 98, 25, 52, 176, 88, 180, // 3.....b.4.X. - 108, 191, 132, 22, 141, 69, 11, 239, 151, 158, 183, 197, // l....E...... - 214, 36, 62, 9, 58, 29, 204, 217, 80, 70, 222, 84, // .$>.:...PF.T - 70, 121, 197, 111, 143, 171, 112, 114, 35, 94, 103, 153, // Fy.o..pr#^g. - 183, 115, 12, 199, 143, 197, 176, 211, 113, 103, 97, 20, // .s......qga. - 57, 131, 14, 227, 119, 254, 209, 21, 33, 135, 94, 97, // 9...w...!.^a - 231, 156, 209, 135, 113, 64, 39, 184, 181, 228, 128, 41, // ....q@'....) - 100, 151, 33, 122, 36, 215, 158, 112, 248, 105, 200, 175, // d.!z$..p.i.. - 29, 241, 123, 244, 246, 141, 132, 207, 107, 77, 211, 152, // ..{.....kM.. - 228, 182, 157, 139, 95, 42, 92, 235, 18, 151, 195, 146, // ...._*...... - 232, 177, 236, 246, 80, 84, 192, 84, 85, 219, 213, 193, // ....PT.TU... - 54, 31, 132, 110, 135, 176, 206, 155, 97, 33, 118, 244, // 6..n....a!v. - 176, 43, 196, 246, 132, 26, 240, 126, 162, 223, 203, 208, // .+.....~.... - 25, 168, 90, 125, 178, 74, 37, 54, 69, 12, 217, 117, // ..Z}.J%6E..u - 197, 186, 83, 163, 164, 252, 88, 108, 199, 3, 177, 163, // ..S...Xl.... - 193, 224, 206, 89, 133, 128, 217, 217, 130, 183, 94, 195, // ...Y......^. - 73, 19, 28, 135, 202, 188, 172, 191, 63, 206, 127, 202, // I.......?... - 67, 103, 75, 154, 114, 21, 135, 28, 116, 178, 44, 190, // CgK.r...t.,. - 163, 208, 151, 91, 126, 79, 158, 107, 0, 89, 168, 228, // ...[~O.k.Y.. - 237, 197, 143, 23, 124, 102, 232, 116, 56, 204, 85, 153, // ....|f.t8.U. - 51, 196, 182, 56, 171, 181, 102, 95, 152, 219, 223, 42, // 3..8..f_...* - 204, 109, 45, 76, 236, 220, 99, 225, 108, 32, 130, 13, // .m-L..c.l .. - 9, 114, 83, 9, 114, 187, 47, 200, 61, 97, 254, 189, // .rS.r./.=a.. - 194, 85, 9, 211, 172, 214, 225, 125, 1, 172, 91, 45, // .U.....}..[- - 219, 173, 37, 91, 141, 213, 90, 18, 9, 119, 91, 75, // ..%[..Z..w[K - 34, 197, 38, 16, 193, 184, 245, 30, 33, 203, 182, 232, // ".&.....!... - 30, 221, 46, 32, 227, 119, 213, 11, 171, 90, 209, 186, // ... .w...Z.. - 79, 186, 91, 45, 221, 173, 145, 174, 113, 231, 13, 25, // O.[-....q... - 3, 19, 144, 12, 33, 96, 146, 53, 33, 60, 121, 138, // ....!`.5!.... - 160, 123, 114, 114, 214, 61, 57, 59, 235, 210, 165, 165, // .{rr.=9;.... - 179, 78, 99, 176, 61, 247, 201, 217, 129, 21, 33, 51, // .Nc.=.....!3 - 40, 153, 0, 155, 108, 84, 150, 205, 12, 60, 2, 249, // (...lT...<.. - 49, 39, 236, 232, 68, 229, 78, 183, 50, 221, 20, 23, // 1'..D.N.2... - 174, 45, 176, 173, 13, 6, 211, 67, 6, 212, 234, 230, // .-.....C.... - 141, 161, 53, 26, 162, 221, 3, 86, 6, 152, 226, 20, // ..5....V.... - 141, 147, 210, 205, 54, 83, 90, 26, 173, 163, 91, 86, // ....6SZ...[V - 78, 18, 164, 94, 164, 251, 79, 232, 160, 211, 22, 237, // N..^..O..... - 14, 181, 65, 9, 107, 211, 85, 178, 176, 101, 146, 136, // ..A.k.U..e.. - 61, 28, 131, 131, 72, 246, 70, 243, 88, 240, 105, 61, // =...H.F.X.i= - 223, 63, 221, 132, 200, 212, 195, 5, 28, 90, 44, 87, // .?.......Z,W - 100, 232, 86, 236, 161, 194, 205, 127, 164, 34, 243, 13, // d.V......".. - 87, 100, 248, 54, 110, 187, 99, 246, 196, 121, 89, 225, // Wd.6n.c..yY. - 213, 180, 220, 95, 155, 113, 145, 105, 194, 137, 57, 189, // ..._.q.i..9. - 67, 87, 122, 191, 166, 114, 99, 133, 100, 8, 93, 151, // CWz..rc.d.]. - 97, 158, 235, 218, 198, 193, 171, 195, 61, 97, 233, 9, // a.......=a.. - 33, 226, 5, 154, 49, 19, 49, 232, 148, 168, 44, 19, // !...1.1...,. - 74, 254, 222, 69, 10, 236, 144, 193, 102, 135, 15, 143, // J..E....f... - 96, 198, 124, 117, 145, 66, 250, 167, 143, 85, 40, 136, // `.|u.B...U(. - 124, 173, 20, 135, 142, 223, 30, 41, 41, 84, 74, 87, // |......))TJW - 102, 247, 71, 183, 200, 160, 138, 242, 26, 232, 201, 243, // f.G......... - 129, 206, 198, 198, 47, 6, 3, 118, 66, 20, 71, 129, // ..../..vB.G. - 5, 227, 147, 1, 179, 130, 92, 46, 190, 10, 230, 219, // ............ - 88, 111, 179, 167, 166, 206, 84, 159, 102, 93, 38, 191, // Xo....T.f]&. - 146, 35, 202, 90, 115, 66, 156, 39, 153, 40, 21, 56, // .#.ZsB.'.(.8 - 86, 205, 20, 246, 137, 9, 170, 86, 228, 215, 105, 250, // V......V..i. - 239, 185, 247, 164, 43, 83, 12, 169, 143, 59, 27, 176, // ....+S...;.. - 183, 133, 93, 34, 156, 75, 165, 193, 41, 86, 177, 226, // ..]".K..)V.. - 148, 3, 167, 227, 115, 125, 58, 126, 255, 133, 167, 246, // ....s}:~.... - 111, 189, 208, 84, 17, 250, 224, 77, 38, 251, 64, 153, // o..T...M&.@. - 142, 188, 171, 220, 227, 111, 4, 197, 151, 185, 27, 87, // .....o.....W - 236, 92, 241, 58, 23, 121, 66, 101, 7, 58, 164, 176, // ...:.yBe.:.. - 251, 40, 88, 130, 248, 144, 156, 243, 77, 122, 190, 48, // .(X.....Mz.0 - 170, 113, 153, 67, 6, 171, 76, 81, 95, 146, 175, 152, // .q.C..LQ_... - 198, 194, 180, 101, 85, 90, 24, 186, 75, 78, 209, 200, // ...eUZ..KN.. - 6, 129, 105, 178, 1, 165, 190, 169, 237, 67, 152, 138, // ..i......C.. - 110, 243, 70, 46, 63, 97, 135, 184, 153, 228, 226, 146, // n.F.?a...... - 211, 166, 115, 30, 48, 182, 189, 201, 219, 198, 94, 16, // ..s.0.....^. - 26, 21, 6, 200, 96, 115, 186, 221, 55, 54, 195, 143, // ....`s..76.. - 69, 187, 223, 167, 219, 99, 145, 187, 72, 64, 198, 177, // E....c..H@.. - 185, 149, 198, 228, 180, 171, 145, 153, 44, 47, 228, 29, // ........,/.. - 160, 80, 131, 108, 40, 106, 160, 216, 189, 186, 73, 232, // .P.l(j....I. - 240, 84, 157, 210, 254, 81, 85, 35, 119, 147, 152, 206, // .T...QU#w... - 70, 74, 205, 104, 8, 0, 212, 138, 186, 184, 89, 141, // FJ.h......Y. - 227, 65, 117, 201, 185, 154, 94, 174, 59, 86, 121, 89, // .Au...^.;VyY - 101, 187, 70, 177, 153, 72, 194, 78, 195, 0, 186, 173, // e.F..H.N.... - 232, 166, 94, 150, 75, 170, 112, 89, 119, 239, 245, 159, // ..^.K.pYw... - 177, 160, 230, 94, 63, 219, 118, 187, 155, 50, 130, 251, // ...^?.v..2.. - 45, 252, 30, 249, 189, 9, 152, 222, 196, 128, 224, 155, // -........... - 37, 235, 200, 78, 131, 190, 198, 200, 183, 241, 154, 239, // %..N........ - 2, 129, 1, 124, 5, 121, 4, 52, 21, 173, 76, 131, // ...|.y.4..L. - 204, 145, 129, 169, 158, 41, 234, 241, 101, 217, 122, 10, // .....)..e.z. - 243, 84, 52, 56, 230, 71, 73, 46, 15, 139, 11, 179, // .T48.GI..... - 71, 210, 203, 62, 133, 75, 153, 172, 148, 163, 140, 199, // G..>.K...... - 48, 140, 100, 231, 71, 37, 65, 211, 93, 201, 190, 171, // 0.d.G%A.]... - 77, 123, 13, 186, 47, 188, 70, 113, 186, 130, 51, 100, // M{../.Fq..3d - 21, 165, 223, 50, 32, 142, 246, 82, 150, 221, 136, 246, // ...2 ..R.... - 175, 105, 174, 74, 146, 131, 196, 231, 10, 27, 156, 102, // .i.J.......f - 114, 19, 210, 170, 174, 61, 31, 233, 94, 254, 15, 133, // r....=..^... - 8, 43, 166, 243, 84, 151, 159, 138, 115, 113, 33, 253, // .+..T...sq!. - 85, 38, 187, 226, 7, 108, 129, 31, 227, 104, 135, 22, // U&...l...h.. - 112, 244, 34, 84, 114, 252, 206, 219, 146, 245, 135, 41, // p."Tr......) - 239, 211, 181, 172, 109, 143, 14, 17, 78, 97, 214, 175, // ....m...Na.. - 171, 251, 64, 124, 5, 111, 197, 23, 251, 205, 2, 72, // ..@|.o.....H - 250, 229, 166, 67, 108, 231, 101, 176, 185, 58, 125, 165, // ...Cl.e..:}. - 84, 22, 185, 8, 157, 194, 192, 247, 145, 58, 220, 214, // T........:.. - 170, 254, 118, 38, 126, 93, 241, 117, 113, 6, 164, 187, // ..v&~].uq... - 232, 127, 32, 168, 46, 153, 242, 24, 43, 34, 227, 81, // .. .....+".Q - 170, 59, 153, 136, 234, 248, 213, 21, 127, 34, 243, 47, // .;......."./ - 167, 171, 185, 62, 209, 44, 144, 93, 64, 148, 37, 114, // ...>.,.]@.%r - 222, 154, 224, 30, 205, 242, 230, 192, 248, 110, 89, 251, // .........nY. - 212, 108, 245, 224, 64, 230, 153, 151, 46, 202, 155, 54, // .l..@......6 - 207, 106, 157, 49, 126, 185, 50, 216, 7, 101, 2, 29, // .j.1~.2..e.. - 168, 78, 122, 158, 38, 142, 47, 23, 194, 190, 4, 140, // .Nz.&./..... - 243, 41, 30, 56, 59, 163, 213, 195, 172, 194, 154, 66, // .).8;......B - 215, 37, 221, 90, 14, 99, 170, 34, 67, 107, 159, 89, // .%.Z.c."Ck.Y - 251, 186, 142, 139, 216, 26, 76, 68, 227, 244, 76, 47, // ......LD..L/ - 187, 77, 151, 95, 45, 38, 24, 201, 219, 254, 202, 220, // .M._-&...... - 210, 125, 178, 171, 122, 208, 81, 89, 157, 119, 47, 219, // .}..z.QY.w/. - 54, 29, 148, 197, 144, 253, 168, 142, 20, 147, 111, 45, // 6.........o- - 118, 26, 241, 21, 194, 151, 119, 250, 86, 37, 227, 182, // v.....w.V%.. - 47, 89, 94, 31, 200, 212, 142, 110, 63, 120, 235, 130, // /Y^....n?x.. - 79, 136, 171, 43, 166, 90, 232, 122, 36, 253, 90, 133, // O..+.Z.z$.Z. - 195, 240, 67, 63, 32, 186, 243, 211, 162, 44, 217, 216, // ..C? ....,.. - 191, 38, 170, 224, 35, 10, 224, 122, 47, 90, 19, 204, // .&..#..z/Z.. - 71, 63, 66, 41, 248, 135, 53, 205, 187, 147, 7, 129, // G?B)..5..... - 57, 168, 123, 26, 180, 225, 160, 94, 4, 75, 151, 143, // 9.{....^.K.. - 210, 89, 184, 11, 231, 77, 243, 96, 252, 86, 203, 186, // .Y...M.`.V.. - 48, 73, 219, 147, 104, 41, 79, 87, 11, 115, 202, 62, // 0I..h)OW.s.> - 62, 42, 177, 216, 244, 29, 10, 198, 140, 239, 78, 226, // >*........N. - 40, 241, 130, 202, 247, 233, 31, 7, 58, 11, 7, 81, // (.......:..Q - 26, 242, 174, 106, 87, 209, 41, 39, 68, 252, 127, 231, // ...jW.)'D... - 89, 87, 40, 102, 56, 0, 0, 0 // YW(f8.. -}; static const struct packed_file { const char *name; @@ -1671,12 +1279,11 @@ static const struct packed_file { size_t size; time_t mtime; } packed_files[] = { - {"/web_root/index.html.gz", v1, sizeof(v1), 1681416959}, - {"/web_root/main.js.orig.gz", v2, sizeof(v2), 1681416959}, - {"/web_root/preact.min.js.gz", v3, sizeof(v3), 1681416959}, - {"/web_root/style.css.gz", v4, sizeof(v4), 1681416959}, - {"/web_root/user.png.gz", v5, sizeof(v5), 1681416959}, - {"/web_root/main.js.gz", v6, sizeof(v6), 1681416959}, + {"/web_root/user.png.gz", v1, sizeof(v1), 1681967907}, + {"/web_root/index.html.gz", v2, sizeof(v2), 1681967907}, + {"/web_root/main.js.gz", v3, sizeof(v3), 1681967907}, + {"/web_root/style.css.gz", v4, sizeof(v4), 1681967907}, + {"/web_root/preact.min.js.gz", v5, sizeof(v5), 1681967907}, {NULL, NULL, 0, 0} }; diff --git a/examples/mqtt-client-aws-iot/main.c b/examples/mqtt-client-aws-iot/main.c index d55f55dd..cc411953 100644 --- a/examples/mqtt-client-aws-iot/main.c +++ b/examples/mqtt-client-aws-iot/main.c @@ -54,7 +54,11 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { struct mg_str topic = mg_str(s_rx_topic); MG_INFO(("Connected to %s", s_url)); MG_INFO(("Subscribing to %s", s_rx_topic)); - mg_mqtt_sub(c, topic, s_qos); + struct mg_mqtt_opts sub_opts; + memset(&sub_opts, 0, sizeof(sub_opts)); + sub_opts.topic = topic; + sub_opts.qos = s_qos; + mg_mqtt_sub(c, &sub_opts); c->data[0] = 'X'; // Set a label that we're logged in } else if (ev == MG_EV_MQTT_MSG) { // When we receive MQTT message, print it @@ -67,7 +71,12 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { if (now_second != prev_second) { struct mg_str topic = mg_str(s_tx_topic), data = mg_str("{\"a\":123}"); MG_INFO(("Publishing to %s", s_tx_topic)); - mg_mqtt_pub(c, topic, data, s_qos, false); + struct mg_mqtt_opts pub_opts; + memset(&pub_opts, 0, sizeof(pub_opts)); + pub_opts.topic = topic; + pub_opts.message = data; + pub_opts.qos = s_qos, pub_opts.retain = false; + mg_mqtt_pub(c, &pub_opts); prev_second = now_second; } } diff --git a/examples/mqtt-client/main.c b/examples/mqtt-client/main.c index 51208238..796c6328 100644 --- a/examples/mqtt-client/main.c +++ b/examples/mqtt-client/main.c @@ -40,10 +40,18 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { struct mg_str subt = mg_str(s_sub_topic); struct mg_str pubt = mg_str(s_pub_topic), data = mg_str("hello"); MG_INFO(("%lu CONNECTED to %s", c->id, s_url)); - mg_mqtt_sub(c, subt, s_qos); + struct mg_mqtt_opts sub_opts; + memset(&sub_opts, 0, sizeof(sub_opts)); + sub_opts.topic = subt; + sub_opts.qos = s_qos; + mg_mqtt_sub(c, &sub_opts); MG_INFO(("%lu SUBSCRIBED to %.*s", c->id, (int) subt.len, subt.ptr)); - - mg_mqtt_pub(c, pubt, data, s_qos, false); + struct mg_mqtt_opts pub_opts; + memset(&pub_opts, 0, sizeof(pub_opts)); + pub_opts.topic = pubt; + pub_opts.message = data; + pub_opts.qos = s_qos, pub_opts.retain = false; + mg_mqtt_pub(c, &pub_opts); MG_INFO(("%lu PUBLISHED %.*s -> %.*s", c->id, (int) data.len, data.ptr, (int) pubt.len, pubt.ptr)); } else if (ev == MG_EV_MQTT_MSG) { @@ -62,9 +70,10 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { static void timer_fn(void *arg) { struct mg_mgr *mgr = (struct mg_mgr *) arg; struct mg_mqtt_opts opts = {.clean = true, - .will_qos = s_qos, - .will_topic = mg_str(s_pub_topic), - .will_message = mg_str("bye")}; + .qos = s_qos, + .topic = mg_str(s_pub_topic), + .version = 4, + .message = mg_str("bye")}; if (s_conn == NULL) s_conn = mg_mqtt_connect(mgr, s_url, &opts, fn, NULL); } diff --git a/examples/mqtt-over-ws-client/main.c b/examples/mqtt-over-ws-client/main.c index b6d816cf..5fd23cdb 100644 --- a/examples/mqtt-over-ws-client/main.c +++ b/examples/mqtt-over-ws-client/main.c @@ -33,9 +33,9 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { } else if (ev == MG_EV_WS_OPEN) { // WS connection established. Perform MQTT login MG_INFO(("Connected to WS. Logging in to MQTT...")); - struct mg_mqtt_opts opts = {.will_qos = 1, - .will_topic = mg_str(s_topic), - .will_message = mg_str("goodbye")}; + struct mg_mqtt_opts opts = {.qos = 1, + .topic = mg_str(s_topic), + .message = mg_str("goodbye")}; size_t len = c->send.len; mg_mqtt_login(c, &opts); mg_ws_wrap(c, c->send.len - len, WEBSOCKET_OP_BINARY); @@ -54,10 +54,19 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { struct mg_str topic = mg_str(s_topic), data = mg_str("hello"); size_t len = c->send.len; MG_INFO(("CONNECTED to %s", s_url)); - mg_mqtt_sub(c, topic, 1); + struct mg_mqtt_opts sub_opts; + memset(&sub_opts, 0, sizeof(sub_opts)); + sub_opts.topic = topic; + sub_opts.qos = 1; + mg_mqtt_sub(c, &sub_opts); len = mg_ws_wrap(c, c->send.len - len, WEBSOCKET_OP_BINARY); MG_INFO(("SUBSCRIBED to %.*s", (int) topic.len, topic.ptr)); - mg_mqtt_pub(c, topic, data, 1, false); + struct mg_mqtt_opts pub_opts; + memset(&pub_opts, 0, sizeof(pub_opts)); + pub_opts.topic = topic; + pub_opts.message = data; + pub_opts.qos = 1, pub_opts.retain = false; + mg_mqtt_pub(c, &pub_opts); MG_INFO(("PUBLISHED %.*s -> %.*s", (int) data.len, data.ptr, (int) topic.len, topic.ptr)); len = mg_ws_wrap(c, c->send.len - len, WEBSOCKET_OP_BINARY); diff --git a/examples/mqtt-server/main.c b/examples/mqtt-server/main.c index 651a696d..0b96ece4 100644 --- a/examples/mqtt-server/main.c +++ b/examples/mqtt-server/main.c @@ -103,7 +103,12 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { mm->data.ptr, (int) mm->topic.len, mm->topic.ptr)); for (struct sub *sub = s_subs; sub != NULL; sub = sub->next) { if (mg_match(mm->topic, sub->topic, NULL)) { - mg_mqtt_pub(sub->c, mm->topic, mm->data, 1, false); + struct mg_mqtt_opts pub_opts; + memset(&pub_opts, 0, sizeof(pub_opts)); + pub_opts.topic = mm->topic; + pub_opts.message = mm->data; + pub_opts.qos = 1, pub_opts.retain = false; + mg_mqtt_pub(sub->c, &pub_opts); } } break; diff --git a/examples/uart-bridge/net.c b/examples/uart-bridge/net.c index fe74e399..e59e42c7 100644 --- a/examples/uart-bridge/net.c +++ b/examples/uart-bridge/net.c @@ -107,7 +107,11 @@ static void mq_fn(struct mg_connection *c, int ev, void *evd, void *fnd) { // c->is_hexdumping = 1; } else if (ev == MG_EV_MQTT_OPEN) { c->data[0] = 'M'; - mg_mqtt_sub(c, mqtt_topic("rx", "b/rx"), 1); // Subscribe to RX topic + struct mg_mqtt_opts sub_opts; + memset(&sub_opts, 0, sizeof(sub_opts)); + sub_opts.topic = mqtt_topic("rx", "b/rx"); + sub_opts.qos = 1; + mg_mqtt_sub(c, &sub_opts); // Subscribe to RX topic } else if (ev == MG_EV_MQTT_MSG) { struct mg_mqtt_message *mm = evd; // MQTT message uart_write(mm->data.ptr, mm->data.len); // Send to UART @@ -140,8 +144,14 @@ static void timer_fn(void *param) { for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) { if (c->data[0] == 'W') mg_ws_send(c, buf, len, WEBSOCKET_OP_TEXT); if (c->data[0] == 'T') mg_send(c, buf, len); - if (c->data[0] == 'M') - mg_mqtt_pub(c, mqtt_topic("tx", "b/tx"), mg_str_n(buf, len), 1, false); + if (c->data[0] == 'M') { + struct mg_mqtt_opts pub_opts; + memset(&pub_opts, 0, sizeof(pub_opts)); + pub_opts.topic = mqtt_topic("tx", "b/tx"); + pub_opts.message = mg_str_n(buf, len); + pub_opts.qos = 1, pub_opts.retain = false; + mg_mqtt_pub(c, &pub_opts); + } } } } diff --git a/examples/zephyr/mqtt-aws-client/src/main.c b/examples/zephyr/mqtt-aws-client/src/main.c index 716351df..75bde87a 100644 --- a/examples/zephyr/mqtt-aws-client/src/main.c +++ b/examples/zephyr/mqtt-aws-client/src/main.c @@ -31,7 +31,11 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { struct mg_str topic = mg_str(s_rx_topic); MG_INFO(("Connected to %s", s_url)); MG_INFO(("Subscribing to %s", s_rx_topic)); - mg_mqtt_sub(c, topic, s_qos); + struct mg_mqtt_opts sub_opts; + memset(&sub_opts, 0, sizeof(sub_opts)); + sub_opts.topic = topic; + sub_opts.qos = s_qos; + mg_mqtt_sub(c, &sub_opts); c->data[0] = 'X'; // Set a label that we're logged in } else if (ev == MG_EV_MQTT_MSG) { // When we receive MQTT message, print it @@ -44,7 +48,12 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { if (now_second != prev_second) { struct mg_str topic = mg_str(s_tx_topic), data = mg_str("{\"a\":123}"); MG_INFO(("Publishing to %s", s_tx_topic)); - mg_mqtt_pub(c, topic, data, s_qos, false); + struct mg_mqtt_opts pub_opts; + memset(&pub_opts, 0, sizeof(pub_opts)); + pub_opts.topic = topic; + pub_opts.message = data; + pub_opts.qos = s_qos, pub_opts.retain = false; + mg_mqtt_pub(c, &pub_opts); prev_second = now_second; } } diff --git a/mongoose.c b/mongoose.c index 3383a9be..e1e97fbc 100644 --- a/mongoose.c +++ b/mongoose.c @@ -2920,22 +2920,228 @@ void mg_md5_final(mg_md5_ctx *ctx, unsigned char digest[16]) { void mg_mqtt_send_header(struct mg_connection *c, uint8_t cmd, uint8_t flags, uint32_t len) { uint8_t buf[1 + sizeof(len)], *vlen = &buf[1]; - buf[0] = (uint8_t) ((cmd << 4) | flags); + buf[0] = (uint8_t)((cmd << 4) | flags); do { *vlen = len % 0x80; len /= 0x80; if (len > 0) *vlen |= 0x80; vlen++; } while (len > 0 && vlen < &buf[sizeof(buf)]); - mg_send(c, buf, (size_t) (vlen - buf)); + mg_send(c, buf, (size_t)(vlen - buf)); } static void mg_send_u16(struct mg_connection *c, uint16_t value) { mg_send(c, &value, sizeof(value)); } +static void mg_send_u32(struct mg_connection *c, uint32_t value) { + mg_send(c, &value, sizeof(value)); +} + +static uint8_t compute_variable_length_size(uint32_t length) { + uint8_t bytes_needed = 0; + do { + bytes_needed++; + length /= 0x80; + } while (length > 0); + + return bytes_needed; +} + +static int encode_variable_length(uint8_t *buf, int value) { + int len = 0; + + do { + uint8_t byte = (uint8_t)(value % 128); + value /= 128; + if (value > 0) byte |= 0x80; + buf[len++] = byte; + } while (value > 0); + + return len; +} + +static uint32_t decode_variable_length(const char *buf, + uint32_t *bytes_consumed) { + const uint8_t *p = (const uint8_t *) buf; + uint32_t value = 0; + uint32_t multiplier = 1; + uint8_t encoded_byte; + uint32_t offset; + + for (offset = 0; offset < 4; offset++) { + encoded_byte = p[offset]; + value += (encoded_byte & 0x7F) * multiplier; + multiplier *= 128; + + if (!(encoded_byte & 0x80)) break; + } + + if (bytes_consumed != NULL) *bytes_consumed = offset + 1; + + return value; +} + +static int mqtt_prop_type_by_id(uint8_t prop_id) { + size_t num_properties = sizeof(mqtt_prop_map) / sizeof(mqtt_prop_map[0]); + for (size_t i = 0; i < num_properties; ++i) { + if (mqtt_prop_map[i].id == prop_id) { + return mqtt_prop_map[i].type; + } + } + + return -1; // Property ID not found +} + +/* +returns the size of the properties section, without the +size of the content's length +*/ +static uint32_t get_properties_length(struct mg_mqtt_prop *props, int count) { + uint32_t size = 0; + for (int i = 0; i < count; i++) { + size++; // identifier + switch (mqtt_prop_type_by_id(props[i].id)) { + case MQTT_PROP_TYPE_STRING_PAIR: + size += (uint32_t)(props[i].val.len + props[i].key.len + + 2 * sizeof(uint16_t)); + break; + case MQTT_PROP_TYPE_STRING: + size += (uint32_t)(props[i].val.len + sizeof(uint16_t)); + break; + case MQTT_PROP_TYPE_BINARY_DATA: + size += (uint32_t)(props[i].val.len + sizeof(uint16_t)); + break; + case MQTT_PROP_TYPE_VARIABLE_INT: + size += compute_variable_length_size((uint32_t) props[i].iv); + break; + case MQTT_PROP_TYPE_INT: + size += (uint32_t) sizeof(uint32_t); + break; + case MQTT_PROP_TYPE_SHORT: + size += (uint32_t) sizeof(uint16_t); + break; + default: + return size; // cannot parse further down + } + } + + return size; +} + +/* +returns the entire size of the properties section, including the +size of the variable length of the content +*/ +static uint32_t get_full_properties_size(struct mg_mqtt_prop *props, + int count) { + uint32_t size = get_properties_length(props, count); + size += compute_variable_length_size(size); + return size; +} + +static void mg_send_mqtt_properties(struct mg_connection *c, + struct mg_mqtt_prop *props, int nr_props) { + uint32_t total_size = get_properties_length(props, nr_props); + uint8_t buf_v[4] = {0, 0, 0, 0}; + uint8_t buf[4] = {0, 0, 0, 0}; + int len = encode_variable_length(buf, (int) total_size); + + mg_send(c, buf, (size_t) len); + for (int i = 0; i < nr_props; i++) { + mg_send(c, &props[i].id, sizeof(props[i].id)); + switch (mqtt_prop_type_by_id(props[i].id)) { + case MQTT_PROP_TYPE_STRING_PAIR: + mg_send_u16(c, mg_htons((uint16_t) props[i].key.len)); + mg_send(c, props[i].key.ptr, props[i].key.len); + mg_send_u16(c, mg_htons((uint16_t) props[i].val.len)); + mg_send(c, props[i].val.ptr, props[i].val.len); + break; + case MQTT_PROP_TYPE_BYTE: + mg_send(c, &props[i].iv, sizeof(uint8_t)); + break; + case MQTT_PROP_TYPE_SHORT: + mg_send_u16(c, mg_htons((uint16_t) props[i].iv)); + break; + case MQTT_PROP_TYPE_INT: + mg_send_u32(c, mg_htonl((uint32_t) props[i].iv)); + break; + case MQTT_PROP_TYPE_STRING: + mg_send_u16(c, mg_htons((uint16_t) props[i].val.len)); + mg_send(c, props[i].val.ptr, props[i].val.len); + break; + case MQTT_PROP_TYPE_BINARY_DATA: + mg_send_u16(c, mg_htons((uint16_t) props[i].val.len)); + mg_send(c, props[i].val.ptr, props[i].val.len); + break; + case MQTT_PROP_TYPE_VARIABLE_INT: + len = encode_variable_length(buf_v, (int) props[i].iv); + mg_send(c, buf_v, (size_t) len); + break; + } + } +} + +size_t mg_mqtt_next_prop(struct mg_mqtt_message *msg, struct mg_mqtt_prop *prop, + size_t crt_pos) { + unsigned char *i = + (unsigned char *) msg->dgram.ptr + msg->props_start + crt_pos; + size_t new_pos = crt_pos; + uint32_t bytes_consumed; + + if (crt_pos >= msg->dgram.len || + crt_pos >= msg->props_start + msg->props_size) + return 0; + + uint8_t id = i[0]; + i++, new_pos++; + prop->id = id; + + switch (mqtt_prop_type_by_id(id)) { + case MQTT_PROP_TYPE_STRING_PAIR: + prop->key.len = (uint16_t)((((uint16_t) i[0]) << 8) | i[1]); + prop->key.ptr = (char *) i + 2; + i += 2 + prop->key.len; + prop->val.len = (uint16_t)((((uint16_t) i[0]) << 8) | i[1]); + prop->val.ptr = (char *) i + 2; + new_pos += 2 * sizeof(uint16_t) + prop->val.len + prop->key.len; + break; + case MQTT_PROP_TYPE_BYTE: + prop->iv = (uint8_t) i[0]; + new_pos++; + break; + case MQTT_PROP_TYPE_SHORT: + prop->iv = (uint16_t)((((uint16_t) i[0]) << 8) | i[1]); + new_pos += sizeof(uint16_t); + break; + case MQTT_PROP_TYPE_INT: + prop->iv = ((uint32_t) i[0] << 24) | ((uint32_t) i[1] << 16) | + ((uint32_t) i[2] << 8) | i[3]; + new_pos += sizeof(uint32_t); + break; + case MQTT_PROP_TYPE_STRING: + prop->val.len = (uint16_t)((((uint16_t) i[0]) << 8) | i[1]); + prop->val.ptr = (char *) i + 2; + new_pos += 2 + prop->val.len; + break; + case MQTT_PROP_TYPE_BINARY_DATA: + prop->val.len = (uint16_t)((((uint16_t) i[0]) << 8) | i[1]); + prop->val.ptr = (char *) i + 2; + new_pos += 2 + prop->val.len; + break; + case MQTT_PROP_TYPE_VARIABLE_INT: + prop->iv = decode_variable_length((char *) i, &bytes_consumed); + new_pos += bytes_consumed; + break; + default: + new_pos = 0; + } + + return new_pos; +} + void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts) { - char rnd[10], client_id[21], zero = 0; + char rnd[10], client_id[21]; struct mg_str cid = opts->client_id; uint32_t total_len = 7 + 1 + 2 + 2; uint8_t hdr[8] = {0, 4, 'M', 'Q', 'T', 'T', opts->version, 0}; @@ -2949,7 +3155,7 @@ void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts) { if (hdr[6] == 0) hdr[6] = 4; // If version is not set, use 4 (3.1.1) c->is_mqtt5 = hdr[6] == 5; // Set version 5 flag - hdr[7] = (uint8_t) ((opts->will_qos & 3) << 3); // Connection flags + hdr[7] = (uint8_t)((opts->qos & 3) << 3); // Connection flags if (opts->user.len > 0) { total_len += 2 + (uint32_t) opts->user.len; hdr[7] |= MQTT_HAS_USER_NAME; @@ -2958,31 +3164,38 @@ void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts) { total_len += 2 + (uint32_t) opts->pass.len; hdr[7] |= MQTT_HAS_PASSWORD; } - if (opts->will_topic.len > 0 && opts->will_message.len > 0) { - total_len += - 4 + (uint32_t) opts->will_topic.len + (uint32_t) opts->will_message.len; + if (opts->topic.len > 0 && opts->message.len > 0) { + total_len += 4 + (uint32_t) opts->topic.len + (uint32_t) opts->message.len; hdr[7] |= MQTT_HAS_WILL; } if (opts->clean || cid.len == 0) hdr[7] |= MQTT_CLEAN_SESSION; - if (opts->will_retain) hdr[7] |= MQTT_WILL_RETAIN; + if (opts->retain) hdr[7] |= MQTT_WILL_RETAIN; total_len += (uint32_t) cid.len; - if (c->is_mqtt5) total_len += 1U + (hdr[7] & MQTT_HAS_WILL ? 1U : 0); + if (c->is_mqtt5) { + total_len += get_full_properties_size(opts->props, opts->num_props); + if (hdr[7] & MQTT_HAS_WILL) + total_len += get_full_properties_size(opts->will_props, + opts->num_will_props); + } mg_mqtt_send_header(c, MQTT_CMD_CONNECT, 0, total_len); mg_send(c, hdr, sizeof(hdr)); // keepalive == 0 means "do not disconnect us!" mg_send_u16(c, mg_htons((uint16_t) opts->keepalive)); - if (c->is_mqtt5) mg_send(c, &zero, sizeof(zero)); // V5 properties + if (c->is_mqtt5) mg_send_mqtt_properties(c, opts->props, opts->num_props); + mg_send_u16(c, mg_htons((uint16_t) cid.len)); mg_send(c, cid.ptr, cid.len); if (hdr[7] & MQTT_HAS_WILL) { - if (c->is_mqtt5) mg_send(c, &zero, sizeof(zero)); // will props - mg_send_u16(c, mg_htons((uint16_t) opts->will_topic.len)); - mg_send(c, opts->will_topic.ptr, opts->will_topic.len); - mg_send_u16(c, mg_htons((uint16_t) opts->will_message.len)); - mg_send(c, opts->will_message.ptr, opts->will_message.len); + if (c->is_mqtt5) + mg_send_mqtt_properties(c, opts->will_props, opts->num_will_props); + + mg_send_u16(c, mg_htons((uint16_t) opts->topic.len)); + mg_send(c, opts->topic.ptr, opts->topic.len); + mg_send_u16(c, mg_htons((uint16_t) opts->message.len)); + mg_send(c, opts->message.ptr, opts->message.len); } if (opts->user.len > 0) { mg_send_u16(c, mg_htons((uint16_t) opts->user.len)); @@ -2994,34 +3207,43 @@ void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts) { } } -void mg_mqtt_pub(struct mg_connection *c, struct mg_str topic, - struct mg_str data, int qos, bool retain) { - uint8_t flags = (uint8_t) (((qos & 3) << 1) | (retain ? 1 : 0)), zero = 0; - uint32_t len = 2 + (uint32_t) topic.len + (uint32_t) data.len; - MG_DEBUG(("%lu [%.*s] -> [%.*s]", c->id, (int) topic.len, (char *) topic.ptr, - (int) data.len, (char *) data.ptr)); - if (qos > 0) len += 2; - if (c->is_mqtt5) len++; +void mg_mqtt_pub(struct mg_connection *c, const struct mg_mqtt_opts *opts) { + uint8_t flags = (uint8_t)(((opts->qos & 3) << 1) | (opts->retain ? 1 : 0)); + uint32_t len = 2 + (uint32_t) opts->topic.len + (uint32_t) opts->message.len; + MG_DEBUG(("%lu [%.*s] -> [%.*s]", c->id, (int) opts->topic.len, + (char *) opts->topic.ptr, (int) opts->message.len, + (char *) opts->message.ptr)); + if (opts->qos > 0) len += 2; + if (c->is_mqtt5) + len += get_full_properties_size(opts->props, opts->num_props); + mg_mqtt_send_header(c, MQTT_CMD_PUBLISH, flags, len); - mg_send_u16(c, mg_htons((uint16_t) topic.len)); - mg_send(c, topic.ptr, topic.len); - if (qos > 0) { + mg_send_u16(c, mg_htons((uint16_t) opts->topic.len)); + mg_send(c, opts->topic.ptr, opts->topic.len); + if (opts->qos > 0) { if (++c->mgr->mqtt_id == 0) ++c->mgr->mqtt_id; mg_send_u16(c, mg_htons(c->mgr->mqtt_id)); } - if (c->is_mqtt5) mg_send(c, &zero, sizeof(zero)); - mg_send(c, data.ptr, data.len); + + if (c->is_mqtt5) mg_send_mqtt_properties(c, opts->props, opts->num_props); + + mg_send(c, opts->message.ptr, opts->message.len); } -void mg_mqtt_sub(struct mg_connection *c, struct mg_str topic, int qos) { - uint8_t qos_ = qos & 3, zero = 0; - uint32_t len = 2 + (uint32_t) topic.len + 2 + 1 + (c->is_mqtt5 ? 1 : 0); +void mg_mqtt_sub(struct mg_connection *c, const struct mg_mqtt_opts *opts) { + uint8_t qos_ = opts->qos & 3; + uint32_t len = + 2 + (uint32_t) opts->topic.len + 2 + 1 + + (c->is_mqtt5 ? get_full_properties_size(opts->props, opts->num_props) + : 0); + mg_mqtt_send_header(c, MQTT_CMD_SUBSCRIBE, 2, len); if (++c->mgr->mqtt_id == 0) ++c->mgr->mqtt_id; mg_send_u16(c, mg_htons(c->mgr->mqtt_id)); - if (c->is_mqtt5) mg_send(c, &zero, sizeof(zero)); - mg_send_u16(c, mg_htons((uint16_t) topic.len)); - mg_send(c, topic.ptr, topic.len); + if (c->is_mqtt5) mg_send_mqtt_properties(c, opts->props, opts->num_props); + + mg_send_u16(c, mg_htons((uint16_t) opts->topic.len)); + mg_send(c, opts->topic.ptr, opts->topic.len); mg_send(c, &qos_, sizeof(qos_)); } @@ -3033,21 +3255,21 @@ int mg_mqtt_parse(const uint8_t *buf, size_t len, uint8_t version, memset(m, 0, sizeof(*m)); m->dgram.ptr = (char *) buf; if (len < 2) return MQTT_INCOMPLETE; - m->cmd = (uint8_t) (buf[0] >> 4); + m->cmd = (uint8_t)(buf[0] >> 4); m->qos = (buf[0] >> 1) & 3; n = len_len = 0; p = (uint8_t *) buf + 1; - while ((size_t) (p - buf) < len) { + while ((size_t)(p - buf) < len) { lc = *((uint8_t *) p++); - n += (uint32_t) ((lc & 0x7f) << 7 * len_len); + n += (uint32_t)((lc & 0x7f) << 7 * len_len); len_len++; if (!(lc & 0x80)) break; if (len_len >= 4) return MQTT_MALFORMED; } end = p + n; if ((lc & 0x80) || (end > buf + len)) return MQTT_INCOMPLETE; - m->dgram.len = (size_t) (end - buf); + m->dgram.len = (size_t)(end - buf); switch (m->cmd) { case MQTT_CMD_CONNACK: @@ -3063,25 +3285,29 @@ int mg_mqtt_parse(const uint8_t *buf, size_t len, uint8_t version, case MQTT_CMD_UNSUBSCRIBE: case MQTT_CMD_UNSUBACK: if (p + 2 > end) return MQTT_MALFORMED; - m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]); + m->id = (uint16_t)((((uint16_t) p[0]) << 8) | p[1]); p += 2; break; case MQTT_CMD_PUBLISH: { if (p + 2 > end) return MQTT_MALFORMED; - m->topic.len = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]); + m->topic.len = (uint16_t)((((uint16_t) p[0]) << 8) | p[1]); m->topic.ptr = (char *) p + 2; p += 2 + m->topic.len; if (p > end) return MQTT_MALFORMED; if (m->qos > 0) { if (p + 2 > end) return MQTT_MALFORMED; - m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]); + m->id = (uint16_t)((((uint16_t) p[0]) << 8) | p[1]); p += 2; } if (p > end) return MQTT_MALFORMED; - if (version == 5 && p + 2 < end) p += 1 + p[0]; // Skip options + if (version == 5 && p + 2 < end) { + m->props_size = decode_variable_length((char *) p, &len_len); + m->props_start = (size_t)(p + len_len - buf); + p += len_len + m->props_size; + } if (p > end) return MQTT_MALFORMED; m->data.ptr = (char *) p; - m->data.len = (size_t) (end - p); + m->data.len = (size_t)(end - p); break; } default: @@ -3119,8 +3345,16 @@ static void mqtt_cb(struct mg_connection *c, int ev, void *ev_data, mm.topic.ptr, (int) mm.data.len, mm.data.ptr)); if (mm.qos > 0) { uint16_t id = mg_htons(mm.id); - mg_mqtt_send_header(c, MQTT_CMD_PUBACK, 0, sizeof(id)); + uint32_t remaining_len = sizeof(id); + if (c->is_mqtt5) remaining_len += 1; + + mg_mqtt_send_header(c, MQTT_CMD_PUBACK, 0, remaining_len); mg_send(c, &id, sizeof(id)); + + if (c->is_mqtt5) { + uint16_t zero = 0; + mg_send(c, &zero, sizeof(zero)); + } } mg_call(c, MG_EV_MQTT_MSG, &mm); break; @@ -3145,8 +3379,22 @@ void mg_mqtt_pong(struct mg_connection *nc) { mg_mqtt_send_header(nc, MQTT_CMD_PINGRESP, 0, 0); } -void mg_mqtt_disconnect(struct mg_connection *nc) { - mg_mqtt_send_header(nc, MQTT_CMD_DISCONNECT, 0, 0); +void mg_mqtt_disconnect(struct mg_connection *nc, + const struct mg_mqtt_opts *opts) { + uint32_t len; + + if (nc->is_mqtt5) + len = 1 + get_full_properties_size(opts->props, opts->num_props); + else + len = 0; + + mg_mqtt_send_header(nc, MQTT_CMD_DISCONNECT, 0, len); + + if (nc->is_mqtt5) { + uint8_t zero = 0; + mg_send(nc, &zero, sizeof(zero)); // reason code + mg_send_mqtt_properties(nc, opts->props, opts->num_props); + } } struct mg_connection *mg_mqtt_connect(struct mg_mgr *mgr, const char *url, @@ -4297,7 +4545,7 @@ bool mg_open_listener(struct mg_connection *c, const char *url) { #if defined(SO_REUSEADDR) && (!defined(LWIP_SOCKET) || SO_REUSE) } else if ((rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on))) != 0) { - // 1. SO_RESUSEADDR semantics on UNIX and Windows is different. On + // 1. SO_REUSEADDR semantics on UNIX and Windows is different. On // Windows, SO_REUSEADDR allows to bind a socket to a port without error // even if the port is already open by another program. This is not the // behavior SO_REUSEADDR was designed for, and leads to hard-to-track diff --git a/mongoose.h b/mongoose.h index 506872a5..f3b7bd11 100644 --- a/mongoose.h +++ b/mongoose.h @@ -1414,19 +1414,102 @@ int64_t mg_sntp_parse(const unsigned char *buf, size_t len); #define MQTT_CMD_DISCONNECT 14 #define MQTT_CMD_AUTH 15 +#define MQTT_PROP_PAYLOAD_FORMAT_INDICATOR 0x01 +#define MQTT_PROP_MESSAGE_EXPIRY_INTERVAL 0x02 +#define MQTT_PROP_CONTENT_TYPE 0x03 +#define MQTT_PROP_RESPONSE_TOPIC 0x08 +#define MQTT_PROP_CORRELATION_DATA 0x09 +#define MQTT_PROP_SUBSCRIPTION_IDENTIFIER 0x0B +#define MQTT_PROP_SESSION_EXPIRY_INTERVAL 0x11 +#define MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER 0x12 +#define MQTT_PROP_SERVER_KEEP_ALIVE 0x13 +#define MQTT_PROP_AUTHENTICATION_METHOD 0x15 +#define MQTT_PROP_AUTHENTICATION_DATA 0x16 +#define MQTT_PROP_REQUEST_PROBLEM_INFORMATION 0x17 +#define MQTT_PROP_WILL_DELAY_INTERVAL 0x18 +#define MQTT_PROP_REQUEST_RESPONSE_INFORMATION 0x19 +#define MQTT_PROP_RESPONSE_INFORMATION 0x1A +#define MQTT_PROP_SERVER_REFERENCE 0x1C +#define MQTT_PROP_REASON_STRING 0x1F +#define MQTT_PROP_RECEIVE_MAXIMUM 0x21 +#define MQTT_PROP_TOPIC_ALIAS_MAXIMUM 0x22 +#define MQTT_PROP_TOPIC_ALIAS 0x23 +#define MQTT_PROP_MAXIMUM_QOS 0x24 +#define MQTT_PROP_RETAIN_AVAILABLE 0x25 +#define MQTT_PROP_USER_PROPERTY 0x26 +#define MQTT_PROP_MAXIMUM_PACKET_SIZE 0x27 +#define MQTT_PROP_WILDCARD_SUBSCRIPTION_AVAILABLE 0x28 +#define MQTT_PROP_SUBSCRIPTION_IDENTIFIER_AVAILABLE 0x29 +#define MQTT_PROP_SHARED_SUBSCRIPTION_AVAILABLE 0x2A + +enum { + MQTT_PROP_TYPE_BYTE, + MQTT_PROP_TYPE_STRING, + MQTT_PROP_TYPE_STRING_PAIR, + MQTT_PROP_TYPE_BINARY_DATA, + MQTT_PROP_TYPE_VARIABLE_INT, + MQTT_PROP_TYPE_INT, + MQTT_PROP_TYPE_SHORT +}; + enum { MQTT_OK, MQTT_INCOMPLETE, MQTT_MALFORMED }; +struct mqtt_prop_map_t { + uint8_t id; + uint8_t type; +}; + +static const struct mqtt_prop_map_t mqtt_prop_map[] = { + {MQTT_PROP_PAYLOAD_FORMAT_INDICATOR, MQTT_PROP_TYPE_BYTE}, + {MQTT_PROP_MESSAGE_EXPIRY_INTERVAL, MQTT_PROP_TYPE_INT}, + {MQTT_PROP_CONTENT_TYPE, MQTT_PROP_TYPE_STRING}, + {MQTT_PROP_RESPONSE_TOPIC, MQTT_PROP_TYPE_STRING}, + {MQTT_PROP_CORRELATION_DATA, MQTT_PROP_TYPE_BINARY_DATA}, + {MQTT_PROP_SUBSCRIPTION_IDENTIFIER, MQTT_PROP_TYPE_VARIABLE_INT}, + {MQTT_PROP_SESSION_EXPIRY_INTERVAL, MQTT_PROP_TYPE_INT}, + {MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER, MQTT_PROP_TYPE_STRING}, + {MQTT_PROP_SERVER_KEEP_ALIVE, MQTT_PROP_TYPE_SHORT}, + {MQTT_PROP_AUTHENTICATION_METHOD, MQTT_PROP_TYPE_STRING}, + {MQTT_PROP_AUTHENTICATION_DATA, MQTT_PROP_TYPE_BINARY_DATA}, + {MQTT_PROP_REQUEST_PROBLEM_INFORMATION, MQTT_PROP_TYPE_BYTE}, + {MQTT_PROP_WILL_DELAY_INTERVAL, MQTT_PROP_TYPE_INT}, + {MQTT_PROP_REQUEST_RESPONSE_INFORMATION, MQTT_PROP_TYPE_BYTE}, + {MQTT_PROP_RESPONSE_INFORMATION, MQTT_PROP_TYPE_STRING}, + {MQTT_PROP_SERVER_REFERENCE, MQTT_PROP_TYPE_STRING}, + {MQTT_PROP_REASON_STRING, MQTT_PROP_TYPE_STRING}, + {MQTT_PROP_RECEIVE_MAXIMUM, MQTT_PROP_TYPE_SHORT}, + {MQTT_PROP_TOPIC_ALIAS_MAXIMUM, MQTT_PROP_TYPE_SHORT}, + {MQTT_PROP_TOPIC_ALIAS, MQTT_PROP_TYPE_SHORT}, + {MQTT_PROP_MAXIMUM_QOS, MQTT_PROP_TYPE_BYTE}, + {MQTT_PROP_RETAIN_AVAILABLE, MQTT_PROP_TYPE_BYTE}, + {MQTT_PROP_USER_PROPERTY, MQTT_PROP_TYPE_STRING_PAIR}, + {MQTT_PROP_MAXIMUM_PACKET_SIZE, MQTT_PROP_TYPE_INT}, + {MQTT_PROP_WILDCARD_SUBSCRIPTION_AVAILABLE, MQTT_PROP_TYPE_BYTE}, + {MQTT_PROP_SUBSCRIPTION_IDENTIFIER_AVAILABLE, MQTT_PROP_TYPE_BYTE}, + {MQTT_PROP_SHARED_SUBSCRIPTION_AVAILABLE, MQTT_PROP_TYPE_BYTE}}; + +struct mg_mqtt_prop { + uint8_t id; // Enumerated at MQTT5 Reference + uint32_t iv; // integer value for 8-, 16-, 32-bit integers types + struct mg_str key; // non-NULL only for user property type + struct mg_str val; // non-NULL only for UTF-8 types and user properties +}; + struct mg_mqtt_opts { struct mg_str user; // Username, can be empty struct mg_str pass; // Password, can be empty struct mg_str client_id; // Client ID - struct mg_str will_topic; // Will topic - struct mg_str will_message; // Will message - uint8_t will_qos; // Will message quality of service + struct mg_str topic; // topic + struct mg_str message; // message + uint8_t qos; // message quality of service uint8_t version; // Can be 4 (3.1.1), or 5. If 0, assume 4. uint16_t keepalive; // Keep-alive timer in seconds - bool will_retain; // Retain last will + bool retain; // Retain last will bool clean; // Use clean session, 0 or 1 + struct mg_mqtt_prop *props; // MQTT5 props array + int num_props; // number of props + struct mg_mqtt_prop *will_props; // only found in the CONNECT packet + int num_will_props; // number of will props }; struct mg_mqtt_message { @@ -1437,6 +1520,8 @@ struct mg_mqtt_message { uint8_t cmd; // MQTT command, one of MQTT_CMD_* uint8_t qos; // Quality of service uint8_t ack; // Connack return code. 0 - success + size_t props_start; // offset to the start of the properties + size_t props_size; // length of the properties }; struct mg_connection *mg_mqtt_connect(struct mg_mgr *, const char *url, @@ -1445,15 +1530,17 @@ struct mg_connection *mg_mqtt_connect(struct mg_mgr *, const char *url, struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url, mg_event_handler_t fn, void *fn_data); void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts); -void mg_mqtt_pub(struct mg_connection *c, struct mg_str topic, - struct mg_str data, int qos, bool retain); -void mg_mqtt_sub(struct mg_connection *, struct mg_str topic, int qos); +void mg_mqtt_pub(struct mg_connection *c, const struct mg_mqtt_opts *opts); +void mg_mqtt_sub(struct mg_connection *, const struct mg_mqtt_opts *opts); int mg_mqtt_parse(const uint8_t *, size_t, uint8_t, struct mg_mqtt_message *); void mg_mqtt_send_header(struct mg_connection *, uint8_t cmd, uint8_t flags, uint32_t len); void mg_mqtt_ping(struct mg_connection *); void mg_mqtt_pong(struct mg_connection *); -void mg_mqtt_disconnect(struct mg_connection *); +void mg_mqtt_disconnect(struct mg_connection *, + const struct mg_mqtt_opts *opts); +size_t mg_mqtt_next_prop(struct mg_mqtt_message *, struct mg_mqtt_prop *, + size_t ofs); diff --git a/src/mqtt.c b/src/mqtt.c index 726cdc41..c003bbcc 100644 --- a/src/mqtt.c +++ b/src/mqtt.c @@ -15,22 +15,228 @@ void mg_mqtt_send_header(struct mg_connection *c, uint8_t cmd, uint8_t flags, uint32_t len) { uint8_t buf[1 + sizeof(len)], *vlen = &buf[1]; - buf[0] = (uint8_t) ((cmd << 4) | flags); + buf[0] = (uint8_t)((cmd << 4) | flags); do { *vlen = len % 0x80; len /= 0x80; if (len > 0) *vlen |= 0x80; vlen++; } while (len > 0 && vlen < &buf[sizeof(buf)]); - mg_send(c, buf, (size_t) (vlen - buf)); + mg_send(c, buf, (size_t)(vlen - buf)); } static void mg_send_u16(struct mg_connection *c, uint16_t value) { mg_send(c, &value, sizeof(value)); } +static void mg_send_u32(struct mg_connection *c, uint32_t value) { + mg_send(c, &value, sizeof(value)); +} + +static uint8_t compute_variable_length_size(uint32_t length) { + uint8_t bytes_needed = 0; + do { + bytes_needed++; + length /= 0x80; + } while (length > 0); + + return bytes_needed; +} + +static int encode_variable_length(uint8_t *buf, int value) { + int len = 0; + + do { + uint8_t byte = (uint8_t)(value % 128); + value /= 128; + if (value > 0) byte |= 0x80; + buf[len++] = byte; + } while (value > 0); + + return len; +} + +static uint32_t decode_variable_length(const char *buf, + uint32_t *bytes_consumed) { + const uint8_t *p = (const uint8_t *) buf; + uint32_t value = 0; + uint32_t multiplier = 1; + uint8_t encoded_byte; + uint32_t offset; + + for (offset = 0; offset < 4; offset++) { + encoded_byte = p[offset]; + value += (encoded_byte & 0x7F) * multiplier; + multiplier *= 128; + + if (!(encoded_byte & 0x80)) break; + } + + if (bytes_consumed != NULL) *bytes_consumed = offset + 1; + + return value; +} + +static int mqtt_prop_type_by_id(uint8_t prop_id) { + size_t num_properties = sizeof(mqtt_prop_map) / sizeof(mqtt_prop_map[0]); + for (size_t i = 0; i < num_properties; ++i) { + if (mqtt_prop_map[i].id == prop_id) { + return mqtt_prop_map[i].type; + } + } + + return -1; // Property ID not found +} + +/* +returns the size of the properties section, without the +size of the content's length +*/ +static uint32_t get_properties_length(struct mg_mqtt_prop *props, int count) { + uint32_t size = 0; + for (int i = 0; i < count; i++) { + size++; // identifier + switch (mqtt_prop_type_by_id(props[i].id)) { + case MQTT_PROP_TYPE_STRING_PAIR: + size += (uint32_t)(props[i].val.len + props[i].key.len + + 2 * sizeof(uint16_t)); + break; + case MQTT_PROP_TYPE_STRING: + size += (uint32_t)(props[i].val.len + sizeof(uint16_t)); + break; + case MQTT_PROP_TYPE_BINARY_DATA: + size += (uint32_t)(props[i].val.len + sizeof(uint16_t)); + break; + case MQTT_PROP_TYPE_VARIABLE_INT: + size += compute_variable_length_size((uint32_t) props[i].iv); + break; + case MQTT_PROP_TYPE_INT: + size += (uint32_t) sizeof(uint32_t); + break; + case MQTT_PROP_TYPE_SHORT: + size += (uint32_t) sizeof(uint16_t); + break; + default: + return size; // cannot parse further down + } + } + + return size; +} + +/* +returns the entire size of the properties section, including the +size of the variable length of the content +*/ +static uint32_t get_full_properties_size(struct mg_mqtt_prop *props, + int count) { + uint32_t size = get_properties_length(props, count); + size += compute_variable_length_size(size); + return size; +} + +static void mg_send_mqtt_properties(struct mg_connection *c, + struct mg_mqtt_prop *props, int nr_props) { + uint32_t total_size = get_properties_length(props, nr_props); + uint8_t buf_v[4] = {0, 0, 0, 0}; + uint8_t buf[4] = {0, 0, 0, 0}; + int len = encode_variable_length(buf, (int) total_size); + + mg_send(c, buf, (size_t) len); + for (int i = 0; i < nr_props; i++) { + mg_send(c, &props[i].id, sizeof(props[i].id)); + switch (mqtt_prop_type_by_id(props[i].id)) { + case MQTT_PROP_TYPE_STRING_PAIR: + mg_send_u16(c, mg_htons((uint16_t) props[i].key.len)); + mg_send(c, props[i].key.ptr, props[i].key.len); + mg_send_u16(c, mg_htons((uint16_t) props[i].val.len)); + mg_send(c, props[i].val.ptr, props[i].val.len); + break; + case MQTT_PROP_TYPE_BYTE: + mg_send(c, &props[i].iv, sizeof(uint8_t)); + break; + case MQTT_PROP_TYPE_SHORT: + mg_send_u16(c, mg_htons((uint16_t) props[i].iv)); + break; + case MQTT_PROP_TYPE_INT: + mg_send_u32(c, mg_htonl((uint32_t) props[i].iv)); + break; + case MQTT_PROP_TYPE_STRING: + mg_send_u16(c, mg_htons((uint16_t) props[i].val.len)); + mg_send(c, props[i].val.ptr, props[i].val.len); + break; + case MQTT_PROP_TYPE_BINARY_DATA: + mg_send_u16(c, mg_htons((uint16_t) props[i].val.len)); + mg_send(c, props[i].val.ptr, props[i].val.len); + break; + case MQTT_PROP_TYPE_VARIABLE_INT: + len = encode_variable_length(buf_v, (int) props[i].iv); + mg_send(c, buf_v, (size_t) len); + break; + } + } +} + +size_t mg_mqtt_next_prop(struct mg_mqtt_message *msg, struct mg_mqtt_prop *prop, + size_t crt_pos) { + unsigned char *i = + (unsigned char *) msg->dgram.ptr + msg->props_start + crt_pos; + size_t new_pos = crt_pos; + uint32_t bytes_consumed; + + if (crt_pos >= msg->dgram.len || + crt_pos >= msg->props_start + msg->props_size) + return 0; + + uint8_t id = i[0]; + i++, new_pos++; + prop->id = id; + + switch (mqtt_prop_type_by_id(id)) { + case MQTT_PROP_TYPE_STRING_PAIR: + prop->key.len = (uint16_t)((((uint16_t) i[0]) << 8) | i[1]); + prop->key.ptr = (char *) i + 2; + i += 2 + prop->key.len; + prop->val.len = (uint16_t)((((uint16_t) i[0]) << 8) | i[1]); + prop->val.ptr = (char *) i + 2; + new_pos += 2 * sizeof(uint16_t) + prop->val.len + prop->key.len; + break; + case MQTT_PROP_TYPE_BYTE: + prop->iv = (uint8_t) i[0]; + new_pos++; + break; + case MQTT_PROP_TYPE_SHORT: + prop->iv = (uint16_t)((((uint16_t) i[0]) << 8) | i[1]); + new_pos += sizeof(uint16_t); + break; + case MQTT_PROP_TYPE_INT: + prop->iv = ((uint32_t) i[0] << 24) | ((uint32_t) i[1] << 16) | + ((uint32_t) i[2] << 8) | i[3]; + new_pos += sizeof(uint32_t); + break; + case MQTT_PROP_TYPE_STRING: + prop->val.len = (uint16_t)((((uint16_t) i[0]) << 8) | i[1]); + prop->val.ptr = (char *) i + 2; + new_pos += 2 + prop->val.len; + break; + case MQTT_PROP_TYPE_BINARY_DATA: + prop->val.len = (uint16_t)((((uint16_t) i[0]) << 8) | i[1]); + prop->val.ptr = (char *) i + 2; + new_pos += 2 + prop->val.len; + break; + case MQTT_PROP_TYPE_VARIABLE_INT: + prop->iv = decode_variable_length((char *) i, &bytes_consumed); + new_pos += bytes_consumed; + break; + default: + new_pos = 0; + } + + return new_pos; +} + void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts) { - char rnd[10], client_id[21], zero = 0; + char rnd[10], client_id[21]; struct mg_str cid = opts->client_id; uint32_t total_len = 7 + 1 + 2 + 2; uint8_t hdr[8] = {0, 4, 'M', 'Q', 'T', 'T', opts->version, 0}; @@ -44,7 +250,7 @@ void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts) { if (hdr[6] == 0) hdr[6] = 4; // If version is not set, use 4 (3.1.1) c->is_mqtt5 = hdr[6] == 5; // Set version 5 flag - hdr[7] = (uint8_t) ((opts->will_qos & 3) << 3); // Connection flags + hdr[7] = (uint8_t)((opts->qos & 3) << 3); // Connection flags if (opts->user.len > 0) { total_len += 2 + (uint32_t) opts->user.len; hdr[7] |= MQTT_HAS_USER_NAME; @@ -53,31 +259,38 @@ void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts) { total_len += 2 + (uint32_t) opts->pass.len; hdr[7] |= MQTT_HAS_PASSWORD; } - if (opts->will_topic.len > 0 && opts->will_message.len > 0) { - total_len += - 4 + (uint32_t) opts->will_topic.len + (uint32_t) opts->will_message.len; + if (opts->topic.len > 0 && opts->message.len > 0) { + total_len += 4 + (uint32_t) opts->topic.len + (uint32_t) opts->message.len; hdr[7] |= MQTT_HAS_WILL; } if (opts->clean || cid.len == 0) hdr[7] |= MQTT_CLEAN_SESSION; - if (opts->will_retain) hdr[7] |= MQTT_WILL_RETAIN; + if (opts->retain) hdr[7] |= MQTT_WILL_RETAIN; total_len += (uint32_t) cid.len; - if (c->is_mqtt5) total_len += 1U + (hdr[7] & MQTT_HAS_WILL ? 1U : 0); + if (c->is_mqtt5) { + total_len += get_full_properties_size(opts->props, opts->num_props); + if (hdr[7] & MQTT_HAS_WILL) + total_len += get_full_properties_size(opts->will_props, + opts->num_will_props); + } mg_mqtt_send_header(c, MQTT_CMD_CONNECT, 0, total_len); mg_send(c, hdr, sizeof(hdr)); // keepalive == 0 means "do not disconnect us!" mg_send_u16(c, mg_htons((uint16_t) opts->keepalive)); - if (c->is_mqtt5) mg_send(c, &zero, sizeof(zero)); // V5 properties + if (c->is_mqtt5) mg_send_mqtt_properties(c, opts->props, opts->num_props); + mg_send_u16(c, mg_htons((uint16_t) cid.len)); mg_send(c, cid.ptr, cid.len); if (hdr[7] & MQTT_HAS_WILL) { - if (c->is_mqtt5) mg_send(c, &zero, sizeof(zero)); // will props - mg_send_u16(c, mg_htons((uint16_t) opts->will_topic.len)); - mg_send(c, opts->will_topic.ptr, opts->will_topic.len); - mg_send_u16(c, mg_htons((uint16_t) opts->will_message.len)); - mg_send(c, opts->will_message.ptr, opts->will_message.len); + if (c->is_mqtt5) + mg_send_mqtt_properties(c, opts->will_props, opts->num_will_props); + + mg_send_u16(c, mg_htons((uint16_t) opts->topic.len)); + mg_send(c, opts->topic.ptr, opts->topic.len); + mg_send_u16(c, mg_htons((uint16_t) opts->message.len)); + mg_send(c, opts->message.ptr, opts->message.len); } if (opts->user.len > 0) { mg_send_u16(c, mg_htons((uint16_t) opts->user.len)); @@ -89,34 +302,43 @@ void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts) { } } -void mg_mqtt_pub(struct mg_connection *c, struct mg_str topic, - struct mg_str data, int qos, bool retain) { - uint8_t flags = (uint8_t) (((qos & 3) << 1) | (retain ? 1 : 0)), zero = 0; - uint32_t len = 2 + (uint32_t) topic.len + (uint32_t) data.len; - MG_DEBUG(("%lu [%.*s] -> [%.*s]", c->id, (int) topic.len, (char *) topic.ptr, - (int) data.len, (char *) data.ptr)); - if (qos > 0) len += 2; - if (c->is_mqtt5) len++; +void mg_mqtt_pub(struct mg_connection *c, const struct mg_mqtt_opts *opts) { + uint8_t flags = (uint8_t)(((opts->qos & 3) << 1) | (opts->retain ? 1 : 0)); + uint32_t len = 2 + (uint32_t) opts->topic.len + (uint32_t) opts->message.len; + MG_DEBUG(("%lu [%.*s] -> [%.*s]", c->id, (int) opts->topic.len, + (char *) opts->topic.ptr, (int) opts->message.len, + (char *) opts->message.ptr)); + if (opts->qos > 0) len += 2; + if (c->is_mqtt5) + len += get_full_properties_size(opts->props, opts->num_props); + mg_mqtt_send_header(c, MQTT_CMD_PUBLISH, flags, len); - mg_send_u16(c, mg_htons((uint16_t) topic.len)); - mg_send(c, topic.ptr, topic.len); - if (qos > 0) { + mg_send_u16(c, mg_htons((uint16_t) opts->topic.len)); + mg_send(c, opts->topic.ptr, opts->topic.len); + if (opts->qos > 0) { if (++c->mgr->mqtt_id == 0) ++c->mgr->mqtt_id; mg_send_u16(c, mg_htons(c->mgr->mqtt_id)); } - if (c->is_mqtt5) mg_send(c, &zero, sizeof(zero)); - mg_send(c, data.ptr, data.len); + + if (c->is_mqtt5) mg_send_mqtt_properties(c, opts->props, opts->num_props); + + mg_send(c, opts->message.ptr, opts->message.len); } -void mg_mqtt_sub(struct mg_connection *c, struct mg_str topic, int qos) { - uint8_t qos_ = qos & 3, zero = 0; - uint32_t len = 2 + (uint32_t) topic.len + 2 + 1 + (c->is_mqtt5 ? 1 : 0); +void mg_mqtt_sub(struct mg_connection *c, const struct mg_mqtt_opts *opts) { + uint8_t qos_ = opts->qos & 3; + uint32_t len = + 2 + (uint32_t) opts->topic.len + 2 + 1 + + (c->is_mqtt5 ? get_full_properties_size(opts->props, opts->num_props) + : 0); + mg_mqtt_send_header(c, MQTT_CMD_SUBSCRIBE, 2, len); if (++c->mgr->mqtt_id == 0) ++c->mgr->mqtt_id; mg_send_u16(c, mg_htons(c->mgr->mqtt_id)); - if (c->is_mqtt5) mg_send(c, &zero, sizeof(zero)); - mg_send_u16(c, mg_htons((uint16_t) topic.len)); - mg_send(c, topic.ptr, topic.len); + if (c->is_mqtt5) mg_send_mqtt_properties(c, opts->props, opts->num_props); + + mg_send_u16(c, mg_htons((uint16_t) opts->topic.len)); + mg_send(c, opts->topic.ptr, opts->topic.len); mg_send(c, &qos_, sizeof(qos_)); } @@ -128,21 +350,21 @@ int mg_mqtt_parse(const uint8_t *buf, size_t len, uint8_t version, memset(m, 0, sizeof(*m)); m->dgram.ptr = (char *) buf; if (len < 2) return MQTT_INCOMPLETE; - m->cmd = (uint8_t) (buf[0] >> 4); + m->cmd = (uint8_t)(buf[0] >> 4); m->qos = (buf[0] >> 1) & 3; n = len_len = 0; p = (uint8_t *) buf + 1; - while ((size_t) (p - buf) < len) { + while ((size_t)(p - buf) < len) { lc = *((uint8_t *) p++); - n += (uint32_t) ((lc & 0x7f) << 7 * len_len); + n += (uint32_t)((lc & 0x7f) << 7 * len_len); len_len++; if (!(lc & 0x80)) break; if (len_len >= 4) return MQTT_MALFORMED; } end = p + n; if ((lc & 0x80) || (end > buf + len)) return MQTT_INCOMPLETE; - m->dgram.len = (size_t) (end - buf); + m->dgram.len = (size_t)(end - buf); switch (m->cmd) { case MQTT_CMD_CONNACK: @@ -158,25 +380,29 @@ int mg_mqtt_parse(const uint8_t *buf, size_t len, uint8_t version, case MQTT_CMD_UNSUBSCRIBE: case MQTT_CMD_UNSUBACK: if (p + 2 > end) return MQTT_MALFORMED; - m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]); + m->id = (uint16_t)((((uint16_t) p[0]) << 8) | p[1]); p += 2; break; case MQTT_CMD_PUBLISH: { if (p + 2 > end) return MQTT_MALFORMED; - m->topic.len = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]); + m->topic.len = (uint16_t)((((uint16_t) p[0]) << 8) | p[1]); m->topic.ptr = (char *) p + 2; p += 2 + m->topic.len; if (p > end) return MQTT_MALFORMED; if (m->qos > 0) { if (p + 2 > end) return MQTT_MALFORMED; - m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]); + m->id = (uint16_t)((((uint16_t) p[0]) << 8) | p[1]); p += 2; } if (p > end) return MQTT_MALFORMED; - if (version == 5 && p + 2 < end) p += 1 + p[0]; // Skip options + if (version == 5 && p + 2 < end) { + m->props_size = decode_variable_length((char *) p, &len_len); + m->props_start = (size_t)(p + len_len - buf); + p += len_len + m->props_size; + } if (p > end) return MQTT_MALFORMED; m->data.ptr = (char *) p; - m->data.len = (size_t) (end - p); + m->data.len = (size_t)(end - p); break; } default: @@ -214,8 +440,16 @@ static void mqtt_cb(struct mg_connection *c, int ev, void *ev_data, mm.topic.ptr, (int) mm.data.len, mm.data.ptr)); if (mm.qos > 0) { uint16_t id = mg_htons(mm.id); - mg_mqtt_send_header(c, MQTT_CMD_PUBACK, 0, sizeof(id)); + uint32_t remaining_len = sizeof(id); + if (c->is_mqtt5) remaining_len += 1; + + mg_mqtt_send_header(c, MQTT_CMD_PUBACK, 0, remaining_len); mg_send(c, &id, sizeof(id)); + + if (c->is_mqtt5) { + uint16_t zero = 0; + mg_send(c, &zero, sizeof(zero)); + } } mg_call(c, MG_EV_MQTT_MSG, &mm); break; @@ -240,8 +474,22 @@ void mg_mqtt_pong(struct mg_connection *nc) { mg_mqtt_send_header(nc, MQTT_CMD_PINGRESP, 0, 0); } -void mg_mqtt_disconnect(struct mg_connection *nc) { - mg_mqtt_send_header(nc, MQTT_CMD_DISCONNECT, 0, 0); +void mg_mqtt_disconnect(struct mg_connection *nc, + const struct mg_mqtt_opts *opts) { + uint32_t len; + + if (nc->is_mqtt5) + len = 1 + get_full_properties_size(opts->props, opts->num_props); + else + len = 0; + + mg_mqtt_send_header(nc, MQTT_CMD_DISCONNECT, 0, len); + + if (nc->is_mqtt5) { + uint8_t zero = 0; + mg_send(nc, &zero, sizeof(zero)); // reason code + mg_send_mqtt_properties(nc, opts->props, opts->num_props); + } } struct mg_connection *mg_mqtt_connect(struct mg_mgr *mgr, const char *url, diff --git a/src/mqtt.h b/src/mqtt.h index f93619d5..f77906dd 100644 --- a/src/mqtt.h +++ b/src/mqtt.h @@ -19,19 +19,102 @@ #define MQTT_CMD_DISCONNECT 14 #define MQTT_CMD_AUTH 15 +#define MQTT_PROP_PAYLOAD_FORMAT_INDICATOR 0x01 +#define MQTT_PROP_MESSAGE_EXPIRY_INTERVAL 0x02 +#define MQTT_PROP_CONTENT_TYPE 0x03 +#define MQTT_PROP_RESPONSE_TOPIC 0x08 +#define MQTT_PROP_CORRELATION_DATA 0x09 +#define MQTT_PROP_SUBSCRIPTION_IDENTIFIER 0x0B +#define MQTT_PROP_SESSION_EXPIRY_INTERVAL 0x11 +#define MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER 0x12 +#define MQTT_PROP_SERVER_KEEP_ALIVE 0x13 +#define MQTT_PROP_AUTHENTICATION_METHOD 0x15 +#define MQTT_PROP_AUTHENTICATION_DATA 0x16 +#define MQTT_PROP_REQUEST_PROBLEM_INFORMATION 0x17 +#define MQTT_PROP_WILL_DELAY_INTERVAL 0x18 +#define MQTT_PROP_REQUEST_RESPONSE_INFORMATION 0x19 +#define MQTT_PROP_RESPONSE_INFORMATION 0x1A +#define MQTT_PROP_SERVER_REFERENCE 0x1C +#define MQTT_PROP_REASON_STRING 0x1F +#define MQTT_PROP_RECEIVE_MAXIMUM 0x21 +#define MQTT_PROP_TOPIC_ALIAS_MAXIMUM 0x22 +#define MQTT_PROP_TOPIC_ALIAS 0x23 +#define MQTT_PROP_MAXIMUM_QOS 0x24 +#define MQTT_PROP_RETAIN_AVAILABLE 0x25 +#define MQTT_PROP_USER_PROPERTY 0x26 +#define MQTT_PROP_MAXIMUM_PACKET_SIZE 0x27 +#define MQTT_PROP_WILDCARD_SUBSCRIPTION_AVAILABLE 0x28 +#define MQTT_PROP_SUBSCRIPTION_IDENTIFIER_AVAILABLE 0x29 +#define MQTT_PROP_SHARED_SUBSCRIPTION_AVAILABLE 0x2A + +enum { + MQTT_PROP_TYPE_BYTE, + MQTT_PROP_TYPE_STRING, + MQTT_PROP_TYPE_STRING_PAIR, + MQTT_PROP_TYPE_BINARY_DATA, + MQTT_PROP_TYPE_VARIABLE_INT, + MQTT_PROP_TYPE_INT, + MQTT_PROP_TYPE_SHORT +}; + enum { MQTT_OK, MQTT_INCOMPLETE, MQTT_MALFORMED }; +struct mqtt_prop_map_t { + uint8_t id; + uint8_t type; +}; + +static const struct mqtt_prop_map_t mqtt_prop_map[] = { + {MQTT_PROP_PAYLOAD_FORMAT_INDICATOR, MQTT_PROP_TYPE_BYTE}, + {MQTT_PROP_MESSAGE_EXPIRY_INTERVAL, MQTT_PROP_TYPE_INT}, + {MQTT_PROP_CONTENT_TYPE, MQTT_PROP_TYPE_STRING}, + {MQTT_PROP_RESPONSE_TOPIC, MQTT_PROP_TYPE_STRING}, + {MQTT_PROP_CORRELATION_DATA, MQTT_PROP_TYPE_BINARY_DATA}, + {MQTT_PROP_SUBSCRIPTION_IDENTIFIER, MQTT_PROP_TYPE_VARIABLE_INT}, + {MQTT_PROP_SESSION_EXPIRY_INTERVAL, MQTT_PROP_TYPE_INT}, + {MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER, MQTT_PROP_TYPE_STRING}, + {MQTT_PROP_SERVER_KEEP_ALIVE, MQTT_PROP_TYPE_SHORT}, + {MQTT_PROP_AUTHENTICATION_METHOD, MQTT_PROP_TYPE_STRING}, + {MQTT_PROP_AUTHENTICATION_DATA, MQTT_PROP_TYPE_BINARY_DATA}, + {MQTT_PROP_REQUEST_PROBLEM_INFORMATION, MQTT_PROP_TYPE_BYTE}, + {MQTT_PROP_WILL_DELAY_INTERVAL, MQTT_PROP_TYPE_INT}, + {MQTT_PROP_REQUEST_RESPONSE_INFORMATION, MQTT_PROP_TYPE_BYTE}, + {MQTT_PROP_RESPONSE_INFORMATION, MQTT_PROP_TYPE_STRING}, + {MQTT_PROP_SERVER_REFERENCE, MQTT_PROP_TYPE_STRING}, + {MQTT_PROP_REASON_STRING, MQTT_PROP_TYPE_STRING}, + {MQTT_PROP_RECEIVE_MAXIMUM, MQTT_PROP_TYPE_SHORT}, + {MQTT_PROP_TOPIC_ALIAS_MAXIMUM, MQTT_PROP_TYPE_SHORT}, + {MQTT_PROP_TOPIC_ALIAS, MQTT_PROP_TYPE_SHORT}, + {MQTT_PROP_MAXIMUM_QOS, MQTT_PROP_TYPE_BYTE}, + {MQTT_PROP_RETAIN_AVAILABLE, MQTT_PROP_TYPE_BYTE}, + {MQTT_PROP_USER_PROPERTY, MQTT_PROP_TYPE_STRING_PAIR}, + {MQTT_PROP_MAXIMUM_PACKET_SIZE, MQTT_PROP_TYPE_INT}, + {MQTT_PROP_WILDCARD_SUBSCRIPTION_AVAILABLE, MQTT_PROP_TYPE_BYTE}, + {MQTT_PROP_SUBSCRIPTION_IDENTIFIER_AVAILABLE, MQTT_PROP_TYPE_BYTE}, + {MQTT_PROP_SHARED_SUBSCRIPTION_AVAILABLE, MQTT_PROP_TYPE_BYTE}}; + +struct mg_mqtt_prop { + uint8_t id; // Enumerated at MQTT5 Reference + uint32_t iv; // integer value for 8-, 16-, 32-bit integers types + struct mg_str key; // non-NULL only for user property type + struct mg_str val; // non-NULL only for UTF-8 types and user properties +}; + struct mg_mqtt_opts { struct mg_str user; // Username, can be empty struct mg_str pass; // Password, can be empty struct mg_str client_id; // Client ID - struct mg_str will_topic; // Will topic - struct mg_str will_message; // Will message - uint8_t will_qos; // Will message quality of service + struct mg_str topic; // topic + struct mg_str message; // message + uint8_t qos; // message quality of service uint8_t version; // Can be 4 (3.1.1), or 5. If 0, assume 4. uint16_t keepalive; // Keep-alive timer in seconds - bool will_retain; // Retain last will + bool retain; // Retain last will bool clean; // Use clean session, 0 or 1 + struct mg_mqtt_prop *props; // MQTT5 props array + int num_props; // number of props + struct mg_mqtt_prop *will_props; // only found in the CONNECT packet + int num_will_props; // number of will props }; struct mg_mqtt_message { @@ -42,6 +125,8 @@ struct mg_mqtt_message { uint8_t cmd; // MQTT command, one of MQTT_CMD_* uint8_t qos; // Quality of service uint8_t ack; // Connack return code. 0 - success + size_t props_start; // offset to the start of the properties + size_t props_size; // length of the properties }; struct mg_connection *mg_mqtt_connect(struct mg_mgr *, const char *url, @@ -50,12 +135,14 @@ struct mg_connection *mg_mqtt_connect(struct mg_mgr *, const char *url, struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url, mg_event_handler_t fn, void *fn_data); void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts); -void mg_mqtt_pub(struct mg_connection *c, struct mg_str topic, - struct mg_str data, int qos, bool retain); -void mg_mqtt_sub(struct mg_connection *, struct mg_str topic, int qos); +void mg_mqtt_pub(struct mg_connection *c, const struct mg_mqtt_opts *opts); +void mg_mqtt_sub(struct mg_connection *, const struct mg_mqtt_opts *opts); int mg_mqtt_parse(const uint8_t *, size_t, uint8_t, struct mg_mqtt_message *); void mg_mqtt_send_header(struct mg_connection *, uint8_t cmd, uint8_t flags, uint32_t len); void mg_mqtt_ping(struct mg_connection *); void mg_mqtt_pong(struct mg_connection *); -void mg_mqtt_disconnect(struct mg_connection *); +void mg_mqtt_disconnect(struct mg_connection *, + const struct mg_mqtt_opts *opts); +size_t mg_mqtt_next_prop(struct mg_mqtt_message *, struct mg_mqtt_prop *, + size_t ofs); diff --git a/test/unit_test.c b/test/unit_test.c index 894c766e..325c9a4a 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -350,6 +350,7 @@ struct mqtt_data { static void mqtt_cb(struct mg_connection *c, int ev, void *evd, void *fnd) { struct mqtt_data *test_data = (struct mqtt_data *) fnd; char *buf = test_data->buf; + if (ev == MG_EV_MQTT_OPEN) { buf[0] = *(int *) evd == 0 ? 'X' : 'Y'; } else if (ev == MG_EV_MQTT_CMD) { @@ -364,10 +365,56 @@ static void mqtt_cb(struct mg_connection *c, int ev, void *evd, void *fnd) { struct mg_mqtt_message *mm = (struct mg_mqtt_message *) evd; snprintf(buf + 1, test_data->bufsize, "%.*s/%.*s", (int) mm->topic.len, mm->topic.ptr, (int) mm->data.len, mm->data.ptr); + + if (mm->cmd == MQTT_CMD_PUBLISH && c->is_mqtt5) { + size_t pos = 0; + struct mg_mqtt_prop prop; + + // note: the server will send the properties sorted by their ID + ASSERT((pos = mg_mqtt_next_prop(mm, &prop, pos)) > 0); + ASSERT(prop.iv == 10 && prop.id == MQTT_PROP_MESSAGE_EXPIRY_INTERVAL); + + ASSERT((pos = mg_mqtt_next_prop(mm, &prop, pos)) > 0); + ASSERT(prop.id == MQTT_PROP_CONTENT_TYPE); + ASSERT(strncmp(prop.val.ptr, "test_content_val_2", prop.val.len) == 0 && + prop.val.len == strlen("test_content_val_2")); + + ASSERT((pos = mg_mqtt_next_prop(mm, &prop, pos)) > 0); + ASSERT(prop.id == MQTT_PROP_USER_PROPERTY); + ASSERT(strncmp(prop.key.ptr, "test_key_1", prop.key.len) == 0 && + prop.key.len == strlen("test_key_1")); + ASSERT(strncmp(prop.val.ptr, "test_value_1", prop.val.len) == 0 && + prop.val.len == strlen("test_value_1")); + + ASSERT((pos = mg_mqtt_next_prop(mm, &prop, pos)) > 0); + ASSERT(prop.id == MQTT_PROP_USER_PROPERTY); + ASSERT(strncmp(prop.key.ptr, "test_key_2", prop.key.len) == 0 && + prop.key.len == strlen("test_key_2")); + ASSERT(strncmp(prop.val.ptr, "test_value_2", prop.val.len) == 0 && + prop.val.len == strlen("test_value_2")); + + ASSERT((pos = mg_mqtt_next_prop(mm, &prop, pos)) == 0); + } } (void) c; } +static void construct_props(struct mg_mqtt_prop *props) { + props[0].id = MQTT_PROP_MESSAGE_EXPIRY_INTERVAL; + props[0].iv = 10; + + props[1].id = MQTT_PROP_USER_PROPERTY; + props[1].key = mg_str("test_key_1"); + props[1].val = mg_str("test_value_1"); + + props[2].id = MQTT_PROP_USER_PROPERTY; + props[2].key = mg_str("test_key_2"); + props[2].val = mg_str("test_value_2"); + + props[3].id = MQTT_PROP_CONTENT_TYPE; + props[3].val = mg_str("test_content_val_2"); +} + static void test_mqtt_base(void); static void test_mqtt_base(void) { char buf[50] = {0}; @@ -396,6 +443,7 @@ static void test_mqtt_ver(uint8_t mqtt_version) { struct mg_str topic = mg_str("x/f12"), data = mg_str("hi"); struct mg_connection *c; struct mg_mqtt_opts opts; + struct mg_mqtt_prop properties[4]; const char *url = "mqtt://broker.hivemq.com:1883"; int i; mg_mgr_init(&mgr); @@ -406,11 +454,15 @@ static void test_mqtt_ver(uint8_t mqtt_version) { if (buf[0] != 'X') MG_INFO(("[%s]", buf)); ASSERT(buf[0] == 'X'); ASSERT(test_data.subscribed == 0); - mg_mqtt_sub(c, topic, 1); + + opts.topic = topic, opts.qos = 1; + mg_mqtt_sub(c, &opts); for (i = 0; i < 500 && test_data.subscribed == 0; i++) mg_mgr_poll(&mgr, 10); ASSERT(test_data.subscribed == 1); ASSERT(test_data.published == 0); - mg_mqtt_pub(c, topic, data, 1, false); + + opts.topic = topic, opts.message = data, opts.qos = 1, opts.retain = false; + mg_mqtt_pub(c, &opts); for (i = 0; i < 500 && test_data.published == 0; i++) mg_mgr_poll(&mgr, 10); ASSERT(test_data.published == 1); for (i = 0; i < 500 && buf[1] == 0; i++) mg_mgr_poll(&mgr, 10); @@ -422,24 +474,32 @@ static void test_mqtt_ver(uint8_t mqtt_version) { test_data.published = 0; memset(buf, 0, sizeof(buf)); memset(&opts, 0, sizeof(opts)); - opts.clean = true; - opts.will_qos = 1; - opts.will_retain = true; - opts.keepalive = 20; + + opts.clean = true, opts.qos = 1, opts.retain = true, opts.keepalive = 20; opts.version = mqtt_version; - opts.will_topic = mg_str(mg_random_str(will_topic, sizeof(will_topic))); - opts.will_message = mg_str("mg_will_messsage"); + opts.topic = mg_str(mg_random_str(will_topic, sizeof(will_topic))); + opts.message = mg_str("mg_will_messsage"); opts.client_id = mg_str(mg_random_str(client_id, sizeof(client_id))); c = mg_mqtt_connect(&mgr, url, &opts, mqtt_cb, &test_data); for (i = 0; i < 300 && buf[0] == 0; i++) mg_mgr_poll(&mgr, 10); if (buf[0] != 'X') MG_INFO(("[%s]", buf)); ASSERT(buf[0] == 'X'); ASSERT(test_data.subscribed == 0); - mg_mqtt_sub(c, topic, 1); + + opts.topic = topic, opts.qos = 1; + mg_mqtt_sub(c, &opts); for (i = 0; i < 500 && test_data.subscribed == 0; i++) mg_mgr_poll(&mgr, 10); ASSERT(test_data.subscribed == 1); ASSERT(test_data.published == 0); - mg_mqtt_pub(c, topic, data, 1, false); + + opts.topic = topic, opts.message = data, opts.qos = 1, opts.retain = false; + if (mqtt_version == 5) { + opts.props = properties; + opts.num_props = 4; + construct_props(properties); + } + + mg_mqtt_pub(c, &opts); for (i = 0; i < 500 && test_data.published == 0; i++) mg_mgr_poll(&mgr, 10); ASSERT(test_data.published == 1); for (i = 0; i < 500 && buf[1] == 0; i++) mg_mgr_poll(&mgr, 10); @@ -452,8 +512,8 @@ static void test_mqtt_ver(uint8_t mqtt_version) { static void test_mqtt(void) { test_mqtt_base(); - test_mqtt_ver(5); test_mqtt_ver(4); + test_mqtt_ver(5); test_mqtt_base(); } @@ -580,7 +640,7 @@ static int cmpbody(const char *buf, const char *str) { struct mg_str s = mg_str(str); size_t len = strlen(buf); mg_http_parse(buf, len, &hm); - if (hm.body.len > len) hm.body.len = len - (size_t) (hm.body.ptr - buf); + if (hm.body.len > len) hm.body.len = len - (size_t)(hm.body.ptr - buf); return mg_strcmp(hm.body, s); }