##// END OF EJS Templates
branching: merge stable into default
Raphaël Gomès -
r50480:18282cf1 merge default
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,236 +1,238 b''
1 35fb62a3a673d5322f6274a44ba6456e5e4b3b37 0 iD8DBQBEYmO2ywK+sNU5EO8RAnaYAKCO7x15xUn5mnhqWNXqk/ehlhRt2QCfRDfY0LrUq2q4oK/KypuJYPHgq1A=
1 35fb62a3a673d5322f6274a44ba6456e5e4b3b37 0 iD8DBQBEYmO2ywK+sNU5EO8RAnaYAKCO7x15xUn5mnhqWNXqk/ehlhRt2QCfRDfY0LrUq2q4oK/KypuJYPHgq1A=
2 2be3001847cb18a23c403439d9e7d0ace30804e9 0 iD8DBQBExUbjywK+sNU5EO8RAhzxAKCtyHAQUzcTSZTqlfJ0by6vhREwWQCghaQFHfkfN0l9/40EowNhuMOKnJk=
2 2be3001847cb18a23c403439d9e7d0ace30804e9 0 iD8DBQBExUbjywK+sNU5EO8RAhzxAKCtyHAQUzcTSZTqlfJ0by6vhREwWQCghaQFHfkfN0l9/40EowNhuMOKnJk=
3 36a957364b1b89c150f2d0e60a99befe0ee08bd3 0 iD8DBQBFfL2QywK+sNU5EO8RAjYFAKCoGlaWRTeMsjdmxAjUYx6diZxOBwCfY6IpBYsKvPTwB3oktnPt5Rmrlys=
3 36a957364b1b89c150f2d0e60a99befe0ee08bd3 0 iD8DBQBFfL2QywK+sNU5EO8RAjYFAKCoGlaWRTeMsjdmxAjUYx6diZxOBwCfY6IpBYsKvPTwB3oktnPt5Rmrlys=
4 27230c29bfec36d5540fbe1c976810aefecfd1d2 0 iD8DBQBFheweywK+sNU5EO8RAt7VAKCrqJQWT2/uo2RWf0ZI4bLp6v82jACgjrMdsaTbxRsypcmEsdPhlG6/8F4=
4 27230c29bfec36d5540fbe1c976810aefecfd1d2 0 iD8DBQBFheweywK+sNU5EO8RAt7VAKCrqJQWT2/uo2RWf0ZI4bLp6v82jACgjrMdsaTbxRsypcmEsdPhlG6/8F4=
5 fb4b6d5fe100b0886f8bc3d6731ec0e5ed5c4694 0 iD8DBQBGgHicywK+sNU5EO8RAgNxAJ0VG8ixAaeudx4sZbhngI1syu49HQCeNUJQfWBgA8bkJ2pvsFpNxwYaX3I=
5 fb4b6d5fe100b0886f8bc3d6731ec0e5ed5c4694 0 iD8DBQBGgHicywK+sNU5EO8RAgNxAJ0VG8ixAaeudx4sZbhngI1syu49HQCeNUJQfWBgA8bkJ2pvsFpNxwYaX3I=
6 23889160905a1b09fffe1c07378e9fc1827606eb 0 iD8DBQBHGTzoywK+sNU5EO8RAr/UAJ0Y8s4jQtzgS+G9vM8z6CWBThZ8fwCcCT5XDj2XwxKkz/0s6UELwjsO3LU=
6 23889160905a1b09fffe1c07378e9fc1827606eb 0 iD8DBQBHGTzoywK+sNU5EO8RAr/UAJ0Y8s4jQtzgS+G9vM8z6CWBThZ8fwCcCT5XDj2XwxKkz/0s6UELwjsO3LU=
7 bae2e9c838e90a393bae3973a7850280413e091a 0 iD8DBQBH6DO5ywK+sNU5EO8RAsfrAJ0e4r9c9GF/MJsM7Xjd3NesLRC3+ACffj6+6HXdZf8cswAoFPO+DY00oD0=
7 bae2e9c838e90a393bae3973a7850280413e091a 0 iD8DBQBH6DO5ywK+sNU5EO8RAsfrAJ0e4r9c9GF/MJsM7Xjd3NesLRC3+ACffj6+6HXdZf8cswAoFPO+DY00oD0=
8 d5cbbe2c49cee22a9fbeb9ea41daa0ac4e26b846 0 iD8DBQBINdwsywK+sNU5EO8RAjIUAKCPmlFJSpsPAAUKF+iNHAwVnwmzeQCdEXrL27CWclXuUKdbQC8De7LICtE=
8 d5cbbe2c49cee22a9fbeb9ea41daa0ac4e26b846 0 iD8DBQBINdwsywK+sNU5EO8RAjIUAKCPmlFJSpsPAAUKF+iNHAwVnwmzeQCdEXrL27CWclXuUKdbQC8De7LICtE=
9 d2375bbee6d47e62ba8e415c86e83a465dc4dce9 0 iD8DBQBIo1wpywK+sNU5EO8RAmRNAJ94x3OFt6blbqu/yBoypm/AJ44fuACfUaldXcV5z9tht97hSp22DVTEPGc=
9 d2375bbee6d47e62ba8e415c86e83a465dc4dce9 0 iD8DBQBIo1wpywK+sNU5EO8RAmRNAJ94x3OFt6blbqu/yBoypm/AJ44fuACfUaldXcV5z9tht97hSp22DVTEPGc=
10 2a67430f92f15ea5159c26b09ec4839a0c549a26 0 iEYEABECAAYFAkk1hykACgkQywK+sNU5EO85QACeNJNUanjc2tl4wUoPHNuv+lSj0ZMAoIm93wSTc/feyYnO2YCaQ1iyd9Nu
10 2a67430f92f15ea5159c26b09ec4839a0c549a26 0 iEYEABECAAYFAkk1hykACgkQywK+sNU5EO85QACeNJNUanjc2tl4wUoPHNuv+lSj0ZMAoIm93wSTc/feyYnO2YCaQ1iyd9Nu
11 3773e510d433969e277b1863c317b674cbee2065 0 iEYEABECAAYFAklNbbAACgkQywK+sNU5EO8o+gCfeb2/lfIJZMvyDA1m+G1CsBAxfFsAoIa6iAMG8SBY7hW1Q85Yf/LXEvaE
11 3773e510d433969e277b1863c317b674cbee2065 0 iEYEABECAAYFAklNbbAACgkQywK+sNU5EO8o+gCfeb2/lfIJZMvyDA1m+G1CsBAxfFsAoIa6iAMG8SBY7hW1Q85Yf/LXEvaE
12 11a4eb81fb4f4742451591489e2797dc47903277 0 iEYEABECAAYFAklcAnsACgkQywK+sNU5EO+uXwCbBVHNNsLy1g7BlAyQJwadYVyHOXoAoKvtAVO71+bv7EbVoukwTzT+P4Sx
12 11a4eb81fb4f4742451591489e2797dc47903277 0 iEYEABECAAYFAklcAnsACgkQywK+sNU5EO+uXwCbBVHNNsLy1g7BlAyQJwadYVyHOXoAoKvtAVO71+bv7EbVoukwTzT+P4Sx
13 11efa41037e280d08cfb07c09ad485df30fb0ea8 0 iEYEABECAAYFAkmvJRQACgkQywK+sNU5EO9XZwCeLMgDgPSMWMm6vgjL4lDs2pEc5+0AnRxfiFbpbBfuEFTqKz9nbzeyoBlx
13 11efa41037e280d08cfb07c09ad485df30fb0ea8 0 iEYEABECAAYFAkmvJRQACgkQywK+sNU5EO9XZwCeLMgDgPSMWMm6vgjL4lDs2pEc5+0AnRxfiFbpbBfuEFTqKz9nbzeyoBlx
14 02981000012e3adf40c4849bd7b3d5618f9ce82d 0 iEYEABECAAYFAknEH3wACgkQywK+sNU5EO+uXwCeI+LbLMmhjU1lKSfU3UWJHjjUC7oAoIZLvYDGOL/tNZFUuatc3RnZ2eje
14 02981000012e3adf40c4849bd7b3d5618f9ce82d 0 iEYEABECAAYFAknEH3wACgkQywK+sNU5EO+uXwCeI+LbLMmhjU1lKSfU3UWJHjjUC7oAoIZLvYDGOL/tNZFUuatc3RnZ2eje
15 196d40e7c885fa6e95f89134809b3ec7bdbca34b 0 iEYEABECAAYFAkpL2X4ACgkQywK+sNU5EO9FOwCfXJycjyKJXsvQqKkHrglwOQhEKS4An36GfKzptfN8b1qNc3+ya/5c2WOM
15 196d40e7c885fa6e95f89134809b3ec7bdbca34b 0 iEYEABECAAYFAkpL2X4ACgkQywK+sNU5EO9FOwCfXJycjyKJXsvQqKkHrglwOQhEKS4An36GfKzptfN8b1qNc3+ya/5c2WOM
16 3ef6c14a1e8e83a31226f5881b7fe6095bbfa6f6 0 iEYEABECAAYFAkpopLIACgkQywK+sNU5EO8QSgCfZ0ztsd071rOa2lhmp9Fyue/WoI0AoLTei80/xrhRlB8L/rZEf2KBl8dA
16 3ef6c14a1e8e83a31226f5881b7fe6095bbfa6f6 0 iEYEABECAAYFAkpopLIACgkQywK+sNU5EO8QSgCfZ0ztsd071rOa2lhmp9Fyue/WoI0AoLTei80/xrhRlB8L/rZEf2KBl8dA
17 31ec469f9b556f11819937cf68ee53f2be927ebf 0 iEYEABECAAYFAksBuxAACgkQywK+sNU5EO+mBwCfagB+A0txzWZ6dRpug3LEoK7Z1QsAoKpbk8vsLjv6/oRDicSk/qBu33+m
17 31ec469f9b556f11819937cf68ee53f2be927ebf 0 iEYEABECAAYFAksBuxAACgkQywK+sNU5EO+mBwCfagB+A0txzWZ6dRpug3LEoK7Z1QsAoKpbk8vsLjv6/oRDicSk/qBu33+m
18 439d7ea6fe3aa4ab9ec274a68846779153789de9 0 iEYEABECAAYFAksVw0kACgkQywK+sNU5EO/oZwCfdfBEkgp38xq6wN2F4nj+SzofrJIAnjmxt04vaJSeOOeHylHvk6lzuQsw
18 439d7ea6fe3aa4ab9ec274a68846779153789de9 0 iEYEABECAAYFAksVw0kACgkQywK+sNU5EO/oZwCfdfBEkgp38xq6wN2F4nj+SzofrJIAnjmxt04vaJSeOOeHylHvk6lzuQsw
19 296a0b14a68621f6990c54fdba0083f6f20935bf 0 iEYEABECAAYFAks+jCoACgkQywK+sNU5EO9J8wCeMUGF9E/gS2UBsqIz56WS4HMPRPUAoI5J95mwEIK8Clrl7qFRidNI6APq
19 296a0b14a68621f6990c54fdba0083f6f20935bf 0 iEYEABECAAYFAks+jCoACgkQywK+sNU5EO9J8wCeMUGF9E/gS2UBsqIz56WS4HMPRPUAoI5J95mwEIK8Clrl7qFRidNI6APq
20 4aa619c4c2c09907034d9824ebb1dd0e878206eb 0 iEYEABECAAYFAktm9IsACgkQywK+sNU5EO9XGgCgk4HclRQhexEtooPE5GcUCdB6M8EAn2ptOhMVbIoO+JncA+tNACPFXh0O
20 4aa619c4c2c09907034d9824ebb1dd0e878206eb 0 iEYEABECAAYFAktm9IsACgkQywK+sNU5EO9XGgCgk4HclRQhexEtooPE5GcUCdB6M8EAn2ptOhMVbIoO+JncA+tNACPFXh0O
21 ff2704a8ded37fbebd8b6eb5ec733731d725da8a 0 iEYEABECAAYFAkuRoSQACgkQywK+sNU5EO//3QCeJDc5r2uFyFCtAlpSA27DEE5rrxAAn2FSwTy9fhrB3QAdDQlwkEZcQzDh
21 ff2704a8ded37fbebd8b6eb5ec733731d725da8a 0 iEYEABECAAYFAkuRoSQACgkQywK+sNU5EO//3QCeJDc5r2uFyFCtAlpSA27DEE5rrxAAn2FSwTy9fhrB3QAdDQlwkEZcQzDh
22 2b01dab594167bc0dd33331dbaa6dca3dca1b3aa 0 iEYEABECAAYFAku1IwIACgkQywK+sNU5EO9MjgCdHLVwkTZlNHxhcznZKBL1rjN+J7cAoLLWi9LTL6f/TgBaPSKOy1ublbaW
22 2b01dab594167bc0dd33331dbaa6dca3dca1b3aa 0 iEYEABECAAYFAku1IwIACgkQywK+sNU5EO9MjgCdHLVwkTZlNHxhcznZKBL1rjN+J7cAoLLWi9LTL6f/TgBaPSKOy1ublbaW
23 39f725929f0c48c5fb3b90c071fc3066012456ca 0 iEYEABECAAYFAkvclvsACgkQywK+sNU5EO9FSwCeL9i5x8ALW/LE5+lCX6MFEAe4MhwAn1ev5o6SX6GrNdDfKweiemfO2VBk
23 39f725929f0c48c5fb3b90c071fc3066012456ca 0 iEYEABECAAYFAkvclvsACgkQywK+sNU5EO9FSwCeL9i5x8ALW/LE5+lCX6MFEAe4MhwAn1ev5o6SX6GrNdDfKweiemfO2VBk
24 fdcf80f26604f233dc4d8f0a5ef9d7470e317e8a 0 iEYEABECAAYFAkvsKTkACgkQywK+sNU5EO9qEACgiSiRGvTG2vXGJ65tUSOIYihTuFAAnRzRIqEVSw8M8/RGeUXRps0IzaCO
24 fdcf80f26604f233dc4d8f0a5ef9d7470e317e8a 0 iEYEABECAAYFAkvsKTkACgkQywK+sNU5EO9qEACgiSiRGvTG2vXGJ65tUSOIYihTuFAAnRzRIqEVSw8M8/RGeUXRps0IzaCO
25 24fe2629c6fd0c74c90bd066e77387c2b02e8437 0 iEYEABECAAYFAkwFLRsACgkQywK+sNU5EO+pJACgp13tPI+pbwKZV+LeMjcQ4H6tCZYAoJebzhd6a8yYx6qiwpJxA9BXZNXy
25 24fe2629c6fd0c74c90bd066e77387c2b02e8437 0 iEYEABECAAYFAkwFLRsACgkQywK+sNU5EO+pJACgp13tPI+pbwKZV+LeMjcQ4H6tCZYAoJebzhd6a8yYx6qiwpJxA9BXZNXy
26 f786fc4b8764cd2a5526d259cf2f94d8a66924d9 0 iEYEABECAAYFAkwsyxcACgkQywK+sNU5EO+crACfUpNAF57PmClkSri9nJcBjb2goN4AniPCNaKvnki7TnUsi1u2oxltpKKL
26 f786fc4b8764cd2a5526d259cf2f94d8a66924d9 0 iEYEABECAAYFAkwsyxcACgkQywK+sNU5EO+crACfUpNAF57PmClkSri9nJcBjb2goN4AniPCNaKvnki7TnUsi1u2oxltpKKL
27 bf1774d95bde614af3956d92b20e2a0c68c5fec7 0 iEYEABECAAYFAkxVwccACgkQywK+sNU5EO+oFQCeJzwZ+we1fIIyBGCddHceOUAN++cAnjvT6A8ZWW0zV21NXIFF1qQmjxJd
27 bf1774d95bde614af3956d92b20e2a0c68c5fec7 0 iEYEABECAAYFAkxVwccACgkQywK+sNU5EO+oFQCeJzwZ+we1fIIyBGCddHceOUAN++cAnjvT6A8ZWW0zV21NXIFF1qQmjxJd
28 c00f03a4982e467fb6b6bd45908767db6df4771d 0 iEYEABECAAYFAkxXDqsACgkQywK+sNU5EO/GJACfT9Rz4hZOxPQEs91JwtmfjevO84gAmwSmtfo5mmWSm8gtTUebCcdTv0Kf
28 c00f03a4982e467fb6b6bd45908767db6df4771d 0 iEYEABECAAYFAkxXDqsACgkQywK+sNU5EO/GJACfT9Rz4hZOxPQEs91JwtmfjevO84gAmwSmtfo5mmWSm8gtTUebCcdTv0Kf
29 ff5cec76b1c5b6be9c3bb923aae8c3c6d079d6b9 0 iD8DBQBMdo+qywK+sNU5EO8RAqQpAJ975BL2CCAiWMz9SXthNQ9xG181IwCgp4O+KViHPkufZVFn2aTKMNvcr1A=
29 ff5cec76b1c5b6be9c3bb923aae8c3c6d079d6b9 0 iD8DBQBMdo+qywK+sNU5EO8RAqQpAJ975BL2CCAiWMz9SXthNQ9xG181IwCgp4O+KViHPkufZVFn2aTKMNvcr1A=
30 93d8bff78c96fe7e33237b257558ee97290048a4 0 iD8DBQBMpfvdywK+sNU5EO8RAsxVAJ0UaL1XB51C76JUBhafc9GBefuMxwCdEWkTOzwvE0SarJBe9i008jhbqW4=
30 93d8bff78c96fe7e33237b257558ee97290048a4 0 iD8DBQBMpfvdywK+sNU5EO8RAsxVAJ0UaL1XB51C76JUBhafc9GBefuMxwCdEWkTOzwvE0SarJBe9i008jhbqW4=
31 333421b9e0f96c7bc788e5667c146a58a9440a55 0 iD8DBQBMz0HOywK+sNU5EO8RAlsEAJ0USh6yOG7OrWkADGunVt9QimBQnwCbBqeMnKgSbwEw8jZwE3Iz1mdrYlo=
31 333421b9e0f96c7bc788e5667c146a58a9440a55 0 iD8DBQBMz0HOywK+sNU5EO8RAlsEAJ0USh6yOG7OrWkADGunVt9QimBQnwCbBqeMnKgSbwEw8jZwE3Iz1mdrYlo=
32 4438875ec01bd0fc32be92b0872eb6daeed4d44f 0 iD8DBQBM4WYUywK+sNU5EO8RAhCVAJ0dJswachwFAHALmk1x0RJehxzqPQCbBNskP9n/X689jB+btNTZTyKU/fw=
32 4438875ec01bd0fc32be92b0872eb6daeed4d44f 0 iD8DBQBM4WYUywK+sNU5EO8RAhCVAJ0dJswachwFAHALmk1x0RJehxzqPQCbBNskP9n/X689jB+btNTZTyKU/fw=
33 6aff4f144ad356311318b0011df0bb21f2c97429 0 iD8DBQBM9uxXywK+sNU5EO8RAv+4AKCDj4qKP16GdPaq1tP6BUwpM/M1OACfRyzLPp/qiiN8xJTWoWYSe/XjJug=
33 6aff4f144ad356311318b0011df0bb21f2c97429 0 iD8DBQBM9uxXywK+sNU5EO8RAv+4AKCDj4qKP16GdPaq1tP6BUwpM/M1OACfRyzLPp/qiiN8xJTWoWYSe/XjJug=
34 e3bf16703e2601de99e563cdb3a5d50b64e6d320 0 iD8DBQBNH8WqywK+sNU5EO8RAiQTAJ9sBO+TeiGro4si77VVaQaA6jcRUgCfSA28dBbjj0oFoQwvPoZjANiZBH8=
34 e3bf16703e2601de99e563cdb3a5d50b64e6d320 0 iD8DBQBNH8WqywK+sNU5EO8RAiQTAJ9sBO+TeiGro4si77VVaQaA6jcRUgCfSA28dBbjj0oFoQwvPoZjANiZBH8=
35 a6c855c32ea081da3c3b8ff628f1847ff271482f 0 iD8DBQBNSJJ+ywK+sNU5EO8RAoJaAKCweDEF70fu+r1Zn7pYDXdlk5RuSgCeO9gK/eit8Lin/1n3pO7aYguFLok=
35 a6c855c32ea081da3c3b8ff628f1847ff271482f 0 iD8DBQBNSJJ+ywK+sNU5EO8RAoJaAKCweDEF70fu+r1Zn7pYDXdlk5RuSgCeO9gK/eit8Lin/1n3pO7aYguFLok=
36 2b2155623ee2559caf288fd333f30475966c4525 0 iD8DBQBNSJeBywK+sNU5EO8RAm1KAJ4hW9Cm9nHaaGJguchBaPLlAr+O3wCgqgmMok8bdAS06N6PL60PSTM//Gg=
36 2b2155623ee2559caf288fd333f30475966c4525 0 iD8DBQBNSJeBywK+sNU5EO8RAm1KAJ4hW9Cm9nHaaGJguchBaPLlAr+O3wCgqgmMok8bdAS06N6PL60PSTM//Gg=
37 2616325766e3504c8ae7c84bd15ee610901fe91d 0 iD8DBQBNbWy9ywK+sNU5EO8RAlWCAJ4mW8HbzjJj9GpK98muX7k+7EvEHwCfaTLbC/DH3QEsZBhEP+M8tzL6RU4=
37 2616325766e3504c8ae7c84bd15ee610901fe91d 0 iD8DBQBNbWy9ywK+sNU5EO8RAlWCAJ4mW8HbzjJj9GpK98muX7k+7EvEHwCfaTLbC/DH3QEsZBhEP+M8tzL6RU4=
38 aa1f3be38ab127280761889d2dca906ca465b5f4 0 iD8DBQBNeQq7ywK+sNU5EO8RAlEOAJ4tlEDdetE9lKfjGgjbkcR8PrC3egCfXCfF3qNVvU/2YYjpgvRwevjvDy0=
38 aa1f3be38ab127280761889d2dca906ca465b5f4 0 iD8DBQBNeQq7ywK+sNU5EO8RAlEOAJ4tlEDdetE9lKfjGgjbkcR8PrC3egCfXCfF3qNVvU/2YYjpgvRwevjvDy0=
39 b032bec2c0a651ca0ddecb65714bfe6770f67d70 0 iD8DBQBNlg5kywK+sNU5EO8RAnGEAJ9gmEx6MfaR4XcG2m/93vwtfyzs3gCgltzx8/YdHPwqDwRX/WbpYgi33is=
39 b032bec2c0a651ca0ddecb65714bfe6770f67d70 0 iD8DBQBNlg5kywK+sNU5EO8RAnGEAJ9gmEx6MfaR4XcG2m/93vwtfyzs3gCgltzx8/YdHPwqDwRX/WbpYgi33is=
40 3cb1e95676ad089596bd81d0937cad37d6e3b7fb 0 iD8DBQBNvTy4ywK+sNU5EO8RAmp8AJ9QnxK4jTJ7G722MyeBxf0UXEdGwACgtlM7BKtNQfbEH/fOW5y+45W88VI=
40 3cb1e95676ad089596bd81d0937cad37d6e3b7fb 0 iD8DBQBNvTy4ywK+sNU5EO8RAmp8AJ9QnxK4jTJ7G722MyeBxf0UXEdGwACgtlM7BKtNQfbEH/fOW5y+45W88VI=
41 733af5d9f6b22387913e1d11350fb8cb7c1487dd 0 iD8DBQBN5q/8ywK+sNU5EO8RArRGAKCNGT94GKIYtSuwZ57z1sQbcw6uLACfffpbMV4NAPMl8womAwg+7ZPKnIU=
41 733af5d9f6b22387913e1d11350fb8cb7c1487dd 0 iD8DBQBN5q/8ywK+sNU5EO8RArRGAKCNGT94GKIYtSuwZ57z1sQbcw6uLACfffpbMV4NAPMl8womAwg+7ZPKnIU=
42 de9eb6b1da4fc522b1cab16d86ca166204c24f25 0 iD8DBQBODhfhywK+sNU5EO8RAr2+AJ4ugbAj8ae8/K0bYZzx3sascIAg1QCeK3b+zbbVVqd3b7CDpwFnaX8kTd4=
42 de9eb6b1da4fc522b1cab16d86ca166204c24f25 0 iD8DBQBODhfhywK+sNU5EO8RAr2+AJ4ugbAj8ae8/K0bYZzx3sascIAg1QCeK3b+zbbVVqd3b7CDpwFnaX8kTd4=
43 4a43e23b8c55b4566b8200bf69fe2158485a2634 0 iD8DBQBONzIMywK+sNU5EO8RAj5SAJ0aPS3+JHnyI6bHB2Fl0LImbDmagwCdGbDLp1S7TFobxXudOH49bX45Iik=
43 4a43e23b8c55b4566b8200bf69fe2158485a2634 0 iD8DBQBONzIMywK+sNU5EO8RAj5SAJ0aPS3+JHnyI6bHB2Fl0LImbDmagwCdGbDLp1S7TFobxXudOH49bX45Iik=
44 d629f1e89021103f1753addcef6b310e4435b184 0 iD8DBQBOWAsBywK+sNU5EO8RAht4AJwJl9oNFopuGkj5m8aKuf7bqPkoAQCeNrEm7UhFsZKYT5iUOjnMV7s2LaM=
44 d629f1e89021103f1753addcef6b310e4435b184 0 iD8DBQBOWAsBywK+sNU5EO8RAht4AJwJl9oNFopuGkj5m8aKuf7bqPkoAQCeNrEm7UhFsZKYT5iUOjnMV7s2LaM=
45 351a9292e430e35766c552066ed3e87c557b803b 0 iD8DBQBOh3zUywK+sNU5EO8RApFMAKCD3Y/u3avDFndznwqfG5UeTHMlvACfUivPIVQZyDZnhZMq0UhC6zhCEQg=
45 351a9292e430e35766c552066ed3e87c557b803b 0 iD8DBQBOh3zUywK+sNU5EO8RApFMAKCD3Y/u3avDFndznwqfG5UeTHMlvACfUivPIVQZyDZnhZMq0UhC6zhCEQg=
46 384082750f2c51dc917d85a7145748330fa6ef4d 0 iD8DBQBOmd+OywK+sNU5EO8RAgDgAJ9V/X+G7VLwhTpHrZNiOHabzSyzYQCdE2kKfIevJUYB9QLAWCWP6DPwrwI=
46 384082750f2c51dc917d85a7145748330fa6ef4d 0 iD8DBQBOmd+OywK+sNU5EO8RAgDgAJ9V/X+G7VLwhTpHrZNiOHabzSyzYQCdE2kKfIevJUYB9QLAWCWP6DPwrwI=
47 41453d55b481ddfcc1dacb445179649e24ca861d 0 iD8DBQBOsFhpywK+sNU5EO8RAqM6AKCyfxUae3/zLuiLdQz+JR78690eMACfQ6JTBQib4AbE+rUDdkeFYg9K/+4=
47 41453d55b481ddfcc1dacb445179649e24ca861d 0 iD8DBQBOsFhpywK+sNU5EO8RAqM6AKCyfxUae3/zLuiLdQz+JR78690eMACfQ6JTBQib4AbE+rUDdkeFYg9K/+4=
48 195dbd1cef0c2f9f8bcf4ea303238105f716bda3 0 iD8DBQBO1/fWywK+sNU5EO8RAmoPAKCR5lpv1D6JLURHD8KVLSV4GRVEBgCgnd0Sy78ligNfqAMafmACRDvj7vo=
48 195dbd1cef0c2f9f8bcf4ea303238105f716bda3 0 iD8DBQBO1/fWywK+sNU5EO8RAmoPAKCR5lpv1D6JLURHD8KVLSV4GRVEBgCgnd0Sy78ligNfqAMafmACRDvj7vo=
49 6344043924497cd06d781d9014c66802285072e4 0 iD8DBQBPALgmywK+sNU5EO8RAlfhAJ9nYOdWnhfVDHYtDTJAyJtXBAQS9wCgnefoSQt7QABkbGxM+Q85UYEBuD0=
49 6344043924497cd06d781d9014c66802285072e4 0 iD8DBQBPALgmywK+sNU5EO8RAlfhAJ9nYOdWnhfVDHYtDTJAyJtXBAQS9wCgnefoSQt7QABkbGxM+Q85UYEBuD0=
50 db33555eafeaf9df1e18950e29439eaa706d399b 0 iD8DBQBPGdzxywK+sNU5EO8RAppkAJ9jOXhUVE/97CPgiMA0pMGiIYnesQCfengAszcBiSiKGugiI8Okc9ghU+Y=
50 db33555eafeaf9df1e18950e29439eaa706d399b 0 iD8DBQBPGdzxywK+sNU5EO8RAppkAJ9jOXhUVE/97CPgiMA0pMGiIYnesQCfengAszcBiSiKGugiI8Okc9ghU+Y=
51 2aa5b51f310fb3befd26bed99c02267f5c12c734 0 iD8DBQBPKZ9bywK+sNU5EO8RAt1TAJ45r1eJ0YqSkInzrrayg4TVCh0SnQCgm0GA/Ua74jnnDwVQ60lAwROuz1Q=
51 2aa5b51f310fb3befd26bed99c02267f5c12c734 0 iD8DBQBPKZ9bywK+sNU5EO8RAt1TAJ45r1eJ0YqSkInzrrayg4TVCh0SnQCgm0GA/Ua74jnnDwVQ60lAwROuz1Q=
52 53e2cd303ecf8ca7c7eeebd785c34e5ed6b0f4a4 0 iD8DBQBPT/fvywK+sNU5EO8RAnfYAKCn7d0vwqIb100YfWm1F7nFD5B+FACeM02YHpQLSNsztrBCObtqcnfod7Q=
52 53e2cd303ecf8ca7c7eeebd785c34e5ed6b0f4a4 0 iD8DBQBPT/fvywK+sNU5EO8RAnfYAKCn7d0vwqIb100YfWm1F7nFD5B+FACeM02YHpQLSNsztrBCObtqcnfod7Q=
53 b9bd95e61b49c221c4cca24e6da7c946fc02f992 0 iD8DBQBPeLsIywK+sNU5EO8RAvpNAKCtKe2gitz8dYn52IRF0hFOPCR7AQCfRJL/RWCFweu2T1vH/mUOCf8SXXc=
53 b9bd95e61b49c221c4cca24e6da7c946fc02f992 0 iD8DBQBPeLsIywK+sNU5EO8RAvpNAKCtKe2gitz8dYn52IRF0hFOPCR7AQCfRJL/RWCFweu2T1vH/mUOCf8SXXc=
54 d9e2f09d5488c395ae9ddbb320ceacd24757e055 0 iD8DBQBPju/dywK+sNU5EO8RArBYAJ9xtifdbk+hCOJO8OZa4JfHX8OYZQCeKPMBaBWiT8N/WHoOm1XU0q+iono=
54 d9e2f09d5488c395ae9ddbb320ceacd24757e055 0 iD8DBQBPju/dywK+sNU5EO8RArBYAJ9xtifdbk+hCOJO8OZa4JfHX8OYZQCeKPMBaBWiT8N/WHoOm1XU0q+iono=
55 00182b3d087909e3c3ae44761efecdde8f319ef3 0 iD8DBQBPoFhIywK+sNU5EO8RAhzhAKCBj1n2jxPTkZNJJ5pSp3soa+XHIgCgsZZpAQxOpXwCp0eCdNGe0+pmxmg=
55 00182b3d087909e3c3ae44761efecdde8f319ef3 0 iD8DBQBPoFhIywK+sNU5EO8RAhzhAKCBj1n2jxPTkZNJJ5pSp3soa+XHIgCgsZZpAQxOpXwCp0eCdNGe0+pmxmg=
56 5983de86462c5a9f42a3ad0f5e90ce5b1d221d25 0 iD8DBQBPovNWywK+sNU5EO8RAhgiAJ980T91FdPTRMmVONDhpkMsZwVIMACgg3bKvoWSeuCW28llUhAJtUjrMv0=
56 5983de86462c5a9f42a3ad0f5e90ce5b1d221d25 0 iD8DBQBPovNWywK+sNU5EO8RAhgiAJ980T91FdPTRMmVONDhpkMsZwVIMACgg3bKvoWSeuCW28llUhAJtUjrMv0=
57 85a358df5bbbe404ca25730c9c459b34263441dc 0 iD8DBQBPyZsWywK+sNU5EO8RAnpLAJ48qrGDJRT+pteS0mSQ11haqHstPwCdG4ccGbk+0JHb7aNy8/NRGAOqn9w=
57 85a358df5bbbe404ca25730c9c459b34263441dc 0 iD8DBQBPyZsWywK+sNU5EO8RAnpLAJ48qrGDJRT+pteS0mSQ11haqHstPwCdG4ccGbk+0JHb7aNy8/NRGAOqn9w=
58 b013baa3898e117959984fc64c29d8c784d2f28b 0 iD8DBQBP8QOPywK+sNU5EO8RAqimAKCFRSx0lvG6y8vne2IhNG062Hn0dACeMLI5/zhpWpHBIVeAAquYfx2XFeA=
58 b013baa3898e117959984fc64c29d8c784d2f28b 0 iD8DBQBP8QOPywK+sNU5EO8RAqimAKCFRSx0lvG6y8vne2IhNG062Hn0dACeMLI5/zhpWpHBIVeAAquYfx2XFeA=
59 7f5094bb3f423fc799e471aac2aee81a7ce57a0b 0 iD8DBQBQGiL8ywK+sNU5EO8RAq5oAJ4rMMCPx6O+OuzNXVOexogedWz/QgCeIiIxLd76I4pXO48tdXhr0hQcBuM=
59 7f5094bb3f423fc799e471aac2aee81a7ce57a0b 0 iD8DBQBQGiL8ywK+sNU5EO8RAq5oAJ4rMMCPx6O+OuzNXVOexogedWz/QgCeIiIxLd76I4pXO48tdXhr0hQcBuM=
60 072209ae4ddb654eb2d5fd35bff358c738414432 0 iD8DBQBQQkq0ywK+sNU5EO8RArDTAJ9nk5CySnNAjAXYvqvx4uWCw9ThZwCgqmFRehH/l+oTwj3f8nw8u8qTCdc=
60 072209ae4ddb654eb2d5fd35bff358c738414432 0 iD8DBQBQQkq0ywK+sNU5EO8RArDTAJ9nk5CySnNAjAXYvqvx4uWCw9ThZwCgqmFRehH/l+oTwj3f8nw8u8qTCdc=
61 b3f0f9a39c4e1d0250048cd803ab03542d6f140a 0 iD8DBQBQamltywK+sNU5EO8RAlsqAJ4qF/m6aFu4mJCOKTiAP5RvZFK02ACfawYShUZO6OXEFfveU0aAxDR0M1k=
61 b3f0f9a39c4e1d0250048cd803ab03542d6f140a 0 iD8DBQBQamltywK+sNU5EO8RAlsqAJ4qF/m6aFu4mJCOKTiAP5RvZFK02ACfawYShUZO6OXEFfveU0aAxDR0M1k=
62 d118a4f4fd16d9b558ec3f3e87bfee772861d2b7 0 iD8DBQBQgPV5ywK+sNU5EO8RArylAJ0abcx5NlDjyv3ZDWpAfRIHyRsJtQCgn4TMuEayqgxzrvadQZHdTEU2g38=
62 d118a4f4fd16d9b558ec3f3e87bfee772861d2b7 0 iD8DBQBQgPV5ywK+sNU5EO8RArylAJ0abcx5NlDjyv3ZDWpAfRIHyRsJtQCgn4TMuEayqgxzrvadQZHdTEU2g38=
63 195ad823b5d58c68903a6153a25e3fb4ed25239d 0 iD8DBQBQkuT9ywK+sNU5EO8RAhB4AKCeerItoK2Jipm2cVf4euGofAa/WACeJj3TVd4pFILpb+ogj7ebweFLJi0=
63 195ad823b5d58c68903a6153a25e3fb4ed25239d 0 iD8DBQBQkuT9ywK+sNU5EO8RAhB4AKCeerItoK2Jipm2cVf4euGofAa/WACeJj3TVd4pFILpb+ogj7ebweFLJi0=
64 0c10cf8191469e7c3c8844922e17e71a176cb7cb 0 iD8DBQBQvQWoywK+sNU5EO8RAnq3AJoCn98u4geFx5YaQaeh99gFhCd7bQCgjoBwBSUyOvGd0yBy60E3Vv3VZhM=
64 0c10cf8191469e7c3c8844922e17e71a176cb7cb 0 iD8DBQBQvQWoywK+sNU5EO8RAnq3AJoCn98u4geFx5YaQaeh99gFhCd7bQCgjoBwBSUyOvGd0yBy60E3Vv3VZhM=
65 a4765077b65e6ae29ba42bab7834717b5072d5ba 0 iD8DBQBQ486sywK+sNU5EO8RAhmJAJ90aLfLKZhmcZN7kqphigQJxiFOQACeJ5IUZxjGKH4xzi3MrgIcx9n+dB0=
65 a4765077b65e6ae29ba42bab7834717b5072d5ba 0 iD8DBQBQ486sywK+sNU5EO8RAhmJAJ90aLfLKZhmcZN7kqphigQJxiFOQACeJ5IUZxjGKH4xzi3MrgIcx9n+dB0=
66 f5fbe15ca7449f2c9a3cf817c86d0ae68b307214 0 iD8DBQBQ+yuYywK+sNU5EO8RAm9JAJoD/UciWvpGeKBcpGtZJBFJVcL/HACghDXSgQ+xQDjB+6uGrdgAQsRR1Lg=
66 f5fbe15ca7449f2c9a3cf817c86d0ae68b307214 0 iD8DBQBQ+yuYywK+sNU5EO8RAm9JAJoD/UciWvpGeKBcpGtZJBFJVcL/HACghDXSgQ+xQDjB+6uGrdgAQsRR1Lg=
67 a6088c05e43a8aee0472ca3a4f6f8d7dd914ebbf 0 iD8DBQBRDDROywK+sNU5EO8RAh75AJ9uJCGoCWnP0Lv/+XuYs4hvUl+sAgCcD36QgAnuw8IQXrvv684BAXAnHcA=
67 a6088c05e43a8aee0472ca3a4f6f8d7dd914ebbf 0 iD8DBQBRDDROywK+sNU5EO8RAh75AJ9uJCGoCWnP0Lv/+XuYs4hvUl+sAgCcD36QgAnuw8IQXrvv684BAXAnHcA=
68 7511d4df752e61fe7ae4f3682e0a0008573b0402 0 iD8DBQBRFYaoywK+sNU5EO8RAuErAJoDyhXn+lptU3+AevVdwAIeNFyR2gCdHzPHyWd+JDeWCUR+pSOBi8O2ppM=
68 7511d4df752e61fe7ae4f3682e0a0008573b0402 0 iD8DBQBRFYaoywK+sNU5EO8RAuErAJoDyhXn+lptU3+AevVdwAIeNFyR2gCdHzPHyWd+JDeWCUR+pSOBi8O2ppM=
69 5b7175377babacce80a6c1e12366d8032a6d4340 0 iD8DBQBRMCYgywK+sNU5EO8RAq1/AKCWKlt9ysibyQgYwoxxIOZv5J8rpwCcDSHQaaf1fFZUTnQsOePwcM2Y/Sg=
69 5b7175377babacce80a6c1e12366d8032a6d4340 0 iD8DBQBRMCYgywK+sNU5EO8RAq1/AKCWKlt9ysibyQgYwoxxIOZv5J8rpwCcDSHQaaf1fFZUTnQsOePwcM2Y/Sg=
70 50c922c1b5145dab8baefefb0437d363b6a6c21c 0 iD8DBQBRWnUnywK+sNU5EO8RAuQRAJwM42cJqJPeqJ0jVNdMqKMDqr4dSACeP0cRVGz1gitMuV0x8f3mrZrqc7I=
70 50c922c1b5145dab8baefefb0437d363b6a6c21c 0 iD8DBQBRWnUnywK+sNU5EO8RAuQRAJwM42cJqJPeqJ0jVNdMqKMDqr4dSACeP0cRVGz1gitMuV0x8f3mrZrqc7I=
71 8a7bd2dccd44ed571afe7424cd7f95594f27c092 0 iD8DBQBRXfBvywK+sNU5EO8RAn+LAKCsMmflbuXjYRxlzFwId5ptm8TZcwCdGkyLbZcASBOkzQUm/WW1qfknJHU=
71 8a7bd2dccd44ed571afe7424cd7f95594f27c092 0 iD8DBQBRXfBvywK+sNU5EO8RAn+LAKCsMmflbuXjYRxlzFwId5ptm8TZcwCdGkyLbZcASBOkzQUm/WW1qfknJHU=
72 292cd385856d98bacb2c3086f8897bc660c2beea 0 iD8DBQBRcM0BywK+sNU5EO8RAjp4AKCJBykQbvXhKuvLSMxKx3a2TBiXcACfbr/kLg5GlZTF/XDPmY+PyHgI/GM=
72 292cd385856d98bacb2c3086f8897bc660c2beea 0 iD8DBQBRcM0BywK+sNU5EO8RAjp4AKCJBykQbvXhKuvLSMxKx3a2TBiXcACfbr/kLg5GlZTF/XDPmY+PyHgI/GM=
73 23f785b38af38d2fca6b8f3db56b8007a84cd73a 0 iD8DBQBRgZwNywK+sNU5EO8RAmO4AJ4u2ILGuimRP6MJgE2t65LZ5dAdkACgiENEstIdrlFC80p+sWKD81kKIYI=
73 23f785b38af38d2fca6b8f3db56b8007a84cd73a 0 iD8DBQBRgZwNywK+sNU5EO8RAmO4AJ4u2ILGuimRP6MJgE2t65LZ5dAdkACgiENEstIdrlFC80p+sWKD81kKIYI=
74 ddc7a6be20212d18f3e27d9d7e6f079a66d96f21 0 iD8DBQBRkswvywK+sNU5EO8RAiYYAJsHTHyHbJeAgmGvBTmDrfcKu4doUgCeLm7eGBjx7yAPUvEtxef8rAkQmXI=
74 ddc7a6be20212d18f3e27d9d7e6f079a66d96f21 0 iD8DBQBRkswvywK+sNU5EO8RAiYYAJsHTHyHbJeAgmGvBTmDrfcKu4doUgCeLm7eGBjx7yAPUvEtxef8rAkQmXI=
75 cceaf7af4c9e9e6fa2dbfdcfe9856c5da69c4ffd 0 iD8DBQBRqnFLywK+sNU5EO8RAsWNAJ9RR6t+y1DLFc2HeH0eN9VfZAKF9gCeJ8ezvhtKq/LMs0/nvcgKQc/d5jk=
75 cceaf7af4c9e9e6fa2dbfdcfe9856c5da69c4ffd 0 iD8DBQBRqnFLywK+sNU5EO8RAsWNAJ9RR6t+y1DLFc2HeH0eN9VfZAKF9gCeJ8ezvhtKq/LMs0/nvcgKQc/d5jk=
76 009794acc6e37a650f0fae37872e733382ac1c0c 0 iD8DBQBR0guxywK+sNU5EO8RArNkAKCq9pMihVzP8Os5kCmgbWpe5C37wgCgqzuPZTHvAsXF5wTyaSTMVa9Ccq4=
76 009794acc6e37a650f0fae37872e733382ac1c0c 0 iD8DBQBR0guxywK+sNU5EO8RArNkAKCq9pMihVzP8Os5kCmgbWpe5C37wgCgqzuPZTHvAsXF5wTyaSTMVa9Ccq4=
77 f0d7721d7322dcfb5af33599c2543f27335334bb 0 iD8DBQBR8taaywK+sNU5EO8RAqeEAJ4idDhhDuEsgsUjeQgWNj498matHACfT67gSF5w0ylsrBx1Hb52HkGXDm0=
77 f0d7721d7322dcfb5af33599c2543f27335334bb 0 iD8DBQBR8taaywK+sNU5EO8RAqeEAJ4idDhhDuEsgsUjeQgWNj498matHACfT67gSF5w0ylsrBx1Hb52HkGXDm0=
78 f37b5a17e6a0ee17afde2cdde5393dd74715fb58 0 iD8DBQBR+ymFywK+sNU5EO8RAuSdAJkBMcd9DAZ3rWE9WGKPm2YZ8LBoXACfXn/wbEsVy7ZgJoUwiWmHSnQaWCI=
78 f37b5a17e6a0ee17afde2cdde5393dd74715fb58 0 iD8DBQBR+ymFywK+sNU5EO8RAuSdAJkBMcd9DAZ3rWE9WGKPm2YZ8LBoXACfXn/wbEsVy7ZgJoUwiWmHSnQaWCI=
79 335a558f81dc73afeab4d7be63617392b130117f 0 iQIVAwUAUiZrIyBXgaxoKi1yAQK2iw//cquNqqSkc8Re5/TZT9I6NH+lh6DbOKjJP0Xl1Wqq0K+KSIUgZG4G32ovaEb2l5X0uY+3unRPiZ0ebl0YSw4Fb2ZiPIADXLBTOYRrY2Wwd3tpJeGI6wEgZt3SfcITV/g7NJrCjT3FlYoSOIayrExM80InSdcEM0Q3Rx6HKzY2acyxzgZeAtAW5ohFvHilSvY6p5Gcm4+QptMxvw45GPdreUmjeXZxNXNXZ8P+MjMz/QJbai/N7PjmK8lqnhkBsT48Ng/KhhmOkGntNJ2/ImBWLFGcWngSvJ7sfWwnyhndvGhe0Hq1NcCf7I8TjNDxU5TR+m+uW7xjXdLoDbUjBdX4sKXnh8ZjbYiODKBOrrDq25cf8nA/tnpKyE/qsVy60kOk6loY4XKiYmn1V49Ta0emmDx0hqo3HgxHHsHX0NDnGdWGol7cPRET0RzVobKq1A0jnrhPooWidvLh9bPzLonrWDo+ib+DuySoRkuYUK4pgZJ2mbg6daFOBEZygkSyRB8bo1UQUP7EgQDrWe4khb/5GHEfDkrQz3qu/sXvc0Ir1mOUWBFPHC2DjjCn/oMJuUkG1SwM8l2Bfv7h67ssES6YQ2+RjOix4yid7EXS/Ogl45PzCIPSI5+BbNs10JhE0w5uErBHlF53EDTe/TSLc+GU6DB6PP6dH912Njdr3jpNSUQ=
79 335a558f81dc73afeab4d7be63617392b130117f 0 iQIVAwUAUiZrIyBXgaxoKi1yAQK2iw//cquNqqSkc8Re5/TZT9I6NH+lh6DbOKjJP0Xl1Wqq0K+KSIUgZG4G32ovaEb2l5X0uY+3unRPiZ0ebl0YSw4Fb2ZiPIADXLBTOYRrY2Wwd3tpJeGI6wEgZt3SfcITV/g7NJrCjT3FlYoSOIayrExM80InSdcEM0Q3Rx6HKzY2acyxzgZeAtAW5ohFvHilSvY6p5Gcm4+QptMxvw45GPdreUmjeXZxNXNXZ8P+MjMz/QJbai/N7PjmK8lqnhkBsT48Ng/KhhmOkGntNJ2/ImBWLFGcWngSvJ7sfWwnyhndvGhe0Hq1NcCf7I8TjNDxU5TR+m+uW7xjXdLoDbUjBdX4sKXnh8ZjbYiODKBOrrDq25cf8nA/tnpKyE/qsVy60kOk6loY4XKiYmn1V49Ta0emmDx0hqo3HgxHHsHX0NDnGdWGol7cPRET0RzVobKq1A0jnrhPooWidvLh9bPzLonrWDo+ib+DuySoRkuYUK4pgZJ2mbg6daFOBEZygkSyRB8bo1UQUP7EgQDrWe4khb/5GHEfDkrQz3qu/sXvc0Ir1mOUWBFPHC2DjjCn/oMJuUkG1SwM8l2Bfv7h67ssES6YQ2+RjOix4yid7EXS/Ogl45PzCIPSI5+BbNs10JhE0w5uErBHlF53EDTe/TSLc+GU6DB6PP6dH912Njdr3jpNSUQ=
80 e7fa36d2ad3a7944a52dca126458d6f482db3524 0 iQIVAwUAUktg4yBXgaxoKi1yAQLO0g//du/2ypYYUfmM/yZ4zztNKIvgMSGTDVbCCGB2y2/wk2EcolpjpGTkcgnJT413ksYtw78ZU+mvv0RjgrFCm8DQ8kroJaQZ2qHmtSUb42hPBPvtg6kL9YaA4yvp87uUBpFRavGS5uX4hhEIyvZKzhXUBvqtL3TfwR7ld21bj8j00wudqELyyU9IrojIY9jkJ3XL/4shBGgP7u6OK5g8yJ6zTnWgysUetxHBPrYjG25lziiiZQFvZqK1B3PUqAOaFPltQs0PB8ipOCAHQgJsjaREj8VmC3+rskmSSy66NHm6gAB9+E8oAgOcU7FzWbdYgnz4kR3M7TQvHX9U61NinPXC6Q9d1VPhO3E6sIGvqJ4YeQOn65V9ezYuIpFSlgQzCHMmLVnOV96Uv1R/Z39I4w7D3S5qoZcQT/siQwGbsZoPMGFYmqOK1da5TZWrrJWkYzc9xvzT9m3q3Wds5pmCmo4b/dIqDifWwYEcNAZ0/YLHwCN5SEZWuunkEwtU5o7TZAv3bvDDA6WxUrrHI/y9/qvvhXxsJnY8IueNhshdmWZfXKz+lJi2Dvk7DUlEQ1zZWSsozi1E+3biMPJO47jsxjoT/jmE5+GHLCgcnXXDVBeaVal99IOaTRFukiz2EMsry1s8fnwEE5XKDKRlU/dOPfsje0gc7bgE0QD/u3E4NJ99g9A=
80 e7fa36d2ad3a7944a52dca126458d6f482db3524 0 iQIVAwUAUktg4yBXgaxoKi1yAQLO0g//du/2ypYYUfmM/yZ4zztNKIvgMSGTDVbCCGB2y2/wk2EcolpjpGTkcgnJT413ksYtw78ZU+mvv0RjgrFCm8DQ8kroJaQZ2qHmtSUb42hPBPvtg6kL9YaA4yvp87uUBpFRavGS5uX4hhEIyvZKzhXUBvqtL3TfwR7ld21bj8j00wudqELyyU9IrojIY9jkJ3XL/4shBGgP7u6OK5g8yJ6zTnWgysUetxHBPrYjG25lziiiZQFvZqK1B3PUqAOaFPltQs0PB8ipOCAHQgJsjaREj8VmC3+rskmSSy66NHm6gAB9+E8oAgOcU7FzWbdYgnz4kR3M7TQvHX9U61NinPXC6Q9d1VPhO3E6sIGvqJ4YeQOn65V9ezYuIpFSlgQzCHMmLVnOV96Uv1R/Z39I4w7D3S5qoZcQT/siQwGbsZoPMGFYmqOK1da5TZWrrJWkYzc9xvzT9m3q3Wds5pmCmo4b/dIqDifWwYEcNAZ0/YLHwCN5SEZWuunkEwtU5o7TZAv3bvDDA6WxUrrHI/y9/qvvhXxsJnY8IueNhshdmWZfXKz+lJi2Dvk7DUlEQ1zZWSsozi1E+3biMPJO47jsxjoT/jmE5+GHLCgcnXXDVBeaVal99IOaTRFukiz2EMsry1s8fnwEE5XKDKRlU/dOPfsje0gc7bgE0QD/u3E4NJ99g9A=
81 1596f2d8f2421314b1ddead8f7d0c91009358994 0 iQIVAwUAUmRq+yBXgaxoKi1yAQLolhAAi+l4ZFdQTu9yJDv22YmkmHH4fI3d5VBYgvfJPufpyaj7pX626QNW18UNcGSw2BBpYHIJzWPkk/4XznLVKr4Ciw2N3/yqloEFV0V2SSrTbMWiR9qXI4KJH+Df3KZnKs3FgiYpXkErL4GWkc1jLVR50xQ5RnkMljjtCd0NTeV2PHZ6gP2qbu6CS+5sm3AFhTDGnx8GicbMw76ZNw5M2G+T48yH9jn5KQi2SBThfi4H9Bpr8FDuR7PzQLgw9SbtYxtdQxNkK55k0nG4oLDxduNakU6SH9t8n8tdCfMt58kTzlQVrPFiTFjKu2n2JioDTz2HEivbZ5H757cu7SvpX8gW3paeBc57e+GOLMisMZABXLICq59c3QnrMwFY4FG+5cpiHVXoaZz/0bYCJx+IhU4QLWqZuzb18KSyHUCqQRzXlzS6QV5O7dY5YNQXFC44j/dS5zdgWMYo2mc6mVP2OaPUn7F6aQh5MCDYorPIOkcNjOg7ytajo7DXbzWt5Al8qt6386BJksyR3GAonc09+l8IFeNxk8HZNP4ETQ8aWj0dC9jgBDPK43T2Bju/i84s+U/bRe4tGSQalZUEv06mkIH/VRJp5w2izYTsdIjA4FT9d36OhaxlfoO1X6tHR9AyA3bF/g/ozvBwuo3kTRUUqo+Ggvx/DmcPQdDiZZQIqDBXch0=
81 1596f2d8f2421314b1ddead8f7d0c91009358994 0 iQIVAwUAUmRq+yBXgaxoKi1yAQLolhAAi+l4ZFdQTu9yJDv22YmkmHH4fI3d5VBYgvfJPufpyaj7pX626QNW18UNcGSw2BBpYHIJzWPkk/4XznLVKr4Ciw2N3/yqloEFV0V2SSrTbMWiR9qXI4KJH+Df3KZnKs3FgiYpXkErL4GWkc1jLVR50xQ5RnkMljjtCd0NTeV2PHZ6gP2qbu6CS+5sm3AFhTDGnx8GicbMw76ZNw5M2G+T48yH9jn5KQi2SBThfi4H9Bpr8FDuR7PzQLgw9SbtYxtdQxNkK55k0nG4oLDxduNakU6SH9t8n8tdCfMt58kTzlQVrPFiTFjKu2n2JioDTz2HEivbZ5H757cu7SvpX8gW3paeBc57e+GOLMisMZABXLICq59c3QnrMwFY4FG+5cpiHVXoaZz/0bYCJx+IhU4QLWqZuzb18KSyHUCqQRzXlzS6QV5O7dY5YNQXFC44j/dS5zdgWMYo2mc6mVP2OaPUn7F6aQh5MCDYorPIOkcNjOg7ytajo7DXbzWt5Al8qt6386BJksyR3GAonc09+l8IFeNxk8HZNP4ETQ8aWj0dC9jgBDPK43T2Bju/i84s+U/bRe4tGSQalZUEv06mkIH/VRJp5w2izYTsdIjA4FT9d36OhaxlfoO1X6tHR9AyA3bF/g/ozvBwuo3kTRUUqo+Ggvx/DmcPQdDiZZQIqDBXch0=
82 d825e4025e39d1c39db943cdc89818abd0a87c27 0 iQIVAwUAUnQlXiBXgaxoKi1yAQJd3BAAi7LjMSpXmdR7B8K98C3/By4YHsCOAocMl3JXiLd7SXwKmlta1zxtkgWwWJnNYE3lVJvGCl+l4YsGKmFu755MGXlyORh1x4ohckoC1a8cqnbNAgD6CSvjSaZfnINLGZQP1wIP4yWj0FftKVANQBjj/xkkxO530mjBYnUvyA4PeDd5A1AOUUu6qHzX6S5LcprEt7iktLI+Ae1dYTkiCpckDtyYUKIk3RK/4AGWwGCPddVWeV5bDxLs8GHyMbqdBwx+2EAMtyZfXT+z6MDRsL/gEBVOXHb/UR0qpYED+qFnbtTlxqQkRE/wBhwDoRzUgcSuukQ9iPn79WNDSdT5b6Jd393uEO5BNF/DB6rrOiWmlpoooWgTY9kcwGB02v0hhLrH5r1wkv8baaPl+qjCjBxf4CNKm/83KN5/umGbZlORqPSN5JVxK6vDNwFFmHLaZbMT1g27GsGOWm84VH+dgolgk4nmRNSO37eTNM5Y1C3Zf2amiqDSRcAxCgseg0Jh10G7i52SSTcZPI2MqrwT9eIyg8PTIxT1D5bPcCzkg5nTTL6S7bet7OSwynRnHslhvVUBly8aIj4eY/5cQqAucUUa5sq6xLD8N27Tl+sQi+kE6KtWu2c0ZhpouflYp55XNMHgU4KeFcVcDtHfJRF6THT6tFcHFNauCHbhfN2F33ANMP4=
82 d825e4025e39d1c39db943cdc89818abd0a87c27 0 iQIVAwUAUnQlXiBXgaxoKi1yAQJd3BAAi7LjMSpXmdR7B8K98C3/By4YHsCOAocMl3JXiLd7SXwKmlta1zxtkgWwWJnNYE3lVJvGCl+l4YsGKmFu755MGXlyORh1x4ohckoC1a8cqnbNAgD6CSvjSaZfnINLGZQP1wIP4yWj0FftKVANQBjj/xkkxO530mjBYnUvyA4PeDd5A1AOUUu6qHzX6S5LcprEt7iktLI+Ae1dYTkiCpckDtyYUKIk3RK/4AGWwGCPddVWeV5bDxLs8GHyMbqdBwx+2EAMtyZfXT+z6MDRsL/gEBVOXHb/UR0qpYED+qFnbtTlxqQkRE/wBhwDoRzUgcSuukQ9iPn79WNDSdT5b6Jd393uEO5BNF/DB6rrOiWmlpoooWgTY9kcwGB02v0hhLrH5r1wkv8baaPl+qjCjBxf4CNKm/83KN5/umGbZlORqPSN5JVxK6vDNwFFmHLaZbMT1g27GsGOWm84VH+dgolgk4nmRNSO37eTNM5Y1C3Zf2amiqDSRcAxCgseg0Jh10G7i52SSTcZPI2MqrwT9eIyg8PTIxT1D5bPcCzkg5nTTL6S7bet7OSwynRnHslhvVUBly8aIj4eY/5cQqAucUUa5sq6xLD8N27Tl+sQi+kE6KtWu2c0ZhpouflYp55XNMHgU4KeFcVcDtHfJRF6THT6tFcHFNauCHbhfN2F33ANMP4=
83 209e04a06467e2969c0cc6501335be0406d46ef0 0 iQIVAwUAUpv1oCBXgaxoKi1yAQKOFBAAma2wlsr3w/5NvDwq2rmOrgtNDq1DnNqcXloaOdwegX1z3/N++5uVjLjI0VyguexnwK+7E8rypMZ+4glaiZvIiGPnGMYbG9iOoz5XBhtUHzI5ECYfm5QU81by9VmCIvArDFe5Hlnz4XaXpEGnAwPywD+yzV3/+tyoV7MgsVinCMtbX9OF84/ubWKNzq2810FpQRfYoCOrF8sUed/1TcQrSm1eMB/PnuxjFCFySiR6J7Urd9bJoJIDtdZOQeeHaL5Z8Pcsyzjoe/9oTwJ3L3tl/NMZtRxiQUWtfRA0zvEnQ4QEkZSDMd/JnGiWHPVeP4P92+YN15za9yhneEAtustrTNAmVF2Uh92RIlmkG475HFhvwPJ4DfCx0vU1OOKX/U4c1rifW7H7HaipoaMlsDU2VFsAHcc3YF8ulVt27bH2yUaLGJz7eqpt+3DzZTKp4d/brZA2EkbVgsoYP+XYLbzxfwWlaMwiN3iCnlTFbNogH8MxhfHFWBj6ouikqOz8HlNl6BmSQiUCBnz5fquVpXmW2Md+TDekk+uOW9mvk1QMU62br+Z6PEZupkdTrqKaz+8ZMWvTRct8SiOcu7R11LpfERyrwYGGPei0P2YrEGIWGgXvEobXoPTSl7J+mpOA/rp2Q1zA3ihjgzwtGZZF+ThQXZGIMGaA2YPgzuYRqY8l5oc=
83 209e04a06467e2969c0cc6501335be0406d46ef0 0 iQIVAwUAUpv1oCBXgaxoKi1yAQKOFBAAma2wlsr3w/5NvDwq2rmOrgtNDq1DnNqcXloaOdwegX1z3/N++5uVjLjI0VyguexnwK+7E8rypMZ+4glaiZvIiGPnGMYbG9iOoz5XBhtUHzI5ECYfm5QU81by9VmCIvArDFe5Hlnz4XaXpEGnAwPywD+yzV3/+tyoV7MgsVinCMtbX9OF84/ubWKNzq2810FpQRfYoCOrF8sUed/1TcQrSm1eMB/PnuxjFCFySiR6J7Urd9bJoJIDtdZOQeeHaL5Z8Pcsyzjoe/9oTwJ3L3tl/NMZtRxiQUWtfRA0zvEnQ4QEkZSDMd/JnGiWHPVeP4P92+YN15za9yhneEAtustrTNAmVF2Uh92RIlmkG475HFhvwPJ4DfCx0vU1OOKX/U4c1rifW7H7HaipoaMlsDU2VFsAHcc3YF8ulVt27bH2yUaLGJz7eqpt+3DzZTKp4d/brZA2EkbVgsoYP+XYLbzxfwWlaMwiN3iCnlTFbNogH8MxhfHFWBj6ouikqOz8HlNl6BmSQiUCBnz5fquVpXmW2Md+TDekk+uOW9mvk1QMU62br+Z6PEZupkdTrqKaz+8ZMWvTRct8SiOcu7R11LpfERyrwYGGPei0P2YrEGIWGgXvEobXoPTSl7J+mpOA/rp2Q1zA3ihjgzwtGZZF+ThQXZGIMGaA2YPgzuYRqY8l5oc=
84 ca387377df7a3a67dbb90b6336b781cdadc3ef41 0 iQIVAwUAUsThISBXgaxoKi1yAQJpvRAAkRkCWLjHBZnWxX9Oe6t2HQgkSsmn9wMHvXXGFkcAmrqJ86yfyrxLq2Ns0X7Qwky37kOwKsywM53FQlsx9j//Y+ncnGZoObFTz9YTuSbOHGVsTbAruXWxBrGOf1nFTlg8afcbH0jPfQXwxf3ptfBhgsFCzORcqc8HNopAW+2sgXGhHnbVtq6LF90PWkbKjCCQLiX3da1uETGAElrl4jA5Y2i64S1Q/2X+UFrNslkIIRCGmAJ6BnE6KLJaUftpfbN7Br7a3z9xxWqxRYDOinxDgfAPAucOJPLgMVQ0bJIallaRu7KTmIWKIuSBgg1/hgfoX8I1w49WrTGp0gGY140kl8RWwczAz/SB03Xtbl2+h6PV7rUV2K/5g61DkwdVbWqXM9wmJZmvjEKK0qQbBT0By4QSEDNcKKqtaFFwhFzx4dkXph0igHOtXhSNzMd8PsFx/NRn9NLFIpirxfqVDwakpDNBZw4Q9hUAlTPxSFL3vD9/Zs7lV4/dAvvl+tixJEi2k/iv248b/AI1PrPIQEqDvjrozzzYvrS4HtbkUn+IiHiepQaYnpqKoXvBu6btK/nv0GTxB5OwVJzMA1RPDcxIFfZA2AazHjrXiPAl5uWYEddEvRjaCiF8xkQkfiXzLOoqhKQHdwPGcfMFEs9lNR8BrB2ZOajBJc8RPsFDswhT5h4=
84 ca387377df7a3a67dbb90b6336b781cdadc3ef41 0 iQIVAwUAUsThISBXgaxoKi1yAQJpvRAAkRkCWLjHBZnWxX9Oe6t2HQgkSsmn9wMHvXXGFkcAmrqJ86yfyrxLq2Ns0X7Qwky37kOwKsywM53FQlsx9j//Y+ncnGZoObFTz9YTuSbOHGVsTbAruXWxBrGOf1nFTlg8afcbH0jPfQXwxf3ptfBhgsFCzORcqc8HNopAW+2sgXGhHnbVtq6LF90PWkbKjCCQLiX3da1uETGAElrl4jA5Y2i64S1Q/2X+UFrNslkIIRCGmAJ6BnE6KLJaUftpfbN7Br7a3z9xxWqxRYDOinxDgfAPAucOJPLgMVQ0bJIallaRu7KTmIWKIuSBgg1/hgfoX8I1w49WrTGp0gGY140kl8RWwczAz/SB03Xtbl2+h6PV7rUV2K/5g61DkwdVbWqXM9wmJZmvjEKK0qQbBT0By4QSEDNcKKqtaFFwhFzx4dkXph0igHOtXhSNzMd8PsFx/NRn9NLFIpirxfqVDwakpDNBZw4Q9hUAlTPxSFL3vD9/Zs7lV4/dAvvl+tixJEi2k/iv248b/AI1PrPIQEqDvjrozzzYvrS4HtbkUn+IiHiepQaYnpqKoXvBu6btK/nv0GTxB5OwVJzMA1RPDcxIFfZA2AazHjrXiPAl5uWYEddEvRjaCiF8xkQkfiXzLOoqhKQHdwPGcfMFEs9lNR8BrB2ZOajBJc8RPsFDswhT5h4=
85 8862469e16f9236208581b20de5f96bd13cc039d 0 iQIVAwUAUt7cLSBXgaxoKi1yAQLOkRAAidp501zafqe+JnDwlf7ORcJc+FgCE6mK1gxDfReCbkMsY7AzspogU7orqfSmr6XXdrDwmk3Y5x3mf44OGzNQjvuNWhqnTgJ7sOcU/lICGQUc8WiGNzHEMFGX9S+K4dpUaBf8Tcl8pU3iArhlthDghW6SZeDFB/FDBaUx9dkdFp6eXrmu4OuGRZEvwUvPtCGxIL7nKNnufI1du/MsWQxvC2ORHbMNtRq6tjA0fLZi4SvbySuYifQRS32BfHkFS5Qu4/40+1k7kd0YFyyQUvIsVa17lrix3zDqMavG8x7oOlqM/axDMBT6DhpdBMAdc5qqf8myz8lwjlFjyDUL6u3Z4/yE0nUrmEudXiXwG0xbVoEN8SCNrDmmvFMt6qdCpdDMkHr2TuSh0Hh4FT5CDkzPI8ZRssv/01j/QvIO3c/xlbpGRPWpsPXEVOz3pmjYN4qyQesnBKWCENsQLy/8s2rey8iQgx2GtsrNw8+wGX6XE4v3QtwUrRe12hWoNrEHWl0xnLv2mvAFqdMAMpFY6EpOKLlE4hoCs2CmTJ2dv6e2tiGTXGU6/frI5iuNRK61OXnH5OjEc8DCGH/GC7NXyDOXOB+7BdBvvf50l2C/vxR2TKgTncLtHeLCrR0GHNHsxqRo1UDwOWur0r7fdfCRvb2tIr5LORCqKYVKd60/BAXjHWc=
85 8862469e16f9236208581b20de5f96bd13cc039d 0 iQIVAwUAUt7cLSBXgaxoKi1yAQLOkRAAidp501zafqe+JnDwlf7ORcJc+FgCE6mK1gxDfReCbkMsY7AzspogU7orqfSmr6XXdrDwmk3Y5x3mf44OGzNQjvuNWhqnTgJ7sOcU/lICGQUc8WiGNzHEMFGX9S+K4dpUaBf8Tcl8pU3iArhlthDghW6SZeDFB/FDBaUx9dkdFp6eXrmu4OuGRZEvwUvPtCGxIL7nKNnufI1du/MsWQxvC2ORHbMNtRq6tjA0fLZi4SvbySuYifQRS32BfHkFS5Qu4/40+1k7kd0YFyyQUvIsVa17lrix3zDqMavG8x7oOlqM/axDMBT6DhpdBMAdc5qqf8myz8lwjlFjyDUL6u3Z4/yE0nUrmEudXiXwG0xbVoEN8SCNrDmmvFMt6qdCpdDMkHr2TuSh0Hh4FT5CDkzPI8ZRssv/01j/QvIO3c/xlbpGRPWpsPXEVOz3pmjYN4qyQesnBKWCENsQLy/8s2rey8iQgx2GtsrNw8+wGX6XE4v3QtwUrRe12hWoNrEHWl0xnLv2mvAFqdMAMpFY6EpOKLlE4hoCs2CmTJ2dv6e2tiGTXGU6/frI5iuNRK61OXnH5OjEc8DCGH/GC7NXyDOXOB+7BdBvvf50l2C/vxR2TKgTncLtHeLCrR0GHNHsxqRo1UDwOWur0r7fdfCRvb2tIr5LORCqKYVKd60/BAXjHWc=
86 3cec5134e9c4bceab6a00c60f52a4f80677a78f2 0 iQIVAwUAUu1lIyBXgaxoKi1yAQIzCBAAizSWvTkWt8+tReM9jUetoSToF+XahLhn381AYdErFCBErX4bNL+vyEj+Jt2DHsAfabkvNBe3k7rtFlXHwpq6POa/ciFGPDhFlplNv6yN1jOKBlMsgdjpn7plZKcLHODOigU7IMlgg70Um8qVrRgQ8FhvbVgR2I5+CD6bucFzqo78wNl9mCIHIQCpGKIUoz56GbwT+rUpEB182Z3u6rf4NWj35RZLGAicVV2A2eAAFh4ZvuC+Z0tXMkp6Gq9cINawZgqfLbzVYJeXBtJC39lHPyp5P3LaEVRhntc9YTwbfkVGjyJZR60iYrieeKpOYRnzgHauPVdgVhkTkBxshmEPY7svKYSQqlj8hLuFa+a3ajbIPrpQAAi1MgtamA991atNqGiSTjdZa9kLQvfdn0k80+gkCxpuO56PhvtdjKsYVRgQMTYmQVQdh3x4WbQOSqTADXXIZUaWxx4RmNSlxY7KD+3lPP09teOD+A3B2cP60bC5NsCfULtQFXQzdC7NvfIyYfYBTZa+Pv6HFkVe10cbnqTt83hBy0D77vdaegPRe56qDNU+GrIG2/rosnlKGFjFoK/pTYkR9uzfkrhEjLwyfkoXlBqY+376W0PC5fP10pJeQBS9DuXpCPlgtyW0Jy1ayCT1YR4QJC4n75vZwTFBFRBhSi0HqFquOgy83+O0Q/k=
86 3cec5134e9c4bceab6a00c60f52a4f80677a78f2 0 iQIVAwUAUu1lIyBXgaxoKi1yAQIzCBAAizSWvTkWt8+tReM9jUetoSToF+XahLhn381AYdErFCBErX4bNL+vyEj+Jt2DHsAfabkvNBe3k7rtFlXHwpq6POa/ciFGPDhFlplNv6yN1jOKBlMsgdjpn7plZKcLHODOigU7IMlgg70Um8qVrRgQ8FhvbVgR2I5+CD6bucFzqo78wNl9mCIHIQCpGKIUoz56GbwT+rUpEB182Z3u6rf4NWj35RZLGAicVV2A2eAAFh4ZvuC+Z0tXMkp6Gq9cINawZgqfLbzVYJeXBtJC39lHPyp5P3LaEVRhntc9YTwbfkVGjyJZR60iYrieeKpOYRnzgHauPVdgVhkTkBxshmEPY7svKYSQqlj8hLuFa+a3ajbIPrpQAAi1MgtamA991atNqGiSTjdZa9kLQvfdn0k80+gkCxpuO56PhvtdjKsYVRgQMTYmQVQdh3x4WbQOSqTADXXIZUaWxx4RmNSlxY7KD+3lPP09teOD+A3B2cP60bC5NsCfULtQFXQzdC7NvfIyYfYBTZa+Pv6HFkVe10cbnqTt83hBy0D77vdaegPRe56qDNU+GrIG2/rosnlKGFjFoK/pTYkR9uzfkrhEjLwyfkoXlBqY+376W0PC5fP10pJeQBS9DuXpCPlgtyW0Jy1ayCT1YR4QJC4n75vZwTFBFRBhSi0HqFquOgy83+O0Q/k=
87 b96cb15ec9e04d8ac5ee08b34fcbbe4200588965 0 iQIVAwUAUxJPlyBXgaxoKi1yAQLIRA//Qh9qzoYthPAWAUNbzybWXC/oMBI2X89NQC7l1ivKhv7cn9L79D8SWXM18q7LTwLdlwOkV/a0NTE3tkQTLvxJpfnRLCBbMOcGiIn/PxsAae8IhMAUbR7qz+XOynHOs60ZhK9X8seQHJRf1YtOI9gYTL/WYk8Cnpmc6xZQ90TNhoPPkpdfe8Y236V11SbYtN14fmrPaWQ3GXwyrvQaqM1F7BxSnC/sbm9+/wprsTa8gRQo7YQL/T5jJQgFiatG3yayrDdJtoRq3TZKtsxw8gtQdfVCrrBibbysjM8++dnwA92apHNUY8LzyptPy7rSDXRrIpPUWGGTQTD+6HQwkcLFtIuUpw4I75SV3z2r6LyOLKzDJUIunKOOYFS/rEIQGxZHxZOBAvbI+73mHAn3pJqm+UAA7R1n7tk3JyQncg50qJlm9zIUPGpNFcdEqak5iXzGYx292VlcE+fbJYeIPWggpilaVUgdmXtMCG0O0uX6C8MDmzVDCjd6FzDJ4GTZwgmWJaamvls85CkZgyN/UqlisfFXub0A1h7qAzBSVpP1+Ti+UbBjlrGX8BMRYHRGYIeIq16elcWwSpLgshjDwNn2r2EdwX8xKU5mucgTzSLprbOYGdQaqnvf6e8IX5WMBgwVW9YdY9yJKSLF7kE1AlM9nfVcXwOK4mHoMvnNgiX3zsw=
87 b96cb15ec9e04d8ac5ee08b34fcbbe4200588965 0 iQIVAwUAUxJPlyBXgaxoKi1yAQLIRA//Qh9qzoYthPAWAUNbzybWXC/oMBI2X89NQC7l1ivKhv7cn9L79D8SWXM18q7LTwLdlwOkV/a0NTE3tkQTLvxJpfnRLCBbMOcGiIn/PxsAae8IhMAUbR7qz+XOynHOs60ZhK9X8seQHJRf1YtOI9gYTL/WYk8Cnpmc6xZQ90TNhoPPkpdfe8Y236V11SbYtN14fmrPaWQ3GXwyrvQaqM1F7BxSnC/sbm9+/wprsTa8gRQo7YQL/T5jJQgFiatG3yayrDdJtoRq3TZKtsxw8gtQdfVCrrBibbysjM8++dnwA92apHNUY8LzyptPy7rSDXRrIpPUWGGTQTD+6HQwkcLFtIuUpw4I75SV3z2r6LyOLKzDJUIunKOOYFS/rEIQGxZHxZOBAvbI+73mHAn3pJqm+UAA7R1n7tk3JyQncg50qJlm9zIUPGpNFcdEqak5iXzGYx292VlcE+fbJYeIPWggpilaVUgdmXtMCG0O0uX6C8MDmzVDCjd6FzDJ4GTZwgmWJaamvls85CkZgyN/UqlisfFXub0A1h7qAzBSVpP1+Ti+UbBjlrGX8BMRYHRGYIeIq16elcWwSpLgshjDwNn2r2EdwX8xKU5mucgTzSLprbOYGdQaqnvf6e8IX5WMBgwVW9YdY9yJKSLF7kE1AlM9nfVcXwOK4mHoMvnNgiX3zsw=
88 3f83fc5cfe715d292069ee8417c83804f6c6c1e4 0 iQIVAwUAUztENyBXgaxoKi1yAQIpkhAAmJj5JRTSn0Dn/OTAHggalw8KYFbAck1X35Wg9O7ku7sd+cOnNnkYfqAdz2m5ikqWHP7aWMiNkNy7Ree2110NqkQVYG/2AJStXBdIOmewqnjDlNt+rbJQN/JsjeKSCy+ToNvhqX5cTM9DF2pwRjMsTXVff307S6/3pga244i+RFAeG3WCUrzfDu641MGFLjG4atCj8ZFLg9DcW5bsRiOs5ZK5Il+UAb2yyoS2KNQ70VLhYULhGtqq9tuO4nLRGN3DX/eDcYfncPCav1GckW4OZKakcbLtAdW0goSgGWloxcM+j2E6Z1JZ9tOTTkFN77EvX0ZWZLmYM7sUN1meFnKbVxrtGKlMelwKwlT252c65PAKa9zsTaRUKvN7XclyxZAYVCsiCQ/V08NXhNgXJXcoKUAeGNf6wruOyvRU9teia8fAiuHJoY58WC8jC4nYG3iZTnl+zNj2A5xuEUpYHhjUfe3rNJeK7CwUpJKlbxopu5mnW9AE9ITfI490eaapRLTojOBDJNqCORAtbggMD46fLeCOzzB8Gl70U2p5P34F92Sn6mgERFKh/10XwJcj4ZIeexbQK8lqQ2cIanDN9dAmbvavPTY8grbANuq+vXDGxjIjfxapqzsSPqUJ5KnfTQyLq5NWwquR9t38XvHZfktkd140BFKwIUAIlKKaFfYXXtM=
88 3f83fc5cfe715d292069ee8417c83804f6c6c1e4 0 iQIVAwUAUztENyBXgaxoKi1yAQIpkhAAmJj5JRTSn0Dn/OTAHggalw8KYFbAck1X35Wg9O7ku7sd+cOnNnkYfqAdz2m5ikqWHP7aWMiNkNy7Ree2110NqkQVYG/2AJStXBdIOmewqnjDlNt+rbJQN/JsjeKSCy+ToNvhqX5cTM9DF2pwRjMsTXVff307S6/3pga244i+RFAeG3WCUrzfDu641MGFLjG4atCj8ZFLg9DcW5bsRiOs5ZK5Il+UAb2yyoS2KNQ70VLhYULhGtqq9tuO4nLRGN3DX/eDcYfncPCav1GckW4OZKakcbLtAdW0goSgGWloxcM+j2E6Z1JZ9tOTTkFN77EvX0ZWZLmYM7sUN1meFnKbVxrtGKlMelwKwlT252c65PAKa9zsTaRUKvN7XclyxZAYVCsiCQ/V08NXhNgXJXcoKUAeGNf6wruOyvRU9teia8fAiuHJoY58WC8jC4nYG3iZTnl+zNj2A5xuEUpYHhjUfe3rNJeK7CwUpJKlbxopu5mnW9AE9ITfI490eaapRLTojOBDJNqCORAtbggMD46fLeCOzzB8Gl70U2p5P34F92Sn6mgERFKh/10XwJcj4ZIeexbQK8lqQ2cIanDN9dAmbvavPTY8grbANuq+vXDGxjIjfxapqzsSPqUJ5KnfTQyLq5NWwquR9t38XvHZfktkd140BFKwIUAIlKKaFfYXXtM=
89 564f55b251224f16508dd1311452db7780dafe2b 0 iQIVAwUAU1BmFSBXgaxoKi1yAQJ2Aw//bjK++xJuZCIdktg/i5FxBwoxdbipfTkKsN/YjUwrEmroYM8IkqIsO+U54OGCYWr3NPJ3VS8wUQeJ+NF3ffcjmjC297R9J+X0c5G90DdQUYX44jG/tP8Tqpev4Q7DLCXT26aRwEMdJQpq0eGaqv55E5Cxnyt3RrLCqe7RjPresZFg7iYrro5nq8TGYwBhessHXnCix9QI0HtXiLpms+0UGz8Sbi9nEYW+M0OZCyO1TvykCpFzEsLNwqqtFvhOMD/AMiWcTKNUpjmOn3V83xjWl+jnDUt7BxJ7n1efUnlwl4IeWlSUb73q/durtaymb97cSdKFmXHv4pdAShQEuEpVVGO1WELsKoXmbj30ItTW2V3KvNbjFsvIdDo7zLCpXyTq1HC56W7QCIMINX2qT+hrAMWC12tPQ05f89Cv1+jpk6eOPFqIHFdi663AjyrnGll8nwN7HJWwtA5wTXisu3bec51FAq4yJTzPMtOE9spz36E+Go2hZ1cAv9oCSceZcM0wB8KiMfaZJKNZNZk1jvsdiio4CcdASOFQPOspz07GqQxVP7W+F1Oz32LgwcNAEAS/f3juwDj45GYfAWJrTh3dnJy5DTD2LVC7KtkxxUVkWkqxivnDB9anj++FN9eyekxzut5eFED+WrCfZMcSPW0ai7wbslhKUhCwSf/v3DgGwsM=
89 564f55b251224f16508dd1311452db7780dafe2b 0 iQIVAwUAU1BmFSBXgaxoKi1yAQJ2Aw//bjK++xJuZCIdktg/i5FxBwoxdbipfTkKsN/YjUwrEmroYM8IkqIsO+U54OGCYWr3NPJ3VS8wUQeJ+NF3ffcjmjC297R9J+X0c5G90DdQUYX44jG/tP8Tqpev4Q7DLCXT26aRwEMdJQpq0eGaqv55E5Cxnyt3RrLCqe7RjPresZFg7iYrro5nq8TGYwBhessHXnCix9QI0HtXiLpms+0UGz8Sbi9nEYW+M0OZCyO1TvykCpFzEsLNwqqtFvhOMD/AMiWcTKNUpjmOn3V83xjWl+jnDUt7BxJ7n1efUnlwl4IeWlSUb73q/durtaymb97cSdKFmXHv4pdAShQEuEpVVGO1WELsKoXmbj30ItTW2V3KvNbjFsvIdDo7zLCpXyTq1HC56W7QCIMINX2qT+hrAMWC12tPQ05f89Cv1+jpk6eOPFqIHFdi663AjyrnGll8nwN7HJWwtA5wTXisu3bec51FAq4yJTzPMtOE9spz36E+Go2hZ1cAv9oCSceZcM0wB8KiMfaZJKNZNZk1jvsdiio4CcdASOFQPOspz07GqQxVP7W+F1Oz32LgwcNAEAS/f3juwDj45GYfAWJrTh3dnJy5DTD2LVC7KtkxxUVkWkqxivnDB9anj++FN9eyekxzut5eFED+WrCfZMcSPW0ai7wbslhKUhCwSf/v3DgGwsM=
90 2195ac506c6ababe86985b932f4948837c0891b5 0 iQIVAwUAU2LO/CBXgaxoKi1yAQI/3w/7BT/VRPyxey6tYp7i5cONIlEB3gznebGYwm0SGYNE6lsvS2VLh6ztb+j4eqOadr8Ssna6bslBx+dVsm+VuJ+vrNLMucD5Uc+fhn6dAfVqg+YBzUEaedI5yNsJizcJUDI7hUVsxiPiiYd9hchCWJ+z2tVt2jCyG2lMV2rbW36AM89sgz/wn5/AaAFsgoS6up/uzA3Tmw+qZSO6dZChb4Q8midIUWEbNzVhokgYcw7/HmjmvkvV9RJYiG8aBnMdQmxTE69q2dTjnnDL6wu61WU2FpTN09HRFbemUqzAfoJp8MmXq6jWgfLcm0cI3kRo7ZNpnEkmVKsfKQCXXiaR4alt9IQpQ6Jl7LSYsYI+D4ejpYysIsZyAE8qzltYhBKJWqO27A5V4WdJsoTgA/RwKfPRlci4PY8I4N466S7PBXVz/Cc5EpFkecvrgceTmBafb8JEi+gPiD2Po4vtW3bCeV4xldiEXHeJ77byUz7fZU7jL78SjJVOCCQTJfKZVr36kTz3KlaOz3E700RxzEFDYbK7I41mdANeQBmNNbcvRTy5ma6W6I3McEcAH4wqM5fFQ8YS+QWJxk85Si8KtaDPqoEdC/0dQPavuU/jAVjhV8IbmmkOtO7WvOHQDBtrR15yMxGMnUwMrPHaRNKdHNYRG0LL7lpCtdMi1mzLQgHYY9SRYvI=
90 2195ac506c6ababe86985b932f4948837c0891b5 0 iQIVAwUAU2LO/CBXgaxoKi1yAQI/3w/7BT/VRPyxey6tYp7i5cONIlEB3gznebGYwm0SGYNE6lsvS2VLh6ztb+j4eqOadr8Ssna6bslBx+dVsm+VuJ+vrNLMucD5Uc+fhn6dAfVqg+YBzUEaedI5yNsJizcJUDI7hUVsxiPiiYd9hchCWJ+z2tVt2jCyG2lMV2rbW36AM89sgz/wn5/AaAFsgoS6up/uzA3Tmw+qZSO6dZChb4Q8midIUWEbNzVhokgYcw7/HmjmvkvV9RJYiG8aBnMdQmxTE69q2dTjnnDL6wu61WU2FpTN09HRFbemUqzAfoJp8MmXq6jWgfLcm0cI3kRo7ZNpnEkmVKsfKQCXXiaR4alt9IQpQ6Jl7LSYsYI+D4ejpYysIsZyAE8qzltYhBKJWqO27A5V4WdJsoTgA/RwKfPRlci4PY8I4N466S7PBXVz/Cc5EpFkecvrgceTmBafb8JEi+gPiD2Po4vtW3bCeV4xldiEXHeJ77byUz7fZU7jL78SjJVOCCQTJfKZVr36kTz3KlaOz3E700RxzEFDYbK7I41mdANeQBmNNbcvRTy5ma6W6I3McEcAH4wqM5fFQ8YS+QWJxk85Si8KtaDPqoEdC/0dQPavuU/jAVjhV8IbmmkOtO7WvOHQDBtrR15yMxGMnUwMrPHaRNKdHNYRG0LL7lpCtdMi1mzLQgHYY9SRYvI=
91 269c80ee5b3cb3684fa8edc61501b3506d02eb10 0 iQIVAwUAU4uX5CBXgaxoKi1yAQLpdg/+OxulOKwZN+Nr7xsRhUijYjyAElRf2mGDvMrbAOA2xNf85DOXjOrX5TKETumf1qANA5cHa1twA8wYgxUzhx30H+w5EsLjyeSsOncRnD5WZNqSoIq2XevT0T4c8xdyNftyBqK4h/SC/t2h3vEiSCUaGcfNK8yk4XO45MIk4kk9nlA9jNWdA5ZMLgEFBye2ggz0JjEAPUkVDqlr9sNORDEbnwZxGPV8CK9HaL/I8VWClaFgjKQmjqV3SQsNFe2XPffzXmIipFJ+ODuXVxYpAsvLiGmcfuUfSDHQ4L9QvjBsWe1PgYMr/6CY/lPYmR+xW5mJUE9eIdN4MYcXgicLrmMpdF5pToNccNCMtfa6CDvEasPRqe2bDzL/Q9dQbdOVE/boaYBlgmYLL+/u+dpqip9KkyGgbSo9uJzst1mLTCzJmr5bw+surul28i9HM+4+Lewg4UUdHLz46no1lfTlB5o5EAhiOZBTEVdoBaKfewVpDa/aBRvtWX7UMVRG5qrtA0sXwydN00Jaqkr9m20W0jWjtc1ZC72QCrynVHOyfIb2rN98rnuy2QN4bTvjNpNjHOhhhPTOoVo0YYPdiUupm46vymUTQCmWsglU4Rlaa3vXneP7JenL5TV8WLPs9J28lF0IkOnyBXY7OFcpvYO1euu7iR1VdjfrQukMyaX18usymiA=
91 269c80ee5b3cb3684fa8edc61501b3506d02eb10 0 iQIVAwUAU4uX5CBXgaxoKi1yAQLpdg/+OxulOKwZN+Nr7xsRhUijYjyAElRf2mGDvMrbAOA2xNf85DOXjOrX5TKETumf1qANA5cHa1twA8wYgxUzhx30H+w5EsLjyeSsOncRnD5WZNqSoIq2XevT0T4c8xdyNftyBqK4h/SC/t2h3vEiSCUaGcfNK8yk4XO45MIk4kk9nlA9jNWdA5ZMLgEFBye2ggz0JjEAPUkVDqlr9sNORDEbnwZxGPV8CK9HaL/I8VWClaFgjKQmjqV3SQsNFe2XPffzXmIipFJ+ODuXVxYpAsvLiGmcfuUfSDHQ4L9QvjBsWe1PgYMr/6CY/lPYmR+xW5mJUE9eIdN4MYcXgicLrmMpdF5pToNccNCMtfa6CDvEasPRqe2bDzL/Q9dQbdOVE/boaYBlgmYLL+/u+dpqip9KkyGgbSo9uJzst1mLTCzJmr5bw+surul28i9HM+4+Lewg4UUdHLz46no1lfTlB5o5EAhiOZBTEVdoBaKfewVpDa/aBRvtWX7UMVRG5qrtA0sXwydN00Jaqkr9m20W0jWjtc1ZC72QCrynVHOyfIb2rN98rnuy2QN4bTvjNpNjHOhhhPTOoVo0YYPdiUupm46vymUTQCmWsglU4Rlaa3vXneP7JenL5TV8WLPs9J28lF0IkOnyBXY7OFcpvYO1euu7iR1VdjfrQukMyaX18usymiA=
92 2d8cd3d0e83c7336c0cb45a9f88638363f993848 0 iQIVAwUAU7OLTCBXgaxoKi1yAQJ+pw/+M3yOesgf55eo3PUTZw02QZxDyEg9ElrRc6664/QFXaJuYdz8H3LGG/NYs8uEdYihiGpS1Qc70jwd1IoUlrCELsaSSZpzWQ+VpQFX29aooBoetfL+8WgqV8zJHCtY0E1EBg/Z3ZL3n2OS++fVeWlKtp5mwEq8uLTUmhIS7GseP3bIG/CwF2Zz4bzhmPGK8V2s74aUvELZLCfkBE1ULNs7Nou1iPDGnhYOD53eq1KGIPlIg1rnLbyYw5bhS20wy5IxkWf2eCaXfmQBTG61kO5m3nkzfVgtxmZHLqYggISTJXUovfGsWZcp5a71clCSMVal+Mfviw8L/UPHG0Ie1c36djJiFLxM0f2HlwVMjegQOZSAeMGg1YL1xnIys2zMMsKgEeR+JISTal1pJyLcT9x5mr1HCnUczSGXE5zsixN+PORRnZOqcEZTa2mHJ1h5jJeEm36B/eR57BMJG+i0QgZqTpLzYTFrp2eWokGMjFB1MvgAkL2YoRsw9h6TeIwqzK8mFwLi28bf1c90gX9uMbwY/NOqGzfQKBR9bvCjs2k/gmJ+qd5AbC3DvOxHnN6hRZUqNq76Bo4F+CUVcjQ/NXnfnOIVNbILpl5Un5kl+8wLFM+mNxDxduajaUwLhSHZofKmmCSLbuuaGmQTC7a/4wzhQM9e5dX0X/8sOo8CptW7uw4=
92 2d8cd3d0e83c7336c0cb45a9f88638363f993848 0 iQIVAwUAU7OLTCBXgaxoKi1yAQJ+pw/+M3yOesgf55eo3PUTZw02QZxDyEg9ElrRc6664/QFXaJuYdz8H3LGG/NYs8uEdYihiGpS1Qc70jwd1IoUlrCELsaSSZpzWQ+VpQFX29aooBoetfL+8WgqV8zJHCtY0E1EBg/Z3ZL3n2OS++fVeWlKtp5mwEq8uLTUmhIS7GseP3bIG/CwF2Zz4bzhmPGK8V2s74aUvELZLCfkBE1ULNs7Nou1iPDGnhYOD53eq1KGIPlIg1rnLbyYw5bhS20wy5IxkWf2eCaXfmQBTG61kO5m3nkzfVgtxmZHLqYggISTJXUovfGsWZcp5a71clCSMVal+Mfviw8L/UPHG0Ie1c36djJiFLxM0f2HlwVMjegQOZSAeMGg1YL1xnIys2zMMsKgEeR+JISTal1pJyLcT9x5mr1HCnUczSGXE5zsixN+PORRnZOqcEZTa2mHJ1h5jJeEm36B/eR57BMJG+i0QgZqTpLzYTFrp2eWokGMjFB1MvgAkL2YoRsw9h6TeIwqzK8mFwLi28bf1c90gX9uMbwY/NOqGzfQKBR9bvCjs2k/gmJ+qd5AbC3DvOxHnN6hRZUqNq76Bo4F+CUVcjQ/NXnfnOIVNbILpl5Un5kl+8wLFM+mNxDxduajaUwLhSHZofKmmCSLbuuaGmQTC7a/4wzhQM9e5dX0X/8sOo8CptW7uw4=
93 6c36dc6cd61a0e1b563f1d51e55bdf4dacf12162 0 iQIVAwUAU8n97yBXgaxoKi1yAQKqcA/+MT0VFoP6N8fHnlxj85maoM2HfZbAzX7oEW1B8F1WH6rHESHDexDWIYWJ2XnEeTD4GCXN0/1p+O/I0IMPNzqoSz8BU0SR4+ejhRkGrKG7mcFiF5G8enxaiISn9nmax6DyRfqtOQBzuXYGObXg9PGvMS6zbR0SorJK61xX7fSsUNN6BAvHJfpwcVkOrrFAIpEhs/Gh9wg0oUKCffO/Abs6oS+P6nGLylpIyXqC7rKZ4uPVc6Ljh9DOcpV4NCU6kQbNE7Ty79E0/JWWLsHOEY4F4WBzI7rVh7dOkRMmfNGaqvKkuNkJOEqTR1o1o73Hhbxn4NU7IPbVP/zFKC+/4QVtcPk2IPlpK1MqA1H2hBNYZhJlNhvAa7LwkIxM0916/zQ8dbFAzp6Ay/t/L0tSEcIrudTz2KTrY0WKw+pkzB/nTwaS3XZre6H2B+gszskmf1Y41clkIy/nH9K7zBuzANWyK3+bm40vmMoBbbnsweUAKkyCwqm4KTyQoYQWzu/ZiZcI+Uuk/ajJ9s7EhJbIlSnYG9ttWL/IZ1h+qPU9mqVO9fcaqkeL/NIRh+IsnzaWo0zmHU1bK+/E29PPGGf3v6+IEJmXg7lvNl5pHiMd2tb7RNO/UaNSv1Y2E9naD4FQwSWo38GRBcnRGuKCLdZNHGUR+6dYo6BJCGG8wtZvNXb3TOo=
93 6c36dc6cd61a0e1b563f1d51e55bdf4dacf12162 0 iQIVAwUAU8n97yBXgaxoKi1yAQKqcA/+MT0VFoP6N8fHnlxj85maoM2HfZbAzX7oEW1B8F1WH6rHESHDexDWIYWJ2XnEeTD4GCXN0/1p+O/I0IMPNzqoSz8BU0SR4+ejhRkGrKG7mcFiF5G8enxaiISn9nmax6DyRfqtOQBzuXYGObXg9PGvMS6zbR0SorJK61xX7fSsUNN6BAvHJfpwcVkOrrFAIpEhs/Gh9wg0oUKCffO/Abs6oS+P6nGLylpIyXqC7rKZ4uPVc6Ljh9DOcpV4NCU6kQbNE7Ty79E0/JWWLsHOEY4F4WBzI7rVh7dOkRMmfNGaqvKkuNkJOEqTR1o1o73Hhbxn4NU7IPbVP/zFKC+/4QVtcPk2IPlpK1MqA1H2hBNYZhJlNhvAa7LwkIxM0916/zQ8dbFAzp6Ay/t/L0tSEcIrudTz2KTrY0WKw+pkzB/nTwaS3XZre6H2B+gszskmf1Y41clkIy/nH9K7zBuzANWyK3+bm40vmMoBbbnsweUAKkyCwqm4KTyQoYQWzu/ZiZcI+Uuk/ajJ9s7EhJbIlSnYG9ttWL/IZ1h+qPU9mqVO9fcaqkeL/NIRh+IsnzaWo0zmHU1bK+/E29PPGGf3v6+IEJmXg7lvNl5pHiMd2tb7RNO/UaNSv1Y2E9naD4FQwSWo38GRBcnRGuKCLdZNHGUR+6dYo6BJCGG8wtZvNXb3TOo=
94 3178e49892020336491cdc6945885c4de26ffa8b 0 iQIVAwUAU9whUCBXgaxoKi1yAQJDKxAAoGzdHXV/BvZ598VExEQ8IqkmBVIP1QZDVBr/orMc1eFM4tbGKxumMGbqgJsg+NetI0irkh/YWeJQ13lT4Og72iJ+4UC9eF9pcpUKr/0eBYdU2N/p2MIbVNWh3aF5QkbuQpSri0VbHOWkxqwoqrrwXEjgHaKYP4PKh+Dzukax4yzBUIyzAG38pt4a8hbjnozCl2uAikxk4Ojg+ZufhPoZWgFEuYzSfK5SrwVKOwuxKYFGbbVGTQMIXLvBhOipAmHp4JMEYHfG85kwuyx/DCDbGmXKPQYQfClwjJ4ob/IwG8asyMsPWs+09vrvpVO08HBuph3GjuiWJ1fhEef/ImWmZdQySI9Y4SjwP4dMVfzLCnY+PYPDM9Sq/5Iee13gI2lVM2NtAfQZPXh9l8u6SbCir1UhMNMx0qVMkqMAATmiZ+ETHCO75q4Wdcmnv5fk2PbvaGBVtrHGeiyuz5mK/j4cMbd0R9R0hR1PyC4dOhNqOnbqELNIe0rKNByG1RkpiQYsqZTU6insmnZrv4fVsxfA4JOObPfKNT4oa24MHS73ldLFCfQAuIxVE7RDJJ3bHeh/yO6Smo28FuVRldBl5e+wj2MykS8iVcuSa1smw6gJ14iLBH369nlR3fAAQxI0omVYPDHLr7SsH3vJasTaCD7V3SL4lW6vo/yaAh4ImlTAE+Y=
94 3178e49892020336491cdc6945885c4de26ffa8b 0 iQIVAwUAU9whUCBXgaxoKi1yAQJDKxAAoGzdHXV/BvZ598VExEQ8IqkmBVIP1QZDVBr/orMc1eFM4tbGKxumMGbqgJsg+NetI0irkh/YWeJQ13lT4Og72iJ+4UC9eF9pcpUKr/0eBYdU2N/p2MIbVNWh3aF5QkbuQpSri0VbHOWkxqwoqrrwXEjgHaKYP4PKh+Dzukax4yzBUIyzAG38pt4a8hbjnozCl2uAikxk4Ojg+ZufhPoZWgFEuYzSfK5SrwVKOwuxKYFGbbVGTQMIXLvBhOipAmHp4JMEYHfG85kwuyx/DCDbGmXKPQYQfClwjJ4ob/IwG8asyMsPWs+09vrvpVO08HBuph3GjuiWJ1fhEef/ImWmZdQySI9Y4SjwP4dMVfzLCnY+PYPDM9Sq/5Iee13gI2lVM2NtAfQZPXh9l8u6SbCir1UhMNMx0qVMkqMAATmiZ+ETHCO75q4Wdcmnv5fk2PbvaGBVtrHGeiyuz5mK/j4cMbd0R9R0hR1PyC4dOhNqOnbqELNIe0rKNByG1RkpiQYsqZTU6insmnZrv4fVsxfA4JOObPfKNT4oa24MHS73ldLFCfQAuIxVE7RDJJ3bHeh/yO6Smo28FuVRldBl5e+wj2MykS8iVcuSa1smw6gJ14iLBH369nlR3fAAQxI0omVYPDHLr7SsH3vJasTaCD7V3SL4lW6vo/yaAh4ImlTAE+Y=
95 5dc91146f35369949ea56b40172308158b59063a 0 iQIVAwUAVAUgJyBXgaxoKi1yAQJkEg/9EXFZvPpuvU7AjII1dlIT8F534AXrO30+H6hweg+h2mUCSb/mZnbo3Jr1tATgBWbIKkYmmsiIKNlJMFNPZTWhImGcVA93t6v85tSFiNJRI2QP9ypl5wTt2KhiS/s7GbUYCtPDm6xyNYoSvDo6vXJ5mfGlgFZY5gYLwEHq/lIRWLWD4EWYWbk5yN+B7rHu6A1n3yro73UR8DudEhYYqC23KbWEqFOiNd1IGj3UJlxIHUE4AcDukxbfiMWrKvv1kuT/vXak3X7cLXlO56aUbMopvaUflA3PSr3XAqynDd69cxACo/T36fuwzCQN4ICpdzGTos0rQALSr7CKF5YP9LMhVhCsOn0pCsAkSiw4HxxbcHQLl+t+0rchNysc4dWGwDt6GAfYcdm3fPtGFtA3qsN8lOpCquFH3TAZ3TrIjLFoTOk6s1xX1x5rjP/DAHc/y3KZU0Ffx3TwdQEEEIFaAXaxQG848rdfzV42+dnFnXh1G/MIrKAmv3ZSUkQ3XJfGc7iu82FsYE1NLHriUQDmMRBzCoQ1Rn1Kji119Cxf5rsMcQ6ZISR1f0jDCUS/qxlHvSqETLp8H63NSUfvuKSC7uC6pGvq9XQm1JRNO5UuJfK6tHzy0jv9bt2IRo2xbmvpDu9L5oHHd3JePsAmFmbrFf/7Qem3JyzEvRcpdcdHtefxcxc=
95 5dc91146f35369949ea56b40172308158b59063a 0 iQIVAwUAVAUgJyBXgaxoKi1yAQJkEg/9EXFZvPpuvU7AjII1dlIT8F534AXrO30+H6hweg+h2mUCSb/mZnbo3Jr1tATgBWbIKkYmmsiIKNlJMFNPZTWhImGcVA93t6v85tSFiNJRI2QP9ypl5wTt2KhiS/s7GbUYCtPDm6xyNYoSvDo6vXJ5mfGlgFZY5gYLwEHq/lIRWLWD4EWYWbk5yN+B7rHu6A1n3yro73UR8DudEhYYqC23KbWEqFOiNd1IGj3UJlxIHUE4AcDukxbfiMWrKvv1kuT/vXak3X7cLXlO56aUbMopvaUflA3PSr3XAqynDd69cxACo/T36fuwzCQN4ICpdzGTos0rQALSr7CKF5YP9LMhVhCsOn0pCsAkSiw4HxxbcHQLl+t+0rchNysc4dWGwDt6GAfYcdm3fPtGFtA3qsN8lOpCquFH3TAZ3TrIjLFoTOk6s1xX1x5rjP/DAHc/y3KZU0Ffx3TwdQEEEIFaAXaxQG848rdfzV42+dnFnXh1G/MIrKAmv3ZSUkQ3XJfGc7iu82FsYE1NLHriUQDmMRBzCoQ1Rn1Kji119Cxf5rsMcQ6ZISR1f0jDCUS/qxlHvSqETLp8H63NSUfvuKSC7uC6pGvq9XQm1JRNO5UuJfK6tHzy0jv9bt2IRo2xbmvpDu9L5oHHd3JePsAmFmbrFf/7Qem3JyzEvRcpdcdHtefxcxc=
96 f768c888aaa68d12dd7f509dcc7f01c9584357d0 0 iQIVAwUAVCxczSBXgaxoKi1yAQJYiA/9HnqKuU7IsGACgsUGt+YaqZQumg077Anj158kihSytmSts6xDxqVY1UQB38dqAKLJrQc7RbN0YK0NVCKZZrx/4OqgWvjiL5qWUJKqQzsDx4LGTUlbPlZNZawW2urmmYW6c9ZZDs1EVnVeZMDrOdntddtnBgtILDwrZ8o3U7FwSlfnm03vTkqUMj9okA3AsI8+lQIlo4qbqjQJYwvUC1ZezRdQwaT1LyoWUgjmhoZ1XWcWKOs9baikaJr6fMv8vZpwmaOY1+pztxYlROeSPVWt9P6yOf0Hi/2eg8AwSZLaX96xfk9IvXUSItg/wjTWP9BhnNs/ulwTnN8QOgSXpYxH4RXwsYOyU7BvwAekA9xi17wuzPrGEliScplxICIZ7jiiwv/VngMvM9AYw2mNBvZt2ZIGrrLaK6pq/zBm5tbviwqt5/8U5aqO8k1O0e4XYm5WmQ1c2AkXRO+xwvFpondlSF2y0flzf2FRXP82QMfsy7vxIP0KmaQ4ex+J8krZgMjNTwXh2M4tdYNtu5AehJQEP3l6giy2srkMDuFLqoe1yECjVlGdgA86ve3J/84I8KGgsufYMhfQnwHHGXCbONcNsDvO0QOee6CIQVcdKCG7dac3M89SC6Ns2CjuC8BIYDRnxbGQb7Fvn4ZcadyJKKbXQJzMgRV25K6BAwTIdvYAtgU=
96 f768c888aaa68d12dd7f509dcc7f01c9584357d0 0 iQIVAwUAVCxczSBXgaxoKi1yAQJYiA/9HnqKuU7IsGACgsUGt+YaqZQumg077Anj158kihSytmSts6xDxqVY1UQB38dqAKLJrQc7RbN0YK0NVCKZZrx/4OqgWvjiL5qWUJKqQzsDx4LGTUlbPlZNZawW2urmmYW6c9ZZDs1EVnVeZMDrOdntddtnBgtILDwrZ8o3U7FwSlfnm03vTkqUMj9okA3AsI8+lQIlo4qbqjQJYwvUC1ZezRdQwaT1LyoWUgjmhoZ1XWcWKOs9baikaJr6fMv8vZpwmaOY1+pztxYlROeSPVWt9P6yOf0Hi/2eg8AwSZLaX96xfk9IvXUSItg/wjTWP9BhnNs/ulwTnN8QOgSXpYxH4RXwsYOyU7BvwAekA9xi17wuzPrGEliScplxICIZ7jiiwv/VngMvM9AYw2mNBvZt2ZIGrrLaK6pq/zBm5tbviwqt5/8U5aqO8k1O0e4XYm5WmQ1c2AkXRO+xwvFpondlSF2y0flzf2FRXP82QMfsy7vxIP0KmaQ4ex+J8krZgMjNTwXh2M4tdYNtu5AehJQEP3l6giy2srkMDuFLqoe1yECjVlGdgA86ve3J/84I8KGgsufYMhfQnwHHGXCbONcNsDvO0QOee6CIQVcdKCG7dac3M89SC6Ns2CjuC8BIYDRnxbGQb7Fvn4ZcadyJKKbXQJzMgRV25K6BAwTIdvYAtgU=
97 7f8d16af8cae246fa5a48e723d48d58b015aed94 0 iQIVAwUAVEL0XyBXgaxoKi1yAQJLkRAAjZhpUju5nnSYtN9S0/vXS/tjuAtBTUdGwc0mz97VrM6Yhc6BjSCZL59tjeqQaoH7Lqf94pRAtZyIB2Vj/VVMDbM+/eaoSr1JixxppU+a4eqScaj82944u4C5YMSMC22PMvEwqKmy87RinZKJlFwSQ699zZ5g6mnNq8xeAiDlYhoF2QKzUXwnKxzpvjGsYhYGDMmVS1QPmky4WGvuTl6KeGkv8LidKf7r6/2RZeMcq+yjJ7R0RTtyjo1cM5dMcn/jRdwZxuV4cmFweCAeoy5guV+X6du022TpVndjOSDoKiRgdk7pTuaToXIy+9bleHpEo9bwKx58wvOMg7sirAYjrA4Xcx762RHiUuidTTPktm8sNsBQmgwJZ8Pzm+8TyHjFGLnBfeiDbQQEdLCXloz0jVOVRflDfMays1WpAYUV8XNOsgxnD2jDU8L0NLkJiX5Y0OerGq9AZ+XbgJFVBFhaOfsm2PEc3jq00GOLzrGzA+4b3CGpFzM3EyK9OnnwbP7SqCGb7PJgjmQ7IO8IWEmVYGaKtWONSm8zRLcKdH8xuk8iN1qCkBXMty/wfTEVTkIlMVEDbslYkVfj0rAPJ8B37bfe0Yz4CEMkCmARIB1rIOpMhnavXGuD50OP2PBBY/8DyC5aY97z9f04na/ffk+l7rWaHihjHufKIApt5OnfJ1w=
97 7f8d16af8cae246fa5a48e723d48d58b015aed94 0 iQIVAwUAVEL0XyBXgaxoKi1yAQJLkRAAjZhpUju5nnSYtN9S0/vXS/tjuAtBTUdGwc0mz97VrM6Yhc6BjSCZL59tjeqQaoH7Lqf94pRAtZyIB2Vj/VVMDbM+/eaoSr1JixxppU+a4eqScaj82944u4C5YMSMC22PMvEwqKmy87RinZKJlFwSQ699zZ5g6mnNq8xeAiDlYhoF2QKzUXwnKxzpvjGsYhYGDMmVS1QPmky4WGvuTl6KeGkv8LidKf7r6/2RZeMcq+yjJ7R0RTtyjo1cM5dMcn/jRdwZxuV4cmFweCAeoy5guV+X6du022TpVndjOSDoKiRgdk7pTuaToXIy+9bleHpEo9bwKx58wvOMg7sirAYjrA4Xcx762RHiUuidTTPktm8sNsBQmgwJZ8Pzm+8TyHjFGLnBfeiDbQQEdLCXloz0jVOVRflDfMays1WpAYUV8XNOsgxnD2jDU8L0NLkJiX5Y0OerGq9AZ+XbgJFVBFhaOfsm2PEc3jq00GOLzrGzA+4b3CGpFzM3EyK9OnnwbP7SqCGb7PJgjmQ7IO8IWEmVYGaKtWONSm8zRLcKdH8xuk8iN1qCkBXMty/wfTEVTkIlMVEDbslYkVfj0rAPJ8B37bfe0Yz4CEMkCmARIB1rIOpMhnavXGuD50OP2PBBY/8DyC5aY97z9f04na/ffk+l7rWaHihjHufKIApt5OnfJ1w=
98 ced632394371a36953ce4d394f86278ae51a2aae 0 iQIVAwUAVFWpfSBXgaxoKi1yAQLCQw//cvCi/Di3z/2ZEDQt4Ayyxv18gzewqrYyoElgnEzr5uTynD9Mf25hprstKla/Y5C6q+y0K6qCHPimGOkz3H+wZ2GVUgLKAwMABkfSb5IZiLTGaB2DjAJKZRwB6h43wG/DSFggE3dYszWuyHW88c72ZzVF5CSNc4J1ARLjDSgnNYJQ6XdPw3C9KgiLFDXzynPpZbPg0AK5bdPUKJruMeIKPn36Hx/Tv5GXUrbc2/lcnyRDFWisaDl0X/5eLdA+r3ID0cSmyPLYOeCgszRiW++KGw+PPDsWVeM3ZaZ9SgaBWU7MIn9A7yQMnnSzgDbN+9v/VMT3zbk1WJXlQQK8oA+CCdHH9EY33RfZ6ST/lr3pSQbUG1hdK6Sw+H6WMkOnnEk6HtLwa4xZ3HjDpoPkhVV+S0C7D5WWOovbubxuBiW5v8tK4sIOS6bAaKevTBKRbo4Rs6qmS/Ish5Q+z5bKst80cyEdi4QSoPZ/W+6kh1KfOprMxynwPQhtEcDYW2gfLpgPIM7RdXPKukLlkV2qX3eF/tqApGU4KNdP4I3N80Ri0h+6tVU/K4TMYzlRV3ziLBumJ4TnBrTHU3X6AfZUfTgslQzokX8/7a3tbctX6kZuJPggLGisdFSdirHbrUc+y5VKuJtPr+LxxgZKRFbs2VpJRem6FvwGNyndWLv32v0GMtQ=
98 ced632394371a36953ce4d394f86278ae51a2aae 0 iQIVAwUAVFWpfSBXgaxoKi1yAQLCQw//cvCi/Di3z/2ZEDQt4Ayyxv18gzewqrYyoElgnEzr5uTynD9Mf25hprstKla/Y5C6q+y0K6qCHPimGOkz3H+wZ2GVUgLKAwMABkfSb5IZiLTGaB2DjAJKZRwB6h43wG/DSFggE3dYszWuyHW88c72ZzVF5CSNc4J1ARLjDSgnNYJQ6XdPw3C9KgiLFDXzynPpZbPg0AK5bdPUKJruMeIKPn36Hx/Tv5GXUrbc2/lcnyRDFWisaDl0X/5eLdA+r3ID0cSmyPLYOeCgszRiW++KGw+PPDsWVeM3ZaZ9SgaBWU7MIn9A7yQMnnSzgDbN+9v/VMT3zbk1WJXlQQK8oA+CCdHH9EY33RfZ6ST/lr3pSQbUG1hdK6Sw+H6WMkOnnEk6HtLwa4xZ3HjDpoPkhVV+S0C7D5WWOovbubxuBiW5v8tK4sIOS6bAaKevTBKRbo4Rs6qmS/Ish5Q+z5bKst80cyEdi4QSoPZ/W+6kh1KfOprMxynwPQhtEcDYW2gfLpgPIM7RdXPKukLlkV2qX3eF/tqApGU4KNdP4I3N80Ri0h+6tVU/K4TMYzlRV3ziLBumJ4TnBrTHU3X6AfZUfTgslQzokX8/7a3tbctX6kZuJPggLGisdFSdirHbrUc+y5VKuJtPr+LxxgZKRFbs2VpJRem6FvwGNyndWLv32v0GMtQ=
99 643c58303fb0ec020907af28b9e486be299ba043 0 iQIVAwUAVGKawCBXgaxoKi1yAQL7zxAAjpXKNvzm/PKVlTfDjuVOYZ9H8w9QKUZ0vfrNJrN6Eo6hULIostbdRc25FcMWocegTqvKbz3IG+L2TKOIdZJS9M9QS4URybUd37URq4Jai8kMiJY31KixNNnjO2G1B39aIXUhY+EPx12aY31/OVy4laXIVtN6qpSncjo9baXSOMZmx6RyA1dbyfwXRjT/aODCGHZXgLJHS/kHlkCsThVlqYQ4rUCDkXIeMqIGF1CR0KjfmKpp1fS14OMgpLgdnt9+pnBZ+qcf1YdpOeQob1zwunjMYOyYC74FyOTdwaynU2iDsuBrmkE8kgEedIn7+WWe9fp/6TQJMVOeTQPZBNSRRSUYCw5Tg/0L/+jLtzjc2mY4444sDPbR7scrtU+/GtvlR5z0Y5pofwEdFME7PZNOp9a4kMiSa7ZERyGdN7U1pDu9JU6BZRz+nPzW217PVnTF7YFV/GGUzMTk9i7EZb5M4T9r9gfxFSMPeT5ct712CdBfyRlsSbSWk8XclTXwW385kLVYNDtOukWrvEiwxpA14Xb/ZUXbIDZVf5rP2HrZHMkghzeUYPjRn/IlgYUt7sDNmqFZNIc9mRFrZC9uFQ/Nul5InZodNODQDM+nHpxaztt4xl4qKep8SDEPAQjNr8biC6T9MtLKbWbSKDlqYYNv0pb2PuGub3y9rvkF1Y05mgM=
99 643c58303fb0ec020907af28b9e486be299ba043 0 iQIVAwUAVGKawCBXgaxoKi1yAQL7zxAAjpXKNvzm/PKVlTfDjuVOYZ9H8w9QKUZ0vfrNJrN6Eo6hULIostbdRc25FcMWocegTqvKbz3IG+L2TKOIdZJS9M9QS4URybUd37URq4Jai8kMiJY31KixNNnjO2G1B39aIXUhY+EPx12aY31/OVy4laXIVtN6qpSncjo9baXSOMZmx6RyA1dbyfwXRjT/aODCGHZXgLJHS/kHlkCsThVlqYQ4rUCDkXIeMqIGF1CR0KjfmKpp1fS14OMgpLgdnt9+pnBZ+qcf1YdpOeQob1zwunjMYOyYC74FyOTdwaynU2iDsuBrmkE8kgEedIn7+WWe9fp/6TQJMVOeTQPZBNSRRSUYCw5Tg/0L/+jLtzjc2mY4444sDPbR7scrtU+/GtvlR5z0Y5pofwEdFME7PZNOp9a4kMiSa7ZERyGdN7U1pDu9JU6BZRz+nPzW217PVnTF7YFV/GGUzMTk9i7EZb5M4T9r9gfxFSMPeT5ct712CdBfyRlsSbSWk8XclTXwW385kLVYNDtOukWrvEiwxpA14Xb/ZUXbIDZVf5rP2HrZHMkghzeUYPjRn/IlgYUt7sDNmqFZNIc9mRFrZC9uFQ/Nul5InZodNODQDM+nHpxaztt4xl4qKep8SDEPAQjNr8biC6T9MtLKbWbSKDlqYYNv0pb2PuGub3y9rvkF1Y05mgM=
100 902554884335e5ca3661d63be9978eb4aec3f68a 0 iQIVAwUAVH0KMyBXgaxoKi1yAQLUKxAAjgyYpmqD0Ji5OQ3995yX0dmwHOaaSuYpq71VUsOMYBskjH4xE2UgcTrX8RWUf0E+Ya91Nw3veTf+IZlYLaWuOYuJPRzw+zD1sVY8xprwqBOXNaA7n8SsTqZPSh6qgw4S0pUm0xJUOZzUP1l9S7BtIdJP7KwZ7hs9YZev4r9M3G15xOIPn5qJqBAtIeE6f5+ezoyOpSPZFtLFc4qKQ/YWzOT5uuSaYogXgVByXRFaO84+1TD93LR0PyVWxhwU9JrDU5d7P/bUTW1BXdjsxTbBnigWswKHC71EHpgz/HCYxivVL30qNdOm4Fow1Ec2GdUzGunSqTPrq18ScZDYW1x87f3JuqPM+ce/lxRWBBqP1yE30/8l/Us67m6enWXdGER8aL1lYTGOIWAhvJpfzv9KebaUq1gMFLo6j+OfwR3rYPiCHgi20nTNBa+LOceWFjCGzFa3T9UQWHW/MBElfAxK65uecbGRRYY9V1/+wxtTUiS6ixpmzL8S7uUd5n6oMaeeMiD82NLgPIbMyUHQv6eFEcCj0U9NT2uKbFRmclMs5V+8D+RTCsLJ55R9PD5OoRw/6K/coqqPShYmJvgYsFQPzXVpQdCRae31xdfGFmd5KUetqyrT+4GUdJWzSm0giSgovpEJNxXglrvNdvSO7fX3R1oahhwOwtGqMwNilcK+iDw=
100 902554884335e5ca3661d63be9978eb4aec3f68a 0 iQIVAwUAVH0KMyBXgaxoKi1yAQLUKxAAjgyYpmqD0Ji5OQ3995yX0dmwHOaaSuYpq71VUsOMYBskjH4xE2UgcTrX8RWUf0E+Ya91Nw3veTf+IZlYLaWuOYuJPRzw+zD1sVY8xprwqBOXNaA7n8SsTqZPSh6qgw4S0pUm0xJUOZzUP1l9S7BtIdJP7KwZ7hs9YZev4r9M3G15xOIPn5qJqBAtIeE6f5+ezoyOpSPZFtLFc4qKQ/YWzOT5uuSaYogXgVByXRFaO84+1TD93LR0PyVWxhwU9JrDU5d7P/bUTW1BXdjsxTbBnigWswKHC71EHpgz/HCYxivVL30qNdOm4Fow1Ec2GdUzGunSqTPrq18ScZDYW1x87f3JuqPM+ce/lxRWBBqP1yE30/8l/Us67m6enWXdGER8aL1lYTGOIWAhvJpfzv9KebaUq1gMFLo6j+OfwR3rYPiCHgi20nTNBa+LOceWFjCGzFa3T9UQWHW/MBElfAxK65uecbGRRYY9V1/+wxtTUiS6ixpmzL8S7uUd5n6oMaeeMiD82NLgPIbMyUHQv6eFEcCj0U9NT2uKbFRmclMs5V+8D+RTCsLJ55R9PD5OoRw/6K/coqqPShYmJvgYsFQPzXVpQdCRae31xdfGFmd5KUetqyrT+4GUdJWzSm0giSgovpEJNxXglrvNdvSO7fX3R1oahhwOwtGqMwNilcK+iDw=
101 6dad422ecc5adb63d9fa649eeb8e05a5f9bc4900 0 iQIVAwUAVJNALCBXgaxoKi1yAQKgmw/+OFbHHOMmN2zs2lI2Y0SoMALPNQBInMBq2E6RMCMbfcS9Cn75iD29DnvBwAYNWaWsYEGyheJ7JjGBiuNKPOrLaHkdjG+5ypbhAfNDyHDiteMsXfH7D1L+cTOAB8yvhimZHOTTVF0zb/uRyVIPNowAyervUVRjDptzdfcvjUS+X+/Ufgwms6Y4CcuzFLFCxpmryJhLtOpwUPLlzIqeNkFOYWkHanCgtZX03PNIWhorH3AWOc9yztwWPQ+kcKl3FMlyuNMPhS/ElxSF6GHGtreRbtP+ZLoSIOMb2QBKpGDpZLgJ3JQEHDcZ0h5CLZWL9dDUJR3M8pg1qglqMFSWMgRPTzxPS4QntPgT/Ewd3+U5oCZUh052fG41OeCZ0CnVCpqi5PjUIDhzQkONxRCN2zbjQ2GZY7glbXoqytissihEIVP9m7RmBVq1rbjOKr+yUetJ9gOZcsMtZiCEq4Uj2cbA1x32MQv7rxwAgQP1kgQ62b0sN08HTjQpI7/IkNALLIDHoQWWr45H97i34qK1dd5uCOnYk7juvhGNX5XispxNnC01/CUVNnqChfDHpgnDjgT+1H618LiTgUAD3zo4IVAhCqF5XWsS4pQEENOB3Msffi62fYowvJx7f/htWeRLZ2OA+B85hhDiD4QBdHCRoz3spVp0asNqDxX4f4ndj8RlzfM=
101 6dad422ecc5adb63d9fa649eeb8e05a5f9bc4900 0 iQIVAwUAVJNALCBXgaxoKi1yAQKgmw/+OFbHHOMmN2zs2lI2Y0SoMALPNQBInMBq2E6RMCMbfcS9Cn75iD29DnvBwAYNWaWsYEGyheJ7JjGBiuNKPOrLaHkdjG+5ypbhAfNDyHDiteMsXfH7D1L+cTOAB8yvhimZHOTTVF0zb/uRyVIPNowAyervUVRjDptzdfcvjUS+X+/Ufgwms6Y4CcuzFLFCxpmryJhLtOpwUPLlzIqeNkFOYWkHanCgtZX03PNIWhorH3AWOc9yztwWPQ+kcKl3FMlyuNMPhS/ElxSF6GHGtreRbtP+ZLoSIOMb2QBKpGDpZLgJ3JQEHDcZ0h5CLZWL9dDUJR3M8pg1qglqMFSWMgRPTzxPS4QntPgT/Ewd3+U5oCZUh052fG41OeCZ0CnVCpqi5PjUIDhzQkONxRCN2zbjQ2GZY7glbXoqytissihEIVP9m7RmBVq1rbjOKr+yUetJ9gOZcsMtZiCEq4Uj2cbA1x32MQv7rxwAgQP1kgQ62b0sN08HTjQpI7/IkNALLIDHoQWWr45H97i34qK1dd5uCOnYk7juvhGNX5XispxNnC01/CUVNnqChfDHpgnDjgT+1H618LiTgUAD3zo4IVAhCqF5XWsS4pQEENOB3Msffi62fYowvJx7f/htWeRLZ2OA+B85hhDiD4QBdHCRoz3spVp0asNqDxX4f4ndj8RlzfM=
102 1265a3a71d75396f5d4cf6935ae7d9ba5407a547 0 iQIVAwUAVKXKYCBXgaxoKi1yAQIfsA/+PFfaWuZ6Jna12Y3MpKMnBCXYLWEJgMNlWHWzwU8lD26SKSlvMyHQsVZlkld2JmFugUCn1OV3OA4YWT6BA7VALq6Zsdcu5Dc8LRbyajBUkzGRpOUyWuFzjkCpGVbrQzbCR/bel/BBXzSqL4ipdtWgJ4y+WpZIhWkNXclBkR52b5hUTjN9vzhyhVVI7eURGwIEf7vVs1fDOcEGtaGY/ynzMTzyxIDsEEygCZau86wpKlYlqhCgxKDyzyGfpH3B1UlNGFt1afW8AWe1eHjdqC7TJZpMqmQ/Ju8vco8Xht6OXw4ZLHj7y39lpccfKTBLiK/cAKSg+xgyaH/BLhzoEkNAwYSFAB4i4IoV0KUC8nFxHfsoswBxJnMqU751ziMrpZ/XHZ1xQoEOdXgz2I04vlRn8xtynOVhcgjoAXwtbia7oNh/qCH/hl5/CdAtaawuCxJBf237F+cwur4PMAAvsGefRfZco/DInpr3qegr8rwInTxlO48ZG+o5xA4TPwT0QQTUjMdNfC146ZSbp65wG7VxJDocMZ8KJN/lqPaOvX+FVYWq4YnJhlldiV9DGgmym1AAaP0D3te2GcfHXpt/f6NYUPpgiBHy0GnOlNcQyGnnONg1A6oKVWB3k7WP28+PQbQEiCIFk2nkf5VZmye7OdHRGKOFfuprYFP1WwTWnVoNX9c=
102 1265a3a71d75396f5d4cf6935ae7d9ba5407a547 0 iQIVAwUAVKXKYCBXgaxoKi1yAQIfsA/+PFfaWuZ6Jna12Y3MpKMnBCXYLWEJgMNlWHWzwU8lD26SKSlvMyHQsVZlkld2JmFugUCn1OV3OA4YWT6BA7VALq6Zsdcu5Dc8LRbyajBUkzGRpOUyWuFzjkCpGVbrQzbCR/bel/BBXzSqL4ipdtWgJ4y+WpZIhWkNXclBkR52b5hUTjN9vzhyhVVI7eURGwIEf7vVs1fDOcEGtaGY/ynzMTzyxIDsEEygCZau86wpKlYlqhCgxKDyzyGfpH3B1UlNGFt1afW8AWe1eHjdqC7TJZpMqmQ/Ju8vco8Xht6OXw4ZLHj7y39lpccfKTBLiK/cAKSg+xgyaH/BLhzoEkNAwYSFAB4i4IoV0KUC8nFxHfsoswBxJnMqU751ziMrpZ/XHZ1xQoEOdXgz2I04vlRn8xtynOVhcgjoAXwtbia7oNh/qCH/hl5/CdAtaawuCxJBf237F+cwur4PMAAvsGefRfZco/DInpr3qegr8rwInTxlO48ZG+o5xA4TPwT0QQTUjMdNfC146ZSbp65wG7VxJDocMZ8KJN/lqPaOvX+FVYWq4YnJhlldiV9DGgmym1AAaP0D3te2GcfHXpt/f6NYUPpgiBHy0GnOlNcQyGnnONg1A6oKVWB3k7WP28+PQbQEiCIFk2nkf5VZmye7OdHRGKOFfuprYFP1WwTWnVoNX9c=
103 db8e3f7948b1fdeb9ad12d448fc3525759908b9f 0 iQIVAwUAVLsaciBXgaxoKi1yAQKMIA//a90/GvySL9UID+iYvzV2oDaAPDD0T+4Xs43I7DT5NIoDz+3yq2VV54XevQe5lYiURmsb/Q9nX2VR/Qq1J9c/R6Gy+CIfmJ3HzMZ0aAX8ZlZgQPYZKh/2kY5Ojl++k6MTqbqcrICNs4+UE/4IAxPyOfu5gy7TpdJmRZo2J3lWVC2Jbhd02Mzb+tjtfbOM+QcQxPwt9PpqmQszJceyVYOSm3jvD1uJdSOC04tBQrQwrxktQ09Om0LUMMaB5zFXpJtqUzfw7l4U4AaddEmkd3vUfLtHxc21RB01c3cpe2dJnjifDfwseLsI8rS4jmi/91c74TeBatSOhvbqzEkm/p8xZFXE4Uh+EpWjTsVqmfQaRq6NfNCR7I/kvGv8Ps6w8mg8uX8fd8lx+GJbodj+Uy0X3oqHyqPMky/df5i79zADBDuz+yuxFfDD9i22DJPIYcilfGgwpIUuO2lER5nSMVmReuWTVBnT6SEN66Q4KR8zLtIRr+t1qUUCy6wYbgwrdHVCbgMF8RPOVZPjbs17RIqcHjch0Xc7bShKGhQg4WHDjXHK61w4tOa1Yp7jT6COkl01XC9BLcGxJYKFvNCbeDZQGvVgJNoEvHxBxD9rGMVRjfuxeJawc2fGzZJn0ySyLDW0pfd4EJNgTh9bLdPjWz2VlXqn4A6bgaLgTPqjmN0VBXw=
103 db8e3f7948b1fdeb9ad12d448fc3525759908b9f 0 iQIVAwUAVLsaciBXgaxoKi1yAQKMIA//a90/GvySL9UID+iYvzV2oDaAPDD0T+4Xs43I7DT5NIoDz+3yq2VV54XevQe5lYiURmsb/Q9nX2VR/Qq1J9c/R6Gy+CIfmJ3HzMZ0aAX8ZlZgQPYZKh/2kY5Ojl++k6MTqbqcrICNs4+UE/4IAxPyOfu5gy7TpdJmRZo2J3lWVC2Jbhd02Mzb+tjtfbOM+QcQxPwt9PpqmQszJceyVYOSm3jvD1uJdSOC04tBQrQwrxktQ09Om0LUMMaB5zFXpJtqUzfw7l4U4AaddEmkd3vUfLtHxc21RB01c3cpe2dJnjifDfwseLsI8rS4jmi/91c74TeBatSOhvbqzEkm/p8xZFXE4Uh+EpWjTsVqmfQaRq6NfNCR7I/kvGv8Ps6w8mg8uX8fd8lx+GJbodj+Uy0X3oqHyqPMky/df5i79zADBDuz+yuxFfDD9i22DJPIYcilfGgwpIUuO2lER5nSMVmReuWTVBnT6SEN66Q4KR8zLtIRr+t1qUUCy6wYbgwrdHVCbgMF8RPOVZPjbs17RIqcHjch0Xc7bShKGhQg4WHDjXHK61w4tOa1Yp7jT6COkl01XC9BLcGxJYKFvNCbeDZQGvVgJNoEvHxBxD9rGMVRjfuxeJawc2fGzZJn0ySyLDW0pfd4EJNgTh9bLdPjWz2VlXqn4A6bgaLgTPqjmN0VBXw=
104 fbdd5195528fae4f41feebc1838215c110b25d6a 0 iQIVAwUAVM7fBCBXgaxoKi1yAQKoYw/+LeIGcjQmHIVFQULsiBtPDf+eGAADQoP3mKBy+eX/3Fa0qqUNfES2Q3Y6RRApyZ1maPRMt8BvvhZMgQsu9QIrmf3zsFxZGFwoyrIj4hM3xvAbEZXqmWiR85/Ywd4ImeLaZ0c7mkO1/HGF1n2Mv47bfM4hhNe7VGJSSrTY4srFHDfk4IG9f18DukJVzRD9/dZeBw6eUN1ukuLEgQAD5Sl47bUdKSetglOSR1PjXfZ1hjtz5ywUyBc5P9p3LC4wSvlcJKl22zEvB3L0hkoDcPsdIPEnJAeXxKlR1rQpoA3fEgrstGiSNUW/9Tj0VekAHLO95SExmQyoG/AhbjRRzIj4uQ0aevCJyiAhkv+ffOSf99PMW9L1k3tVjLhpMWEz9BOAWyX7cDFWj5t/iktI046O9HGN9SGVx18e9xM6pEgRcLA2TyjEmtkA4jX0JeN7WeCweMLiSxyGP7pSPSJdpJeXaFtRpSF62p/G0Z5wN9s05LHqDyqNVtCvg4WjkuV5LZSdLbMcYBWGBxQzCG6qowXFXIawmbaFiBZwTfOgNls9ndz5RGupAaxY317prxPFv/pXoesc1P8bdK09ZvjhbmmD66Q/BmS2dOMQ8rXRjuVdlR8j2QBtFZxekMcRD02nBAVnwHg1VWQMIRaGjdgmW4wOkirWVn7me177FnBxrxW1tG4=
104 fbdd5195528fae4f41feebc1838215c110b25d6a 0 iQIVAwUAVM7fBCBXgaxoKi1yAQKoYw/+LeIGcjQmHIVFQULsiBtPDf+eGAADQoP3mKBy+eX/3Fa0qqUNfES2Q3Y6RRApyZ1maPRMt8BvvhZMgQsu9QIrmf3zsFxZGFwoyrIj4hM3xvAbEZXqmWiR85/Ywd4ImeLaZ0c7mkO1/HGF1n2Mv47bfM4hhNe7VGJSSrTY4srFHDfk4IG9f18DukJVzRD9/dZeBw6eUN1ukuLEgQAD5Sl47bUdKSetglOSR1PjXfZ1hjtz5ywUyBc5P9p3LC4wSvlcJKl22zEvB3L0hkoDcPsdIPEnJAeXxKlR1rQpoA3fEgrstGiSNUW/9Tj0VekAHLO95SExmQyoG/AhbjRRzIj4uQ0aevCJyiAhkv+ffOSf99PMW9L1k3tVjLhpMWEz9BOAWyX7cDFWj5t/iktI046O9HGN9SGVx18e9xM6pEgRcLA2TyjEmtkA4jX0JeN7WeCweMLiSxyGP7pSPSJdpJeXaFtRpSF62p/G0Z5wN9s05LHqDyqNVtCvg4WjkuV5LZSdLbMcYBWGBxQzCG6qowXFXIawmbaFiBZwTfOgNls9ndz5RGupAaxY317prxPFv/pXoesc1P8bdK09ZvjhbmmD66Q/BmS2dOMQ8rXRjuVdlR8j2QBtFZxekMcRD02nBAVnwHg1VWQMIRaGjdgmW4wOkirWVn7me177FnBxrxW1tG4=
105 5b4ed033390bf6e2879c8f5c28c84e1ee3b87231 0 iQIVAwUAVPQL9CBXgaxoKi1yAQJIXxAAtD2hWhaKa+lABmCOYG92FE/WdqY/91Xv5atTL8Xeko/MkirIKZiOuxNWX+J34TVevINZSWmMfDSc5TkGxktL9jW/pDB/CXn+CVZpxRabPYFH9HM2K3g8VaTV1MFtV2+feOMDIPCmq5ogMF9/kXjmifiEBrJcFsE82fdexJ3OHoOY4iHFxEhh3GzvNqEQygk4VeU6VYziNvSQj9G//PsK3Bmk7zm5ScsZcMVML3SIYFuej1b1PI1v0N8mmCRooVNBGhD/eA0iLtdh/hSb9s/8UgJ4f9HOcx9zqs8V4i14lpd/fo0+yvFuVrVbWGzrDrk5EKLENhVPwvc1KA32PTQ4Z9u7VQIBIxq3K5lL2VlCMIYc1BSaSQBjuiLm8VdN6iDuf5poNZhk1rvtpQgpxJzh362dlGtR/iTJuLCeW7gCqWUAorLTeHy0bLQ/jSOeTAGys8bUHtlRL4QbnhLbUmJmRYVvCJ+Yt1aTgTSNcoFjoLJarR1169BXgdCA38BgReUL6kB224UJSTzB1hJUyB2LvCWrXZMipZmR99Iwdq7MePD3+AoSIXQNUMY9blxuuF5x7W2ikNXmVWuab4Z8rQRtmGqEuIMBSunxAnZSn+i8057dFKlq+/yGy+WW3RQg+RnLnwZs1zCDTfu98/GT5k5hFpjXZeUWWiOVwQJ5HrqncCw=
105 5b4ed033390bf6e2879c8f5c28c84e1ee3b87231 0 iQIVAwUAVPQL9CBXgaxoKi1yAQJIXxAAtD2hWhaKa+lABmCOYG92FE/WdqY/91Xv5atTL8Xeko/MkirIKZiOuxNWX+J34TVevINZSWmMfDSc5TkGxktL9jW/pDB/CXn+CVZpxRabPYFH9HM2K3g8VaTV1MFtV2+feOMDIPCmq5ogMF9/kXjmifiEBrJcFsE82fdexJ3OHoOY4iHFxEhh3GzvNqEQygk4VeU6VYziNvSQj9G//PsK3Bmk7zm5ScsZcMVML3SIYFuej1b1PI1v0N8mmCRooVNBGhD/eA0iLtdh/hSb9s/8UgJ4f9HOcx9zqs8V4i14lpd/fo0+yvFuVrVbWGzrDrk5EKLENhVPwvc1KA32PTQ4Z9u7VQIBIxq3K5lL2VlCMIYc1BSaSQBjuiLm8VdN6iDuf5poNZhk1rvtpQgpxJzh362dlGtR/iTJuLCeW7gCqWUAorLTeHy0bLQ/jSOeTAGys8bUHtlRL4QbnhLbUmJmRYVvCJ+Yt1aTgTSNcoFjoLJarR1169BXgdCA38BgReUL6kB224UJSTzB1hJUyB2LvCWrXZMipZmR99Iwdq7MePD3+AoSIXQNUMY9blxuuF5x7W2ikNXmVWuab4Z8rQRtmGqEuIMBSunxAnZSn+i8057dFKlq+/yGy+WW3RQg+RnLnwZs1zCDTfu98/GT5k5hFpjXZeUWWiOVwQJ5HrqncCw=
106 07a92bbd02e5e3a625e0820389b47786b02b2cea 0 iQIVAwUAVPSP9SBXgaxoKi1yAQLkBQ//dRQExJHFepJfZ0gvGnUoYI4APsLmne5XtfeXJ8OtUyC4a6RylxA5BavDWgXwUh9BGhOX2cBSz1fyvzohrPrvNnlBrYKAvOIJGEAiBTXHYTxHINEKPtDF92Uz23T0Rn/wnSvvlbWF7Pvd+0DMJpFDEyr9n6jvVLR7mgxMaCqZbVaB1W/wTwDjni780WgVx8OPUXkLx3/DyarMcIiPeI5UN+FeHDovTsBWFC95msFLm80PMRPuHOejWp65yyEemGujZEPO2D5VVah7fshM2HTz63+bkEBYoqrftuv3vXKBRG78MIrUrKpqxmnCKNKDUUWJ4yk3+NwuOiHlKdly5kZ7MNFaL73XKo8HH287lDWz0lIazs91dQA9a9JOyTsp8YqGtIJGGCbhrUDtiQJ199oBU84mw3VH/EEzm4mPv4sW5fm7BnnoH/a+9vXySc+498rkdLlzFwxrQkWyJ/pFOx4UA3mCtGQK+OSwLPc+X4SRqA4fiyqKxVAL1kpLTSDL3QA82I7GzBaXsxUXzS4nmteMhUyzTdwAhKVydL0gC3d7NmkAFSyRjdGzutUUXshYxg0ywRgYebe8uzJcTj4nNRgaalYLdg3guuDulD+dJmILsrcLmA6KD/pvfDn8PYt+4ZjNIvN2E9GF6uXDu4Ux+AlOTLk9BChxUF8uBX9ev5cvWtQ=
106 07a92bbd02e5e3a625e0820389b47786b02b2cea 0 iQIVAwUAVPSP9SBXgaxoKi1yAQLkBQ//dRQExJHFepJfZ0gvGnUoYI4APsLmne5XtfeXJ8OtUyC4a6RylxA5BavDWgXwUh9BGhOX2cBSz1fyvzohrPrvNnlBrYKAvOIJGEAiBTXHYTxHINEKPtDF92Uz23T0Rn/wnSvvlbWF7Pvd+0DMJpFDEyr9n6jvVLR7mgxMaCqZbVaB1W/wTwDjni780WgVx8OPUXkLx3/DyarMcIiPeI5UN+FeHDovTsBWFC95msFLm80PMRPuHOejWp65yyEemGujZEPO2D5VVah7fshM2HTz63+bkEBYoqrftuv3vXKBRG78MIrUrKpqxmnCKNKDUUWJ4yk3+NwuOiHlKdly5kZ7MNFaL73XKo8HH287lDWz0lIazs91dQA9a9JOyTsp8YqGtIJGGCbhrUDtiQJ199oBU84mw3VH/EEzm4mPv4sW5fm7BnnoH/a+9vXySc+498rkdLlzFwxrQkWyJ/pFOx4UA3mCtGQK+OSwLPc+X4SRqA4fiyqKxVAL1kpLTSDL3QA82I7GzBaXsxUXzS4nmteMhUyzTdwAhKVydL0gC3d7NmkAFSyRjdGzutUUXshYxg0ywRgYebe8uzJcTj4nNRgaalYLdg3guuDulD+dJmILsrcLmA6KD/pvfDn8PYt+4ZjNIvN2E9GF6uXDu4Ux+AlOTLk9BChxUF8uBX9ev5cvWtQ=
107 2e2e9a0750f91a6fe0ad88e4de34f8efefdcab08 0 iQIVAwUAVRw4nyBXgaxoKi1yAQIFExAAkbCPtLjQlJvPaYCL1KhNR+ZVAmn7JrFH3XhvR26RayYbs4NxR3W1BhwhDy9+W+28szEx1kQvmr6t1bXAFywY0tNJOeuLU7uFfmbgAfYgkQ9kpsQNqFYkjbCyftw0S9vX9VOJ9DqUoDWuKfX7VzjkwE9dCfKI5F+dvzxnd6ZFjB85nyHBQuTZlzXl0+csY212RJ2G2j/mzEBVyeZj9l7Rm+1X8AC1xQMWRJGiyd0b7nhYqoOcceeJFAV1t9QO4+gjmkM5kL0orjxTnuVsxPTxcC5ca1BfidPWrZEto3duHWNiATGnCDylxxr52BxCAS+BWePW9J0PROtw1pYaZ9pF4N5X5LSXJzqX7ZiNGckxqIjry09+Tbsa8FS0VkkYBEiGotpuo4Jd05V6qpXfW2JqAfEVo6X6aGvPM2B7ZUtKi30I4J+WprrOP3WgZ/ZWHe1ERYKgjDqisn3t/D40q30WQUeQGltGsOX0Udqma2RjBugO5BHGzJ2yer4GdJXg7q1OMzrjAEuz1IoKvIB/o1pg86quVA4H2gQnL1B8t1M38/DIafyw7mrEY4Z3GL44Reev63XVvDE099Vbhqp7ufwq81Fpq7Xxa5vsr9SJ+8IqqQr8AcYSuK3G3L6BmIuSUAYMRqgl35FWoWkGyZIG5c6K6zI8w5Pb0aGi6Lb2Wfb9zbc=
107 2e2e9a0750f91a6fe0ad88e4de34f8efefdcab08 0 iQIVAwUAVRw4nyBXgaxoKi1yAQIFExAAkbCPtLjQlJvPaYCL1KhNR+ZVAmn7JrFH3XhvR26RayYbs4NxR3W1BhwhDy9+W+28szEx1kQvmr6t1bXAFywY0tNJOeuLU7uFfmbgAfYgkQ9kpsQNqFYkjbCyftw0S9vX9VOJ9DqUoDWuKfX7VzjkwE9dCfKI5F+dvzxnd6ZFjB85nyHBQuTZlzXl0+csY212RJ2G2j/mzEBVyeZj9l7Rm+1X8AC1xQMWRJGiyd0b7nhYqoOcceeJFAV1t9QO4+gjmkM5kL0orjxTnuVsxPTxcC5ca1BfidPWrZEto3duHWNiATGnCDylxxr52BxCAS+BWePW9J0PROtw1pYaZ9pF4N5X5LSXJzqX7ZiNGckxqIjry09+Tbsa8FS0VkkYBEiGotpuo4Jd05V6qpXfW2JqAfEVo6X6aGvPM2B7ZUtKi30I4J+WprrOP3WgZ/ZWHe1ERYKgjDqisn3t/D40q30WQUeQGltGsOX0Udqma2RjBugO5BHGzJ2yer4GdJXg7q1OMzrjAEuz1IoKvIB/o1pg86quVA4H2gQnL1B8t1M38/DIafyw7mrEY4Z3GL44Reev63XVvDE099Vbhqp7ufwq81Fpq7Xxa5vsr9SJ+8IqqQr8AcYSuK3G3L6BmIuSUAYMRqgl35FWoWkGyZIG5c6K6zI8w5Pb0aGi6Lb2Wfb9zbc=
108 e89f909edffad558b56f4affa8239e4832f88de0 0 iQIVAwUAVTBozCBXgaxoKi1yAQLHeg/+IvfpPmG7OSqCoHvMVETYdrqT7lKCwfCQWMFOC/2faWs1n4R/qQNm6ckE5OY888RK8tVQ7ue03Pg/iyWgQlYfS7Njd3WPjS4JsnEBxIvuGkIu6TPIXAUAH0PFTBh0cZEICDpPEVT2X3bPRwDHA+hUE9RrxM5zJ39Fpk/pTYCjQ9UKfEhXlEfka75YB39g2Y/ssaSbn5w/tAAx8sL72Y4G96D4IV2seLHZhB3VQ7UZKThEWn6UdVOoKj+urIwGaBYMeekGVtHSh6fnHOw3EtDO9mQ5HtAz2Bl4CwRYN8eSN+Dwgr+mdk8MWpQQJ+i1A8jUhUp8gn1Pe5GkIH4CWZ9+AvLLnshe2MkVaTT1g7EQk37tFkkdZDRBsOHIvpF71B9pEA1gMUlX4gKgh5YwukgpQlDmFCfY7XmX6eXw9Ub+EckEwYuGMz7Fbwe9J/Ce4DxvgJgq3/cu/jb3bmbewH6tZmcrlqziqqA8GySIwcURnF1c37e7+e7x1jhFJfCWpHzvCusjKhUp9tZsl9Rt1Bo/y41QY+avY7//ymhbwTMKgqjzCYoA+ipF4JfZlFiZF+JhvOSIFb0ltkfdqKD+qOjlkFaglvQU1bpGKLJ6cz4Xk2Jqt5zhcrpyDMGVv9aiWywCK2ZP34RNaJ6ZFwzwdpXihqgkm5dBGoZ4ztFUfmjXzIg=
108 e89f909edffad558b56f4affa8239e4832f88de0 0 iQIVAwUAVTBozCBXgaxoKi1yAQLHeg/+IvfpPmG7OSqCoHvMVETYdrqT7lKCwfCQWMFOC/2faWs1n4R/qQNm6ckE5OY888RK8tVQ7ue03Pg/iyWgQlYfS7Njd3WPjS4JsnEBxIvuGkIu6TPIXAUAH0PFTBh0cZEICDpPEVT2X3bPRwDHA+hUE9RrxM5zJ39Fpk/pTYCjQ9UKfEhXlEfka75YB39g2Y/ssaSbn5w/tAAx8sL72Y4G96D4IV2seLHZhB3VQ7UZKThEWn6UdVOoKj+urIwGaBYMeekGVtHSh6fnHOw3EtDO9mQ5HtAz2Bl4CwRYN8eSN+Dwgr+mdk8MWpQQJ+i1A8jUhUp8gn1Pe5GkIH4CWZ9+AvLLnshe2MkVaTT1g7EQk37tFkkdZDRBsOHIvpF71B9pEA1gMUlX4gKgh5YwukgpQlDmFCfY7XmX6eXw9Ub+EckEwYuGMz7Fbwe9J/Ce4DxvgJgq3/cu/jb3bmbewH6tZmcrlqziqqA8GySIwcURnF1c37e7+e7x1jhFJfCWpHzvCusjKhUp9tZsl9Rt1Bo/y41QY+avY7//ymhbwTMKgqjzCYoA+ipF4JfZlFiZF+JhvOSIFb0ltkfdqKD+qOjlkFaglvQU1bpGKLJ6cz4Xk2Jqt5zhcrpyDMGVv9aiWywCK2ZP34RNaJ6ZFwzwdpXihqgkm5dBGoZ4ztFUfmjXzIg=
109 8cc6036bca532e06681c5a8fa37efaa812de67b5 0 iQIVAwUAVUP0xCBXgaxoKi1yAQLIChAAme3kg1Z0V8t5PnWKDoIvscIeAsD2s6EhMy1SofmdZ4wvYD1VmGC6TgXMCY7ssvRBhxqwG3GxwYpwELASuw2GYfVot2scN7+b8Hs5jHtkQevKbxarYni+ZI9mw/KldnJixD1yW3j+LoJFh/Fu6GD2yrfGIhimFLozcwUu3EbLk7JzyHSn7/8NFjLJz0foAYfcbowU9/BFwNVLrQPnsUbWcEifsq5bYso9MBO9k+25yLgqHoqMbGpJcgjubNy1cWoKnlKS+lOJl0/waAk+aIjHXMzFpRRuJDjxEZn7V4VdV5d23nrBTcit1BfMzga5df7VrLPVRbom1Bi0kQ0BDeDex3hHNqHS5X+HSrd/njzP1xp8twG8hTE+njv85PWoGBTo1eUGW/esChIJKA5f3/F4B9ErgBNNOKnYmRgxixd562OWAwAQZK0r0roe2H/Mfg2VvgxT0kHd22NQLoAv0YI4jcXcCFrnV/80vHUQ8AsAYAbkLcz1jkfk3YwYDP8jbJCqcwJRt9ialYKJwvXlEe0TMeGdq7EjCO0z/pIpu82k2R/C0FtCFih3bUvJEmWoVVx8UGkDDQEORLbzxQCt0IOiQGFcoCCxgQmL0x9ZoljCWg5vZuuhU4uSOuRTuM+aa4xoLkeOcvgGRSOXrqfkV8JpWKoJB4dmY2qSuxw8LsAAzK0=
109 8cc6036bca532e06681c5a8fa37efaa812de67b5 0 iQIVAwUAVUP0xCBXgaxoKi1yAQLIChAAme3kg1Z0V8t5PnWKDoIvscIeAsD2s6EhMy1SofmdZ4wvYD1VmGC6TgXMCY7ssvRBhxqwG3GxwYpwELASuw2GYfVot2scN7+b8Hs5jHtkQevKbxarYni+ZI9mw/KldnJixD1yW3j+LoJFh/Fu6GD2yrfGIhimFLozcwUu3EbLk7JzyHSn7/8NFjLJz0foAYfcbowU9/BFwNVLrQPnsUbWcEifsq5bYso9MBO9k+25yLgqHoqMbGpJcgjubNy1cWoKnlKS+lOJl0/waAk+aIjHXMzFpRRuJDjxEZn7V4VdV5d23nrBTcit1BfMzga5df7VrLPVRbom1Bi0kQ0BDeDex3hHNqHS5X+HSrd/njzP1xp8twG8hTE+njv85PWoGBTo1eUGW/esChIJKA5f3/F4B9ErgBNNOKnYmRgxixd562OWAwAQZK0r0roe2H/Mfg2VvgxT0kHd22NQLoAv0YI4jcXcCFrnV/80vHUQ8AsAYAbkLcz1jkfk3YwYDP8jbJCqcwJRt9ialYKJwvXlEe0TMeGdq7EjCO0z/pIpu82k2R/C0FtCFih3bUvJEmWoVVx8UGkDDQEORLbzxQCt0IOiQGFcoCCxgQmL0x9ZoljCWg5vZuuhU4uSOuRTuM+aa4xoLkeOcvgGRSOXrqfkV8JpWKoJB4dmY2qSuxw8LsAAzK0=
110 ed18f4acf435a2824c6f49fba40f42b9df5da7ad 0 iQIVAwUAVWy9mCBXgaxoKi1yAQIm+Q/+I/tV8DC51d4f/6T5OR+motlIx9U5za5p9XUUzfp3tzSY2PutVko/FclajVdFekZsK5pUzlh/GZhfe1jjyEEIr3UC3yWk8hMcvvS+2UDmfy81QxN7Uf0kz4mZOlME6d/fYDzf4cDKkkCXoec3kyZBw7L84mteUcrJoyb5K3fkQBrK5CG/CV7+uZN6b9+quKjtDhDEkAyc6phNanzWNgiHGucEbNgXsKM01HmV1TnN4GXTKx8y2UDalIJOPyes2OWHggibMHbaNnGnwSBAK+k29yaQ5FD0rsA+q0j3TijA1NfqvtluNEPbFOx/wJV4CxonYad93gWyEdgU34LRqqw1bx7PFUvew2/T3TJsxQLoCt67OElE7ScG8evuNEe8/4r3LDnzYFx7QMP5r5+B7PxVpj/DT+buS16BhYS8pXMMqLynFOQkX5uhEM7mNC0JTXQsBMHSDAcizVDrdFCF2OSfQjLpUfFP1VEWX7EInqj7hZrd+GE7TfBD8/rwSBSkkCX2aa9uKyt6Ius1GgQUuEETskAUvvpsNBzZxtvGpMMhqQLGlJYnBbhOmsbOyTSnXU66KJ5e/H3O0KRrF09i74v30DaY4uIH8xG6KpSkfw5s/oiLCtagfc0goUvvojk9pACDR3CKM/jVC63EVp2oUcjT72jUgSLxBgi7siLD8IW86wc=
110 ed18f4acf435a2824c6f49fba40f42b9df5da7ad 0 iQIVAwUAVWy9mCBXgaxoKi1yAQIm+Q/+I/tV8DC51d4f/6T5OR+motlIx9U5za5p9XUUzfp3tzSY2PutVko/FclajVdFekZsK5pUzlh/GZhfe1jjyEEIr3UC3yWk8hMcvvS+2UDmfy81QxN7Uf0kz4mZOlME6d/fYDzf4cDKkkCXoec3kyZBw7L84mteUcrJoyb5K3fkQBrK5CG/CV7+uZN6b9+quKjtDhDEkAyc6phNanzWNgiHGucEbNgXsKM01HmV1TnN4GXTKx8y2UDalIJOPyes2OWHggibMHbaNnGnwSBAK+k29yaQ5FD0rsA+q0j3TijA1NfqvtluNEPbFOx/wJV4CxonYad93gWyEdgU34LRqqw1bx7PFUvew2/T3TJsxQLoCt67OElE7ScG8evuNEe8/4r3LDnzYFx7QMP5r5+B7PxVpj/DT+buS16BhYS8pXMMqLynFOQkX5uhEM7mNC0JTXQsBMHSDAcizVDrdFCF2OSfQjLpUfFP1VEWX7EInqj7hZrd+GE7TfBD8/rwSBSkkCX2aa9uKyt6Ius1GgQUuEETskAUvvpsNBzZxtvGpMMhqQLGlJYnBbhOmsbOyTSnXU66KJ5e/H3O0KRrF09i74v30DaY4uIH8xG6KpSkfw5s/oiLCtagfc0goUvvojk9pACDR3CKM/jVC63EVp2oUcjT72jUgSLxBgi7siLD8IW86wc=
111 540cd0ddac49c1125b2e013aa2ff18ecbd4dd954 0 iQIVAwUAVZRtzSBXgaxoKi1yAQJVLhAAtfn+8OzHIp6wRC4NUbkImAJRLsNTRPKeRSWPCF5O5XXQ84hp+86qjhndIE6mcJSAt4cVP8uky6sEa8ULd6b3ACRBvtgZtsecA9S/KtRjyE9CKr8nP+ogBNqJPaYlTz9RuwGedOd+8I9lYgsnRjfaHSByNMX08WEHtWqAWhSkAz/HO32ardS38cN97fckCgQtA8v7c77nBT7vcw4epgxyUQvMUxUhqmCVVhVfz8JXa5hyJxFrOtqgaVuQ1B5Y/EKxcyZT+JNHPtu3V1uc1awS/w16CEPstNBSFHax5MuT9UbY0mV2ZITP99EkM+vdomh82VHdnMo0i7Pz7XF45ychD4cteroO9gGqDDt9j7hd1rubBX1bfkPsd/APJlyeshusyTj+FqsUD/HDlvM9LRjY1HpU7i7yAlLQQ3851XKMLUPNFYu2r3bo8Wt/CCHtJvB4wYuH+7Wo3muudpU01ziJBxQrUWwPbUrG+7LvO1iEEVxB8l+8Vq0mU3Te7lJi1kGetm6xHNbtvQip5P2YUqvv+lLo/K8KoJDxsh63Y01JGwdmUDb8mnFlRx4J7hQJaoNEvz3cgnc4X8gDJD8sUOjGOPnbtz2QwTY+zj/5+FdLxWDCxNrHX5vvkVdJHcCqEfVvQTKfDMOUeKuhjI7GD7t3xRPfUxq19jjoLPe7aqn1Z1s=
111 540cd0ddac49c1125b2e013aa2ff18ecbd4dd954 0 iQIVAwUAVZRtzSBXgaxoKi1yAQJVLhAAtfn+8OzHIp6wRC4NUbkImAJRLsNTRPKeRSWPCF5O5XXQ84hp+86qjhndIE6mcJSAt4cVP8uky6sEa8ULd6b3ACRBvtgZtsecA9S/KtRjyE9CKr8nP+ogBNqJPaYlTz9RuwGedOd+8I9lYgsnRjfaHSByNMX08WEHtWqAWhSkAz/HO32ardS38cN97fckCgQtA8v7c77nBT7vcw4epgxyUQvMUxUhqmCVVhVfz8JXa5hyJxFrOtqgaVuQ1B5Y/EKxcyZT+JNHPtu3V1uc1awS/w16CEPstNBSFHax5MuT9UbY0mV2ZITP99EkM+vdomh82VHdnMo0i7Pz7XF45ychD4cteroO9gGqDDt9j7hd1rubBX1bfkPsd/APJlyeshusyTj+FqsUD/HDlvM9LRjY1HpU7i7yAlLQQ3851XKMLUPNFYu2r3bo8Wt/CCHtJvB4wYuH+7Wo3muudpU01ziJBxQrUWwPbUrG+7LvO1iEEVxB8l+8Vq0mU3Te7lJi1kGetm6xHNbtvQip5P2YUqvv+lLo/K8KoJDxsh63Y01JGwdmUDb8mnFlRx4J7hQJaoNEvz3cgnc4X8gDJD8sUOjGOPnbtz2QwTY+zj/5+FdLxWDCxNrHX5vvkVdJHcCqEfVvQTKfDMOUeKuhjI7GD7t3xRPfUxq19jjoLPe7aqn1Z1s=
112 96a38d44ba093bd1d1ecfd34119e94056030278b 0 iQIVAwUAVarUUyBXgaxoKi1yAQIfJw/+MG/0736F/9IvzgCTF6omIC+9kS8JH0n/JBGPhpbPAHK4xxjhOOz6m3Ia3c3HNoy+I6calwU6YV7k5dUzlyLhM0Z5oYpdrH+OBNxDEsD5SfhclfR63MK1kmgtD33izijsZ++6a+ZaVfyxpMTksKOktWSIDD63a5b/avb6nKY64KwJcbbeXPdelxvXV7TXYm0GvWc46BgvrHOJpYHCDaXorAn6BMq7EQF8sxdNK4GVMNMVk1njve0HOg3Kz8llPB/7QmddZXYLFGmWqICyUn1IsJDfePxzh8sOYVCbxAgitTJHJJmmH5gzVzw7t7ljtmxSJpcUGQJB2MphejmNFGfgvJPB9c6xOCfUqDjxN5m24V+UYesZntpfgs3lpfvE7785IpVnf6WfKG4PKty01ome/joHlDlrRTekKMlpiBapGMfv8EHvPBrOA+5yAHNfKsmcyCcjD1nvXYZ2/X9qY35AhdcBuNkyp55oPDOdtYIHfnOIxlYMKG1dusDx3Z4eveF0lQTzfRVoE5w+k9A2Ov3Zx0aiSkFFevJjrq5QBfs9dAiT8JYgBmWhaJzCtJm12lQirRMKR/br88Vwt/ry/UVY9cereMNvRYUGOGfC8CGGDCw4WDD+qWvyB3mmrXVuMlXxQRIZRJy5KazaQXsBWuIsx4kgGqC5Uo+yzpiQ1VMuCyI=
112 96a38d44ba093bd1d1ecfd34119e94056030278b 0 iQIVAwUAVarUUyBXgaxoKi1yAQIfJw/+MG/0736F/9IvzgCTF6omIC+9kS8JH0n/JBGPhpbPAHK4xxjhOOz6m3Ia3c3HNoy+I6calwU6YV7k5dUzlyLhM0Z5oYpdrH+OBNxDEsD5SfhclfR63MK1kmgtD33izijsZ++6a+ZaVfyxpMTksKOktWSIDD63a5b/avb6nKY64KwJcbbeXPdelxvXV7TXYm0GvWc46BgvrHOJpYHCDaXorAn6BMq7EQF8sxdNK4GVMNMVk1njve0HOg3Kz8llPB/7QmddZXYLFGmWqICyUn1IsJDfePxzh8sOYVCbxAgitTJHJJmmH5gzVzw7t7ljtmxSJpcUGQJB2MphejmNFGfgvJPB9c6xOCfUqDjxN5m24V+UYesZntpfgs3lpfvE7785IpVnf6WfKG4PKty01ome/joHlDlrRTekKMlpiBapGMfv8EHvPBrOA+5yAHNfKsmcyCcjD1nvXYZ2/X9qY35AhdcBuNkyp55oPDOdtYIHfnOIxlYMKG1dusDx3Z4eveF0lQTzfRVoE5w+k9A2Ov3Zx0aiSkFFevJjrq5QBfs9dAiT8JYgBmWhaJzCtJm12lQirRMKR/br88Vwt/ry/UVY9cereMNvRYUGOGfC8CGGDCw4WDD+qWvyB3mmrXVuMlXxQRIZRJy5KazaQXsBWuIsx4kgGqC5Uo+yzpiQ1VMuCyI=
113 21aa1c313b05b1a85f8ffa1120d51579ddf6bf24 0 iQIVAwUAVbuouCBXgaxoKi1yAQL2ng//eI1w51F4YkDiUAhrZuc8RE/chEd2o4F6Jyu9laA03vbim598ntqGjX3+UkOyTQ/zGVeZfW2cNG8zkJjSLk138DHCYl2YPPD/yxqMOJp/a7U34+HrA0aE5Y2pcfx+FofZHRvRtt40UCngicjKivko8au7Ezayidpa/vQbc6dNvGrwwk4KMgOP2HYIfHgCirR5UmaWtNpzlLhf9E7JSNL5ZXij3nt6AgEPyn0OvmmOLyUARO/JTJ6vVyLEtwiXg7B3sF5RpmyFDhrkZ+MbFHgL4k/3y9Lb97WaZl8nXJIaNPOTPJqkApFY/56S12PKYK4js2OgU+QsX1XWvouAhEx6CC6Jk9EHhr6+9qxYFhBJw7RjbswUG6LvJy/kBe+Ei5UbYg9dATf3VxQ6Gqs19lebtzltERH2yNwaHyVeqqakPSonOaUyxGMRRosvNHyrTTor38j8d27KksgpocXzBPZcc1MlS3vJg2nIwZlc9EKM9z5R0J1KAi1Z/+xzBjiGRYg5EZY6ElAw30eCjGta7tXlBssJiKeHut7QTLxCZHQuX1tKxDDs1qlXlGCMbrFqo0EiF9hTssptRG3ZyLwMdzEjnh4ki6gzONZKDI8uayAS3N+CEtWcGUtiA9OwuiFXTwodmles/Mh14LEhiVZoDK3L9TPcY22o2qRuku/6wq6QKsg=
113 21aa1c313b05b1a85f8ffa1120d51579ddf6bf24 0 iQIVAwUAVbuouCBXgaxoKi1yAQL2ng//eI1w51F4YkDiUAhrZuc8RE/chEd2o4F6Jyu9laA03vbim598ntqGjX3+UkOyTQ/zGVeZfW2cNG8zkJjSLk138DHCYl2YPPD/yxqMOJp/a7U34+HrA0aE5Y2pcfx+FofZHRvRtt40UCngicjKivko8au7Ezayidpa/vQbc6dNvGrwwk4KMgOP2HYIfHgCirR5UmaWtNpzlLhf9E7JSNL5ZXij3nt6AgEPyn0OvmmOLyUARO/JTJ6vVyLEtwiXg7B3sF5RpmyFDhrkZ+MbFHgL4k/3y9Lb97WaZl8nXJIaNPOTPJqkApFY/56S12PKYK4js2OgU+QsX1XWvouAhEx6CC6Jk9EHhr6+9qxYFhBJw7RjbswUG6LvJy/kBe+Ei5UbYg9dATf3VxQ6Gqs19lebtzltERH2yNwaHyVeqqakPSonOaUyxGMRRosvNHyrTTor38j8d27KksgpocXzBPZcc1MlS3vJg2nIwZlc9EKM9z5R0J1KAi1Z/+xzBjiGRYg5EZY6ElAw30eCjGta7tXlBssJiKeHut7QTLxCZHQuX1tKxDDs1qlXlGCMbrFqo0EiF9hTssptRG3ZyLwMdzEjnh4ki6gzONZKDI8uayAS3N+CEtWcGUtiA9OwuiFXTwodmles/Mh14LEhiVZoDK3L9TPcY22o2qRuku/6wq6QKsg=
114 1a45e49a6bed023deb229102a8903234d18054d3 0 iQIVAwUAVeYa2SBXgaxoKi1yAQLWVA//Q7vU0YzngbxIbrTPvfFiNTJcT4bx9u1xMHRZf6QBIE3KtRHKTooJwH9lGR0HHM+8DWWZup3Vzo6JuWHMGoW0v5fzDyk2czwM9BgQQPfEmoJ/ZuBMevTkTZngjgHVwhP3tHFym8Rk9vVxyiZd35EcxP+4F817GCzD+K7XliIBqVggmv9YeQDXfEtvo7UZrMPPec79t8tzt2UadI3KC1jWUriTS1Fg1KxgXW6srD80D10bYyCkkdo/KfF6BGZ9SkF+U3b95cuqSmOfoyyQwUA3JbMXXOnIefnC7lqRC2QTC6mYDx5hIkBiwymXJBe8rpq/S94VVvPGfW6A5upyeCZISLEEnAz0GlykdpIy/NogzhmWpbAMOus05Xnen6xPdNig6c/M5ZleRxVobNrZSd7c5qI3aUUyfMKXlY1j9oiUTjSKH1IizwaI3aL/MM70eErBxXiLs2tpQvZeaVLn3kwCB5YhywO3LK0x+FNx4Gl90deAXMYibGNiLTq9grpB8fuLg9M90JBjFkeYkrSJ2yGYumYyP/WBA3mYEYGDLNstOby4riTU3WCqVl+eah6ss3l+gNDjLxiMtJZ/g0gQACaAvxQ9tYp5eeRMuLRTp79QQPxv97s8IyVwE/TlPlcSFlEXAzsBvqvsolQXRVi9AxA6M2davYabBYAgRf6rRfgujoU=
114 1a45e49a6bed023deb229102a8903234d18054d3 0 iQIVAwUAVeYa2SBXgaxoKi1yAQLWVA//Q7vU0YzngbxIbrTPvfFiNTJcT4bx9u1xMHRZf6QBIE3KtRHKTooJwH9lGR0HHM+8DWWZup3Vzo6JuWHMGoW0v5fzDyk2czwM9BgQQPfEmoJ/ZuBMevTkTZngjgHVwhP3tHFym8Rk9vVxyiZd35EcxP+4F817GCzD+K7XliIBqVggmv9YeQDXfEtvo7UZrMPPec79t8tzt2UadI3KC1jWUriTS1Fg1KxgXW6srD80D10bYyCkkdo/KfF6BGZ9SkF+U3b95cuqSmOfoyyQwUA3JbMXXOnIefnC7lqRC2QTC6mYDx5hIkBiwymXJBe8rpq/S94VVvPGfW6A5upyeCZISLEEnAz0GlykdpIy/NogzhmWpbAMOus05Xnen6xPdNig6c/M5ZleRxVobNrZSd7c5qI3aUUyfMKXlY1j9oiUTjSKH1IizwaI3aL/MM70eErBxXiLs2tpQvZeaVLn3kwCB5YhywO3LK0x+FNx4Gl90deAXMYibGNiLTq9grpB8fuLg9M90JBjFkeYkrSJ2yGYumYyP/WBA3mYEYGDLNstOby4riTU3WCqVl+eah6ss3l+gNDjLxiMtJZ/g0gQACaAvxQ9tYp5eeRMuLRTp79QQPxv97s8IyVwE/TlPlcSFlEXAzsBvqvsolQXRVi9AxA6M2davYabBYAgRf6rRfgujoU=
115 9a466b9f9792e3ad7ae3fc6c43c3ff2e136b718d 0 iQIVAwUAVg1oMSBXgaxoKi1yAQLPag/+Pv0+pR9b9Y5RflEcERUzVu92q+l/JEiP7PHP9pAZuXoQ0ikYBFo1Ygw8tkIG00dgEaLk/2b7E3OxaU9pjU3thoX//XpTcbkJtVhe7Bkjh9/S3dRpm2FWNL9n0qnywebziB45Xs8XzUwBZTYOkVRInYr/NzSo8KNbQH1B4u2g56veb8u/7GtEvBSGnMGVYKhVUZ3jxyDf371QkdafMOJPpogkZcVhXusvMZPDBYtTIzswyxBJ2jxHzjt8+EKs+FI3FxzvQ9Ze3M5Daa7xfiHI3sOgECO8GMVaJi0F49lttKx08KONw8xLlEof+cJ+qxLxQ42X5XOQglJ2/bv5ES5JiZYAti2XSXbZK96p4wexqL4hnaLVU/2iEUfqB9Sj6itEuhGOknPD9fQo1rZXYIS8CT5nGTNG4rEpLFN6VwWn1btIMNkEHw998zU7N3HAOk6adD6zGcntUfMBvQC3V4VK3o7hp8PGeySrWrOLcC/xLKM+XRonz46woJK5D8w8lCVYAxBWEGKAFtj9hv9R8Ye9gCW0Q8BvJ7MwGpn+7fLQ1BVZdV1LZQTSBUr5u8mNeDsRo4H2hITQRhUeElIwlMsUbbN078a4JPOUgPz1+Fi8oHRccBchN6I40QohL934zhcKXQ+NXYN8BgpCicPztSg8O8Y/qvhFP12Zu4tOH8P/dFY=
115 9a466b9f9792e3ad7ae3fc6c43c3ff2e136b718d 0 iQIVAwUAVg1oMSBXgaxoKi1yAQLPag/+Pv0+pR9b9Y5RflEcERUzVu92q+l/JEiP7PHP9pAZuXoQ0ikYBFo1Ygw8tkIG00dgEaLk/2b7E3OxaU9pjU3thoX//XpTcbkJtVhe7Bkjh9/S3dRpm2FWNL9n0qnywebziB45Xs8XzUwBZTYOkVRInYr/NzSo8KNbQH1B4u2g56veb8u/7GtEvBSGnMGVYKhVUZ3jxyDf371QkdafMOJPpogkZcVhXusvMZPDBYtTIzswyxBJ2jxHzjt8+EKs+FI3FxzvQ9Ze3M5Daa7xfiHI3sOgECO8GMVaJi0F49lttKx08KONw8xLlEof+cJ+qxLxQ42X5XOQglJ2/bv5ES5JiZYAti2XSXbZK96p4wexqL4hnaLVU/2iEUfqB9Sj6itEuhGOknPD9fQo1rZXYIS8CT5nGTNG4rEpLFN6VwWn1btIMNkEHw998zU7N3HAOk6adD6zGcntUfMBvQC3V4VK3o7hp8PGeySrWrOLcC/xLKM+XRonz46woJK5D8w8lCVYAxBWEGKAFtj9hv9R8Ye9gCW0Q8BvJ7MwGpn+7fLQ1BVZdV1LZQTSBUr5u8mNeDsRo4H2hITQRhUeElIwlMsUbbN078a4JPOUgPz1+Fi8oHRccBchN6I40QohL934zhcKXQ+NXYN8BgpCicPztSg8O8Y/qvhFP12Zu4tOH8P/dFY=
116 b66e3ca0b90c3095ea28dfd39aa24247bebf5c20 0 iQIVAwUAViarTyBXgaxoKi1yAQLZgRAAh7c7ebn7kUWI5M/b/T6qHGjFrU5azkjamzy9IG+KIa2hZgSMxyEM7JJUFqKP4TiWa3sW03bjKGSM/SjjDSSyheX+JIVSPNyKrBwneYhPq45Ius8eiHziClkt0CSsl2d9xDRpI0JmHbN0Pf8nh7rnbL+231GDAOT6dP+2S8K1HGa/0BgEcL9gpYs4/2GyjL+hBSUjyrabzvwe48DCN5W0tEJbGFw5YEADxdfbVbNEuXL81tR4PFGiJxPW0QKRLDB74MWmiWC0gi2ZC/IhbNBZ2sLb6694d4Bx4PVwtiARh63HNXVMEaBrFu1S9NcMQyHvAOc6Zw4izF/PCeTcdEnPk8J1t5PTz09Lp0EAKxe7CWIViy350ke5eiaxO3ySrNMX6d83BOHLDqEFMSWm+ad+KEMT4CJrK4X/n/XMgEFAaU5nWlIRqrLRIeU2Ifc625T0Xh4BgTqXPpytQxhgV5b+Fi6duNk4cy+QnHT4ymxI6BPD9HvSQwc+O7h37qjvJVZmpQX6AP8O75Yza8ZbcYKRIIxZzOkwNpzE5A/vpvP5bCRn7AGcT3ORWmAYr/etr3vxUvt2fQz6U/R4S915V+AeWBdcp+uExu6VZ42M0vhhh0lyzx1VRJGVdV+LoxFKkaC42d0yT+O1QEhSB7WL1D3/a/iWubv6ieB/cvNMhFaK9DA=
116 b66e3ca0b90c3095ea28dfd39aa24247bebf5c20 0 iQIVAwUAViarTyBXgaxoKi1yAQLZgRAAh7c7ebn7kUWI5M/b/T6qHGjFrU5azkjamzy9IG+KIa2hZgSMxyEM7JJUFqKP4TiWa3sW03bjKGSM/SjjDSSyheX+JIVSPNyKrBwneYhPq45Ius8eiHziClkt0CSsl2d9xDRpI0JmHbN0Pf8nh7rnbL+231GDAOT6dP+2S8K1HGa/0BgEcL9gpYs4/2GyjL+hBSUjyrabzvwe48DCN5W0tEJbGFw5YEADxdfbVbNEuXL81tR4PFGiJxPW0QKRLDB74MWmiWC0gi2ZC/IhbNBZ2sLb6694d4Bx4PVwtiARh63HNXVMEaBrFu1S9NcMQyHvAOc6Zw4izF/PCeTcdEnPk8J1t5PTz09Lp0EAKxe7CWIViy350ke5eiaxO3ySrNMX6d83BOHLDqEFMSWm+ad+KEMT4CJrK4X/n/XMgEFAaU5nWlIRqrLRIeU2Ifc625T0Xh4BgTqXPpytQxhgV5b+Fi6duNk4cy+QnHT4ymxI6BPD9HvSQwc+O7h37qjvJVZmpQX6AP8O75Yza8ZbcYKRIIxZzOkwNpzE5A/vpvP5bCRn7AGcT3ORWmAYr/etr3vxUvt2fQz6U/R4S915V+AeWBdcp+uExu6VZ42M0vhhh0lyzx1VRJGVdV+LoxFKkaC42d0yT+O1QEhSB7WL1D3/a/iWubv6ieB/cvNMhFaK9DA=
117 47dd34f2e7272be9e3b2a5a83cd0d20be44293f4 0 iQIVAwUAVjZiKiBXgaxoKi1yAQKBWQ/+JcE37vprSOA5e0ezs/avC7leR6hTlXy9O5bpFnvMpbVMTUp+KfBE4HxTT0KKXKh9lGtNaQ+lAmHuy1OQE1hBKPIaCUd8/1gunGsXgRM3TJ9LwjFd4qFpOMxvOouc6kW5kmea7V9W2fg6aFNjjc/4/0J3HMOIjmf2fFz87xqR1xX8iezJ57A4pUPNViJlOWXRzfa56cI6VUe5qOMD0NRXcY+JyI5qW25Y/aL5D9loeKflpzd53Ue+Pu3qlhddJd3PVkaAiVDH+DYyRb8sKgwuiEsyaBO18IBgC8eDmTohEJt6707A+WNhwBJwp9aOUhHC7caaKRYhEKuDRQ3op++VqwuxbFRXx22XYR9bEzQIlpsv9GY2k8SShU5MZqUKIhk8vppFI6RaID5bmALnLLmjmXfSPYSJDzDuCP5UTQgI3PKPOATorVrqMdKzfb7FiwtcTvtHAXpOgLaY9P9XIePbnei6Rx9TfoHYDvzFWRqzSjl21xR+ZUrJtG2fx7XLbMjEAZJcnjP++GRvNbHBOi57aX0l2LO1peQqZVMULoIivaoLFP3i16RuXXQ/bvKyHmKjJzGrLc0QCa0yfrvV2m30RRMaYlOv7ToJfdfZLXvSAP0zbAuDaXdjGnq7gpfIlNE3xM+kQ75Akcf4V4fK1p061EGBQvQz6Ov3PkPiWL/bxrQ=
117 47dd34f2e7272be9e3b2a5a83cd0d20be44293f4 0 iQIVAwUAVjZiKiBXgaxoKi1yAQKBWQ/+JcE37vprSOA5e0ezs/avC7leR6hTlXy9O5bpFnvMpbVMTUp+KfBE4HxTT0KKXKh9lGtNaQ+lAmHuy1OQE1hBKPIaCUd8/1gunGsXgRM3TJ9LwjFd4qFpOMxvOouc6kW5kmea7V9W2fg6aFNjjc/4/0J3HMOIjmf2fFz87xqR1xX8iezJ57A4pUPNViJlOWXRzfa56cI6VUe5qOMD0NRXcY+JyI5qW25Y/aL5D9loeKflpzd53Ue+Pu3qlhddJd3PVkaAiVDH+DYyRb8sKgwuiEsyaBO18IBgC8eDmTohEJt6707A+WNhwBJwp9aOUhHC7caaKRYhEKuDRQ3op++VqwuxbFRXx22XYR9bEzQIlpsv9GY2k8SShU5MZqUKIhk8vppFI6RaID5bmALnLLmjmXfSPYSJDzDuCP5UTQgI3PKPOATorVrqMdKzfb7FiwtcTvtHAXpOgLaY9P9XIePbnei6Rx9TfoHYDvzFWRqzSjl21xR+ZUrJtG2fx7XLbMjEAZJcnjP++GRvNbHBOi57aX0l2LO1peQqZVMULoIivaoLFP3i16RuXXQ/bvKyHmKjJzGrLc0QCa0yfrvV2m30RRMaYlOv7ToJfdfZLXvSAP0zbAuDaXdjGnq7gpfIlNE3xM+kQ75Akcf4V4fK1p061EGBQvQz6Ov3PkPiWL/bxrQ=
118 1aa5083cbebbe7575c88f3402ab377539b484897 0 iQIVAwUAVkEdCCBXgaxoKi1yAQKdWg//crTr5gsnHQppuD1p+PPn3/7SMsWJ7bgbuaXgERDLC0zWMfhM2oMmu/4jqXnpangdBVvb0SojejgzxoBo9FfRQiIoKt0vxmmn+S8CrEwb99rpP4M7lgyMAInKPMXQdYxkoDNwL70Afmog6eBtlxjYnu8nmUE/swu6JoVns+tF8UOvIKFYbuCcGujo2pUOQC0xBGiHeHSGRDJOlWmY2d7D/PkQtQE/u/d4QZt7enTHMiV44XVJ8+0U0f1ZQE7V+hNWf+IjwcZtL95dnQzUKs6tXMIln/OwO+eJ3d61BfLvmABvCwUC9IepPssNSFBUfGqBAP5wXOzFIPSYn00IWpmZtCnpUNL99X1IV3RP+p99gnEDTScQFPYt5B0q5I1nFdRh1p48BSF/kjPA7V++UfBwMXrrYLKhUR9BjmrRzYnyXJKwbH6iCNj5hsXUkVrBdBi/FnMczgsVILfFcIXUfnJD3E/dG+1lmuObg6dEynxiGChTuaR4KkLa5ZRkUcUl6fWlSRsqSNbGEEbdwcI+nTCZqJUlLSghumhs0Z89Hs1nltBd1ALX2VLJEHrKMrFQ8NfEBeCB6ENqMJi5qPlq354MCdGOZ9RvisX/HlxE4Q61BW0+EwnyXSch6LFSOS3axOocUazMoK1XiOTJSv/5bAsnwb0ztDWeUj9fZEJL+SWtgB8=
118 1aa5083cbebbe7575c88f3402ab377539b484897 0 iQIVAwUAVkEdCCBXgaxoKi1yAQKdWg//crTr5gsnHQppuD1p+PPn3/7SMsWJ7bgbuaXgERDLC0zWMfhM2oMmu/4jqXnpangdBVvb0SojejgzxoBo9FfRQiIoKt0vxmmn+S8CrEwb99rpP4M7lgyMAInKPMXQdYxkoDNwL70Afmog6eBtlxjYnu8nmUE/swu6JoVns+tF8UOvIKFYbuCcGujo2pUOQC0xBGiHeHSGRDJOlWmY2d7D/PkQtQE/u/d4QZt7enTHMiV44XVJ8+0U0f1ZQE7V+hNWf+IjwcZtL95dnQzUKs6tXMIln/OwO+eJ3d61BfLvmABvCwUC9IepPssNSFBUfGqBAP5wXOzFIPSYn00IWpmZtCnpUNL99X1IV3RP+p99gnEDTScQFPYt5B0q5I1nFdRh1p48BSF/kjPA7V++UfBwMXrrYLKhUR9BjmrRzYnyXJKwbH6iCNj5hsXUkVrBdBi/FnMczgsVILfFcIXUfnJD3E/dG+1lmuObg6dEynxiGChTuaR4KkLa5ZRkUcUl6fWlSRsqSNbGEEbdwcI+nTCZqJUlLSghumhs0Z89Hs1nltBd1ALX2VLJEHrKMrFQ8NfEBeCB6ENqMJi5qPlq354MCdGOZ9RvisX/HlxE4Q61BW0+EwnyXSch6LFSOS3axOocUazMoK1XiOTJSv/5bAsnwb0ztDWeUj9fZEJL+SWtgB8=
119 2d437a0f3355834a9485bbbeb30a52a052c98f19 0 iQIVAwUAVl5U9CBXgaxoKi1yAQLocg//a4YFz9UVSIEzVEJMUPJnN2dBvEXRpwpb5CdKPd428+18K6VWZd5Mc6xNNRV5AV/hCYylgqDplIvyOvwCj7uN8nEOrLUQQ0Pp37M5ZIX8ZVCK/wgchJ2ltabUG1NrZ7/JA84U79VGLAECMnD0Z9WvZDESpVXmdXfxrk1eCc3omRB0ofNghEx+xpYworfZsu8aap1GHQuBsjPv4VyUWGpMq/KA01PdxRTELmrJnfSyr0nPKwxlI5KsbA1GOe+Mk3tp5HJ42DZqLtKSGPirf6E+6lRJeB0H7EpotN4wD3yZDsw6AgRb2C/ay/3T3Oz7CN+45mwuujV9Cxx5zs1EeOgZcqgA/hXMcwlQyvQDMrWpO8ytSBm6MhOuFOTB3HnUxfsnfSocLJsbNwGWKceAzACcXSqapveVAz/7h+InFgl/8Qce28UJdnX5wro5gP6UWt+xrvc7vfmVGgI3oxbiOUrfglhkjmrxBjEiDQy4BWH7HWMZUVxnqPQRcxIE10+dv0KtM/PBkbUtnbGJ88opFBGkFweje5vQcZy/duuPEIufRkPr8EV47QjOxlvldEjlLq3+QUdJZEgCIFw1X0y7Pix4dsPFjwOmAyo4El1ePrdFzG3dXSVA3eHvMDRnYnNlue9wHvKhYbBle5xTOZBgGuMzhDVe+54JLql5JYr4WrI1pvA=
119 2d437a0f3355834a9485bbbeb30a52a052c98f19 0 iQIVAwUAVl5U9CBXgaxoKi1yAQLocg//a4YFz9UVSIEzVEJMUPJnN2dBvEXRpwpb5CdKPd428+18K6VWZd5Mc6xNNRV5AV/hCYylgqDplIvyOvwCj7uN8nEOrLUQQ0Pp37M5ZIX8ZVCK/wgchJ2ltabUG1NrZ7/JA84U79VGLAECMnD0Z9WvZDESpVXmdXfxrk1eCc3omRB0ofNghEx+xpYworfZsu8aap1GHQuBsjPv4VyUWGpMq/KA01PdxRTELmrJnfSyr0nPKwxlI5KsbA1GOe+Mk3tp5HJ42DZqLtKSGPirf6E+6lRJeB0H7EpotN4wD3yZDsw6AgRb2C/ay/3T3Oz7CN+45mwuujV9Cxx5zs1EeOgZcqgA/hXMcwlQyvQDMrWpO8ytSBm6MhOuFOTB3HnUxfsnfSocLJsbNwGWKceAzACcXSqapveVAz/7h+InFgl/8Qce28UJdnX5wro5gP6UWt+xrvc7vfmVGgI3oxbiOUrfglhkjmrxBjEiDQy4BWH7HWMZUVxnqPQRcxIE10+dv0KtM/PBkbUtnbGJ88opFBGkFweje5vQcZy/duuPEIufRkPr8EV47QjOxlvldEjlLq3+QUdJZEgCIFw1X0y7Pix4dsPFjwOmAyo4El1ePrdFzG3dXSVA3eHvMDRnYnNlue9wHvKhYbBle5xTOZBgGuMzhDVe+54JLql5JYr4WrI1pvA=
120 ea389970c08449440587712117f178d33bab3f1e 0 iQIVAwUAVociGyBXgaxoKi1yAQJx9Q//TzMypcls5CQW3DM9xY1Q+RFeIw1LcDIev6NDBjUYxULb2WIK2qPw4Th5czF622SMd+XO/kiQeWYp9IW90MZOUVT1YGgUPKlKWMjkf0lZEPzprHjHq0+z/no1kBCBQg2uUOLsb6Y7zom4hFCyPsxXOk5nnxcFEK0VDbODa9zoKb/flyQ7rtzs+Z6BljIQ0TJAJsXs+6XgrW1XJ/f6nbeqsQyPklIBJuGKiaU1Pg8wQe6QqFaO1NYgM3hBETku6r3OTpUhu/2FTUZ7yDWGGzBqmifxzdHoj7/B+2qzRpII77PlZqoe6XF+UOObSFnhKvXKLjlGY5cy3SXBMbHkPcYtHua8wYR8LqO2bYYnsDd9qD0DJ+LlqH0ZMUkB2Cdk9q/cp1PGJWGlYYecHP87DLuWKwS+a6LhVI9TGkIUosVtLaIMsUUEz83RJFb4sSGOXtjk5DDznn9QW8ltXXMTdGQwFq1vmuiXATYenhszbvagrnbAnDyNFths4IhS1jG8237SB36nGmO3zQm5V7AMHfSrISB/8VPyY4Si7uvAV2kMWxuMhYuQbBwVx/KxbKrYjowuvJvCKaV101rWxvSeU2wDih20v+dnQKPveRNnO8AAK/ICflVVsISkd7hXcfk+SnhfxcPQTr+HQIJEW9wt5Q8WbgHk9wuR8kgXQEX6tCGpT/w=
120 ea389970c08449440587712117f178d33bab3f1e 0 iQIVAwUAVociGyBXgaxoKi1yAQJx9Q//TzMypcls5CQW3DM9xY1Q+RFeIw1LcDIev6NDBjUYxULb2WIK2qPw4Th5czF622SMd+XO/kiQeWYp9IW90MZOUVT1YGgUPKlKWMjkf0lZEPzprHjHq0+z/no1kBCBQg2uUOLsb6Y7zom4hFCyPsxXOk5nnxcFEK0VDbODa9zoKb/flyQ7rtzs+Z6BljIQ0TJAJsXs+6XgrW1XJ/f6nbeqsQyPklIBJuGKiaU1Pg8wQe6QqFaO1NYgM3hBETku6r3OTpUhu/2FTUZ7yDWGGzBqmifxzdHoj7/B+2qzRpII77PlZqoe6XF+UOObSFnhKvXKLjlGY5cy3SXBMbHkPcYtHua8wYR8LqO2bYYnsDd9qD0DJ+LlqH0ZMUkB2Cdk9q/cp1PGJWGlYYecHP87DLuWKwS+a6LhVI9TGkIUosVtLaIMsUUEz83RJFb4sSGOXtjk5DDznn9QW8ltXXMTdGQwFq1vmuiXATYenhszbvagrnbAnDyNFths4IhS1jG8237SB36nGmO3zQm5V7AMHfSrISB/8VPyY4Si7uvAV2kMWxuMhYuQbBwVx/KxbKrYjowuvJvCKaV101rWxvSeU2wDih20v+dnQKPveRNnO8AAK/ICflVVsISkd7hXcfk+SnhfxcPQTr+HQIJEW9wt5Q8WbgHk9wuR8kgXQEX6tCGpT/w=
121 158bdc8965720ca4061f8f8d806563cfc7cdb62e 0 iQIVAwUAVqBhFyBXgaxoKi1yAQLJpQ//S8kdgmVlS+CI0d2hQVGYWB/eK+tcntG+bZKLto4bvVy5d0ymlDL0x7VrJMOkwzkU1u/GaYo3L6CVEiM/JGCgB32bllrpx+KwQ0AyHswMZruo/6xrjDIYymLMEJ9yonXBZsG7pf2saYTHm3C5/ZIPkrDZSlssJHJDdeWqd75hUnx3nX8dZ4jIIxYDhtdB5/EmuEGOVlbeBHVpwfDXidSJUHJRwJvDqezUlN003sQdUvOHHtRqBrhsYEhHqPMOxDidAgCvjSfWZQKOTKaPE/gQo/BP3GU++Fg55jBz+SBXpdfQJI2Gd8FZfjLkhFa9vTTTcd10YCd4CZbYLpj/4R2xWj1U4oTVEFa6d+AA5Yyu8xG53XSCCPyzfagyuyfLqsaq5r1qDZO/Mh5KZCTvc9xSF5KXj57mKvzMDpiNeQcamGmsV4yXxymKJKGMQvbnzqp+ItIdbnfk38Nuac8rqNnGmFYwMIPa50680vSZT/NhrlPJ8FVTJlfHtSUZbdjPpsqw7BgjFWaVUdwgCKIGERiK7zfR0innj9rF5oVwT8EbKiaR1uVxOKnTwZzPCbdO1euNg/HutZLVQmugiLAv5Z38L3YZf5bH7zJdUydhiTI4mGn/mgncsKXoSarnnduhoYu9OsQZc9pndhxjAEuAslEIyBsLy81fR2HOhUzw5FGNgdY=
121 158bdc8965720ca4061f8f8d806563cfc7cdb62e 0 iQIVAwUAVqBhFyBXgaxoKi1yAQLJpQ//S8kdgmVlS+CI0d2hQVGYWB/eK+tcntG+bZKLto4bvVy5d0ymlDL0x7VrJMOkwzkU1u/GaYo3L6CVEiM/JGCgB32bllrpx+KwQ0AyHswMZruo/6xrjDIYymLMEJ9yonXBZsG7pf2saYTHm3C5/ZIPkrDZSlssJHJDdeWqd75hUnx3nX8dZ4jIIxYDhtdB5/EmuEGOVlbeBHVpwfDXidSJUHJRwJvDqezUlN003sQdUvOHHtRqBrhsYEhHqPMOxDidAgCvjSfWZQKOTKaPE/gQo/BP3GU++Fg55jBz+SBXpdfQJI2Gd8FZfjLkhFa9vTTTcd10YCd4CZbYLpj/4R2xWj1U4oTVEFa6d+AA5Yyu8xG53XSCCPyzfagyuyfLqsaq5r1qDZO/Mh5KZCTvc9xSF5KXj57mKvzMDpiNeQcamGmsV4yXxymKJKGMQvbnzqp+ItIdbnfk38Nuac8rqNnGmFYwMIPa50680vSZT/NhrlPJ8FVTJlfHtSUZbdjPpsqw7BgjFWaVUdwgCKIGERiK7zfR0innj9rF5oVwT8EbKiaR1uVxOKnTwZzPCbdO1euNg/HutZLVQmugiLAv5Z38L3YZf5bH7zJdUydhiTI4mGn/mgncsKXoSarnnduhoYu9OsQZc9pndhxjAEuAslEIyBsLy81fR2HOhUzw5FGNgdY=
122 2408645de650d8a29a6ce9e7dce601d8dd0d1474 0 iQIVAwUAVq/xFSBXgaxoKi1yAQLsxhAAg+E6uJCtZZOugrrFi9S6C20SRPBwHwmw22PC5z3Ufp9Vf3vqSL/+zmWI9d/yezIVcTXgM9rKCvq58sZvo4FuO2ngPx7bL9LMJ3qx0IyHUKjwa3AwrzjSzvVhNIrRoimD+lVBI/GLmoszpMICM+Nyg3D41fNJKs6YpnwwsHNJkjMwz0n2SHAShWAgIilyANNVnwnzHE68AIkB/gBkUGtrjf6xB9mXQxAv4GPco/234FAkX9xSWsM0Rx+JLLrSBXoHmIlmu9LPjC0AKn8/DDke+fj7bFaF7hdJBUYOtlYH6f7NIvyZSpw0FHl7jPxoRCtXzIV+1dZEbbIMIXzNtzPFVDYDfMhLqpTgthkZ9x0UaMaHecCUWYYBp8G/IyVS40GJodl8xnRiXUkFejbK/NDdR1f9iZS0dtiFu66cATMdb6d+MG+zW0nDKiQmBt6bwynysqn4g3SIGQFEPyEoRy0bXiefHrlkeHbdfc4zgoejx3ywcRDMGvUbpWs5C43EPu44irKXcqC695vAny3A7nZpt/XP5meDdOF67DNQPvhFdjPPbJBpSsUi2hUlZ+599wUfr3lNVzeEzHT7XApTOf6ysuGtHH3qcVHpFqQSRL1MI0f2xL13UadgTVWYrnHEis7f+ncwlWiR0ucpJB3+dQQh3NVGVo89MfbIZPkA8iil03U=
122 2408645de650d8a29a6ce9e7dce601d8dd0d1474 0 iQIVAwUAVq/xFSBXgaxoKi1yAQLsxhAAg+E6uJCtZZOugrrFi9S6C20SRPBwHwmw22PC5z3Ufp9Vf3vqSL/+zmWI9d/yezIVcTXgM9rKCvq58sZvo4FuO2ngPx7bL9LMJ3qx0IyHUKjwa3AwrzjSzvVhNIrRoimD+lVBI/GLmoszpMICM+Nyg3D41fNJKs6YpnwwsHNJkjMwz0n2SHAShWAgIilyANNVnwnzHE68AIkB/gBkUGtrjf6xB9mXQxAv4GPco/234FAkX9xSWsM0Rx+JLLrSBXoHmIlmu9LPjC0AKn8/DDke+fj7bFaF7hdJBUYOtlYH6f7NIvyZSpw0FHl7jPxoRCtXzIV+1dZEbbIMIXzNtzPFVDYDfMhLqpTgthkZ9x0UaMaHecCUWYYBp8G/IyVS40GJodl8xnRiXUkFejbK/NDdR1f9iZS0dtiFu66cATMdb6d+MG+zW0nDKiQmBt6bwynysqn4g3SIGQFEPyEoRy0bXiefHrlkeHbdfc4zgoejx3ywcRDMGvUbpWs5C43EPu44irKXcqC695vAny3A7nZpt/XP5meDdOF67DNQPvhFdjPPbJBpSsUi2hUlZ+599wUfr3lNVzeEzHT7XApTOf6ysuGtHH3qcVHpFqQSRL1MI0f2xL13UadgTVWYrnHEis7f+ncwlWiR0ucpJB3+dQQh3NVGVo89MfbIZPkA8iil03U=
123 b698abf971e7377d9b7ec7fc8c52df45255b0329 0 iQIVAwUAVrJ4YCBXgaxoKi1yAQJsKw/+JHSR0bIyarO4/VilFwsYxCprOnPxmUdS4qc4yjvpbf7Dqqr/OnOHJA29LrMoqWqsHgREepemjqiNindwNtlZec+KgmbF08ihSBBpls96UTTYTcytKRkkbrB+FhwB0iDl/o8RgGPniyG6M7gOp6p8pXQVRCOToIY1B/G0rtpkcU1N3GbiZntO5Fm/LPAVIE74VaDsamMopQ/wEB8qiERngX/M8SjO1ZSaVNW6KjRUsarLXQB9ziVJBolK/WnQsDwEeuWU2udpjBiOHnFC6h84uBpc8rLGhr419bKMJcjgl+0sl2zHGPY2edQYuJqVjVENzf4zzZA+xPgKw3GrSTpd37PEnGU/fufdJ0X+pp3kvmO1cV3TsvVMTCn7NvS6+w8SGdHdwKQQwelYI6vmJnjuOCATbafJiHMaOQ0GVYYk6PPoGrYcQ081x6dStCMaHIPOV1Wirwd2wq+SN9Ql8H6njftBf5Sa5tVWdW/zrhsltMsdZYZagZ/oFT3t83exL0rgZ96bZFs0j3HO3APELygIVuQ6ybPsFyToMDbURNDvr7ZqPKhQkkdHIUMqEez5ReuVgpbO9CWV/yWpB1/ZCpjNBZyDvw05kG2mOoC7AbHc8aLUS/8DetAmhwyb48LW4qjfUkO7RyxVSxqdnaBOMlsg1wsP2S+SlkZKsDHjcquZJ5U=
123 b698abf971e7377d9b7ec7fc8c52df45255b0329 0 iQIVAwUAVrJ4YCBXgaxoKi1yAQJsKw/+JHSR0bIyarO4/VilFwsYxCprOnPxmUdS4qc4yjvpbf7Dqqr/OnOHJA29LrMoqWqsHgREepemjqiNindwNtlZec+KgmbF08ihSBBpls96UTTYTcytKRkkbrB+FhwB0iDl/o8RgGPniyG6M7gOp6p8pXQVRCOToIY1B/G0rtpkcU1N3GbiZntO5Fm/LPAVIE74VaDsamMopQ/wEB8qiERngX/M8SjO1ZSaVNW6KjRUsarLXQB9ziVJBolK/WnQsDwEeuWU2udpjBiOHnFC6h84uBpc8rLGhr419bKMJcjgl+0sl2zHGPY2edQYuJqVjVENzf4zzZA+xPgKw3GrSTpd37PEnGU/fufdJ0X+pp3kvmO1cV3TsvVMTCn7NvS6+w8SGdHdwKQQwelYI6vmJnjuOCATbafJiHMaOQ0GVYYk6PPoGrYcQ081x6dStCMaHIPOV1Wirwd2wq+SN9Ql8H6njftBf5Sa5tVWdW/zrhsltMsdZYZagZ/oFT3t83exL0rgZ96bZFs0j3HO3APELygIVuQ6ybPsFyToMDbURNDvr7ZqPKhQkkdHIUMqEez5ReuVgpbO9CWV/yWpB1/ZCpjNBZyDvw05kG2mOoC7AbHc8aLUS/8DetAmhwyb48LW4qjfUkO7RyxVSxqdnaBOMlsg1wsP2S+SlkZKsDHjcquZJ5U=
124 d493d64757eb45ada99fcb3693e479a51b7782da 0 iQIVAwUAVtYt4SBXgaxoKi1yAQL6TQ/9FzYE/xOSC2LYqPdPjCXNjGuZdN1WMf/8fUMYT83NNOoLEBGx37C0bAxgD4/P03FwYMuP37IjIcX8vN6fWvtG9Oo0o2n/oR3SKjpsheh2zxhAFX3vXhFD4U18wCz/DnM0O1qGJwJ49kk/99WNgDWeW4n9dMzTFpcaeZBCu1REbZQS40Z+ArXTDCr60g5TLN1XR1WKEzQJvF71rvaE6P8d3GLoGobTIJMLi5UnMwGsnsv2/EIPrWHQiAY9ZEnYq6deU/4RMh9c7afZie9I+ycIA/qVH6vXNt3/a2BP3Frmv8IvKPzqwnoWmIUamew9lLf1joD5joBy8Yu+qMW0/s6DYUGQ4Slk9qIfn6wh4ySgT/7FJUMcayx9ONDq7920RjRc+XFpD8B3Zhj2mM+0g9At1FgX2w2Gkf957oz2nlgTVh9sdPvP6UvWzhqszPMpdG5Vt0oc5vuyobW333qSkufCxi5gmH7do1DIzErMcy8b6IpZUDeQ/dakKwLQpZVVPF15IrNa/zsOW55SrGrL8/ErM/mXNQBBAqvRsOLq2njFqK2JaoG6biH21DMjHVZFw2wBRoLQxbOppfz2/e3mNkNy9HjgJTW3+0iHWvRzMSjwRbk9BlbkmH6kG5163ElHq3Ft3uuQyZBL9I5SQxlHi9s/CV0YSTYthpWR3ChKIMoqBQ0=
124 d493d64757eb45ada99fcb3693e479a51b7782da 0 iQIVAwUAVtYt4SBXgaxoKi1yAQL6TQ/9FzYE/xOSC2LYqPdPjCXNjGuZdN1WMf/8fUMYT83NNOoLEBGx37C0bAxgD4/P03FwYMuP37IjIcX8vN6fWvtG9Oo0o2n/oR3SKjpsheh2zxhAFX3vXhFD4U18wCz/DnM0O1qGJwJ49kk/99WNgDWeW4n9dMzTFpcaeZBCu1REbZQS40Z+ArXTDCr60g5TLN1XR1WKEzQJvF71rvaE6P8d3GLoGobTIJMLi5UnMwGsnsv2/EIPrWHQiAY9ZEnYq6deU/4RMh9c7afZie9I+ycIA/qVH6vXNt3/a2BP3Frmv8IvKPzqwnoWmIUamew9lLf1joD5joBy8Yu+qMW0/s6DYUGQ4Slk9qIfn6wh4ySgT/7FJUMcayx9ONDq7920RjRc+XFpD8B3Zhj2mM+0g9At1FgX2w2Gkf957oz2nlgTVh9sdPvP6UvWzhqszPMpdG5Vt0oc5vuyobW333qSkufCxi5gmH7do1DIzErMcy8b6IpZUDeQ/dakKwLQpZVVPF15IrNa/zsOW55SrGrL8/ErM/mXNQBBAqvRsOLq2njFqK2JaoG6biH21DMjHVZFw2wBRoLQxbOppfz2/e3mNkNy9HjgJTW3+0iHWvRzMSjwRbk9BlbkmH6kG5163ElHq3Ft3uuQyZBL9I5SQxlHi9s/CV0YSTYthpWR3ChKIMoqBQ0=
125 ae279d4a19e9683214cbd1fe8298cf0b50571432 0 iQIVAwUAVvqzViBXgaxoKi1yAQKUCxAAtctMD3ydbe+li3iYjhY5qT0wyHwPr9fcLqsQUJ4ZtD4sK3oxCRZFWFxNBk5bIIyiwusSEJPiPddoQ7NljSZlYDI0HR3R4vns55fmDwPG07Ykf7aSyqr+c2ppCGzn2/2ID476FNtzKqjF+LkVyadgI9vgZk5S4BgdSlfSRBL+1KtB1BlF5etIZnc5U9qs1uqzZJc06xyyF8HlrmMZkAvRUbsx/JzA5LgzZ2WzueaxZgYzYjDk0nPLgyPPBj0DVyWXnW/kdRNmKHNbaZ9aZlWmdPCEoq5iBm71d7Xoa61shmeuVZWvxHNqXdjVMHVeT61cRxjdfxTIkJwvlRGwpy7V17vTgzWFxw6QJpmr7kupRo3idsDydLDPHGUsxP3uMZFsp6+4rEe6qbafjNajkRyiw7kVGCxboOFN0rLVJPZwZGksEIkw58IHcPhZNT1bHHocWOA/uHJTAynfKsAdv/LDdGKcZWUCFOzlokw54xbPvdrBtEOnYNp15OY01IAJd2FCUki5WHvhELUggTjfank1Tc3/Rt1KrGOFhg80CWq6eMiuiWkHGvYq3fjNLbgjl3JJatUFoB+cX1ulDOGsLJEXQ4v5DNHgel0o2H395owNlStksSeW1UBVk0hUK/ADtVUYKAPEIFiboh1iDpEOl40JVnYdsGz3w5FLj2w+16/1vWs=
125 ae279d4a19e9683214cbd1fe8298cf0b50571432 0 iQIVAwUAVvqzViBXgaxoKi1yAQKUCxAAtctMD3ydbe+li3iYjhY5qT0wyHwPr9fcLqsQUJ4ZtD4sK3oxCRZFWFxNBk5bIIyiwusSEJPiPddoQ7NljSZlYDI0HR3R4vns55fmDwPG07Ykf7aSyqr+c2ppCGzn2/2ID476FNtzKqjF+LkVyadgI9vgZk5S4BgdSlfSRBL+1KtB1BlF5etIZnc5U9qs1uqzZJc06xyyF8HlrmMZkAvRUbsx/JzA5LgzZ2WzueaxZgYzYjDk0nPLgyPPBj0DVyWXnW/kdRNmKHNbaZ9aZlWmdPCEoq5iBm71d7Xoa61shmeuVZWvxHNqXdjVMHVeT61cRxjdfxTIkJwvlRGwpy7V17vTgzWFxw6QJpmr7kupRo3idsDydLDPHGUsxP3uMZFsp6+4rEe6qbafjNajkRyiw7kVGCxboOFN0rLVJPZwZGksEIkw58IHcPhZNT1bHHocWOA/uHJTAynfKsAdv/LDdGKcZWUCFOzlokw54xbPvdrBtEOnYNp15OY01IAJd2FCUki5WHvhELUggTjfank1Tc3/Rt1KrGOFhg80CWq6eMiuiWkHGvYq3fjNLbgjl3JJatUFoB+cX1ulDOGsLJEXQ4v5DNHgel0o2H395owNlStksSeW1UBVk0hUK/ADtVUYKAPEIFiboh1iDpEOl40JVnYdsGz3w5FLj2w+16/1vWs=
126 740156eedf2c450aee58b1a90b0e826f47c5da64 0 iQIVAwUAVxLGMCBXgaxoKi1yAQLhIg/8DDX+sCz7LmqO47/FfTo+OqGR+bTTqpfK3WebitL0Z6hbXPj7s45jijqIFGqKgMPqS5oom1xeuGTPHdYA0NNoc/mxSCuNLfuXYolpNWPN71HeSDRV9SnhMThG5HSxI+P0Ye4rbsCHrVV+ib1rV81QE2kZ9aZsJd0HnGd512xJ+2ML7AXweM/4lcLmMthN+oi/dv1OGLzfckrcr/fEATCLZt55eO7idx11J1Fk4ptQ6dQ/bKznlD4hneyy1HMPsGxw+bCXrMF2C/nUiRLHdKgGqZ+cDq6loQRfFlQoIhfoEnWC424qbjH4rvHgkZHqC59Oi/ti9Hi75oq9Tb79yzlCY/fGsdrlJpEzrTQdHFMHUoO9CC+JYObXHRo3ALnC5350ZBKxlkdpmucrHTgcDabfhRlx9vDxP4RDopm2hAjk2LJH7bdxnGEyZYkTOZ3hXKnVpt2hUQb4jyzzC9Kl47TFpPKNVKI+NLqRRZAIdXXiy24KD7WzzE6L0NNK0/IeqKBENLL8I1PmDQ6XmYTQVhTuad1jjm2PZDyGiXmJFZO1O/NGecVTvVynKsDT6XhEvzyEtjXqD98rrhbeMHTcmNSwwJMDvm9ws0075sLQyq2EYFG6ECWFypdA/jfumTmxOTkMtuy/V1Gyq7YJ8YaksZ7fXNY9VuJFP72grmlXc6Dvpr4=
126 740156eedf2c450aee58b1a90b0e826f47c5da64 0 iQIVAwUAVxLGMCBXgaxoKi1yAQLhIg/8DDX+sCz7LmqO47/FfTo+OqGR+bTTqpfK3WebitL0Z6hbXPj7s45jijqIFGqKgMPqS5oom1xeuGTPHdYA0NNoc/mxSCuNLfuXYolpNWPN71HeSDRV9SnhMThG5HSxI+P0Ye4rbsCHrVV+ib1rV81QE2kZ9aZsJd0HnGd512xJ+2ML7AXweM/4lcLmMthN+oi/dv1OGLzfckrcr/fEATCLZt55eO7idx11J1Fk4ptQ6dQ/bKznlD4hneyy1HMPsGxw+bCXrMF2C/nUiRLHdKgGqZ+cDq6loQRfFlQoIhfoEnWC424qbjH4rvHgkZHqC59Oi/ti9Hi75oq9Tb79yzlCY/fGsdrlJpEzrTQdHFMHUoO9CC+JYObXHRo3ALnC5350ZBKxlkdpmucrHTgcDabfhRlx9vDxP4RDopm2hAjk2LJH7bdxnGEyZYkTOZ3hXKnVpt2hUQb4jyzzC9Kl47TFpPKNVKI+NLqRRZAIdXXiy24KD7WzzE6L0NNK0/IeqKBENLL8I1PmDQ6XmYTQVhTuad1jjm2PZDyGiXmJFZO1O/NGecVTvVynKsDT6XhEvzyEtjXqD98rrhbeMHTcmNSwwJMDvm9ws0075sLQyq2EYFG6ECWFypdA/jfumTmxOTkMtuy/V1Gyq7YJ8YaksZ7fXNY9VuJFP72grmlXc6Dvpr4=
127 f85de28eae32e7d3064b1a1321309071bbaaa069 0 iQIVAwUAVyZQaiBXgaxoKi1yAQJhCQ//WrRZ55k3VI/OgY+I/HvgFHOC0sbhe207Kedxvy00a3AtXM6wa5E95GNX04QxUfTWUf5ZHDfEgj0/mQywNrH1oJG47iPZSs+qXNLqtgAaXtrih6r4/ruUwFCRFxqK9mkhjG61SKicw3Q7uGva950g6ZUE5BsZ7XJWgoDcJzWKR+AH992G6H//Fhi4zFQAmB34++sm80wV6wMxVKA/qhQzetooTR2x9qrHpvCKMzKllleJe48yzPLJjQoaaVgXCDav0eIePFNw0WvVSldOEp/ADDdTGa65qsC1rO2BB1Cu5+frJ/vUoo0PwIgqgD6p2i41hfIKvkp6130TxmRVxUx+ma8gBYEpPIabV0flLU72gq8lMlGBBSnQ+fcZsfs/Ug0xRN0tzkEScmZFiDxRGk0y7IalXzv6irwOyC2fZCajXGJDzkROQXWMgy9eKkwuFhZBmPVYtrATSq3jHLVmJg5vfdeiVzA6NKxAgGm2z8AsRrijKK8WRqFYiH6xcWKG5u+FroPQdKa0nGCkPSTH3tvC6fAHTVm7JeXch5QE/LiS9Y575pM2PeIP+k+Fr1ugK0AEvYJAXa5UIIcdszPyI+TwPTtWaQ83X99qGAdmRWLvSYjqevOVr7F/fhO3XKFXRCcHA3EzVYnG7nWiVACYF3H2UgN4PWjStbx/Qhhdi9xAuks=
127 f85de28eae32e7d3064b1a1321309071bbaaa069 0 iQIVAwUAVyZQaiBXgaxoKi1yAQJhCQ//WrRZ55k3VI/OgY+I/HvgFHOC0sbhe207Kedxvy00a3AtXM6wa5E95GNX04QxUfTWUf5ZHDfEgj0/mQywNrH1oJG47iPZSs+qXNLqtgAaXtrih6r4/ruUwFCRFxqK9mkhjG61SKicw3Q7uGva950g6ZUE5BsZ7XJWgoDcJzWKR+AH992G6H//Fhi4zFQAmB34++sm80wV6wMxVKA/qhQzetooTR2x9qrHpvCKMzKllleJe48yzPLJjQoaaVgXCDav0eIePFNw0WvVSldOEp/ADDdTGa65qsC1rO2BB1Cu5+frJ/vUoo0PwIgqgD6p2i41hfIKvkp6130TxmRVxUx+ma8gBYEpPIabV0flLU72gq8lMlGBBSnQ+fcZsfs/Ug0xRN0tzkEScmZFiDxRGk0y7IalXzv6irwOyC2fZCajXGJDzkROQXWMgy9eKkwuFhZBmPVYtrATSq3jHLVmJg5vfdeiVzA6NKxAgGm2z8AsRrijKK8WRqFYiH6xcWKG5u+FroPQdKa0nGCkPSTH3tvC6fAHTVm7JeXch5QE/LiS9Y575pM2PeIP+k+Fr1ugK0AEvYJAXa5UIIcdszPyI+TwPTtWaQ83X99qGAdmRWLvSYjqevOVr7F/fhO3XKFXRCcHA3EzVYnG7nWiVACYF3H2UgN4PWjStbx/Qhhdi9xAuks=
128 a56296f55a5e1038ea5016dace2076b693c28a56 0 iQIVAwUAVyZarCBXgaxoKi1yAQL87g/8D7whM3e08HVGDHHEkVUgqLIfueVy1mx0AkRvelmZmwaocFNGpZTd3AjSwy6qXbRNZFXrWU85JJvQCi3PSo/8bK43kwqLJ4lv+Hv2zVTvz30vbLWTSndH3oVRu38lIA7b5K9J4y50pMCwjKLG9iyp+aQG4RBz76fJMlhXy0gu38A8JZVKEeAnQCbtzxKXBzsC8k0/ku/bEQEoo9D4AAGlVTbl5AsHMp3Z6NWu7kEHAX/52/VKU2I0LxYqRxoL1tjTVGkAQfkOHz1gOhLXUgGSYmA9Fb265AYj9cnGWCfyNonlE0Rrk2kAsrjBTGiLyb8WvK/TZmRo4ZpNukzenS9UuAOKxA22Kf9+oN9kKBu1HnwqusYDH9pto1WInCZKV1al7DMBXbGFcnyTXk2xuiTGhVRG5LzCO2QMByBLXiYl77WqqJnzxK3v5lAc/immJl5qa3ATUlTnVBjAs+6cbsbCoY6sjXCT0ClndA9+iZZ1TjPnmLrSeFh5AoE8WHmnFV6oqGN4caX6wiIW5vO+x5Q2ruSsDrwXosXIYzm+0KYKRq9O+MaTwR44Dvq3/RyeIu/cif/Nc7B8bR5Kf7OiRf2T5u97MYAomwGcQfXqgUfm6y7D3Yg+IdAdAJKitxhRPsqqdxIuteXMvOvwukXNDiWP1zsKoYLI37EcwzvbGLUlZvg=
128 a56296f55a5e1038ea5016dace2076b693c28a56 0 iQIVAwUAVyZarCBXgaxoKi1yAQL87g/8D7whM3e08HVGDHHEkVUgqLIfueVy1mx0AkRvelmZmwaocFNGpZTd3AjSwy6qXbRNZFXrWU85JJvQCi3PSo/8bK43kwqLJ4lv+Hv2zVTvz30vbLWTSndH3oVRu38lIA7b5K9J4y50pMCwjKLG9iyp+aQG4RBz76fJMlhXy0gu38A8JZVKEeAnQCbtzxKXBzsC8k0/ku/bEQEoo9D4AAGlVTbl5AsHMp3Z6NWu7kEHAX/52/VKU2I0LxYqRxoL1tjTVGkAQfkOHz1gOhLXUgGSYmA9Fb265AYj9cnGWCfyNonlE0Rrk2kAsrjBTGiLyb8WvK/TZmRo4ZpNukzenS9UuAOKxA22Kf9+oN9kKBu1HnwqusYDH9pto1WInCZKV1al7DMBXbGFcnyTXk2xuiTGhVRG5LzCO2QMByBLXiYl77WqqJnzxK3v5lAc/immJl5qa3ATUlTnVBjAs+6cbsbCoY6sjXCT0ClndA9+iZZ1TjPnmLrSeFh5AoE8WHmnFV6oqGN4caX6wiIW5vO+x5Q2ruSsDrwXosXIYzm+0KYKRq9O+MaTwR44Dvq3/RyeIu/cif/Nc7B8bR5Kf7OiRf2T5u97MYAomwGcQfXqgUfm6y7D3Yg+IdAdAJKitxhRPsqqdxIuteXMvOvwukXNDiWP1zsKoYLI37EcwzvbGLUlZvg=
129 aaabed77791a75968a12b8c43ad263631a23ee81 0 iQIVAwUAVzpH4CBXgaxoKi1yAQLm5A/9GUYv9CeIepjcdWSBAtNhCBJcqgk2cBcV0XaeQomfxqYWfbW2fze6eE+TrXPKTX1ajycgqquMyo3asQolhHXwasv8+5CQxowjGfyVg7N/kyyjgmJljI+rCi74VfnsEhvG/J4GNr8JLVQmSICfALqQjw7XN8doKthYhwOfIY2vY419613v4oeBQXSsItKC/tfKw9lYvlk4qJKDffJQFyAekgv43ovWqHNkl4LaR6ubtjOsxCnxHfr7OtpX3muM9MLT/obBax5I3EsmiDTQBOjbvI6TcLczs5tVCnTa1opQsPUcEmdA4WpUEiTnLl9lk9le/BIImfYfEP33oVYmubRlKhJYnUiu89ao9L+48FBoqCY88HqbjQI1GO6icfRJN/+NLVeE9wubltbWFETH6e2Q+Ex4+lkul1tQMLPcPt10suMHnEo3/FcOTPt6/DKeMpsYgckHSJq5KzTg632xifyySmb9qkpdGGpY9lRal6FHw3rAhRBqucMgxso4BwC51h04RImtCUQPoA3wpb4BvCHba/thpsUFnHefOvsu3ei4JyHXZK84LPwOj31PcucNFdGDTW6jvKrF1vVUIVS9uMJkJXPu0V4i/oEQSUKifJZivROlpvj1eHy3KeMtjq2kjGyXY2KdzxpT8wX/oYJhCtm1XWMui5f24XBjE6xOcjjm8k4=
129 aaabed77791a75968a12b8c43ad263631a23ee81 0 iQIVAwUAVzpH4CBXgaxoKi1yAQLm5A/9GUYv9CeIepjcdWSBAtNhCBJcqgk2cBcV0XaeQomfxqYWfbW2fze6eE+TrXPKTX1ajycgqquMyo3asQolhHXwasv8+5CQxowjGfyVg7N/kyyjgmJljI+rCi74VfnsEhvG/J4GNr8JLVQmSICfALqQjw7XN8doKthYhwOfIY2vY419613v4oeBQXSsItKC/tfKw9lYvlk4qJKDffJQFyAekgv43ovWqHNkl4LaR6ubtjOsxCnxHfr7OtpX3muM9MLT/obBax5I3EsmiDTQBOjbvI6TcLczs5tVCnTa1opQsPUcEmdA4WpUEiTnLl9lk9le/BIImfYfEP33oVYmubRlKhJYnUiu89ao9L+48FBoqCY88HqbjQI1GO6icfRJN/+NLVeE9wubltbWFETH6e2Q+Ex4+lkul1tQMLPcPt10suMHnEo3/FcOTPt6/DKeMpsYgckHSJq5KzTg632xifyySmb9qkpdGGpY9lRal6FHw3rAhRBqucMgxso4BwC51h04RImtCUQPoA3wpb4BvCHba/thpsUFnHefOvsu3ei4JyHXZK84LPwOj31PcucNFdGDTW6jvKrF1vVUIVS9uMJkJXPu0V4i/oEQSUKifJZivROlpvj1eHy3KeMtjq2kjGyXY2KdzxpT8wX/oYJhCtm1XWMui5f24XBjE6xOcjjm8k4=
130 a9764ab80e11bcf6a37255db7dd079011f767c6c 0 iQIVAwUAV09KHyBXgaxoKi1yAQJBWg/+OywRrqU+zvnL1tHJ95PgatsF7S4ZAHZFR098+oCjUDtKpvnm71o2TKiY4D5cckyD2KNwLWg/qW6V+5+2EYU0Y/ViwPVcngib/ZeJP+Nr44TK3YZMRmfFuUEEzA7sZ2r2Gm8eswv//W79I0hXJeFd/o6FgLnn7AbOjcOn3IhWdGAP6jUHv9zyJigQv6K9wgyvAnK1RQE+2CgMcoyeqao/zs23IPXI6XUHOwfrQ7XrQ83+ciMqN7XNRx+TKsUQoYeUew4AanoDSMPAQ4kIudsP5tOgKeLRPmHX9zg6Y5S1nTpLRNdyAxuNuyZtkQxDYcG5Hft/SIx27tZUo3gywHL2U+9RYD2nvXqaWzT3sYB2sPBOiq7kjHRgvothkXemAFsbq2nKFrN0PRua9WG4l3ny0xYmDFPlJ/s0E9XhmQaqy+uXtVbA2XdLEvE6pQ0YWbHEKMniW26w6LJkx4IV6RX/7Kpq7byw/bW65tu/BzgISKau5FYLY4CqZJH7f8QBg3XWpzB91AR494tdsD+ugM45wrY/6awGQx9CY5SAzGqTyFuSFQxgB2rBurb01seZPf8nqG8V13UYXfX/O3/WMOBMr7U/RVqmAA0ZMYOyEwfVUmHqrFjkxpXX+JdNKRiA1GJp5sdRpCxSeXdQ/Ni6AAGZV2IyRb4G4Y++1vP4yPBalas=
130 a9764ab80e11bcf6a37255db7dd079011f767c6c 0 iQIVAwUAV09KHyBXgaxoKi1yAQJBWg/+OywRrqU+zvnL1tHJ95PgatsF7S4ZAHZFR098+oCjUDtKpvnm71o2TKiY4D5cckyD2KNwLWg/qW6V+5+2EYU0Y/ViwPVcngib/ZeJP+Nr44TK3YZMRmfFuUEEzA7sZ2r2Gm8eswv//W79I0hXJeFd/o6FgLnn7AbOjcOn3IhWdGAP6jUHv9zyJigQv6K9wgyvAnK1RQE+2CgMcoyeqao/zs23IPXI6XUHOwfrQ7XrQ83+ciMqN7XNRx+TKsUQoYeUew4AanoDSMPAQ4kIudsP5tOgKeLRPmHX9zg6Y5S1nTpLRNdyAxuNuyZtkQxDYcG5Hft/SIx27tZUo3gywHL2U+9RYD2nvXqaWzT3sYB2sPBOiq7kjHRgvothkXemAFsbq2nKFrN0PRua9WG4l3ny0xYmDFPlJ/s0E9XhmQaqy+uXtVbA2XdLEvE6pQ0YWbHEKMniW26w6LJkx4IV6RX/7Kpq7byw/bW65tu/BzgISKau5FYLY4CqZJH7f8QBg3XWpzB91AR494tdsD+ugM45wrY/6awGQx9CY5SAzGqTyFuSFQxgB2rBurb01seZPf8nqG8V13UYXfX/O3/WMOBMr7U/RVqmAA0ZMYOyEwfVUmHqrFjkxpXX+JdNKRiA1GJp5sdRpCxSeXdQ/Ni6AAGZV2IyRb4G4Y++1vP4yPBalas=
131 26a5d605b8683a292bb89aea11f37a81b06ac016 0 iQIVAwUAV3bOsSBXgaxoKi1yAQLiDg//fxmcNpTUedsXqEwNdGFJsJ2E25OANgyv1saZHNfbYFWXIR8g4nyjNaj2SjtXF0wzOq5aHlMWXjMZPOT6pQBdTnOYDdgv+O8DGpgHs5x/f+uuxtpVkdxR6uRP0/ImlTEtDix8VQiN3nTu5A0N3C7E2y+D1JIIyTp6vyjzxvGQTY0MD/qgB55Dn6khx8c3phDtMkzmVEwL4ItJxVRVNw1m+2FOXHu++hJEruJdeMV0CKOV6LVbXHho+yt3jQDKhlIgJ65EPLKrf+yRalQtSWpu7y/vUMcEUde9XeQ5x05ebCiI4MkJ0ULQro/Bdx9vBHkAstUC7D+L5y45ZnhHjOwxz9c3GQMZQt1HuyORqbBhf9hvOkUQ2GhlDHc5U04nBe0VhEoCw9ra54n+AgUyqWr4CWimSW6pMTdquCzAAbcJWgdNMwDHrMalCYHhJksKFARKq3uSTR1Noz7sOCSIEQvOozawKSQfOwGxn/5bNepKh4uIRelC1uEDoqculqCLgAruzcMNIMndNVYaJ09IohJzA9jVApa+SZVPAeREg71lnS3d8jaWh1Lu5JFlAAKQeKGVJmNm40Y3HBjtHQDrI67TT59oDAhjo420Wf9VFCaj2k0weYBLWSeJhfUZ5x3PVpAHUvP/rnHPwNYyY0wVoQEvM/bnQdcpICmKhqcK+vKjDrM=
131 26a5d605b8683a292bb89aea11f37a81b06ac016 0 iQIVAwUAV3bOsSBXgaxoKi1yAQLiDg//fxmcNpTUedsXqEwNdGFJsJ2E25OANgyv1saZHNfbYFWXIR8g4nyjNaj2SjtXF0wzOq5aHlMWXjMZPOT6pQBdTnOYDdgv+O8DGpgHs5x/f+uuxtpVkdxR6uRP0/ImlTEtDix8VQiN3nTu5A0N3C7E2y+D1JIIyTp6vyjzxvGQTY0MD/qgB55Dn6khx8c3phDtMkzmVEwL4ItJxVRVNw1m+2FOXHu++hJEruJdeMV0CKOV6LVbXHho+yt3jQDKhlIgJ65EPLKrf+yRalQtSWpu7y/vUMcEUde9XeQ5x05ebCiI4MkJ0ULQro/Bdx9vBHkAstUC7D+L5y45ZnhHjOwxz9c3GQMZQt1HuyORqbBhf9hvOkUQ2GhlDHc5U04nBe0VhEoCw9ra54n+AgUyqWr4CWimSW6pMTdquCzAAbcJWgdNMwDHrMalCYHhJksKFARKq3uSTR1Noz7sOCSIEQvOozawKSQfOwGxn/5bNepKh4uIRelC1uEDoqculqCLgAruzcMNIMndNVYaJ09IohJzA9jVApa+SZVPAeREg71lnS3d8jaWh1Lu5JFlAAKQeKGVJmNm40Y3HBjtHQDrI67TT59oDAhjo420Wf9VFCaj2k0weYBLWSeJhfUZ5x3PVpAHUvP/rnHPwNYyY0wVoQEvM/bnQdcpICmKhqcK+vKjDrM=
132 519bb4f9d3a47a6e83c2b414d58811ed38f503c2 0 iQIVAwUAV42tNyBXgaxoKi1yAQI/Iw//V0NtxpVD4sClotAwffBVW42Uv+SG+07CJoOuFYnmHZv/plOzXuuJlmm95L00/qyRCCTUyAGxK/eP5cAKP2V99ln6rNhh8gpgvmZlnYjU3gqFv8tCQ+fkwgRiWmgKjRL6/bK9FY5cO7ATLVu3kCkFd8CEgzlAaUqBfkNFxZxLDLvKqRlhXxVXhKjvkKg5DZ6eJqRQY7w3UqqR+sF1rMLtVyt490Wqv7YQKwcvY7MEKTyH4twGLx/RhBpBi+GccVKvWC011ffjSjxqAfQqrrSVt0Ld1Khj2/p1bDDYpTgtdDgCzclSXWEQpmSdFRBF5wYs/pDMUreI/E6mlWkB4hfZZk1NBRPRWYikXwnhU3ziubCGesZDyBYLrK1vT+tf6giseo22YQmDnOftbS999Pcn04cyCafeFuOjkubYaINB25T20GS5Wb4a0nHPRAOOVxzk/m/arwYgF0ZZZDDvJ48TRMDf3XOc1jc5qZ7AN/OQKbvh2B08vObnnPm3lmBY1qOnhwzJxpNiq+Z/ypokGXQkGBfKUo7rWHJy5iXLb3Biv9AhxY9d5pSTjBmTAYJEic3q03ztzlnfMyi+C13+YxFAbSSNGBP8Hejkkz0NvmB1TBuCKpnZA8spxY5rhZ/zMx+cCw8hQvWHHDUURps7SQvZEfrJSCGJFPDHL3vbfK+LNwI=
132 519bb4f9d3a47a6e83c2b414d58811ed38f503c2 0 iQIVAwUAV42tNyBXgaxoKi1yAQI/Iw//V0NtxpVD4sClotAwffBVW42Uv+SG+07CJoOuFYnmHZv/plOzXuuJlmm95L00/qyRCCTUyAGxK/eP5cAKP2V99ln6rNhh8gpgvmZlnYjU3gqFv8tCQ+fkwgRiWmgKjRL6/bK9FY5cO7ATLVu3kCkFd8CEgzlAaUqBfkNFxZxLDLvKqRlhXxVXhKjvkKg5DZ6eJqRQY7w3UqqR+sF1rMLtVyt490Wqv7YQKwcvY7MEKTyH4twGLx/RhBpBi+GccVKvWC011ffjSjxqAfQqrrSVt0Ld1Khj2/p1bDDYpTgtdDgCzclSXWEQpmSdFRBF5wYs/pDMUreI/E6mlWkB4hfZZk1NBRPRWYikXwnhU3ziubCGesZDyBYLrK1vT+tf6giseo22YQmDnOftbS999Pcn04cyCafeFuOjkubYaINB25T20GS5Wb4a0nHPRAOOVxzk/m/arwYgF0ZZZDDvJ48TRMDf3XOc1jc5qZ7AN/OQKbvh2B08vObnnPm3lmBY1qOnhwzJxpNiq+Z/ypokGXQkGBfKUo7rWHJy5iXLb3Biv9AhxY9d5pSTjBmTAYJEic3q03ztzlnfMyi+C13+YxFAbSSNGBP8Hejkkz0NvmB1TBuCKpnZA8spxY5rhZ/zMx+cCw8hQvWHHDUURps7SQvZEfrJSCGJFPDHL3vbfK+LNwI=
133 299546f84e68dbb9bd026f0f3a974ce4bdb93686 0 iQIcBAABCAAGBQJXn3rFAAoJELnJ3IJKpb3VmZoQAK0cdOfi/OURglnN0vYYGwdvSXTPpZauPEYEpwML3dW1j6HRnl5L+H8D8vlYzahK95X4+NNBhqtyyB6wmIVI0NkYfXfd6ACntJE/EnTdLIHIP2NAAoVsggIjiNr26ubRegaD5ya63Ofxz+Yq5iRsUUfHet7o+CyFhExyzdu+Vcz1/E9GztxNfTDVpC/mf+RMLwQTfHOhoTVbaamLCmGAIjw39w72X+vRMJoYNF44te6PvsfI67+6uuC0+9DjMnp5eL/hquSQ1qfks71rnWwxuiPcUDZloIueowVmt0z0sO4loSP1nZ5IP/6ZOoAzSjspqsxeay9sKP0kzSYLGsmCi29otyVSnXiKtyMCW5z5iM6k8XQcMi5mWy9RcpqlNYD7RUTn3g0+a8u7F6UEtske3/qoweJLPhtTmBNOfDNw4JXwOBSZea0QnIIjCeCc4ZGqfojPpbvcA4rkRpxI23YoMrT2v/kp4wgwrqK9fi8ctt8WbXpmGoAQDXWj2bWcuzj94HsAhLduFKv6sxoDz871hqjmjjnjQSU7TSNNnVzdzwqYkMB+BvhcNYxk6lcx3Aif3AayGdrWDubtU/ZRNoLzBwe6gm0udRMXBj4D/60GD6TIkYeL7HjJwfBb6Bf7qvQ6y7g0zbYG9uwBmMeduU7XchErGqQGSEyyJH3DG9OLaFOj
133 299546f84e68dbb9bd026f0f3a974ce4bdb93686 0 iQIcBAABCAAGBQJXn3rFAAoJELnJ3IJKpb3VmZoQAK0cdOfi/OURglnN0vYYGwdvSXTPpZauPEYEpwML3dW1j6HRnl5L+H8D8vlYzahK95X4+NNBhqtyyB6wmIVI0NkYfXfd6ACntJE/EnTdLIHIP2NAAoVsggIjiNr26ubRegaD5ya63Ofxz+Yq5iRsUUfHet7o+CyFhExyzdu+Vcz1/E9GztxNfTDVpC/mf+RMLwQTfHOhoTVbaamLCmGAIjw39w72X+vRMJoYNF44te6PvsfI67+6uuC0+9DjMnp5eL/hquSQ1qfks71rnWwxuiPcUDZloIueowVmt0z0sO4loSP1nZ5IP/6ZOoAzSjspqsxeay9sKP0kzSYLGsmCi29otyVSnXiKtyMCW5z5iM6k8XQcMi5mWy9RcpqlNYD7RUTn3g0+a8u7F6UEtske3/qoweJLPhtTmBNOfDNw4JXwOBSZea0QnIIjCeCc4ZGqfojPpbvcA4rkRpxI23YoMrT2v/kp4wgwrqK9fi8ctt8WbXpmGoAQDXWj2bWcuzj94HsAhLduFKv6sxoDz871hqjmjjnjQSU7TSNNnVzdzwqYkMB+BvhcNYxk6lcx3Aif3AayGdrWDubtU/ZRNoLzBwe6gm0udRMXBj4D/60GD6TIkYeL7HjJwfBb6Bf7qvQ6y7g0zbYG9uwBmMeduU7XchErGqQGSEyyJH3DG9OLaFOj
134 ccd436f7db6d5d7b9af89715179b911d031d44f1 0 iQIVAwUAV8h7F0emf/qjRqrOAQjmdhAAgYhom8fzL/YHeVLddm71ZB+pKDviKASKGSrBHY4D5Szrh/pYTedmG9IptYue5vzXpspHAaGvZN5xkwrz1/5nmnCsLA8DFaYT9qCkize6EYzxSBtA/W1S9Mv5tObinr1EX9rCSyI4HEJYE8i1IQM5h07SqUsMKDoasd4e29t6gRWg5pfOYq1kc2MTck35W9ff1Fii8S28dqbO3cLU6g5K0pT0JLCZIq7hyTNQdxHAYfebxkVl7PZrZR383IrnyotXVKFFc44qinv94T50uR4yUNYPQ8Gu0TgoGQQjBjk1Lrxot2xpgPQAy8vx+EOJgpg/yNZnYkmJZMxjDkTGVrwvXtOXZzmy2jti7PniET9hUBCU7aNHnoJJLzIf+Vb1CIRP0ypJl8GYCZx6HIYwOQH6EtcaeUqq3r+WXWv74ijIE7OApotmutM9buTvdOLdZddBzFPIjykc6cXO+W4E0kl6u9/OHtaZ3Nynh0ejBRafRWAVw2yU3T9SgQyICsmYWJCThkj14WqCJr2b7jfGlg9MkQOUG6/3f4xz2R3SgyUD8KiGsq/vdBE53zh0YA9gppLoum6AY+z61G1NhVGlrtps90txZBehuARUUz2dJC0pBMRy8XFwXMewDSIe6ATg25pHZsxHfhcalBpJncBl8pORs7oQl+GKBVxlnV4jm1pCzLU=
134 ccd436f7db6d5d7b9af89715179b911d031d44f1 0 iQIVAwUAV8h7F0emf/qjRqrOAQjmdhAAgYhom8fzL/YHeVLddm71ZB+pKDviKASKGSrBHY4D5Szrh/pYTedmG9IptYue5vzXpspHAaGvZN5xkwrz1/5nmnCsLA8DFaYT9qCkize6EYzxSBtA/W1S9Mv5tObinr1EX9rCSyI4HEJYE8i1IQM5h07SqUsMKDoasd4e29t6gRWg5pfOYq1kc2MTck35W9ff1Fii8S28dqbO3cLU6g5K0pT0JLCZIq7hyTNQdxHAYfebxkVl7PZrZR383IrnyotXVKFFc44qinv94T50uR4yUNYPQ8Gu0TgoGQQjBjk1Lrxot2xpgPQAy8vx+EOJgpg/yNZnYkmJZMxjDkTGVrwvXtOXZzmy2jti7PniET9hUBCU7aNHnoJJLzIf+Vb1CIRP0ypJl8GYCZx6HIYwOQH6EtcaeUqq3r+WXWv74ijIE7OApotmutM9buTvdOLdZddBzFPIjykc6cXO+W4E0kl6u9/OHtaZ3Nynh0ejBRafRWAVw2yU3T9SgQyICsmYWJCThkj14WqCJr2b7jfGlg9MkQOUG6/3f4xz2R3SgyUD8KiGsq/vdBE53zh0YA9gppLoum6AY+z61G1NhVGlrtps90txZBehuARUUz2dJC0pBMRy8XFwXMewDSIe6ATg25pHZsxHfhcalBpJncBl8pORs7oQl+GKBVxlnV4jm1pCzLU=
135 149433e68974eb5c63ccb03f794d8b57339a80c4 0 iQIcBAABAgAGBQJX8AfCAAoJELnJ3IJKpb3VnNAP/3umS8tohcZTr4m6DJm9u4XGr2m3FWQmjTEfimGpsOuBC8oCgsq0eAlORYcV68zDax+vQHQu3pqfPXaX+y4ZFDuz0ForNRiPJn+Q+tj1+NrOT1e8h4gH0nSK4rDxEGaa6x01fyC/xQMqN6iNfzbLLB7+WadZlyBRbHaUeZFDlPxPDf1rjDpu1vqwtOrVzSxMasRGEceiUegwsFdFMAefCq0ya/pKe9oV+GgGfR4qNrP7BfpOBcN/Po/ctkFCbLOhHbu6M7HpBSiD57BUy5lfhQQtSjzCKEVTyrWEH0ApjjXKuJzLSyq7xsHKQSOPMgGQprGehyzdCETlZOdauGrC0t9vBCr7kXEhXtycqxBC03vknA2eNeV610VX+HgO9VpCVZWHtENiArhALCcpoEsJvT29xCBYpSii/wnTpYJFT9yW8tjQCxH0zrmEZJvO1/nMINEBQFScB/nzUELn9asnghNf6vMpSGy0fSM27j87VAXCzJ5lqa6WCL/RrKgvYflow/m5AzUfMQhpqpH1vmh4ba1zZ4123lgnW4pNZDV9kmwXrEagGbWe1rnmsMzHugsECiYQyIngjWzHfpHgyEr49Uc5bMM1MlTypeHYYL4kV1jJ8Ou0SC4aV+49p8Onmb2NlVY7JKV7hqDCuZPI164YXMxhPNst4XK0/ENhoOE+8iB6
135 149433e68974eb5c63ccb03f794d8b57339a80c4 0 iQIcBAABAgAGBQJX8AfCAAoJELnJ3IJKpb3VnNAP/3umS8tohcZTr4m6DJm9u4XGr2m3FWQmjTEfimGpsOuBC8oCgsq0eAlORYcV68zDax+vQHQu3pqfPXaX+y4ZFDuz0ForNRiPJn+Q+tj1+NrOT1e8h4gH0nSK4rDxEGaa6x01fyC/xQMqN6iNfzbLLB7+WadZlyBRbHaUeZFDlPxPDf1rjDpu1vqwtOrVzSxMasRGEceiUegwsFdFMAefCq0ya/pKe9oV+GgGfR4qNrP7BfpOBcN/Po/ctkFCbLOhHbu6M7HpBSiD57BUy5lfhQQtSjzCKEVTyrWEH0ApjjXKuJzLSyq7xsHKQSOPMgGQprGehyzdCETlZOdauGrC0t9vBCr7kXEhXtycqxBC03vknA2eNeV610VX+HgO9VpCVZWHtENiArhALCcpoEsJvT29xCBYpSii/wnTpYJFT9yW8tjQCxH0zrmEZJvO1/nMINEBQFScB/nzUELn9asnghNf6vMpSGy0fSM27j87VAXCzJ5lqa6WCL/RrKgvYflow/m5AzUfMQhpqpH1vmh4ba1zZ4123lgnW4pNZDV9kmwXrEagGbWe1rnmsMzHugsECiYQyIngjWzHfpHgyEr49Uc5bMM1MlTypeHYYL4kV1jJ8Ou0SC4aV+49p8Onmb2NlVY7JKV7hqDCuZPI164YXMxhPNst4XK0/ENhoOE+8iB6
136 438173c415874f6ac653efc1099dec9c9150e90f 0 iQIVAwUAWAZ3okemf/qjRqrOAQj89xAAw/6QZ07yqvH+aZHeGQfgJ/X1Nze/hSMzkqbwGkuUOWD5ztN8+c39EXCn8JlqyLUPD7uGzhTV0299k5fGRihLIseXr0hy/cvVW16uqfeKJ/4/qL9zLS3rwSAgWbaHd1s6UQZVfGCb8V6oC1dkJxfrE9h6kugBqV97wStIRxmCpMDjsFv/zdNwsv6eEdxbiMilLn2/IbWXFOVKJzzv9iEY5Pu5McFR+nnrMyUZQhyGtVPLSkoEPsOysorfCZaVLJ6MnVaJunp9XEv94Pqx9+k+shsQvJHWkc0Nnb6uDHZYkLR5v2AbFsbJ9jDHsdr9A7qeQTiZay7PGI0uPoIrkmLya3cYbU1ADhwloAeQ/3gZLaJaKEjrXcFSsz7AZ9yq74rTwiPulF8uqZxJUodk2m/zy83HBrxxp/vgxWJ5JP2WXPtB8qKY+05umAt4rQS+fd2H/xOu2V2d5Mq1WmgknLBLC0ItaNaf91sSHtgEy22GtcvWQE7S6VWU1PoSYmOLITdJKAsmb7Eq+yKDW9nt0lOpUu2wUhBGctlgXgcWOmJP6gL6edIg66czAkVBp/fpKNl8Z/A0hhpuH7nW7GW/mzLVQnc+JW4wqUVkwlur3NRfvSt5ZyTY/SaR++nRf62h7PHIjU+f0kWQRdCcEQ0X38b8iAjeXcsOW8NCOPpm0zcz3i8=
136 438173c415874f6ac653efc1099dec9c9150e90f 0 iQIVAwUAWAZ3okemf/qjRqrOAQj89xAAw/6QZ07yqvH+aZHeGQfgJ/X1Nze/hSMzkqbwGkuUOWD5ztN8+c39EXCn8JlqyLUPD7uGzhTV0299k5fGRihLIseXr0hy/cvVW16uqfeKJ/4/qL9zLS3rwSAgWbaHd1s6UQZVfGCb8V6oC1dkJxfrE9h6kugBqV97wStIRxmCpMDjsFv/zdNwsv6eEdxbiMilLn2/IbWXFOVKJzzv9iEY5Pu5McFR+nnrMyUZQhyGtVPLSkoEPsOysorfCZaVLJ6MnVaJunp9XEv94Pqx9+k+shsQvJHWkc0Nnb6uDHZYkLR5v2AbFsbJ9jDHsdr9A7qeQTiZay7PGI0uPoIrkmLya3cYbU1ADhwloAeQ/3gZLaJaKEjrXcFSsz7AZ9yq74rTwiPulF8uqZxJUodk2m/zy83HBrxxp/vgxWJ5JP2WXPtB8qKY+05umAt4rQS+fd2H/xOu2V2d5Mq1WmgknLBLC0ItaNaf91sSHtgEy22GtcvWQE7S6VWU1PoSYmOLITdJKAsmb7Eq+yKDW9nt0lOpUu2wUhBGctlgXgcWOmJP6gL6edIg66czAkVBp/fpKNl8Z/A0hhpuH7nW7GW/mzLVQnc+JW4wqUVkwlur3NRfvSt5ZyTY/SaR++nRf62h7PHIjU+f0kWQRdCcEQ0X38b8iAjeXcsOW8NCOPpm0zcz3i8=
137 eab27446995210c334c3d06f1a659e3b9b5da769 0 iQIcBAABCAAGBQJYGNsXAAoJELnJ3IJKpb3Vf30QAK/dq5vEHEkufLGiYxxkvIyiRaswS+8jamXeHMQrdK8CuokcQYhEv9xiUI6FMIoX4Zc0xfoFCBc+X4qE+Ed9SFYWgQkDs/roJq1C1mTYA+KANMqJkDt00QZq536snFQvjCXAA5fwR/DpgGOOuGMRfvbjh7x8mPyVoPr4HDQCGFXnTYdn193HpTOqUsipzIV5OJqQ9p0sfJjwKP4ZfD0tqqdjTkNwMyJuwuRaReXFvGGCjH2PqkZE/FwQG0NJJjt0xaMUmv5U5tXHC9tEVobVV/qEslqfbH2v1YPF5d8Jmdn7F76FU5J0nTd+3rIVjYGYSt01cR6wtGnzvr/7kw9kbChw4wYhXxnmIALSd48FpA1qWjlPcAdHfUUwObxOxfqmlnBGtAQFK+p5VXCsxDZEIT9MSxscfCjyDQZpkY5S5B3PFIRg6V9bdl5a4rEt27aucuKTHj1Ok2vip4WfaIKk28YMjjzuOQRbr6Pp7mJcCC1/ERHUJdLsaQP+dy18z6XbDjX3O2JDRNYbCBexQyV/Kfrt5EOS5fXiByQUHv+PyR+9Ju6QWkkcFBfgsxq25kFl+eos4V9lxPOY5jDpw2BWu9TyHtTWkjL/YxDUGwUO9WA/WzrcT4skr9FYrFV/oEgi8MkwydC0cFICDfd6tr9upqkkr1W025Im1UBXXJ89bTVj
137 eab27446995210c334c3d06f1a659e3b9b5da769 0 iQIcBAABCAAGBQJYGNsXAAoJELnJ3IJKpb3Vf30QAK/dq5vEHEkufLGiYxxkvIyiRaswS+8jamXeHMQrdK8CuokcQYhEv9xiUI6FMIoX4Zc0xfoFCBc+X4qE+Ed9SFYWgQkDs/roJq1C1mTYA+KANMqJkDt00QZq536snFQvjCXAA5fwR/DpgGOOuGMRfvbjh7x8mPyVoPr4HDQCGFXnTYdn193HpTOqUsipzIV5OJqQ9p0sfJjwKP4ZfD0tqqdjTkNwMyJuwuRaReXFvGGCjH2PqkZE/FwQG0NJJjt0xaMUmv5U5tXHC9tEVobVV/qEslqfbH2v1YPF5d8Jmdn7F76FU5J0nTd+3rIVjYGYSt01cR6wtGnzvr/7kw9kbChw4wYhXxnmIALSd48FpA1qWjlPcAdHfUUwObxOxfqmlnBGtAQFK+p5VXCsxDZEIT9MSxscfCjyDQZpkY5S5B3PFIRg6V9bdl5a4rEt27aucuKTHj1Ok2vip4WfaIKk28YMjjzuOQRbr6Pp7mJcCC1/ERHUJdLsaQP+dy18z6XbDjX3O2JDRNYbCBexQyV/Kfrt5EOS5fXiByQUHv+PyR+9Ju6QWkkcFBfgsxq25kFl+eos4V9lxPOY5jDpw2BWu9TyHtTWkjL/YxDUGwUO9WA/WzrcT4skr9FYrFV/oEgi8MkwydC0cFICDfd6tr9upqkkr1W025Im1UBXXJ89bTVj
138 b3b1ae98f6a0e14c1e1ba806a6c18e193b6dae5c 0 iQIVAwUAWECEaEemf/qjRqrOAQjuZw/+IWJKnKOsaUMcB9ly3Fo/eskqDL6A0j69IXTJDeBDGMoyGbQU/gZyX2yc6Sw3EhwTSCXu5vKpzg3a6e8MNrC1iHqli4wJ/jPY7XtmiqTYDixdsBLNk46VfOi73ooFe08wVDSNB65xpZsrtPDSioNmQ2kSJwSHb71UlauS4xGkM74vuDpWvX5OZRSfBqMh6NjG5RwBBnS8mzA0SW2dCI2jSc5SCGIzIZpzM0xUN21xzq0YQbrk9qEsmi7ks0eowdhUjeET2wSWwhOK4jS4IfMyRO7KueUB05yHs4mChj9kNFNWtSzXKwKBQbZzwO/1Y7IJjU+AsbWkiUu+6ipqBPQWzS28gCwGOrv5BcIJS+tzsvLUKWgcixyfy5UAqJ32gCdzKC54FUpT2zL6Ad0vXGM6WkpZA7yworN4RCFPexXbi0x2GSTLG8PyIoZ4Iwgtj5NtsEDHrz0380FxgnKUIC3ny2SVuPlyD+9wepD3QYcxdRk1BIzcFT9ZxNlgil3IXRVPwVejvQ/zr6/ILdhBnZ8ojjvVCy3b86B1OhZj/ZByYo5QaykVqWl0V9vJOZlZfvOpm2HiDhm/2uNrVWxG4O6EwhnekAdaJYmeLq1YbhIfGA6KVOaB9Yi5A5BxK9QGXBZ6sLj+dIUD3QR47r9yAqVQE8Gr/Oh6oQXBQqOQv7WzBBs=
138 b3b1ae98f6a0e14c1e1ba806a6c18e193b6dae5c 0 iQIVAwUAWECEaEemf/qjRqrOAQjuZw/+IWJKnKOsaUMcB9ly3Fo/eskqDL6A0j69IXTJDeBDGMoyGbQU/gZyX2yc6Sw3EhwTSCXu5vKpzg3a6e8MNrC1iHqli4wJ/jPY7XtmiqTYDixdsBLNk46VfOi73ooFe08wVDSNB65xpZsrtPDSioNmQ2kSJwSHb71UlauS4xGkM74vuDpWvX5OZRSfBqMh6NjG5RwBBnS8mzA0SW2dCI2jSc5SCGIzIZpzM0xUN21xzq0YQbrk9qEsmi7ks0eowdhUjeET2wSWwhOK4jS4IfMyRO7KueUB05yHs4mChj9kNFNWtSzXKwKBQbZzwO/1Y7IJjU+AsbWkiUu+6ipqBPQWzS28gCwGOrv5BcIJS+tzsvLUKWgcixyfy5UAqJ32gCdzKC54FUpT2zL6Ad0vXGM6WkpZA7yworN4RCFPexXbi0x2GSTLG8PyIoZ4Iwgtj5NtsEDHrz0380FxgnKUIC3ny2SVuPlyD+9wepD3QYcxdRk1BIzcFT9ZxNlgil3IXRVPwVejvQ/zr6/ILdhBnZ8ojjvVCy3b86B1OhZj/ZByYo5QaykVqWl0V9vJOZlZfvOpm2HiDhm/2uNrVWxG4O6EwhnekAdaJYmeLq1YbhIfGA6KVOaB9Yi5A5BxK9QGXBZ6sLj+dIUD3QR47r9yAqVQE8Gr/Oh6oQXBQqOQv7WzBBs=
139 e69874dc1f4e142746ff3df91e678a09c6fc208c 0 iQIVAwUAWG0oGUemf/qjRqrOAQh3uhAAu4TN7jkkgH7Hxn8S1cB6Ru0x8MQutzzzpjShhsE/G7nzCxsZ5eWdJ5ItwXmKhunb7T0og54CGcTxfmdPtCI7AhhHh9/TM2Hv1EBcsXCiwjG8E+P6X1UJkijgTGjNWuCvEDOsQAvgywslECBNnXp2QA5I5UdCMeqDdTAb8ujvbD8I4pxUx1xXKY18DgQGJh13mRlfkEVnPxUi2n8emnwPLjbVVkVISkMFUkaOl8a4fOeZC1xzDpoQocoH2Q8DYa9RCPPSHHSYPNMWGCdNGN2CoAurcHWWvc7jNU28/tBhTazfFv8LYh63lLQ8SIIPZHJAOxo45ufMspzUfNgoD6y3vlF5aW7DpdxwYHnueh7S1Fxgtd9cOnxmxQsgiF4LK0a+VXOi/Tli/fivZHDRCGHJvJgsMQm7pzkay9sGohes6jAnsOv2E8DwFC71FO/btrAp07IRFxH9WhUeMsXLMS9oBlubMxMM58M+xzSKApK6bz2MkLsx9cewmfmfbJnRIK1xDv+J+77pWWNGlxCCjl1WU+aA3M7G8HzwAqjL75ASOWtBrJlFXvlLgzobwwetg6cm44Rv1P39i3rDySZvi4BDlOQHWFupgMKiXnZ1PeL7eBDs/aawrE0V2ysNkf9An+XJZkos2JSLPWcoNigfXNUu5c1AqsERvHA246XJzqvCEK8=
139 e69874dc1f4e142746ff3df91e678a09c6fc208c 0 iQIVAwUAWG0oGUemf/qjRqrOAQh3uhAAu4TN7jkkgH7Hxn8S1cB6Ru0x8MQutzzzpjShhsE/G7nzCxsZ5eWdJ5ItwXmKhunb7T0og54CGcTxfmdPtCI7AhhHh9/TM2Hv1EBcsXCiwjG8E+P6X1UJkijgTGjNWuCvEDOsQAvgywslECBNnXp2QA5I5UdCMeqDdTAb8ujvbD8I4pxUx1xXKY18DgQGJh13mRlfkEVnPxUi2n8emnwPLjbVVkVISkMFUkaOl8a4fOeZC1xzDpoQocoH2Q8DYa9RCPPSHHSYPNMWGCdNGN2CoAurcHWWvc7jNU28/tBhTazfFv8LYh63lLQ8SIIPZHJAOxo45ufMspzUfNgoD6y3vlF5aW7DpdxwYHnueh7S1Fxgtd9cOnxmxQsgiF4LK0a+VXOi/Tli/fivZHDRCGHJvJgsMQm7pzkay9sGohes6jAnsOv2E8DwFC71FO/btrAp07IRFxH9WhUeMsXLMS9oBlubMxMM58M+xzSKApK6bz2MkLsx9cewmfmfbJnRIK1xDv+J+77pWWNGlxCCjl1WU+aA3M7G8HzwAqjL75ASOWtBrJlFXvlLgzobwwetg6cm44Rv1P39i3rDySZvi4BDlOQHWFupgMKiXnZ1PeL7eBDs/aawrE0V2ysNkf9An+XJZkos2JSLPWcoNigfXNUu5c1AqsERvHA246XJzqvCEK8=
140 a1dd2c0c479e0550040542e392e87bc91262517e 0 iQIcBAABCAAGBQJYgBBEAAoJELnJ3IJKpb3VJosP/10rr3onsVbL8E+ri1Q0TJc8uhqIsBVyD/vS1MJtbxRaAdIV92o13YOent0o5ASFF/0yzVKlOWPQRjsYYbYY967k1TruDaWxJAnpeFgMni2Afl/qyWrW4AY2xegZNZCfMmwJA+uSJDdAn+jPV40XbuCZ+OgyZo5S05dfclHFxdc8rPKeUsJtvs5PMmCL3iQl1sulp1ASjuhRtFWZgSFsC6rb2Y7evD66ikL93+0/BPEB4SVX17vB/XEzdmh4ntyt4+d1XAznLHS33IU8UHbTkUmLy+82WnNH7HBB2V7gO47m/HhvaYjEfeW0bqMzN3aOUf30Vy/wB4HHsvkBGDgL5PYVHRRovGcAuCmnYbOkawqbRewW5oDs7UT3HbShNpxCxfsYpo7deHr11zWA3ooWCSlIRRREU4BfwVmn+Ds1hT5HM28Q6zr6GQZegDUbiT9i1zU0EpyfTpH7gc6NTVQrO1z1p70NBnQMqXcHjWJwjSwLER2Qify9MjrGXTL6ofD5zVZKobeRmq94mf3lDq26H7coraM9X5h9xa49VgAcRHzn/WQ6wcFCKDQr6FT67hTUOlF7Jriv8/5h/ziSZr10fCObKeKWN8Skur29VIAHHY4NuUqbM55WohD+jZ2O3d4tze1eWm5MDgWD8RlrfYhQ+cLOwH65AOtts0LNZwlvJuC7
140 a1dd2c0c479e0550040542e392e87bc91262517e 0 iQIcBAABCAAGBQJYgBBEAAoJELnJ3IJKpb3VJosP/10rr3onsVbL8E+ri1Q0TJc8uhqIsBVyD/vS1MJtbxRaAdIV92o13YOent0o5ASFF/0yzVKlOWPQRjsYYbYY967k1TruDaWxJAnpeFgMni2Afl/qyWrW4AY2xegZNZCfMmwJA+uSJDdAn+jPV40XbuCZ+OgyZo5S05dfclHFxdc8rPKeUsJtvs5PMmCL3iQl1sulp1ASjuhRtFWZgSFsC6rb2Y7evD66ikL93+0/BPEB4SVX17vB/XEzdmh4ntyt4+d1XAznLHS33IU8UHbTkUmLy+82WnNH7HBB2V7gO47m/HhvaYjEfeW0bqMzN3aOUf30Vy/wB4HHsvkBGDgL5PYVHRRovGcAuCmnYbOkawqbRewW5oDs7UT3HbShNpxCxfsYpo7deHr11zWA3ooWCSlIRRREU4BfwVmn+Ds1hT5HM28Q6zr6GQZegDUbiT9i1zU0EpyfTpH7gc6NTVQrO1z1p70NBnQMqXcHjWJwjSwLER2Qify9MjrGXTL6ofD5zVZKobeRmq94mf3lDq26H7coraM9X5h9xa49VgAcRHzn/WQ6wcFCKDQr6FT67hTUOlF7Jriv8/5h/ziSZr10fCObKeKWN8Skur29VIAHHY4NuUqbM55WohD+jZ2O3d4tze1eWm5MDgWD8RlrfYhQ+cLOwH65AOtts0LNZwlvJuC7
141 e1526da1e6d84e03146151c9b6e6950fe9a83d7d 0 iQIVAwUAWJIKpUemf/qjRqrOAQjjThAAvl1K/GZBrkanwEPXomewHkWKTEy1s5d5oWmPPGrSb9G4LM/3/abSbQ7fnzkS6IWi4Ao0za68w/MohaVGKoMAslRbelaTqlus0wE3zxb2yQ/j2NeZzFnFEuR/vbUug7uzH+onko2jXrt7VcPNXLOa1/g5CWwaf/YPfJO4zv+atlzBHvuFcQCkdbcOJkccCnBUoR7y0PJoBJX6K7wJQ+hWLdcY4nVaxkGPRmsZJo9qogXZMw1CwJVjofxRI0S/5vMtEqh8srYsg7qlTNv8eYnwdpfuunn2mI7Khx10Tz85PZDnr3SGRiFvdfmT30pI7jL3bhOHALkaoy2VevteJjIyMxANTvjIUBNQUi+7Kj3VIKmkL9NAMAQBbshiQL1wTrXdqOeC8Nm1BfCQEox2yiC6pDFbXVbguwJZ5VKFizTTK6f6BdNYKTVx8lNEdjAsWH8ojgGWwGXBbTkClULHezJ/sODaZzK/+M/IzbGmlF27jJYpdJX8fUoybZNw9lXwIfQQWHmQHEOJYCljD9G1tvYY70+xAFexgBX5Ib48UK4DRITVNecyQZL7bLTzGcM0TAE0EtD4M42wawsYP3Cva9UxShFLICQdPoa4Wmfs6uLbXG1DDLol/j7b6bL+6W8E3AlW+aAPc8GZm51/w3VlYqqciWTc12OJpu8FiD0pZ/iBw+E=
141 e1526da1e6d84e03146151c9b6e6950fe9a83d7d 0 iQIVAwUAWJIKpUemf/qjRqrOAQjjThAAvl1K/GZBrkanwEPXomewHkWKTEy1s5d5oWmPPGrSb9G4LM/3/abSbQ7fnzkS6IWi4Ao0za68w/MohaVGKoMAslRbelaTqlus0wE3zxb2yQ/j2NeZzFnFEuR/vbUug7uzH+onko2jXrt7VcPNXLOa1/g5CWwaf/YPfJO4zv+atlzBHvuFcQCkdbcOJkccCnBUoR7y0PJoBJX6K7wJQ+hWLdcY4nVaxkGPRmsZJo9qogXZMw1CwJVjofxRI0S/5vMtEqh8srYsg7qlTNv8eYnwdpfuunn2mI7Khx10Tz85PZDnr3SGRiFvdfmT30pI7jL3bhOHALkaoy2VevteJjIyMxANTvjIUBNQUi+7Kj3VIKmkL9NAMAQBbshiQL1wTrXdqOeC8Nm1BfCQEox2yiC6pDFbXVbguwJZ5VKFizTTK6f6BdNYKTVx8lNEdjAsWH8ojgGWwGXBbTkClULHezJ/sODaZzK/+M/IzbGmlF27jJYpdJX8fUoybZNw9lXwIfQQWHmQHEOJYCljD9G1tvYY70+xAFexgBX5Ib48UK4DRITVNecyQZL7bLTzGcM0TAE0EtD4M42wawsYP3Cva9UxShFLICQdPoa4Wmfs6uLbXG1DDLol/j7b6bL+6W8E3AlW+aAPc8GZm51/w3VlYqqciWTc12OJpu8FiD0pZ/iBw+E=
142 25703b624d27e3917d978af56d6ad59331e0464a 0 iQIcBAABCAAGBQJYuMSwAAoJELnJ3IJKpb3VL3YP/iKWY3+K3cLUBD3Ne5MhfS7N3t6rlk9YD4kmU8JnVeV1oAfg36VCylpbJLBnmQdvC8AfBJOkXi6DHp9RKXXmlsOeoppdWYGX5RMOzuwuGPBii6cA6KFd+WBpBJlRtklz61qGCAtv4q8V1mga0yucihghzt4lD/PPz7mk6yUBL8s3rK+bIHGdEhnK2dfnn/U2G0K/vGgsYZESORISuBclCrrc7M3/v1D+FBMCEYX9FXYU4PhYkKXK1mSqzCB7oENu/WP4ijl1nRnEIyzBV9pKO4ylnXTpbZAr/e4PofzjzPXb0zume1191C3wvgJ4eDautGide/Pxls5s6fJRaIowf5XVYQ5srX/NC9N3K77Hy01t5u8nwcyAhjmajZYuB9j37nmiwFawqS/y2eHovrUjkGdelV8OM7/iAexPRC8i2NcGk0m6XuzWy1Dxr8453VD8Hh3tTeafd6v5uHXSLjwogpu/th5rk/i9/5GBzc1MyJgRTwBhVHi/yFxfyakrSU7HT2cwX/Lb5KgWccogqfvrFYQABIBanxLIeZxTv8OIjC75EYknbxYtvvgb35ZdJytwrTHSZN0S7Ua2dHx2KUnHB6thbLu/v9fYrCgFF76DK4Ogd22Cbvv6NqRoglG26d0bqdwz/l1n3o416YjupteW8LMxHzuwiJy69WP1yi10eNDq
142 25703b624d27e3917d978af56d6ad59331e0464a 0 iQIcBAABCAAGBQJYuMSwAAoJELnJ3IJKpb3VL3YP/iKWY3+K3cLUBD3Ne5MhfS7N3t6rlk9YD4kmU8JnVeV1oAfg36VCylpbJLBnmQdvC8AfBJOkXi6DHp9RKXXmlsOeoppdWYGX5RMOzuwuGPBii6cA6KFd+WBpBJlRtklz61qGCAtv4q8V1mga0yucihghzt4lD/PPz7mk6yUBL8s3rK+bIHGdEhnK2dfnn/U2G0K/vGgsYZESORISuBclCrrc7M3/v1D+FBMCEYX9FXYU4PhYkKXK1mSqzCB7oENu/WP4ijl1nRnEIyzBV9pKO4ylnXTpbZAr/e4PofzjzPXb0zume1191C3wvgJ4eDautGide/Pxls5s6fJRaIowf5XVYQ5srX/NC9N3K77Hy01t5u8nwcyAhjmajZYuB9j37nmiwFawqS/y2eHovrUjkGdelV8OM7/iAexPRC8i2NcGk0m6XuzWy1Dxr8453VD8Hh3tTeafd6v5uHXSLjwogpu/th5rk/i9/5GBzc1MyJgRTwBhVHi/yFxfyakrSU7HT2cwX/Lb5KgWccogqfvrFYQABIBanxLIeZxTv8OIjC75EYknbxYtvvgb35ZdJytwrTHSZN0S7Ua2dHx2KUnHB6thbLu/v9fYrCgFF76DK4Ogd22Cbvv6NqRoglG26d0bqdwz/l1n3o416YjupteW8LMxHzuwiJy69WP1yi10eNDq
143 ed5b25874d998ababb181a939dd37a16ea644435 0 iQIcBAABCAAGBQJY4r/gAAoJELnJ3IJKpb3VtwYP/RuTmo252ExXQk/n5zGJZvZQnI86vO1+yGuyOlGFFBwf1v3sOLW1HD7fxF6/GdT8CSQrRqtC17Ya3qtayfY/0AEiSuH2bklBXSB1H5wPyguS5iLqyilCJY0SkHYBIDhJ0xftuIjsa805wdMm3OdclnTOkYT+K1WL8Ylbx/Ni2Lsx1rPpYdcQ/HlTkr5ca1ZbNOOSxSNI4+ilGlKbdSYeEsmqB2sDEiSaDEoxGGoSgzAE9+5Q2FfCGXV0bq4vfmEPoT9lhB4kANE+gcFUvsJTu8Z7EdF8y3CJLiy8+KHO/VLKTGJ1pMperbig9nAXl1AOt+izBFGJGTolbR/ShkkDWB/QVcqIF5CysAWMgnHAx7HjnMDBOANcKzhMMfOi3GUvOCNNIqIIoJHKRHaRk0YbMdt7z2mKpTrRQ9Zadz764jXOqqrPgQFM3jkBHzAvZz9yShrHGh42Y+iReAF9pAN0xPjyZ5Y2qp+DSl0bIQqrAet6Zd3QuoJtXczAeRrAvgn7O9MyLnMyE5s7xxI7o8M7zfWtChLF8ytJUzmRo3iVJNOJH+Zls9N30PGw6vubQAnB5ieaVTv8lnNpcAnEQD/i0tmRSxzyyqoOQbnItIPKFOsaYW+eX9sgJmObU3yDc5k3cs+yAFD2CM/uiUsLcTKyxPNcP1JHBYpwhOjIGczSHVS1
143 ed5b25874d998ababb181a939dd37a16ea644435 0 iQIcBAABCAAGBQJY4r/gAAoJELnJ3IJKpb3VtwYP/RuTmo252ExXQk/n5zGJZvZQnI86vO1+yGuyOlGFFBwf1v3sOLW1HD7fxF6/GdT8CSQrRqtC17Ya3qtayfY/0AEiSuH2bklBXSB1H5wPyguS5iLqyilCJY0SkHYBIDhJ0xftuIjsa805wdMm3OdclnTOkYT+K1WL8Ylbx/Ni2Lsx1rPpYdcQ/HlTkr5ca1ZbNOOSxSNI4+ilGlKbdSYeEsmqB2sDEiSaDEoxGGoSgzAE9+5Q2FfCGXV0bq4vfmEPoT9lhB4kANE+gcFUvsJTu8Z7EdF8y3CJLiy8+KHO/VLKTGJ1pMperbig9nAXl1AOt+izBFGJGTolbR/ShkkDWB/QVcqIF5CysAWMgnHAx7HjnMDBOANcKzhMMfOi3GUvOCNNIqIIoJHKRHaRk0YbMdt7z2mKpTrRQ9Zadz764jXOqqrPgQFM3jkBHzAvZz9yShrHGh42Y+iReAF9pAN0xPjyZ5Y2qp+DSl0bIQqrAet6Zd3QuoJtXczAeRrAvgn7O9MyLnMyE5s7xxI7o8M7zfWtChLF8ytJUzmRo3iVJNOJH+Zls9N30PGw6vubQAnB5ieaVTv8lnNpcAnEQD/i0tmRSxzyyqoOQbnItIPKFOsaYW+eX9sgJmObU3yDc5k3cs+yAFD2CM/uiUsLcTKyxPNcP1JHBYpwhOjIGczSHVS1
144 77eaf9539499a1b8be259ffe7ada787d07857f80 0 iQIcBAABCAAGBQJY9iz9AAoJELnJ3IJKpb3VYqEQAJNkB09sXgYRLA4kGQv3p4v02q9WZ1lHkAhOlNwIh7Zp+pGvT33nHZffByA0v+xtJNV9TNMIFFjkCg3jl5Z42CCe33ZlezGBAzXU+70QPvOR0ojlYk+FdMfeSyCBzWYokIpImwNmwNGKVrUAfywdikCsUC2aRjKg4Mn7GnqWl9WrBG6JEOOUamdx8qV2f6g/utRiqj4YQ86P0y4K3yakwc1LMM+vRfrwvsf1+DZ9t7QRENNKQ6gRnUdfryqSFIWn1VkBVMwIN5W3yIrTMfgH1wAZxbnYHrN5qDK7mcbP7bOA3XWJuEC+3QRnheRFd/21O1dMFuYjaKApXPHRlTGRMOaz2eydbfBopUS1BtfYEh4/B/1yJb9/HDw6LiAjea7ACHiaNec83z643005AvtUuWhjX3QTPkYlQzWaosanGy1IOGtXCPp1L0A+9gUpqyqycfPjQCbST5KRzYSZn3Ngmed5Bb6jsgvg5e5y0En/SQgK/pTKnxemAmFFVvIIrrWGRKj0AD0IFEHEepmwprPRs97EZPoBPFAGmVRuASBeIhFQxSDIXV0ebHJoUmz5w1rTy7U3Eq0ff6nW14kjWOUplatXz5LpWJ3VkZKrI+4gelto5xpTI6gJl2nmezhXQIlInk17cPuxmiHjeMdlOHZRh/zICLhQNL5fGne0ZL+qlrXY
144 77eaf9539499a1b8be259ffe7ada787d07857f80 0 iQIcBAABCAAGBQJY9iz9AAoJELnJ3IJKpb3VYqEQAJNkB09sXgYRLA4kGQv3p4v02q9WZ1lHkAhOlNwIh7Zp+pGvT33nHZffByA0v+xtJNV9TNMIFFjkCg3jl5Z42CCe33ZlezGBAzXU+70QPvOR0ojlYk+FdMfeSyCBzWYokIpImwNmwNGKVrUAfywdikCsUC2aRjKg4Mn7GnqWl9WrBG6JEOOUamdx8qV2f6g/utRiqj4YQ86P0y4K3yakwc1LMM+vRfrwvsf1+DZ9t7QRENNKQ6gRnUdfryqSFIWn1VkBVMwIN5W3yIrTMfgH1wAZxbnYHrN5qDK7mcbP7bOA3XWJuEC+3QRnheRFd/21O1dMFuYjaKApXPHRlTGRMOaz2eydbfBopUS1BtfYEh4/B/1yJb9/HDw6LiAjea7ACHiaNec83z643005AvtUuWhjX3QTPkYlQzWaosanGy1IOGtXCPp1L0A+9gUpqyqycfPjQCbST5KRzYSZn3Ngmed5Bb6jsgvg5e5y0En/SQgK/pTKnxemAmFFVvIIrrWGRKj0AD0IFEHEepmwprPRs97EZPoBPFAGmVRuASBeIhFQxSDIXV0ebHJoUmz5w1rTy7U3Eq0ff6nW14kjWOUplatXz5LpWJ3VkZKrI+4gelto5xpTI6gJl2nmezhXQIlInk17cPuxmiHjeMdlOHZRh/zICLhQNL5fGne0ZL+qlrXY
145 616e788321cc4ae9975b7f0c54c849f36d82182b 0 iQIVAwUAWPZuQkemf/qjRqrOAQjFlg/9HXEegJMv8FP+uILPoaiA2UCiqWUL2MVJ0K1cvafkwUq+Iwir8sTe4VJ1v6V+ZRiOuzs4HMnoGJrIks4vHRbAxJ3J6xCfvrsbHdl59grv54vuoL5FlZvkdIe8L7/ovKrUmNwPWZX2v+ffFPrsEBeVlVrXpp4wOPhDxCKTmjYVOp87YqXfJsud7EQFPqpV4jX8DEDtJWT95OE9x0srBg0HpSE95d/BM4TuXTVNI8fV41YEqearKeFIhLxu37HxUmGmkAALCi8RJmm4hVpUHgk3tAVzImI8DglUqnC6VEfaYb+PKzIqHelhb66JO/48qN2S/JXihpNHAVUBysBT0b1xEnc6eNsF2fQEB+bEcf8IGj7/ILee1cmwPtoK2OXR2+xWWWjlu2keVcKeI0yAajJw/dP21yvVzVq0ypst7iD+EGHLJWJSmZscbyH5ICr+TJ5yQvIGZJtfsAdAUUTM2xpqSDW4mT5kYyg75URbQ3AKI7lOhJBmkkGQErE4zIQMkaAqcWziVF20xiRWfJoFxT2fK5weaRGIjELH49NLlyvZxYc4LlRo9lIdC7l/6lYDdTx15VuEj1zx/91y/d7OtPm+KCA2Bbdqth8m/fMD8trfQ6jSG/wgsvjZ+S0eoXa92qIR/igsCI+6EwP7duuzL2iyKOPXupQVNN10PKI7EuKv4Lk=
145 616e788321cc4ae9975b7f0c54c849f36d82182b 0 iQIVAwUAWPZuQkemf/qjRqrOAQjFlg/9HXEegJMv8FP+uILPoaiA2UCiqWUL2MVJ0K1cvafkwUq+Iwir8sTe4VJ1v6V+ZRiOuzs4HMnoGJrIks4vHRbAxJ3J6xCfvrsbHdl59grv54vuoL5FlZvkdIe8L7/ovKrUmNwPWZX2v+ffFPrsEBeVlVrXpp4wOPhDxCKTmjYVOp87YqXfJsud7EQFPqpV4jX8DEDtJWT95OE9x0srBg0HpSE95d/BM4TuXTVNI8fV41YEqearKeFIhLxu37HxUmGmkAALCi8RJmm4hVpUHgk3tAVzImI8DglUqnC6VEfaYb+PKzIqHelhb66JO/48qN2S/JXihpNHAVUBysBT0b1xEnc6eNsF2fQEB+bEcf8IGj7/ILee1cmwPtoK2OXR2+xWWWjlu2keVcKeI0yAajJw/dP21yvVzVq0ypst7iD+EGHLJWJSmZscbyH5ICr+TJ5yQvIGZJtfsAdAUUTM2xpqSDW4mT5kYyg75URbQ3AKI7lOhJBmkkGQErE4zIQMkaAqcWziVF20xiRWfJoFxT2fK5weaRGIjELH49NLlyvZxYc4LlRo9lIdC7l/6lYDdTx15VuEj1zx/91y/d7OtPm+KCA2Bbdqth8m/fMD8trfQ6jSG/wgsvjZ+S0eoXa92qIR/igsCI+6EwP7duuzL2iyKOPXupQVNN10PKI7EuKv4Lk=
146 bb96d4a497432722623ae60d9bc734a1e360179e 0 iQIVAwUAWQkDfEemf/qjRqrOAQierQ/7BuQ0IW0T0cglgqIgkLuYLx2VXJCTEtRNCWmrH2UMK7fAdpAhN0xf+xedv56zYHrlyHpbskDbWvsKIHJdw/4bQitXaIFTyuMMtSR5vXy4Nly34O/Xs2uGb3Y5qwdubeK2nZr4lSPgiRHb/zI/B1Oy8GX830ljmIOY7B0nUWy4DrXcy/M41SnAMLFyD1K6T/8tkv7M4Fai7dQoF9EmIIkShVPktI3lqp3m7infZ4XnJqcqUB0NSfQZwZaUaoalOdCvEIe3ab5ewgl/CuvlDI4oqMQGjXCtNLbtiZSwo6hvudO6ewT+Zn/VdabkZyRtXUxu56ajjd6h22nU1+vknqDzo5tzw6oh1Ubzf8tzyv3Gmmr+tlOjzfK7tXXnT3vR9aEGli0qri0DzOpsDSY0pDC7EsS4LINPoNdsGQrGQdoX++AISROlNjvyuo4Vrp26tPHCSupkKOXuZaiozycAa2Q+aI1EvkPZSXe8SAXKDVtFn05ZB58YVkFzZKAYAxkE/ven59zb4aIbOgR12tZbJoZZsVHrlf/TcDtiXVfIMEMsCtJ1tPgD1rAsEURWRxK3mJ0Ev6KTHgNz4PeBhq1gIP/Y665aX2+cCjc4+vApPUienh5aOr1bQFpIDyYZsafHGMUFNCwRh8bX98oTGa0hjqz4ypwXE4Wztjdc+48UiHARp/Y=
146 bb96d4a497432722623ae60d9bc734a1e360179e 0 iQIVAwUAWQkDfEemf/qjRqrOAQierQ/7BuQ0IW0T0cglgqIgkLuYLx2VXJCTEtRNCWmrH2UMK7fAdpAhN0xf+xedv56zYHrlyHpbskDbWvsKIHJdw/4bQitXaIFTyuMMtSR5vXy4Nly34O/Xs2uGb3Y5qwdubeK2nZr4lSPgiRHb/zI/B1Oy8GX830ljmIOY7B0nUWy4DrXcy/M41SnAMLFyD1K6T/8tkv7M4Fai7dQoF9EmIIkShVPktI3lqp3m7infZ4XnJqcqUB0NSfQZwZaUaoalOdCvEIe3ab5ewgl/CuvlDI4oqMQGjXCtNLbtiZSwo6hvudO6ewT+Zn/VdabkZyRtXUxu56ajjd6h22nU1+vknqDzo5tzw6oh1Ubzf8tzyv3Gmmr+tlOjzfK7tXXnT3vR9aEGli0qri0DzOpsDSY0pDC7EsS4LINPoNdsGQrGQdoX++AISROlNjvyuo4Vrp26tPHCSupkKOXuZaiozycAa2Q+aI1EvkPZSXe8SAXKDVtFn05ZB58YVkFzZKAYAxkE/ven59zb4aIbOgR12tZbJoZZsVHrlf/TcDtiXVfIMEMsCtJ1tPgD1rAsEURWRxK3mJ0Ev6KTHgNz4PeBhq1gIP/Y665aX2+cCjc4+vApPUienh5aOr1bQFpIDyYZsafHGMUFNCwRh8bX98oTGa0hjqz4ypwXE4Wztjdc+48UiHARp/Y=
147 c850f0ed54c1d42f9aa079ad528f8127e5775217 0 iQIVAwUAWTQINUemf/qjRqrOAQjZDw//b4pEgHYfWRVDEmLZtevysfhlJzbSyLAnWgNnRUVdSwl4WRF1r6ds/q7N4Ege5wQHjOpRtx4jC3y/riMbrLUlaeUXzCdqKgm4JcINS1nXy3IfkeDdUKyOR9upjaVhIEzCMRpyzabdYuflh5CoxayO7GFk2iZ8c1oAl4QzuLSspn9w+znqDg0HrMDbRNijStSulNjkqutih9UqT/PYizhE1UjL0NSnpYyD1vDljsHModJc2dhSzuZ1c4VFZHkienk+CNyeLtVKg8aC+Ej/Ppwq6FlE461T/RxOEzf+WFAc9F4iJibSN2kAFB4ySJ43y+OKkvzAwc5XbUx0y6OlWn2Ph+5T54sIwqasG3DjXyVrwVtAvCrcWUmOyS0RfkKoDVepMPIhFXyrhGqUYSq25Gt6tHVtIrlcWARIGGWlsE+PSHi87qcnSjs4xUzZwVvJWz4fuM1AUG/GTpyt4w3kB85XQikIINkmSTmsM/2/ar75T6jBL3kqOCGOL3n7bVZsGXllhkkQ7e/jqPPWnNXm8scDYdT3WENNu34zZp5ZmqdTXPAIIaqGswnU04KfUSEoYtOMri3E2VvrgMkiINm9BOKpgeTsMb3dkYRw2ZY3UAH9QfdX9BZywk6v3kkE5ghLWMUoQ4sqRlTo7mJKA8+EodjmIGRV/kAv1f7pigg6pIWWEyo=
147 c850f0ed54c1d42f9aa079ad528f8127e5775217 0 iQIVAwUAWTQINUemf/qjRqrOAQjZDw//b4pEgHYfWRVDEmLZtevysfhlJzbSyLAnWgNnRUVdSwl4WRF1r6ds/q7N4Ege5wQHjOpRtx4jC3y/riMbrLUlaeUXzCdqKgm4JcINS1nXy3IfkeDdUKyOR9upjaVhIEzCMRpyzabdYuflh5CoxayO7GFk2iZ8c1oAl4QzuLSspn9w+znqDg0HrMDbRNijStSulNjkqutih9UqT/PYizhE1UjL0NSnpYyD1vDljsHModJc2dhSzuZ1c4VFZHkienk+CNyeLtVKg8aC+Ej/Ppwq6FlE461T/RxOEzf+WFAc9F4iJibSN2kAFB4ySJ43y+OKkvzAwc5XbUx0y6OlWn2Ph+5T54sIwqasG3DjXyVrwVtAvCrcWUmOyS0RfkKoDVepMPIhFXyrhGqUYSq25Gt6tHVtIrlcWARIGGWlsE+PSHi87qcnSjs4xUzZwVvJWz4fuM1AUG/GTpyt4w3kB85XQikIINkmSTmsM/2/ar75T6jBL3kqOCGOL3n7bVZsGXllhkkQ7e/jqPPWnNXm8scDYdT3WENNu34zZp5ZmqdTXPAIIaqGswnU04KfUSEoYtOMri3E2VvrgMkiINm9BOKpgeTsMb3dkYRw2ZY3UAH9QfdX9BZywk6v3kkE5ghLWMUoQ4sqRlTo7mJKA8+EodjmIGRV/kAv1f7pigg6pIWWEyo=
148 26c49ed51a698ec016d2b4c6b44ca3c3f73cc788 0 iQIcBAABCAAGBQJZXQSmAAoJELnJ3IJKpb3VmTwP/jsxFTlKzWU8EnEhEViiP2YREOD3AXU7685DIMnoyVAsZgxrt0CG6Y92b5sINCeh5B0ORPQ7+xi2Xmz6tX8EeAR+/Dpdx6K623yExf8kq91zgfMvYkatNMu6ZVfywibYZAASq02oKoX7WqSPcQG/OwgtdFiGacCrG5iMH7wRv0N9hPc6D5vAV8/H/Inq8twpSG5SGDpCdKj7KPZiY8DFu/3OXatJtl+byg8zWT4FCYKkBPvmZp8/sRhDKBgwr3RvF1p84uuw/QxXjt+DmGxgtjvObjHr+shCMcKBAuZ4RtZmyEo/0L81uaTElHu1ejsEzsEKxs+8YifnH070PTFoV4VXQyXfTc8AyaqHE6rzX96a/HjQiJnL4dFeTZIrUhGK3AkObFLWJxVTo4J8+oliBQQldIh1H2yb1ZMfwapLnUGIqSieHDGZ6K2ccNJK8Q7IRhTCvYc0cjsnbwTpV4cebGqf3WXZhX0cZN+TNfhh/HGRzR1EeAAavjJqpDam1OBA5TmtJd/lHLIRVR5jyG+r4SK0XDlJ8uSfah7MpVH6aQ6UrycPyFusGXQlIqJ1DYQaBrI/SRJfIvRUmvVz9WgKLe83oC3Ui3aWR9rNjMb2InuQuXjeZaeaYfBAUYACcGfCZpZZvoEkMHCqtTng1rbbFnKMFk5kVy9YWuVgK9Iuh0O5
148 26c49ed51a698ec016d2b4c6b44ca3c3f73cc788 0 iQIcBAABCAAGBQJZXQSmAAoJELnJ3IJKpb3VmTwP/jsxFTlKzWU8EnEhEViiP2YREOD3AXU7685DIMnoyVAsZgxrt0CG6Y92b5sINCeh5B0ORPQ7+xi2Xmz6tX8EeAR+/Dpdx6K623yExf8kq91zgfMvYkatNMu6ZVfywibYZAASq02oKoX7WqSPcQG/OwgtdFiGacCrG5iMH7wRv0N9hPc6D5vAV8/H/Inq8twpSG5SGDpCdKj7KPZiY8DFu/3OXatJtl+byg8zWT4FCYKkBPvmZp8/sRhDKBgwr3RvF1p84uuw/QxXjt+DmGxgtjvObjHr+shCMcKBAuZ4RtZmyEo/0L81uaTElHu1ejsEzsEKxs+8YifnH070PTFoV4VXQyXfTc8AyaqHE6rzX96a/HjQiJnL4dFeTZIrUhGK3AkObFLWJxVTo4J8+oliBQQldIh1H2yb1ZMfwapLnUGIqSieHDGZ6K2ccNJK8Q7IRhTCvYc0cjsnbwTpV4cebGqf3WXZhX0cZN+TNfhh/HGRzR1EeAAavjJqpDam1OBA5TmtJd/lHLIRVR5jyG+r4SK0XDlJ8uSfah7MpVH6aQ6UrycPyFusGXQlIqJ1DYQaBrI/SRJfIvRUmvVz9WgKLe83oC3Ui3aWR9rNjMb2InuQuXjeZaeaYfBAUYACcGfCZpZZvoEkMHCqtTng1rbbFnKMFk5kVy9YWuVgK9Iuh0O5
149 857876ebaed4e315f63157bd157d6ce553c7ab73 0 iQIVAwUAWW9XW0emf/qjRqrOAQhI7A//cKXIM4l8vrWWsc1Os4knXm/2UaexmAwV70TpviKL9RxCy5zBP/EapCaGRCH8uNPOQTkWGR9Aucm3CtxhggCMzULQxxeH86mEpWf1xILWLySPXW/t2f+2zxrwLSAxxqFJtuYv83Pe8CnS3y4BlgHnBKYXH8XXuW8uvfc0lHKblhrspGBIAinx7vPLoGQcpYrn9USWUKq5d9FaCLQCDT9501FHKf5dlYQajevCUDnewtn5ohelOXjTJQClW3aygv/z+98Kq7ZhayeIiZu+SeP+Ay7lZPklXcy6eyRiQtGCa1yesb9v53jKtgxWewV4o6zyuUesdknZ/IBeNUgw8LepqTIJo6/ckyvBOsSQcda81DuYNUChZLYTSXYPHEUmYiz6CvNoLEgHF/oO5p6CZXOPWbmLWrAFd+0+1Tuq8BSh+PSdEREM3ZLOikkXoVzTKBgu4zpMvmBnjliBg7WhixkcG0v5WunlV9/oHAIpsKdL7AatU+oCPulp+xDpTKzRazEemYiWG9zYKzwSMk9Nc17e2tk+EtFSPsPo4iVCXMgdIZSTNBvynKEFXZQVPWVa+bYRdAmbSY8awiX7exxYL10UcpnN2q/AH/F7rQzAmo8eZ3OtD0+3Nk3JRx0/CMyzKLPYDpdUgwmaPb+s2Bsy7f7TfmA7jTa69YqB1/zVwlWULr0=
149 857876ebaed4e315f63157bd157d6ce553c7ab73 0 iQIVAwUAWW9XW0emf/qjRqrOAQhI7A//cKXIM4l8vrWWsc1Os4knXm/2UaexmAwV70TpviKL9RxCy5zBP/EapCaGRCH8uNPOQTkWGR9Aucm3CtxhggCMzULQxxeH86mEpWf1xILWLySPXW/t2f+2zxrwLSAxxqFJtuYv83Pe8CnS3y4BlgHnBKYXH8XXuW8uvfc0lHKblhrspGBIAinx7vPLoGQcpYrn9USWUKq5d9FaCLQCDT9501FHKf5dlYQajevCUDnewtn5ohelOXjTJQClW3aygv/z+98Kq7ZhayeIiZu+SeP+Ay7lZPklXcy6eyRiQtGCa1yesb9v53jKtgxWewV4o6zyuUesdknZ/IBeNUgw8LepqTIJo6/ckyvBOsSQcda81DuYNUChZLYTSXYPHEUmYiz6CvNoLEgHF/oO5p6CZXOPWbmLWrAFd+0+1Tuq8BSh+PSdEREM3ZLOikkXoVzTKBgu4zpMvmBnjliBg7WhixkcG0v5WunlV9/oHAIpsKdL7AatU+oCPulp+xDpTKzRazEemYiWG9zYKzwSMk9Nc17e2tk+EtFSPsPo4iVCXMgdIZSTNBvynKEFXZQVPWVa+bYRdAmbSY8awiX7exxYL10UcpnN2q/AH/F7rQzAmo8eZ3OtD0+3Nk3JRx0/CMyzKLPYDpdUgwmaPb+s2Bsy7f7TfmA7jTa69YqB1/zVwlWULr0=
150 5544af8622863796a0027566f6b646e10d522c4c 0 iQIcBAABCAAGBQJZjJflAAoJELnJ3IJKpb3V19kQALCvTdPrpce5+rBNbFtLGNFxTMDol1dUy87EUAWiArnfOzW3rKBdYxvxDL23BpgUfjRm1fAXdayVvlj6VC6Dyb195OLmc/I9z7SjFxsfmxWilF6U0GIa3W0x37i05EjfcccrBIuSLrvR6AWyJhjLOBCcyAqD/HcEom00/L+o2ry9CDQNLEeVuNewJiupcUqsTIG2yS26lWbtLZuoqS2T4Nlg8wjJhiSXlsZSuAF55iUJKlTQP6KyWReiaYuEVfm/Bybp0A2bFcZCYpWPwnwKBdSCHhIalH8PO57gh9J7xJVnyyBg5PU6n4l6PrGOmKhNiU/xyNe36tEAdMW6svcVvt8hiY0dnwWqR6wgnFFDu0lnTMUcjsy5M5FBY6wSw9Fph8zcNRzYyaeUbasNonPvrIrk21nT3ET3RzVR3ri2nJDVF+0GlpogGfk9k7wY3808091BMsyV3448ZPKQeWiK4Yy4UOUwbKV7YAsS5MdDnC1uKjl4GwLn9UCY/+Q2/2R0CBZ13Tox+Nbo6hBRuRGtFIbLK9j7IIUhhZrIZFSh8cDNkC+UMaS52L5z7ECvoYIUpw+MJ7NkMLHIVGZ2Nxn0C7IbGO6uHyR7D6bdNpxilU+WZStHk0ppZItRTm/htar4jifnaCI8F8OQNYmZ3cQhxx6qV2Tyow8arvWb1NYXrocG
150 5544af8622863796a0027566f6b646e10d522c4c 0 iQIcBAABCAAGBQJZjJflAAoJELnJ3IJKpb3V19kQALCvTdPrpce5+rBNbFtLGNFxTMDol1dUy87EUAWiArnfOzW3rKBdYxvxDL23BpgUfjRm1fAXdayVvlj6VC6Dyb195OLmc/I9z7SjFxsfmxWilF6U0GIa3W0x37i05EjfcccrBIuSLrvR6AWyJhjLOBCcyAqD/HcEom00/L+o2ry9CDQNLEeVuNewJiupcUqsTIG2yS26lWbtLZuoqS2T4Nlg8wjJhiSXlsZSuAF55iUJKlTQP6KyWReiaYuEVfm/Bybp0A2bFcZCYpWPwnwKBdSCHhIalH8PO57gh9J7xJVnyyBg5PU6n4l6PrGOmKhNiU/xyNe36tEAdMW6svcVvt8hiY0dnwWqR6wgnFFDu0lnTMUcjsy5M5FBY6wSw9Fph8zcNRzYyaeUbasNonPvrIrk21nT3ET3RzVR3ri2nJDVF+0GlpogGfk9k7wY3808091BMsyV3448ZPKQeWiK4Yy4UOUwbKV7YAsS5MdDnC1uKjl4GwLn9UCY/+Q2/2R0CBZ13Tox+Nbo6hBRuRGtFIbLK9j7IIUhhZrIZFSh8cDNkC+UMaS52L5z7ECvoYIUpw+MJ7NkMLHIVGZ2Nxn0C7IbGO6uHyR7D6bdNpxilU+WZStHk0ppZItRTm/htar4jifnaCI8F8OQNYmZ3cQhxx6qV2Tyow8arvWb1NYXrocG
151 943c91326b23954e6e1c6960d0239511f9530258 0 iQIcBAABCAAGBQJZjKKZAAoJELnJ3IJKpb3VGQkP/0iF6Khef0lBaRhbSAPwa7RUBb3iaBeuwmeic/hUjMoU1E5NR36bDDaF3u2di5mIYPBONFIeCPf9/DKyFkidueX1UnlAQa3mjh/QfKTb4/yO2Nrk7eH+QtrYxVUUYYjwgp4rS0Nd/++I1IUOor54vqJzJ7ZnM5O1RsE7VI1esAC/BTlUuO354bbm08B0owsZBwVvcVvpV4zeTvq5qyPxBJ3M0kw83Pgwh3JZB9IYhOabhSUBcA2fIPHgYGYnJVC+bLOeMWI1HJkJeoYfClNUiQUjAmi0cdTC733eQnHkDw7xyyFi+zkKu6JmU1opxkHSuj4Hrjul7Gtw3vVWWUPufz3AK7oymNp2Xr5y1HQLDtNJP3jicTTG1ae2TdX5Az3ze0I8VGbpR81/6ShAvY2cSKttV3I+2k4epxTTTf0xaZS1eUdnFOox6acElG2reNzx7EYYxpHj17K8N2qNzyY78iPgbJ+L39PBFoiGXMZJqWCxxIHoK1MxlXa8WwSnsXAU768dJvEn2N1x3fl+aeaWzeM4/5Qd83YjFuCeycuRnIo3rejSX3rWFAwZE0qQHKI5YWdKDLxIfdHTjdfMP7np+zLcHt0DV/dHmj2hKQgU0OK04fx7BrmdS1tw67Y9bL3H3TDohn7khU1FrqrKVuqSLbLsxnNyWRbZQF+DCoYrHlIW
151 943c91326b23954e6e1c6960d0239511f9530258 0 iQIcBAABCAAGBQJZjKKZAAoJELnJ3IJKpb3VGQkP/0iF6Khef0lBaRhbSAPwa7RUBb3iaBeuwmeic/hUjMoU1E5NR36bDDaF3u2di5mIYPBONFIeCPf9/DKyFkidueX1UnlAQa3mjh/QfKTb4/yO2Nrk7eH+QtrYxVUUYYjwgp4rS0Nd/++I1IUOor54vqJzJ7ZnM5O1RsE7VI1esAC/BTlUuO354bbm08B0owsZBwVvcVvpV4zeTvq5qyPxBJ3M0kw83Pgwh3JZB9IYhOabhSUBcA2fIPHgYGYnJVC+bLOeMWI1HJkJeoYfClNUiQUjAmi0cdTC733eQnHkDw7xyyFi+zkKu6JmU1opxkHSuj4Hrjul7Gtw3vVWWUPufz3AK7oymNp2Xr5y1HQLDtNJP3jicTTG1ae2TdX5Az3ze0I8VGbpR81/6ShAvY2cSKttV3I+2k4epxTTTf0xaZS1eUdnFOox6acElG2reNzx7EYYxpHj17K8N2qNzyY78iPgbJ+L39PBFoiGXMZJqWCxxIHoK1MxlXa8WwSnsXAU768dJvEn2N1x3fl+aeaWzeM4/5Qd83YjFuCeycuRnIo3rejSX3rWFAwZE0qQHKI5YWdKDLxIfdHTjdfMP7np+zLcHt0DV/dHmj2hKQgU0OK04fx7BrmdS1tw67Y9bL3H3TDohn7khU1FrqrKVuqSLbLsxnNyWRbZQF+DCoYrHlIW
152 3fee7f7d2da04226914c2258cc2884dc27384fd7 0 iQIcBAABCAAGBQJZjOJfAAoJELnJ3IJKpb3VvikP/iGjfahwkl2BDZYGq6Ia64a0bhEh0iltoWTCCDKMbHuuO+7h07fHpBl/XX5XPnS7imBUVWLOARhVL7aDPb0tu5NZzMKN57XUC/0FWFyf7lXXAVaOapR4kP8RtQvnoxfNSLRgiZQL88KIRBgFc8pbl8hLA6UbcHPsOk4dXKvmfPfHBHnzdUEDcSXDdyOBhuyOSzRs8egXVi3WeX6OaXG3twkw/uCF3pgOMOSyWVDwD+KvK+IBmSxCTKXzsb+pqpc7pPOFWhSXjpbuYUcI5Qy7mpd0bFL3qNqgvUNq2gX5mT6zH/TsVD10oSUjYYqKMO+gi34OgTVWRRoQfWBwrQwxsC/MxH6ZeOetl2YkS13OxdmYpNAFNQ8ye0vZigJRA+wHoC9dn0h8c5X4VJt/dufHeXc887EGJpLg6GDXi5Emr2ydAUhBJKlpi2yss22AmiQ4G9NE1hAjxqhPvkgBK/hpbr3FurV4hjTG6XKsF8I0WdbYz2CW/FEbp1+4T49ChhrwW0orZdEQX7IEjXr45Hs5sTInT90Hy2XG3Kovi0uVMt15cKsSEYDoFHkR4NgCZX2Y+qS5ryH8yqor3xtel3KsBIy6Ywn8pAo2f8flW3nro/O6x+0NKGV+ZZ0uo/FctuQLBrQVs025T1ai/6MbscQXvFVZVPKrUzlQaNPf/IwNOaRa
152 3fee7f7d2da04226914c2258cc2884dc27384fd7 0 iQIcBAABCAAGBQJZjOJfAAoJELnJ3IJKpb3VvikP/iGjfahwkl2BDZYGq6Ia64a0bhEh0iltoWTCCDKMbHuuO+7h07fHpBl/XX5XPnS7imBUVWLOARhVL7aDPb0tu5NZzMKN57XUC/0FWFyf7lXXAVaOapR4kP8RtQvnoxfNSLRgiZQL88KIRBgFc8pbl8hLA6UbcHPsOk4dXKvmfPfHBHnzdUEDcSXDdyOBhuyOSzRs8egXVi3WeX6OaXG3twkw/uCF3pgOMOSyWVDwD+KvK+IBmSxCTKXzsb+pqpc7pPOFWhSXjpbuYUcI5Qy7mpd0bFL3qNqgvUNq2gX5mT6zH/TsVD10oSUjYYqKMO+gi34OgTVWRRoQfWBwrQwxsC/MxH6ZeOetl2YkS13OxdmYpNAFNQ8ye0vZigJRA+wHoC9dn0h8c5X4VJt/dufHeXc887EGJpLg6GDXi5Emr2ydAUhBJKlpi2yss22AmiQ4G9NE1hAjxqhPvkgBK/hpbr3FurV4hjTG6XKsF8I0WdbYz2CW/FEbp1+4T49ChhrwW0orZdEQX7IEjXr45Hs5sTInT90Hy2XG3Kovi0uVMt15cKsSEYDoFHkR4NgCZX2Y+qS5ryH8yqor3xtel3KsBIy6Ywn8pAo2f8flW3nro/O6x+0NKGV+ZZ0uo/FctuQLBrQVs025T1ai/6MbscQXvFVZVPKrUzlQaNPf/IwNOaRa
153 920977f72c7b70acfdaf56ab35360584d7845827 0 iQIcBAABCAAGBQJZv+wSAAoJELnJ3IJKpb3VH3kQAJp3OkV6qOPXBnlOSSodbVZveEQ5dGJfG9hk+VokcK6MFnieAFouROoGNlQXQtzj6cMqK+LGCP/NeJEG323gAxpxMzc32g7TqbVEhKNqNK8HvQSt04aCVZXtBmP0cPzc348UPP1X1iPTkyZxaJ0kHulaHVptwGbFZZyhwGefauU4eMafJsYqwgiGmvDpjUFu6P8YJXliYeTo1HX2lNChS1xmvJbop1YHfBYACsi8Eron0vMuhaQ+TKYq8Zd762u2roRYnaQ23ubEaVsjGDUYxXXVmit2gdaEKk+6Rq2I+EgcI5XvFzK8gvoP7siz6FL1jVf715k9/UYoWj9KDNUm8cweiyiUpjHQt0S+Ro9ryKvQy6tQVunRZqBN/kZWVth/FlMbUENbxVyXZcXv+m7OLvk+vyK7UZ7yT+OBzgRr0PyUuafzSVW3e+RZJtGxYGM5ew2bWQ8L6wuBucRYZOSnXXtCw7cKEMlK3BTjfAfpHUdIZIG492R9d6aOECUK/MpNvCiXXaZoh5Kj4a0dARiuWFCZxWwt3bmOg13oQ841zLdzOi/YZe15vCm8OB4Ffg6CkmPKhZhnMwVbFmlaBcoaeMzzpMuog91J1M2zgEUBTYwe/HKiNr/0iilJMPFRpZ+zEb2GvVoc8FMttXi8aomlXf/6LHCC9ndexGC29jIzl41+
153 920977f72c7b70acfdaf56ab35360584d7845827 0 iQIcBAABCAAGBQJZv+wSAAoJELnJ3IJKpb3VH3kQAJp3OkV6qOPXBnlOSSodbVZveEQ5dGJfG9hk+VokcK6MFnieAFouROoGNlQXQtzj6cMqK+LGCP/NeJEG323gAxpxMzc32g7TqbVEhKNqNK8HvQSt04aCVZXtBmP0cPzc348UPP1X1iPTkyZxaJ0kHulaHVptwGbFZZyhwGefauU4eMafJsYqwgiGmvDpjUFu6P8YJXliYeTo1HX2lNChS1xmvJbop1YHfBYACsi8Eron0vMuhaQ+TKYq8Zd762u2roRYnaQ23ubEaVsjGDUYxXXVmit2gdaEKk+6Rq2I+EgcI5XvFzK8gvoP7siz6FL1jVf715k9/UYoWj9KDNUm8cweiyiUpjHQt0S+Ro9ryKvQy6tQVunRZqBN/kZWVth/FlMbUENbxVyXZcXv+m7OLvk+vyK7UZ7yT+OBzgRr0PyUuafzSVW3e+RZJtGxYGM5ew2bWQ8L6wuBucRYZOSnXXtCw7cKEMlK3BTjfAfpHUdIZIG492R9d6aOECUK/MpNvCiXXaZoh5Kj4a0dARiuWFCZxWwt3bmOg13oQ841zLdzOi/YZe15vCm8OB4Ffg6CkmPKhZhnMwVbFmlaBcoaeMzzpMuog91J1M2zgEUBTYwe/HKiNr/0iilJMPFRpZ+zEb2GvVoc8FMttXi8aomlXf/6LHCC9ndexGC29jIzl41+
154 2f427b57bf9019c6dc3750baa539dc22c1be50f6 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlnQtVIQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91TTkD/409sWTM9vUH2qkqNTb1IXyGpqzb9UGOSVDioz6rvgZEBgh9D1oBTWnfBXW8sOWR0A7iCL6qZh2Yi7g7p0mKGXh9LZViLtSwwMSXpNiGBO7RVPW+NQ6DOY5Rhr0i08UBiVEkZXHeIVCd2Bd6mhAiUsm5iUh9Jne10wO8cIxeAUnsx4DBdHBMWLg6AZKWllSgN+r9H+7wnOhDbkvj1Cu6+ugKpEs+xvbTh47OTyM+w9tC1aoZD4HhfR5w5O16FC+TIoE6wmWut6e2pxIMHDB3H08Dky6gNjucY/ntJXvOZW5kYrQA3LHKks8ebpjsIXesOAvReOAsDz0drwzbWZan9Cbj8yWoYz/HCgHCnX3WqKKORSP5pvdrsqYua9DXtJwBeSWY4vbIM2kECAiyw1SrOGudxlyWBlW1f1jhGR2DsBlwoieeAvUVoaNwO7pYirwxR4nFPdLDRCQ4hLK/GFiuyr+lGoc1WUzVRNBYD3udcOZAbqq4JhWLf0Gvd5xP0rn1cJNhHMvrPH4Ki4a5KeeK6gQI7GT9/+PPQzTdpxXj6KwofktJtVNqm5sJmJ+wMIddnobFlNNLZ/F7OMONWajuVhh+vSOV34YLdhqzAR5XItkeJL6qyAJjNH5PjsnhT7nMqjgwriPz6xxYOLJWgtK5ZqcSCx4gWy9KJVVja8wJ7rRUg==
154 2f427b57bf9019c6dc3750baa539dc22c1be50f6 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlnQtVIQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91TTkD/409sWTM9vUH2qkqNTb1IXyGpqzb9UGOSVDioz6rvgZEBgh9D1oBTWnfBXW8sOWR0A7iCL6qZh2Yi7g7p0mKGXh9LZViLtSwwMSXpNiGBO7RVPW+NQ6DOY5Rhr0i08UBiVEkZXHeIVCd2Bd6mhAiUsm5iUh9Jne10wO8cIxeAUnsx4DBdHBMWLg6AZKWllSgN+r9H+7wnOhDbkvj1Cu6+ugKpEs+xvbTh47OTyM+w9tC1aoZD4HhfR5w5O16FC+TIoE6wmWut6e2pxIMHDB3H08Dky6gNjucY/ntJXvOZW5kYrQA3LHKks8ebpjsIXesOAvReOAsDz0drwzbWZan9Cbj8yWoYz/HCgHCnX3WqKKORSP5pvdrsqYua9DXtJwBeSWY4vbIM2kECAiyw1SrOGudxlyWBlW1f1jhGR2DsBlwoieeAvUVoaNwO7pYirwxR4nFPdLDRCQ4hLK/GFiuyr+lGoc1WUzVRNBYD3udcOZAbqq4JhWLf0Gvd5xP0rn1cJNhHMvrPH4Ki4a5KeeK6gQI7GT9/+PPQzTdpxXj6KwofktJtVNqm5sJmJ+wMIddnobFlNNLZ/F7OMONWajuVhh+vSOV34YLdhqzAR5XItkeJL6qyAJjNH5PjsnhT7nMqjgwriPz6xxYOLJWgtK5ZqcSCx4gWy9KJVVja8wJ7rRUg==
155 1e2454b60e5936f5e77498cab2648db469504487 0 iQJVBAABCAA/FiEEOoFVFj0OIKUw/LeGR6Z/+qNGqs4FAlnqRBUhHGtidWxsb2NrK21lcmN1cmlhbEByaW5nd29ybGQub3JnAAoJEEemf/qjRqrOAQQP/28EzmTKFL/RxmNYePdzqrmcdJ2tn+s7OYmGdtneN2sESZ4MK0xb5Q8Mkm+41aXS52zzJdz9ynwdun8DG4wZ3sE5MOG+GgK6K0ecOv1XTKS3a2DkUM0fl5hlcXN7Zz7m7m5M6sy6vSxHP7kTyzQWt//z175ZLSQEu1a0nm/BLH+HP9e8DfnJ2Nfcnwp32kV0Nj1xTqjRV1Yo/oCnXfVvsxEJU+CDUGBiLc29ZcoWVbTw9c1VcxihJ6k0pK711KZ+bedSk7yc1OudiJF7idjB0bLQY6ESHNNNjK8uLppok0RsyuhvvDTAoTsl1rMKGmXMM0Ela3/5oxZ/5lUZB73vEJhzEi48ULvstpq82EO39KylkEfQxwMBPhnBIHQaGRkl7QPLXGOYUDMY6gT08Sm3e8/NqEJc/AgckXehpH3gSS2Ji2xg7/E8H5plGsswFidw//oYTTwm0j0halWpB521TD2wmjkjRHXzk1mj0EoFQUMfwHTIZU3E8flUBasD3mZ9XqZJPr66RV7QCrXayH75B/i0CyNqd/Hv5Tkf2TlC3EkEBZwZyAjqw7EyL1LuS936sc7fWuMFsH5k/fwjVwzIc1LmP+nmk2Dd9hIC66vec4w1QZeeAXuDKgOJjvQzj2n+uYRuObl4kKcxvoXqgQN0glGuB1IW7lPllGHR1kplhoub
155 1e2454b60e5936f5e77498cab2648db469504487 0 iQJVBAABCAA/FiEEOoFVFj0OIKUw/LeGR6Z/+qNGqs4FAlnqRBUhHGtidWxsb2NrK21lcmN1cmlhbEByaW5nd29ybGQub3JnAAoJEEemf/qjRqrOAQQP/28EzmTKFL/RxmNYePdzqrmcdJ2tn+s7OYmGdtneN2sESZ4MK0xb5Q8Mkm+41aXS52zzJdz9ynwdun8DG4wZ3sE5MOG+GgK6K0ecOv1XTKS3a2DkUM0fl5hlcXN7Zz7m7m5M6sy6vSxHP7kTyzQWt//z175ZLSQEu1a0nm/BLH+HP9e8DfnJ2Nfcnwp32kV0Nj1xTqjRV1Yo/oCnXfVvsxEJU+CDUGBiLc29ZcoWVbTw9c1VcxihJ6k0pK711KZ+bedSk7yc1OudiJF7idjB0bLQY6ESHNNNjK8uLppok0RsyuhvvDTAoTsl1rMKGmXMM0Ela3/5oxZ/5lUZB73vEJhzEi48ULvstpq82EO39KylkEfQxwMBPhnBIHQaGRkl7QPLXGOYUDMY6gT08Sm3e8/NqEJc/AgckXehpH3gSS2Ji2xg7/E8H5plGsswFidw//oYTTwm0j0halWpB521TD2wmjkjRHXzk1mj0EoFQUMfwHTIZU3E8flUBasD3mZ9XqZJPr66RV7QCrXayH75B/i0CyNqd/Hv5Tkf2TlC3EkEBZwZyAjqw7EyL1LuS936sc7fWuMFsH5k/fwjVwzIc1LmP+nmk2Dd9hIC66vec4w1QZeeAXuDKgOJjvQzj2n+uYRuObl4kKcxvoXqgQN0glGuB1IW7lPllGHR1kplhoub
156 0ccb43d4cf01d013ae05917ec4f305509f851b2d 0 iQJVBAABCAA/FiEEOoFVFj0OIKUw/LeGR6Z/+qNGqs4FAln6Qp8hHGtidWxsb2NrK21lcmN1cmlhbEByaW5nd29ybGQub3JnAAoJEEemf/qjRqrOJ8MP/2ufm/dbrFoE0F8hewhztG1vS4stus13lZ9lmM9kza8OKeOgY/MDH8GaV3O8GnRiCNUFsVD8JEIexE31c84H2Ie7VQO0GQSUHSyMCRrbED6IvfrWp6EZ6RDNPk4LHBfxCuPmuVHGRoGZtsLKJBPIxIHJKWMlEJlj9BZuUxZp/8kurQ6CXwblVbFzXdOaZQlioOBH27Bk3S0+gXfJ+wA2ed5XOQvT9jwjqC8y/1t8obaoPTpzyAvb9NArG+9RT9vfNN42aWISZNwg6RW5oLJISqoGrAes6EoG7dZfOC0UoKMVYXoNvZzJvVlMHyjugIoid+WI+V8y9bPrRTfbPCmocCzEzCOLEHQta8roNijB0bKcq8hmQPHcMyXlj1Srnqlco49jbhftgJoPTwzb10wQyU0VFvaZDPW/EQUT3M/k4j3sVESjANdyG1iu6EDV080LK1LgAdhjpKMBbf6mcgAe06/07XFMbKNrZMEislOcVFp98BSKjdioUNpy91rCeSmkEsASJ3yMArRnSkuVgpyrtJaGWl79VUcmOwKhUOA/8MXMz/Oqu7hvve/sgv71xlnim460nnLw6YHPyeeCsz6KSoUK3knFXAbTk/0jvU1ixUZbI122aMzX04UgPGeTukCOUw49XfaOdN+x0YXlkl4PsrnRQhIoixY2gosPpK4YO73G
156 0ccb43d4cf01d013ae05917ec4f305509f851b2d 0 iQJVBAABCAA/FiEEOoFVFj0OIKUw/LeGR6Z/+qNGqs4FAln6Qp8hHGtidWxsb2NrK21lcmN1cmlhbEByaW5nd29ybGQub3JnAAoJEEemf/qjRqrOJ8MP/2ufm/dbrFoE0F8hewhztG1vS4stus13lZ9lmM9kza8OKeOgY/MDH8GaV3O8GnRiCNUFsVD8JEIexE31c84H2Ie7VQO0GQSUHSyMCRrbED6IvfrWp6EZ6RDNPk4LHBfxCuPmuVHGRoGZtsLKJBPIxIHJKWMlEJlj9BZuUxZp/8kurQ6CXwblVbFzXdOaZQlioOBH27Bk3S0+gXfJ+wA2ed5XOQvT9jwjqC8y/1t8obaoPTpzyAvb9NArG+9RT9vfNN42aWISZNwg6RW5oLJISqoGrAes6EoG7dZfOC0UoKMVYXoNvZzJvVlMHyjugIoid+WI+V8y9bPrRTfbPCmocCzEzCOLEHQta8roNijB0bKcq8hmQPHcMyXlj1Srnqlco49jbhftgJoPTwzb10wQyU0VFvaZDPW/EQUT3M/k4j3sVESjANdyG1iu6EDV080LK1LgAdhjpKMBbf6mcgAe06/07XFMbKNrZMEislOcVFp98BSKjdioUNpy91rCeSmkEsASJ3yMArRnSkuVgpyrtJaGWl79VUcmOwKhUOA/8MXMz/Oqu7hvve/sgv71xlnim460nnLw6YHPyeeCsz6KSoUK3knFXAbTk/0jvU1ixUZbI122aMzX04UgPGeTukCOUw49XfaOdN+x0YXlkl4PsrnRQhIoixY2gosPpK4YO73G
157 cabc840ffdee8a72f3689fb77dd74d04fdc2bc04 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAloB+EYQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91TfwEAC/pYW7TC8mQnqSJzde4yiv2+zgflfJzRlg5rbvlUQl1gSBla3sFADZcic0ebAc+8XUu8eIzyPX+oa4wjsHvL13silUCkUzTEEQLqfKPX1bhA4mwfSDb5A7v2VZ5q8qhRGnlhTsB79ML8uBOhR/Bigdm2ixURPEZ37pWljiMp9XWBMtxPxXn/m0n5CDViibX6QqQCR4k3orcsIGd72YXU6B8NGbBN8qlqMSd0pGvSF4vM2cgVhz7D71+zU4XL/HVP97aU9GsOwN9QWW029DOJu6KG6x51WWtfD/tzyNDu7+lZ5/IKyqHX4tyqCIXEGAsQ3XypeHgCq5hV3E6LJLRqPcLpUNDiQlCg6tNPRaOuMC878MRIlffKqMH+sWo8Z7zHrut+LfRh5/k1aCh4J+FIlE6Hgbvbvv2Z8JxDpUKl0Tr+i0oHNTapbGXIecq1ZFR4kcdchodUHXBC2E6HWR50/ek5YKPddzw8WPGsBtzXMfkhFr3WkvyP2Gbe2XJnkuYptTJA+u2CfhrvgmWsYlvt/myTaMZQEzZ+uir4Xoo5NvzqTL30SFqPrP4Nh0n9G6vpVJl/eZxoYK9jL3VC0vDhnZXitkvDpjXZuJqw/HgExXWKZFfiQ3X2HY48v1gvJiSegZ5rX+uGGJtW2/Mp5FidePEgnFIqZW/yhBfs2Hzj1D2A==
157 cabc840ffdee8a72f3689fb77dd74d04fdc2bc04 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAloB+EYQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91TfwEAC/pYW7TC8mQnqSJzde4yiv2+zgflfJzRlg5rbvlUQl1gSBla3sFADZcic0ebAc+8XUu8eIzyPX+oa4wjsHvL13silUCkUzTEEQLqfKPX1bhA4mwfSDb5A7v2VZ5q8qhRGnlhTsB79ML8uBOhR/Bigdm2ixURPEZ37pWljiMp9XWBMtxPxXn/m0n5CDViibX6QqQCR4k3orcsIGd72YXU6B8NGbBN8qlqMSd0pGvSF4vM2cgVhz7D71+zU4XL/HVP97aU9GsOwN9QWW029DOJu6KG6x51WWtfD/tzyNDu7+lZ5/IKyqHX4tyqCIXEGAsQ3XypeHgCq5hV3E6LJLRqPcLpUNDiQlCg6tNPRaOuMC878MRIlffKqMH+sWo8Z7zHrut+LfRh5/k1aCh4J+FIlE6Hgbvbvv2Z8JxDpUKl0Tr+i0oHNTapbGXIecq1ZFR4kcdchodUHXBC2E6HWR50/ek5YKPddzw8WPGsBtzXMfkhFr3WkvyP2Gbe2XJnkuYptTJA+u2CfhrvgmWsYlvt/myTaMZQEzZ+uir4Xoo5NvzqTL30SFqPrP4Nh0n9G6vpVJl/eZxoYK9jL3VC0vDhnZXitkvDpjXZuJqw/HgExXWKZFfiQ3X2HY48v1gvJiSegZ5rX+uGGJtW2/Mp5FidePEgnFIqZW/yhBfs2Hzj1D2A==
158 a92b9f8e11ba330614cdfd6af0e03b15c1ff3797 0 iQJVBAABCAA/FiEEOoFVFj0OIKUw/LeGR6Z/+qNGqs4FAlohslshHGtidWxsb2NrK21lcmN1cmlhbEByaW5nd29ybGQub3JnAAoJEEemf/qjRqrO7P8P/1qGts96acEdB9BZbK/Eesalb1wUByLXZoP8j+1wWwqh/Kq/q7V4Qe0z1jw/92oZbmnLy2C8sDhWv/XKxACKv69oPrcqQix1E8M+07u88ZXqHJMSxkOmvA2Vimp9EG1qgje+qchgOVgvhEhysA96bRpEnc6V0RnBqI5UdfbKtlfBmX5mUE/qsoBZhly1FTmzV1bhYlGgNLyqtJQpcbA34wyPoywsp8DRBiHWrIzz5XNR+DJFTOe4Kqio1i5r8R4QSIM5vtTbj5pbsmtGcP2CsFC9S3xTSAU6AEJKxGpubPk3ckNj3P9zolvR7krU5Jt8LIgXSVaKLt9rPhmxCbPrLtORgXkUupJcrwzQl+oYz5bkl9kowFa959waIPYoCuuW402mOTDq/L3xwDH9AKK5rELPl3fNo+5OIDKAKRIu6zRSAzBtyGT6kkfb1NSghumP4scR7cgUmLaNibZBa8eJj92gwf+ucSGoB/dF/YHWNe0jY09LFK3nyCoftmyLzxcRk1JLGNngw8MCIuisHTskhxSm/qlX7qjunoZnA3yy9behhy/YaFt4YzYZbMTivt2gszX5ktToaDqfxWDYdIa79kp8G68rYPeybelTS74LwbK3blXPI3I1nddkW52znHYLvW6BYyi+QQ5jPZLkiOC+AF0q+c4gYmPaLVN/mpMZjjmB
158 a92b9f8e11ba330614cdfd6af0e03b15c1ff3797 0 iQJVBAABCAA/FiEEOoFVFj0OIKUw/LeGR6Z/+qNGqs4FAlohslshHGtidWxsb2NrK21lcmN1cmlhbEByaW5nd29ybGQub3JnAAoJEEemf/qjRqrO7P8P/1qGts96acEdB9BZbK/Eesalb1wUByLXZoP8j+1wWwqh/Kq/q7V4Qe0z1jw/92oZbmnLy2C8sDhWv/XKxACKv69oPrcqQix1E8M+07u88ZXqHJMSxkOmvA2Vimp9EG1qgje+qchgOVgvhEhysA96bRpEnc6V0RnBqI5UdfbKtlfBmX5mUE/qsoBZhly1FTmzV1bhYlGgNLyqtJQpcbA34wyPoywsp8DRBiHWrIzz5XNR+DJFTOe4Kqio1i5r8R4QSIM5vtTbj5pbsmtGcP2CsFC9S3xTSAU6AEJKxGpubPk3ckNj3P9zolvR7krU5Jt8LIgXSVaKLt9rPhmxCbPrLtORgXkUupJcrwzQl+oYz5bkl9kowFa959waIPYoCuuW402mOTDq/L3xwDH9AKK5rELPl3fNo+5OIDKAKRIu6zRSAzBtyGT6kkfb1NSghumP4scR7cgUmLaNibZBa8eJj92gwf+ucSGoB/dF/YHWNe0jY09LFK3nyCoftmyLzxcRk1JLGNngw8MCIuisHTskhxSm/qlX7qjunoZnA3yy9behhy/YaFt4YzYZbMTivt2gszX5ktToaDqfxWDYdIa79kp8G68rYPeybelTS74LwbK3blXPI3I1nddkW52znHYLvW6BYyi+QQ5jPZLkiOC+AF0q+c4gYmPaLVN/mpMZjjmB
159 27b6df1b5adbdf647cf5c6675b40575e1b197c60 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlpmbwIQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91W4BD/4h+y7QH7FkNcueOBrmdci7w1apkPX7KuknKxf8+FmA1QDGWYATnqD6IcAk3+f4reO4n9qc0y2BGrIz/pyTSIHvJW+ORrbPCKVrXlfUgkUK3TumtRObt8B75BVBBNaJ93r1yOALpo/K8wSwRrBF+Yl6aCoFiibUEbfcfaOAHVqZXKC1ZPtLRwq5NHIw0wWB0qNoAXj+FJV1EHO7SEjj2lXqw/r0HriQMdObWLgAb6QVUq7oVMpAumUeuQtZ169qHdqYfF1OLdCnsVBcwYEz/cBLC43bvYiwFxSkbAFyl656caWiwA3PISFSzP9Co0zWU/Qf8f7dTdAdT/orzCfUq8YoXqryfRSxi+8L8/EMxankzdW73Rx5X+0539pSq+gDDtTOyNuW6+CZwa5D84b31rsd+jTx8zVm3SRHRKsoGF2EEMQkWmDbhIFjX5W1fE84Ul3umypv+lPSvCPlQpIqv2hZmcTR12sgjdBjU8z+Zcq22SHFybqiYNmWpkVUtiMvTlHMoJfi5PI6xF8D2dxV4ErG+NflqdjaXydgnbO6D3/A1FCASig0wL4jMxSeRqnRRqLihN3VaGG2QH6MLJ+Ty6YuoonKtopw9JNOZydr/XN7K5LcjX1T3+31qmnHZyBXRSejWl9XN93IDbQcnMBWHkz/cJLN0kKu4pvnV8UGUcyXfA==
159 27b6df1b5adbdf647cf5c6675b40575e1b197c60 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlpmbwIQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91W4BD/4h+y7QH7FkNcueOBrmdci7w1apkPX7KuknKxf8+FmA1QDGWYATnqD6IcAk3+f4reO4n9qc0y2BGrIz/pyTSIHvJW+ORrbPCKVrXlfUgkUK3TumtRObt8B75BVBBNaJ93r1yOALpo/K8wSwRrBF+Yl6aCoFiibUEbfcfaOAHVqZXKC1ZPtLRwq5NHIw0wWB0qNoAXj+FJV1EHO7SEjj2lXqw/r0HriQMdObWLgAb6QVUq7oVMpAumUeuQtZ169qHdqYfF1OLdCnsVBcwYEz/cBLC43bvYiwFxSkbAFyl656caWiwA3PISFSzP9Co0zWU/Qf8f7dTdAdT/orzCfUq8YoXqryfRSxi+8L8/EMxankzdW73Rx5X+0539pSq+gDDtTOyNuW6+CZwa5D84b31rsd+jTx8zVm3SRHRKsoGF2EEMQkWmDbhIFjX5W1fE84Ul3umypv+lPSvCPlQpIqv2hZmcTR12sgjdBjU8z+Zcq22SHFybqiYNmWpkVUtiMvTlHMoJfi5PI6xF8D2dxV4ErG+NflqdjaXydgnbO6D3/A1FCASig0wL4jMxSeRqnRRqLihN3VaGG2QH6MLJ+Ty6YuoonKtopw9JNOZydr/XN7K5LcjX1T3+31qmnHZyBXRSejWl9XN93IDbQcnMBWHkz/cJLN0kKu4pvnV8UGUcyXfA==
160 d334afc585e29577f271c5eda03378736a16ca6b 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlpzZuUQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91TiDEADDD6Tn04UjgrZ36nAqOcHaG1ZT2Cm1/sbTw+6duAhf3+uKWFqi2bgcdCBkdfRH7KfEU0GNsPpiC6mzWw3PDWmGhnLJAkR+9FTBU0edK01hkNW8RelDTL5J9IzIGwrP4KFfcUue6yrxU8GnSxnf5Vy/N5ZZzLV/P3hdBte5We9PD5KHPAwTzzcZ9Wiog700rFDDChyFq7hNQ3H0GpknF6+Ck5XmJ3DOqt1MFHk9V4Z/ASU59cQXKOeaMChlBpTb1gIIWjOE99v5aY06dc1WlwttuHtCZvZgtAduRAB6XYWyniS/7nXBv0MXD3EWbpH1pkOaWUxw217HpNP4g9Yo3u/i8UW+NkSJOeXtC1CFjWmUNj138IhS1pogaiPPnIs+H6eOJsmnGhN2KbOMjA5Dn9vSTi6s/98TarfUSiwxA4L7fJy5qowFETftuBO0fJpbB8+ZtpnjNp0MMKed27OUSv69i6BmLrP+eqk+MVO6PovvIySlWAP9/REM/I5/mFkqoI+ruT4a9osNGDZ4Jqb382b7EmpEMDdgb7+ezsybgDfizuaTs/LBae7h79o1m30DxZ/EZ5C+2LY8twbGSORvZN4ViMVhIhWBTlOE/iVBOj807Y2OaUURcuLfHRmaCcfF1uIzg0uNB/aM/WSE0+AXh2IX+mipoTS3eh/V2EKldBHcOQ==
160 d334afc585e29577f271c5eda03378736a16ca6b 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlpzZuUQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91TiDEADDD6Tn04UjgrZ36nAqOcHaG1ZT2Cm1/sbTw+6duAhf3+uKWFqi2bgcdCBkdfRH7KfEU0GNsPpiC6mzWw3PDWmGhnLJAkR+9FTBU0edK01hkNW8RelDTL5J9IzIGwrP4KFfcUue6yrxU8GnSxnf5Vy/N5ZZzLV/P3hdBte5We9PD5KHPAwTzzcZ9Wiog700rFDDChyFq7hNQ3H0GpknF6+Ck5XmJ3DOqt1MFHk9V4Z/ASU59cQXKOeaMChlBpTb1gIIWjOE99v5aY06dc1WlwttuHtCZvZgtAduRAB6XYWyniS/7nXBv0MXD3EWbpH1pkOaWUxw217HpNP4g9Yo3u/i8UW+NkSJOeXtC1CFjWmUNj138IhS1pogaiPPnIs+H6eOJsmnGhN2KbOMjA5Dn9vSTi6s/98TarfUSiwxA4L7fJy5qowFETftuBO0fJpbB8+ZtpnjNp0MMKed27OUSv69i6BmLrP+eqk+MVO6PovvIySlWAP9/REM/I5/mFkqoI+ruT4a9osNGDZ4Jqb382b7EmpEMDdgb7+ezsybgDfizuaTs/LBae7h79o1m30DxZ/EZ5C+2LY8twbGSORvZN4ViMVhIhWBTlOE/iVBOj807Y2OaUURcuLfHRmaCcfF1uIzg0uNB/aM/WSE0+AXh2IX+mipoTS3eh/V2EKldBHcOQ==
161 369aadf7a3264b03c8b09efce715bc41e6ab4a9b 0 iQJVBAABCAA/FiEEOoFVFj0OIKUw/LeGR6Z/+qNGqs4FAlqe5w8hHGtidWxsb2NrK21lcmN1cmlhbEByaW5nd29ybGQub3JnAAoJEEemf/qjRqrO1lUQAK6+S26rE3AMt6667ClT+ubPl+nNMRkWJXa8EyPplBUGTPdMheViOe+28dCsveJxqUF7A4TMLMA/eIj4cRIwmVbBaivfQKnG5GMZ+9N6j6oqE/OAJujdHzzZ3+o9KJGtRgJP2tzdY/6qkXwL3WN6KULz7pSkrKZLOiNfj4k2bf3bXeB7d3N5erxJYlhddlPBlHXImRkWiPR/bdaAaYJq+EEWCbia6MWXlSAqEjIgQi+ytuh/9Z+QSsJCsECDRqEExZClqHGkCLYhST99NqqdYCGJzAFMgh+xWxZxI0LO08pJxYctHGoHm+vvRVMfmdbxEydEy01H6jX+1e7Yq44bovIiIOkaXCTSuEBol+R5aPKJhgvqgZ5IlcTLoIYQBE3MZMKZ89NWy3TvgcNkQiOPCCkKs1+DukXKqTt62zOTxfa6mIZDCXdGai6vZBJ5b0yeEd3HV96yHb9dFlS5w1cG7prIBRv5BkqEaFbRMGZGV31Ri7BuVu0O68Pfdq+R+4A1YLdJ0H5DySe2dGlwE2DMKhdtVu1bie4UWHK10TphmqhBk6B9Ew2+tASCU7iczAqRzyzMLBTHIfCYO2R+5Yuh0CApt47KV23OcLje9nORyE2yaDTbVUPiXzdOnbRaCQf7eW5/1y/LLjG6OwtuETTcHKh7ruko+u7rFL96a4DNlNdk
161 369aadf7a3264b03c8b09efce715bc41e6ab4a9b 0 iQJVBAABCAA/FiEEOoFVFj0OIKUw/LeGR6Z/+qNGqs4FAlqe5w8hHGtidWxsb2NrK21lcmN1cmlhbEByaW5nd29ybGQub3JnAAoJEEemf/qjRqrO1lUQAK6+S26rE3AMt6667ClT+ubPl+nNMRkWJXa8EyPplBUGTPdMheViOe+28dCsveJxqUF7A4TMLMA/eIj4cRIwmVbBaivfQKnG5GMZ+9N6j6oqE/OAJujdHzzZ3+o9KJGtRgJP2tzdY/6qkXwL3WN6KULz7pSkrKZLOiNfj4k2bf3bXeB7d3N5erxJYlhddlPBlHXImRkWiPR/bdaAaYJq+EEWCbia6MWXlSAqEjIgQi+ytuh/9Z+QSsJCsECDRqEExZClqHGkCLYhST99NqqdYCGJzAFMgh+xWxZxI0LO08pJxYctHGoHm+vvRVMfmdbxEydEy01H6jX+1e7Yq44bovIiIOkaXCTSuEBol+R5aPKJhgvqgZ5IlcTLoIYQBE3MZMKZ89NWy3TvgcNkQiOPCCkKs1+DukXKqTt62zOTxfa6mIZDCXdGai6vZBJ5b0yeEd3HV96yHb9dFlS5w1cG7prIBRv5BkqEaFbRMGZGV31Ri7BuVu0O68Pfdq+R+4A1YLdJ0H5DySe2dGlwE2DMKhdtVu1bie4UWHK10TphmqhBk6B9Ew2+tASCU7iczAqRzyzMLBTHIfCYO2R+5Yuh0CApt47KV23OcLje9nORyE2yaDTbVUPiXzdOnbRaCQf7eW5/1y/LLjG6OwtuETTcHKh7ruko+u7rFL96a4DNlNdk
162 8bba684efde7f45add05f737952093bb2aa07155 0 iQJVBAABCAA/FiEEOoFVFj0OIKUw/LeGR6Z/+qNGqs4FAlqe6dkhHGtidWxsb2NrK21lcmN1cmlhbEByaW5nd29ybGQub3JnAAoJEEemf/qjRqrOJmIQALUVCoWUFYYaRxGH4OpmIQ2o1JrMefvarFhaPY1r3+G87sjXgw15uobEQDtoybTUYbcdSxJQT1KE1FOm3wU0VyN6PY9c1PMEAVgJlve0eDiXNNlBsoYMXnpq1HidZknkjpXgUPdE/LElxpJJRlJQZlS29bkGmEDZQBoOvlcZoBRDSYcbM07wn7d+1gmJkcHViDBMAbSrudfO0OYzDC1BjtGyKm7Mes2WB1yFYw+ySa8hF/xPKEDvoZINOE5n3PBJiCvPuTw3PqsHvWgKOA1Obx9fATlxj7EHBLfKBTNfpUwPMRSH1cmA+qUS9mRDrdLvrThwalr6D3r2RJ2ntOipcZpKMmxARRV+VUAI1K6H0/Ws3XAxENqhF7RgRruJFVq8G8EcHJLZEoVHsR+VOnd/pzgkFKS+tIsYYRcMpL0DdMF8pV3xrEFahgRhaEZOh4jsG3Z+sGLVFFl7DdMqeGs6m/TwDrvfuYtGczfGRB0wqu8KOwhR1BjNJKcr4lk35GKwSXmI1vk6Z1gAm0e13995lqbCJwkuOKynQlHWVOR6hu3ypvAgV/zXLF5t8HHtL48sOJ8a33THuJT4whbXSIb9BQXu/NQnNhK8G3Kly5UN88vL4a3sZi/Y86h4R2fKOSib/txJ3ydLbMeS8LlJMqeF/hrBanVF0r15NZ2CdmL1Qxim
162 8bba684efde7f45add05f737952093bb2aa07155 0 iQJVBAABCAA/FiEEOoFVFj0OIKUw/LeGR6Z/+qNGqs4FAlqe6dkhHGtidWxsb2NrK21lcmN1cmlhbEByaW5nd29ybGQub3JnAAoJEEemf/qjRqrOJmIQALUVCoWUFYYaRxGH4OpmIQ2o1JrMefvarFhaPY1r3+G87sjXgw15uobEQDtoybTUYbcdSxJQT1KE1FOm3wU0VyN6PY9c1PMEAVgJlve0eDiXNNlBsoYMXnpq1HidZknkjpXgUPdE/LElxpJJRlJQZlS29bkGmEDZQBoOvlcZoBRDSYcbM07wn7d+1gmJkcHViDBMAbSrudfO0OYzDC1BjtGyKm7Mes2WB1yFYw+ySa8hF/xPKEDvoZINOE5n3PBJiCvPuTw3PqsHvWgKOA1Obx9fATlxj7EHBLfKBTNfpUwPMRSH1cmA+qUS9mRDrdLvrThwalr6D3r2RJ2ntOipcZpKMmxARRV+VUAI1K6H0/Ws3XAxENqhF7RgRruJFVq8G8EcHJLZEoVHsR+VOnd/pzgkFKS+tIsYYRcMpL0DdMF8pV3xrEFahgRhaEZOh4jsG3Z+sGLVFFl7DdMqeGs6m/TwDrvfuYtGczfGRB0wqu8KOwhR1BjNJKcr4lk35GKwSXmI1vk6Z1gAm0e13995lqbCJwkuOKynQlHWVOR6hu3ypvAgV/zXLF5t8HHtL48sOJ8a33THuJT4whbXSIb9BQXu/NQnNhK8G3Kly5UN88vL4a3sZi/Y86h4R2fKOSib/txJ3ydLbMeS8LlJMqeF/hrBanVF0r15NZ2CdmL1Qxim
163 7de7bd407251af2bc98e5b809c8598ee95830daf 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlrE4p0QHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91c4UD/4tC+mBWxBw/JYm4vlFTKWLHopLEa1/uhFRK/uGsdgcCyexbCDbisjJpl3JTQb+wQDlZnUorm8zB206y418YqhJ7lCauRgcoqKka0e3kvKnwmklwmuGkwOIoruWxxhCcgRCT4C+jZ/ZE3Kre0CKnUvlASsHtbkqrCqFClEcIlPVohlccmjbpQXN+akB40tkMF5Xf0AMBPYG7UievmeHhz3pO/yex/Uc6RhgWAqD4zjA1bh+3REGs3CaoYgKUTXZw/XYI9cqAI0FobRuXSVbq2dqkXCFLfD+WizxUz55rZA+CP4pqLndwxGm4fLy4gk2iLHxKfrHsAul7n5e4tHmxDcOOa1K0fIJDBijuXoNfXN7nF4NQUlfpmtOxUxfniVohvXJeYV8ecepsDMSFqDtEtbdhsep5QDx85lGLNLQAA1f36swJzLBSqGw688Hjql2c9txK2eVrVxNp+M8tqn9qU/h2/firgu9a2DxQB45M7ISfkutmpizN5TNlEyElH0htHnKG7+AIbRAm4novCXfSzP8eepk0kVwj9QMIx/rw4aeicRdPWBTcDIG0gWELb0skunTQqeZwPPESwimntdmwCxfFksgT0t79ZEDAWWfxNLhJP/HWO2mYG5GUJOzNQ4rj/YXLcye6A4KkhvuZlVCaKAbnm60ivoG082HYuozV4qPOQ==
163 7de7bd407251af2bc98e5b809c8598ee95830daf 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlrE4p0QHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91c4UD/4tC+mBWxBw/JYm4vlFTKWLHopLEa1/uhFRK/uGsdgcCyexbCDbisjJpl3JTQb+wQDlZnUorm8zB206y418YqhJ7lCauRgcoqKka0e3kvKnwmklwmuGkwOIoruWxxhCcgRCT4C+jZ/ZE3Kre0CKnUvlASsHtbkqrCqFClEcIlPVohlccmjbpQXN+akB40tkMF5Xf0AMBPYG7UievmeHhz3pO/yex/Uc6RhgWAqD4zjA1bh+3REGs3CaoYgKUTXZw/XYI9cqAI0FobRuXSVbq2dqkXCFLfD+WizxUz55rZA+CP4pqLndwxGm4fLy4gk2iLHxKfrHsAul7n5e4tHmxDcOOa1K0fIJDBijuXoNfXN7nF4NQUlfpmtOxUxfniVohvXJeYV8ecepsDMSFqDtEtbdhsep5QDx85lGLNLQAA1f36swJzLBSqGw688Hjql2c9txK2eVrVxNp+M8tqn9qU/h2/firgu9a2DxQB45M7ISfkutmpizN5TNlEyElH0htHnKG7+AIbRAm4novCXfSzP8eepk0kVwj9QMIx/rw4aeicRdPWBTcDIG0gWELb0skunTQqeZwPPESwimntdmwCxfFksgT0t79ZEDAWWfxNLhJP/HWO2mYG5GUJOzNQ4rj/YXLcye6A4KkhvuZlVCaKAbnm60ivoG082HYuozV4qPOQ==
164 ed5448edcbfa747b9154099e18630e49024fd47b 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlrXnuoQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91fSHEACBVg4FsCE2nN5aEKAQb7l7rG4XTQ9FbvoTYB3tkvmsLQSRfh2GB2ZDBOI7Vswo2UxXupr4qSkUQbeHrwrk9A1s5b/T5e4wSKZuFJOrkwLVZDFfUHumKomqdoVj/D8+LDt7Rz+Wm7OClO/4dTAsl2E4rkl7XPtqjC3jESGad8IBANlPVBhNUMER4eFcPZzq1qi2MrlJKEKpdeZEWJ/ow7gka/aTLqHMfRwhA3kS5X34Yai17kLQZGQdWISWYiM9Zd2b/FSTHZGy8rf9cvjXs3EXfEB5nePveDrFOfmuubVRDplO+/naJjNBqwxeB99jb7Fk3sekPZNW/NqR/w1jvQFA3OP9fS2g1OwfXMWyx6DvBJNfQwppNH3JUvA5PEiorul4GJ2nuubXk+Or1yzoRJtwOGz/GQi2BcsPKaL6niewrInFw18jMVhx/4Jbpu+glaim4EvT/PfJ5KdSwF7pJxsoiqvw7A2C2/DsZRbCeal9GrTulkNf/hgpCJOBK1DqVVq1O5MI/oYQ69HxgMq9Ip1OGJJhse3qjevBJbpNCosCpjb3htlo4go29H8yyGJb09i05WtNW2EQchrTHrlruFr7mKJ5h1mAYket74QQyaGzqwgD5kwSVnIcwHpfb8oiJTwA5R+LtbAQXWC/fFu1g1KEp/4hGOQoRU04+mYuPsrzaA==
164 ed5448edcbfa747b9154099e18630e49024fd47b 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlrXnuoQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91fSHEACBVg4FsCE2nN5aEKAQb7l7rG4XTQ9FbvoTYB3tkvmsLQSRfh2GB2ZDBOI7Vswo2UxXupr4qSkUQbeHrwrk9A1s5b/T5e4wSKZuFJOrkwLVZDFfUHumKomqdoVj/D8+LDt7Rz+Wm7OClO/4dTAsl2E4rkl7XPtqjC3jESGad8IBANlPVBhNUMER4eFcPZzq1qi2MrlJKEKpdeZEWJ/ow7gka/aTLqHMfRwhA3kS5X34Yai17kLQZGQdWISWYiM9Zd2b/FSTHZGy8rf9cvjXs3EXfEB5nePveDrFOfmuubVRDplO+/naJjNBqwxeB99jb7Fk3sekPZNW/NqR/w1jvQFA3OP9fS2g1OwfXMWyx6DvBJNfQwppNH3JUvA5PEiorul4GJ2nuubXk+Or1yzoRJtwOGz/GQi2BcsPKaL6niewrInFw18jMVhx/4Jbpu+glaim4EvT/PfJ5KdSwF7pJxsoiqvw7A2C2/DsZRbCeal9GrTulkNf/hgpCJOBK1DqVVq1O5MI/oYQ69HxgMq9Ip1OGJJhse3qjevBJbpNCosCpjb3htlo4go29H8yyGJb09i05WtNW2EQchrTHrlruFr7mKJ5h1mAYket74QQyaGzqwgD5kwSVnIcwHpfb8oiJTwA5R+LtbAQXWC/fFu1g1KEp/4hGOQoRU04+mYuPsrzaA==
165 1ec874717d8a93b19e0d50628443e0ee5efab3a9 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlraM3wQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91RAJEACSnf/HWwS0/OZaqz4Hfh0UBgkXDmH1IC90Pc/kczf//WuXu5AVnnRHDziOlCYYZAnZ2iKu0EQI6GT2K2garaWkaEhukOnjz4WADVys6DAzJyw5iOXeEpIOlZH6hbYbsW3zVcPjiMPo8cY5tIYEy4E/8RcVly1SDtWxvt/nWYQd2MxObLrpU7bPP6a2Db4Vy8WpGRbZRJmOvDNworld5rB5M/OGgHyMa9hg2Hjn+cLtQSEJY4O92A6h2hix9xpDC7zzfoluD2piDslocTm/gyeln2BJJBAtr+aRoHO9hI0baq5yFRQLO8aqQRJJP8dXgYZIWgSU/9oVGPZoGotJyw24iiB37R/YCisKE+cEUjfVclHTDFCkzmYP2ZMbGaktohJeF7EMau0ZJ8II5F0ja3bj6GrwfpGGY5OOcQrzIYW7nB0msFWTljb34qN3nd7m+hQ5hji3Hp9CFXEbCboVmm46LqwukSDWTmnfcP8knxWbBlJ4xDxySwTtcHAJhnUmKxu7oe3D/0Ttdv7HscI40eeMdr01pLQ0Ee3a4OumQ1hn+oL+o+tlqg8PKT20q528CMHgSJp6aIlU7pEK81b+Zj6B57us4P97qSL6XLNUIfubADCaf/KUDwh1HvKhHXV2aRli1GX1REFsy0ItGZn0yhQxIDJKc/FKsEMBKvlVIHGQFw==
165 1ec874717d8a93b19e0d50628443e0ee5efab3a9 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlraM3wQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91RAJEACSnf/HWwS0/OZaqz4Hfh0UBgkXDmH1IC90Pc/kczf//WuXu5AVnnRHDziOlCYYZAnZ2iKu0EQI6GT2K2garaWkaEhukOnjz4WADVys6DAzJyw5iOXeEpIOlZH6hbYbsW3zVcPjiMPo8cY5tIYEy4E/8RcVly1SDtWxvt/nWYQd2MxObLrpU7bPP6a2Db4Vy8WpGRbZRJmOvDNworld5rB5M/OGgHyMa9hg2Hjn+cLtQSEJY4O92A6h2hix9xpDC7zzfoluD2piDslocTm/gyeln2BJJBAtr+aRoHO9hI0baq5yFRQLO8aqQRJJP8dXgYZIWgSU/9oVGPZoGotJyw24iiB37R/YCisKE+cEUjfVclHTDFCkzmYP2ZMbGaktohJeF7EMau0ZJ8II5F0ja3bj6GrwfpGGY5OOcQrzIYW7nB0msFWTljb34qN3nd7m+hQ5hji3Hp9CFXEbCboVmm46LqwukSDWTmnfcP8knxWbBlJ4xDxySwTtcHAJhnUmKxu7oe3D/0Ttdv7HscI40eeMdr01pLQ0Ee3a4OumQ1hn+oL+o+tlqg8PKT20q528CMHgSJp6aIlU7pEK81b+Zj6B57us4P97qSL6XLNUIfubADCaf/KUDwh1HvKhHXV2aRli1GX1REFsy0ItGZn0yhQxIDJKc/FKsEMBKvlVIHGQFw==
166 6614cac550aea66d19c601e45efd1b7bd08d7c40 0 iQJVBAABCAA/FiEEOoFVFj0OIKUw/LeGR6Z/+qNGqs4FAlruOCQhHGtidWxsb2NrK21lcmN1cmlhbEByaW5nd29ybGQub3JnAAoJEEemf/qjRqrOENQQAI1ttaffqYucUEyBARP1GDlZMIGDJgNG7smPMU4Sw7YEzB9mcmxnBFlPx/9n973ucEnLJVONBSZq0VWIKJwPp1RMBpAHuGrMlhkMvYIAukg5EBN3YpA1UogHYycwLj2Ye7fNgiN5FIkaodt9++c4d1Lfu658A2pAeg8qUn5uJ77vVcZRp988u9eVDQfubS8P6bB4KZc87VDAUUeXy+AcS9KHGBmdRAabwU4m09VPZ4h8NEj3+YUPnKXBaNK9pXK5pnkmB8uFePayimnw6St6093oylQTVw/tfxGLBImnHw+6KCu2ut9r5PxXEVxVYpranGbS4jYqpzRtpQBxyo/Igu7fqrioR2rGLQL5NcHsoUEdOC7VW+0HgHjXKtRy7agmcFcgjFco47D3hor7Y16lwgm+RV2EWQ/u2M4Bbo1EWj1oxQ/0j5DOM5UeAJ3Jh64gb4sCDqJfADR8NQaxh7QiqYhn69IcjsEfzU/11VuqWXlQgghJhEEP/bojRyM0qee87CKLiTescafIfnRsNQhyhsKqdHU1QAp29cCqh3mzNxJH3PDYg4fjRaGW4PM7K5gmSXFn/Ifeza0cuZ4XLdYZ76Z1BG80pqBpKZy1unGob+RpItlSmO5jQw7OoRuf0q3Id92gawUDDLuQ7Xg3zOVqV8/wJBlHM7ZUz162bnNsO5Hn
166 6614cac550aea66d19c601e45efd1b7bd08d7c40 0 iQJVBAABCAA/FiEEOoFVFj0OIKUw/LeGR6Z/+qNGqs4FAlruOCQhHGtidWxsb2NrK21lcmN1cmlhbEByaW5nd29ybGQub3JnAAoJEEemf/qjRqrOENQQAI1ttaffqYucUEyBARP1GDlZMIGDJgNG7smPMU4Sw7YEzB9mcmxnBFlPx/9n973ucEnLJVONBSZq0VWIKJwPp1RMBpAHuGrMlhkMvYIAukg5EBN3YpA1UogHYycwLj2Ye7fNgiN5FIkaodt9++c4d1Lfu658A2pAeg8qUn5uJ77vVcZRp988u9eVDQfubS8P6bB4KZc87VDAUUeXy+AcS9KHGBmdRAabwU4m09VPZ4h8NEj3+YUPnKXBaNK9pXK5pnkmB8uFePayimnw6St6093oylQTVw/tfxGLBImnHw+6KCu2ut9r5PxXEVxVYpranGbS4jYqpzRtpQBxyo/Igu7fqrioR2rGLQL5NcHsoUEdOC7VW+0HgHjXKtRy7agmcFcgjFco47D3hor7Y16lwgm+RV2EWQ/u2M4Bbo1EWj1oxQ/0j5DOM5UeAJ3Jh64gb4sCDqJfADR8NQaxh7QiqYhn69IcjsEfzU/11VuqWXlQgghJhEEP/bojRyM0qee87CKLiTescafIfnRsNQhyhsKqdHU1QAp29cCqh3mzNxJH3PDYg4fjRaGW4PM7K5gmSXFn/Ifeza0cuZ4XLdYZ76Z1BG80pqBpKZy1unGob+RpItlSmO5jQw7OoRuf0q3Id92gawUDDLuQ7Xg3zOVqV8/wJBlHM7ZUz162bnNsO5Hn
167 9c5ced5276d6e7d54f7c3dadf5247b7ee98ec79c 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlsYGdAQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91S3fEACmrG3S5eAUhnKqkXFe+HZUwmUvLKRhyWDLlWQzEHaJZQCFWxqSM1ag7JtAx3WkWwmWrOZ0+T/w/xMv81h9JAv9RsoszUT/RH4RsnWoc2ddcK93Q/PrNJ29kFjvC8j3LF42WfHEIeNqAki5c3GbprUL86KG7XVYuMvpPI/SeNSz8siPaKjXo6sg6bAupPCyapisTmeRHcCUc5UfeTTq4YQdS9UI0p9Fo8/vcqmnWY6XnQCRYs2U8Y2I2QCJBHBE5p4KrxrFsAdPWMCg0dJT0goSbzpfDjukPHQaAnUKjCtXCwrzA/KY8fDH9hm5tt1FnC6nl6BRpEHRoHqTfE1ag2QktJZTn5+JWpzz85qFDl5ktmxj1gS80jkOUJ2699RykBy7NACu+TtLJdBk+E1TN0pAU+zsrTSGiteuikEBjQP/8i4whUZCFIHLPgVlxrHWwn0/oszj1Q/u86sCxnYTflR2GLZs3fbSGBEKDDrjqwetxMlwi/3Qhf0PN9aAI7S13YnA89tGLGRLTsVsOoKiQoTExQaCUpE5jFYBLVjsTPh2AjPhG3Zaf7R5ZIvW4CbVYORNTMaYhFNnFyczILJLRid+INHLVifNiJuaLiAFD5Izq9Me4H+GpwB5AI7aG1r+01Si2KbqqpdfoK430UeDV+U/MvEU7v0RoeF30M7uVYv+kg==
167 9c5ced5276d6e7d54f7c3dadf5247b7ee98ec79c 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlsYGdAQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91S3fEACmrG3S5eAUhnKqkXFe+HZUwmUvLKRhyWDLlWQzEHaJZQCFWxqSM1ag7JtAx3WkWwmWrOZ0+T/w/xMv81h9JAv9RsoszUT/RH4RsnWoc2ddcK93Q/PrNJ29kFjvC8j3LF42WfHEIeNqAki5c3GbprUL86KG7XVYuMvpPI/SeNSz8siPaKjXo6sg6bAupPCyapisTmeRHcCUc5UfeTTq4YQdS9UI0p9Fo8/vcqmnWY6XnQCRYs2U8Y2I2QCJBHBE5p4KrxrFsAdPWMCg0dJT0goSbzpfDjukPHQaAnUKjCtXCwrzA/KY8fDH9hm5tt1FnC6nl6BRpEHRoHqTfE1ag2QktJZTn5+JWpzz85qFDl5ktmxj1gS80jkOUJ2699RykBy7NACu+TtLJdBk+E1TN0pAU+zsrTSGiteuikEBjQP/8i4whUZCFIHLPgVlxrHWwn0/oszj1Q/u86sCxnYTflR2GLZs3fbSGBEKDDrjqwetxMlwi/3Qhf0PN9aAI7S13YnA89tGLGRLTsVsOoKiQoTExQaCUpE5jFYBLVjsTPh2AjPhG3Zaf7R5ZIvW4CbVYORNTMaYhFNnFyczILJLRid+INHLVifNiJuaLiAFD5Izq9Me4H+GpwB5AI7aG1r+01Si2KbqqpdfoK430UeDV+U/MvEU7v0RoeF30M7uVYv+kg==
168 0b63a6743010dfdbf8a8154186e119949bdaa1cc 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAls7n+0QHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91XVGEAC1aPuUmW9R0QjWUmyY4vMO7AOT4F1sHKrkgNaoG/RCvczuZOCz/fGliEKQ52pkvThrOgOvNfJlIGOu91noLKsYUybO8eeTksCzc7agUjk6/Xsed35D8gNEPuiVTNu379sTQRnOA2T/plQnVCY2PjMzBe6nQ2DJYnggJelCUxuqUsLM76OvMEeNlXvyxZmyAcFT5dfSBYbjAt0kklRRQWgaug3GwLJY/+0tmXhq0tCpAF6myXoVQm/ynSxjR+5+2/+F5nudOQmDnL0zGayOAQU97RLAAxf1L+3DTRfbtxams9ZrGfRzQGcI1d4I4ernfnFYI19kSzMPcW4qI7gQQlTfOzs8X5d2fKiqUFjlgOO42hgM6cQv2Hx3u+bxF00sAvrW8sWRjfMQACuNH3FJoeIubpohN5o1Madv4ayGAZkcyskYRCs9X40gn+Q9gv34uknjaF/mep7BBl08JC9zFqwGaLyCssSsHV7ncekkUZfcWfq4TNNEUZFIu7UtsnZYz0aYrueAKMp+4udTjfKKnSZL2o0n1g11iH9KTQO/dWP7rVbu/OIbLeE+D87oXOWGfDNBRyHLItrM70Vum0HxtFuWc1clj8qzF61Mx0umFfUmdGQcl9DGivmc7TLNzBKG11ElDuDIey6Yxc6nwWiAJ6v1H5bO3WBi/klbT2fWguOo5w==
168 0b63a6743010dfdbf8a8154186e119949bdaa1cc 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAls7n+0QHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91XVGEAC1aPuUmW9R0QjWUmyY4vMO7AOT4F1sHKrkgNaoG/RCvczuZOCz/fGliEKQ52pkvThrOgOvNfJlIGOu91noLKsYUybO8eeTksCzc7agUjk6/Xsed35D8gNEPuiVTNu379sTQRnOA2T/plQnVCY2PjMzBe6nQ2DJYnggJelCUxuqUsLM76OvMEeNlXvyxZmyAcFT5dfSBYbjAt0kklRRQWgaug3GwLJY/+0tmXhq0tCpAF6myXoVQm/ynSxjR+5+2/+F5nudOQmDnL0zGayOAQU97RLAAxf1L+3DTRfbtxams9ZrGfRzQGcI1d4I4ernfnFYI19kSzMPcW4qI7gQQlTfOzs8X5d2fKiqUFjlgOO42hgM6cQv2Hx3u+bxF00sAvrW8sWRjfMQACuNH3FJoeIubpohN5o1Madv4ayGAZkcyskYRCs9X40gn+Q9gv34uknjaF/mep7BBl08JC9zFqwGaLyCssSsHV7ncekkUZfcWfq4TNNEUZFIu7UtsnZYz0aYrueAKMp+4udTjfKKnSZL2o0n1g11iH9KTQO/dWP7rVbu/OIbLeE+D87oXOWGfDNBRyHLItrM70Vum0HxtFuWc1clj8qzF61Mx0umFfUmdGQcl9DGivmc7TLNzBKG11ElDuDIey6Yxc6nwWiAJ6v1H5bO3WBi/klbT2fWguOo5w==
169 e90130af47ce8dd53a3109aed9d15876b3e7dee8 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAltQ1bUQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91RQVD/9NA5t2mlt7pFc0Sswktc5dI8GaSYxgeknacLkEdkYx9L+mzg77G7TGueeu5duovjdI/vDIzdadGtJJ+zJE5icCqeUFDfNZNZLQ+7StuC8/f+4i/DaCzjHJ4tDYd0x6R5efisLWRKkWoodI1Iit7gCL493gj1HZaIzRLaqYkbOk3PhOEkTcov2cnhb4h54OKm07qlg6PYH507WGmmTDDnhL9SwdfBXHA2ps9dCe52NzPMyebXoZYA9T5Yz67eQ8D+YCh9bLauA59dW0Iyx59yGJ0tmLwVKBgbUkynAknwk/hdNlF7r6wLqbR00NLKmAZl8crdVSqFUU/vAsPQLn3BkbtpzqjmisIq2BWEt/YWYZOHUvJoK81cRcsVpPuAOIQM/rTm9pprTq7RFtuVnCj+QnmWwEPZJcS/7pnnIXte3gQt76ovLuFxr7dq99anEA7gnTbSdADIzgZhJMM8hJcrcgvbI4xz0H1qKn3webTNl/jPgTsNjAPYcmRZcoU2wUIR+OPhZvfwhvreRX0dGUV6gqxWnx3u3dsWE9jcBIGlNfYnIkLXyqBdOL6f4yQoxaVjRg/ScEt3hU17TknuPIDOXE/iMgWnYpnTqKBolt/Vbx7qB1OiK7AmQvXY1bnhtkIfOoIwZ9X1Zi2vmV1Wz4G0a5Vxq5eNKpQgACA2HE0MS2HQ==
169 e90130af47ce8dd53a3109aed9d15876b3e7dee8 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAltQ1bUQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91RQVD/9NA5t2mlt7pFc0Sswktc5dI8GaSYxgeknacLkEdkYx9L+mzg77G7TGueeu5duovjdI/vDIzdadGtJJ+zJE5icCqeUFDfNZNZLQ+7StuC8/f+4i/DaCzjHJ4tDYd0x6R5efisLWRKkWoodI1Iit7gCL493gj1HZaIzRLaqYkbOk3PhOEkTcov2cnhb4h54OKm07qlg6PYH507WGmmTDDnhL9SwdfBXHA2ps9dCe52NzPMyebXoZYA9T5Yz67eQ8D+YCh9bLauA59dW0Iyx59yGJ0tmLwVKBgbUkynAknwk/hdNlF7r6wLqbR00NLKmAZl8crdVSqFUU/vAsPQLn3BkbtpzqjmisIq2BWEt/YWYZOHUvJoK81cRcsVpPuAOIQM/rTm9pprTq7RFtuVnCj+QnmWwEPZJcS/7pnnIXte3gQt76ovLuFxr7dq99anEA7gnTbSdADIzgZhJMM8hJcrcgvbI4xz0H1qKn3webTNl/jPgTsNjAPYcmRZcoU2wUIR+OPhZvfwhvreRX0dGUV6gqxWnx3u3dsWE9jcBIGlNfYnIkLXyqBdOL6f4yQoxaVjRg/ScEt3hU17TknuPIDOXE/iMgWnYpnTqKBolt/Vbx7qB1OiK7AmQvXY1bnhtkIfOoIwZ9X1Zi2vmV1Wz4G0a5Vxq5eNKpQgACA2HE0MS2HQ==
170 33ac6a72308a215e6086fbced347ec10aa963b0a 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlthwaIQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91atOD/0de4nA55WJpiQzAqTg4xWIRZB6y0pkQ8D4cKNQkNiwPQAdDEPf85RuYmoPusNxhM40qfJlmHOw8sbRaqqabhVBPEzL1DpKe4GBucagLZqoL3pycyMzhkhzMka2RJT6nekCchTKJTIs2gx4FOA/QwaFYNkXFfguAEvi01isVdMo0GFLQ7pf7wU8UO1PPdkYphH0xPUvsreQ3pR3+6WwMLovk4JYW4cSaM4YkLlqJQPSO2YAlyXAwiQRvu2A227ydVqHOgLeV5zMQPy2v2zTgl2AoMdWp8+g2lJrYwclkNR+LAk5OlGYamyZwlmsTO7OX3n7xJYtfjbqdoqEKhO1igMi3ZSjqwkaBxxkXxArrteD19bpUyInTjbwTRO3mSe5aNkEDGoOYWn8UOn5ZkeEo7NyhP4OTXqyxQs9rwjD79xZk+6fGB777vuZDUdLZYRQFOPEximpmCGJDrZWj5PeIALWkrRGWBl2eFJ5sl6/pFlUJDjDEstnrsfosp6NJ3VFiD9EunFWsTlV2qXaueh9+TfaSRmGHVuwFCDt7nATVEzTt8l74xsL3xUPS4u9EcNPuEhCRu1zLojCGjemEA29R9tJS8oWd6SwXKryzjo8SyN7yQVSM/yl212IOiOHTQF8vVZuJnailtcWc3D4NoOxntnnv8fnd1nr8M5QSjYQVzSkHw==
170 33ac6a72308a215e6086fbced347ec10aa963b0a 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlthwaIQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91atOD/0de4nA55WJpiQzAqTg4xWIRZB6y0pkQ8D4cKNQkNiwPQAdDEPf85RuYmoPusNxhM40qfJlmHOw8sbRaqqabhVBPEzL1DpKe4GBucagLZqoL3pycyMzhkhzMka2RJT6nekCchTKJTIs2gx4FOA/QwaFYNkXFfguAEvi01isVdMo0GFLQ7pf7wU8UO1PPdkYphH0xPUvsreQ3pR3+6WwMLovk4JYW4cSaM4YkLlqJQPSO2YAlyXAwiQRvu2A227ydVqHOgLeV5zMQPy2v2zTgl2AoMdWp8+g2lJrYwclkNR+LAk5OlGYamyZwlmsTO7OX3n7xJYtfjbqdoqEKhO1igMi3ZSjqwkaBxxkXxArrteD19bpUyInTjbwTRO3mSe5aNkEDGoOYWn8UOn5ZkeEo7NyhP4OTXqyxQs9rwjD79xZk+6fGB777vuZDUdLZYRQFOPEximpmCGJDrZWj5PeIALWkrRGWBl2eFJ5sl6/pFlUJDjDEstnrsfosp6NJ3VFiD9EunFWsTlV2qXaueh9+TfaSRmGHVuwFCDt7nATVEzTt8l74xsL3xUPS4u9EcNPuEhCRu1zLojCGjemEA29R9tJS8oWd6SwXKryzjo8SyN7yQVSM/yl212IOiOHTQF8vVZuJnailtcWc3D4NoOxntnnv8fnd1nr8M5QSjYQVzSkHw==
171 ede3bf31fe63677fdf5bd8db687977d4e3d792ed 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAluOq84QHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91ao3D/oC9zKNbk+MMUP0cSfl+ESRbP/sAI466IYDkr9f1klooIFMsdqCd16eS36DVwIwrBYapRaNszC6Pg0KCFKCdeAWJLcgeIawwOkZPrLKQmS3I9GTl9gxtExeFvRryaAdP1DAPEU6JkyHo3xmURkJB58VjuBquZz4cYnL2aE1ag04CWAoRFiLu6bt1hEZ8pONU6cbDpHaJVyUZmJRB+llpybgdLnlBTrhfWjNofTh8MM6+vz67lIienYoSbepY+029J98phBTV+UEfWSBWw1hcNT/+QmOBGWWTLfBARsNDZFeYgQQOo3gRghKO7qUA/hqzDTmMG4/a2obs0LGsBlcMZ1Ky//zhdAJ/EN7uH9svM1t1fkw1RgvftmybptK5KiusZ9AWhnggHSwZtj1I6i/sojqsj9MrtdrD+1LfiKuAv/FtcMHSeff8IfItrd2B67JIj4wCzU8vDrAbAAqODHx7AnssvNbYrH2iOigSINFMNJoLU/xLxBhTxitU2Zf8puHA4CQ3+BybgOH9HPqCtGcVAB7bcp4hiezGrachM+2oec2YwcGCpIobMPl43cmWkLhtGF5qfl7APVfbo18UXk8ZGmBY8YAYwEyksk2SBMJV6+XHw9J7uaaugc3uN8PuMVLqvSMpWN1ZdRsSkxrOJK+UNW7kbUi0wHnsV1rN0U0BIfVOQ==
171 ede3bf31fe63677fdf5bd8db687977d4e3d792ed 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAluOq84QHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91ao3D/oC9zKNbk+MMUP0cSfl+ESRbP/sAI466IYDkr9f1klooIFMsdqCd16eS36DVwIwrBYapRaNszC6Pg0KCFKCdeAWJLcgeIawwOkZPrLKQmS3I9GTl9gxtExeFvRryaAdP1DAPEU6JkyHo3xmURkJB58VjuBquZz4cYnL2aE1ag04CWAoRFiLu6bt1hEZ8pONU6cbDpHaJVyUZmJRB+llpybgdLnlBTrhfWjNofTh8MM6+vz67lIienYoSbepY+029J98phBTV+UEfWSBWw1hcNT/+QmOBGWWTLfBARsNDZFeYgQQOo3gRghKO7qUA/hqzDTmMG4/a2obs0LGsBlcMZ1Ky//zhdAJ/EN7uH9svM1t1fkw1RgvftmybptK5KiusZ9AWhnggHSwZtj1I6i/sojqsj9MrtdrD+1LfiKuAv/FtcMHSeff8IfItrd2B67JIj4wCzU8vDrAbAAqODHx7AnssvNbYrH2iOigSINFMNJoLU/xLxBhTxitU2Zf8puHA4CQ3+BybgOH9HPqCtGcVAB7bcp4hiezGrachM+2oec2YwcGCpIobMPl43cmWkLhtGF5qfl7APVfbo18UXk8ZGmBY8YAYwEyksk2SBMJV6+XHw9J7uaaugc3uN8PuMVLqvSMpWN1ZdRsSkxrOJK+UNW7kbUi0wHnsV1rN0U0BIfVOQ==
172 5405cb1a79010ac50c58cd84e6f50c4556bf2a4c 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAluyfokQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91eWpD/0eu/JfD6SfaT4Ozd2767ojNIW4M9BgcRH/FehFBd/3iQ/YQmaMVd6GmdaagM5YUpD9U+rDK95l8rUstuTglXeKD2SVcDM4Oq9ToyZyp5aizWjkxRxHT60W95G5FQO/tBbs63jfNrVDWDElbkpcn/gUG6JbX+q/S/mKd6WsuwNQC1N4VOWp0OWCmFGBWN7t/DqxGLGEajJM0NB97/r/IV6TzrGtaPf1CXaepDVvZwIIeas/eQgGInyqry7WBSn5sCUq4opIh1UigMABUAgzIZbgTg8NLGSmEgRgk0Vb4K+pLejLLDb5YD7ZwuUCkbd8oJImKQfU6++Ajd70TbNQRvVhMtd15iCtOOjLR+VNkUiDXm0g1U53sREMLdj/+SMJZB6Z18DotdgpaeCmwA/wWijXOdt76xwUKjByioxyQilPrzrWGaoSG4ynjiD2Y+eSRS1DxbpDgt4YEuiVA6U3ay99oW7KkhFjQsUtKl4SJ5SQWiEofvgtb2maNrXkPtKOtNRHhc61v73zYnsxtl2qduC99YOTin90FykD80XvgJZfyow/LICb77MNGwYBsJJMDQ3jG1YyUC2CQsb8wyrWM4TO3tspKAQPyMegUaVtBqw7ZhgiC3OXEes+z+AL5YRSZXALfurXPYbja8M8uGL2TYB3/5bKYvBXxvfmSGIeY6VieQ==
172 5405cb1a79010ac50c58cd84e6f50c4556bf2a4c 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAluyfokQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91eWpD/0eu/JfD6SfaT4Ozd2767ojNIW4M9BgcRH/FehFBd/3iQ/YQmaMVd6GmdaagM5YUpD9U+rDK95l8rUstuTglXeKD2SVcDM4Oq9ToyZyp5aizWjkxRxHT60W95G5FQO/tBbs63jfNrVDWDElbkpcn/gUG6JbX+q/S/mKd6WsuwNQC1N4VOWp0OWCmFGBWN7t/DqxGLGEajJM0NB97/r/IV6TzrGtaPf1CXaepDVvZwIIeas/eQgGInyqry7WBSn5sCUq4opIh1UigMABUAgzIZbgTg8NLGSmEgRgk0Vb4K+pLejLLDb5YD7ZwuUCkbd8oJImKQfU6++Ajd70TbNQRvVhMtd15iCtOOjLR+VNkUiDXm0g1U53sREMLdj/+SMJZB6Z18DotdgpaeCmwA/wWijXOdt76xwUKjByioxyQilPrzrWGaoSG4ynjiD2Y+eSRS1DxbpDgt4YEuiVA6U3ay99oW7KkhFjQsUtKl4SJ5SQWiEofvgtb2maNrXkPtKOtNRHhc61v73zYnsxtl2qduC99YOTin90FykD80XvgJZfyow/LICb77MNGwYBsJJMDQ3jG1YyUC2CQsb8wyrWM4TO3tspKAQPyMegUaVtBqw7ZhgiC3OXEes+z+AL5YRSZXALfurXPYbja8M8uGL2TYB3/5bKYvBXxvfmSGIeY6VieQ==
173 956ec6f1320df26f3133ec40f3de866ea0695fd7 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlvOG20QHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91eZ+EACb/XfPWaMkwIX54JaFWtL/nVkDcaL8xLVzlI+PxL0ZtHdQTGVQNp5f1BnZU9RKPZ9QOuz+QKNvb4hOOXBwmCi2AAjmTYUqtKThHmOT50ZRICkllY+YlZ3tI6JXRDhh7pSXaus8jBFG/VwuUlVmK5sA2TP+lIJijOgV9rThszfS4Q2I8sBTIaeZS1hyujFxGRO++tjYR+jPuo/98FhqJ5EylVYvKmnflWkOYLFNFqgDI6DQs7Dl+u2nrNAzZJQlgk+1ekd66T3WyK8U3tcFLZGRQ+gpzINH0Syn6USaaE+0nGi4we1hJS8JK0txWyHXJGNZYaWQAC2l1hIBfA38azwVLSe2w9JatXhS3HWByILy8JkEQ2kSo1xTD4mBkszZo/kWZpZRsAWydxCnzhNgKmTJYxASFTTX1mpdX4EzJBOs/++52y1OjVc0Ko0+6vSwxsC6zgIGJx1Os7vVgWHql0XbDmJ1NDdNmz7q5HjFcbNOWScKf6UGcBKV4dpW1w+7CvdoMFHUsVTa2zn6YOki3NEt0GWLXq+0aXbHSw8XETcyunQKjDi9ddKOw0rYGip6EKUKhOILZimQ0lgYRE23RDdT5Tl2D8s66SUuipgP9vGjbMaE/FhO3OAb7406jyCrOVfDis7sK0Hvw074GhIfZUjA4W4Ey2TeExCZHHhBdoPTrg==
173 956ec6f1320df26f3133ec40f3de866ea0695fd7 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlvOG20QHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91eZ+EACb/XfPWaMkwIX54JaFWtL/nVkDcaL8xLVzlI+PxL0ZtHdQTGVQNp5f1BnZU9RKPZ9QOuz+QKNvb4hOOXBwmCi2AAjmTYUqtKThHmOT50ZRICkllY+YlZ3tI6JXRDhh7pSXaus8jBFG/VwuUlVmK5sA2TP+lIJijOgV9rThszfS4Q2I8sBTIaeZS1hyujFxGRO++tjYR+jPuo/98FhqJ5EylVYvKmnflWkOYLFNFqgDI6DQs7Dl+u2nrNAzZJQlgk+1ekd66T3WyK8U3tcFLZGRQ+gpzINH0Syn6USaaE+0nGi4we1hJS8JK0txWyHXJGNZYaWQAC2l1hIBfA38azwVLSe2w9JatXhS3HWByILy8JkEQ2kSo1xTD4mBkszZo/kWZpZRsAWydxCnzhNgKmTJYxASFTTX1mpdX4EzJBOs/++52y1OjVc0Ko0+6vSwxsC6zgIGJx1Os7vVgWHql0XbDmJ1NDdNmz7q5HjFcbNOWScKf6UGcBKV4dpW1w+7CvdoMFHUsVTa2zn6YOki3NEt0GWLXq+0aXbHSw8XETcyunQKjDi9ddKOw0rYGip6EKUKhOILZimQ0lgYRE23RDdT5Tl2D8s66SUuipgP9vGjbMaE/FhO3OAb7406jyCrOVfDis7sK0Hvw074GhIfZUjA4W4Ey2TeExCZHHhBdoPTrg==
174 a91a2837150bdcb27ae76b3646e6c93cd6a15904 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlvclPMQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91fc0EADF/62jqCARFaQRRcKpobPNBZupwSbnQ7E296ZRwHdZvT8CVGfkWBUIStyh+r8bfmBzzea6d9/SUoRqCoV9rwCXuRbeCZZRMMkqx9IblV3foaIOxyQi0KE2lpzGJAHxPiNxD3czZV4B+P6X2wNmG9OLjmHyQ7o64GvPAJ+Ko/EsND1tkx4qB16mEuEHVxtfaG6hbjgpLekIA3+3xur3E8cWBsNO28HtQBK83r2qURwv6eG3TfkbmiE+Ie5TNC15LPVhAOHVSD7miZdI82uk2063puCKZxIJXsy7EMjHfChTM9c7B4+TdEBjms3y+Byz2EV7kRfjplGOnBbYvfY7qiteTn/22+rLrTTQNkndDN/Sqr1DjwsvxKDeIfsqgXzGQPupLOrGdGf4ILAtA0Reme7VKNN5Px6dNxnjKKwsnSrKTQ7ZcmD+W1LKlL63lBEQvEy+TLmmFLfM2xvvBxL5177AKZrj/8gMUzEi1K2MelDGrasA7OSjTlABoleDvZzVOf1nC0Bv83tFc8FeMHLwNOxkFSsjORvZuIH/G9BYUTAd96iLwQRBxXLOVNitxAOQT+s3hs7JEaUzTHlAY+lNeFAxUujb4H0V40Xgr20O1u7PJ53tzApIrg9JQPgvUXntmRs8fpNo6f3P6Sg8XtaCCHIUAB6qTHiose56llf6bzl66A==
174 a91a2837150bdcb27ae76b3646e6c93cd6a15904 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlvclPMQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91fc0EADF/62jqCARFaQRRcKpobPNBZupwSbnQ7E296ZRwHdZvT8CVGfkWBUIStyh+r8bfmBzzea6d9/SUoRqCoV9rwCXuRbeCZZRMMkqx9IblV3foaIOxyQi0KE2lpzGJAHxPiNxD3czZV4B+P6X2wNmG9OLjmHyQ7o64GvPAJ+Ko/EsND1tkx4qB16mEuEHVxtfaG6hbjgpLekIA3+3xur3E8cWBsNO28HtQBK83r2qURwv6eG3TfkbmiE+Ie5TNC15LPVhAOHVSD7miZdI82uk2063puCKZxIJXsy7EMjHfChTM9c7B4+TdEBjms3y+Byz2EV7kRfjplGOnBbYvfY7qiteTn/22+rLrTTQNkndDN/Sqr1DjwsvxKDeIfsqgXzGQPupLOrGdGf4ILAtA0Reme7VKNN5Px6dNxnjKKwsnSrKTQ7ZcmD+W1LKlL63lBEQvEy+TLmmFLfM2xvvBxL5177AKZrj/8gMUzEi1K2MelDGrasA7OSjTlABoleDvZzVOf1nC0Bv83tFc8FeMHLwNOxkFSsjORvZuIH/G9BYUTAd96iLwQRBxXLOVNitxAOQT+s3hs7JEaUzTHlAY+lNeFAxUujb4H0V40Xgr20O1u7PJ53tzApIrg9JQPgvUXntmRs8fpNo6f3P6Sg8XtaCCHIUAB6qTHiose56llf6bzl66A==
175 1c8c54cf97256f4468da2eb4dbee24f7f3888e71 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlwG+eIQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91YqSD/9IAwdaPrOeiT+DVBW2x33oFeY1X1f5CBG/vCJptalOd2QDIsD0ANEzQHmzV25RKD851v155Txt/BPlkuBfO/kg0BbOoqTpGZk+5CcoFWeyhJct2CxtCLdEpyZ/98/htMR4VfWprCX2GHXPjS813l9pebsN3WgBUOc2VaUdHNRoAGsMVgWC5BWwNP4XSA9oixFL/O4aGLQ6pPfP3vmMFySWXWnIN8gUZ4sm53eKaT0QCICAgzFh+GzRd81uACDfoJn1d8RS9GK+h6j8x0crLY5CpQQy8lRVkokvc0h6XK44ofc57p9GHAOfprHY3DbBhD9H6fLAf5raUsqPkLRYVGqhg8bOsBr3vJ56hiXJYOYPZSYXGjnHRcUrgfPVrY+6mPTeCIQMPmWBHwYH5Tc5TLrPuxxCL4wVywqGbfmIVP+WFUikkykAAwuPOZAswxJJOB0gsnnxcApmTeXRznBXyvzscMlWVZiMjzflKRRJ9V5RI4Fdc6n1wQ4vuLSO4AUnIypIsV6ZFAOBuFKH7x6nPG0tP3FYzcICaMOPbxEx3LStnuU+UuEs6TIxM6IiR3LPiiDGZ2BA2gjJhDxQFV8hAl8KDO3LsYuyUQCv3RTAP+YejH21bIXdnwDlNqy8Hrd53rq7jZsdb2pMVvOZZ3VmIu64f+jVkD/r5msDUkQL3M9jwg==
175 1c8c54cf97256f4468da2eb4dbee24f7f3888e71 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlwG+eIQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91YqSD/9IAwdaPrOeiT+DVBW2x33oFeY1X1f5CBG/vCJptalOd2QDIsD0ANEzQHmzV25RKD851v155Txt/BPlkuBfO/kg0BbOoqTpGZk+5CcoFWeyhJct2CxtCLdEpyZ/98/htMR4VfWprCX2GHXPjS813l9pebsN3WgBUOc2VaUdHNRoAGsMVgWC5BWwNP4XSA9oixFL/O4aGLQ6pPfP3vmMFySWXWnIN8gUZ4sm53eKaT0QCICAgzFh+GzRd81uACDfoJn1d8RS9GK+h6j8x0crLY5CpQQy8lRVkokvc0h6XK44ofc57p9GHAOfprHY3DbBhD9H6fLAf5raUsqPkLRYVGqhg8bOsBr3vJ56hiXJYOYPZSYXGjnHRcUrgfPVrY+6mPTeCIQMPmWBHwYH5Tc5TLrPuxxCL4wVywqGbfmIVP+WFUikkykAAwuPOZAswxJJOB0gsnnxcApmTeXRznBXyvzscMlWVZiMjzflKRRJ9V5RI4Fdc6n1wQ4vuLSO4AUnIypIsV6ZFAOBuFKH7x6nPG0tP3FYzcICaMOPbxEx3LStnuU+UuEs6TIxM6IiR3LPiiDGZ2BA2gjJhDxQFV8hAl8KDO3LsYuyUQCv3RTAP+YejH21bIXdnwDlNqy8Hrd53rq7jZsdb2pMVvOZZ3VmIu64f+jVkD/r5msDUkQL3M9jwg==
176 197f092b2cd9691e2a55d198f717b231af9be6f9 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlwz6DUQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91SbtD/47TJkSFuDJrvrpLuZROeR48opM8kPtMdbFKZxmeUtap/1q1ahBcA8cnkf5t5iEna57OkPfx0FVw7zupFZSD970q8KeQa1C1oRf+DV83rkOqMEzTLmDYZ5YWWILyDb2NrSkBzArhLNhEtWrFFo9uoigwJWiyNGXUkjVd7XUaYvxVYvnHJcmr98l9sW+RxgV2Cm/6ImeW6BkSUjfrJpZlHUecxcHIaDVniSCVzVF7T+tgG0+CxpehmRrPE/qlPTY2DVHuG6ogwjmu7pWr4kW3M6pTmOYICKjkojIhPTAfNDZGNYruJMukEeB2JyxSz+J9jhjPe//9x4JznpCzm/JzCHFO9CfONjHIcUqLa9qxqhmBFpr1U5J7vRir4ch7v8TGtGbcR3833HTUA7EEMu/Ca48XVfGNDmySQs8zgGpj1yzf/lBGbiAzTSp7Zp+ANLu+R3NjeiDUYQbgf3vcpoHL44duk4dzhD+ofFD75PF1SMTluWbeLCSENH9io2pxVDj3I5VhlNxHdbqY1WXb+sDBVr4niIGzQiKqVOV33ghyRpzVJFZ7SaQG7VR/mLL3UnvJuapLYtUV9+/7Si/CHl7m8NntPMvx1nM/Z4t/BN8Z5cdhPn2PLxp9f5VCmCqLlCQDSv94cCTLlatiCTfF7axgE0u7+CWiOUNyyqg/vu0pjTwIA==
176 197f092b2cd9691e2a55d198f717b231af9be6f9 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlwz6DUQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91SbtD/47TJkSFuDJrvrpLuZROeR48opM8kPtMdbFKZxmeUtap/1q1ahBcA8cnkf5t5iEna57OkPfx0FVw7zupFZSD970q8KeQa1C1oRf+DV83rkOqMEzTLmDYZ5YWWILyDb2NrSkBzArhLNhEtWrFFo9uoigwJWiyNGXUkjVd7XUaYvxVYvnHJcmr98l9sW+RxgV2Cm/6ImeW6BkSUjfrJpZlHUecxcHIaDVniSCVzVF7T+tgG0+CxpehmRrPE/qlPTY2DVHuG6ogwjmu7pWr4kW3M6pTmOYICKjkojIhPTAfNDZGNYruJMukEeB2JyxSz+J9jhjPe//9x4JznpCzm/JzCHFO9CfONjHIcUqLa9qxqhmBFpr1U5J7vRir4ch7v8TGtGbcR3833HTUA7EEMu/Ca48XVfGNDmySQs8zgGpj1yzf/lBGbiAzTSp7Zp+ANLu+R3NjeiDUYQbgf3vcpoHL44duk4dzhD+ofFD75PF1SMTluWbeLCSENH9io2pxVDj3I5VhlNxHdbqY1WXb+sDBVr4niIGzQiKqVOV33ghyRpzVJFZ7SaQG7VR/mLL3UnvJuapLYtUV9+/7Si/CHl7m8NntPMvx1nM/Z4t/BN8Z5cdhPn2PLxp9f5VCmCqLlCQDSv94cCTLlatiCTfF7axgE0u7+CWiOUNyyqg/vu0pjTwIA==
177 593718ff5844cad7a27ee3eb5adad89ac8550949 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlxCG6EQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91YptD/9DG76IvubjzVsfX1UiQcV1mqWuSgz/idpeFCrc6Z1dyFB5UmbHKfAaZnrPBR7ly6bGD9+NZupB9A8QRxX92koiq0Hw2ywbwR5oWVrBaDiinIDLiTQTUCPnNMH0FSNrt4Kf9Gj4RqMufZvL+dR0pDYV0n6HP3aGOeTnowNhv0lUbw/Gx20YrcCU9uf3GbgRvMQiFNv9cTJAdQlH++98C8MVLfRU4ZxP11hI7sR8mp1q6ruJoozd0Cta67E6MyC/L2Rp3W89psvvY7DSTg9RwQwoS8I6U9iyQJ16Bb6UgZVV6jqQqOSxWUaPfKUhJLl2ENHH5f3rzoi3NH6jHuy5rq2v9XuvOpQ7LqSi1Ev0oq1xllZiyD4Zm69Z/Is0mxwqPskZGWR5Lh6Uq3Dh0zJW7O5M2m1IHdAYqffHpUr2NgEQVST4VDvO4fR2d7n6+ZNXYbZrpmQ1j4bpOZCEMqWXPfl4HY7a60hWa884mWxtVLGvhYycxnN8r1o5ouS0pAMAI6qEFFW1XFFN4eNDDWl83BkuDa32DTEthoyi15JM5jS7VPDYACdHE3IVqsTsZq7nn60uoFCGpdMcSqrD2mlUd9Z12x8NnCIrxKhlHLkq89OrQAcz8/0bbluGuzm3FHKb+8VQWr0MgkvOLTqqvOqn97oBdKqo0eyT0IPz8QeVYPbZfQ==
177 593718ff5844cad7a27ee3eb5adad89ac8550949 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlxCG6EQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91YptD/9DG76IvubjzVsfX1UiQcV1mqWuSgz/idpeFCrc6Z1dyFB5UmbHKfAaZnrPBR7ly6bGD9+NZupB9A8QRxX92koiq0Hw2ywbwR5oWVrBaDiinIDLiTQTUCPnNMH0FSNrt4Kf9Gj4RqMufZvL+dR0pDYV0n6HP3aGOeTnowNhv0lUbw/Gx20YrcCU9uf3GbgRvMQiFNv9cTJAdQlH++98C8MVLfRU4ZxP11hI7sR8mp1q6ruJoozd0Cta67E6MyC/L2Rp3W89psvvY7DSTg9RwQwoS8I6U9iyQJ16Bb6UgZVV6jqQqOSxWUaPfKUhJLl2ENHH5f3rzoi3NH6jHuy5rq2v9XuvOpQ7LqSi1Ev0oq1xllZiyD4Zm69Z/Is0mxwqPskZGWR5Lh6Uq3Dh0zJW7O5M2m1IHdAYqffHpUr2NgEQVST4VDvO4fR2d7n6+ZNXYbZrpmQ1j4bpOZCEMqWXPfl4HY7a60hWa884mWxtVLGvhYycxnN8r1o5ouS0pAMAI6qEFFW1XFFN4eNDDWl83BkuDa32DTEthoyi15JM5jS7VPDYACdHE3IVqsTsZq7nn60uoFCGpdMcSqrD2mlUd9Z12x8NnCIrxKhlHLkq89OrQAcz8/0bbluGuzm3FHKb+8VQWr0MgkvOLTqqvOqn97oBdKqo0eyT0IPz8QeVYPbZfQ==
178 83377b4b4ae0e9a6b8e579f7b0a693b8cf5c3b10 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlxUk3gQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91aT7EACaycWeal53ShxaNyTNOa5IPZ71+iyWA9xEh7hK6cDDirpItarWLRVWoWqBlWRBBs6uU4BxnpPSCLFkJLu6ts/5p4R6/0Z04Pasd6sFi14bCGslmPJFlwrpfFDpQvFR6xZAtv1xGb8n+rjpK+wfstjRgyf84zn4//0dOdylY5EUXOk4/3zcXKAzPgZHBRper+PlQ0ICgYHiKQUlyDWrFrdSEis6OqBa+PbxdmgzLYbhXi0bvS5XRWM9EVJZa+5ITEVOEGPClRcoA7SJE5DiapMYlwNnB3U6TEazJoj5yuvGhrJzj9lx7/jx9tzZ/mhdOVsSRiSCBu46B/E63fnUDqaMw8KKlFKBRuzKnqnByZD8fuD34YJ6A82hta56W4SJ4pusa/X2nAJn1QbRjESY4wN4FEaNdYiMbpgbG2uBDhmEowAyhXtiuQAPCUra5o42a+E+tAgV5uNUAal8vk0DcPRmzc4UntQiQGwxL0fsTEpMQtG5ryxWRmOIBq6aKGuLVELllPCwOh8UIGLlpAoEynlNi9qJNT6kHpSmwquiU6TG6R1dA/ckBK2H90hewtb/jwLlenGugpylLQ2U/NsDdoWRyHNrdB4eUJiWD/BBPXktZQJVja97Js+Vn44ctCkNjui/53xcBQfIYdHGLttIEq56v/yZiSviCcTUhBPRSEdoUg==
178 83377b4b4ae0e9a6b8e579f7b0a693b8cf5c3b10 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlxUk3gQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91aT7EACaycWeal53ShxaNyTNOa5IPZ71+iyWA9xEh7hK6cDDirpItarWLRVWoWqBlWRBBs6uU4BxnpPSCLFkJLu6ts/5p4R6/0Z04Pasd6sFi14bCGslmPJFlwrpfFDpQvFR6xZAtv1xGb8n+rjpK+wfstjRgyf84zn4//0dOdylY5EUXOk4/3zcXKAzPgZHBRper+PlQ0ICgYHiKQUlyDWrFrdSEis6OqBa+PbxdmgzLYbhXi0bvS5XRWM9EVJZa+5ITEVOEGPClRcoA7SJE5DiapMYlwNnB3U6TEazJoj5yuvGhrJzj9lx7/jx9tzZ/mhdOVsSRiSCBu46B/E63fnUDqaMw8KKlFKBRuzKnqnByZD8fuD34YJ6A82hta56W4SJ4pusa/X2nAJn1QbRjESY4wN4FEaNdYiMbpgbG2uBDhmEowAyhXtiuQAPCUra5o42a+E+tAgV5uNUAal8vk0DcPRmzc4UntQiQGwxL0fsTEpMQtG5ryxWRmOIBq6aKGuLVELllPCwOh8UIGLlpAoEynlNi9qJNT6kHpSmwquiU6TG6R1dA/ckBK2H90hewtb/jwLlenGugpylLQ2U/NsDdoWRyHNrdB4eUJiWD/BBPXktZQJVja97Js+Vn44ctCkNjui/53xcBQfIYdHGLttIEq56v/yZiSviCcTUhBPRSEdoUg==
179 4ea21df312ec7159c5b3633096b6ecf68750b0dd 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlyQ7VYQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91aziD/4uI/Nr+UJgOri1zfa6ObXuMVO2FeadAolKemMDE/c4ddPUN2AwysZyJaOHmqj5VR0nf4a9CpTBc8Ciq9tfaFSWN6XFIJ2s3GPHhsnyhsPbF56c2bpl2W/csxor9eDGpv9TrQOK0qgI4wGxSQVFW0uUgHtZ5Yd6JWupHuyDfWopJf3oonissKI9ykRLeZEQ3sPIP6vTWMM3pdavAmDii3qKVEaCEGWmXgnM/vfBJ/tA1U5LSXpxwkJB7Pi/6Xc6OnGHWmCpsA4L6TSRkoyho4a6tLUA1Qlqm6sMxJjXAer8dmDLpmXL7gF3JhZgkiX74i2zDZnM4i42E6EhO52l3uorF5gtsw85dY20MSoBOmn5bM7k40TCA+vriNZJgmDrTYgY3B00mNysioEuSpDkILPJIV4U9LTazsxR49h3/mH2D1Sdxu6YtCIPE8ggThmveW/dZQy6W1xLfS66pFmDvq8ND0WjDa/Fi9dmjMcQtzA9CZL8AMlSc2aLJs++KjCuN+t6tn/tLhLz1nHaSitqgsIoJmBWb00QjOilnAQq7H8gUpUqMdLyEeL2B9HfJobQx6A8Op2xohjI7qD5gLGAxh+QMmuUmf7wx1h2UuQvrNW5di7S3k3nxfhm87Gkth3j0M/aMy0P6irPOKcKns55r6eOzItC+ezQayXc4A10F+x6Ew==
179 4ea21df312ec7159c5b3633096b6ecf68750b0dd 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlyQ7VYQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91aziD/4uI/Nr+UJgOri1zfa6ObXuMVO2FeadAolKemMDE/c4ddPUN2AwysZyJaOHmqj5VR0nf4a9CpTBc8Ciq9tfaFSWN6XFIJ2s3GPHhsnyhsPbF56c2bpl2W/csxor9eDGpv9TrQOK0qgI4wGxSQVFW0uUgHtZ5Yd6JWupHuyDfWopJf3oonissKI9ykRLeZEQ3sPIP6vTWMM3pdavAmDii3qKVEaCEGWmXgnM/vfBJ/tA1U5LSXpxwkJB7Pi/6Xc6OnGHWmCpsA4L6TSRkoyho4a6tLUA1Qlqm6sMxJjXAer8dmDLpmXL7gF3JhZgkiX74i2zDZnM4i42E6EhO52l3uorF5gtsw85dY20MSoBOmn5bM7k40TCA+vriNZJgmDrTYgY3B00mNysioEuSpDkILPJIV4U9LTazsxR49h3/mH2D1Sdxu6YtCIPE8ggThmveW/dZQy6W1xLfS66pFmDvq8ND0WjDa/Fi9dmjMcQtzA9CZL8AMlSc2aLJs++KjCuN+t6tn/tLhLz1nHaSitqgsIoJmBWb00QjOilnAQq7H8gUpUqMdLyEeL2B9HfJobQx6A8Op2xohjI7qD5gLGAxh+QMmuUmf7wx1h2UuQvrNW5di7S3k3nxfhm87Gkth3j0M/aMy0P6irPOKcKns55r6eOzItC+ezQayXc4A10F+x6Ew==
180 4a8d9ed864754837a185a642170cde24392f9abf 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAly3aLkQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91bpXD/0Qdx3lNv6230rl369PnGM7o56BFywJtGtQ0FjBj81/Q6IKNJkAus/FXA02MevAxnKhyCMPHbiWQn4cn+Fpt9Y7FOFl3MTdoY5v4rGDAbAaJsjyK3BNqSwWD1uFaOnFDzA/112MJ6nDciVaOzeD7qakMj8zdVhvyEfFszN7f7xT1JyGc+cOWfbvcIv/IXWZNrSZC0EzcZspfwxYQwFscgDL3AHeKeYqihJ6vgWxgEg4V8ZnJ6roJeERTp2wwvIj/pKSEpgzfLQfHiEwvH9MKMaJHGx4huzWJxYX2DB83LaK7cgkKqzyQ+z8rsb27oFPMVgb1Kg78+6sRujFdkahFWYYGPT6sFBDWkRQ/J7DRnBzHH2wbBoyNkApmLEfaRGJpxX8wojPFGJkNr6GF12uF7E+djsuE8ZL7l4p2YD33NBSzcEjNTlgruRauj/7SoSC3BgDlrqCypCkNgn5nDDjvf6oJx16qGqZsglHJOl0S2LRiGaMQTpBhpDWAyVIAQBRW/vF1IRnNJaQ+dX7M9VqlVsXnfh8WD+FPKDgpiSLO8hIuvlYlcrtU9rXyWu1njKvCs744G836k4SNBoi+y6bi6XbmU0Uv0GSCLyj1BIsqglfXuac0QHlz5RNmS6LVf7z13ZIn/ePXehYoKHu+PNDmbVGGwAVoZP4HLEqonD3SVpVcQ==
180 4a8d9ed864754837a185a642170cde24392f9abf 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAly3aLkQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91bpXD/0Qdx3lNv6230rl369PnGM7o56BFywJtGtQ0FjBj81/Q6IKNJkAus/FXA02MevAxnKhyCMPHbiWQn4cn+Fpt9Y7FOFl3MTdoY5v4rGDAbAaJsjyK3BNqSwWD1uFaOnFDzA/112MJ6nDciVaOzeD7qakMj8zdVhvyEfFszN7f7xT1JyGc+cOWfbvcIv/IXWZNrSZC0EzcZspfwxYQwFscgDL3AHeKeYqihJ6vgWxgEg4V8ZnJ6roJeERTp2wwvIj/pKSEpgzfLQfHiEwvH9MKMaJHGx4huzWJxYX2DB83LaK7cgkKqzyQ+z8rsb27oFPMVgb1Kg78+6sRujFdkahFWYYGPT6sFBDWkRQ/J7DRnBzHH2wbBoyNkApmLEfaRGJpxX8wojPFGJkNr6GF12uF7E+djsuE8ZL7l4p2YD33NBSzcEjNTlgruRauj/7SoSC3BgDlrqCypCkNgn5nDDjvf6oJx16qGqZsglHJOl0S2LRiGaMQTpBhpDWAyVIAQBRW/vF1IRnNJaQ+dX7M9VqlVsXnfh8WD+FPKDgpiSLO8hIuvlYlcrtU9rXyWu1njKvCs744G836k4SNBoi+y6bi6XbmU0Uv0GSCLyj1BIsqglfXuac0QHlz5RNmS6LVf7z13ZIn/ePXehYoKHu+PNDmbVGGwAVoZP4HLEqonD3SVpVcQ==
181 07e479ef7c9639be0029f00e6a722b96dcc05fee 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlzJ5QYQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91U0QD/4xQ00Suo+XNM/2v01NEALJA8pFxSaUcz1fBVQDwIQbApAHbjVDgIShuFlAXu7Jf582+C5wJu0J8L5Rb+Q9WJuM9sM+6cxUWclT3D3gB326LuQg86y5MYbzmwsSCOnBdRn/MY18on2XTa8t4Mxf0jAaHPUXEadmuwkOw4ds62eUD81lkakGoxgXrD1GUhAlGItNPOb0rp2XFj7i+LvazMX2mWOEXMXA5KPQrOvLsKnoESiPfONXumBfZNVSxVA7fJ3Vl1+PldBax+w9LQMgVGo+BkqPt7i+lPTcnlh2Nbf8y3zERTcItFBzrBxmuG6pINfNpZY/fi+9VL7mpMYlzlxs7VcLF8bVnpYpxpHfDR4hPjP0sq6+/nSSGUfzQXmfGHq0ZdoVGSzrDEv8UzYE9ehWUhHNE+sIU3MpwjC+WiW2YhYzPYN2KOlfSog3LuWLAcn3ZghWg1S4crsPt9CeE0vKxkNWNz9dzvhbniW7VGorXJKFCJzMu6pGaP/UjwpHxR+C6J1MGUW2TQwdIUyhPA8HfHJSVbifFJV+1CYEDcqRcFETpxm4YNrLJNL/Ns7zoWmdmEUXT1NEnK1r3Pe2Xi1o56FHGPffOWASmqFnF/coZCq6b4vmBWK/n8mI/JF1yxltfwacaY+1pEor92ztK34Lme1A+R7zyObGYNDcWiGZgA==
181 07e479ef7c9639be0029f00e6a722b96dcc05fee 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlzJ5QYQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91U0QD/4xQ00Suo+XNM/2v01NEALJA8pFxSaUcz1fBVQDwIQbApAHbjVDgIShuFlAXu7Jf582+C5wJu0J8L5Rb+Q9WJuM9sM+6cxUWclT3D3gB326LuQg86y5MYbzmwsSCOnBdRn/MY18on2XTa8t4Mxf0jAaHPUXEadmuwkOw4ds62eUD81lkakGoxgXrD1GUhAlGItNPOb0rp2XFj7i+LvazMX2mWOEXMXA5KPQrOvLsKnoESiPfONXumBfZNVSxVA7fJ3Vl1+PldBax+w9LQMgVGo+BkqPt7i+lPTcnlh2Nbf8y3zERTcItFBzrBxmuG6pINfNpZY/fi+9VL7mpMYlzlxs7VcLF8bVnpYpxpHfDR4hPjP0sq6+/nSSGUfzQXmfGHq0ZdoVGSzrDEv8UzYE9ehWUhHNE+sIU3MpwjC+WiW2YhYzPYN2KOlfSog3LuWLAcn3ZghWg1S4crsPt9CeE0vKxkNWNz9dzvhbniW7VGorXJKFCJzMu6pGaP/UjwpHxR+C6J1MGUW2TQwdIUyhPA8HfHJSVbifFJV+1CYEDcqRcFETpxm4YNrLJNL/Ns7zoWmdmEUXT1NEnK1r3Pe2Xi1o56FHGPffOWASmqFnF/coZCq6b4vmBWK/n8mI/JF1yxltfwacaY+1pEor92ztK34Lme1A+R7zyObGYNDcWiGZgA==
182 c3484ddbdb9621256d597ed86b90d229c59c2af9 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlz3zjsQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91XWVEACnlQCHCF7dMrvTHwE4nA+i/I1l8UfRwR3ufXhBxjVUqxS75mHMcCsOwClAa2HaqNP97IGbk2fi9y53SOKH67imNVm8NY8yIook1C8T7nKsFmyM3l63FdVQDgUF6AJ0krDt6iJo4vjk8CyRHowAcmL942jcfBU9U5/Jli11Sx33MKF/eMXnuXYRBNESh97f1bDgwydp7QT8dj/T23YvuIVtfq9h8D46qXWkpwbgtnXMnaz21kqcN6A5aKbadG4ELf9175cBlfe+ZpOqpy+OSuQBByOP5eBNl5d0vq/i4WQyJZs8GoVd5Bh559+HjKIKv11Y+gXoaQMf4VSp2JZwwPlTR5Me5N6AJNViXW1Bm108ZWeXR81Hu2+t2eQv6EelcQxnW0e/mTCUot8TaewYFJ+4VWwAAca81FP0X8J0YcdIkvvNmrU9V62B3WYK3iYgbwm7IlR3+7ilQUz3NZCZOqJpo+c7k/yhuoj4ZMDq8JzaqBnBnARbvUF61B4iVhto4xpruUQw8FwFLUuZLohsESCNCCgqdoiyJHnVQVitoNJlCeEPl+W+UUeFfwf9fzrS6nj9xWkNm9lBOahaH+fV69msi5Ex/gy8y4H+4T8z0f3gFO7kp9eKr5C7hoGyKQWv5D61H1qEZOFUZjXHBhMxbe+og40G0apMm3qmsj2KsCNDdQ==
182 c3484ddbdb9621256d597ed86b90d229c59c2af9 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAlz3zjsQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91XWVEACnlQCHCF7dMrvTHwE4nA+i/I1l8UfRwR3ufXhBxjVUqxS75mHMcCsOwClAa2HaqNP97IGbk2fi9y53SOKH67imNVm8NY8yIook1C8T7nKsFmyM3l63FdVQDgUF6AJ0krDt6iJo4vjk8CyRHowAcmL942jcfBU9U5/Jli11Sx33MKF/eMXnuXYRBNESh97f1bDgwydp7QT8dj/T23YvuIVtfq9h8D46qXWkpwbgtnXMnaz21kqcN6A5aKbadG4ELf9175cBlfe+ZpOqpy+OSuQBByOP5eBNl5d0vq/i4WQyJZs8GoVd5Bh559+HjKIKv11Y+gXoaQMf4VSp2JZwwPlTR5Me5N6AJNViXW1Bm108ZWeXR81Hu2+t2eQv6EelcQxnW0e/mTCUot8TaewYFJ+4VWwAAca81FP0X8J0YcdIkvvNmrU9V62B3WYK3iYgbwm7IlR3+7ilQUz3NZCZOqJpo+c7k/yhuoj4ZMDq8JzaqBnBnARbvUF61B4iVhto4xpruUQw8FwFLUuZLohsESCNCCgqdoiyJHnVQVitoNJlCeEPl+W+UUeFfwf9fzrS6nj9xWkNm9lBOahaH+fV69msi5Ex/gy8y4H+4T8z0f3gFO7kp9eKr5C7hoGyKQWv5D61H1qEZOFUZjXHBhMxbe+og40G0apMm3qmsj2KsCNDdQ==
183 97ada9b8d51bef24c5cb4cdca4243f0db694ab6e 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl0kn6UQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91RwND/9uZ3Avf0jXYzGT5t+HhlAeWeqA3wrQOmk0if7ttUholoHYmCbc7V9ufgiQ1jTX/58EhOXHt4L1zlLDf2OMJ7YQz9pfiGjW3vLvVKU7eeQ5epG8J8Hp4BcbEU5gfQBwzZmRMqVfZ9QbNgENysfQxhVT0ONPC5TBUsamAysRQVVPeEQFlW1mSf03LYF1UDjXgquHoIFnnPCZyNUGVRSajW9mDe0OQI95lXE6lISlBkeoTmVs9mR+OeLO3+Dgn2ai8d4gHxdCSU5iDnifSp4aaThfNxueSRFzNI1Q6R6MQrIplqFYZGhAOOXQzZWqThQld6/58IvaBP4aCGs1VxE/qBKNp8txm1QeL/ukOWPgVS9z7Iw5uRuET95aEn/Khisv78lrVGOD5wigt2bb4UiysIgk8+du7HNMqPmS31fCS1vsoJ+y2XoJP2q8bNDiwuVihDWJDlF091HH2+ItmopHGUGeHaxNyRoiSvE7fCBi/u3rleiMsMai8r1QDgBpalUPbaLzBelEKhn2JcDhU5NrG8a+SKRCzpmXkkFPhxrzT1dvEAnoNI0LbmekTDWilp0sZbwdsn2rO51IJ4PU8CgbYROP8Z4DuNMfVyVIpxAEb2zbnIA4YqJ3qcQ3e+qEIw8h9m/ot9YYJ/wCQjIIXN6CUHXLYO30HubNOEDVS4Gem93Gcw==
183 97ada9b8d51bef24c5cb4cdca4243f0db694ab6e 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl0kn6UQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91RwND/9uZ3Avf0jXYzGT5t+HhlAeWeqA3wrQOmk0if7ttUholoHYmCbc7V9ufgiQ1jTX/58EhOXHt4L1zlLDf2OMJ7YQz9pfiGjW3vLvVKU7eeQ5epG8J8Hp4BcbEU5gfQBwzZmRMqVfZ9QbNgENysfQxhVT0ONPC5TBUsamAysRQVVPeEQFlW1mSf03LYF1UDjXgquHoIFnnPCZyNUGVRSajW9mDe0OQI95lXE6lISlBkeoTmVs9mR+OeLO3+Dgn2ai8d4gHxdCSU5iDnifSp4aaThfNxueSRFzNI1Q6R6MQrIplqFYZGhAOOXQzZWqThQld6/58IvaBP4aCGs1VxE/qBKNp8txm1QeL/ukOWPgVS9z7Iw5uRuET95aEn/Khisv78lrVGOD5wigt2bb4UiysIgk8+du7HNMqPmS31fCS1vsoJ+y2XoJP2q8bNDiwuVihDWJDlF091HH2+ItmopHGUGeHaxNyRoiSvE7fCBi/u3rleiMsMai8r1QDgBpalUPbaLzBelEKhn2JcDhU5NrG8a+SKRCzpmXkkFPhxrzT1dvEAnoNI0LbmekTDWilp0sZbwdsn2rO51IJ4PU8CgbYROP8Z4DuNMfVyVIpxAEb2zbnIA4YqJ3qcQ3e+qEIw8h9m/ot9YYJ/wCQjIIXN6CUHXLYO30HubNOEDVS4Gem93Gcw==
184 e386b5f4f8360dbb43a576dd9b1368e386fefa5b 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl01+7cQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91ZM6D/9iWw0AyhcDFI7nEVcSlqDNABQvCnHoNB79UYrTf3GOjuUiyVUTwZ4CIOS+o2wchZXBRWx+T3aHJ1x6qTpXvA3oa9bgerNWFfmVmTuWWMlbQszXS5Lpv5u1lwCoLPDi4sa/gKBSIzt/CMu7zuPzO2yLEnWvR6ljOzjY9LfUx80u1zc899MEEsNuVStkfw9f37lAu+udMRgvQDZeLh+j3Qg5uh3GV3/8Q/I/YFNRHeKSLBkdp5CD3CkUtteBuZfIje/BwttxHG6MdbXMjOe0QmGMNzcSstnVqsENhEa0ZKLxM6NxfwcsxbeKA1uFoTvzT1sFyXXS3NV0noMQBwMrxipzKv4WrjuctmUms6n+VW/w4GMg8gzeUvu7rzqVIehWIBTxV8yWwkWiS9ge6Upiki5vCG+aeMLrwsNqsptOh4BEcsvcpd2ZZtUDRHYFVUK4z/RRlpKb6CdzkGeMWwP6oWAv4N0veD73Y7wPz76ZFNU2yvqViRPxrU2A2P44R8dLFvEOmcO5MHVNwHP0kpaj9dpGwBI0t2A32vDF8LEsnd86LQBm6X5ZWWJ5hGmtZotp4blkH1oFKt+ZeccHcwueIMU3v9e02ElhM4Mo2nD3yyQvMkzDqp5lZEfNqEK8rlj2TNfc8XyjAsp1hKpnjDa1olKKfdq8OniUpsaYDTku4+vuGw==
184 e386b5f4f8360dbb43a576dd9b1368e386fefa5b 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl01+7cQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91ZM6D/9iWw0AyhcDFI7nEVcSlqDNABQvCnHoNB79UYrTf3GOjuUiyVUTwZ4CIOS+o2wchZXBRWx+T3aHJ1x6qTpXvA3oa9bgerNWFfmVmTuWWMlbQszXS5Lpv5u1lwCoLPDi4sa/gKBSIzt/CMu7zuPzO2yLEnWvR6ljOzjY9LfUx80u1zc899MEEsNuVStkfw9f37lAu+udMRgvQDZeLh+j3Qg5uh3GV3/8Q/I/YFNRHeKSLBkdp5CD3CkUtteBuZfIje/BwttxHG6MdbXMjOe0QmGMNzcSstnVqsENhEa0ZKLxM6NxfwcsxbeKA1uFoTvzT1sFyXXS3NV0noMQBwMrxipzKv4WrjuctmUms6n+VW/w4GMg8gzeUvu7rzqVIehWIBTxV8yWwkWiS9ge6Upiki5vCG+aeMLrwsNqsptOh4BEcsvcpd2ZZtUDRHYFVUK4z/RRlpKb6CdzkGeMWwP6oWAv4N0veD73Y7wPz76ZFNU2yvqViRPxrU2A2P44R8dLFvEOmcO5MHVNwHP0kpaj9dpGwBI0t2A32vDF8LEsnd86LQBm6X5ZWWJ5hGmtZotp4blkH1oFKt+ZeccHcwueIMU3v9e02ElhM4Mo2nD3yyQvMkzDqp5lZEfNqEK8rlj2TNfc8XyjAsp1hKpnjDa1olKKfdq8OniUpsaYDTku4+vuGw==
185 e91930d712e8507d1bc1b2dffd96c83edc4cbed3 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl1DD/sQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91bvmD/4/QDZZGVe+WiMUxbT+grfFjwjX4nkg7Vt+6vQbjN68NC5XpSiCzW8uu0LRemX0KJKoOfQxqHk3YKkZZHIk10Fe6RSLWt8dqlfa2J9B2U8DwMEBykCOuxcLlDe7DGaaMXlXXRhNXebRheNPLeNe+r7beMAAjwchTIIJD5xcFnPRFR0nN7Vj7eRUdWIQ9H/s7TolPz1Mf7IWqapLjPtofiwSgtRoXfIAkuuabnE4eMVJ8rsLwcuMhxWP2zjEfEg68YkiGBAFmlnRk+3lJpiB9kVapB3cWcsWv2OBhz0D3NgGp82eWkjJCZZhZ+zHHrQ6L9zbiArzW9NVvPEAKLbl3XUhFUzFTUD+S38wsYLYL5RkzhlCI2/K1LJLOtj7r0Seen0v8X842p0cXmxTg/o1Vg3JOm04l9AwzCsnqwIqV7Ru//KPqH91MFFH6T6tbfjtLHRmjxRjMZmVt7ZQjS84opVCZwgUTZZJB2kd1goROjdowQVK6qsEonlzGjWb9zc3el5L9uzDeim3e5t2GNRVt8veQaLc+U2hHWniVsDJMvqp2Hr9IWUKp+bu/35B1nElvooS40gj2WhkfkCbbXSg9qnVLwGxxcGdF28Z0nhQcfKiJAc+8l9l19GNhdKxOi4zUXlp90opPWfT7wGQmysvTjQeFL2zX9ziuHUZZwlW1YbeMQ==
185 e91930d712e8507d1bc1b2dffd96c83edc4cbed3 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl1DD/sQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91bvmD/4/QDZZGVe+WiMUxbT+grfFjwjX4nkg7Vt+6vQbjN68NC5XpSiCzW8uu0LRemX0KJKoOfQxqHk3YKkZZHIk10Fe6RSLWt8dqlfa2J9B2U8DwMEBykCOuxcLlDe7DGaaMXlXXRhNXebRheNPLeNe+r7beMAAjwchTIIJD5xcFnPRFR0nN7Vj7eRUdWIQ9H/s7TolPz1Mf7IWqapLjPtofiwSgtRoXfIAkuuabnE4eMVJ8rsLwcuMhxWP2zjEfEg68YkiGBAFmlnRk+3lJpiB9kVapB3cWcsWv2OBhz0D3NgGp82eWkjJCZZhZ+zHHrQ6L9zbiArzW9NVvPEAKLbl3XUhFUzFTUD+S38wsYLYL5RkzhlCI2/K1LJLOtj7r0Seen0v8X842p0cXmxTg/o1Vg3JOm04l9AwzCsnqwIqV7Ru//KPqH91MFFH6T6tbfjtLHRmjxRjMZmVt7ZQjS84opVCZwgUTZZJB2kd1goROjdowQVK6qsEonlzGjWb9zc3el5L9uzDeim3e5t2GNRVt8veQaLc+U2hHWniVsDJMvqp2Hr9IWUKp+bu/35B1nElvooS40gj2WhkfkCbbXSg9qnVLwGxxcGdF28Z0nhQcfKiJAc+8l9l19GNhdKxOi4zUXlp90opPWfT7wGQmysvTjQeFL2zX9ziuHUZZwlW1YbeMQ==
186 a4e32fd539ab41489a51b2aa88bda9a73b839562 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl1xTxUQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91ZQgD/96mViQ6fEh84l4XyAlY6Dq3SgMqEXttsUpk/GPoW4ykDFKN6VoiOaPoyNODO/46V3yeAjYjy3vX7Ua4/MY1NlnNoliQcTYtRV3SlDdoueTPOLfO6YSV27LG+dX/HYvPc/htCVmIVItU1JL+KEpXnv+bT50Bk+m6OgzfJMDzdHQ5ICImT8gW7UXlH/mlNtWMOrJDk3cArGhGs/pTFVrfgRTfDfDGSA9xW0/QvsNI5iwZHgMYaqoPFDnw6d/NXWRlk77KNiXkBEOKHf6UEWecMKmiSCm8RePSiX9ezqdcBAHygOg4KUeiR2kPNl4QJtskyG4CwWxlmGlfgKx07s7rGafE+DWLEYC9Wa8qK6/LPiowm17m/UlAYxdFXaBCiN0wgEw7oNmjcx/791ez+CL1+h6pd0+iSVI4bO9/YZ8LPROYef18MFm+IFIDIOgZU4eUbpBrzBb3IM1a519xgnmWXAjtRtGWEZMuHaSoLJf2pDXvaUPX6YpJeqCBFO3q/swbiJsQsy6xRW0Dwtn7umU1PGdmMoTnskTRKy9Kgzv7lf/nsUuRbzzM4ut9m1TOo27AulObMrmQB4YvLi/LEnYaRNx18yaqOceMxb/mS0tHLgcZToy9rTV+vtC21vgwfzGia2neLLe50tnIsBPP/AdTOw9ZDMRfXMCajWM22hPxvnGcw==
186 a4e32fd539ab41489a51b2aa88bda9a73b839562 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl1xTxUQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91ZQgD/96mViQ6fEh84l4XyAlY6Dq3SgMqEXttsUpk/GPoW4ykDFKN6VoiOaPoyNODO/46V3yeAjYjy3vX7Ua4/MY1NlnNoliQcTYtRV3SlDdoueTPOLfO6YSV27LG+dX/HYvPc/htCVmIVItU1JL+KEpXnv+bT50Bk+m6OgzfJMDzdHQ5ICImT8gW7UXlH/mlNtWMOrJDk3cArGhGs/pTFVrfgRTfDfDGSA9xW0/QvsNI5iwZHgMYaqoPFDnw6d/NXWRlk77KNiXkBEOKHf6UEWecMKmiSCm8RePSiX9ezqdcBAHygOg4KUeiR2kPNl4QJtskyG4CwWxlmGlfgKx07s7rGafE+DWLEYC9Wa8qK6/LPiowm17m/UlAYxdFXaBCiN0wgEw7oNmjcx/791ez+CL1+h6pd0+iSVI4bO9/YZ8LPROYef18MFm+IFIDIOgZU4eUbpBrzBb3IM1a519xgnmWXAjtRtGWEZMuHaSoLJf2pDXvaUPX6YpJeqCBFO3q/swbiJsQsy6xRW0Dwtn7umU1PGdmMoTnskTRKy9Kgzv7lf/nsUuRbzzM4ut9m1TOo27AulObMrmQB4YvLi/LEnYaRNx18yaqOceMxb/mS0tHLgcZToy9rTV+vtC21vgwfzGia2neLLe50tnIsBPP/AdTOw9ZDMRfXMCajWM22hPxvnGcw==
187 181e52f2b62f4768aa0d988936c929dc7c4a41a0 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl2UzlMQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91SDzD/0YZqtN+LK5AusJjWaTa61DRIPhJQoZD+HKg4kAzjL8zw8SxBGLxMZkGmve9QFMNzqIr5kkPk6yEKrEWYqyPtpwrv5Xh5D4d8AKfphdzwSr+BvMk4fBEvwnBhrUJtKDEiuYQdbh4+OQfQs1c3xhtinjXn30160uzFvLQY6/h4hxai2XWj4trgoNXqPHDHlQKc6kRfPpmNO2UZhG+2Xfsava2JpcP4xA2R0XkI10be5MDoGU4AFCMUcXZzIto0DYT+HOezowoNpdC1EWVHfa+bdrlzHHO7WPaTLzEPy44/IhXmNhbwFKOk5RZ/qBADQvs9BDfmIDczOoZKTC5+ESZM0PR2np5t7+JFMUeeRcINqBdSc4Aszw3iHjgNbJJ3viU72JZvGGGd9MglP590tA0proVGxQgvXDq3mtq3Se5yOLAjmRnktW5Tnt8/Z3ycuZz+QsTEMXR5uIZvgz63ibfsCGTXFYUz9h7McGgmhfKWvQw9+MH6kRbE9U8qaUumgf4zi4HNzmf8AyaMJo07DIMwWVgjlVUdWUlN/Eg61fU3wC79mV8mLVsi5/TZ986obz4csoYSYXyyez5ScRji+znSw8vUx0YhoiOQbDms/y2QZR/toyon554tHkDZsya2lhpwXs8T0IFZhERXsmz/XmT3fWnhSzyrUe6VjBMep1zn6lvQ==
187 181e52f2b62f4768aa0d988936c929dc7c4a41a0 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl2UzlMQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91SDzD/0YZqtN+LK5AusJjWaTa61DRIPhJQoZD+HKg4kAzjL8zw8SxBGLxMZkGmve9QFMNzqIr5kkPk6yEKrEWYqyPtpwrv5Xh5D4d8AKfphdzwSr+BvMk4fBEvwnBhrUJtKDEiuYQdbh4+OQfQs1c3xhtinjXn30160uzFvLQY6/h4hxai2XWj4trgoNXqPHDHlQKc6kRfPpmNO2UZhG+2Xfsava2JpcP4xA2R0XkI10be5MDoGU4AFCMUcXZzIto0DYT+HOezowoNpdC1EWVHfa+bdrlzHHO7WPaTLzEPy44/IhXmNhbwFKOk5RZ/qBADQvs9BDfmIDczOoZKTC5+ESZM0PR2np5t7+JFMUeeRcINqBdSc4Aszw3iHjgNbJJ3viU72JZvGGGd9MglP590tA0proVGxQgvXDq3mtq3Se5yOLAjmRnktW5Tnt8/Z3ycuZz+QsTEMXR5uIZvgz63ibfsCGTXFYUz9h7McGgmhfKWvQw9+MH6kRbE9U8qaUumgf4zi4HNzmf8AyaMJo07DIMwWVgjlVUdWUlN/Eg61fU3wC79mV8mLVsi5/TZ986obz4csoYSYXyyez5ScRji+znSw8vUx0YhoiOQbDms/y2QZR/toyon554tHkDZsya2lhpwXs8T0IFZhERXsmz/XmT3fWnhSzyrUe6VjBMep1zn6lvQ==
188 59338f9561099de77c684c00f76507f11e46ebe8 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl2ty1MQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91XBUD/wJqwW0cuMCUvuUODLIfWa7ZxNl1mV9eW3tFQEuLGry97s12KDwBe0Erdjj7DASl4/6Xpc4PYxelZwSw4xT1UQg7wd/C3daCq/cDXrAkl7ZNTAHu6iAnHh25mOpIBfhMbh4j3YD0A2OoI17QGScU6S7Uv0Gz1CY20lJmEqsMzuuDPm2zrdPnTWffRUuPgskAg3czaw45Na7nUBeaxN1On0O5WqMYZsCGyi14g5S0Z0LHMKRJzc/s48JUTDjTbbzJ6HBxrxWTW2v8gN2J6QDYykcLBB9kV6laal9jhWs9n/w0yWwHfBfJ+E4EiMXeRdZgGA55OCOuDxnmmONs1/Z0WwPo+vQlowEnjDMT0jPrPePZ5P4BDXZD3tGsmdXDHM7j+VfDyPh1FBFpcaej44t84X1OWtAnLZ3VMPLwobz9MOzz4wr9UuHq23hus0Fen+FJYOAlTx9qPAqBrCTpGl+h1DMKD62D7lF8Z1CxTlqg9PPBB7IZNCXoN7FZ4Wfhv1AarMVNNUgBx6m0r6OScCXrluuFklYDSIZrfgiwosXxsHW27RjxktrV4O+J1GT/chLBJFViTZg/gX/9UC3eLkzp1t6gC6T9SQ+lq0/I+1/rHQkxNaywLycBPOG1yb/59mibEwB9+Mu9anRYKFNHEktNoEmyw5G9UoZhD+1tHt4tkJCwA==
188 59338f9561099de77c684c00f76507f11e46ebe8 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl2ty1MQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91XBUD/wJqwW0cuMCUvuUODLIfWa7ZxNl1mV9eW3tFQEuLGry97s12KDwBe0Erdjj7DASl4/6Xpc4PYxelZwSw4xT1UQg7wd/C3daCq/cDXrAkl7ZNTAHu6iAnHh25mOpIBfhMbh4j3YD0A2OoI17QGScU6S7Uv0Gz1CY20lJmEqsMzuuDPm2zrdPnTWffRUuPgskAg3czaw45Na7nUBeaxN1On0O5WqMYZsCGyi14g5S0Z0LHMKRJzc/s48JUTDjTbbzJ6HBxrxWTW2v8gN2J6QDYykcLBB9kV6laal9jhWs9n/w0yWwHfBfJ+E4EiMXeRdZgGA55OCOuDxnmmONs1/Z0WwPo+vQlowEnjDMT0jPrPePZ5P4BDXZD3tGsmdXDHM7j+VfDyPh1FBFpcaej44t84X1OWtAnLZ3VMPLwobz9MOzz4wr9UuHq23hus0Fen+FJYOAlTx9qPAqBrCTpGl+h1DMKD62D7lF8Z1CxTlqg9PPBB7IZNCXoN7FZ4Wfhv1AarMVNNUgBx6m0r6OScCXrluuFklYDSIZrfgiwosXxsHW27RjxktrV4O+J1GT/chLBJFViTZg/gX/9UC3eLkzp1t6gC6T9SQ+lq0/I+1/rHQkxNaywLycBPOG1yb/59mibEwB9+Mu9anRYKFNHEktNoEmyw5G9UoZhD+1tHt4tkJCwA==
189 ca3dca416f8d5863ca6f5a4a6a6bb835dcd5feeb 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl3BrQ4QHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91ZXjEACfBdZczf0a4bmeaaxRwxXAniSS4rVkF790g22fsvSZFvQEpmwqNtsvbTt3N1V2QSDSZyhBa+/qfpuZ689VXMlR3rcJOVjo/7193QLXHOPfRn7sDeeCxjsbtXXLbLa8UT56gtT5gUa4i0LC2kHBEi+UhV9EGgSaDTBxWUFJ9RY2sosy1XFiOUlkUoHUbqUF28J3/CxEXzULWkqTOPwh94JYsgXSSS69WNZEfsuEBSPCzn8Gd7z7lWudZ/VTZBTpTji7HQxpFtSZxNzpwmcmVOH9HlEKoA1K4JoR+1TMHqSytQXlz3FMF6c6Z1G+OPpwTGCjGTkB9ZAusP3gU8KIZTTEXthiEluRtnRq1yu4K2LTyY172JPJvANAWpVEvBvn4k5c9tDOEt9RCAPqCrgNGzDTrw02+gZyyNkjcS6hPn+cDJ6OQ1j2eCQtHlqfHLSc7FsRjUSTiKSEUTdWvHbNfOYe6Yth/tnQ7TnpnS9S0eiugFzZs2f8P85Gfa3uTFQIDm67Ud+8Yu1uOxa6bhECLaXEACnLofzz8sioLsJMiOoG2HmwhyPyfZUHXlb2zdsSP3LC+gKN39VvzSxhhjrIUJoM4ulP0GP1/lkMVzOady66iLaEwDvEn4FLmu395SubHwbre1Jx83hiCQpZfPkI0PhKnh4yVm+BRGUpX97rMTGjzw==
189 ca3dca416f8d5863ca6f5a4a6a6bb835dcd5feeb 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl3BrQ4QHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91ZXjEACfBdZczf0a4bmeaaxRwxXAniSS4rVkF790g22fsvSZFvQEpmwqNtsvbTt3N1V2QSDSZyhBa+/qfpuZ689VXMlR3rcJOVjo/7193QLXHOPfRn7sDeeCxjsbtXXLbLa8UT56gtT5gUa4i0LC2kHBEi+UhV9EGgSaDTBxWUFJ9RY2sosy1XFiOUlkUoHUbqUF28J3/CxEXzULWkqTOPwh94JYsgXSSS69WNZEfsuEBSPCzn8Gd7z7lWudZ/VTZBTpTji7HQxpFtSZxNzpwmcmVOH9HlEKoA1K4JoR+1TMHqSytQXlz3FMF6c6Z1G+OPpwTGCjGTkB9ZAusP3gU8KIZTTEXthiEluRtnRq1yu4K2LTyY172JPJvANAWpVEvBvn4k5c9tDOEt9RCAPqCrgNGzDTrw02+gZyyNkjcS6hPn+cDJ6OQ1j2eCQtHlqfHLSc7FsRjUSTiKSEUTdWvHbNfOYe6Yth/tnQ7TnpnS9S0eiugFzZs2f8P85Gfa3uTFQIDm67Ud+8Yu1uOxa6bhECLaXEACnLofzz8sioLsJMiOoG2HmwhyPyfZUHXlb2zdsSP3LC+gKN39VvzSxhhjrIUJoM4ulP0GP1/lkMVzOady66iLaEwDvEn4FLmu395SubHwbre1Jx83hiCQpZfPkI0PhKnh4yVm+BRGUpX97rMTGjzw==
190 a50fecefa691c9b72a99e49aa6fe9dd13943c2bf 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl3pEYIQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91duiD/9fwJbyrXXdpoBCeW3pgiz/xKZRQq0N3UqC/5m3PGl2qPfDqTi1GA6J+O24Cpy/FXYLEKlrEG2jy/iBZnGgTpb2sgycHFlWCT7VbuS8SDE3FFloTE8ZOGy5eJRo1UXYu4vsvNtmarN1xJQPrVK4l/Co5XWXFx15H/oMXLaHzS0kzQ/rHsMr7UXM0QwtmLC0S9IMetg5EUQx9GtHHaRnh1PIyP5NxP9VQ9RK4hmT6F2g60bcsMfpgF0I/RgL3tcdUn1RNIZ2OXHBhKYL+xOUe+wadDPIyPDqLXNEqPH7xqi0MQm/jOG++AvUPM7AdVc9Y2eRFOIIBIY0nkU5LL4yVVdqoc8kgwz14xhJXGTpMDRD54F6WrQtxhbHcb+JF7QDe3i9wI1LvurW4IIA5e4DC1q9yKKxNx9cDUOMF5q9ehiW9V120LTXJnYOUwfB7D4bIhe2mpOw8yYABU3gZ0Q6iVBTH+9rZYZ9TETX6vkf/DnJXteo39OhKrZ1Z4Gj6MSAjPJLARnYGnRMgvsyHSbV0TsGA4tdEaBs3dZmUV7maxLbs70sO6r9WwUY37TcYYHGdRplD9AreDLcxvjXA73Iluoy9WBGxRWF8wftQjaE9XR4KkDFrAoqqYZwN2AwHiTjVD1lQx+xvxZeEQ3ZBDprH3Uy6TwqUo5jbvHgR2+HqaZlTg==
190 a50fecefa691c9b72a99e49aa6fe9dd13943c2bf 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl3pEYIQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91duiD/9fwJbyrXXdpoBCeW3pgiz/xKZRQq0N3UqC/5m3PGl2qPfDqTi1GA6J+O24Cpy/FXYLEKlrEG2jy/iBZnGgTpb2sgycHFlWCT7VbuS8SDE3FFloTE8ZOGy5eJRo1UXYu4vsvNtmarN1xJQPrVK4l/Co5XWXFx15H/oMXLaHzS0kzQ/rHsMr7UXM0QwtmLC0S9IMetg5EUQx9GtHHaRnh1PIyP5NxP9VQ9RK4hmT6F2g60bcsMfpgF0I/RgL3tcdUn1RNIZ2OXHBhKYL+xOUe+wadDPIyPDqLXNEqPH7xqi0MQm/jOG++AvUPM7AdVc9Y2eRFOIIBIY0nkU5LL4yVVdqoc8kgwz14xhJXGTpMDRD54F6WrQtxhbHcb+JF7QDe3i9wI1LvurW4IIA5e4DC1q9yKKxNx9cDUOMF5q9ehiW9V120LTXJnYOUwfB7D4bIhe2mpOw8yYABU3gZ0Q6iVBTH+9rZYZ9TETX6vkf/DnJXteo39OhKrZ1Z4Gj6MSAjPJLARnYGnRMgvsyHSbV0TsGA4tdEaBs3dZmUV7maxLbs70sO6r9WwUY37TcYYHGdRplD9AreDLcxvjXA73Iluoy9WBGxRWF8wftQjaE9XR4KkDFrAoqqYZwN2AwHiTjVD1lQx+xvxZeEQ3ZBDprH3Uy6TwqUo5jbvHgR2+HqaZlTg==
191 b4c82b70418022e67cc0e69b1aa3c3aa43aa1d29 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl4TkWgQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91aV6D/4xzlluOwsBhLXWUi7bDp4HtYnyDhq4XuDORAMO5mCZ7I7J6uqGoViqH4AhXoo3yPp1cDiRzzl172xpec38uTL8C5zHhARKuAl5Pn1A8rYORvYzT9nsDh4MAtfTokhg81awRzhun9xtPUT2nETAOgampW0g7r241MSR1j0myAkC7zqO3yf+1rYo7kiv7fh+74MkrSn4HEmEaLsI5gW05tFR+ip6vpm6eikFinqeVJegDCuyTPMvH0D9ZeBNlyoOfdEd6DDYsWvWAmLSO9FGbb03R5aOFRp7RmQRFH/qcueeePa/9Z1zO+YyCeBy0wvWCkjfLMY99HhNhdNfy/qC/69V5RGQYvaapy6BEAi4eCH73hsxzCQpKopUl9VrpwhNasJ41KWc90RsPO91bkTdDddF7e2qjq762aNgm7ysEzIHMgSsMgsE9w8hz70RE7bk/gYn26ak3XP4nCOY0OJQ8mgaElN/FP1kxqqT7MM7WeMiNMFTD1gvWwEAu9Y47AwUedkTrykQsAFzc+CyaIaW+/Kuyv0j5E7v8zAcVTTX4xIyqR4yL2Nwe1rYE4MZgs0L9gQ3rcdyft6899gAiiq96MPR3gLJUPbBz2azH/e0CzNXvDJa39jIm2ez0qC7c88NhTKhFjHE9EW5GI3g8mhS5dJXCnUSq4spgtrJdfGenL3vLw==
191 b4c82b70418022e67cc0e69b1aa3c3aa43aa1d29 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl4TkWgQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91aV6D/4xzlluOwsBhLXWUi7bDp4HtYnyDhq4XuDORAMO5mCZ7I7J6uqGoViqH4AhXoo3yPp1cDiRzzl172xpec38uTL8C5zHhARKuAl5Pn1A8rYORvYzT9nsDh4MAtfTokhg81awRzhun9xtPUT2nETAOgampW0g7r241MSR1j0myAkC7zqO3yf+1rYo7kiv7fh+74MkrSn4HEmEaLsI5gW05tFR+ip6vpm6eikFinqeVJegDCuyTPMvH0D9ZeBNlyoOfdEd6DDYsWvWAmLSO9FGbb03R5aOFRp7RmQRFH/qcueeePa/9Z1zO+YyCeBy0wvWCkjfLMY99HhNhdNfy/qC/69V5RGQYvaapy6BEAi4eCH73hsxzCQpKopUl9VrpwhNasJ41KWc90RsPO91bkTdDddF7e2qjq762aNgm7ysEzIHMgSsMgsE9w8hz70RE7bk/gYn26ak3XP4nCOY0OJQ8mgaElN/FP1kxqqT7MM7WeMiNMFTD1gvWwEAu9Y47AwUedkTrykQsAFzc+CyaIaW+/Kuyv0j5E7v8zAcVTTX4xIyqR4yL2Nwe1rYE4MZgs0L9gQ3rcdyft6899gAiiq96MPR3gLJUPbBz2azH/e0CzNXvDJa39jIm2ez0qC7c88NhTKhFjHE9EW5GI3g8mhS5dJXCnUSq4spgtrJdfGenL3vLw==
192 84a0102c05c7852c8215ef6cf21d809927586b69 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl4nP/4QHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91VaHD/93dVKKFMJtclNMIG2AK3yZjfQ3HaqIuK1CqOuZyVQmk5fbnLydbi5RjIQMkaYPSKjDz0OKlfzDYo6kQrZrZUzIxzPBOz8/NMRSHGAWqvzQMbQGjYILsqDQ+wbol9wk8IDoyFzIcB4gPED1U5kWVCBTEqRrYiGP4siiycXVO5334Q5zOrvcjze0ksufbKQhL6SEUovfLtpX+DW6Z841LmR53aquEH8iBGswHKRt4ukyvmXTQAgea4lWXZXj3DH6oZqe0yzg5ogF4vFaoIgZDpBh2LZKuh6gwJtvA9jsFj5HVOzYDcllkgpaOTV1g/xKPo1EkLpt0W0vd/4vnjSKNo0fmOTvZzI9vCCXLlRSUhoboY6AFHN7XtL9gYWI0rj81p/WrnnQQ7Iv2YHS1KCLr765HW6mjREwFMLD9RrLLDQ0DWIyNuGq8/yrqoruAhidEE9ifITnNh38wVISdiPxORj3onZkAn7VbOWQnlJtYkynlk2t3HnHWfduLGc2G0BkLvg4YfEDsZBA+ssr+TspkZ1dVAq8kf4JKNR01sfjBF6Fj1zRPkoexV40/pPiW55ikfOI9LRHxRiOUyndLviIBv1Mbm90PZ89lT4OTMejD8hhb4omlVxH3HFv4j7TozuPFOuouH7ARRwbPFl/0ldPlESoGvFiyOrqNzlql+JvyLUSbg==
192 84a0102c05c7852c8215ef6cf21d809927586b69 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl4nP/4QHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91VaHD/93dVKKFMJtclNMIG2AK3yZjfQ3HaqIuK1CqOuZyVQmk5fbnLydbi5RjIQMkaYPSKjDz0OKlfzDYo6kQrZrZUzIxzPBOz8/NMRSHGAWqvzQMbQGjYILsqDQ+wbol9wk8IDoyFzIcB4gPED1U5kWVCBTEqRrYiGP4siiycXVO5334Q5zOrvcjze0ksufbKQhL6SEUovfLtpX+DW6Z841LmR53aquEH8iBGswHKRt4ukyvmXTQAgea4lWXZXj3DH6oZqe0yzg5ogF4vFaoIgZDpBh2LZKuh6gwJtvA9jsFj5HVOzYDcllkgpaOTV1g/xKPo1EkLpt0W0vd/4vnjSKNo0fmOTvZzI9vCCXLlRSUhoboY6AFHN7XtL9gYWI0rj81p/WrnnQQ7Iv2YHS1KCLr765HW6mjREwFMLD9RrLLDQ0DWIyNuGq8/yrqoruAhidEE9ifITnNh38wVISdiPxORj3onZkAn7VbOWQnlJtYkynlk2t3HnHWfduLGc2G0BkLvg4YfEDsZBA+ssr+TspkZ1dVAq8kf4JKNR01sfjBF6Fj1zRPkoexV40/pPiW55ikfOI9LRHxRiOUyndLviIBv1Mbm90PZ89lT4OTMejD8hhb4omlVxH3HFv4j7TozuPFOuouH7ARRwbPFl/0ldPlESoGvFiyOrqNzlql+JvyLUSbg==
193 e4344e463c0c888a2f437b78b5982ecdf3f6650a 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl4rFTIQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91eStD/wNSk7/07dvzItYmxg9LuUInYH17pZrXm8+jGEejoYZw74R1BHusFBcnmB1URldbq4IdzlxXNKrcnmJH/lgYCdbZ8OG0MaQrEIyLz0WmY27ARb/AwDuiy/dn0X3NgvQjqPffLHrYHmdqvqBsb0+qG3v7b0xt+BGDkebt1TXCy9wjIa1iqCOQ0EJi2dcuD2dWlhPM2kuslMjKlqe57D5bwaHBDS6K9Sd4VABRdv7mExrMBSr1SnkasrBsvb47UVXYUJRI3GGyA/wYYAi3fW9ZxG25x2SA0rjF5U68c5rmQMD94FLmaSoaqSvigkSBDOF/DIwlRO5vB4NlP7/+TjNOo92r4GbTZyMTnrsORqQJKcMrpfVbM8gRngPTJz2FxBSoz86HQ3wVXnS0gVUJNM+ctWdvzvtrv1Np3wF0/zWHddrtfYdNgnuyKjQL3chpJs7y5aQxdgU1vHdf4X2NwhA77Cf/U6bSemhR+MfZlp4it7pZiu96b8jKsEbKrCi998tKCKVv70WhGXce3gebKPY3Gn/qUL6X3rx4Uj5CPrIjWZNhwRJJ3BXSTnKog2eUIWJC0rXXrGRV6Sf6514zbi0MCOexnAjZM1xs5NUd/wrugDnMp4+P+ZPZyseeVB51NSnGhxlYLwD9EN+4ocjyBzMINOcQw1GPkB5Rrqwh+19q5SnvA==
193 e4344e463c0c888a2f437b78b5982ecdf3f6650a 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl4rFTIQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91eStD/wNSk7/07dvzItYmxg9LuUInYH17pZrXm8+jGEejoYZw74R1BHusFBcnmB1URldbq4IdzlxXNKrcnmJH/lgYCdbZ8OG0MaQrEIyLz0WmY27ARb/AwDuiy/dn0X3NgvQjqPffLHrYHmdqvqBsb0+qG3v7b0xt+BGDkebt1TXCy9wjIa1iqCOQ0EJi2dcuD2dWlhPM2kuslMjKlqe57D5bwaHBDS6K9Sd4VABRdv7mExrMBSr1SnkasrBsvb47UVXYUJRI3GGyA/wYYAi3fW9ZxG25x2SA0rjF5U68c5rmQMD94FLmaSoaqSvigkSBDOF/DIwlRO5vB4NlP7/+TjNOo92r4GbTZyMTnrsORqQJKcMrpfVbM8gRngPTJz2FxBSoz86HQ3wVXnS0gVUJNM+ctWdvzvtrv1Np3wF0/zWHddrtfYdNgnuyKjQL3chpJs7y5aQxdgU1vHdf4X2NwhA77Cf/U6bSemhR+MfZlp4it7pZiu96b8jKsEbKrCi998tKCKVv70WhGXce3gebKPY3Gn/qUL6X3rx4Uj5CPrIjWZNhwRJJ3BXSTnKog2eUIWJC0rXXrGRV6Sf6514zbi0MCOexnAjZM1xs5NUd/wrugDnMp4+P+ZPZyseeVB51NSnGhxlYLwD9EN+4ocjyBzMINOcQw1GPkB5Rrqwh+19q5SnvA==
194 7f5410dfc8a64bb587d19637deb95d378fd1eb5c 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl44RUUQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91WcUD/9em14ckTP9APTrSpe6y4FLS6cIUZabNN6wDXjTrHmS26hoNvWrT+RpWQ5XSOOJhZdhjkR1k87EOw9+m6+36ZaL+RXYnjrbku9fxbbFBraGTFy0JZHAT6v57uQ8P7XwqN4dGvXXpgE5UuY5sp1uDRbtIPNts3iWJKAnIazxUnyotHNtJQNESHySomzR1s93z1oOMpHapAqUmPbcZywg4otWjrOnkhOok3Sa3TgGthpHbM0qmh6J9ZaRBXsKEpLkjCRNggdvqww1w4omcAJzY4V5tG8WfhW+Xl8zBBe0K5m/ug3e25sWR5Dqm4+qUO0HZWQ3m3/M7CCuQrWFXTkr7nKac50vtFzsqHlHNoaiKnvQKoruQs3266TGsrzCCOSy8BqmpysD6sB79owLKoh0LfFOcSwG9kZ8sovEvTfrRn8g3YAp7XbXkDxbcLMijr7P4gWq8sC1NZJn1yhLXitcCfAAuVrVQfPVdt2pp8Ry2NdGnHjikQjOn/wAKlYJ5F8JMdn6eEI/Gveg2g8uR9kp/9zaXRx6rU3ccuZQ7cBQbBlBsmmpd7gJRp2v0NKsV8hXtCPnBvcfCqgYHLg7FQVq1wKe5glvtmx9uPZNsl/S++fSxGoXfp9wVi048J42KyEH6yvoySCvbYeSFQvMfAoD1xJ4xWtT8ZEj6oiHvzHw1u/zgw==
194 7f5410dfc8a64bb587d19637deb95d378fd1eb5c 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl44RUUQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91WcUD/9em14ckTP9APTrSpe6y4FLS6cIUZabNN6wDXjTrHmS26hoNvWrT+RpWQ5XSOOJhZdhjkR1k87EOw9+m6+36ZaL+RXYnjrbku9fxbbFBraGTFy0JZHAT6v57uQ8P7XwqN4dGvXXpgE5UuY5sp1uDRbtIPNts3iWJKAnIazxUnyotHNtJQNESHySomzR1s93z1oOMpHapAqUmPbcZywg4otWjrOnkhOok3Sa3TgGthpHbM0qmh6J9ZaRBXsKEpLkjCRNggdvqww1w4omcAJzY4V5tG8WfhW+Xl8zBBe0K5m/ug3e25sWR5Dqm4+qUO0HZWQ3m3/M7CCuQrWFXTkr7nKac50vtFzsqHlHNoaiKnvQKoruQs3266TGsrzCCOSy8BqmpysD6sB79owLKoh0LfFOcSwG9kZ8sovEvTfrRn8g3YAp7XbXkDxbcLMijr7P4gWq8sC1NZJn1yhLXitcCfAAuVrVQfPVdt2pp8Ry2NdGnHjikQjOn/wAKlYJ5F8JMdn6eEI/Gveg2g8uR9kp/9zaXRx6rU3ccuZQ7cBQbBlBsmmpd7gJRp2v0NKsV8hXtCPnBvcfCqgYHLg7FQVq1wKe5glvtmx9uPZNsl/S++fSxGoXfp9wVi048J42KyEH6yvoySCvbYeSFQvMfAoD1xJ4xWtT8ZEj6oiHvzHw1u/zgw==
195 6d121acbb82e65fe4dd3c2318a1b61981b958492 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl5f3IEQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91WoeD/9qhywGg/TI/FJEeJN5bJjcpB/YQeYDWCHh69yUmMPenf+6CaV/3QPc3R8JyQSKWwGUwc0IgZiJBb/HoUvBzpQyTvmGqddWsIGBpdGAkbLmRrE5BakR7Shs987a3Oq4hB03DJD4sQ1VitWg2OvGNd8rl1kSIF8aIErVI6ZiSw5eYemc/1VyBJXHWSFmcfnQqdsyPppH9e9/TAhio+YP4EmLmoxUcyRSb3UbtO2NT9+DEADaex+H2l9evg7AkTieVd6N163uqsLJIxSfCh5ZVmzaGW6uEoyC4U+9bkAyVE3Cy5z2giYblBzUkO9xqEZoA4tOM+b+gHokY8Sq3iGVw046CIW5+FjU9B5+7hCqWThYjnpnt+RomtHxrkqQ9SSHYnEWb4YTHqs+J7lWbm3ErjF08hYOyMA9/VT47UAKw4XL4Ss/1Pr7YezdmwB4jn7dqvslNvTqRAUOzB/15YeCfbd23SL4YzGaKBs9ajkxFFeCNNpLQ8CRm3a7/K6qkYyfSUpgUX7xBmRQTvUgr3nVk1epH/kOKwryy94Z+nlHF0qEMEq+1QOa5yvt3Kkr4H03pOFbLhdpjID5IYP4rRQTKB9yOS3XWBCE63AQVc7uuaBGPMCSLaKRAFDUXWY7GzCqda88WeN5BFC5iHrQTYE1IQ5YaWu38QMsJt2HHVc27+BuLA==
195 6d121acbb82e65fe4dd3c2318a1b61981b958492 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl5f3IEQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91WoeD/9qhywGg/TI/FJEeJN5bJjcpB/YQeYDWCHh69yUmMPenf+6CaV/3QPc3R8JyQSKWwGUwc0IgZiJBb/HoUvBzpQyTvmGqddWsIGBpdGAkbLmRrE5BakR7Shs987a3Oq4hB03DJD4sQ1VitWg2OvGNd8rl1kSIF8aIErVI6ZiSw5eYemc/1VyBJXHWSFmcfnQqdsyPppH9e9/TAhio+YP4EmLmoxUcyRSb3UbtO2NT9+DEADaex+H2l9evg7AkTieVd6N163uqsLJIxSfCh5ZVmzaGW6uEoyC4U+9bkAyVE3Cy5z2giYblBzUkO9xqEZoA4tOM+b+gHokY8Sq3iGVw046CIW5+FjU9B5+7hCqWThYjnpnt+RomtHxrkqQ9SSHYnEWb4YTHqs+J7lWbm3ErjF08hYOyMA9/VT47UAKw4XL4Ss/1Pr7YezdmwB4jn7dqvslNvTqRAUOzB/15YeCfbd23SL4YzGaKBs9ajkxFFeCNNpLQ8CRm3a7/K6qkYyfSUpgUX7xBmRQTvUgr3nVk1epH/kOKwryy94Z+nlHF0qEMEq+1QOa5yvt3Kkr4H03pOFbLhdpjID5IYP4rRQTKB9yOS3XWBCE63AQVc7uuaBGPMCSLaKRAFDUXWY7GzCqda88WeN5BFC5iHrQTYE1IQ5YaWu38QMsJt2HHVc27+BuLA==
196 8fca7e8449a847e3cf1054f2c07b51237699fad3 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl6GDVQQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91egzEACNEyQwLWCQEeNyxXKuTsnXhYU/au7nSGOti/9+zg/22SSceMsVcIyNr2ZnkMf3hnzBjL7Efsthif0QXyfB0LZDXwNuDmNlDtUV2veyVGSDE2UqiSbDBRu6MYTvtfYX87RmSWla3HHO09pwpcrhxyHs3mliQsXyB2+D+ovTOIjYukQLnh34jQnwiWEYLDXkHEHHTpdXqAnA7tVen3ardLyTWgky6DUwlfcnoVsAPXnDkqQ9aE2w7SoAsNtEAddmkjKoYYdBkV5aUInU/DyFVF7qnlCcvWm+EkN1708xZUQ1KzdAyeeoIrMkBgpSoyeNQ9pcU3T7B100UxLo/FP/A7y96b2kHnKJU6fVyD3OeHvP9SeucurC6jn2YoG3e1wSOQcbEuCsdGjqgAHnKt2SMPsEBu2qJJcUdco9tANN5BdntBo7bLc/zcpXZH3TkRfRSndWXPaXDJaQNvbH7aLIUTCP9oQaqTN+9BQ+Egt7YsB4C58JZmC87FAuekDULc4LWK2gDPFf7F/PvBnMh7+YylPl/8LLrEnz2Q/GM0S1HLhBrDf6vzxV5wVzCu9Q2N0PCkg6lDAJFVWLTEbxcRukKxbyK88Yzrb4GuUY4F5V21fN4vuxkOay7eoiXUcHMN2IN+DwhNWQSm5pUnpqGTfCYj/ZBbAykP2UnVOClL6O2JQA2A==
196 8fca7e8449a847e3cf1054f2c07b51237699fad3 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl6GDVQQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91egzEACNEyQwLWCQEeNyxXKuTsnXhYU/au7nSGOti/9+zg/22SSceMsVcIyNr2ZnkMf3hnzBjL7Efsthif0QXyfB0LZDXwNuDmNlDtUV2veyVGSDE2UqiSbDBRu6MYTvtfYX87RmSWla3HHO09pwpcrhxyHs3mliQsXyB2+D+ovTOIjYukQLnh34jQnwiWEYLDXkHEHHTpdXqAnA7tVen3ardLyTWgky6DUwlfcnoVsAPXnDkqQ9aE2w7SoAsNtEAddmkjKoYYdBkV5aUInU/DyFVF7qnlCcvWm+EkN1708xZUQ1KzdAyeeoIrMkBgpSoyeNQ9pcU3T7B100UxLo/FP/A7y96b2kHnKJU6fVyD3OeHvP9SeucurC6jn2YoG3e1wSOQcbEuCsdGjqgAHnKt2SMPsEBu2qJJcUdco9tANN5BdntBo7bLc/zcpXZH3TkRfRSndWXPaXDJaQNvbH7aLIUTCP9oQaqTN+9BQ+Egt7YsB4C58JZmC87FAuekDULc4LWK2gDPFf7F/PvBnMh7+YylPl/8LLrEnz2Q/GM0S1HLhBrDf6vzxV5wVzCu9Q2N0PCkg6lDAJFVWLTEbxcRukKxbyK88Yzrb4GuUY4F5V21fN4vuxkOay7eoiXUcHMN2IN+DwhNWQSm5pUnpqGTfCYj/ZBbAykP2UnVOClL6O2JQA2A==
197 26ce8e7515036d3431a03aaeb7bc72dd96cb1112 0 iQJJBAABCgAzFiEE64UTlbQiPuL3ugso2lR0C/CHMroFAl6YlRUVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJENpUdAvwhzK6Z3YP/iOqphn99v0z2OupCl0q8CepbcdZMJWW3j00OAHYSO43M0FULpMpzC2o+kZDeqeLyzN7DsjoGts2cUnAOe9WX73sPkX1n1dbiDcUSsRqNND+tCkEZMtTn4DaGNIq1zSkkm8Q7O/1uwZPnX6FaIRMBs9qGbdfmMPNEvzny2tgrKc3ra1+AA8RCdtsbpqhjy+xf+EKVB/SMsQVVSJEgPkUkW6PwpaspdrxQKgZrb7C7Jx/gRVzMTUmCQe1sVCSnZNO3I/woAqDY2UNg7/hBubeRh/EjoH1o4ONTXgBQdYCl7QdcwDHpDc2HstonrFq51qxBecHDVw+ZKQds63Ixtxuab3SK0o/SWabZ1v8bGaWnyWnRWXL/1qkyFWly+fjEGGlv1kHl3n0UmwlUY8FQJCYDZgR0FqQGXAF3vMJOEp82ysk6jWN/7NRzcnoUC7HpNo1jPMiPRjskgVf3bhErfUQnhlF1YsVu/jPTixyfftbiaZmwILMkaPF8Kg3Cyf63p2cdcnTHdbP1U6ncR+BucthlbFei4WL0J2iERb8TBeCxOyCHlEUq8kampjbmPXN7VxnK4oX3xeBTf8mMbvrD5Fv3svRD+SkCCKu/MwQvB1VT6q425TSKHbCWeNqGjVLvetpx+skVH7eaXLEQ3wlCfo/0OQTRimx2O73EnOF5r8Q2POm
197 26ce8e7515036d3431a03aaeb7bc72dd96cb1112 0 iQJJBAABCgAzFiEE64UTlbQiPuL3ugso2lR0C/CHMroFAl6YlRUVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJENpUdAvwhzK6Z3YP/iOqphn99v0z2OupCl0q8CepbcdZMJWW3j00OAHYSO43M0FULpMpzC2o+kZDeqeLyzN7DsjoGts2cUnAOe9WX73sPkX1n1dbiDcUSsRqNND+tCkEZMtTn4DaGNIq1zSkkm8Q7O/1uwZPnX6FaIRMBs9qGbdfmMPNEvzny2tgrKc3ra1+AA8RCdtsbpqhjy+xf+EKVB/SMsQVVSJEgPkUkW6PwpaspdrxQKgZrb7C7Jx/gRVzMTUmCQe1sVCSnZNO3I/woAqDY2UNg7/hBubeRh/EjoH1o4ONTXgBQdYCl7QdcwDHpDc2HstonrFq51qxBecHDVw+ZKQds63Ixtxuab3SK0o/SWabZ1v8bGaWnyWnRWXL/1qkyFWly+fjEGGlv1kHl3n0UmwlUY8FQJCYDZgR0FqQGXAF3vMJOEp82ysk6jWN/7NRzcnoUC7HpNo1jPMiPRjskgVf3bhErfUQnhlF1YsVu/jPTixyfftbiaZmwILMkaPF8Kg3Cyf63p2cdcnTHdbP1U6ncR+BucthlbFei4WL0J2iERb8TBeCxOyCHlEUq8kampjbmPXN7VxnK4oX3xeBTf8mMbvrD5Fv3svRD+SkCCKu/MwQvB1VT6q425TSKHbCWeNqGjVLvetpx+skVH7eaXLEQ3wlCfo/0OQTRimx2O73EnOF5r8Q2POm
198 cf3e07d7648a4371ce584d15dd692e7a6845792f 0 iQJJBAABCgAzFiEE64UTlbQiPuL3ugso2lR0C/CHMroFAl6sS5sVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJENpUdAvwhzK6FQcP/1usy9WxajBppBZ54ep+qesxufLoux5qkRU7j4XZ0Id4/IcKQZeik0C/0mFMjc+dYhQDGpDiuXCADKMv5h2DCIoaWUC0GueVtVkPhhMW3zMg/BmepV7dhUuipfQ4fck8gYuaBOclunLX1MFd+CS/6BQ6XIrsKasnx9WrbO2JpieBXv+8I5mslChaZf2AxeIvUVb2BkKqsCD0rqbIjTjtfHWJpaH6spFa7XX/BZWeEYz2Nc6LVJNZY0AmvJh8ebpoGOx85dokRIEAzTmBh04SbkChi+350ki6MvG3Ax+3yrUZVc1PJtBDreL7dMs7Y3ENafSMhKnBrRaPVMyUHEm2Ygn4cmJ1YiGw4OWha1n7dtRW/uI96lXKDt8iLAQ4WBRojPhYNl4L3b6/6voCgpZUOpd7PgTRc3/00siCmYIOQzAO0HkDsALoNpk8LcCxpPFYTr8dF3bSsAT9fuaLNV6tI2ofbRLXh0gFXYdaWu10eVRrSMUMiH7n3H6EpzLa4sNdyFrK0vU4aSTlBERcjj2rj86dY0XQQL181V7Yhg8m8nyj+BzraRh7et2UXNsVosOnbTa1XX0qFVu+qAVp2BeqC4k31jm0MJk+1pDzkuAPs07z3ITwkDmTHjzxm5qoZyZ1/n37BB6miD+8xJYNH7vBX/yrDW790HbloasQOcXcerNR
198 cf3e07d7648a4371ce584d15dd692e7a6845792f 0 iQJJBAABCgAzFiEE64UTlbQiPuL3ugso2lR0C/CHMroFAl6sS5sVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJENpUdAvwhzK6FQcP/1usy9WxajBppBZ54ep+qesxufLoux5qkRU7j4XZ0Id4/IcKQZeik0C/0mFMjc+dYhQDGpDiuXCADKMv5h2DCIoaWUC0GueVtVkPhhMW3zMg/BmepV7dhUuipfQ4fck8gYuaBOclunLX1MFd+CS/6BQ6XIrsKasnx9WrbO2JpieBXv+8I5mslChaZf2AxeIvUVb2BkKqsCD0rqbIjTjtfHWJpaH6spFa7XX/BZWeEYz2Nc6LVJNZY0AmvJh8ebpoGOx85dokRIEAzTmBh04SbkChi+350ki6MvG3Ax+3yrUZVc1PJtBDreL7dMs7Y3ENafSMhKnBrRaPVMyUHEm2Ygn4cmJ1YiGw4OWha1n7dtRW/uI96lXKDt8iLAQ4WBRojPhYNl4L3b6/6voCgpZUOpd7PgTRc3/00siCmYIOQzAO0HkDsALoNpk8LcCxpPFYTr8dF3bSsAT9fuaLNV6tI2ofbRLXh0gFXYdaWu10eVRrSMUMiH7n3H6EpzLa4sNdyFrK0vU4aSTlBERcjj2rj86dY0XQQL181V7Yhg8m8nyj+BzraRh7et2UXNsVosOnbTa1XX0qFVu+qAVp2BeqC4k31jm0MJk+1pDzkuAPs07z3ITwkDmTHjzxm5qoZyZ1/n37BB6miD+8xJYNH7vBX/yrDW790HbloasQOcXcerNR
199 065704cbdbdbb05dcd6bb814eb9bbdd982211b28 0 iQJJBAABCgAzFiEE64UTlbQiPuL3ugso2lR0C/CHMroFAl7amzkVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJENpUdAvwhzK6AKEP/26Hoe8VqkuGwU0ZDsK6YgErXEPs8xtgZ9A2iouDkIqw2dm1TDmWnB5X8XaWmhAWFMUdjcqd1ZZJrAyD0p13xUOm3D+hlDXYTd2INkLwS8cVu22czZ5eoxtPkjuGYlPvek9b3vrrejkZ4vpamdS3iSvIx+TzvEW+w5eZFh9s1a9gR77hcZZoir24vtM9MsNnnBuI/5/fdWkhBoe17HSU4II56ckNXDrGO0nuqrWDxPr64WAcz6EmlTGc+cUqOM45Uc0sCr3GNQGEm6VCAw5oXq2Vt9O6sjgExLxr8zdud6w5hl9b8h2MrxyisgcnVR7efbumaRuNb8QZZPzk5QqlRxbaEcStyIXzAdar4fArQUY2vrmv1WyLJR3S/G3p8QkyWYL3CZNKjCAVxSa5ytS5Dr/bM2sWaEnIHqq+W6DOagpWV4uRRnwaId9tB9b0KBoFElXZRlaq0FlNYG8RLg65ZlkF+lj6RACO23epxapadcJwibDQiNYX20mcSEFDkSEgECnLQBecA2WZvw134RRbL3vuvB49SKS0ZEJ95myXMZa9kyIJY/g+oAFBuyZeK9O8DwGii0zFDOi6VWDTZzc3/15RRS6ehqQyYrLQntYtVGwHpxnUrp2kBjk3hDIvaYOcFbTnhTGcQCzckFnIZN2oxr5YZOI+Fpfak6RQTVhnHh0/
199 065704cbdbdbb05dcd6bb814eb9bbdd982211b28 0 iQJJBAABCgAzFiEE64UTlbQiPuL3ugso2lR0C/CHMroFAl7amzkVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJENpUdAvwhzK6AKEP/26Hoe8VqkuGwU0ZDsK6YgErXEPs8xtgZ9A2iouDkIqw2dm1TDmWnB5X8XaWmhAWFMUdjcqd1ZZJrAyD0p13xUOm3D+hlDXYTd2INkLwS8cVu22czZ5eoxtPkjuGYlPvek9b3vrrejkZ4vpamdS3iSvIx+TzvEW+w5eZFh9s1a9gR77hcZZoir24vtM9MsNnnBuI/5/fdWkhBoe17HSU4II56ckNXDrGO0nuqrWDxPr64WAcz6EmlTGc+cUqOM45Uc0sCr3GNQGEm6VCAw5oXq2Vt9O6sjgExLxr8zdud6w5hl9b8h2MrxyisgcnVR7efbumaRuNb8QZZPzk5QqlRxbaEcStyIXzAdar4fArQUY2vrmv1WyLJR3S/G3p8QkyWYL3CZNKjCAVxSa5ytS5Dr/bM2sWaEnIHqq+W6DOagpWV4uRRnwaId9tB9b0KBoFElXZRlaq0FlNYG8RLg65ZlkF+lj6RACO23epxapadcJwibDQiNYX20mcSEFDkSEgECnLQBecA2WZvw134RRbL3vuvB49SKS0ZEJ95myXMZa9kyIJY/g+oAFBuyZeK9O8DwGii0zFDOi6VWDTZzc3/15RRS6ehqQyYrLQntYtVGwHpxnUrp2kBjk3hDIvaYOcFbTnhTGcQCzckFnIZN2oxr5YZOI+Fpfak6RQTVhnHh0/
200 0ea9c86fac8974cd74dc12ea681c8986eb6da6c4 0 iQJJBAABCgAzFiEE64UTlbQiPuL3ugso2lR0C/CHMroFAl78z0gVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJENpUdAvwhzK6IrkP/2m/DJ93BR/SljCFe7KnExrDTzDI/i69x+ljomRZJmMRa86zRkclgd5L49woExDd1ZGebUY650V16adKNmVpz2rS6bQOgEr2NBD5fL+GiTX6UJ1VMgmQ8x1m8DYuI8pfBWbqQuZIl1vCEc0RmT3tHLZ7T8XgG9RXa4XielI2uhyimJPyZsE1K7c8Fa6UakH++DhYFBj+3QYbwS2fFDdA29L/4N5JLUzHkIbF7tPg7P1RBk+vhopKz9MMIu4S95LU+Gk7eQ3FfE8Jnv959hX2o/B2sdT2tEPIuDRSxZhSKLdlGbMy5IZvc/bZ+a5jlb2w23tlpfgzQxNarFqpX/weiJCtsxzeMXQHEVFG/+VuIOIYbfILWzySFcnSvcAtmNXExxH2F9j+XmQkLysnsgIfplNVEEIgZDBPGAkAQ+lH7UrEdw31ciSrCDsjXDaPQWcmk4zkfrXlwN7R9zJguJ+OuZ/Ga7NXWdZAC+YkPSKAfCesdUefcesyiresO8GEk9DyRNQsX/gl5BjEeuqYyUsve5541IMqscvdosg6HrU/RrmeR7sM7tZrDwCWdOWu/GdFatQ+k6zArSrMTKUBztzV93MIwUHDrnd+7OOYDfAuqGy7oM2KoW0Jp8sS2hotIJZ9a+VGwQcxCJ93I5sVT6ePBdmBoIAFW+rbncnD+E/RvVpl
200 0ea9c86fac8974cd74dc12ea681c8986eb6da6c4 0 iQJJBAABCgAzFiEE64UTlbQiPuL3ugso2lR0C/CHMroFAl78z0gVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJENpUdAvwhzK6IrkP/2m/DJ93BR/SljCFe7KnExrDTzDI/i69x+ljomRZJmMRa86zRkclgd5L49woExDd1ZGebUY650V16adKNmVpz2rS6bQOgEr2NBD5fL+GiTX6UJ1VMgmQ8x1m8DYuI8pfBWbqQuZIl1vCEc0RmT3tHLZ7T8XgG9RXa4XielI2uhyimJPyZsE1K7c8Fa6UakH++DhYFBj+3QYbwS2fFDdA29L/4N5JLUzHkIbF7tPg7P1RBk+vhopKz9MMIu4S95LU+Gk7eQ3FfE8Jnv959hX2o/B2sdT2tEPIuDRSxZhSKLdlGbMy5IZvc/bZ+a5jlb2w23tlpfgzQxNarFqpX/weiJCtsxzeMXQHEVFG/+VuIOIYbfILWzySFcnSvcAtmNXExxH2F9j+XmQkLysnsgIfplNVEEIgZDBPGAkAQ+lH7UrEdw31ciSrCDsjXDaPQWcmk4zkfrXlwN7R9zJguJ+OuZ/Ga7NXWdZAC+YkPSKAfCesdUefcesyiresO8GEk9DyRNQsX/gl5BjEeuqYyUsve5541IMqscvdosg6HrU/RrmeR7sM7tZrDwCWdOWu/GdFatQ+k6zArSrMTKUBztzV93MIwUHDrnd+7OOYDfAuqGy7oM2KoW0Jp8sS2hotIJZ9a+VGwQcxCJ93I5sVT6ePBdmBoIAFW+rbncnD+E/RvVpl
201 28163c5de797e5416f9b588940f4608269b4d50a 0 iQJJBAABCgAzFiEE64UTlbQiPuL3ugso2lR0C/CHMroFAl8VylYVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJENpUdAvwhzK6zUEQAJoLrpMmHvM4VYepsu2UTFI2VA1iL7cd+AOlcAokn/29JOqmAWD2ujUMv2FIdcNqAW/ayeEW9oLAi0dOfLqS6UAxfw8hYEiM6hV1R0W9DOUV5CRQ5T86cbaZFBrrJL9N87tHjro0eS3i8iwPpklnWrwf8fkcBq8SKFBZbubat8X/mejbbq6zYML9SEhtrKHyBPL5iQjzqDEGWyTqJYusHGVkAtFMZWxStDA3VSr3x9Iy0495XdegYRkUFytRsz1zB3vfawJsWRY7tQfff5CF6knZ+UIpetjgJIlm21/vQmcL1aTIxem0CFQt5bub1a+LYI1TWt59rFrnRj97K6Kq6xG6lPjnM3l/w2nehGfpL/Tfjih9gY8ToS1GRg2JJ4IiXAI57fv5fZcZv3R0xAGfWfRdwMsO2siaDrd4R/kraDlTPZZ1Qmpa+Y4XtFxSGIXtf9DWt/7pw81GWrUH0u/WYjfSpYvbdr7GvYpdzxMmtEULoxJ9ibyFDyDyqEkJfT6onFb1aaHQJ1mjho1x93uDeAEq0R5UCSNDxi31Hq/nWtA9IwCjYeQkv9D1rxFcSx3MetUpJofdBYvvFsvjNTM5GO2ETvsjyzXf2Qa3oobQoKBqbTuKR6yJlCsmWJuejbDbblBdx3mj4xpXxmX/YQHQ+2PYrfopel/8Am8j7sq0sNcV
201 28163c5de797e5416f9b588940f4608269b4d50a 0 iQJJBAABCgAzFiEE64UTlbQiPuL3ugso2lR0C/CHMroFAl8VylYVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJENpUdAvwhzK6zUEQAJoLrpMmHvM4VYepsu2UTFI2VA1iL7cd+AOlcAokn/29JOqmAWD2ujUMv2FIdcNqAW/ayeEW9oLAi0dOfLqS6UAxfw8hYEiM6hV1R0W9DOUV5CRQ5T86cbaZFBrrJL9N87tHjro0eS3i8iwPpklnWrwf8fkcBq8SKFBZbubat8X/mejbbq6zYML9SEhtrKHyBPL5iQjzqDEGWyTqJYusHGVkAtFMZWxStDA3VSr3x9Iy0495XdegYRkUFytRsz1zB3vfawJsWRY7tQfff5CF6knZ+UIpetjgJIlm21/vQmcL1aTIxem0CFQt5bub1a+LYI1TWt59rFrnRj97K6Kq6xG6lPjnM3l/w2nehGfpL/Tfjih9gY8ToS1GRg2JJ4IiXAI57fv5fZcZv3R0xAGfWfRdwMsO2siaDrd4R/kraDlTPZZ1Qmpa+Y4XtFxSGIXtf9DWt/7pw81GWrUH0u/WYjfSpYvbdr7GvYpdzxMmtEULoxJ9ibyFDyDyqEkJfT6onFb1aaHQJ1mjho1x93uDeAEq0R5UCSNDxi31Hq/nWtA9IwCjYeQkv9D1rxFcSx3MetUpJofdBYvvFsvjNTM5GO2ETvsjyzXf2Qa3oobQoKBqbTuKR6yJlCsmWJuejbDbblBdx3mj4xpXxmX/YQHQ+2PYrfopel/8Am8j7sq0sNcV
202 7fc3c5fbc65f6fe85d70ea63923b8767dda4f2e0 0 iQJJBAABCgAzFiEE64UTlbQiPuL3ugso2lR0C/CHMroFAl8oTNkVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJENpUdAvwhzK6YLIP/0ZRwrBhBrMsy4UDS6dBwJ2WS5MRFIGTx44TW5Km/QGahz8kU+IEnKcV3Q9K7qu6Navt4uFvwFxJxDebcl4TJMfLqXH8gp8cma3GHLcHEgdms+lWe7osVVfDsynnSpZbwzUgeHoiJz805BAPrpesfq8GUDzeONJJcVtbAanSg+E0tnFNUE3592Oz8VjvgBAlPMdaRiPiTs2FrEN6+h1zxgHRSY8q4ZC88y1x5dst2yjCef9SUQ5MW1OCMuy+ki3QSwxRZfa28Z+17sJ6Lfy2ZqE2J7dZquGXllF6wPYGHmUZ1NKu4gY9aIghJBUzk6gZgvoqlJ44jFSlw4+Q8k9UW8GgLrMOkKCGstTztHDXdqCU4FMpUP+SaMq/XN4XRiyw5FiYyhBaCF3K3QwGqYNP4jadZqYAe1/UnjLWoPN5ZiXZQW7yD5MwOtrZOJFmm4PuFaAAPy4cdSvHpVA8HVQWyLhE0BSA7r8spPVptP3w9GG+qEGR3pvs0mVjMOVI/nWNuD40PILtGqqhbBIUawKqxtfdA1Pf1qcxWTC2Uxgtw0YuMHztPWihW0xfDxxdZ13ewQ4ETdWj598CyaUs3nVRX4ru33pmWBfhLSlXRsNhqc7N7XJ0xE8eHIUs7F3WCwBjMMemV6K3HN0xT4b+7uDdw2RuUA2HGtKLzNAGN9gyMd6/
202 7fc3c5fbc65f6fe85d70ea63923b8767dda4f2e0 0 iQJJBAABCgAzFiEE64UTlbQiPuL3ugso2lR0C/CHMroFAl8oTNkVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJENpUdAvwhzK6YLIP/0ZRwrBhBrMsy4UDS6dBwJ2WS5MRFIGTx44TW5Km/QGahz8kU+IEnKcV3Q9K7qu6Navt4uFvwFxJxDebcl4TJMfLqXH8gp8cma3GHLcHEgdms+lWe7osVVfDsynnSpZbwzUgeHoiJz805BAPrpesfq8GUDzeONJJcVtbAanSg+E0tnFNUE3592Oz8VjvgBAlPMdaRiPiTs2FrEN6+h1zxgHRSY8q4ZC88y1x5dst2yjCef9SUQ5MW1OCMuy+ki3QSwxRZfa28Z+17sJ6Lfy2ZqE2J7dZquGXllF6wPYGHmUZ1NKu4gY9aIghJBUzk6gZgvoqlJ44jFSlw4+Q8k9UW8GgLrMOkKCGstTztHDXdqCU4FMpUP+SaMq/XN4XRiyw5FiYyhBaCF3K3QwGqYNP4jadZqYAe1/UnjLWoPN5ZiXZQW7yD5MwOtrZOJFmm4PuFaAAPy4cdSvHpVA8HVQWyLhE0BSA7r8spPVptP3w9GG+qEGR3pvs0mVjMOVI/nWNuD40PILtGqqhbBIUawKqxtfdA1Pf1qcxWTC2Uxgtw0YuMHztPWihW0xfDxxdZ13ewQ4ETdWj598CyaUs3nVRX4ru33pmWBfhLSlXRsNhqc7N7XJ0xE8eHIUs7F3WCwBjMMemV6K3HN0xT4b+7uDdw2RuUA2HGtKLzNAGN9gyMd6/
203 f62bb5d07848ca598aa860a517394130b61bf2ee 0 iQJJBAABCgAzFiEE64UTlbQiPuL3ugso2lR0C/CHMroFAl9OKQ8VHDc4OTVwdWxraXRAZ21haWwuY29tAAoJENpUdAvwhzK6fZ8QAJrThdhW9z05KenVuMDofakaCK0MGjSu4Tjg0D5vcVSOi8MGUU1XLky7T8HGhCZvGS2WWsqWenfj+BigXz1Ri4Iw5/j9WE2e7K1tu4if3ZTWrrcwtGgVL5ABnqJ7i9N3SxAIZ8+ws+UkZ4qdd33YsdJesY00Hzk2QJcPCI8VMINeDedh+EQZAcYYD0T5oWYBttHn+xzk7GROL3LJLoZK6YiPigd0ZpWnJJvZtjH8S9SenVNsa0FFGvjbe4tYQz1AcJxc9J7onBkzSPDONdeONWItyaLUF/luvtgfY84OigHpnR1W+h11HfwtPlXMNP21kV2vyN8aLR1Zplx2QNZXykwm2zpD/3MZROb+OjTq/FmKACdgtylCL7vm0fQwcGoydKryuFw08b0EKSS4YQ6qIakh8d1Cz5WKMlvzd/TudoW+MNOChFreN9db2mYSxjHrtqeDp7I8uV1JdtC+UXPtBNXIOddg1/C2V2X7palfscrLbIFAVGsUf6x4AeGjatuxUUxrp0flEjH4IvRIuhwv1QSdLTJQCq3zMoosPgRskETlgqrjZawxWspGNbXOX45YWb+vEib17c11OE0C5vQFtA6q6MDO/g/g95eVGijIxUiLM45Nh7O+e7ugHiFwWQiD5KlVz1w5QRsCfIdYPOXXUEMyVDE94WduEHB+2D1FZ8hi
203 f62bb5d07848ca598aa860a517394130b61bf2ee 0 iQJJBAABCgAzFiEE64UTlbQiPuL3ugso2lR0C/CHMroFAl9OKQ8VHDc4OTVwdWxraXRAZ21haWwuY29tAAoJENpUdAvwhzK6fZ8QAJrThdhW9z05KenVuMDofakaCK0MGjSu4Tjg0D5vcVSOi8MGUU1XLky7T8HGhCZvGS2WWsqWenfj+BigXz1Ri4Iw5/j9WE2e7K1tu4if3ZTWrrcwtGgVL5ABnqJ7i9N3SxAIZ8+ws+UkZ4qdd33YsdJesY00Hzk2QJcPCI8VMINeDedh+EQZAcYYD0T5oWYBttHn+xzk7GROL3LJLoZK6YiPigd0ZpWnJJvZtjH8S9SenVNsa0FFGvjbe4tYQz1AcJxc9J7onBkzSPDONdeONWItyaLUF/luvtgfY84OigHpnR1W+h11HfwtPlXMNP21kV2vyN8aLR1Zplx2QNZXykwm2zpD/3MZROb+OjTq/FmKACdgtylCL7vm0fQwcGoydKryuFw08b0EKSS4YQ6qIakh8d1Cz5WKMlvzd/TudoW+MNOChFreN9db2mYSxjHrtqeDp7I8uV1JdtC+UXPtBNXIOddg1/C2V2X7palfscrLbIFAVGsUf6x4AeGjatuxUUxrp0flEjH4IvRIuhwv1QSdLTJQCq3zMoosPgRskETlgqrjZawxWspGNbXOX45YWb+vEib17c11OE0C5vQFtA6q6MDO/g/g95eVGijIxUiLM45Nh7O+e7ugHiFwWQiD5KlVz1w5QRsCfIdYPOXXUEMyVDE94WduEHB+2D1FZ8hi
204 07731064ac41dacdf0ec869ebd05c2e848c14fbf 0 iQJJBAABCgAzFiEE64UTlbQiPuL3ugso2lR0C/CHMroFAl93L8cVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJENpUdAvwhzK6xZIP/R34y1j74tumvkIQhijDuMEar3mEOcA0Bjy2iLMjEJtIwQ7OqRbQRY4bn5c88+uQtP2W2KH7OY8tusy+zplkclP2YZUMfUfeClz0G9Ud+94+hs41TX60Htm2dM3UbDo6aCO/j8Ado0U8W7m6LDd1UR/4UfcM5q2YZAq4n6a4twJuDqlv6xx9nFRK8AbeKihIGzv+J46YrqWi9unmLc0kTb6qWT/7H2FeMeBNN+XfGZ+ry/zEyTdhyURTaWEvt6h4EnroPFRmb779aK7dFNDZvc30bh5CnBfGflvvl5sQLDOU7Dqjmhie+PdVK0XNr1PGxNbI2Y9RSKyKXKHRI4jgxHfsB1957cVD++rzSBs4nAockPlAqupK8wL/RWZ0ilB+un1zPizk67cwApnQcWIRro+6D4OuqhA98DAHLu9R7vsjArxCcmgHXdjMiOpLs2K5dqYG15bgeJ+csVDzgFs8vtiaXWYbDdHrhMMAx0V+tLb9Yh6CashwPmi8+7mroJgqtZTLPg4cRwj0TiuHXzLUQrAzjf2o48KiUCEx6pz7PdQtaePO/l2qJCBWuXhY7pSNLy3kHv1gFN+hqKHLdJVNMoF0aR0O4u87ry7SD1dvz90BshH9kHy8FR3q77ITNVNFghWzNp4faTdqiNMMtx4fw+j28G5yQS3hmCkApmti9zJi
204 07731064ac41dacdf0ec869ebd05c2e848c14fbf 0 iQJJBAABCgAzFiEE64UTlbQiPuL3ugso2lR0C/CHMroFAl93L8cVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJENpUdAvwhzK6xZIP/R34y1j74tumvkIQhijDuMEar3mEOcA0Bjy2iLMjEJtIwQ7OqRbQRY4bn5c88+uQtP2W2KH7OY8tusy+zplkclP2YZUMfUfeClz0G9Ud+94+hs41TX60Htm2dM3UbDo6aCO/j8Ado0U8W7m6LDd1UR/4UfcM5q2YZAq4n6a4twJuDqlv6xx9nFRK8AbeKihIGzv+J46YrqWi9unmLc0kTb6qWT/7H2FeMeBNN+XfGZ+ry/zEyTdhyURTaWEvt6h4EnroPFRmb779aK7dFNDZvc30bh5CnBfGflvvl5sQLDOU7Dqjmhie+PdVK0XNr1PGxNbI2Y9RSKyKXKHRI4jgxHfsB1957cVD++rzSBs4nAockPlAqupK8wL/RWZ0ilB+un1zPizk67cwApnQcWIRro+6D4OuqhA98DAHLu9R7vsjArxCcmgHXdjMiOpLs2K5dqYG15bgeJ+csVDzgFs8vtiaXWYbDdHrhMMAx0V+tLb9Yh6CashwPmi8+7mroJgqtZTLPg4cRwj0TiuHXzLUQrAzjf2o48KiUCEx6pz7PdQtaePO/l2qJCBWuXhY7pSNLy3kHv1gFN+hqKHLdJVNMoF0aR0O4u87ry7SD1dvz90BshH9kHy8FR3q77ITNVNFghWzNp4faTdqiNMMtx4fw+j28G5yQS3hmCkApmti9zJi
205 0e06a7ab9e0d5c65af4e511aee1e0342998799df 0 iQJJBAABCgAzFiEE64UTlbQiPuL3ugso2lR0C/CHMroFAl+PEggVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJENpUdAvwhzK6KGoP/3rNBknIuLpJ/+nWiTQNY3GsJwl1Z0QX97cpXevNYQDjNGFpOJveJwEKq5ouAfD+bLILuEjdgdMaB/87b1fuf4stsH3myG6PlvgXeP9cpEMGejh4UvLBO74l5qALYI5J5f7/M8tPN1VGSC0cAcSvRilh+zl8KXakCjz/zoVpdDwE9YsbdZHhYMe2aiGJw0tueao22kP7txuqmy6coHVHIHhxLhvZ/HGSjoUD+oCcBVw9dIReariUFWw+56MAhAf99JhiQ/In+w1qKcoLF64Y7m45Tl7MPsweCpVQ0wtoprOMFziYhmwZcPPTa4WnNbE2MbnJcKyCKF3t3dJqqEplp64KYjskckZlK6lbhLrAi/nGU6HNRCRjIyzcA4qPhaEYb8DnebBPCpuKMaZMyJCZd+N7ydDAujGa+q2U5O1t1nLBRMou7eXD86L3aH2mukbUkkGmZXUP6M1C4ErEPZU78QoqUr+A+74+y+2lgWdkXYv5QmApitGMIel1sh80XYcdZmNAeXzB3QL3KnYp+mDapSe6oKAcArHWzbrCm4zWng6B6JKV+rHfbb9dxdJ3cSJwY+tTZQHwHZkQFVxiJsw2ID5jZsFwKkfXhqLW3FY+u20WQriVF5EDahdy5VvhNbsEVTY42m7OAUK7FjVqyX+gvtNx/mhyoPOv+6P+oPMj1HWa
205 0e06a7ab9e0d5c65af4e511aee1e0342998799df 0 iQJJBAABCgAzFiEE64UTlbQiPuL3ugso2lR0C/CHMroFAl+PEggVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJENpUdAvwhzK6KGoP/3rNBknIuLpJ/+nWiTQNY3GsJwl1Z0QX97cpXevNYQDjNGFpOJveJwEKq5ouAfD+bLILuEjdgdMaB/87b1fuf4stsH3myG6PlvgXeP9cpEMGejh4UvLBO74l5qALYI5J5f7/M8tPN1VGSC0cAcSvRilh+zl8KXakCjz/zoVpdDwE9YsbdZHhYMe2aiGJw0tueao22kP7txuqmy6coHVHIHhxLhvZ/HGSjoUD+oCcBVw9dIReariUFWw+56MAhAf99JhiQ/In+w1qKcoLF64Y7m45Tl7MPsweCpVQ0wtoprOMFziYhmwZcPPTa4WnNbE2MbnJcKyCKF3t3dJqqEplp64KYjskckZlK6lbhLrAi/nGU6HNRCRjIyzcA4qPhaEYb8DnebBPCpuKMaZMyJCZd+N7ydDAujGa+q2U5O1t1nLBRMou7eXD86L3aH2mukbUkkGmZXUP6M1C4ErEPZU78QoqUr+A+74+y+2lgWdkXYv5QmApitGMIel1sh80XYcdZmNAeXzB3QL3KnYp+mDapSe6oKAcArHWzbrCm4zWng6B6JKV+rHfbb9dxdJ3cSJwY+tTZQHwHZkQFVxiJsw2ID5jZsFwKkfXhqLW3FY+u20WQriVF5EDahdy5VvhNbsEVTY42m7OAUK7FjVqyX+gvtNx/mhyoPOv+6P+oPMj1HWa
206 18c17d63fdabd009e70bf994e5efb7db422f4f7f 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl+gXVsQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91SAmEADN4fJHjY+Gxu4voL7BHCW3iar3jqyziY+q681nGBK6Tr3APslQkENFahAyHPawkuyiznfWVzzQh/aSbvqDDYCUe+ROjsjSGOwmyd45CN4X01RF1gavuCD5iAn5nw/PML4owtHkM4MhSI0V3++GgczFiDrG09EfGt4XxPWJT5XZaeR4uLB+FJL1DjuJQx8KTZDdlPsLzUCh41l76wrYRqP47KNtm50co4MJOx7r6BQn8ZmfNxG+TBnNRasES1mWv8OtYTleHZPHjvxKXmXNwuCPg1u33vKGIM/00yBm9/KHnfPUnLDxVXIo7yycLtU7KVXLeY/cOG3+w3tAY58EBozr8MA8zIAY773MqFq+I5TRKTQAxzpTtWm6FeW6jw1VAN4oImaWKWuKqIs7FbTwtw6158Mr5xbm7Rd7al8o9h8l9Y0kYyTWdzNnGCRGsZJ9VRnK7+EJ7O7PxicY1tNzcqidP/CvS7zA6oCeOGhu5C79K0Ww0NkcHcIeMznM1NK+OihEcqG5vLzuxqRXB93xrOay+zXBk/DIr0AdRbXUJQ8jJR9FjVZMHFTH2azAvBURsGwmJcJWIP5EKg2xNl9L1XH2BjwArS7U7Z+MiuetKZZfSw9MT2EVFCTNFmC3RPmFe/BLt1Pqax1nXN/U2NVVr0hqoyolfdBEFJyPOEsz4OhmIQ==
206 18c17d63fdabd009e70bf994e5efb7db422f4f7f 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl+gXVsQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91SAmEADN4fJHjY+Gxu4voL7BHCW3iar3jqyziY+q681nGBK6Tr3APslQkENFahAyHPawkuyiznfWVzzQh/aSbvqDDYCUe+ROjsjSGOwmyd45CN4X01RF1gavuCD5iAn5nw/PML4owtHkM4MhSI0V3++GgczFiDrG09EfGt4XxPWJT5XZaeR4uLB+FJL1DjuJQx8KTZDdlPsLzUCh41l76wrYRqP47KNtm50co4MJOx7r6BQn8ZmfNxG+TBnNRasES1mWv8OtYTleHZPHjvxKXmXNwuCPg1u33vKGIM/00yBm9/KHnfPUnLDxVXIo7yycLtU7KVXLeY/cOG3+w3tAY58EBozr8MA8zIAY773MqFq+I5TRKTQAxzpTtWm6FeW6jw1VAN4oImaWKWuKqIs7FbTwtw6158Mr5xbm7Rd7al8o9h8l9Y0kYyTWdzNnGCRGsZJ9VRnK7+EJ7O7PxicY1tNzcqidP/CvS7zA6oCeOGhu5C79K0Ww0NkcHcIeMznM1NK+OihEcqG5vLzuxqRXB93xrOay+zXBk/DIr0AdRbXUJQ8jJR9FjVZMHFTH2azAvBURsGwmJcJWIP5EKg2xNl9L1XH2BjwArS7U7Z+MiuetKZZfSw9MT2EVFCTNFmC3RPmFe/BLt1Pqax1nXN/U2NVVr0hqoyolfdBEFJyPOEsz4OhmIQ==
207 1d5189a57405ceca5aa244052c9f948977f4699b 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl/JMCcQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91d8VEADPmycxSrG/9WClJrXrZXVugf2Bp6SiKWarCWmZQ32sh/Xkl6Km8I6uVQL0k82lQO71jOin6APY2HJeOC57mBeX9HOPcN/l+I8g4HecdI6UO8+tQzPqzno92Nm+tj0XxSelmMZ1KwDYpiHBo8F9VMILTZSdFdC5zBBMQOHhJDAtIUJx5W8n2/mcDvFEpv5OHqS2kYzHHqn9/V+J6iOweP2ftd3N84EZZHb7e8hYbLHS1aNJRe7SsruCYJujHr8Ym5izl5YTpwvVCvudbK/OnrFd0MqT3oRS8WRPwwYcYJkj5AtDLA0VLbx47KeR0vLCC7hTkFoOtFtxc7WIJOZVb/DPi38UsSJLG2tFuSvnW8b1YBCUD5o39F/4FxUuug/JxEG3nvP0Hf6PbPiAn/ZPJqNOyyY51YfjAaAGZeP+UNM4OgOdsSq1gAcCQEMclb54YuRe/J/fuBkQVKbaPuVYPCypqdc/KppS9hZzD3R3OEiztNXqn8u2tl33qsvdEJBlZq9NCD/wJMIzKC/6I5YNkYtgdfAH+xhqHgPvohGyc5q7jS8UvfIl6Wro8e+nWEXkOv2yQSU8nq/5hcyQj5SctznUxArpAt7CbNmGze42t29EdrP4P5w2K6t1lELUw1SVjzt/j9Xc5k/sDj4MxqP8KNRgoDSPRtv7+1/ECC4SfwVj5w==
207 1d5189a57405ceca5aa244052c9f948977f4699b 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAl/JMCcQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91d8VEADPmycxSrG/9WClJrXrZXVugf2Bp6SiKWarCWmZQ32sh/Xkl6Km8I6uVQL0k82lQO71jOin6APY2HJeOC57mBeX9HOPcN/l+I8g4HecdI6UO8+tQzPqzno92Nm+tj0XxSelmMZ1KwDYpiHBo8F9VMILTZSdFdC5zBBMQOHhJDAtIUJx5W8n2/mcDvFEpv5OHqS2kYzHHqn9/V+J6iOweP2ftd3N84EZZHb7e8hYbLHS1aNJRe7SsruCYJujHr8Ym5izl5YTpwvVCvudbK/OnrFd0MqT3oRS8WRPwwYcYJkj5AtDLA0VLbx47KeR0vLCC7hTkFoOtFtxc7WIJOZVb/DPi38UsSJLG2tFuSvnW8b1YBCUD5o39F/4FxUuug/JxEG3nvP0Hf6PbPiAn/ZPJqNOyyY51YfjAaAGZeP+UNM4OgOdsSq1gAcCQEMclb54YuRe/J/fuBkQVKbaPuVYPCypqdc/KppS9hZzD3R3OEiztNXqn8u2tl33qsvdEJBlZq9NCD/wJMIzKC/6I5YNkYtgdfAH+xhqHgPvohGyc5q7jS8UvfIl6Wro8e+nWEXkOv2yQSU8nq/5hcyQj5SctznUxArpAt7CbNmGze42t29EdrP4P5w2K6t1lELUw1SVjzt/j9Xc5k/sDj4MxqP8KNRgoDSPRtv7+1/ECC4SfwVj5w==
208 9da65e3cf3706ff41e08b311381c588440c27baf 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmAHEb4VHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfMJ0P/0A0L7tLfx03TWyz7VLPs9t3ojqGjFCaZAGPyS0Wtkpw0fhllYzf4WjFyGGsM1Re8fY7iakSoU3hzHID9svxH1CZ2qneaWHyXc166gFEhvOUmySQMRN26HnRG2Spc+gc/SMLUcAavzMiHukffD+IF0sDwQyTxwei40dc2T2whlqlIJ5r3VvV9KJVWotupKyH4XcWC5qr5tQvoc4jUnP+oyRtmv9sr9yqoC0nI6SALK61USfe6wl/g1vDDmwz3mE75LsVAJjPYVQzceMSAKqSnS2eB1xSdrs8AGB+VbG7aBAAlYo2kiQGYWnriXNJK5b6fwqbiyhMsyxShg/uFUnWeO52/0/tt7/2sHhXs7+IBM8nW/DSr1QbHaJ+p874zmJGsNT3FC370YioSuaqwTBFMvh37qi95bwqxGUYCoTr6nahfiXdUO3PC3OHCH/gXFmisKx2Lq7X1DIZZRqbKr0gPdksLJqk1zRrB++KGq5KEUsLFdQq4BePxleQy9thGzujBp1kqb9s/9eWlNfDVTVtL1n8jujoK66EwgknN9m66xMuLGRmCclMZ9NwVmfP9jumD0jz+YYrIZC2EoRGyftmNhlZahwDwgtQ70FSxNr/r+bSgMcUPdplkwh6c+UZGJpFyaKvJQfHcm6wuShKbrccSai4e6BU43J/yvbAVH0+1wus
208 9da65e3cf3706ff41e08b311381c588440c27baf 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmAHEb4VHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfMJ0P/0A0L7tLfx03TWyz7VLPs9t3ojqGjFCaZAGPyS0Wtkpw0fhllYzf4WjFyGGsM1Re8fY7iakSoU3hzHID9svxH1CZ2qneaWHyXc166gFEhvOUmySQMRN26HnRG2Spc+gc/SMLUcAavzMiHukffD+IF0sDwQyTxwei40dc2T2whlqlIJ5r3VvV9KJVWotupKyH4XcWC5qr5tQvoc4jUnP+oyRtmv9sr9yqoC0nI6SALK61USfe6wl/g1vDDmwz3mE75LsVAJjPYVQzceMSAKqSnS2eB1xSdrs8AGB+VbG7aBAAlYo2kiQGYWnriXNJK5b6fwqbiyhMsyxShg/uFUnWeO52/0/tt7/2sHhXs7+IBM8nW/DSr1QbHaJ+p874zmJGsNT3FC370YioSuaqwTBFMvh37qi95bwqxGUYCoTr6nahfiXdUO3PC3OHCH/gXFmisKx2Lq7X1DIZZRqbKr0gPdksLJqk1zRrB++KGq5KEUsLFdQq4BePxleQy9thGzujBp1kqb9s/9eWlNfDVTVtL1n8jujoK66EwgknN9m66xMuLGRmCclMZ9NwVmfP9jumD0jz+YYrIZC2EoRGyftmNhlZahwDwgtQ70FSxNr/r+bSgMcUPdplkwh6c+UZGJpFyaKvJQfHcm6wuShKbrccSai4e6BU43J/yvbAVH0+1wus
209 0e2e7300f4302b02412b0b734717697049494c4c 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmAZlogVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfalsQAJjgyWsRM1Dty8MYagJiC3lDqqeUkIkdMB569d0NKaiarwL/vxPS7nx+ELNw0stWKDhgTjZlgUvkjqZEZgR4C4mdAbZYO1gWVc03eOeHMJB46oEIXv27pZYkQZ1SwDfVDfoCKExGExRw/cfoALXX6PvB7B0Az35ZcStCIgHn0ltTeJDge1XUCs8+10x2pjYBZssQ8ZVRhP3WeVZovX5CglrHW+9Uo09dJIIW7lmIgK2LLT0nsgeRTfb0YX7BiDATVAJgUQxf6MD2Sxt/oaWejL3zICKV5Cs+MaNElhpCD1YoVOe2DpASk60IHPZCmaOyCZCyBL9Yn2xxO9oDTVXJidwyKcvjCOaz4X6c5jdkgm0TaKlqfbY8LiUsQet0zzbQT7g+8jHv31wkjnxOMkbvHZZGoQLZTjS9M5NeWkvW8FzO9QLpp/sFJRCsNzjEzJWZCiAPKv51/4j7tNWOZLsKbYmjjQn9MoYZOrsFz4zjHYxz7Wi46JHMNzsHwi5iVreKXp1UGTQYhRZnKKb7g6zS3w3nI1KrGPfEnMf/EqRycLJV9HEoQTGo4T36DBFO7Wvyp6xwsnPGBki78ib5kUWwwSJiBsyx956nblY4wZaC8TiCueVqu0OfHpR4TGNuIkzS7ODNNRpcH65KNulIMRfB4kMLkvBVA27lDhc+XnDevi5q
209 0e2e7300f4302b02412b0b734717697049494c4c 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmAZlogVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfalsQAJjgyWsRM1Dty8MYagJiC3lDqqeUkIkdMB569d0NKaiarwL/vxPS7nx+ELNw0stWKDhgTjZlgUvkjqZEZgR4C4mdAbZYO1gWVc03eOeHMJB46oEIXv27pZYkQZ1SwDfVDfoCKExGExRw/cfoALXX6PvB7B0Az35ZcStCIgHn0ltTeJDge1XUCs8+10x2pjYBZssQ8ZVRhP3WeVZovX5CglrHW+9Uo09dJIIW7lmIgK2LLT0nsgeRTfb0YX7BiDATVAJgUQxf6MD2Sxt/oaWejL3zICKV5Cs+MaNElhpCD1YoVOe2DpASk60IHPZCmaOyCZCyBL9Yn2xxO9oDTVXJidwyKcvjCOaz4X6c5jdkgm0TaKlqfbY8LiUsQet0zzbQT7g+8jHv31wkjnxOMkbvHZZGoQLZTjS9M5NeWkvW8FzO9QLpp/sFJRCsNzjEzJWZCiAPKv51/4j7tNWOZLsKbYmjjQn9MoYZOrsFz4zjHYxz7Wi46JHMNzsHwi5iVreKXp1UGTQYhRZnKKb7g6zS3w3nI1KrGPfEnMf/EqRycLJV9HEoQTGo4T36DBFO7Wvyp6xwsnPGBki78ib5kUWwwSJiBsyx956nblY4wZaC8TiCueVqu0OfHpR4TGNuIkzS7ODNNRpcH65KNulIMRfB4kMLkvBVA27lDhc+XnDevi5q
210 d5d9177c0045d206db575bae6daa98e2cb2fe5bc 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmBHDE4VHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfo20P/2eaVVY+VgaHktRHpJKJsC8tc8brHXfwPTijTzWl/2d4rZ1QwvyYFycl8LwtHeVdjvbDf61YIX2BiucX+rG11x21LyPPgD90pQ0VdRgoGXgVZX27exkvS5DUhqXnVnbey5dH3pFAPtYsC3jHsoo8NyNDrn2nXdvzzABArljIVyjnG5JokPiEH3dQSY78HlJR451HlrWEmRgL9PlzHGDRmpkdypKiV8o58386uqCz5zfugA9aC/JYheNA40xM3PV24GbJ/dtMqztzOh6MVxFWV5+krK2hXBXk/p8eE1SYDoO5tqZAmSgKmBJZ5zas4zRBoJb51BiLM0cBaxmBiqZ+sv9IHknoyEMisc4+0O6z7JKqLiZetVbvNVOkCP/CbKyik+evbZnQB6JhgOSCjfcLD5ZFl8GiRiz84ZT3ges5RTyVcE6jJNUV+nwmNdW2qLQP9JydInKNwTrEgZcrJDv6i+lu519p8+zcOgIF1J+CO8qQaq3+j5MA4Dttat3anWOQNIzbx4yuG75NezVN3jnRGmoSGwg1YLseqjQCBlpJrBWTD1SsuWpgbKx4EiELDN+PcDovxB2pYa+NzFfv0ZFcnWuLpr6KjCgzBkTK5KfmTqu7I+eM29g+2JvmCao+kk8MVyVmV9H2f5xRvuhrEBmDNlLb7uOhJW3a7EvZG6g9EfW9
210 d5d9177c0045d206db575bae6daa98e2cb2fe5bc 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmBHDE4VHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfo20P/2eaVVY+VgaHktRHpJKJsC8tc8brHXfwPTijTzWl/2d4rZ1QwvyYFycl8LwtHeVdjvbDf61YIX2BiucX+rG11x21LyPPgD90pQ0VdRgoGXgVZX27exkvS5DUhqXnVnbey5dH3pFAPtYsC3jHsoo8NyNDrn2nXdvzzABArljIVyjnG5JokPiEH3dQSY78HlJR451HlrWEmRgL9PlzHGDRmpkdypKiV8o58386uqCz5zfugA9aC/JYheNA40xM3PV24GbJ/dtMqztzOh6MVxFWV5+krK2hXBXk/p8eE1SYDoO5tqZAmSgKmBJZ5zas4zRBoJb51BiLM0cBaxmBiqZ+sv9IHknoyEMisc4+0O6z7JKqLiZetVbvNVOkCP/CbKyik+evbZnQB6JhgOSCjfcLD5ZFl8GiRiz84ZT3ges5RTyVcE6jJNUV+nwmNdW2qLQP9JydInKNwTrEgZcrJDv6i+lu519p8+zcOgIF1J+CO8qQaq3+j5MA4Dttat3anWOQNIzbx4yuG75NezVN3jnRGmoSGwg1YLseqjQCBlpJrBWTD1SsuWpgbKx4EiELDN+PcDovxB2pYa+NzFfv0ZFcnWuLpr6KjCgzBkTK5KfmTqu7I+eM29g+2JvmCao+kk8MVyVmV9H2f5xRvuhrEBmDNlLb7uOhJW3a7EvZG6g9EfW9
211 f67b8946bb1b6cfa8328dbf8d6a9128b69ccdcb4 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAmB+71MQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91Vj+EADBa/tHfgyymKmXXl9DSlzwEhX1DkCE0aRcsbfXujnpOQrDi09pfHvtYEbgJfl6m8JEUOjuRRcxofnIWOC9UJCGC3ZfW5tTcHomCFlqjHhUxGKsvQ1Wcec1IH3mmzhqLnd0X57EgnNC6APwgxNVRmC0q7M7rSlNiE8BkHEUuyCau5FvpgdF31Aqa9IQP95pmmeDwL4ByPR1Nssu2/8N5vbcQm55gdjcggNjBvNEbaFHDS9NlGS8quvCMwRZkr3meDfTeCs9d2MveXXvV8GVOFq+WHMoURVijTjON+HuXB7HLegyhVOcigfbU5zxGY/IAJ/tAYEzBLWSYW6wjsN5uuZP267XhKpd2FT8Cfe9t3OnN1K21ndltlaMSdGyAynuepzVE0IELOCiKlgBZkdnft2XkUt2DDg/TqhOeXmUBzIFVze5KULSgrFvjkx71iV22LUGkIxzIuW5ieBMeZotKHzI+ZXO7xNSDIdoSfERKUqfYJKbksnBQLRxYUO77KetjocsMMYyB4Dpzu05+eWpYtZs2u5PsqP/Jv84Mz3QR0szAI1h3KlhmbkvKxnWnFYasAdFPMluX4G4X+9+MulODCwgw/RvQhh13M2QP0vGb1Xzu/JOuxRr3zuliTUfszd7YHVJoROzuT9PlcZ4criwZwv+fvbCN+F9LRbeI/BQBVZi6w==
211 f67b8946bb1b6cfa8328dbf8d6a9128b69ccdcb4 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAmB+71MQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91Vj+EADBa/tHfgyymKmXXl9DSlzwEhX1DkCE0aRcsbfXujnpOQrDi09pfHvtYEbgJfl6m8JEUOjuRRcxofnIWOC9UJCGC3ZfW5tTcHomCFlqjHhUxGKsvQ1Wcec1IH3mmzhqLnd0X57EgnNC6APwgxNVRmC0q7M7rSlNiE8BkHEUuyCau5FvpgdF31Aqa9IQP95pmmeDwL4ByPR1Nssu2/8N5vbcQm55gdjcggNjBvNEbaFHDS9NlGS8quvCMwRZkr3meDfTeCs9d2MveXXvV8GVOFq+WHMoURVijTjON+HuXB7HLegyhVOcigfbU5zxGY/IAJ/tAYEzBLWSYW6wjsN5uuZP267XhKpd2FT8Cfe9t3OnN1K21ndltlaMSdGyAynuepzVE0IELOCiKlgBZkdnft2XkUt2DDg/TqhOeXmUBzIFVze5KULSgrFvjkx71iV22LUGkIxzIuW5ieBMeZotKHzI+ZXO7xNSDIdoSfERKUqfYJKbksnBQLRxYUO77KetjocsMMYyB4Dpzu05+eWpYtZs2u5PsqP/Jv84Mz3QR0szAI1h3KlhmbkvKxnWnFYasAdFPMluX4G4X+9+MulODCwgw/RvQhh13M2QP0vGb1Xzu/JOuxRr3zuliTUfszd7YHVJoROzuT9PlcZ4criwZwv+fvbCN+F9LRbeI/BQBVZi6w==
212 8d2b62d716b095507effaa8d56f87cd27ba659ab 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAmCAO3gQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91YvWD/4kn4nLsu6W6hpSmB6qZB7y9adX8mqwzpSfnt0hwesk5FiBmGnDWHT5IvGHRTq0B3+peG9NH5R0h1WgtCdyh6YxGg0CZwNoarv64U8llS+PTXp8YZo/bVex7QGKQJr45Xik4ZH6htJ0muJUhzpHa6wkthTxK2OuaTTJvJ53lY8dR4lmefxSYPAwWs/jOzkmPwIeK8EnG0ZcBtmheJESOzKnmmOF6N4GnUGFFz/W5q8Gfeqj9xKKDt+zdPHXCEZUYivBcMPL7UNti2kvrp3R7VXBzbw/bPAJTrq68M4Z9mFb0qRZ88ubGXu+LEufsG2Dls/ZF0GnBPeReuFFrg9jimQqo6Rf/+4vV+GtFBY71aofFDDex9/s0q7skNEBxLP6r/KfsachYzvdciRS46zLelrL/NhpDvM6mHOLWmuycCeYShYctGbc2zDK7vD136Da6xlWU5Qci/+6zTtAjaKqdIpJuIzBfKdhaakri8vlpplpNLIDMfTTLyYKVAuHUtZcwHcHWmx54b2ulAmNXtc5yB/JqRIUined+Z6KlYc7c7MKEo2FB2/0okIbx7bIiXbV2of4j3ufv+NPIQel1qsnX58vbYL1spdfynNMTHQ+TYc9lUvuq31znu2LLJ9ZhTOiLEt1QZB28lTukzNuH2MEpGWtrOBIC9AcXjyyZ8HlIwEWMA==
212 8d2b62d716b095507effaa8d56f87cd27ba659ab 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAmCAO3gQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91YvWD/4kn4nLsu6W6hpSmB6qZB7y9adX8mqwzpSfnt0hwesk5FiBmGnDWHT5IvGHRTq0B3+peG9NH5R0h1WgtCdyh6YxGg0CZwNoarv64U8llS+PTXp8YZo/bVex7QGKQJr45Xik4ZH6htJ0muJUhzpHa6wkthTxK2OuaTTJvJ53lY8dR4lmefxSYPAwWs/jOzkmPwIeK8EnG0ZcBtmheJESOzKnmmOF6N4GnUGFFz/W5q8Gfeqj9xKKDt+zdPHXCEZUYivBcMPL7UNti2kvrp3R7VXBzbw/bPAJTrq68M4Z9mFb0qRZ88ubGXu+LEufsG2Dls/ZF0GnBPeReuFFrg9jimQqo6Rf/+4vV+GtFBY71aofFDDex9/s0q7skNEBxLP6r/KfsachYzvdciRS46zLelrL/NhpDvM6mHOLWmuycCeYShYctGbc2zDK7vD136Da6xlWU5Qci/+6zTtAjaKqdIpJuIzBfKdhaakri8vlpplpNLIDMfTTLyYKVAuHUtZcwHcHWmx54b2ulAmNXtc5yB/JqRIUined+Z6KlYc7c7MKEo2FB2/0okIbx7bIiXbV2of4j3ufv+NPIQel1qsnX58vbYL1spdfynNMTHQ+TYc9lUvuq31znu2LLJ9ZhTOiLEt1QZB28lTukzNuH2MEpGWtrOBIC9AcXjyyZ8HlIwEWMA==
213 067f2c53fb24506c9e9fb4639871b13b19a85f8a 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmCQMXEVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfpJgP/isIDkbMuhot376RY2SwilSCkjJRoKRCDyLjJReBUF29t+DPWs8h971t2v5DIasfuQZthMv9A6DYcyEs1Q3NTKvT4TMKTTrqQfIe8UMmUa9PI1SIuTShiWbwonrN8rrVMVVcjPO/gookMV8/uoYW3wn/SThkBEYYauONBBVKbQ/Bt31/OPbEeAEdb/IEJ9X9PL1sfQkf+/DA/cwawS+xn01GAxWybx8eJkcJFdGdUcl/PYWgX76RSUhGvD6aHRJTZ1+sXy7+ligfpdPkNrQ248mVEEQkmZaCQ39dQPMX5zLa2hEX6eW9b1BEhNjHzbDfyqwc+F5czLw+R56vjPUyRCkxAZ6Q5Q3vkgLPBlZ2Ay0Lta/5+qGWcX+nDzfKfr2FhBLAnRZG/M+M2ckzR+8twyKg7/vdD8e/B3+Oxmu5QTS8xuj1628Brf9IehedQHoEPDe2M5ynhlEcybkbLz1R7zWKrh2h76OGQtspcjF997W1uZFx+DH6kHSznIm/8zEXy13R2nZk/0YtGX2UjZDv9bZ5X3B7T1673uscx3VpiT8YLJVKX7FyFLMgUbVY9ZGFlQ/pzUP3gTGa5rAB8b72U45jlXdKKvCn9B3hbS4j9OzJKpjsspWDmFHl2/a01ZOL/SZtMlm7FeYymUXKc10dndXlXTlGxHFUJQsii6t3dDyf
213 067f2c53fb24506c9e9fb4639871b13b19a85f8a 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmCQMXEVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfpJgP/isIDkbMuhot376RY2SwilSCkjJRoKRCDyLjJReBUF29t+DPWs8h971t2v5DIasfuQZthMv9A6DYcyEs1Q3NTKvT4TMKTTrqQfIe8UMmUa9PI1SIuTShiWbwonrN8rrVMVVcjPO/gookMV8/uoYW3wn/SThkBEYYauONBBVKbQ/Bt31/OPbEeAEdb/IEJ9X9PL1sfQkf+/DA/cwawS+xn01GAxWybx8eJkcJFdGdUcl/PYWgX76RSUhGvD6aHRJTZ1+sXy7+ligfpdPkNrQ248mVEEQkmZaCQ39dQPMX5zLa2hEX6eW9b1BEhNjHzbDfyqwc+F5czLw+R56vjPUyRCkxAZ6Q5Q3vkgLPBlZ2Ay0Lta/5+qGWcX+nDzfKfr2FhBLAnRZG/M+M2ckzR+8twyKg7/vdD8e/B3+Oxmu5QTS8xuj1628Brf9IehedQHoEPDe2M5ynhlEcybkbLz1R7zWKrh2h76OGQtspcjF997W1uZFx+DH6kHSznIm/8zEXy13R2nZk/0YtGX2UjZDv9bZ5X3B7T1673uscx3VpiT8YLJVKX7FyFLMgUbVY9ZGFlQ/pzUP3gTGa5rAB8b72U45jlXdKKvCn9B3hbS4j9OzJKpjsspWDmFHl2/a01ZOL/SZtMlm7FeYymUXKc10dndXlXTlGxHFUJQsii6t3dDyf
214 411dc27fd9fd076d6a031a08fcaace659afe2fe3 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmDnSgwVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOftvQP/j1mvheFHsv5TSJ2IEKgEK4G/cIxt+taoWpecEUVN5JAk7q4Y1xnzcoyqQdAyvZcTu7m4ESx865XW6Jvc0I2pG+uKcmO7ZfwrAOugoXXxrlXtopVfDDFZOLlk72x+Z5tQpL9QcBUgetkuOZLFhT+1ETjnFd2H4P4pwPjdTpn+YBmDmh1tWTMzllTDDzvZeE6iAjIpM9IQKL4jKxcEjPAX2XDa1xWhd/o9NZC9kYSTIBQvbFWAz3A0PSAudz0lu5YDXKJNtIHlzZtMFmcUlqJGM4MlD6v9tm8EQbCWTgOm0+wB5miDqv05aC6axD3LnSgrlPsmRDZCIRAws1JHEjKYFob7VRMxpivW7GDSd6QrmUbTHYN5eY0v1YB62dCa8W9qk2E7R5VdLRi4haFTv42u7jOZT0tSzRv/R0QppoVQ7/Fpqpps+aoZBM6EGj/pAxRgBTHeyI9WTFUAYDbhRuN9EoJAqRUCpXn39oR+TsaD9COENAJroX2WLIY8XFD3UzrpA9NPt7JE9mufWoNipNqLdLY7k3p3UxX0/SDboVlax6ORpQN+YzYhCesJaAOhlTAXMRMyXsfw/ScYttXxmIJ7BINYEMSXM55uiUPYFjE/GuZjbjgqk3dmJr7ceAyGa5v+m5Hr6efPSRHKUAxkEcDsXpcTHyEOVt3l7Qwfd+oUumK
214 411dc27fd9fd076d6a031a08fcaace659afe2fe3 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmDnSgwVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOftvQP/j1mvheFHsv5TSJ2IEKgEK4G/cIxt+taoWpecEUVN5JAk7q4Y1xnzcoyqQdAyvZcTu7m4ESx865XW6Jvc0I2pG+uKcmO7ZfwrAOugoXXxrlXtopVfDDFZOLlk72x+Z5tQpL9QcBUgetkuOZLFhT+1ETjnFd2H4P4pwPjdTpn+YBmDmh1tWTMzllTDDzvZeE6iAjIpM9IQKL4jKxcEjPAX2XDa1xWhd/o9NZC9kYSTIBQvbFWAz3A0PSAudz0lu5YDXKJNtIHlzZtMFmcUlqJGM4MlD6v9tm8EQbCWTgOm0+wB5miDqv05aC6axD3LnSgrlPsmRDZCIRAws1JHEjKYFob7VRMxpivW7GDSd6QrmUbTHYN5eY0v1YB62dCa8W9qk2E7R5VdLRi4haFTv42u7jOZT0tSzRv/R0QppoVQ7/Fpqpps+aoZBM6EGj/pAxRgBTHeyI9WTFUAYDbhRuN9EoJAqRUCpXn39oR+TsaD9COENAJroX2WLIY8XFD3UzrpA9NPt7JE9mufWoNipNqLdLY7k3p3UxX0/SDboVlax6ORpQN+YzYhCesJaAOhlTAXMRMyXsfw/ScYttXxmIJ7BINYEMSXM55uiUPYFjE/GuZjbjgqk3dmJr7ceAyGa5v+m5Hr6efPSRHKUAxkEcDsXpcTHyEOVt3l7Qwfd+oUumK
215 d7515d29761d5ada7d9c765f517db67db75dea9a 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmD4lQMVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfVsMP/19G6aZBokNRdErXcT86ahVy82IquR/CmLJcdj/4nehmBXToLCmdeqKe17ZKgZ7bnPnevhO07zPub7RUhDixnb7OxpbXiyP7x67FAqAfKvi8rZggmeWZT5kpiltoBIvHDlOlQhsgtfea0REULyn4zNB6dLED5zh2Ddr5LcWIjfOvIWo1F0eFMcRszL8f2u2ei2dERDuG8MSzMsiFHMAPRMHJjm+YukJBuz78CH4qT/Inkq52ao+3GCh4fFBhPG5+IABeCn1J4cAAK06mPcJqa7fbv7NfUCN9MeDNQUsUGGfIhKzGHJTb7PwXkKJ3qpLPs4FYGV1ZTucrIU1i65hXuf66QcYGlAQmKavS7xDOfZhzrZrAKe65dLpWdEH5mpTMcjaMBS+mhfMJT7DQg9T/9jISiKeqiFNkNOy1cobpJWes8iFwihEBtEhCtiVgnf7i7IzZY/spmSmP4ot/MEBi3jMjvAEaH1HyDGOPuBuqRSIRU+Mf5o1yB2kZmGL9vHWUzm/ySjQFYte061OyE9bZrbF9daOTdRip/CXPApOneVBIMwXc7fWDu45cKyVg7kYo8a0gcFfg39Ceja3Z8iJSFtJTuj1Sd9q8YU6pxqDrfPm1byJJlb7SvAoZfIGQPFk+DF6UVEcWRC0MYRm2bHXlaZwNVpgmFv6ZOVja3jxCJkw8
215 d7515d29761d5ada7d9c765f517db67db75dea9a 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmD4lQMVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfVsMP/19G6aZBokNRdErXcT86ahVy82IquR/CmLJcdj/4nehmBXToLCmdeqKe17ZKgZ7bnPnevhO07zPub7RUhDixnb7OxpbXiyP7x67FAqAfKvi8rZggmeWZT5kpiltoBIvHDlOlQhsgtfea0REULyn4zNB6dLED5zh2Ddr5LcWIjfOvIWo1F0eFMcRszL8f2u2ei2dERDuG8MSzMsiFHMAPRMHJjm+YukJBuz78CH4qT/Inkq52ao+3GCh4fFBhPG5+IABeCn1J4cAAK06mPcJqa7fbv7NfUCN9MeDNQUsUGGfIhKzGHJTb7PwXkKJ3qpLPs4FYGV1ZTucrIU1i65hXuf66QcYGlAQmKavS7xDOfZhzrZrAKe65dLpWdEH5mpTMcjaMBS+mhfMJT7DQg9T/9jISiKeqiFNkNOy1cobpJWes8iFwihEBtEhCtiVgnf7i7IzZY/spmSmP4ot/MEBi3jMjvAEaH1HyDGOPuBuqRSIRU+Mf5o1yB2kZmGL9vHWUzm/ySjQFYte061OyE9bZrbF9daOTdRip/CXPApOneVBIMwXc7fWDu45cKyVg7kYo8a0gcFfg39Ceja3Z8iJSFtJTuj1Sd9q8YU6pxqDrfPm1byJJlb7SvAoZfIGQPFk+DF6UVEcWRC0MYRm2bHXlaZwNVpgmFv6ZOVja3jxCJkw8
216 2813d406b03607cdb8c06cb04c44efcc9a79d9a2 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmESg/wVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOf6kAP/1w3elvhAYQcK9hkEVCg4sQgnvcatOafCNaK0dVW9OOFbt+8DNUcHbtUHZtR6ETmSAMlWilIr/1vRMjy0Zic6afJ30oq8i+4f6DgLyTsLQL/QdwJQIwi2fZmHebv1PSrhT9tJAwtH6oG3cNhSq8KMme4l7sVR7ekB34Cmzk3fa5udMOuQG9xWbGTmeEsx0kYb+1oag+NnnZJqVTi68gGGxRW8TYZ1APXJcrZVfkldtaIWx6U1UdkWSTqWHV4fnnctp/1M+IgXCLT0iupY5LnxqGKQcMte7WKRPPdfhGF1ta+LN+QPHbwXhDRDIWPBVbDeHxjKcjz3h+DOeF0b7c5vKDADgo9LtHui9QhBJiCDHwsM+8gA+kNEDbtvIYYQ6CLxX9m1TttxI4ASIzFGIQF6nBr3mjQCzmOoWtgVh7R4dsQ9YZgm4twjsIg3g0MDhmgs71jn6Gp4BficF25nY8J6Ct8YopkPs2sfiBYJmyh9NJLDjwqNnjq3MBervPX3B+7p1dfIsK4JoSuop5A4lc4OOEhrwm5BKIxm30R4NtB15RZ7nI0DcRFcwNQiTYPG+nOaPsFzeZD6lj8+YnuLyo2aCnf4K26/1YTlE1wOFkCb1reL99++i8FP94poHBKZ7+6HT6gk4Mmnfb52II4yWlh/CYLeKEzFFfAiOTvfhzpIvqg
216 2813d406b03607cdb8c06cb04c44efcc9a79d9a2 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmESg/wVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOf6kAP/1w3elvhAYQcK9hkEVCg4sQgnvcatOafCNaK0dVW9OOFbt+8DNUcHbtUHZtR6ETmSAMlWilIr/1vRMjy0Zic6afJ30oq8i+4f6DgLyTsLQL/QdwJQIwi2fZmHebv1PSrhT9tJAwtH6oG3cNhSq8KMme4l7sVR7ekB34Cmzk3fa5udMOuQG9xWbGTmeEsx0kYb+1oag+NnnZJqVTi68gGGxRW8TYZ1APXJcrZVfkldtaIWx6U1UdkWSTqWHV4fnnctp/1M+IgXCLT0iupY5LnxqGKQcMte7WKRPPdfhGF1ta+LN+QPHbwXhDRDIWPBVbDeHxjKcjz3h+DOeF0b7c5vKDADgo9LtHui9QhBJiCDHwsM+8gA+kNEDbtvIYYQ6CLxX9m1TttxI4ASIzFGIQF6nBr3mjQCzmOoWtgVh7R4dsQ9YZgm4twjsIg3g0MDhmgs71jn6Gp4BficF25nY8J6Ct8YopkPs2sfiBYJmyh9NJLDjwqNnjq3MBervPX3B+7p1dfIsK4JoSuop5A4lc4OOEhrwm5BKIxm30R4NtB15RZ7nI0DcRFcwNQiTYPG+nOaPsFzeZD6lj8+YnuLyo2aCnf4K26/1YTlE1wOFkCb1reL99++i8FP94poHBKZ7+6HT6gk4Mmnfb52II4yWlh/CYLeKEzFFfAiOTvfhzpIvqg
217 53221078e0de65d1a821ce5311dec45a7a978301 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmEeqLUVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfMb4P/R4oPBjSKrlGbuxYClNdP0lV4C1NUU1SPa+Il4QwGQteKD+RDfvp8z8+c45rVIEGiUNzaSJP/ZEyhBVW657rYzIhBnZgqnpwBzOViqe4Q3lHiq6wPKjEDIRJafcqMb6MaViPS6iRn6hhMlAcPcoabwhXrUgv8QyxVSTFlJm0RGbUVekQLIWKEAnwcWLHKt0d2DrB0/706xXtKxdJ8N/2WCVOOkr7UvpdLXo3quOz1S930/o1iF/csggsi9q4oZYj2XBdBGHayoqkhKAQMyBfXH19RqW3SWZafY8whrZDCz+9AAmJJk8hjQl6xrT/ZVweRfqvRoMJBgjQdFTi58wjC8995ZXKEC7jsJCEblyRJkc23opuAArPEkJXLDR+oK1vOfikaRjmQoMPAMDjbxTUyVOuHcX+PxMtq9NAO0MKcnSr+D2Xc28TGY9PkBhRkEnN3nlZH5z7DvF8GfOnUt5SGhFiQHhXnL6jDBCQVDKAoCJn0WKDG9+29I6st2eGEwKaIjZQ9NCtaLASiauopMOyWWbHeM58bCl80TBXuj+3W+mo+zDSLoGwWJc5oFdFpmnGGTQtkxPDiV4ksIgJAMb/KHkGY+RxnEsWgX1VcR2c1sYD4nzOjrt4RuvX1i+cfzRjLOchPiru7BbrBQRTXGhrvNzsS9laTCxCH2oDazIudia4
217 53221078e0de65d1a821ce5311dec45a7a978301 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmEeqLUVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfMb4P/R4oPBjSKrlGbuxYClNdP0lV4C1NUU1SPa+Il4QwGQteKD+RDfvp8z8+c45rVIEGiUNzaSJP/ZEyhBVW657rYzIhBnZgqnpwBzOViqe4Q3lHiq6wPKjEDIRJafcqMb6MaViPS6iRn6hhMlAcPcoabwhXrUgv8QyxVSTFlJm0RGbUVekQLIWKEAnwcWLHKt0d2DrB0/706xXtKxdJ8N/2WCVOOkr7UvpdLXo3quOz1S930/o1iF/csggsi9q4oZYj2XBdBGHayoqkhKAQMyBfXH19RqW3SWZafY8whrZDCz+9AAmJJk8hjQl6xrT/ZVweRfqvRoMJBgjQdFTi58wjC8995ZXKEC7jsJCEblyRJkc23opuAArPEkJXLDR+oK1vOfikaRjmQoMPAMDjbxTUyVOuHcX+PxMtq9NAO0MKcnSr+D2Xc28TGY9PkBhRkEnN3nlZH5z7DvF8GfOnUt5SGhFiQHhXnL6jDBCQVDKAoCJn0WKDG9+29I6st2eGEwKaIjZQ9NCtaLASiauopMOyWWbHeM58bCl80TBXuj+3W+mo+zDSLoGwWJc5oFdFpmnGGTQtkxPDiV4ksIgJAMb/KHkGY+RxnEsWgX1VcR2c1sYD4nzOjrt4RuvX1i+cfzRjLOchPiru7BbrBQRTXGhrvNzsS9laTCxCH2oDazIudia4
218 86a60679cf619e14cee9442f865fcf31b142cb9f 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmEtHx4VHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfALUP/331tj8MaD6Ld0Jq+yLK7dRlLa0iZ6Kbq2Nq2bYFrv1V99RMG/0xipxWnHfn+B0qdane15tgYIugiVl5pQCGRBeva5CJEg5hfiN53tDDXc2duwaj+kYAREPZJm3lEtv4Tp87E8XZxnJ5qDnNeLCmtpFEEs2bgOHHY/fwHUf/hu0jHJHvkxXh8zPHBf2le6UOMR65PS89bv0jKKmtYPVuYhs/sPRFp78FbYZPiJ0x5NxQsrkYd3ViaQaT2Hb47fpTEg/t1yD3nkZyxHzrGhkFwrLJDMTafuPaXtzVN0BPT9iztgONm+5cF4g6+4AvFWvi5ki87UmrYMCHoiBxKycKR6O+rxh5aay/69I5iIJlcrxyZ/YkzaTUbw4rAZdaTfODwaYOBeMPJp/MviNB5kEGeCV3yLpbftIzsO9BPJ4VtSadVA4HPN/OvAGcYvGO58rN22ojHnqyrnmmuhc4K2/i94+dkMbTyKHrROMXwkJFgH4i3nukyo5fYw5c5ggYAvtEsHLpihv9hXPafTQvmz17f+7/fNi6qJsjEhH8MPjfFpydkjptIyszZ9tx6HyE+2699vJGVHRVepw6RFVOuneXsyKzNeSaw/LmO7B+PfBxpBTvWLblD6DH09pzisTacoMrhvugvfGZsYEFxGt34NvN3Hqj0+ongzFM53UvzMy2fLm5
218 86a60679cf619e14cee9442f865fcf31b142cb9f 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmEtHx4VHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfALUP/331tj8MaD6Ld0Jq+yLK7dRlLa0iZ6Kbq2Nq2bYFrv1V99RMG/0xipxWnHfn+B0qdane15tgYIugiVl5pQCGRBeva5CJEg5hfiN53tDDXc2duwaj+kYAREPZJm3lEtv4Tp87E8XZxnJ5qDnNeLCmtpFEEs2bgOHHY/fwHUf/hu0jHJHvkxXh8zPHBf2le6UOMR65PS89bv0jKKmtYPVuYhs/sPRFp78FbYZPiJ0x5NxQsrkYd3ViaQaT2Hb47fpTEg/t1yD3nkZyxHzrGhkFwrLJDMTafuPaXtzVN0BPT9iztgONm+5cF4g6+4AvFWvi5ki87UmrYMCHoiBxKycKR6O+rxh5aay/69I5iIJlcrxyZ/YkzaTUbw4rAZdaTfODwaYOBeMPJp/MviNB5kEGeCV3yLpbftIzsO9BPJ4VtSadVA4HPN/OvAGcYvGO58rN22ojHnqyrnmmuhc4K2/i94+dkMbTyKHrROMXwkJFgH4i3nukyo5fYw5c5ggYAvtEsHLpihv9hXPafTQvmz17f+7/fNi6qJsjEhH8MPjfFpydkjptIyszZ9tx6HyE+2699vJGVHRVepw6RFVOuneXsyKzNeSaw/LmO7B+PfBxpBTvWLblD6DH09pzisTacoMrhvugvfGZsYEFxGt34NvN3Hqj0+ongzFM53UvzMy2fLm5
219 750920b18aaaddd654756be40dec59d90f2643be 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmFcc4wVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfatIP+wXnpFitqScNjqnBK6+DaTj+rmBlKoZGB1IQJW5ziDN59gJmT/axemrc3O8BJ/OFO+gDFTX6mk1/L+1Ul4BAF8Yo8XrPd/V7+M02ZUgKTbHmOqTosa9sLeSEojdQQRfSPTHgtA3CLm6VB91fCCfpS9yfCWO3+T8owNelHl8beSqcSlmAzPjqeF1EmalBO4YjSeOCfSdNpVvUGYG8OL/LwYWJqbea7LpN/Sq0piNMqYbc9GYeB9tnf0338WlGEaLTTDk8V3iES+EZxTNeN8NnpGvU0RN50CUfFVyadtbdXUzRDjF4mpdEnsQBkje3hGotyrzDZs1IjKGCANiNBb6dyn/wgv4APOLFw/BLat1Y7z2ZJ6sqUkBbfOs6H2KfufwFZl1sggG1NNXYrwjdS8dHuwi7FRzWMgcYi8Rle8qX8xK/3+We1rwbHfYxhmlEvC8VEC9PZl/K13aIuKmCQ36Es8C/qAtnNfSKZNkYoi/ueAvGFvJo2win1/wIa/6GvBfCxS3ExR1dH+tAUHj2HgMuQXMI6p9OuEloI/mJbdLmU9vnn06EcIyiIPd3dn4H2k0h2WNzyIoVE6YjD5T86jumrUxIj6hp+C9XYYkoj4KR17Pk7U4i3GixDpupLc/KoxiQRGSQTogPjD5O5RCg41tFaGav/TcyW/pb9gTI+v3ALjbZ
219 750920b18aaaddd654756be40dec59d90f2643be 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmFcc4wVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfatIP+wXnpFitqScNjqnBK6+DaTj+rmBlKoZGB1IQJW5ziDN59gJmT/axemrc3O8BJ/OFO+gDFTX6mk1/L+1Ul4BAF8Yo8XrPd/V7+M02ZUgKTbHmOqTosa9sLeSEojdQQRfSPTHgtA3CLm6VB91fCCfpS9yfCWO3+T8owNelHl8beSqcSlmAzPjqeF1EmalBO4YjSeOCfSdNpVvUGYG8OL/LwYWJqbea7LpN/Sq0piNMqYbc9GYeB9tnf0338WlGEaLTTDk8V3iES+EZxTNeN8NnpGvU0RN50CUfFVyadtbdXUzRDjF4mpdEnsQBkje3hGotyrzDZs1IjKGCANiNBb6dyn/wgv4APOLFw/BLat1Y7z2ZJ6sqUkBbfOs6H2KfufwFZl1sggG1NNXYrwjdS8dHuwi7FRzWMgcYi8Rle8qX8xK/3+We1rwbHfYxhmlEvC8VEC9PZl/K13aIuKmCQ36Es8C/qAtnNfSKZNkYoi/ueAvGFvJo2win1/wIa/6GvBfCxS3ExR1dH+tAUHj2HgMuQXMI6p9OuEloI/mJbdLmU9vnn06EcIyiIPd3dn4H2k0h2WNzyIoVE6YjD5T86jumrUxIj6hp+C9XYYkoj4KR17Pk7U4i3GixDpupLc/KoxiQRGSQTogPjD5O5RCg41tFaGav/TcyW/pb9gTI+v3ALjbZ
220 6ee0244fc1cf889ae543d2ce0ec45201ae0be6e1 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmF4AWgVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfxu8P/R8FftAoLkFGHnrzXA9Wa+ch+wunUNixCSimuXjG5sUtDSDlNT+xGj0deTVRVDylFd5HShR6a8NV+2P9edgJYDOKE70j4DJxHdeDyZ3l09YEBymrluE4FygXwpG0B3Ew9pUD85yFxa6UfIFWvNTGYi7XCHBl85buCkMACafN97802jXuE3JV53FvW6Fp917hM0saG48Cnp33WZxdUrZdxXU0Q8bZ9OBYCuGq8Wt2ZIqfEM6YXmvOzlkZf6oJb65rYOw2KgfLs/5nEGiDUNK2akuEhAZLi7uL0dt4WzYAbLyRhIpMpFPitk9P+Ges7iYINwSyZKZcsNPm0NiJupSjKqIYuuLte9HR59RkDFGgM9hbFnskElgHXMqLxi+RqjDVrj2efbuyWzDCn6eVZyn7vmxy9/oLM9vnVsvvdziN2uNUPL4CVmnOZciCdkEZQtWynyyEGzNyq7kPH593ct3tYMxpzs3wa3o+sSdph3lf7caXskij0d0woRZneuZFwp26Ha9tKMMRmXzgFvipzL+o2ANWV6X2udO0pXmKhzYJSBcUPlmVz8hyJaV2D3nmXeFHKVrPa/CqnSGNPWNQC39im1NyPKbfJAA9DZmw7FKg/b23tJq8w9WkBAghEUhC4e54Eb068awt/RDaD6oBYfpdCnQ1pbC/6PHnRSOm8PubGoOZ
220 6ee0244fc1cf889ae543d2ce0ec45201ae0be6e1 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmF4AWgVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfxu8P/R8FftAoLkFGHnrzXA9Wa+ch+wunUNixCSimuXjG5sUtDSDlNT+xGj0deTVRVDylFd5HShR6a8NV+2P9edgJYDOKE70j4DJxHdeDyZ3l09YEBymrluE4FygXwpG0B3Ew9pUD85yFxa6UfIFWvNTGYi7XCHBl85buCkMACafN97802jXuE3JV53FvW6Fp917hM0saG48Cnp33WZxdUrZdxXU0Q8bZ9OBYCuGq8Wt2ZIqfEM6YXmvOzlkZf6oJb65rYOw2KgfLs/5nEGiDUNK2akuEhAZLi7uL0dt4WzYAbLyRhIpMpFPitk9P+Ges7iYINwSyZKZcsNPm0NiJupSjKqIYuuLte9HR59RkDFGgM9hbFnskElgHXMqLxi+RqjDVrj2efbuyWzDCn6eVZyn7vmxy9/oLM9vnVsvvdziN2uNUPL4CVmnOZciCdkEZQtWynyyEGzNyq7kPH593ct3tYMxpzs3wa3o+sSdph3lf7caXskij0d0woRZneuZFwp26Ha9tKMMRmXzgFvipzL+o2ANWV6X2udO0pXmKhzYJSBcUPlmVz8hyJaV2D3nmXeFHKVrPa/CqnSGNPWNQC39im1NyPKbfJAA9DZmw7FKg/b23tJq8w9WkBAghEUhC4e54Eb068awt/RDaD6oBYfpdCnQ1pbC/6PHnRSOm8PubGoOZ
221 a44bb185f6bdbecc754996d8386722e2f0123b0a 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmGKo4sVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOffmQP/jsOxxP0F9TliKYp7YjgMagtnebk+qdbq9pX8y8GdjGirRwCy/rMm3pXMNQDiWd3ZdYLICZIz8aSYbPL6HD78O6F68IWOVG5AwLM6knUNcEzmrPoFnSU1J7jaz8ERFmfNV6loes3oYj/VhRUDiFEmG1sflCc1iXvTEXaOi2PObo7iORR/2JtOlMQI7bASBTo0F7QTRzOuh+SzgJ6ItqpvjC+I2Iidn8yZ/F3jZXZ24on/D+b2nLQ5b7yc7pzVNyqiTFF6xHQEtRjNRv+hLS9mdD/oI6Vhwmfv7GD8U4MyudDfz5GEv2AE9cwOKRONfHdXhFX3UiubaDmDlo+mE3xXIPYJoTtadoUhVItCe5YAlp9P6uEAaWk/Z1zI+9ydYACycO0RySrphRJ3DmDITs7D2bQEsK/YB1NBzwlUJVFiTu8x2+taBk3vO66cfuyubvPXpdZs6VcnIxSMfduP29zYLj7L1YZo58y3qhKeWcZexYSBT/dtGZlOOdobI/t9YHKnrUtzUCL9JIuxqn06+dSU9DlNuOd19Mdr2wu+xncuzlkd+Y4DavctrA0uSw4CAID6e5UIoknAeOzMSFySZ+JLw79z1LpFx/t3wof5ySC6olLO1NFesK89NAYszIjeTOQnpcK9sA2OaANTDbC7sX12OmpPlRySNcNRsaNgux6Bnl4
221 a44bb185f6bdbecc754996d8386722e2f0123b0a 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmGKo4sVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOffmQP/jsOxxP0F9TliKYp7YjgMagtnebk+qdbq9pX8y8GdjGirRwCy/rMm3pXMNQDiWd3ZdYLICZIz8aSYbPL6HD78O6F68IWOVG5AwLM6knUNcEzmrPoFnSU1J7jaz8ERFmfNV6loes3oYj/VhRUDiFEmG1sflCc1iXvTEXaOi2PObo7iORR/2JtOlMQI7bASBTo0F7QTRzOuh+SzgJ6ItqpvjC+I2Iidn8yZ/F3jZXZ24on/D+b2nLQ5b7yc7pzVNyqiTFF6xHQEtRjNRv+hLS9mdD/oI6Vhwmfv7GD8U4MyudDfz5GEv2AE9cwOKRONfHdXhFX3UiubaDmDlo+mE3xXIPYJoTtadoUhVItCe5YAlp9P6uEAaWk/Z1zI+9ydYACycO0RySrphRJ3DmDITs7D2bQEsK/YB1NBzwlUJVFiTu8x2+taBk3vO66cfuyubvPXpdZs6VcnIxSMfduP29zYLj7L1YZo58y3qhKeWcZexYSBT/dtGZlOOdobI/t9YHKnrUtzUCL9JIuxqn06+dSU9DlNuOd19Mdr2wu+xncuzlkd+Y4DavctrA0uSw4CAID6e5UIoknAeOzMSFySZ+JLw79z1LpFx/t3wof5ySC6olLO1NFesK89NAYszIjeTOQnpcK9sA2OaANTDbC7sX12OmpPlRySNcNRsaNgux6Bnl4
222 5d08b289e2e526259d7d5ea32b70fe76d5b327d7 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmGcvOQVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfNcAP/0zjJ+vfms7hBPltQJxzRX3JaMSDGyFB6+0CXJnEHClcjmcmmFq7yPYSZhO1/wRwNDag1A+xOr+xch0VHy3s2L4JDVqpTEIGDVX9MZxqDYdFMpMmx63KQeOraTbd8MCpbsiCsp+yQWwQ0k8sjajY2FhpJFezcD8EVH+XQJSkBsPGQZGezNt6IVlnsnBpTl6abVFWrsHhpos1Wa7iJM/sS91dy9We5H3B1eEn8KOMyj3eWEA6D8D29kCS66E8+AQ+f9ctresD2g/6xS1P4CTgvqacS+gj04rMUKmmQUoMzAXlS4wO2F6J0mWdKfZsv/urfJx7oc5GZysrXw+T/YLxFKuxls1uCq6mTBxbf/aJ91G4m0UT/fczNrQaDDhPIFEZVktd18NphUOebTGxDiCW/mk9IOXxEI7bprlBdBBM3dkCAg+O0h8kdN007jjoLIiTw7K+XZ1A41zqGqXMQ2R/0xTltX9NXAe9xNhAEQhwSCH2TsB5IKI6+EHE6ZaNsyuwvlPhaQXfmOU22JBlUGE9IdEU5whd9760xJYTx3WEnbuED0UltAt3vgyvq+li1/Z7HDuzUyNha8YsaPw2QeHFUFwzxqoxo501/eDs9bXjBt7E4vsYVQC51sb3uS9kRbBB9GOiyx/HICZcbEQjy5TxVW5Bp0uD6Fu3nRytL0DDDIDF
222 5d08b289e2e526259d7d5ea32b70fe76d5b327d7 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmGcvOQVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfNcAP/0zjJ+vfms7hBPltQJxzRX3JaMSDGyFB6+0CXJnEHClcjmcmmFq7yPYSZhO1/wRwNDag1A+xOr+xch0VHy3s2L4JDVqpTEIGDVX9MZxqDYdFMpMmx63KQeOraTbd8MCpbsiCsp+yQWwQ0k8sjajY2FhpJFezcD8EVH+XQJSkBsPGQZGezNt6IVlnsnBpTl6abVFWrsHhpos1Wa7iJM/sS91dy9We5H3B1eEn8KOMyj3eWEA6D8D29kCS66E8+AQ+f9ctresD2g/6xS1P4CTgvqacS+gj04rMUKmmQUoMzAXlS4wO2F6J0mWdKfZsv/urfJx7oc5GZysrXw+T/YLxFKuxls1uCq6mTBxbf/aJ91G4m0UT/fczNrQaDDhPIFEZVktd18NphUOebTGxDiCW/mk9IOXxEI7bprlBdBBM3dkCAg+O0h8kdN007jjoLIiTw7K+XZ1A41zqGqXMQ2R/0xTltX9NXAe9xNhAEQhwSCH2TsB5IKI6+EHE6ZaNsyuwvlPhaQXfmOU22JBlUGE9IdEU5whd9760xJYTx3WEnbuED0UltAt3vgyvq+li1/Z7HDuzUyNha8YsaPw2QeHFUFwzxqoxo501/eDs9bXjBt7E4vsYVQC51sb3uS9kRbBB9GOiyx/HICZcbEQjy5TxVW5Bp0uD6Fu3nRytL0DDDIDF
223 799fdf4cca80cb9ae40537a90995e6bd163ebc0b 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmHVzPMZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVmiyC/48p6+/JJi8WaY+Xdxh1IMK1/CB3dYcC99+V89asIW+g/X/0FacTSSAGkvDrjNSeYAkXGp3g/LbEbwoZhKxF8MyKU7TOn62lz8JETwebtjxehjVfPUy73RJbuLPDvn9m16YHxuC848hDZHnqk/PjaBVHeZ2cN8T7F9VgXkhyYStV9GT2PSQUsvkQAxjiLilyKs3RaZAduZPvOmGaq2CfK91PbScKaKgYShkKym7gfhU1o4pynNmuPqRwUJyihaZqsKDjOn8OHeJpqAm7ODmR+SIOvMvFbbfS8mTSfYMHsP+r+JgbqSVNG99qEqsIW3HznGe/OpG/1QS3MVVSyi87oHR1UcN91vKIiln92i+7Ct7GttjkgkkqfQEw1oAELCmiHacYEBbLvQGaXdHROeO6wqXUKvI4KeM3CPt2qsouPiKBzSF1eOPd967NNvgTgcabT2ob0YaXmWdZasJnZ74H/3FMMC98WhYe3ja+6cpl67PZlNUWlnIZBlyL63DWSJ09us=
223 799fdf4cca80cb9ae40537a90995e6bd163ebc0b 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmHVzPMZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVmiyC/48p6+/JJi8WaY+Xdxh1IMK1/CB3dYcC99+V89asIW+g/X/0FacTSSAGkvDrjNSeYAkXGp3g/LbEbwoZhKxF8MyKU7TOn62lz8JETwebtjxehjVfPUy73RJbuLPDvn9m16YHxuC848hDZHnqk/PjaBVHeZ2cN8T7F9VgXkhyYStV9GT2PSQUsvkQAxjiLilyKs3RaZAduZPvOmGaq2CfK91PbScKaKgYShkKym7gfhU1o4pynNmuPqRwUJyihaZqsKDjOn8OHeJpqAm7ODmR+SIOvMvFbbfS8mTSfYMHsP+r+JgbqSVNG99qEqsIW3HznGe/OpG/1QS3MVVSyi87oHR1UcN91vKIiln92i+7Ct7GttjkgkkqfQEw1oAELCmiHacYEBbLvQGaXdHROeO6wqXUKvI4KeM3CPt2qsouPiKBzSF1eOPd967NNvgTgcabT2ob0YaXmWdZasJnZ74H/3FMMC98WhYe3ja+6cpl67PZlNUWlnIZBlyL63DWSJ09us=
224 75676122c2bf7594ac732b7388db4c74c648b365 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmH6qwUZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVogkC/4hgjtCXykyst2XuC93IkWdRoXiFn2+C/r/eX25el//+Og5T0KZmttFGrmTCSCdb/ZkjPg1ZHYBUK9gyQCOXoimATIeql/USCcglpVBRMTaaqvpJyHA1antI0HIsNFGjDTIxHsJXgghMEv7qVR33ItpZ8gtWbJJLewOwi2UHtLcmif77SgpeADh/E/PuQT+0Wd5gA6jk9Fml7VBP/nU81j25ZyxB6p8oUv4gFSNDZtrnA97mQ35jYZZITl8e80Y9Z/8KJFcRk29kxIudOikwn6AD7ZW/H85a3lDOtTMhgBDNlMxvXx6eviKfsrIVtNCm6QDF+36VstTR+idWyhnkq8g20NXcgWt79/CTWT7ssFmzdsHhdhWfJF99I0R0FCG0DSV313UmleZawavG1btOh4qCjTAWF5gnvsHfEIV1SAnDeeD6T27c8yIW7au9QXlkZds0xmFWLqkl6TxKpl7oa/bGDArAvOA3zHAeMlwXQKhhthjR7fU9PQnWsFXCt43GVo=
224 75676122c2bf7594ac732b7388db4c74c648b365 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmH6qwUZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVogkC/4hgjtCXykyst2XuC93IkWdRoXiFn2+C/r/eX25el//+Og5T0KZmttFGrmTCSCdb/ZkjPg1ZHYBUK9gyQCOXoimATIeql/USCcglpVBRMTaaqvpJyHA1antI0HIsNFGjDTIxHsJXgghMEv7qVR33ItpZ8gtWbJJLewOwi2UHtLcmif77SgpeADh/E/PuQT+0Wd5gA6jk9Fml7VBP/nU81j25ZyxB6p8oUv4gFSNDZtrnA97mQ35jYZZITl8e80Y9Z/8KJFcRk29kxIudOikwn6AD7ZW/H85a3lDOtTMhgBDNlMxvXx6eviKfsrIVtNCm6QDF+36VstTR+idWyhnkq8g20NXcgWt79/CTWT7ssFmzdsHhdhWfJF99I0R0FCG0DSV313UmleZawavG1btOh4qCjTAWF5gnvsHfEIV1SAnDeeD6T27c8yIW7au9QXlkZds0xmFWLqkl6TxKpl7oa/bGDArAvOA3zHAeMlwXQKhhthjR7fU9PQnWsFXCt43GVo=
225 dcec16e799ddb6d33fcd11b04af530250a417a58 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmIPiSsZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVvRYC/9Ul8I7vJvCaFwotgAuVBGbpcyYwhCkxBuxyROInUjhQdrSqYLUo7frlDEdoos1q0y2w9DiTyBeqeewiYw77DXQzKPtxqJDO3m1exnbtsmUQhQBF8mUyDqO0yay6WcGp9daqIlFnf8HzXxBgvkpI1eReVoLBvGWzc+MWKmdPrVsY8CLyMCSXKQldyEa9uAARBRDnT2HTnPUDwS3lav5sHYhwWUuC/dwSQWlSsmIUrY2sB3yY9KS2CrUFkXGo3tmQNHayCXfKmyW04xoYlIKQxrXLQ5hOCaogExsSkdXzCDaQS6avS0U8QaM/XuXe2BDR4wq7w7iomM7xagoqbx/0VINizfbSh2sA/Nxt4/mf9V2VCPUh9QlSJztNTbSUOvpOPbk9l9KafgEQTspnsleRXQymAhBuCd9aap0Q9NC4vixVPWxjqyxyFS0eRbnZ9/LTI0+ZCHTizupG0nUiXY3cpwQB6a7CRdn8qdMsA0FURAJlVE4nDlSsY4v9AWxPHreGJw=
225 dcec16e799ddb6d33fcd11b04af530250a417a58 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmIPiSsZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVvRYC/9Ul8I7vJvCaFwotgAuVBGbpcyYwhCkxBuxyROInUjhQdrSqYLUo7frlDEdoos1q0y2w9DiTyBeqeewiYw77DXQzKPtxqJDO3m1exnbtsmUQhQBF8mUyDqO0yay6WcGp9daqIlFnf8HzXxBgvkpI1eReVoLBvGWzc+MWKmdPrVsY8CLyMCSXKQldyEa9uAARBRDnT2HTnPUDwS3lav5sHYhwWUuC/dwSQWlSsmIUrY2sB3yY9KS2CrUFkXGo3tmQNHayCXfKmyW04xoYlIKQxrXLQ5hOCaogExsSkdXzCDaQS6avS0U8QaM/XuXe2BDR4wq7w7iomM7xagoqbx/0VINizfbSh2sA/Nxt4/mf9V2VCPUh9QlSJztNTbSUOvpOPbk9l9KafgEQTspnsleRXQymAhBuCd9aap0Q9NC4vixVPWxjqyxyFS0eRbnZ9/LTI0+ZCHTizupG0nUiXY3cpwQB6a7CRdn8qdMsA0FURAJlVE4nDlSsY4v9AWxPHreGJw=
226 c00d3ce4e94bb0ee8d809e25e1dcb2a5fab84e2c 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmIPn9oZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVpamDACfmZw0FscQ6oCs1ZyWZ2sf6xxYnk242h4ca8fyILrGfuhlgkochlMwF8id3EPVKnie3QHBi33Nf5Tz9eFTFR4z/eQ5W8R+bjYWo/F+4FDkaTIprvg4gfoH1MklmpVhPa7MFVmp7tmSx/0EVdpJuMkJSeAU1kQ6Mq8ekMWQT4vtLbkAOGZcnwKiU57j8cYnOjoIqA+22/S0DBWMKjEnuz3k8TjplsZXVgTEUelFAwT4SC3qNSIBvVYyDmdAoD0C4zL88tErY0MeQ/ehId6E1khLvw9I65z/f2hOxXiDdk0b6WV2MCh1rxCX5RUiH0aNUmG+hGphpH0VVqQihkQEIdzZhXiFVlEc/rAbdt3g7pVc2RuWSanBUEOcvly0r40A2wRCka1jjgfz7dtmjZ91SKCPpOUdxHfaqqWz/0Y/oIgpq/UM+1fufDxeLZG+OY8B5y+c+ZUuGacAVNRQku6IB+0dT4/DTEsYWT3VMIH0ZzGFiAQ2g3IPo6qlLFK54LztXTg=
226 c00d3ce4e94bb0ee8d809e25e1dcb2a5fab84e2c 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmIPn9oZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVpamDACfmZw0FscQ6oCs1ZyWZ2sf6xxYnk242h4ca8fyILrGfuhlgkochlMwF8id3EPVKnie3QHBi33Nf5Tz9eFTFR4z/eQ5W8R+bjYWo/F+4FDkaTIprvg4gfoH1MklmpVhPa7MFVmp7tmSx/0EVdpJuMkJSeAU1kQ6Mq8ekMWQT4vtLbkAOGZcnwKiU57j8cYnOjoIqA+22/S0DBWMKjEnuz3k8TjplsZXVgTEUelFAwT4SC3qNSIBvVYyDmdAoD0C4zL88tErY0MeQ/ehId6E1khLvw9I65z/f2hOxXiDdk0b6WV2MCh1rxCX5RUiH0aNUmG+hGphpH0VVqQihkQEIdzZhXiFVlEc/rAbdt3g7pVc2RuWSanBUEOcvly0r40A2wRCka1jjgfz7dtmjZ91SKCPpOUdxHfaqqWz/0Y/oIgpq/UM+1fufDxeLZG+OY8B5y+c+ZUuGacAVNRQku6IB+0dT4/DTEsYWT3VMIH0ZzGFiAQ2g3IPo6qlLFK54LztXTg=
227 d4486810a1795fba9521449b8885ced034f3a6dd 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmIePhwZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVm3LC/wP9h6bFiy1l3fJhmq2yKuXu/oNWqT7CmOPqOPnQoO6Pd7a184kvgrabU9dsnXllj1mtbUhaIcfZ8XAb30lTbr0W1dSDoT0QWMY7sOFgXIvJSbWWmFo8DrYQSTlg1xA0LWdwsSKmce/r1G6D7JERj5VzBs3Hq65Kb9vg94vqdVSvyye+YzSODSh1w8P0qsgv78UWqabSrf28DlUp/kG7j43k1J93ZEOgH7+jrxgiQ2WzhmhlWcUFJOGxchbdDl5XZptwPssNstUgXfZKe5sFOI7WJSN//rHo3JgLbEDCX7TMe82aPl2DxEquHNH8rrOha4UuGZjFwO+/PzykItUCPzPWabE6z49w6+/G1us+ofts1z8Muh0ICegFxbd0bRotGRmJ/iEZqrtgFQokx1SSlZKArbRBbLfWoJcczxWxBK1qCz2avKY4qKcieC9TTo7LrHqA5JvLNuqvInKITYOfq1zCuLvxnaSCQTKKOEEb9/ortjxN9rvx1bFyRorVvXR+J0=
227 d4486810a1795fba9521449b8885ced034f3a6dd 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmIePhwZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVm3LC/wP9h6bFiy1l3fJhmq2yKuXu/oNWqT7CmOPqOPnQoO6Pd7a184kvgrabU9dsnXllj1mtbUhaIcfZ8XAb30lTbr0W1dSDoT0QWMY7sOFgXIvJSbWWmFo8DrYQSTlg1xA0LWdwsSKmce/r1G6D7JERj5VzBs3Hq65Kb9vg94vqdVSvyye+YzSODSh1w8P0qsgv78UWqabSrf28DlUp/kG7j43k1J93ZEOgH7+jrxgiQ2WzhmhlWcUFJOGxchbdDl5XZptwPssNstUgXfZKe5sFOI7WJSN//rHo3JgLbEDCX7TMe82aPl2DxEquHNH8rrOha4UuGZjFwO+/PzykItUCPzPWabE6z49w6+/G1us+ofts1z8Muh0ICegFxbd0bRotGRmJ/iEZqrtgFQokx1SSlZKArbRBbLfWoJcczxWxBK1qCz2avKY4qKcieC9TTo7LrHqA5JvLNuqvInKITYOfq1zCuLvxnaSCQTKKOEEb9/ortjxN9rvx1bFyRorVvXR+J0=
228 5bd6bcd31dd1ebb63b8914b00064f96297267af7 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmJMXf0ZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVpSlC/sHnQTin4bLp+F6keT9gGCoDqx11cf4Npl6RmqM3V4SN3hP3k8gwo5JOMWNSYzwxuBuzJ24EBTtgV139NPdeHce3LEaDMMg+n5YlQjl3vqFnYPAkX973yHH1R1ijkdGNtM4KfWw6C7b8stNaKCQmnRBsKy7oxGKvHoL8ufiSmxVtkP8ImW3x9oiYUEueIWMVhaIvNANxOzsiU++yubo1ldFGXOnNAS91MALeeu7ikClaJQQLp6jMobnn0qI8TGzbe5LnexA81/qIltgFLyUAWA2d3NXVis7hFjwLToyBkObpZfq6X/7a9XhBHMwTM+O8ViYODraupcYw0vrqT93cbuBSN106sC1UERaVN2YNb1gsoyqXTZ2F8ho5QZWJphQw9cwKJkOn81SXJ8ZWr+L8WVm78mrbDV8zT6lQ/7IsmIXTQNWMBgeGc74qyReowyswP7hSbl9iQDcdKMus/4Gm9cqTnYg3Bt8jZ3lupeYMv9ZSFmKDG8A69QFLKYKzd/FFx0=
228 5bd6bcd31dd1ebb63b8914b00064f96297267af7 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmJMXf0ZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVpSlC/sHnQTin4bLp+F6keT9gGCoDqx11cf4Npl6RmqM3V4SN3hP3k8gwo5JOMWNSYzwxuBuzJ24EBTtgV139NPdeHce3LEaDMMg+n5YlQjl3vqFnYPAkX973yHH1R1ijkdGNtM4KfWw6C7b8stNaKCQmnRBsKy7oxGKvHoL8ufiSmxVtkP8ImW3x9oiYUEueIWMVhaIvNANxOzsiU++yubo1ldFGXOnNAS91MALeeu7ikClaJQQLp6jMobnn0qI8TGzbe5LnexA81/qIltgFLyUAWA2d3NXVis7hFjwLToyBkObpZfq6X/7a9XhBHMwTM+O8ViYODraupcYw0vrqT93cbuBSN106sC1UERaVN2YNb1gsoyqXTZ2F8ho5QZWJphQw9cwKJkOn81SXJ8ZWr+L8WVm78mrbDV8zT6lQ/7IsmIXTQNWMBgeGc74qyReowyswP7hSbl9iQDcdKMus/4Gm9cqTnYg3Bt8jZ3lupeYMv9ZSFmKDG8A69QFLKYKzd/FFx0=
229 0ddd5e1f5f67438af85d12e4ce6c39021dde9916 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmJyo/kZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVsTVDACmg+uABE36kJcVJewoVK2I2JAdrO2llq3QbvzNb0eRL7bGy5UKJvF7fy/1FfayZT9/YTc6kGcRIeG+jUUiGRxMr0fOP9RixG78OyV14MmN1vkNTfMbk6BBrkYRbJJioLyk9qsXU6HbfRUdaCkOqwOKXKHm/4lzG/JFvL4JL6v++idx8W/7sADKILNy2DtP22YaRMgz38iM3ejgZghw7ie607C6lYq4wMs39jTZdZ3s6XoN+VgsLJWsI1LFnIADU5Zry8EAFERsvphiM2zG8lkrbPjpvwtidBz999TYnnGLvTMZA5ubspQRERc/eNDRbKdA55cCWNg3DhTancOiu3bQXdYCjF1MCN9g5Q11zbEzdwrbrY0NF7AUq1VW4kGFgChIJ0IuTQ/YETbcbih2Xs4nkAGt64YPtHzmOffF1a2/SUzH3AwgMmhBQBqxa02YTqyKJDHHqgTyFrZIkH/jb+rdfIskaOZZo6JcGUoacFOUhFfhSxxB1kN2HEHvEAQPMkc=
229 0ddd5e1f5f67438af85d12e4ce6c39021dde9916 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmJyo/kZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVsTVDACmg+uABE36kJcVJewoVK2I2JAdrO2llq3QbvzNb0eRL7bGy5UKJvF7fy/1FfayZT9/YTc6kGcRIeG+jUUiGRxMr0fOP9RixG78OyV14MmN1vkNTfMbk6BBrkYRbJJioLyk9qsXU6HbfRUdaCkOqwOKXKHm/4lzG/JFvL4JL6v++idx8W/7sADKILNy2DtP22YaRMgz38iM3ejgZghw7ie607C6lYq4wMs39jTZdZ3s6XoN+VgsLJWsI1LFnIADU5Zry8EAFERsvphiM2zG8lkrbPjpvwtidBz999TYnnGLvTMZA5ubspQRERc/eNDRbKdA55cCWNg3DhTancOiu3bQXdYCjF1MCN9g5Q11zbEzdwrbrY0NF7AUq1VW4kGFgChIJ0IuTQ/YETbcbih2Xs4nkAGt64YPtHzmOffF1a2/SUzH3AwgMmhBQBqxa02YTqyKJDHHqgTyFrZIkH/jb+rdfIskaOZZo6JcGUoacFOUhFfhSxxB1kN2HEHvEAQPMkc=
230 6b10151b962108f65bfa12b3918b1021ca334f73 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmKYxvUZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVqsDC/9EKBjkHvQeY55bqhqqyf5Mccw8cXH5/WBsyJYtEl+W6ykFRlTUUukY0MKzc1xCGG4sryTwqf8qxW92Yqt4bwoFIKIEpOa6CGsf18Ir/fMVNaOmYABtbbLqFgkuarNLz5wIMkGXugqZ4RUhs7HvL0Rsgb24mWpS5temzb2f0URP5uKFCY4MMC+oBFHKFfkn9MwAVIkX+iAakDR4x6dbSPKPNRwRqILKSnGosDZ+dnvvjJTbqZdLowU5OBXdUoa57j9xxcSzCme0hQ0VNuPcn4DQ/N2yZrCsJvvv3soE94jMkhbnfLZ3/EulQAVZZs9Hjur4w/Hk9g8+YK5lIvJDUSX3cBRiYKuGojxDMnXP5f1hW4YdDVCFhnwczeG7Q20fybjwWvB+QgYUkHzGbdCYSHCWE7f/HhTivEPSudYP4SdMnEdWNx2Rqvs+QsgFAEiIgc6lhupyZwyfIdhgxPJ/BAsjUDJnFR0dj86yVoWjoQfkEyf6toK3OjrHNLPEPfWX4Ac=
230 6b10151b962108f65bfa12b3918b1021ca334f73 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmKYxvUZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVqsDC/9EKBjkHvQeY55bqhqqyf5Mccw8cXH5/WBsyJYtEl+W6ykFRlTUUukY0MKzc1xCGG4sryTwqf8qxW92Yqt4bwoFIKIEpOa6CGsf18Ir/fMVNaOmYABtbbLqFgkuarNLz5wIMkGXugqZ4RUhs7HvL0Rsgb24mWpS5temzb2f0URP5uKFCY4MMC+oBFHKFfkn9MwAVIkX+iAakDR4x6dbSPKPNRwRqILKSnGosDZ+dnvvjJTbqZdLowU5OBXdUoa57j9xxcSzCme0hQ0VNuPcn4DQ/N2yZrCsJvvv3soE94jMkhbnfLZ3/EulQAVZZs9Hjur4w/Hk9g8+YK5lIvJDUSX3cBRiYKuGojxDMnXP5f1hW4YdDVCFhnwczeG7Q20fybjwWvB+QgYUkHzGbdCYSHCWE7f/HhTivEPSudYP4SdMnEdWNx2Rqvs+QsgFAEiIgc6lhupyZwyfIdhgxPJ/BAsjUDJnFR0dj86yVoWjoQfkEyf6toK3OjrHNLPEPfWX4Ac=
231 0cc5f74ff7f0f4ac2427096bddbe102dbc2453ae 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmKrK5wZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVvSmC/93B3If9OY0eqbzScqY4S6XgtC1mR3tkQirYaUujCrrt75P8jlFABn1UdrOgXwjHhm+eVxxvlg/JoexSfro89j8UFFqlVzxvDXipVFFGj/n8AeRctkNiaLpDT8ejDQic7ED566gLSeAWlZ6TA14c4+O6SC1vQxr5BCEiQjBVM7bc91O4GB/VTf/31teCtdmjScv0wsISKMJdVBIOcjOaDM1dzSlWE2wNzK551hHr7D3T5v78NJ7+5NbgqzOScRpFxzO8ndDa9YCqVdpixOVbCt1PruxUc9gYjbHbCUnm+3iZ+MnGtSZdyM7XC6BLhg3IGBinzCxff3+K/1p0VR3pr53TGXdQLfkpkRiWVQlWxQUl2MFbGhpFtvqNACMKJrL/tyTFjC+2GWBTetju8OWeqpVKWmLroL6RZaotMQzNG3sRnNwDrVL9VufT1abP9LQm71Rj1c1SsvRNaFhgBannTnaQoz6UQXvM0Rr1foUESJudU5rKr4kiJdSGMqIAsH15z8=
231 0cc5f74ff7f0f4ac2427096bddbe102dbc2453ae 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmKrK5wZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVvSmC/93B3If9OY0eqbzScqY4S6XgtC1mR3tkQirYaUujCrrt75P8jlFABn1UdrOgXwjHhm+eVxxvlg/JoexSfro89j8UFFqlVzxvDXipVFFGj/n8AeRctkNiaLpDT8ejDQic7ED566gLSeAWlZ6TA14c4+O6SC1vQxr5BCEiQjBVM7bc91O4GB/VTf/31teCtdmjScv0wsISKMJdVBIOcjOaDM1dzSlWE2wNzK551hHr7D3T5v78NJ7+5NbgqzOScRpFxzO8ndDa9YCqVdpixOVbCt1PruxUc9gYjbHbCUnm+3iZ+MnGtSZdyM7XC6BLhg3IGBinzCxff3+K/1p0VR3pr53TGXdQLfkpkRiWVQlWxQUl2MFbGhpFtvqNACMKJrL/tyTFjC+2GWBTetju8OWeqpVKWmLroL6RZaotMQzNG3sRnNwDrVL9VufT1abP9LQm71Rj1c1SsvRNaFhgBannTnaQoz6UQXvM0Rr1foUESJudU5rKr4kiJdSGMqIAsH15z8=
232 288de6f5d724bba7bf1669e2838f196962bb7528 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmKrVSEZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVqfUDACWYt2x2yNeb3SgCQsMhntFoKgwZ/CKFpiaz8W6jYij4mnwwWNAcflJAG3NJPK1I4RJrQky+omTmoc7dTAxfbjds7kA8AsXrVIFyP7HV5OKLEACWEAlCrtBLoj+gSYwO+yHQD7CnWqcMqYocHzsfVIr6qT9QQMlixP4lCiKh8ZrwPRGameONVfDBdL+tzw/WnkA5bVeRIlGpHoPe1y7xjP1kfj0a39aDezOcNqzxnzCuhpi+AC1xOpGi9ZqYhF6CmcDVRW6m7NEonbWasYpefpxtVa1xVreI1OIeBO30l7OsPI4DNn+dUpA4tA2VvvU+4RMsHPeT5R2VadXjF3xoH1LSdxv5fSKmRDr98GSwC5MzvTgMzskfMJ3n4Z7jhfPUz4YW4DBr71H27b1Mfdnl2cwXyT/0fD9peBWXe4ZBJ6VegPBUOjuIu0lUyfk7Zj9zb6l1AZC536Q1KolJPswQm9VyrX9Mtk70s0e1Fp3q1oohZVxdLPQvpR4empP0WMdPgg=
232 288de6f5d724bba7bf1669e2838f196962bb7528 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmKrVSEZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVqfUDACWYt2x2yNeb3SgCQsMhntFoKgwZ/CKFpiaz8W6jYij4mnwwWNAcflJAG3NJPK1I4RJrQky+omTmoc7dTAxfbjds7kA8AsXrVIFyP7HV5OKLEACWEAlCrtBLoj+gSYwO+yHQD7CnWqcMqYocHzsfVIr6qT9QQMlixP4lCiKh8ZrwPRGameONVfDBdL+tzw/WnkA5bVeRIlGpHoPe1y7xjP1kfj0a39aDezOcNqzxnzCuhpi+AC1xOpGi9ZqYhF6CmcDVRW6m7NEonbWasYpefpxtVa1xVreI1OIeBO30l7OsPI4DNn+dUpA4tA2VvvU+4RMsHPeT5R2VadXjF3xoH1LSdxv5fSKmRDr98GSwC5MzvTgMzskfMJ3n4Z7jhfPUz4YW4DBr71H27b1Mfdnl2cwXyT/0fD9peBWXe4ZBJ6VegPBUOjuIu0lUyfk7Zj9zb6l1AZC536Q1KolJPswQm9VyrX9Mtk70s0e1Fp3q1oohZVxdLPQvpR4empP0WMdPgg=
233 094a5fa3cf52f936e0de3f1e507c818bee5ece6b 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmLL1jYZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVn4gC/9Ls9JQEQrJPVfqp9+VicJIUUww/aKYWedlQJOlv4oEQJzYQQU9WfJq2d9OAuX2+cXCo7BC+NdjhjKjv7n0+gK0HuhfYYUoXiJvcfa4GSeEyxxnDf55lBCDxURstVrExU7c5OKiG+dPcsTPdvRdkpeAT/4gaewZ1cR0yZILNjpUeSWzQ7zhheXqfooyVkubdZY60XCNo9cSosOl1beNdNB/K5OkCNcYOa2AbiBY8XszQTCc+OU8tj7Ti8LGLZTW2vGD1QdVmqEPhtSQzRvcjbcRPoqXy/4duhN5V6QQ/O57hEF/6m3lXbCzNUDTqBw14Q3+WyLBR8npVwG7LXTCPuTtgv8Pk1ZBqY1UPf67xQu7WZN3EGWc9yuRKGkdetjZ09PJL7dcxctBkje3kQKmv7sdtCEo2DTugw38WN4beQA2hBKgqdUQVjfL+BbD48V+RnTdB4N0Hp7gw0gQdYsI14ZNe5wWhw98COi443dlVgKFl4jriVNM8aS1TQVOy15xyxA=
233 094a5fa3cf52f936e0de3f1e507c818bee5ece6b 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmLL1jYZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVn4gC/9Ls9JQEQrJPVfqp9+VicJIUUww/aKYWedlQJOlv4oEQJzYQQU9WfJq2d9OAuX2+cXCo7BC+NdjhjKjv7n0+gK0HuhfYYUoXiJvcfa4GSeEyxxnDf55lBCDxURstVrExU7c5OKiG+dPcsTPdvRdkpeAT/4gaewZ1cR0yZILNjpUeSWzQ7zhheXqfooyVkubdZY60XCNo9cSosOl1beNdNB/K5OkCNcYOa2AbiBY8XszQTCc+OU8tj7Ti8LGLZTW2vGD1QdVmqEPhtSQzRvcjbcRPoqXy/4duhN5V6QQ/O57hEF/6m3lXbCzNUDTqBw14Q3+WyLBR8npVwG7LXTCPuTtgv8Pk1ZBqY1UPf67xQu7WZN3EGWc9yuRKGkdetjZ09PJL7dcxctBkje3kQKmv7sdtCEo2DTugw38WN4beQA2hBKgqdUQVjfL+BbD48V+RnTdB4N0Hp7gw0gQdYsI14ZNe5wWhw98COi443dlVgKFl4jriVNM8aS1TQVOy15xyxA=
234 f69bffd00abe3a1b94d1032eb2c92e611d16a192 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmLifPsZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVukEC/oCa6AzaJlWh6G45Ap7BCWyB3EDWmcep07W8zRTfHQuuXslNFxRfj8O1DLVP05nDa1Uo2u1nkDxTH+x1fX0q4G8U/yLzCNsiBkCWSeEM8IeolarzzzvFe9Zk+UoRoRlc+vKAjxChtYTEnggQXjLdK+EdbXfEz2kJwdYlGX3lLr0Q2BKnBjSUvFe1Ma/1wxEjZIhDr6t7o8I/49QmPjK7RCYW1WBv77gnml0Oo8cxjDUR9cjqfeKtXKbMJiCsoXCS0hx3vJkBOzcs4ONEIw934is38qPNBBsaUjMrrqm0Mxs6yFricYqGVpmtNijsSRsfS7ZgNfaGaC2Bnu1E7P0A+AzPMPf/BP4uW9ixMbP1hNdr/6N41n19lkdjyQXVWGhB8RM+muf3jc6ZVvgZPMlxvFiz4/rP9nVOdrB96ssFZ9V2Ca/j2tU40AOgjI6sYsAR8pSSgmIdqe+DZQISHTT8D+4uVbtwYD49VklBcxudlbd3dAc5z9rVI3upsyByfRMROc=
234 f69bffd00abe3a1b94d1032eb2c92e611d16a192 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmLifPsZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVukEC/oCa6AzaJlWh6G45Ap7BCWyB3EDWmcep07W8zRTfHQuuXslNFxRfj8O1DLVP05nDa1Uo2u1nkDxTH+x1fX0q4G8U/yLzCNsiBkCWSeEM8IeolarzzzvFe9Zk+UoRoRlc+vKAjxChtYTEnggQXjLdK+EdbXfEz2kJwdYlGX3lLr0Q2BKnBjSUvFe1Ma/1wxEjZIhDr6t7o8I/49QmPjK7RCYW1WBv77gnml0Oo8cxjDUR9cjqfeKtXKbMJiCsoXCS0hx3vJkBOzcs4ONEIw934is38qPNBBsaUjMrrqm0Mxs6yFricYqGVpmtNijsSRsfS7ZgNfaGaC2Bnu1E7P0A+AzPMPf/BP4uW9ixMbP1hNdr/6N41n19lkdjyQXVWGhB8RM+muf3jc6ZVvgZPMlxvFiz4/rP9nVOdrB96ssFZ9V2Ca/j2tU40AOgjI6sYsAR8pSSgmIdqe+DZQISHTT8D+4uVbtwYD49VklBcxudlbd3dAc5z9rVI3upsyByfRMROc=
235 b5c8524827d20fe2e0ca8fb1234a0fe35a1a36c7 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmMQxRoZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVm2gC/9HikIaOE49euIoLj6ctYsJY9PSQK4Acw7BXvdsTVMmW27o87NxH75bGBbmPQ57X1iuKLCQ1RoU3p2Eh1gPbkIsouWO3enBIfsFmkPtWQz28zpCrI9CUXg2ug4PGFPN9XyxNmhJ7vJ4Cst2tRxz9PBKUBO2EXJN1UKIdMvurIeT2sQrDQf1ePc85QkXx79231wZyF98smnV7UYU9ZPFnAzfcuRzdFn7UmH3KKxHTZQ6wAevj/fJXf5NdTlqbeNmq/t75/nGKXSFPWtRGfFs8JHGkkLgBiTJVsHYSqcnKNdVldIFUoJP4c2/SPyoBkqNvoIrr73XRo8tdDF1iY4ddmhHMSmKgSRqLnIEgew3Apa/IwPdolg+lMsOtcjgz4CB9agJ+O0+rdZd2ZUBNMN0nBSUh+lrkMjat8TJAlvut9h/6HAe4Dz8WheoWol8f8t1jLOJvbdvsMYi+Hf9CZjp7PlHT9y/TnDarcw2YIrf6Bv+Fm14ZDelu9VlF2zR1X8cofY=
235 b5c8524827d20fe2e0ca8fb1234a0fe35a1a36c7 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmMQxRoZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVm2gC/9HikIaOE49euIoLj6ctYsJY9PSQK4Acw7BXvdsTVMmW27o87NxH75bGBbmPQ57X1iuKLCQ1RoU3p2Eh1gPbkIsouWO3enBIfsFmkPtWQz28zpCrI9CUXg2ug4PGFPN9XyxNmhJ7vJ4Cst2tRxz9PBKUBO2EXJN1UKIdMvurIeT2sQrDQf1ePc85QkXx79231wZyF98smnV7UYU9ZPFnAzfcuRzdFn7UmH3KKxHTZQ6wAevj/fJXf5NdTlqbeNmq/t75/nGKXSFPWtRGfFs8JHGkkLgBiTJVsHYSqcnKNdVldIFUoJP4c2/SPyoBkqNvoIrr73XRo8tdDF1iY4ddmhHMSmKgSRqLnIEgew3Apa/IwPdolg+lMsOtcjgz4CB9agJ+O0+rdZd2ZUBNMN0nBSUh+lrkMjat8TJAlvut9h/6HAe4Dz8WheoWol8f8t1jLOJvbdvsMYi+Hf9CZjp7PlHT9y/TnDarcw2YIrf6Bv+Fm14ZDelu9VlF2zR1X8cofY=
236 dbdee8ac3e3fcdda1fa55b90c0a235125b7f8e6f 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmM77dQZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZViOTC/sEPicecV3h3v47VAIUigyKNWpcJ+epbRRaH6gqHTkexvULOPL6nJrdfBHkNry1KRtOcjaxQvtWZM+TRCfqsE++Q3ZYakRpWKontb/8xQSbmENvbnElLh6k0STxN/JVc480us7viDG5pHS9DLsgbkHmdCv5KdmSE0hphRrWX+5X7RTqpAfCgdwTkacB5Geu9QfRnuYjz6lvqbs5ITKtBGUYbg3hKzw2894FHtMqV6qa5rk1ZMmVDbQfKQaMVG41UWNoN7bLESi69EmF4q5jsXdIbuBy0KtNXmB+gdAaHN03B5xtc+IsQZOTHEUNlMgov3yEVTcA6fSG9/Z+CMsdCbyQxqkwakbwWS1L2WcAsrkHyafvbNdR2FU34iYRWOck8IUg2Ffv7UFrHabJDy+nY7vcTLb0f7lV4jLXMWEt1hvXWMYek6Y4jtWahg6fjmAdD3Uf4BMfsTdnQKPvJpWXx303jnST3xvFvuqbbbDlhLfAB9M6kxVntvCVkMlMpe39+gM=
236 dbdee8ac3e3fcdda1fa55b90c0a235125b7f8e6f 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmM77dQZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZViOTC/sEPicecV3h3v47VAIUigyKNWpcJ+epbRRaH6gqHTkexvULOPL6nJrdfBHkNry1KRtOcjaxQvtWZM+TRCfqsE++Q3ZYakRpWKontb/8xQSbmENvbnElLh6k0STxN/JVc480us7viDG5pHS9DLsgbkHmdCv5KdmSE0hphRrWX+5X7RTqpAfCgdwTkacB5Geu9QfRnuYjz6lvqbs5ITKtBGUYbg3hKzw2894FHtMqV6qa5rk1ZMmVDbQfKQaMVG41UWNoN7bLESi69EmF4q5jsXdIbuBy0KtNXmB+gdAaHN03B5xtc+IsQZOTHEUNlMgov3yEVTcA6fSG9/Z+CMsdCbyQxqkwakbwWS1L2WcAsrkHyafvbNdR2FU34iYRWOck8IUg2Ffv7UFrHabJDy+nY7vcTLb0f7lV4jLXMWEt1hvXWMYek6Y4jtWahg6fjmAdD3Uf4BMfsTdnQKPvJpWXx303jnST3xvFvuqbbbDlhLfAB9M6kxVntvCVkMlMpe39+gM=
237 a3356ab610fc50000cf0ba55c424a4d96da11db7 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmNWr44ZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVjalC/9ddIeZ1qc3ykUZb+vKw+rZ6WS0rnDgrfFYBQFooK106lB+IC2PlghXSrY2hXn/7Dk95bK90S9AO4TFidDPiRYuBYdXR+G+CzmYFtCQzGBgGyrWgpUYsZUeA3VNqZ+Zbwn/vRNiFVNDsrFudjE6xEwaYdepmoXJsv3NdgZME7T0ZcDIujIa7ihiXvGFPVzMyF/VZg4QvdmerC4pvkeKC3KRNjhBkMQbf0GtQ4kpgMFBj5bmgXbq9rftL5yYy+rDiRQ0qzpOMHbdxvSZjPhK/do5M3rt2cjPxtF+7R3AHxQ6plOf0G89BONYebopY92OIyA3Qg9d/zIKDmibhgyxj4G9YU3+38gPEpsNeEw0fkyxhQbCY3QpNX4JGFaxq5GVCUywvVIuqoiOcQeXlTDN70zhAQHUx0rcGe1Lc6I+rT6Y2lNjJIdiCiMAWIl0D+4SVrLqdMYdSMXcBajTxOudb9KZnu03zNMXuLb8FFk1lFzkY7AcWA++d02f15P3sVZsDXE=
238 04f1dba53c961dfdb875c8469adc96fa999cfbed 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmNyC5sZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVqF+C/4uLaV/4nizZkWD3PjU1WyFYDg4bWDFOHb+PWuQ/3uoHXu1/EaYRnqmcDyOSJ99aXZBQ78rm9xhjxdmbklZ4ll1EGkqfTiYH+ld+rqE8iaqlc/DVy7pFXaenYwxletzO1OezzwF4XDLi6hcqzY9CXA3NM40vf6W4Rs5bEIi4eSbgJSNB1ll6ZzjvkU5bWTUoxSH+fxIJUuo27El2etdlKFQkS3/oTzWHejpVn6SQ1KyojTHMQBDRK4rqJBISp3gTf4TEezb0q0HTutJYDFdQNIRqx7V1Ao4Ei+YNbenJzcWJOA/2uk4V0AvZ4tnjgAzBYKwvIL1HfoQ0OmILeXjlVzV7Xu0G57lavum0sKkz/KZLKyYhKQHjYQLE7YMSM2y6/UEoFNN577vB47CHUq446PSMb8dGs2rmj66rj4iz5ml0yX+V9O2PpmIKoPAu1Y5/6zB9rCL76MRx182IW2m3rm4lsTfXPBPtea/OFt6ylxqCJRxaA0pht4FiAOvicPKXh4=
@@ -1,249 +1,251 b''
1 d40cc5aacc31ed673d9b5b24f98bee78c283062c 0.4f
1 d40cc5aacc31ed673d9b5b24f98bee78c283062c 0.4f
2 1c590d34bf61e2ea12c71738e5a746cd74586157 0.4e
2 1c590d34bf61e2ea12c71738e5a746cd74586157 0.4e
3 7eca4cfa8aad5fce9a04f7d8acadcd0452e2f34e 0.4d
3 7eca4cfa8aad5fce9a04f7d8acadcd0452e2f34e 0.4d
4 b4d0c3786ad3e47beacf8412157326a32b6d25a4 0.4c
4 b4d0c3786ad3e47beacf8412157326a32b6d25a4 0.4c
5 f40273b0ad7b3a6d3012fd37736d0611f41ecf54 0.5
5 f40273b0ad7b3a6d3012fd37736d0611f41ecf54 0.5
6 0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 0.5b
6 0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 0.5b
7 12e0fdbc57a0be78f0e817fd1d170a3615cd35da 0.6
7 12e0fdbc57a0be78f0e817fd1d170a3615cd35da 0.6
8 4ccf3de52989b14c3d84e1097f59e39a992e00bd 0.6b
8 4ccf3de52989b14c3d84e1097f59e39a992e00bd 0.6b
9 eac9c8efcd9bd8244e72fb6821f769f450457a32 0.6c
9 eac9c8efcd9bd8244e72fb6821f769f450457a32 0.6c
10 979c049974485125e1f9357f6bbe9c1b548a64c3 0.7
10 979c049974485125e1f9357f6bbe9c1b548a64c3 0.7
11 3a56574f329a368d645853e0f9e09472aee62349 0.8
11 3a56574f329a368d645853e0f9e09472aee62349 0.8
12 6a03cff2b0f5d30281e6addefe96b993582f2eac 0.8.1
12 6a03cff2b0f5d30281e6addefe96b993582f2eac 0.8.1
13 35fb62a3a673d5322f6274a44ba6456e5e4b3b37 0.9
13 35fb62a3a673d5322f6274a44ba6456e5e4b3b37 0.9
14 2be3001847cb18a23c403439d9e7d0ace30804e9 0.9.1
14 2be3001847cb18a23c403439d9e7d0ace30804e9 0.9.1
15 36a957364b1b89c150f2d0e60a99befe0ee08bd3 0.9.2
15 36a957364b1b89c150f2d0e60a99befe0ee08bd3 0.9.2
16 27230c29bfec36d5540fbe1c976810aefecfd1d2 0.9.3
16 27230c29bfec36d5540fbe1c976810aefecfd1d2 0.9.3
17 fb4b6d5fe100b0886f8bc3d6731ec0e5ed5c4694 0.9.4
17 fb4b6d5fe100b0886f8bc3d6731ec0e5ed5c4694 0.9.4
18 23889160905a1b09fffe1c07378e9fc1827606eb 0.9.5
18 23889160905a1b09fffe1c07378e9fc1827606eb 0.9.5
19 bae2e9c838e90a393bae3973a7850280413e091a 1.0
19 bae2e9c838e90a393bae3973a7850280413e091a 1.0
20 d5cbbe2c49cee22a9fbeb9ea41daa0ac4e26b846 1.0.1
20 d5cbbe2c49cee22a9fbeb9ea41daa0ac4e26b846 1.0.1
21 d2375bbee6d47e62ba8e415c86e83a465dc4dce9 1.0.2
21 d2375bbee6d47e62ba8e415c86e83a465dc4dce9 1.0.2
22 2a67430f92f15ea5159c26b09ec4839a0c549a26 1.1
22 2a67430f92f15ea5159c26b09ec4839a0c549a26 1.1
23 3773e510d433969e277b1863c317b674cbee2065 1.1.1
23 3773e510d433969e277b1863c317b674cbee2065 1.1.1
24 11a4eb81fb4f4742451591489e2797dc47903277 1.1.2
24 11a4eb81fb4f4742451591489e2797dc47903277 1.1.2
25 11efa41037e280d08cfb07c09ad485df30fb0ea8 1.2
25 11efa41037e280d08cfb07c09ad485df30fb0ea8 1.2
26 02981000012e3adf40c4849bd7b3d5618f9ce82d 1.2.1
26 02981000012e3adf40c4849bd7b3d5618f9ce82d 1.2.1
27 196d40e7c885fa6e95f89134809b3ec7bdbca34b 1.3
27 196d40e7c885fa6e95f89134809b3ec7bdbca34b 1.3
28 3ef6c14a1e8e83a31226f5881b7fe6095bbfa6f6 1.3.1
28 3ef6c14a1e8e83a31226f5881b7fe6095bbfa6f6 1.3.1
29 31ec469f9b556f11819937cf68ee53f2be927ebf 1.4
29 31ec469f9b556f11819937cf68ee53f2be927ebf 1.4
30 439d7ea6fe3aa4ab9ec274a68846779153789de9 1.4.1
30 439d7ea6fe3aa4ab9ec274a68846779153789de9 1.4.1
31 296a0b14a68621f6990c54fdba0083f6f20935bf 1.4.2
31 296a0b14a68621f6990c54fdba0083f6f20935bf 1.4.2
32 4aa619c4c2c09907034d9824ebb1dd0e878206eb 1.4.3
32 4aa619c4c2c09907034d9824ebb1dd0e878206eb 1.4.3
33 ff2704a8ded37fbebd8b6eb5ec733731d725da8a 1.5
33 ff2704a8ded37fbebd8b6eb5ec733731d725da8a 1.5
34 2b01dab594167bc0dd33331dbaa6dca3dca1b3aa 1.5.1
34 2b01dab594167bc0dd33331dbaa6dca3dca1b3aa 1.5.1
35 39f725929f0c48c5fb3b90c071fc3066012456ca 1.5.2
35 39f725929f0c48c5fb3b90c071fc3066012456ca 1.5.2
36 fdcf80f26604f233dc4d8f0a5ef9d7470e317e8a 1.5.3
36 fdcf80f26604f233dc4d8f0a5ef9d7470e317e8a 1.5.3
37 24fe2629c6fd0c74c90bd066e77387c2b02e8437 1.5.4
37 24fe2629c6fd0c74c90bd066e77387c2b02e8437 1.5.4
38 f786fc4b8764cd2a5526d259cf2f94d8a66924d9 1.6
38 f786fc4b8764cd2a5526d259cf2f94d8a66924d9 1.6
39 bf1774d95bde614af3956d92b20e2a0c68c5fec7 1.6.1
39 bf1774d95bde614af3956d92b20e2a0c68c5fec7 1.6.1
40 c00f03a4982e467fb6b6bd45908767db6df4771d 1.6.2
40 c00f03a4982e467fb6b6bd45908767db6df4771d 1.6.2
41 ff5cec76b1c5b6be9c3bb923aae8c3c6d079d6b9 1.6.3
41 ff5cec76b1c5b6be9c3bb923aae8c3c6d079d6b9 1.6.3
42 93d8bff78c96fe7e33237b257558ee97290048a4 1.6.4
42 93d8bff78c96fe7e33237b257558ee97290048a4 1.6.4
43 333421b9e0f96c7bc788e5667c146a58a9440a55 1.7
43 333421b9e0f96c7bc788e5667c146a58a9440a55 1.7
44 4438875ec01bd0fc32be92b0872eb6daeed4d44f 1.7.1
44 4438875ec01bd0fc32be92b0872eb6daeed4d44f 1.7.1
45 6aff4f144ad356311318b0011df0bb21f2c97429 1.7.2
45 6aff4f144ad356311318b0011df0bb21f2c97429 1.7.2
46 e3bf16703e2601de99e563cdb3a5d50b64e6d320 1.7.3
46 e3bf16703e2601de99e563cdb3a5d50b64e6d320 1.7.3
47 a6c855c32ea081da3c3b8ff628f1847ff271482f 1.7.4
47 a6c855c32ea081da3c3b8ff628f1847ff271482f 1.7.4
48 2b2155623ee2559caf288fd333f30475966c4525 1.7.5
48 2b2155623ee2559caf288fd333f30475966c4525 1.7.5
49 2616325766e3504c8ae7c84bd15ee610901fe91d 1.8
49 2616325766e3504c8ae7c84bd15ee610901fe91d 1.8
50 aa1f3be38ab127280761889d2dca906ca465b5f4 1.8.1
50 aa1f3be38ab127280761889d2dca906ca465b5f4 1.8.1
51 b032bec2c0a651ca0ddecb65714bfe6770f67d70 1.8.2
51 b032bec2c0a651ca0ddecb65714bfe6770f67d70 1.8.2
52 3cb1e95676ad089596bd81d0937cad37d6e3b7fb 1.8.3
52 3cb1e95676ad089596bd81d0937cad37d6e3b7fb 1.8.3
53 733af5d9f6b22387913e1d11350fb8cb7c1487dd 1.8.4
53 733af5d9f6b22387913e1d11350fb8cb7c1487dd 1.8.4
54 de9eb6b1da4fc522b1cab16d86ca166204c24f25 1.9
54 de9eb6b1da4fc522b1cab16d86ca166204c24f25 1.9
55 4a43e23b8c55b4566b8200bf69fe2158485a2634 1.9.1
55 4a43e23b8c55b4566b8200bf69fe2158485a2634 1.9.1
56 d629f1e89021103f1753addcef6b310e4435b184 1.9.2
56 d629f1e89021103f1753addcef6b310e4435b184 1.9.2
57 351a9292e430e35766c552066ed3e87c557b803b 1.9.3
57 351a9292e430e35766c552066ed3e87c557b803b 1.9.3
58 384082750f2c51dc917d85a7145748330fa6ef4d 2.0-rc
58 384082750f2c51dc917d85a7145748330fa6ef4d 2.0-rc
59 41453d55b481ddfcc1dacb445179649e24ca861d 2.0
59 41453d55b481ddfcc1dacb445179649e24ca861d 2.0
60 195dbd1cef0c2f9f8bcf4ea303238105f716bda3 2.0.1
60 195dbd1cef0c2f9f8bcf4ea303238105f716bda3 2.0.1
61 6344043924497cd06d781d9014c66802285072e4 2.0.2
61 6344043924497cd06d781d9014c66802285072e4 2.0.2
62 db33555eafeaf9df1e18950e29439eaa706d399b 2.1-rc
62 db33555eafeaf9df1e18950e29439eaa706d399b 2.1-rc
63 2aa5b51f310fb3befd26bed99c02267f5c12c734 2.1
63 2aa5b51f310fb3befd26bed99c02267f5c12c734 2.1
64 53e2cd303ecf8ca7c7eeebd785c34e5ed6b0f4a4 2.1.1
64 53e2cd303ecf8ca7c7eeebd785c34e5ed6b0f4a4 2.1.1
65 b9bd95e61b49c221c4cca24e6da7c946fc02f992 2.1.2
65 b9bd95e61b49c221c4cca24e6da7c946fc02f992 2.1.2
66 d9e2f09d5488c395ae9ddbb320ceacd24757e055 2.2-rc
66 d9e2f09d5488c395ae9ddbb320ceacd24757e055 2.2-rc
67 00182b3d087909e3c3ae44761efecdde8f319ef3 2.2
67 00182b3d087909e3c3ae44761efecdde8f319ef3 2.2
68 5983de86462c5a9f42a3ad0f5e90ce5b1d221d25 2.2.1
68 5983de86462c5a9f42a3ad0f5e90ce5b1d221d25 2.2.1
69 85a358df5bbbe404ca25730c9c459b34263441dc 2.2.2
69 85a358df5bbbe404ca25730c9c459b34263441dc 2.2.2
70 b013baa3898e117959984fc64c29d8c784d2f28b 2.2.3
70 b013baa3898e117959984fc64c29d8c784d2f28b 2.2.3
71 a06e2681dd1786e2354d84a5fa9c1c88dd4fa3e0 2.3-rc
71 a06e2681dd1786e2354d84a5fa9c1c88dd4fa3e0 2.3-rc
72 7f5094bb3f423fc799e471aac2aee81a7ce57a0b 2.3
72 7f5094bb3f423fc799e471aac2aee81a7ce57a0b 2.3
73 072209ae4ddb654eb2d5fd35bff358c738414432 2.3.1
73 072209ae4ddb654eb2d5fd35bff358c738414432 2.3.1
74 b3f0f9a39c4e1d0250048cd803ab03542d6f140a 2.3.2
74 b3f0f9a39c4e1d0250048cd803ab03542d6f140a 2.3.2
75 d118a4f4fd16d9b558ec3f3e87bfee772861d2b7 2.4-rc
75 d118a4f4fd16d9b558ec3f3e87bfee772861d2b7 2.4-rc
76 195ad823b5d58c68903a6153a25e3fb4ed25239d 2.4
76 195ad823b5d58c68903a6153a25e3fb4ed25239d 2.4
77 0c10cf8191469e7c3c8844922e17e71a176cb7cb 2.4.1
77 0c10cf8191469e7c3c8844922e17e71a176cb7cb 2.4.1
78 a4765077b65e6ae29ba42bab7834717b5072d5ba 2.4.2
78 a4765077b65e6ae29ba42bab7834717b5072d5ba 2.4.2
79 f5fbe15ca7449f2c9a3cf817c86d0ae68b307214 2.5-rc
79 f5fbe15ca7449f2c9a3cf817c86d0ae68b307214 2.5-rc
80 a6088c05e43a8aee0472ca3a4f6f8d7dd914ebbf 2.5
80 a6088c05e43a8aee0472ca3a4f6f8d7dd914ebbf 2.5
81 7511d4df752e61fe7ae4f3682e0a0008573b0402 2.5.1
81 7511d4df752e61fe7ae4f3682e0a0008573b0402 2.5.1
82 5b7175377babacce80a6c1e12366d8032a6d4340 2.5.2
82 5b7175377babacce80a6c1e12366d8032a6d4340 2.5.2
83 50c922c1b5145dab8baefefb0437d363b6a6c21c 2.5.3
83 50c922c1b5145dab8baefefb0437d363b6a6c21c 2.5.3
84 8a7bd2dccd44ed571afe7424cd7f95594f27c092 2.5.4
84 8a7bd2dccd44ed571afe7424cd7f95594f27c092 2.5.4
85 292cd385856d98bacb2c3086f8897bc660c2beea 2.6-rc
85 292cd385856d98bacb2c3086f8897bc660c2beea 2.6-rc
86 23f785b38af38d2fca6b8f3db56b8007a84cd73a 2.6
86 23f785b38af38d2fca6b8f3db56b8007a84cd73a 2.6
87 ddc7a6be20212d18f3e27d9d7e6f079a66d96f21 2.6.1
87 ddc7a6be20212d18f3e27d9d7e6f079a66d96f21 2.6.1
88 cceaf7af4c9e9e6fa2dbfdcfe9856c5da69c4ffd 2.6.2
88 cceaf7af4c9e9e6fa2dbfdcfe9856c5da69c4ffd 2.6.2
89 009794acc6e37a650f0fae37872e733382ac1c0c 2.6.3
89 009794acc6e37a650f0fae37872e733382ac1c0c 2.6.3
90 f0d7721d7322dcfb5af33599c2543f27335334bb 2.7-rc
90 f0d7721d7322dcfb5af33599c2543f27335334bb 2.7-rc
91 f37b5a17e6a0ee17afde2cdde5393dd74715fb58 2.7
91 f37b5a17e6a0ee17afde2cdde5393dd74715fb58 2.7
92 335a558f81dc73afeab4d7be63617392b130117f 2.7.1
92 335a558f81dc73afeab4d7be63617392b130117f 2.7.1
93 e7fa36d2ad3a7944a52dca126458d6f482db3524 2.7.2
93 e7fa36d2ad3a7944a52dca126458d6f482db3524 2.7.2
94 1596f2d8f2421314b1ddead8f7d0c91009358994 2.8-rc
94 1596f2d8f2421314b1ddead8f7d0c91009358994 2.8-rc
95 d825e4025e39d1c39db943cdc89818abd0a87c27 2.8
95 d825e4025e39d1c39db943cdc89818abd0a87c27 2.8
96 209e04a06467e2969c0cc6501335be0406d46ef0 2.8.1
96 209e04a06467e2969c0cc6501335be0406d46ef0 2.8.1
97 ca387377df7a3a67dbb90b6336b781cdadc3ef41 2.8.2
97 ca387377df7a3a67dbb90b6336b781cdadc3ef41 2.8.2
98 8862469e16f9236208581b20de5f96bd13cc039d 2.9-rc
98 8862469e16f9236208581b20de5f96bd13cc039d 2.9-rc
99 3cec5134e9c4bceab6a00c60f52a4f80677a78f2 2.9
99 3cec5134e9c4bceab6a00c60f52a4f80677a78f2 2.9
100 b96cb15ec9e04d8ac5ee08b34fcbbe4200588965 2.9.1
100 b96cb15ec9e04d8ac5ee08b34fcbbe4200588965 2.9.1
101 3f83fc5cfe715d292069ee8417c83804f6c6c1e4 2.9.2
101 3f83fc5cfe715d292069ee8417c83804f6c6c1e4 2.9.2
102 564f55b251224f16508dd1311452db7780dafe2b 3.0-rc
102 564f55b251224f16508dd1311452db7780dafe2b 3.0-rc
103 2195ac506c6ababe86985b932f4948837c0891b5 3.0
103 2195ac506c6ababe86985b932f4948837c0891b5 3.0
104 269c80ee5b3cb3684fa8edc61501b3506d02eb10 3.0.1
104 269c80ee5b3cb3684fa8edc61501b3506d02eb10 3.0.1
105 2d8cd3d0e83c7336c0cb45a9f88638363f993848 3.0.2
105 2d8cd3d0e83c7336c0cb45a9f88638363f993848 3.0.2
106 6c36dc6cd61a0e1b563f1d51e55bdf4dacf12162 3.1-rc
106 6c36dc6cd61a0e1b563f1d51e55bdf4dacf12162 3.1-rc
107 3178e49892020336491cdc6945885c4de26ffa8b 3.1
107 3178e49892020336491cdc6945885c4de26ffa8b 3.1
108 5dc91146f35369949ea56b40172308158b59063a 3.1.1
108 5dc91146f35369949ea56b40172308158b59063a 3.1.1
109 f768c888aaa68d12dd7f509dcc7f01c9584357d0 3.1.2
109 f768c888aaa68d12dd7f509dcc7f01c9584357d0 3.1.2
110 7f8d16af8cae246fa5a48e723d48d58b015aed94 3.2-rc
110 7f8d16af8cae246fa5a48e723d48d58b015aed94 3.2-rc
111 ced632394371a36953ce4d394f86278ae51a2aae 3.2
111 ced632394371a36953ce4d394f86278ae51a2aae 3.2
112 643c58303fb0ec020907af28b9e486be299ba043 3.2.1
112 643c58303fb0ec020907af28b9e486be299ba043 3.2.1
113 902554884335e5ca3661d63be9978eb4aec3f68a 3.2.2
113 902554884335e5ca3661d63be9978eb4aec3f68a 3.2.2
114 6dad422ecc5adb63d9fa649eeb8e05a5f9bc4900 3.2.3
114 6dad422ecc5adb63d9fa649eeb8e05a5f9bc4900 3.2.3
115 1265a3a71d75396f5d4cf6935ae7d9ba5407a547 3.2.4
115 1265a3a71d75396f5d4cf6935ae7d9ba5407a547 3.2.4
116 db8e3f7948b1fdeb9ad12d448fc3525759908b9f 3.3-rc
116 db8e3f7948b1fdeb9ad12d448fc3525759908b9f 3.3-rc
117 fbdd5195528fae4f41feebc1838215c110b25d6a 3.3
117 fbdd5195528fae4f41feebc1838215c110b25d6a 3.3
118 5b4ed033390bf6e2879c8f5c28c84e1ee3b87231 3.3.1
118 5b4ed033390bf6e2879c8f5c28c84e1ee3b87231 3.3.1
119 07a92bbd02e5e3a625e0820389b47786b02b2cea 3.3.2
119 07a92bbd02e5e3a625e0820389b47786b02b2cea 3.3.2
120 2e2e9a0750f91a6fe0ad88e4de34f8efefdcab08 3.3.3
120 2e2e9a0750f91a6fe0ad88e4de34f8efefdcab08 3.3.3
121 e89f909edffad558b56f4affa8239e4832f88de0 3.4-rc
121 e89f909edffad558b56f4affa8239e4832f88de0 3.4-rc
122 8cc6036bca532e06681c5a8fa37efaa812de67b5 3.4
122 8cc6036bca532e06681c5a8fa37efaa812de67b5 3.4
123 ed18f4acf435a2824c6f49fba40f42b9df5da7ad 3.4.1
123 ed18f4acf435a2824c6f49fba40f42b9df5da7ad 3.4.1
124 540cd0ddac49c1125b2e013aa2ff18ecbd4dd954 3.4.2
124 540cd0ddac49c1125b2e013aa2ff18ecbd4dd954 3.4.2
125 96a38d44ba093bd1d1ecfd34119e94056030278b 3.5-rc
125 96a38d44ba093bd1d1ecfd34119e94056030278b 3.5-rc
126 21aa1c313b05b1a85f8ffa1120d51579ddf6bf24 3.5
126 21aa1c313b05b1a85f8ffa1120d51579ddf6bf24 3.5
127 1a45e49a6bed023deb229102a8903234d18054d3 3.5.1
127 1a45e49a6bed023deb229102a8903234d18054d3 3.5.1
128 9a466b9f9792e3ad7ae3fc6c43c3ff2e136b718d 3.5.2
128 9a466b9f9792e3ad7ae3fc6c43c3ff2e136b718d 3.5.2
129 b66e3ca0b90c3095ea28dfd39aa24247bebf5c20 3.6-rc
129 b66e3ca0b90c3095ea28dfd39aa24247bebf5c20 3.6-rc
130 47dd34f2e7272be9e3b2a5a83cd0d20be44293f4 3.6
130 47dd34f2e7272be9e3b2a5a83cd0d20be44293f4 3.6
131 1aa5083cbebbe7575c88f3402ab377539b484897 3.6.1
131 1aa5083cbebbe7575c88f3402ab377539b484897 3.6.1
132 2d437a0f3355834a9485bbbeb30a52a052c98f19 3.6.2
132 2d437a0f3355834a9485bbbeb30a52a052c98f19 3.6.2
133 ea389970c08449440587712117f178d33bab3f1e 3.6.3
133 ea389970c08449440587712117f178d33bab3f1e 3.6.3
134 158bdc8965720ca4061f8f8d806563cfc7cdb62e 3.7-rc
134 158bdc8965720ca4061f8f8d806563cfc7cdb62e 3.7-rc
135 2408645de650d8a29a6ce9e7dce601d8dd0d1474 3.7
135 2408645de650d8a29a6ce9e7dce601d8dd0d1474 3.7
136 b698abf971e7377d9b7ec7fc8c52df45255b0329 3.7.1
136 b698abf971e7377d9b7ec7fc8c52df45255b0329 3.7.1
137 d493d64757eb45ada99fcb3693e479a51b7782da 3.7.2
137 d493d64757eb45ada99fcb3693e479a51b7782da 3.7.2
138 ae279d4a19e9683214cbd1fe8298cf0b50571432 3.7.3
138 ae279d4a19e9683214cbd1fe8298cf0b50571432 3.7.3
139 740156eedf2c450aee58b1a90b0e826f47c5da64 3.8-rc
139 740156eedf2c450aee58b1a90b0e826f47c5da64 3.8-rc
140 f85de28eae32e7d3064b1a1321309071bbaaa069 3.8
140 f85de28eae32e7d3064b1a1321309071bbaaa069 3.8
141 a56296f55a5e1038ea5016dace2076b693c28a56 3.8.1
141 a56296f55a5e1038ea5016dace2076b693c28a56 3.8.1
142 aaabed77791a75968a12b8c43ad263631a23ee81 3.8.2
142 aaabed77791a75968a12b8c43ad263631a23ee81 3.8.2
143 a9764ab80e11bcf6a37255db7dd079011f767c6c 3.8.3
143 a9764ab80e11bcf6a37255db7dd079011f767c6c 3.8.3
144 26a5d605b8683a292bb89aea11f37a81b06ac016 3.8.4
144 26a5d605b8683a292bb89aea11f37a81b06ac016 3.8.4
145 519bb4f9d3a47a6e83c2b414d58811ed38f503c2 3.9-rc
145 519bb4f9d3a47a6e83c2b414d58811ed38f503c2 3.9-rc
146 299546f84e68dbb9bd026f0f3a974ce4bdb93686 3.9
146 299546f84e68dbb9bd026f0f3a974ce4bdb93686 3.9
147 ccd436f7db6d5d7b9af89715179b911d031d44f1 3.9.1
147 ccd436f7db6d5d7b9af89715179b911d031d44f1 3.9.1
148 149433e68974eb5c63ccb03f794d8b57339a80c4 3.9.2
148 149433e68974eb5c63ccb03f794d8b57339a80c4 3.9.2
149 438173c415874f6ac653efc1099dec9c9150e90f 4.0-rc
149 438173c415874f6ac653efc1099dec9c9150e90f 4.0-rc
150 eab27446995210c334c3d06f1a659e3b9b5da769 4.0
150 eab27446995210c334c3d06f1a659e3b9b5da769 4.0
151 b3b1ae98f6a0e14c1e1ba806a6c18e193b6dae5c 4.0.1
151 b3b1ae98f6a0e14c1e1ba806a6c18e193b6dae5c 4.0.1
152 e69874dc1f4e142746ff3df91e678a09c6fc208c 4.0.2
152 e69874dc1f4e142746ff3df91e678a09c6fc208c 4.0.2
153 a1dd2c0c479e0550040542e392e87bc91262517e 4.1-rc
153 a1dd2c0c479e0550040542e392e87bc91262517e 4.1-rc
154 e1526da1e6d84e03146151c9b6e6950fe9a83d7d 4.1
154 e1526da1e6d84e03146151c9b6e6950fe9a83d7d 4.1
155 25703b624d27e3917d978af56d6ad59331e0464a 4.1.1
155 25703b624d27e3917d978af56d6ad59331e0464a 4.1.1
156 ed5b25874d998ababb181a939dd37a16ea644435 4.1.2
156 ed5b25874d998ababb181a939dd37a16ea644435 4.1.2
157 77eaf9539499a1b8be259ffe7ada787d07857f80 4.1.3
157 77eaf9539499a1b8be259ffe7ada787d07857f80 4.1.3
158 616e788321cc4ae9975b7f0c54c849f36d82182b 4.2-rc
158 616e788321cc4ae9975b7f0c54c849f36d82182b 4.2-rc
159 bb96d4a497432722623ae60d9bc734a1e360179e 4.2
159 bb96d4a497432722623ae60d9bc734a1e360179e 4.2
160 c850f0ed54c1d42f9aa079ad528f8127e5775217 4.2.1
160 c850f0ed54c1d42f9aa079ad528f8127e5775217 4.2.1
161 26c49ed51a698ec016d2b4c6b44ca3c3f73cc788 4.2.2
161 26c49ed51a698ec016d2b4c6b44ca3c3f73cc788 4.2.2
162 857876ebaed4e315f63157bd157d6ce553c7ab73 4.3-rc
162 857876ebaed4e315f63157bd157d6ce553c7ab73 4.3-rc
163 5544af8622863796a0027566f6b646e10d522c4c 4.3
163 5544af8622863796a0027566f6b646e10d522c4c 4.3
164 943c91326b23954e6e1c6960d0239511f9530258 4.2.3
164 943c91326b23954e6e1c6960d0239511f9530258 4.2.3
165 3fee7f7d2da04226914c2258cc2884dc27384fd7 4.3.1
165 3fee7f7d2da04226914c2258cc2884dc27384fd7 4.3.1
166 920977f72c7b70acfdaf56ab35360584d7845827 4.3.2
166 920977f72c7b70acfdaf56ab35360584d7845827 4.3.2
167 2f427b57bf9019c6dc3750baa539dc22c1be50f6 4.3.3
167 2f427b57bf9019c6dc3750baa539dc22c1be50f6 4.3.3
168 1e2454b60e5936f5e77498cab2648db469504487 4.4-rc
168 1e2454b60e5936f5e77498cab2648db469504487 4.4-rc
169 0ccb43d4cf01d013ae05917ec4f305509f851b2d 4.4
169 0ccb43d4cf01d013ae05917ec4f305509f851b2d 4.4
170 cabc840ffdee8a72f3689fb77dd74d04fdc2bc04 4.4.1
170 cabc840ffdee8a72f3689fb77dd74d04fdc2bc04 4.4.1
171 a92b9f8e11ba330614cdfd6af0e03b15c1ff3797 4.4.2
171 a92b9f8e11ba330614cdfd6af0e03b15c1ff3797 4.4.2
172 27b6df1b5adbdf647cf5c6675b40575e1b197c60 4.5-rc
172 27b6df1b5adbdf647cf5c6675b40575e1b197c60 4.5-rc
173 d334afc585e29577f271c5eda03378736a16ca6b 4.5
173 d334afc585e29577f271c5eda03378736a16ca6b 4.5
174 369aadf7a3264b03c8b09efce715bc41e6ab4a9b 4.5.1
174 369aadf7a3264b03c8b09efce715bc41e6ab4a9b 4.5.1
175 8bba684efde7f45add05f737952093bb2aa07155 4.5.2
175 8bba684efde7f45add05f737952093bb2aa07155 4.5.2
176 7de7bd407251af2bc98e5b809c8598ee95830daf 4.5.3
176 7de7bd407251af2bc98e5b809c8598ee95830daf 4.5.3
177 ed5448edcbfa747b9154099e18630e49024fd47b 4.6rc0
177 ed5448edcbfa747b9154099e18630e49024fd47b 4.6rc0
178 1ec874717d8a93b19e0d50628443e0ee5efab3a9 4.6rc1
178 1ec874717d8a93b19e0d50628443e0ee5efab3a9 4.6rc1
179 6614cac550aea66d19c601e45efd1b7bd08d7c40 4.6
179 6614cac550aea66d19c601e45efd1b7bd08d7c40 4.6
180 9c5ced5276d6e7d54f7c3dadf5247b7ee98ec79c 4.6.1
180 9c5ced5276d6e7d54f7c3dadf5247b7ee98ec79c 4.6.1
181 0b63a6743010dfdbf8a8154186e119949bdaa1cc 4.6.2
181 0b63a6743010dfdbf8a8154186e119949bdaa1cc 4.6.2
182 e90130af47ce8dd53a3109aed9d15876b3e7dee8 4.7rc0
182 e90130af47ce8dd53a3109aed9d15876b3e7dee8 4.7rc0
183 33ac6a72308a215e6086fbced347ec10aa963b0a 4.7
183 33ac6a72308a215e6086fbced347ec10aa963b0a 4.7
184 ede3bf31fe63677fdf5bd8db687977d4e3d792ed 4.7.1
184 ede3bf31fe63677fdf5bd8db687977d4e3d792ed 4.7.1
185 5405cb1a79010ac50c58cd84e6f50c4556bf2a4c 4.7.2
185 5405cb1a79010ac50c58cd84e6f50c4556bf2a4c 4.7.2
186 956ec6f1320df26f3133ec40f3de866ea0695fd7 4.8rc0
186 956ec6f1320df26f3133ec40f3de866ea0695fd7 4.8rc0
187 a91a2837150bdcb27ae76b3646e6c93cd6a15904 4.8
187 a91a2837150bdcb27ae76b3646e6c93cd6a15904 4.8
188 1c8c54cf97256f4468da2eb4dbee24f7f3888e71 4.8.1
188 1c8c54cf97256f4468da2eb4dbee24f7f3888e71 4.8.1
189 197f092b2cd9691e2a55d198f717b231af9be6f9 4.8.2
189 197f092b2cd9691e2a55d198f717b231af9be6f9 4.8.2
190 593718ff5844cad7a27ee3eb5adad89ac8550949 4.9rc0
190 593718ff5844cad7a27ee3eb5adad89ac8550949 4.9rc0
191 83377b4b4ae0e9a6b8e579f7b0a693b8cf5c3b10 4.9
191 83377b4b4ae0e9a6b8e579f7b0a693b8cf5c3b10 4.9
192 4ea21df312ec7159c5b3633096b6ecf68750b0dd 4.9.1
192 4ea21df312ec7159c5b3633096b6ecf68750b0dd 4.9.1
193 4a8d9ed864754837a185a642170cde24392f9abf 5.0rc0
193 4a8d9ed864754837a185a642170cde24392f9abf 5.0rc0
194 07e479ef7c9639be0029f00e6a722b96dcc05fee 5.0
194 07e479ef7c9639be0029f00e6a722b96dcc05fee 5.0
195 c3484ddbdb9621256d597ed86b90d229c59c2af9 5.0.1
195 c3484ddbdb9621256d597ed86b90d229c59c2af9 5.0.1
196 97ada9b8d51bef24c5cb4cdca4243f0db694ab6e 5.0.2
196 97ada9b8d51bef24c5cb4cdca4243f0db694ab6e 5.0.2
197 e386b5f4f8360dbb43a576dd9b1368e386fefa5b 5.1rc0
197 e386b5f4f8360dbb43a576dd9b1368e386fefa5b 5.1rc0
198 e91930d712e8507d1bc1b2dffd96c83edc4cbed3 5.1
198 e91930d712e8507d1bc1b2dffd96c83edc4cbed3 5.1
199 a4e32fd539ab41489a51b2aa88bda9a73b839562 5.1.1
199 a4e32fd539ab41489a51b2aa88bda9a73b839562 5.1.1
200 181e52f2b62f4768aa0d988936c929dc7c4a41a0 5.1.2
200 181e52f2b62f4768aa0d988936c929dc7c4a41a0 5.1.2
201 59338f9561099de77c684c00f76507f11e46ebe8 5.2rc0
201 59338f9561099de77c684c00f76507f11e46ebe8 5.2rc0
202 ca3dca416f8d5863ca6f5a4a6a6bb835dcd5feeb 5.2
202 ca3dca416f8d5863ca6f5a4a6a6bb835dcd5feeb 5.2
203 a50fecefa691c9b72a99e49aa6fe9dd13943c2bf 5.2.1
203 a50fecefa691c9b72a99e49aa6fe9dd13943c2bf 5.2.1
204 b4c82b70418022e67cc0e69b1aa3c3aa43aa1d29 5.2.2
204 b4c82b70418022e67cc0e69b1aa3c3aa43aa1d29 5.2.2
205 84a0102c05c7852c8215ef6cf21d809927586b69 5.3rc0
205 84a0102c05c7852c8215ef6cf21d809927586b69 5.3rc0
206 e4344e463c0c888a2f437b78b5982ecdf3f6650a 5.3rc1
206 e4344e463c0c888a2f437b78b5982ecdf3f6650a 5.3rc1
207 7f5410dfc8a64bb587d19637deb95d378fd1eb5c 5.3
207 7f5410dfc8a64bb587d19637deb95d378fd1eb5c 5.3
208 6d121acbb82e65fe4dd3c2318a1b61981b958492 5.3.1
208 6d121acbb82e65fe4dd3c2318a1b61981b958492 5.3.1
209 8fca7e8449a847e3cf1054f2c07b51237699fad3 5.3.2
209 8fca7e8449a847e3cf1054f2c07b51237699fad3 5.3.2
210 26ce8e7515036d3431a03aaeb7bc72dd96cb1112 5.4rc0
210 26ce8e7515036d3431a03aaeb7bc72dd96cb1112 5.4rc0
211 cf3e07d7648a4371ce584d15dd692e7a6845792f 5.4
211 cf3e07d7648a4371ce584d15dd692e7a6845792f 5.4
212 065704cbdbdbb05dcd6bb814eb9bbdd982211b28 5.4.1
212 065704cbdbdbb05dcd6bb814eb9bbdd982211b28 5.4.1
213 0ea9c86fac8974cd74dc12ea681c8986eb6da6c4 5.4.2
213 0ea9c86fac8974cd74dc12ea681c8986eb6da6c4 5.4.2
214 28163c5de797e5416f9b588940f4608269b4d50a 5.5rc0
214 28163c5de797e5416f9b588940f4608269b4d50a 5.5rc0
215 7fc3c5fbc65f6fe85d70ea63923b8767dda4f2e0 5.5
215 7fc3c5fbc65f6fe85d70ea63923b8767dda4f2e0 5.5
216 f62bb5d07848ca598aa860a517394130b61bf2ee 5.5.1
216 f62bb5d07848ca598aa860a517394130b61bf2ee 5.5.1
217 07731064ac41dacdf0ec869ebd05c2e848c14fbf 5.5.2
217 07731064ac41dacdf0ec869ebd05c2e848c14fbf 5.5.2
218 0e06a7ab9e0d5c65af4e511aee1e0342998799df 5.6rc0
218 0e06a7ab9e0d5c65af4e511aee1e0342998799df 5.6rc0
219 18c17d63fdabd009e70bf994e5efb7db422f4f7f 5.6
219 18c17d63fdabd009e70bf994e5efb7db422f4f7f 5.6
220 1d5189a57405ceca5aa244052c9f948977f4699b 5.6.1
220 1d5189a57405ceca5aa244052c9f948977f4699b 5.6.1
221 9da65e3cf3706ff41e08b311381c588440c27baf 5.7rc0
221 9da65e3cf3706ff41e08b311381c588440c27baf 5.7rc0
222 0e2e7300f4302b02412b0b734717697049494c4c 5.7
222 0e2e7300f4302b02412b0b734717697049494c4c 5.7
223 d5d9177c0045d206db575bae6daa98e2cb2fe5bc 5.7.1
223 d5d9177c0045d206db575bae6daa98e2cb2fe5bc 5.7.1
224 f67b8946bb1b6cfa8328dbf8d6a9128b69ccdcb4 5.8rc0
224 f67b8946bb1b6cfa8328dbf8d6a9128b69ccdcb4 5.8rc0
225 8d2b62d716b095507effaa8d56f87cd27ba659ab 5.8rc1
225 8d2b62d716b095507effaa8d56f87cd27ba659ab 5.8rc1
226 067f2c53fb24506c9e9fb4639871b13b19a85f8a 5.8
226 067f2c53fb24506c9e9fb4639871b13b19a85f8a 5.8
227 411dc27fd9fd076d6a031a08fcaace659afe2fe3 5.8.1
227 411dc27fd9fd076d6a031a08fcaace659afe2fe3 5.8.1
228 d7515d29761d5ada7d9c765f517db67db75dea9a 5.9rc0
228 d7515d29761d5ada7d9c765f517db67db75dea9a 5.9rc0
229 2813d406b03607cdb8c06cb04c44efcc9a79d9a2 5.9rc1
229 2813d406b03607cdb8c06cb04c44efcc9a79d9a2 5.9rc1
230 53221078e0de65d1a821ce5311dec45a7a978301 5.9
230 53221078e0de65d1a821ce5311dec45a7a978301 5.9
231 86a60679cf619e14cee9442f865fcf31b142cb9f 5.9.1
231 86a60679cf619e14cee9442f865fcf31b142cb9f 5.9.1
232 750920b18aaaddd654756be40dec59d90f2643be 5.9.2
232 750920b18aaaddd654756be40dec59d90f2643be 5.9.2
233 6ee0244fc1cf889ae543d2ce0ec45201ae0be6e1 5.9.3
233 6ee0244fc1cf889ae543d2ce0ec45201ae0be6e1 5.9.3
234 a44bb185f6bdbecc754996d8386722e2f0123b0a 6.0rc0
234 a44bb185f6bdbecc754996d8386722e2f0123b0a 6.0rc0
235 5d08b289e2e526259d7d5ea32b70fe76d5b327d7 6.0
235 5d08b289e2e526259d7d5ea32b70fe76d5b327d7 6.0
236 799fdf4cca80cb9ae40537a90995e6bd163ebc0b 6.0.1
236 799fdf4cca80cb9ae40537a90995e6bd163ebc0b 6.0.1
237 75676122c2bf7594ac732b7388db4c74c648b365 6.0.2
237 75676122c2bf7594ac732b7388db4c74c648b365 6.0.2
238 dcec16e799ddb6d33fcd11b04af530250a417a58 6.0.3
238 dcec16e799ddb6d33fcd11b04af530250a417a58 6.0.3
239 c00d3ce4e94bb0ee8d809e25e1dcb2a5fab84e2c 6.1rc0
239 c00d3ce4e94bb0ee8d809e25e1dcb2a5fab84e2c 6.1rc0
240 d4486810a1795fba9521449b8885ced034f3a6dd 6.1
240 d4486810a1795fba9521449b8885ced034f3a6dd 6.1
241 5bd6bcd31dd1ebb63b8914b00064f96297267af7 6.1.1
241 5bd6bcd31dd1ebb63b8914b00064f96297267af7 6.1.1
242 0ddd5e1f5f67438af85d12e4ce6c39021dde9916 6.1.2
242 0ddd5e1f5f67438af85d12e4ce6c39021dde9916 6.1.2
243 6b10151b962108f65bfa12b3918b1021ca334f73 6.1.3
243 6b10151b962108f65bfa12b3918b1021ca334f73 6.1.3
244 0cc5f74ff7f0f4ac2427096bddbe102dbc2453ae 6.1.4
244 0cc5f74ff7f0f4ac2427096bddbe102dbc2453ae 6.1.4
245 288de6f5d724bba7bf1669e2838f196962bb7528 6.2rc0
245 288de6f5d724bba7bf1669e2838f196962bb7528 6.2rc0
246 094a5fa3cf52f936e0de3f1e507c818bee5ece6b 6.2
246 094a5fa3cf52f936e0de3f1e507c818bee5ece6b 6.2
247 f69bffd00abe3a1b94d1032eb2c92e611d16a192 6.2.1
247 f69bffd00abe3a1b94d1032eb2c92e611d16a192 6.2.1
248 b5c8524827d20fe2e0ca8fb1234a0fe35a1a36c7 6.2.2
248 b5c8524827d20fe2e0ca8fb1234a0fe35a1a36c7 6.2.2
249 dbdee8ac3e3fcdda1fa55b90c0a235125b7f8e6f 6.2.3
249 dbdee8ac3e3fcdda1fa55b90c0a235125b7f8e6f 6.2.3
250 a3356ab610fc50000cf0ba55c424a4d96da11db7 6.3rc0
251 04f1dba53c961dfdb875c8469adc96fa999cfbed 6.3.0
@@ -1,4203 +1,4230 b''
1 # perf.py - performance test routines
1 # perf.py - performance test routines
2 '''helper extension to measure performance
2 '''helper extension to measure performance
3
3
4 Configurations
4 Configurations
5 ==============
5 ==============
6
6
7 ``perf``
7 ``perf``
8 --------
8 --------
9
9
10 ``all-timing``
10 ``all-timing``
11 When set, additional statistics will be reported for each benchmark: best,
11 When set, additional statistics will be reported for each benchmark: best,
12 worst, median average. If not set only the best timing is reported
12 worst, median average. If not set only the best timing is reported
13 (default: off).
13 (default: off).
14
14
15 ``presleep``
15 ``presleep``
16 number of second to wait before any group of runs (default: 1)
16 number of second to wait before any group of runs (default: 1)
17
17
18 ``pre-run``
18 ``pre-run``
19 number of run to perform before starting measurement.
19 number of run to perform before starting measurement.
20
20
21 ``profile-benchmark``
21 ``profile-benchmark``
22 Enable profiling for the benchmarked section.
22 Enable profiling for the benchmarked section.
23 (The first iteration is benchmarked)
23 (The first iteration is benchmarked)
24
24
25 ``run-limits``
25 ``run-limits``
26 Control the number of runs each benchmark will perform. The option value
26 Control the number of runs each benchmark will perform. The option value
27 should be a list of `<time>-<numberofrun>` pairs. After each run the
27 should be a list of `<time>-<numberofrun>` pairs. After each run the
28 conditions are considered in order with the following logic:
28 conditions are considered in order with the following logic:
29
29
30 If benchmark has been running for <time> seconds, and we have performed
30 If benchmark has been running for <time> seconds, and we have performed
31 <numberofrun> iterations, stop the benchmark,
31 <numberofrun> iterations, stop the benchmark,
32
32
33 The default value is: `3.0-100, 10.0-3`
33 The default value is: `3.0-100, 10.0-3`
34
34
35 ``stub``
35 ``stub``
36 When set, benchmarks will only be run once, useful for testing
36 When set, benchmarks will only be run once, useful for testing
37 (default: off)
37 (default: off)
38 '''
38 '''
39
39
40 # "historical portability" policy of perf.py:
40 # "historical portability" policy of perf.py:
41 #
41 #
42 # We have to do:
42 # We have to do:
43 # - make perf.py "loadable" with as wide Mercurial version as possible
43 # - make perf.py "loadable" with as wide Mercurial version as possible
44 # This doesn't mean that perf commands work correctly with that Mercurial.
44 # This doesn't mean that perf commands work correctly with that Mercurial.
45 # BTW, perf.py itself has been available since 1.1 (or eb240755386d).
45 # BTW, perf.py itself has been available since 1.1 (or eb240755386d).
46 # - make historical perf command work correctly with as wide Mercurial
46 # - make historical perf command work correctly with as wide Mercurial
47 # version as possible
47 # version as possible
48 #
48 #
49 # We have to do, if possible with reasonable cost:
49 # We have to do, if possible with reasonable cost:
50 # - make recent perf command for historical feature work correctly
50 # - make recent perf command for historical feature work correctly
51 # with early Mercurial
51 # with early Mercurial
52 #
52 #
53 # We don't have to do:
53 # We don't have to do:
54 # - make perf command for recent feature work correctly with early
54 # - make perf command for recent feature work correctly with early
55 # Mercurial
55 # Mercurial
56
56
57 import contextlib
57 import contextlib
58 import functools
58 import functools
59 import gc
59 import gc
60 import os
60 import os
61 import random
61 import random
62 import shutil
62 import shutil
63 import struct
63 import struct
64 import sys
64 import sys
65 import tempfile
65 import tempfile
66 import threading
66 import threading
67 import time
67 import time
68
68
69 import mercurial.revlog
69 import mercurial.revlog
70 from mercurial import (
70 from mercurial import (
71 changegroup,
71 changegroup,
72 cmdutil,
72 cmdutil,
73 commands,
73 commands,
74 copies,
74 copies,
75 error,
75 error,
76 extensions,
76 extensions,
77 hg,
77 hg,
78 mdiff,
78 mdiff,
79 merge,
79 merge,
80 util,
80 util,
81 )
81 )
82
82
83 # for "historical portability":
83 # for "historical portability":
84 # try to import modules separately (in dict order), and ignore
84 # try to import modules separately (in dict order), and ignore
85 # failure, because these aren't available with early Mercurial
85 # failure, because these aren't available with early Mercurial
86 try:
86 try:
87 from mercurial import branchmap # since 2.5 (or bcee63733aad)
87 from mercurial import branchmap # since 2.5 (or bcee63733aad)
88 except ImportError:
88 except ImportError:
89 pass
89 pass
90 try:
90 try:
91 from mercurial import obsolete # since 2.3 (or ad0d6c2b3279)
91 from mercurial import obsolete # since 2.3 (or ad0d6c2b3279)
92 except ImportError:
92 except ImportError:
93 pass
93 pass
94 try:
94 try:
95 from mercurial import registrar # since 3.7 (or 37d50250b696)
95 from mercurial import registrar # since 3.7 (or 37d50250b696)
96
96
97 dir(registrar) # forcibly load it
97 dir(registrar) # forcibly load it
98 except ImportError:
98 except ImportError:
99 registrar = None
99 registrar = None
100 try:
100 try:
101 from mercurial import repoview # since 2.5 (or 3a6ddacb7198)
101 from mercurial import repoview # since 2.5 (or 3a6ddacb7198)
102 except ImportError:
102 except ImportError:
103 pass
103 pass
104 try:
104 try:
105 from mercurial.utils import repoviewutil # since 5.0
105 from mercurial.utils import repoviewutil # since 5.0
106 except ImportError:
106 except ImportError:
107 repoviewutil = None
107 repoviewutil = None
108 try:
108 try:
109 from mercurial import scmutil # since 1.9 (or 8b252e826c68)
109 from mercurial import scmutil # since 1.9 (or 8b252e826c68)
110 except ImportError:
110 except ImportError:
111 pass
111 pass
112 try:
112 try:
113 from mercurial import setdiscovery # since 1.9 (or cb98fed52495)
113 from mercurial import setdiscovery # since 1.9 (or cb98fed52495)
114 except ImportError:
114 except ImportError:
115 pass
115 pass
116
116
117 try:
117 try:
118 from mercurial import profiling
118 from mercurial import profiling
119 except ImportError:
119 except ImportError:
120 profiling = None
120 profiling = None
121
121
122 try:
122 try:
123 from mercurial.revlogutils import constants as revlog_constants
123 from mercurial.revlogutils import constants as revlog_constants
124
124
125 perf_rl_kind = (revlog_constants.KIND_OTHER, b'created-by-perf')
125 perf_rl_kind = (revlog_constants.KIND_OTHER, b'created-by-perf')
126
126
127 def revlog(opener, *args, **kwargs):
127 def revlog(opener, *args, **kwargs):
128 return mercurial.revlog.revlog(opener, perf_rl_kind, *args, **kwargs)
128 return mercurial.revlog.revlog(opener, perf_rl_kind, *args, **kwargs)
129
129
130
130
131 except (ImportError, AttributeError):
131 except (ImportError, AttributeError):
132 perf_rl_kind = None
132 perf_rl_kind = None
133
133
134 def revlog(opener, *args, **kwargs):
134 def revlog(opener, *args, **kwargs):
135 return mercurial.revlog.revlog(opener, *args, **kwargs)
135 return mercurial.revlog.revlog(opener, *args, **kwargs)
136
136
137
137
138 def identity(a):
138 def identity(a):
139 return a
139 return a
140
140
141
141
142 try:
142 try:
143 from mercurial import pycompat
143 from mercurial import pycompat
144
144
145 getargspec = pycompat.getargspec # added to module after 4.5
145 getargspec = pycompat.getargspec # added to module after 4.5
146 _byteskwargs = pycompat.byteskwargs # since 4.1 (or fbc3f73dc802)
146 _byteskwargs = pycompat.byteskwargs # since 4.1 (or fbc3f73dc802)
147 _sysstr = pycompat.sysstr # since 4.0 (or 2219f4f82ede)
147 _sysstr = pycompat.sysstr # since 4.0 (or 2219f4f82ede)
148 _bytestr = pycompat.bytestr # since 4.2 (or b70407bd84d5)
148 _bytestr = pycompat.bytestr # since 4.2 (or b70407bd84d5)
149 _xrange = pycompat.xrange # since 4.8 (or 7eba8f83129b)
149 _xrange = pycompat.xrange # since 4.8 (or 7eba8f83129b)
150 fsencode = pycompat.fsencode # since 3.9 (or f4a5e0e86a7e)
150 fsencode = pycompat.fsencode # since 3.9 (or f4a5e0e86a7e)
151 if pycompat.ispy3:
151 if pycompat.ispy3:
152 _maxint = sys.maxsize # per py3 docs for replacing maxint
152 _maxint = sys.maxsize # per py3 docs for replacing maxint
153 else:
153 else:
154 _maxint = sys.maxint
154 _maxint = sys.maxint
155 except (NameError, ImportError, AttributeError):
155 except (NameError, ImportError, AttributeError):
156 import inspect
156 import inspect
157
157
158 getargspec = inspect.getargspec
158 getargspec = inspect.getargspec
159 _byteskwargs = identity
159 _byteskwargs = identity
160 _bytestr = str
160 _bytestr = str
161 fsencode = identity # no py3 support
161 fsencode = identity # no py3 support
162 _maxint = sys.maxint # no py3 support
162 _maxint = sys.maxint # no py3 support
163 _sysstr = lambda x: x # no py3 support
163 _sysstr = lambda x: x # no py3 support
164 _xrange = xrange
164 _xrange = xrange
165
165
166 try:
166 try:
167 # 4.7+
167 # 4.7+
168 queue = pycompat.queue.Queue
168 queue = pycompat.queue.Queue
169 except (NameError, AttributeError, ImportError):
169 except (NameError, AttributeError, ImportError):
170 # <4.7.
170 # <4.7.
171 try:
171 try:
172 queue = pycompat.queue
172 queue = pycompat.queue
173 except (NameError, AttributeError, ImportError):
173 except (NameError, AttributeError, ImportError):
174 import Queue as queue
174 import Queue as queue
175
175
176 try:
176 try:
177 from mercurial import logcmdutil
177 from mercurial import logcmdutil
178
178
179 makelogtemplater = logcmdutil.maketemplater
179 makelogtemplater = logcmdutil.maketemplater
180 except (AttributeError, ImportError):
180 except (AttributeError, ImportError):
181 try:
181 try:
182 makelogtemplater = cmdutil.makelogtemplater
182 makelogtemplater = cmdutil.makelogtemplater
183 except (AttributeError, ImportError):
183 except (AttributeError, ImportError):
184 makelogtemplater = None
184 makelogtemplater = None
185
185
186 # for "historical portability":
186 # for "historical portability":
187 # define util.safehasattr forcibly, because util.safehasattr has been
187 # define util.safehasattr forcibly, because util.safehasattr has been
188 # available since 1.9.3 (or 94b200a11cf7)
188 # available since 1.9.3 (or 94b200a11cf7)
189 _undefined = object()
189 _undefined = object()
190
190
191
191
192 def safehasattr(thing, attr):
192 def safehasattr(thing, attr):
193 return getattr(thing, _sysstr(attr), _undefined) is not _undefined
193 return getattr(thing, _sysstr(attr), _undefined) is not _undefined
194
194
195
195
196 setattr(util, 'safehasattr', safehasattr)
196 setattr(util, 'safehasattr', safehasattr)
197
197
198 # for "historical portability":
198 # for "historical portability":
199 # define util.timer forcibly, because util.timer has been available
199 # define util.timer forcibly, because util.timer has been available
200 # since ae5d60bb70c9
200 # since ae5d60bb70c9
201 if safehasattr(time, 'perf_counter'):
201 if safehasattr(time, 'perf_counter'):
202 util.timer = time.perf_counter
202 util.timer = time.perf_counter
203 elif os.name == b'nt':
203 elif os.name == b'nt':
204 util.timer = time.clock
204 util.timer = time.clock
205 else:
205 else:
206 util.timer = time.time
206 util.timer = time.time
207
207
208 # for "historical portability":
208 # for "historical portability":
209 # use locally defined empty option list, if formatteropts isn't
209 # use locally defined empty option list, if formatteropts isn't
210 # available, because commands.formatteropts has been available since
210 # available, because commands.formatteropts has been available since
211 # 3.2 (or 7a7eed5176a4), even though formatting itself has been
211 # 3.2 (or 7a7eed5176a4), even though formatting itself has been
212 # available since 2.2 (or ae5f92e154d3)
212 # available since 2.2 (or ae5f92e154d3)
213 formatteropts = getattr(
213 formatteropts = getattr(
214 cmdutil, "formatteropts", getattr(commands, "formatteropts", [])
214 cmdutil, "formatteropts", getattr(commands, "formatteropts", [])
215 )
215 )
216
216
217 # for "historical portability":
217 # for "historical portability":
218 # use locally defined option list, if debugrevlogopts isn't available,
218 # use locally defined option list, if debugrevlogopts isn't available,
219 # because commands.debugrevlogopts has been available since 3.7 (or
219 # because commands.debugrevlogopts has been available since 3.7 (or
220 # 5606f7d0d063), even though cmdutil.openrevlog() has been available
220 # 5606f7d0d063), even though cmdutil.openrevlog() has been available
221 # since 1.9 (or a79fea6b3e77).
221 # since 1.9 (or a79fea6b3e77).
222 revlogopts = getattr(
222 revlogopts = getattr(
223 cmdutil,
223 cmdutil,
224 "debugrevlogopts",
224 "debugrevlogopts",
225 getattr(
225 getattr(
226 commands,
226 commands,
227 "debugrevlogopts",
227 "debugrevlogopts",
228 [
228 [
229 (b'c', b'changelog', False, b'open changelog'),
229 (b'c', b'changelog', False, b'open changelog'),
230 (b'm', b'manifest', False, b'open manifest'),
230 (b'm', b'manifest', False, b'open manifest'),
231 (b'', b'dir', False, b'open directory manifest'),
231 (b'', b'dir', False, b'open directory manifest'),
232 ],
232 ],
233 ),
233 ),
234 )
234 )
235
235
236 cmdtable = {}
236 cmdtable = {}
237
237
238 # for "historical portability":
238 # for "historical portability":
239 # define parsealiases locally, because cmdutil.parsealiases has been
239 # define parsealiases locally, because cmdutil.parsealiases has been
240 # available since 1.5 (or 6252852b4332)
240 # available since 1.5 (or 6252852b4332)
241 def parsealiases(cmd):
241 def parsealiases(cmd):
242 return cmd.split(b"|")
242 return cmd.split(b"|")
243
243
244
244
245 if safehasattr(registrar, 'command'):
245 if safehasattr(registrar, 'command'):
246 command = registrar.command(cmdtable)
246 command = registrar.command(cmdtable)
247 elif safehasattr(cmdutil, 'command'):
247 elif safehasattr(cmdutil, 'command'):
248 command = cmdutil.command(cmdtable)
248 command = cmdutil.command(cmdtable)
249 if 'norepo' not in getargspec(command).args:
249 if 'norepo' not in getargspec(command).args:
250 # for "historical portability":
250 # for "historical portability":
251 # wrap original cmdutil.command, because "norepo" option has
251 # wrap original cmdutil.command, because "norepo" option has
252 # been available since 3.1 (or 75a96326cecb)
252 # been available since 3.1 (or 75a96326cecb)
253 _command = command
253 _command = command
254
254
255 def command(name, options=(), synopsis=None, norepo=False):
255 def command(name, options=(), synopsis=None, norepo=False):
256 if norepo:
256 if norepo:
257 commands.norepo += b' %s' % b' '.join(parsealiases(name))
257 commands.norepo += b' %s' % b' '.join(parsealiases(name))
258 return _command(name, list(options), synopsis)
258 return _command(name, list(options), synopsis)
259
259
260
260
261 else:
261 else:
262 # for "historical portability":
262 # for "historical portability":
263 # define "@command" annotation locally, because cmdutil.command
263 # define "@command" annotation locally, because cmdutil.command
264 # has been available since 1.9 (or 2daa5179e73f)
264 # has been available since 1.9 (or 2daa5179e73f)
265 def command(name, options=(), synopsis=None, norepo=False):
265 def command(name, options=(), synopsis=None, norepo=False):
266 def decorator(func):
266 def decorator(func):
267 if synopsis:
267 if synopsis:
268 cmdtable[name] = func, list(options), synopsis
268 cmdtable[name] = func, list(options), synopsis
269 else:
269 else:
270 cmdtable[name] = func, list(options)
270 cmdtable[name] = func, list(options)
271 if norepo:
271 if norepo:
272 commands.norepo += b' %s' % b' '.join(parsealiases(name))
272 commands.norepo += b' %s' % b' '.join(parsealiases(name))
273 return func
273 return func
274
274
275 return decorator
275 return decorator
276
276
277
277
278 try:
278 try:
279 import mercurial.registrar
279 import mercurial.registrar
280 import mercurial.configitems
280 import mercurial.configitems
281
281
282 configtable = {}
282 configtable = {}
283 configitem = mercurial.registrar.configitem(configtable)
283 configitem = mercurial.registrar.configitem(configtable)
284 configitem(
284 configitem(
285 b'perf',
285 b'perf',
286 b'presleep',
286 b'presleep',
287 default=mercurial.configitems.dynamicdefault,
287 default=mercurial.configitems.dynamicdefault,
288 experimental=True,
288 experimental=True,
289 )
289 )
290 configitem(
290 configitem(
291 b'perf',
291 b'perf',
292 b'stub',
292 b'stub',
293 default=mercurial.configitems.dynamicdefault,
293 default=mercurial.configitems.dynamicdefault,
294 experimental=True,
294 experimental=True,
295 )
295 )
296 configitem(
296 configitem(
297 b'perf',
297 b'perf',
298 b'parentscount',
298 b'parentscount',
299 default=mercurial.configitems.dynamicdefault,
299 default=mercurial.configitems.dynamicdefault,
300 experimental=True,
300 experimental=True,
301 )
301 )
302 configitem(
302 configitem(
303 b'perf',
303 b'perf',
304 b'all-timing',
304 b'all-timing',
305 default=mercurial.configitems.dynamicdefault,
305 default=mercurial.configitems.dynamicdefault,
306 experimental=True,
306 experimental=True,
307 )
307 )
308 configitem(
308 configitem(
309 b'perf',
309 b'perf',
310 b'pre-run',
310 b'pre-run',
311 default=mercurial.configitems.dynamicdefault,
311 default=mercurial.configitems.dynamicdefault,
312 )
312 )
313 configitem(
313 configitem(
314 b'perf',
314 b'perf',
315 b'profile-benchmark',
315 b'profile-benchmark',
316 default=mercurial.configitems.dynamicdefault,
316 default=mercurial.configitems.dynamicdefault,
317 )
317 )
318 configitem(
318 configitem(
319 b'perf',
319 b'perf',
320 b'run-limits',
320 b'run-limits',
321 default=mercurial.configitems.dynamicdefault,
321 default=mercurial.configitems.dynamicdefault,
322 experimental=True,
322 experimental=True,
323 )
323 )
324 except (ImportError, AttributeError):
324 except (ImportError, AttributeError):
325 pass
325 pass
326 except TypeError:
326 except TypeError:
327 # compatibility fix for a11fd395e83f
327 # compatibility fix for a11fd395e83f
328 # hg version: 5.2
328 # hg version: 5.2
329 configitem(
329 configitem(
330 b'perf',
330 b'perf',
331 b'presleep',
331 b'presleep',
332 default=mercurial.configitems.dynamicdefault,
332 default=mercurial.configitems.dynamicdefault,
333 )
333 )
334 configitem(
334 configitem(
335 b'perf',
335 b'perf',
336 b'stub',
336 b'stub',
337 default=mercurial.configitems.dynamicdefault,
337 default=mercurial.configitems.dynamicdefault,
338 )
338 )
339 configitem(
339 configitem(
340 b'perf',
340 b'perf',
341 b'parentscount',
341 b'parentscount',
342 default=mercurial.configitems.dynamicdefault,
342 default=mercurial.configitems.dynamicdefault,
343 )
343 )
344 configitem(
344 configitem(
345 b'perf',
345 b'perf',
346 b'all-timing',
346 b'all-timing',
347 default=mercurial.configitems.dynamicdefault,
347 default=mercurial.configitems.dynamicdefault,
348 )
348 )
349 configitem(
349 configitem(
350 b'perf',
350 b'perf',
351 b'pre-run',
351 b'pre-run',
352 default=mercurial.configitems.dynamicdefault,
352 default=mercurial.configitems.dynamicdefault,
353 )
353 )
354 configitem(
354 configitem(
355 b'perf',
355 b'perf',
356 b'profile-benchmark',
356 b'profile-benchmark',
357 default=mercurial.configitems.dynamicdefault,
357 default=mercurial.configitems.dynamicdefault,
358 )
358 )
359 configitem(
359 configitem(
360 b'perf',
360 b'perf',
361 b'run-limits',
361 b'run-limits',
362 default=mercurial.configitems.dynamicdefault,
362 default=mercurial.configitems.dynamicdefault,
363 )
363 )
364
364
365
365
366 def getlen(ui):
366 def getlen(ui):
367 if ui.configbool(b"perf", b"stub", False):
367 if ui.configbool(b"perf", b"stub", False):
368 return lambda x: 1
368 return lambda x: 1
369 return len
369 return len
370
370
371
371
372 class noop:
372 class noop:
373 """dummy context manager"""
373 """dummy context manager"""
374
374
375 def __enter__(self):
375 def __enter__(self):
376 pass
376 pass
377
377
378 def __exit__(self, *args):
378 def __exit__(self, *args):
379 pass
379 pass
380
380
381
381
382 NOOPCTX = noop()
382 NOOPCTX = noop()
383
383
384
384
385 def gettimer(ui, opts=None):
385 def gettimer(ui, opts=None):
386 """return a timer function and formatter: (timer, formatter)
386 """return a timer function and formatter: (timer, formatter)
387
387
388 This function exists to gather the creation of formatter in a single
388 This function exists to gather the creation of formatter in a single
389 place instead of duplicating it in all performance commands."""
389 place instead of duplicating it in all performance commands."""
390
390
391 # enforce an idle period before execution to counteract power management
391 # enforce an idle period before execution to counteract power management
392 # experimental config: perf.presleep
392 # experimental config: perf.presleep
393 time.sleep(getint(ui, b"perf", b"presleep", 1))
393 time.sleep(getint(ui, b"perf", b"presleep", 1))
394
394
395 if opts is None:
395 if opts is None:
396 opts = {}
396 opts = {}
397 # redirect all to stderr unless buffer api is in use
397 # redirect all to stderr unless buffer api is in use
398 if not ui._buffers:
398 if not ui._buffers:
399 ui = ui.copy()
399 ui = ui.copy()
400 uifout = safeattrsetter(ui, b'fout', ignoremissing=True)
400 uifout = safeattrsetter(ui, b'fout', ignoremissing=True)
401 if uifout:
401 if uifout:
402 # for "historical portability":
402 # for "historical portability":
403 # ui.fout/ferr have been available since 1.9 (or 4e1ccd4c2b6d)
403 # ui.fout/ferr have been available since 1.9 (or 4e1ccd4c2b6d)
404 uifout.set(ui.ferr)
404 uifout.set(ui.ferr)
405
405
406 # get a formatter
406 # get a formatter
407 uiformatter = getattr(ui, 'formatter', None)
407 uiformatter = getattr(ui, 'formatter', None)
408 if uiformatter:
408 if uiformatter:
409 fm = uiformatter(b'perf', opts)
409 fm = uiformatter(b'perf', opts)
410 else:
410 else:
411 # for "historical portability":
411 # for "historical portability":
412 # define formatter locally, because ui.formatter has been
412 # define formatter locally, because ui.formatter has been
413 # available since 2.2 (or ae5f92e154d3)
413 # available since 2.2 (or ae5f92e154d3)
414 from mercurial import node
414 from mercurial import node
415
415
416 class defaultformatter:
416 class defaultformatter:
417 """Minimized composition of baseformatter and plainformatter"""
417 """Minimized composition of baseformatter and plainformatter"""
418
418
419 def __init__(self, ui, topic, opts):
419 def __init__(self, ui, topic, opts):
420 self._ui = ui
420 self._ui = ui
421 if ui.debugflag:
421 if ui.debugflag:
422 self.hexfunc = node.hex
422 self.hexfunc = node.hex
423 else:
423 else:
424 self.hexfunc = node.short
424 self.hexfunc = node.short
425
425
426 def __nonzero__(self):
426 def __nonzero__(self):
427 return False
427 return False
428
428
429 __bool__ = __nonzero__
429 __bool__ = __nonzero__
430
430
431 def startitem(self):
431 def startitem(self):
432 pass
432 pass
433
433
434 def data(self, **data):
434 def data(self, **data):
435 pass
435 pass
436
436
437 def write(self, fields, deftext, *fielddata, **opts):
437 def write(self, fields, deftext, *fielddata, **opts):
438 self._ui.write(deftext % fielddata, **opts)
438 self._ui.write(deftext % fielddata, **opts)
439
439
440 def condwrite(self, cond, fields, deftext, *fielddata, **opts):
440 def condwrite(self, cond, fields, deftext, *fielddata, **opts):
441 if cond:
441 if cond:
442 self._ui.write(deftext % fielddata, **opts)
442 self._ui.write(deftext % fielddata, **opts)
443
443
444 def plain(self, text, **opts):
444 def plain(self, text, **opts):
445 self._ui.write(text, **opts)
445 self._ui.write(text, **opts)
446
446
447 def end(self):
447 def end(self):
448 pass
448 pass
449
449
450 fm = defaultformatter(ui, b'perf', opts)
450 fm = defaultformatter(ui, b'perf', opts)
451
451
452 # stub function, runs code only once instead of in a loop
452 # stub function, runs code only once instead of in a loop
453 # experimental config: perf.stub
453 # experimental config: perf.stub
454 if ui.configbool(b"perf", b"stub", False):
454 if ui.configbool(b"perf", b"stub", False):
455 return functools.partial(stub_timer, fm), fm
455 return functools.partial(stub_timer, fm), fm
456
456
457 # experimental config: perf.all-timing
457 # experimental config: perf.all-timing
458 displayall = ui.configbool(b"perf", b"all-timing", False)
458 displayall = ui.configbool(b"perf", b"all-timing", False)
459
459
460 # experimental config: perf.run-limits
460 # experimental config: perf.run-limits
461 limitspec = ui.configlist(b"perf", b"run-limits", [])
461 limitspec = ui.configlist(b"perf", b"run-limits", [])
462 limits = []
462 limits = []
463 for item in limitspec:
463 for item in limitspec:
464 parts = item.split(b'-', 1)
464 parts = item.split(b'-', 1)
465 if len(parts) < 2:
465 if len(parts) < 2:
466 ui.warn((b'malformatted run limit entry, missing "-": %s\n' % item))
466 ui.warn((b'malformatted run limit entry, missing "-": %s\n' % item))
467 continue
467 continue
468 try:
468 try:
469 time_limit = float(_sysstr(parts[0]))
469 time_limit = float(_sysstr(parts[0]))
470 except ValueError as e:
470 except ValueError as e:
471 ui.warn(
471 ui.warn(
472 (
472 (
473 b'malformatted run limit entry, %s: %s\n'
473 b'malformatted run limit entry, %s: %s\n'
474 % (_bytestr(e), item)
474 % (_bytestr(e), item)
475 )
475 )
476 )
476 )
477 continue
477 continue
478 try:
478 try:
479 run_limit = int(_sysstr(parts[1]))
479 run_limit = int(_sysstr(parts[1]))
480 except ValueError as e:
480 except ValueError as e:
481 ui.warn(
481 ui.warn(
482 (
482 (
483 b'malformatted run limit entry, %s: %s\n'
483 b'malformatted run limit entry, %s: %s\n'
484 % (_bytestr(e), item)
484 % (_bytestr(e), item)
485 )
485 )
486 )
486 )
487 continue
487 continue
488 limits.append((time_limit, run_limit))
488 limits.append((time_limit, run_limit))
489 if not limits:
489 if not limits:
490 limits = DEFAULTLIMITS
490 limits = DEFAULTLIMITS
491
491
492 profiler = None
492 profiler = None
493 if profiling is not None:
493 if profiling is not None:
494 if ui.configbool(b"perf", b"profile-benchmark", False):
494 if ui.configbool(b"perf", b"profile-benchmark", False):
495 profiler = profiling.profile(ui)
495 profiler = profiling.profile(ui)
496
496
497 prerun = getint(ui, b"perf", b"pre-run", 0)
497 prerun = getint(ui, b"perf", b"pre-run", 0)
498 t = functools.partial(
498 t = functools.partial(
499 _timer,
499 _timer,
500 fm,
500 fm,
501 displayall=displayall,
501 displayall=displayall,
502 limits=limits,
502 limits=limits,
503 prerun=prerun,
503 prerun=prerun,
504 profiler=profiler,
504 profiler=profiler,
505 )
505 )
506 return t, fm
506 return t, fm
507
507
508
508
509 def stub_timer(fm, func, setup=None, title=None):
509 def stub_timer(fm, func, setup=None, title=None):
510 if setup is not None:
510 if setup is not None:
511 setup()
511 setup()
512 func()
512 func()
513
513
514
514
515 @contextlib.contextmanager
515 @contextlib.contextmanager
516 def timeone():
516 def timeone():
517 r = []
517 r = []
518 ostart = os.times()
518 ostart = os.times()
519 cstart = util.timer()
519 cstart = util.timer()
520 yield r
520 yield r
521 cstop = util.timer()
521 cstop = util.timer()
522 ostop = os.times()
522 ostop = os.times()
523 a, b = ostart, ostop
523 a, b = ostart, ostop
524 r.append((cstop - cstart, b[0] - a[0], b[1] - a[1]))
524 r.append((cstop - cstart, b[0] - a[0], b[1] - a[1]))
525
525
526
526
527 # list of stop condition (elapsed time, minimal run count)
527 # list of stop condition (elapsed time, minimal run count)
528 DEFAULTLIMITS = (
528 DEFAULTLIMITS = (
529 (3.0, 100),
529 (3.0, 100),
530 (10.0, 3),
530 (10.0, 3),
531 )
531 )
532
532
533
533
534 def _timer(
534 def _timer(
535 fm,
535 fm,
536 func,
536 func,
537 setup=None,
537 setup=None,
538 title=None,
538 title=None,
539 displayall=False,
539 displayall=False,
540 limits=DEFAULTLIMITS,
540 limits=DEFAULTLIMITS,
541 prerun=0,
541 prerun=0,
542 profiler=None,
542 profiler=None,
543 ):
543 ):
544 gc.collect()
544 gc.collect()
545 results = []
545 results = []
546 begin = util.timer()
546 begin = util.timer()
547 count = 0
547 count = 0
548 if profiler is None:
548 if profiler is None:
549 profiler = NOOPCTX
549 profiler = NOOPCTX
550 for i in range(prerun):
550 for i in range(prerun):
551 if setup is not None:
551 if setup is not None:
552 setup()
552 setup()
553 func()
553 func()
554 keepgoing = True
554 keepgoing = True
555 while keepgoing:
555 while keepgoing:
556 if setup is not None:
556 if setup is not None:
557 setup()
557 setup()
558 with profiler:
558 with profiler:
559 with timeone() as item:
559 with timeone() as item:
560 r = func()
560 r = func()
561 profiler = NOOPCTX
561 profiler = NOOPCTX
562 count += 1
562 count += 1
563 results.append(item[0])
563 results.append(item[0])
564 cstop = util.timer()
564 cstop = util.timer()
565 # Look for a stop condition.
565 # Look for a stop condition.
566 elapsed = cstop - begin
566 elapsed = cstop - begin
567 for t, mincount in limits:
567 for t, mincount in limits:
568 if elapsed >= t and count >= mincount:
568 if elapsed >= t and count >= mincount:
569 keepgoing = False
569 keepgoing = False
570 break
570 break
571
571
572 formatone(fm, results, title=title, result=r, displayall=displayall)
572 formatone(fm, results, title=title, result=r, displayall=displayall)
573
573
574
574
575 def formatone(fm, timings, title=None, result=None, displayall=False):
575 def formatone(fm, timings, title=None, result=None, displayall=False):
576
576
577 count = len(timings)
577 count = len(timings)
578
578
579 fm.startitem()
579 fm.startitem()
580
580
581 if title:
581 if title:
582 fm.write(b'title', b'! %s\n', title)
582 fm.write(b'title', b'! %s\n', title)
583 if result:
583 if result:
584 fm.write(b'result', b'! result: %s\n', result)
584 fm.write(b'result', b'! result: %s\n', result)
585
585
586 def display(role, entry):
586 def display(role, entry):
587 prefix = b''
587 prefix = b''
588 if role != b'best':
588 if role != b'best':
589 prefix = b'%s.' % role
589 prefix = b'%s.' % role
590 fm.plain(b'!')
590 fm.plain(b'!')
591 fm.write(prefix + b'wall', b' wall %f', entry[0])
591 fm.write(prefix + b'wall', b' wall %f', entry[0])
592 fm.write(prefix + b'comb', b' comb %f', entry[1] + entry[2])
592 fm.write(prefix + b'comb', b' comb %f', entry[1] + entry[2])
593 fm.write(prefix + b'user', b' user %f', entry[1])
593 fm.write(prefix + b'user', b' user %f', entry[1])
594 fm.write(prefix + b'sys', b' sys %f', entry[2])
594 fm.write(prefix + b'sys', b' sys %f', entry[2])
595 fm.write(prefix + b'count', b' (%s of %%d)' % role, count)
595 fm.write(prefix + b'count', b' (%s of %%d)' % role, count)
596 fm.plain(b'\n')
596 fm.plain(b'\n')
597
597
598 timings.sort()
598 timings.sort()
599 min_val = timings[0]
599 min_val = timings[0]
600 display(b'best', min_val)
600 display(b'best', min_val)
601 if displayall:
601 if displayall:
602 max_val = timings[-1]
602 max_val = timings[-1]
603 display(b'max', max_val)
603 display(b'max', max_val)
604 avg = tuple([sum(x) / count for x in zip(*timings)])
604 avg = tuple([sum(x) / count for x in zip(*timings)])
605 display(b'avg', avg)
605 display(b'avg', avg)
606 median = timings[len(timings) // 2]
606 median = timings[len(timings) // 2]
607 display(b'median', median)
607 display(b'median', median)
608
608
609
609
610 # utilities for historical portability
610 # utilities for historical portability
611
611
612
612
613 def getint(ui, section, name, default):
613 def getint(ui, section, name, default):
614 # for "historical portability":
614 # for "historical portability":
615 # ui.configint has been available since 1.9 (or fa2b596db182)
615 # ui.configint has been available since 1.9 (or fa2b596db182)
616 v = ui.config(section, name, None)
616 v = ui.config(section, name, None)
617 if v is None:
617 if v is None:
618 return default
618 return default
619 try:
619 try:
620 return int(v)
620 return int(v)
621 except ValueError:
621 except ValueError:
622 raise error.ConfigError(
622 raise error.ConfigError(
623 b"%s.%s is not an integer ('%s')" % (section, name, v)
623 b"%s.%s is not an integer ('%s')" % (section, name, v)
624 )
624 )
625
625
626
626
627 def safeattrsetter(obj, name, ignoremissing=False):
627 def safeattrsetter(obj, name, ignoremissing=False):
628 """Ensure that 'obj' has 'name' attribute before subsequent setattr
628 """Ensure that 'obj' has 'name' attribute before subsequent setattr
629
629
630 This function is aborted, if 'obj' doesn't have 'name' attribute
630 This function is aborted, if 'obj' doesn't have 'name' attribute
631 at runtime. This avoids overlooking removal of an attribute, which
631 at runtime. This avoids overlooking removal of an attribute, which
632 breaks assumption of performance measurement, in the future.
632 breaks assumption of performance measurement, in the future.
633
633
634 This function returns the object to (1) assign a new value, and
634 This function returns the object to (1) assign a new value, and
635 (2) restore an original value to the attribute.
635 (2) restore an original value to the attribute.
636
636
637 If 'ignoremissing' is true, missing 'name' attribute doesn't cause
637 If 'ignoremissing' is true, missing 'name' attribute doesn't cause
638 abortion, and this function returns None. This is useful to
638 abortion, and this function returns None. This is useful to
639 examine an attribute, which isn't ensured in all Mercurial
639 examine an attribute, which isn't ensured in all Mercurial
640 versions.
640 versions.
641 """
641 """
642 if not util.safehasattr(obj, name):
642 if not util.safehasattr(obj, name):
643 if ignoremissing:
643 if ignoremissing:
644 return None
644 return None
645 raise error.Abort(
645 raise error.Abort(
646 (
646 (
647 b"missing attribute %s of %s might break assumption"
647 b"missing attribute %s of %s might break assumption"
648 b" of performance measurement"
648 b" of performance measurement"
649 )
649 )
650 % (name, obj)
650 % (name, obj)
651 )
651 )
652
652
653 origvalue = getattr(obj, _sysstr(name))
653 origvalue = getattr(obj, _sysstr(name))
654
654
655 class attrutil:
655 class attrutil:
656 def set(self, newvalue):
656 def set(self, newvalue):
657 setattr(obj, _sysstr(name), newvalue)
657 setattr(obj, _sysstr(name), newvalue)
658
658
659 def restore(self):
659 def restore(self):
660 setattr(obj, _sysstr(name), origvalue)
660 setattr(obj, _sysstr(name), origvalue)
661
661
662 return attrutil()
662 return attrutil()
663
663
664
664
665 # utilities to examine each internal API changes
665 # utilities to examine each internal API changes
666
666
667
667
668 def getbranchmapsubsettable():
668 def getbranchmapsubsettable():
669 # for "historical portability":
669 # for "historical portability":
670 # subsettable is defined in:
670 # subsettable is defined in:
671 # - branchmap since 2.9 (or 175c6fd8cacc)
671 # - branchmap since 2.9 (or 175c6fd8cacc)
672 # - repoview since 2.5 (or 59a9f18d4587)
672 # - repoview since 2.5 (or 59a9f18d4587)
673 # - repoviewutil since 5.0
673 # - repoviewutil since 5.0
674 for mod in (branchmap, repoview, repoviewutil):
674 for mod in (branchmap, repoview, repoviewutil):
675 subsettable = getattr(mod, 'subsettable', None)
675 subsettable = getattr(mod, 'subsettable', None)
676 if subsettable:
676 if subsettable:
677 return subsettable
677 return subsettable
678
678
679 # bisecting in bcee63733aad::59a9f18d4587 can reach here (both
679 # bisecting in bcee63733aad::59a9f18d4587 can reach here (both
680 # branchmap and repoview modules exist, but subsettable attribute
680 # branchmap and repoview modules exist, but subsettable attribute
681 # doesn't)
681 # doesn't)
682 raise error.Abort(
682 raise error.Abort(
683 b"perfbranchmap not available with this Mercurial",
683 b"perfbranchmap not available with this Mercurial",
684 hint=b"use 2.5 or later",
684 hint=b"use 2.5 or later",
685 )
685 )
686
686
687
687
688 def getsvfs(repo):
688 def getsvfs(repo):
689 """Return appropriate object to access files under .hg/store"""
689 """Return appropriate object to access files under .hg/store"""
690 # for "historical portability":
690 # for "historical portability":
691 # repo.svfs has been available since 2.3 (or 7034365089bf)
691 # repo.svfs has been available since 2.3 (or 7034365089bf)
692 svfs = getattr(repo, 'svfs', None)
692 svfs = getattr(repo, 'svfs', None)
693 if svfs:
693 if svfs:
694 return svfs
694 return svfs
695 else:
695 else:
696 return getattr(repo, 'sopener')
696 return getattr(repo, 'sopener')
697
697
698
698
699 def getvfs(repo):
699 def getvfs(repo):
700 """Return appropriate object to access files under .hg"""
700 """Return appropriate object to access files under .hg"""
701 # for "historical portability":
701 # for "historical portability":
702 # repo.vfs has been available since 2.3 (or 7034365089bf)
702 # repo.vfs has been available since 2.3 (or 7034365089bf)
703 vfs = getattr(repo, 'vfs', None)
703 vfs = getattr(repo, 'vfs', None)
704 if vfs:
704 if vfs:
705 return vfs
705 return vfs
706 else:
706 else:
707 return getattr(repo, 'opener')
707 return getattr(repo, 'opener')
708
708
709
709
710 def repocleartagscachefunc(repo):
710 def repocleartagscachefunc(repo):
711 """Return the function to clear tags cache according to repo internal API"""
711 """Return the function to clear tags cache according to repo internal API"""
712 if util.safehasattr(repo, b'_tagscache'): # since 2.0 (or 9dca7653b525)
712 if util.safehasattr(repo, b'_tagscache'): # since 2.0 (or 9dca7653b525)
713 # in this case, setattr(repo, '_tagscache', None) or so isn't
713 # in this case, setattr(repo, '_tagscache', None) or so isn't
714 # correct way to clear tags cache, because existing code paths
714 # correct way to clear tags cache, because existing code paths
715 # expect _tagscache to be a structured object.
715 # expect _tagscache to be a structured object.
716 def clearcache():
716 def clearcache():
717 # _tagscache has been filteredpropertycache since 2.5 (or
717 # _tagscache has been filteredpropertycache since 2.5 (or
718 # 98c867ac1330), and delattr() can't work in such case
718 # 98c867ac1330), and delattr() can't work in such case
719 if '_tagscache' in vars(repo):
719 if '_tagscache' in vars(repo):
720 del repo.__dict__['_tagscache']
720 del repo.__dict__['_tagscache']
721
721
722 return clearcache
722 return clearcache
723
723
724 repotags = safeattrsetter(repo, b'_tags', ignoremissing=True)
724 repotags = safeattrsetter(repo, b'_tags', ignoremissing=True)
725 if repotags: # since 1.4 (or 5614a628d173)
725 if repotags: # since 1.4 (or 5614a628d173)
726 return lambda: repotags.set(None)
726 return lambda: repotags.set(None)
727
727
728 repotagscache = safeattrsetter(repo, b'tagscache', ignoremissing=True)
728 repotagscache = safeattrsetter(repo, b'tagscache', ignoremissing=True)
729 if repotagscache: # since 0.6 (or d7df759d0e97)
729 if repotagscache: # since 0.6 (or d7df759d0e97)
730 return lambda: repotagscache.set(None)
730 return lambda: repotagscache.set(None)
731
731
732 # Mercurial earlier than 0.6 (or d7df759d0e97) logically reaches
732 # Mercurial earlier than 0.6 (or d7df759d0e97) logically reaches
733 # this point, but it isn't so problematic, because:
733 # this point, but it isn't so problematic, because:
734 # - repo.tags of such Mercurial isn't "callable", and repo.tags()
734 # - repo.tags of such Mercurial isn't "callable", and repo.tags()
735 # in perftags() causes failure soon
735 # in perftags() causes failure soon
736 # - perf.py itself has been available since 1.1 (or eb240755386d)
736 # - perf.py itself has been available since 1.1 (or eb240755386d)
737 raise error.Abort(b"tags API of this hg command is unknown")
737 raise error.Abort(b"tags API of this hg command is unknown")
738
738
739
739
740 # utilities to clear cache
740 # utilities to clear cache
741
741
742
742
743 def clearfilecache(obj, attrname):
743 def clearfilecache(obj, attrname):
744 unfiltered = getattr(obj, 'unfiltered', None)
744 unfiltered = getattr(obj, 'unfiltered', None)
745 if unfiltered is not None:
745 if unfiltered is not None:
746 obj = obj.unfiltered()
746 obj = obj.unfiltered()
747 if attrname in vars(obj):
747 if attrname in vars(obj):
748 delattr(obj, attrname)
748 delattr(obj, attrname)
749 obj._filecache.pop(attrname, None)
749 obj._filecache.pop(attrname, None)
750
750
751
751
752 def clearchangelog(repo):
752 def clearchangelog(repo):
753 if repo is not repo.unfiltered():
753 if repo is not repo.unfiltered():
754 object.__setattr__(repo, '_clcachekey', None)
754 object.__setattr__(repo, '_clcachekey', None)
755 object.__setattr__(repo, '_clcache', None)
755 object.__setattr__(repo, '_clcache', None)
756 clearfilecache(repo.unfiltered(), 'changelog')
756 clearfilecache(repo.unfiltered(), 'changelog')
757
757
758
758
759 # perf commands
759 # perf commands
760
760
761
761
762 @command(b'perf::walk|perfwalk', formatteropts)
762 @command(b'perf::walk|perfwalk', formatteropts)
763 def perfwalk(ui, repo, *pats, **opts):
763 def perfwalk(ui, repo, *pats, **opts):
764 opts = _byteskwargs(opts)
764 opts = _byteskwargs(opts)
765 timer, fm = gettimer(ui, opts)
765 timer, fm = gettimer(ui, opts)
766 m = scmutil.match(repo[None], pats, {})
766 m = scmutil.match(repo[None], pats, {})
767 timer(
767 timer(
768 lambda: len(
768 lambda: len(
769 list(
769 list(
770 repo.dirstate.walk(m, subrepos=[], unknown=True, ignored=False)
770 repo.dirstate.walk(m, subrepos=[], unknown=True, ignored=False)
771 )
771 )
772 )
772 )
773 )
773 )
774 fm.end()
774 fm.end()
775
775
776
776
777 @command(b'perf::annotate|perfannotate', formatteropts)
777 @command(b'perf::annotate|perfannotate', formatteropts)
778 def perfannotate(ui, repo, f, **opts):
778 def perfannotate(ui, repo, f, **opts):
779 opts = _byteskwargs(opts)
779 opts = _byteskwargs(opts)
780 timer, fm = gettimer(ui, opts)
780 timer, fm = gettimer(ui, opts)
781 fc = repo[b'.'][f]
781 fc = repo[b'.'][f]
782 timer(lambda: len(fc.annotate(True)))
782 timer(lambda: len(fc.annotate(True)))
783 fm.end()
783 fm.end()
784
784
785
785
786 @command(
786 @command(
787 b'perf::status|perfstatus',
787 b'perf::status|perfstatus',
788 [
788 [
789 (b'u', b'unknown', False, b'ask status to look for unknown files'),
789 (b'u', b'unknown', False, b'ask status to look for unknown files'),
790 (b'', b'dirstate', False, b'benchmark the internal dirstate call'),
790 (b'', b'dirstate', False, b'benchmark the internal dirstate call'),
791 ]
791 ]
792 + formatteropts,
792 + formatteropts,
793 )
793 )
794 def perfstatus(ui, repo, **opts):
794 def perfstatus(ui, repo, **opts):
795 """benchmark the performance of a single status call
795 """benchmark the performance of a single status call
796
796
797 The repository data are preserved between each call.
797 The repository data are preserved between each call.
798
798
799 By default, only the status of the tracked file are requested. If
799 By default, only the status of the tracked file are requested. If
800 `--unknown` is passed, the "unknown" files are also tracked.
800 `--unknown` is passed, the "unknown" files are also tracked.
801 """
801 """
802 opts = _byteskwargs(opts)
802 opts = _byteskwargs(opts)
803 # m = match.always(repo.root, repo.getcwd())
803 # m = match.always(repo.root, repo.getcwd())
804 # timer(lambda: sum(map(len, repo.dirstate.status(m, [], False, False,
804 # timer(lambda: sum(map(len, repo.dirstate.status(m, [], False, False,
805 # False))))
805 # False))))
806 timer, fm = gettimer(ui, opts)
806 timer, fm = gettimer(ui, opts)
807 if opts[b'dirstate']:
807 if opts[b'dirstate']:
808 dirstate = repo.dirstate
808 dirstate = repo.dirstate
809 m = scmutil.matchall(repo)
809 m = scmutil.matchall(repo)
810 unknown = opts[b'unknown']
810 unknown = opts[b'unknown']
811
811
812 def status_dirstate():
812 def status_dirstate():
813 s = dirstate.status(
813 s = dirstate.status(
814 m, subrepos=[], ignored=False, clean=False, unknown=unknown
814 m, subrepos=[], ignored=False, clean=False, unknown=unknown
815 )
815 )
816 sum(map(bool, s))
816 sum(map(bool, s))
817
817
818 timer(status_dirstate)
818 timer(status_dirstate)
819 else:
819 else:
820 timer(lambda: sum(map(len, repo.status(unknown=opts[b'unknown']))))
820 timer(lambda: sum(map(len, repo.status(unknown=opts[b'unknown']))))
821 fm.end()
821 fm.end()
822
822
823
823
824 @command(b'perf::addremove|perfaddremove', formatteropts)
824 @command(b'perf::addremove|perfaddremove', formatteropts)
825 def perfaddremove(ui, repo, **opts):
825 def perfaddremove(ui, repo, **opts):
826 opts = _byteskwargs(opts)
826 opts = _byteskwargs(opts)
827 timer, fm = gettimer(ui, opts)
827 timer, fm = gettimer(ui, opts)
828 try:
828 try:
829 oldquiet = repo.ui.quiet
829 oldquiet = repo.ui.quiet
830 repo.ui.quiet = True
830 repo.ui.quiet = True
831 matcher = scmutil.match(repo[None])
831 matcher = scmutil.match(repo[None])
832 opts[b'dry_run'] = True
832 opts[b'dry_run'] = True
833 if 'uipathfn' in getargspec(scmutil.addremove).args:
833 if 'uipathfn' in getargspec(scmutil.addremove).args:
834 uipathfn = scmutil.getuipathfn(repo)
834 uipathfn = scmutil.getuipathfn(repo)
835 timer(lambda: scmutil.addremove(repo, matcher, b"", uipathfn, opts))
835 timer(lambda: scmutil.addremove(repo, matcher, b"", uipathfn, opts))
836 else:
836 else:
837 timer(lambda: scmutil.addremove(repo, matcher, b"", opts))
837 timer(lambda: scmutil.addremove(repo, matcher, b"", opts))
838 finally:
838 finally:
839 repo.ui.quiet = oldquiet
839 repo.ui.quiet = oldquiet
840 fm.end()
840 fm.end()
841
841
842
842
843 def clearcaches(cl):
843 def clearcaches(cl):
844 # behave somewhat consistently across internal API changes
844 # behave somewhat consistently across internal API changes
845 if util.safehasattr(cl, b'clearcaches'):
845 if util.safehasattr(cl, b'clearcaches'):
846 cl.clearcaches()
846 cl.clearcaches()
847 elif util.safehasattr(cl, b'_nodecache'):
847 elif util.safehasattr(cl, b'_nodecache'):
848 # <= hg-5.2
848 # <= hg-5.2
849 from mercurial.node import nullid, nullrev
849 from mercurial.node import nullid, nullrev
850
850
851 cl._nodecache = {nullid: nullrev}
851 cl._nodecache = {nullid: nullrev}
852 cl._nodepos = None
852 cl._nodepos = None
853
853
854
854
855 @command(b'perf::heads|perfheads', formatteropts)
855 @command(b'perf::heads|perfheads', formatteropts)
856 def perfheads(ui, repo, **opts):
856 def perfheads(ui, repo, **opts):
857 """benchmark the computation of a changelog heads"""
857 """benchmark the computation of a changelog heads"""
858 opts = _byteskwargs(opts)
858 opts = _byteskwargs(opts)
859 timer, fm = gettimer(ui, opts)
859 timer, fm = gettimer(ui, opts)
860 cl = repo.changelog
860 cl = repo.changelog
861
861
862 def s():
862 def s():
863 clearcaches(cl)
863 clearcaches(cl)
864
864
865 def d():
865 def d():
866 len(cl.headrevs())
866 len(cl.headrevs())
867
867
868 timer(d, setup=s)
868 timer(d, setup=s)
869 fm.end()
869 fm.end()
870
870
871
871
872 @command(
872 @command(
873 b'perf::tags|perftags',
873 b'perf::tags|perftags',
874 formatteropts
874 formatteropts
875 + [
875 + [
876 (b'', b'clear-revlogs', False, b'refresh changelog and manifest'),
876 (b'', b'clear-revlogs', False, b'refresh changelog and manifest'),
877 ],
877 ],
878 )
878 )
879 def perftags(ui, repo, **opts):
879 def perftags(ui, repo, **opts):
880 opts = _byteskwargs(opts)
880 opts = _byteskwargs(opts)
881 timer, fm = gettimer(ui, opts)
881 timer, fm = gettimer(ui, opts)
882 repocleartagscache = repocleartagscachefunc(repo)
882 repocleartagscache = repocleartagscachefunc(repo)
883 clearrevlogs = opts[b'clear_revlogs']
883 clearrevlogs = opts[b'clear_revlogs']
884
884
885 def s():
885 def s():
886 if clearrevlogs:
886 if clearrevlogs:
887 clearchangelog(repo)
887 clearchangelog(repo)
888 clearfilecache(repo.unfiltered(), 'manifest')
888 clearfilecache(repo.unfiltered(), 'manifest')
889 repocleartagscache()
889 repocleartagscache()
890
890
891 def t():
891 def t():
892 return len(repo.tags())
892 return len(repo.tags())
893
893
894 timer(t, setup=s)
894 timer(t, setup=s)
895 fm.end()
895 fm.end()
896
896
897
897
898 @command(b'perf::ancestors|perfancestors', formatteropts)
898 @command(b'perf::ancestors|perfancestors', formatteropts)
899 def perfancestors(ui, repo, **opts):
899 def perfancestors(ui, repo, **opts):
900 opts = _byteskwargs(opts)
900 opts = _byteskwargs(opts)
901 timer, fm = gettimer(ui, opts)
901 timer, fm = gettimer(ui, opts)
902 heads = repo.changelog.headrevs()
902 heads = repo.changelog.headrevs()
903
903
904 def d():
904 def d():
905 for a in repo.changelog.ancestors(heads):
905 for a in repo.changelog.ancestors(heads):
906 pass
906 pass
907
907
908 timer(d)
908 timer(d)
909 fm.end()
909 fm.end()
910
910
911
911
912 @command(b'perf::ancestorset|perfancestorset', formatteropts)
912 @command(b'perf::ancestorset|perfancestorset', formatteropts)
913 def perfancestorset(ui, repo, revset, **opts):
913 def perfancestorset(ui, repo, revset, **opts):
914 opts = _byteskwargs(opts)
914 opts = _byteskwargs(opts)
915 timer, fm = gettimer(ui, opts)
915 timer, fm = gettimer(ui, opts)
916 revs = repo.revs(revset)
916 revs = repo.revs(revset)
917 heads = repo.changelog.headrevs()
917 heads = repo.changelog.headrevs()
918
918
919 def d():
919 def d():
920 s = repo.changelog.ancestors(heads)
920 s = repo.changelog.ancestors(heads)
921 for rev in revs:
921 for rev in revs:
922 rev in s
922 rev in s
923
923
924 timer(d)
924 timer(d)
925 fm.end()
925 fm.end()
926
926
927
927
928 @command(
928 @command(
929 b'perf::delta-find',
929 b'perf::delta-find',
930 revlogopts + formatteropts,
930 revlogopts + formatteropts,
931 b'-c|-m|FILE REV',
931 b'-c|-m|FILE REV',
932 )
932 )
933 def perf_delta_find(ui, repo, arg_1, arg_2=None, **opts):
933 def perf_delta_find(ui, repo, arg_1, arg_2=None, **opts):
934 """benchmark the process of finding a valid delta for a revlog revision
934 """benchmark the process of finding a valid delta for a revlog revision
935
935
936 When a revlog receives a new revision (e.g. from a commit, or from an
936 When a revlog receives a new revision (e.g. from a commit, or from an
937 incoming bundle), it searches for a suitable delta-base to produce a delta.
937 incoming bundle), it searches for a suitable delta-base to produce a delta.
938 This perf command measures how much time we spend in this process. It
938 This perf command measures how much time we spend in this process. It
939 operates on an already stored revision.
939 operates on an already stored revision.
940
940
941 See `hg help debug-delta-find` for another related command.
941 See `hg help debug-delta-find` for another related command.
942 """
942 """
943 from mercurial import revlogutils
943 from mercurial import revlogutils
944 import mercurial.revlogutils.deltas as deltautil
944 import mercurial.revlogutils.deltas as deltautil
945
945
946 opts = _byteskwargs(opts)
946 opts = _byteskwargs(opts)
947 if arg_2 is None:
947 if arg_2 is None:
948 file_ = None
948 file_ = None
949 rev = arg_1
949 rev = arg_1
950 else:
950 else:
951 file_ = arg_1
951 file_ = arg_1
952 rev = arg_2
952 rev = arg_2
953
953
954 repo = repo.unfiltered()
954 repo = repo.unfiltered()
955
955
956 timer, fm = gettimer(ui, opts)
956 timer, fm = gettimer(ui, opts)
957
957
958 rev = int(rev)
958 rev = int(rev)
959
959
960 revlog = cmdutil.openrevlog(repo, b'perf::delta-find', file_, opts)
960 revlog = cmdutil.openrevlog(repo, b'perf::delta-find', file_, opts)
961
961
962 deltacomputer = deltautil.deltacomputer(revlog)
962 deltacomputer = deltautil.deltacomputer(revlog)
963
963
964 node = revlog.node(rev)
964 node = revlog.node(rev)
965 p1r, p2r = revlog.parentrevs(rev)
965 p1r, p2r = revlog.parentrevs(rev)
966 p1 = revlog.node(p1r)
966 p1 = revlog.node(p1r)
967 p2 = revlog.node(p2r)
967 p2 = revlog.node(p2r)
968 full_text = revlog.revision(rev)
968 full_text = revlog.revision(rev)
969 textlen = len(full_text)
969 textlen = len(full_text)
970 cachedelta = None
970 cachedelta = None
971 flags = revlog.flags(rev)
971 flags = revlog.flags(rev)
972
972
973 revinfo = revlogutils.revisioninfo(
973 revinfo = revlogutils.revisioninfo(
974 node,
974 node,
975 p1,
975 p1,
976 p2,
976 p2,
977 [full_text], # btext
977 [full_text], # btext
978 textlen,
978 textlen,
979 cachedelta,
979 cachedelta,
980 flags,
980 flags,
981 )
981 )
982
982
983 # Note: we should probably purge the potential caches (like the full
983 # Note: we should probably purge the potential caches (like the full
984 # manifest cache) between runs.
984 # manifest cache) between runs.
985 def find_one():
985 def find_one():
986 with revlog._datafp() as fh:
986 with revlog._datafp() as fh:
987 deltacomputer.finddeltainfo(revinfo, fh, target_rev=rev)
987 deltacomputer.finddeltainfo(revinfo, fh, target_rev=rev)
988
988
989 timer(find_one)
989 timer(find_one)
990 fm.end()
990 fm.end()
991
991
992
992
993 @command(b'perf::discovery|perfdiscovery', formatteropts, b'PATH')
993 @command(b'perf::discovery|perfdiscovery', formatteropts, b'PATH')
994 def perfdiscovery(ui, repo, path, **opts):
994 def perfdiscovery(ui, repo, path, **opts):
995 """benchmark discovery between local repo and the peer at given path"""
995 """benchmark discovery between local repo and the peer at given path"""
996 repos = [repo, None]
996 repos = [repo, None]
997 timer, fm = gettimer(ui, opts)
997 timer, fm = gettimer(ui, opts)
998
998
999 try:
999 try:
1000 from mercurial.utils.urlutil import get_unique_pull_path
1000 from mercurial.utils.urlutil import get_unique_pull_path
1001
1001
1002 path = get_unique_pull_path(b'perfdiscovery', repo, ui, path)[0]
1002 path = get_unique_pull_path(b'perfdiscovery', repo, ui, path)[0]
1003 except ImportError:
1003 except ImportError:
1004 path = ui.expandpath(path)
1004 path = ui.expandpath(path)
1005
1005
1006 def s():
1006 def s():
1007 repos[1] = hg.peer(ui, opts, path)
1007 repos[1] = hg.peer(ui, opts, path)
1008
1008
1009 def d():
1009 def d():
1010 setdiscovery.findcommonheads(ui, *repos)
1010 setdiscovery.findcommonheads(ui, *repos)
1011
1011
1012 timer(d, setup=s)
1012 timer(d, setup=s)
1013 fm.end()
1013 fm.end()
1014
1014
1015
1015
1016 @command(
1016 @command(
1017 b'perf::bookmarks|perfbookmarks',
1017 b'perf::bookmarks|perfbookmarks',
1018 formatteropts
1018 formatteropts
1019 + [
1019 + [
1020 (b'', b'clear-revlogs', False, b'refresh changelog and manifest'),
1020 (b'', b'clear-revlogs', False, b'refresh changelog and manifest'),
1021 ],
1021 ],
1022 )
1022 )
1023 def perfbookmarks(ui, repo, **opts):
1023 def perfbookmarks(ui, repo, **opts):
1024 """benchmark parsing bookmarks from disk to memory"""
1024 """benchmark parsing bookmarks from disk to memory"""
1025 opts = _byteskwargs(opts)
1025 opts = _byteskwargs(opts)
1026 timer, fm = gettimer(ui, opts)
1026 timer, fm = gettimer(ui, opts)
1027
1027
1028 clearrevlogs = opts[b'clear_revlogs']
1028 clearrevlogs = opts[b'clear_revlogs']
1029
1029
1030 def s():
1030 def s():
1031 if clearrevlogs:
1031 if clearrevlogs:
1032 clearchangelog(repo)
1032 clearchangelog(repo)
1033 clearfilecache(repo, b'_bookmarks')
1033 clearfilecache(repo, b'_bookmarks')
1034
1034
1035 def d():
1035 def d():
1036 repo._bookmarks
1036 repo._bookmarks
1037
1037
1038 timer(d, setup=s)
1038 timer(d, setup=s)
1039 fm.end()
1039 fm.end()
1040
1040
1041
1041
1042 @command(
1042 @command(
1043 b'perf::bundle',
1043 b'perf::bundle',
1044 [
1044 [
1045 (
1045 (
1046 b'r',
1046 b'r',
1047 b'rev',
1047 b'rev',
1048 [],
1048 [],
1049 b'changesets to bundle',
1049 b'changesets to bundle',
1050 b'REV',
1050 b'REV',
1051 ),
1051 ),
1052 (
1052 (
1053 b't',
1053 b't',
1054 b'type',
1054 b'type',
1055 b'none',
1055 b'none',
1056 b'bundlespec to use (see `hg help bundlespec`)',
1056 b'bundlespec to use (see `hg help bundlespec`)',
1057 b'TYPE',
1057 b'TYPE',
1058 ),
1058 ),
1059 ]
1059 ]
1060 + formatteropts,
1060 + formatteropts,
1061 b'REVS',
1061 b'REVS',
1062 )
1062 )
1063 def perfbundle(ui, repo, *revs, **opts):
1063 def perfbundle(ui, repo, *revs, **opts):
1064 """benchmark the creation of a bundle from a repository
1064 """benchmark the creation of a bundle from a repository
1065
1065
1066 For now, this only supports "none" compression.
1066 For now, this only supports "none" compression.
1067 """
1067 """
1068 try:
1068 try:
1069 from mercurial import bundlecaches
1069 from mercurial import bundlecaches
1070
1070
1071 parsebundlespec = bundlecaches.parsebundlespec
1071 parsebundlespec = bundlecaches.parsebundlespec
1072 except ImportError:
1072 except ImportError:
1073 from mercurial import exchange
1073 from mercurial import exchange
1074
1074
1075 parsebundlespec = exchange.parsebundlespec
1075 parsebundlespec = exchange.parsebundlespec
1076
1076
1077 from mercurial import discovery
1077 from mercurial import discovery
1078 from mercurial import bundle2
1078 from mercurial import bundle2
1079
1079
1080 opts = _byteskwargs(opts)
1080 opts = _byteskwargs(opts)
1081 timer, fm = gettimer(ui, opts)
1081 timer, fm = gettimer(ui, opts)
1082
1082
1083 cl = repo.changelog
1083 cl = repo.changelog
1084 revs = list(revs)
1084 revs = list(revs)
1085 revs.extend(opts.get(b'rev', ()))
1085 revs.extend(opts.get(b'rev', ()))
1086 revs = scmutil.revrange(repo, revs)
1086 revs = scmutil.revrange(repo, revs)
1087 if not revs:
1087 if not revs:
1088 raise error.Abort(b"not revision specified")
1088 raise error.Abort(b"not revision specified")
1089 # make it a consistent set (ie: without topological gaps)
1089 # make it a consistent set (ie: without topological gaps)
1090 old_len = len(revs)
1090 old_len = len(revs)
1091 revs = list(repo.revs(b"%ld::%ld", revs, revs))
1091 revs = list(repo.revs(b"%ld::%ld", revs, revs))
1092 if old_len != len(revs):
1092 if old_len != len(revs):
1093 new_count = len(revs) - old_len
1093 new_count = len(revs) - old_len
1094 msg = b"add %d new revisions to make it a consistent set\n"
1094 msg = b"add %d new revisions to make it a consistent set\n"
1095 ui.write_err(msg % new_count)
1095 ui.write_err(msg % new_count)
1096
1096
1097 targets = [cl.node(r) for r in repo.revs(b"heads(::%ld)", revs)]
1097 targets = [cl.node(r) for r in repo.revs(b"heads(::%ld)", revs)]
1098 bases = [cl.node(r) for r in repo.revs(b"heads(::%ld - %ld)", revs, revs)]
1098 bases = [cl.node(r) for r in repo.revs(b"heads(::%ld - %ld)", revs, revs)]
1099 outgoing = discovery.outgoing(repo, bases, targets)
1099 outgoing = discovery.outgoing(repo, bases, targets)
1100
1100
1101 bundle_spec = opts.get(b'type')
1101 bundle_spec = opts.get(b'type')
1102
1102
1103 bundle_spec = parsebundlespec(repo, bundle_spec, strict=False)
1103 bundle_spec = parsebundlespec(repo, bundle_spec, strict=False)
1104
1104
1105 cgversion = bundle_spec.params.get(b"cg.version")
1105 cgversion = bundle_spec.params.get(b"cg.version")
1106 if cgversion is None:
1106 if cgversion is None:
1107 if bundle_spec.version == b'v1':
1107 if bundle_spec.version == b'v1':
1108 cgversion = b'01'
1108 cgversion = b'01'
1109 if bundle_spec.version == b'v2':
1109 if bundle_spec.version == b'v2':
1110 cgversion = b'02'
1110 cgversion = b'02'
1111 if cgversion not in changegroup.supportedoutgoingversions(repo):
1111 if cgversion not in changegroup.supportedoutgoingversions(repo):
1112 err = b"repository does not support bundle version %s"
1112 err = b"repository does not support bundle version %s"
1113 raise error.Abort(err % cgversion)
1113 raise error.Abort(err % cgversion)
1114
1114
1115 if cgversion == b'01': # bundle1
1115 if cgversion == b'01': # bundle1
1116 bversion = b'HG10' + bundle_spec.wirecompression
1116 bversion = b'HG10' + bundle_spec.wirecompression
1117 bcompression = None
1117 bcompression = None
1118 elif cgversion in (b'02', b'03'):
1118 elif cgversion in (b'02', b'03'):
1119 bversion = b'HG20'
1119 bversion = b'HG20'
1120 bcompression = bundle_spec.wirecompression
1120 bcompression = bundle_spec.wirecompression
1121 else:
1121 else:
1122 err = b'perf::bundle: unexpected changegroup version %s'
1122 err = b'perf::bundle: unexpected changegroup version %s'
1123 raise error.ProgrammingError(err % cgversion)
1123 raise error.ProgrammingError(err % cgversion)
1124
1124
1125 if bcompression is None:
1125 if bcompression is None:
1126 bcompression = b'UN'
1126 bcompression = b'UN'
1127
1127
1128 if bcompression != b'UN':
1128 if bcompression != b'UN':
1129 err = b'perf::bundle: compression currently unsupported: %s'
1129 err = b'perf::bundle: compression currently unsupported: %s'
1130 raise error.ProgrammingError(err % bcompression)
1130 raise error.ProgrammingError(err % bcompression)
1131
1131
1132 def do_bundle():
1132 def do_bundle():
1133 bundle2.writenewbundle(
1133 bundle2.writenewbundle(
1134 ui,
1134 ui,
1135 repo,
1135 repo,
1136 b'perf::bundle',
1136 b'perf::bundle',
1137 os.devnull,
1137 os.devnull,
1138 bversion,
1138 bversion,
1139 outgoing,
1139 outgoing,
1140 bundle_spec.params,
1140 bundle_spec.params,
1141 )
1141 )
1142
1142
1143 timer(do_bundle)
1143 timer(do_bundle)
1144 fm.end()
1144 fm.end()
1145
1145
1146
1146
1147 @command(b'perf::bundleread|perfbundleread', formatteropts, b'BUNDLE')
1147 @command(b'perf::bundleread|perfbundleread', formatteropts, b'BUNDLE')
1148 def perfbundleread(ui, repo, bundlepath, **opts):
1148 def perfbundleread(ui, repo, bundlepath, **opts):
1149 """Benchmark reading of bundle files.
1149 """Benchmark reading of bundle files.
1150
1150
1151 This command is meant to isolate the I/O part of bundle reading as
1151 This command is meant to isolate the I/O part of bundle reading as
1152 much as possible.
1152 much as possible.
1153 """
1153 """
1154 from mercurial import (
1154 from mercurial import (
1155 bundle2,
1155 bundle2,
1156 exchange,
1156 exchange,
1157 streamclone,
1157 streamclone,
1158 )
1158 )
1159
1159
1160 opts = _byteskwargs(opts)
1160 opts = _byteskwargs(opts)
1161
1161
1162 def makebench(fn):
1162 def makebench(fn):
1163 def run():
1163 def run():
1164 with open(bundlepath, b'rb') as fh:
1164 with open(bundlepath, b'rb') as fh:
1165 bundle = exchange.readbundle(ui, fh, bundlepath)
1165 bundle = exchange.readbundle(ui, fh, bundlepath)
1166 fn(bundle)
1166 fn(bundle)
1167
1167
1168 return run
1168 return run
1169
1169
1170 def makereadnbytes(size):
1170 def makereadnbytes(size):
1171 def run():
1171 def run():
1172 with open(bundlepath, b'rb') as fh:
1172 with open(bundlepath, b'rb') as fh:
1173 bundle = exchange.readbundle(ui, fh, bundlepath)
1173 bundle = exchange.readbundle(ui, fh, bundlepath)
1174 while bundle.read(size):
1174 while bundle.read(size):
1175 pass
1175 pass
1176
1176
1177 return run
1177 return run
1178
1178
1179 def makestdioread(size):
1179 def makestdioread(size):
1180 def run():
1180 def run():
1181 with open(bundlepath, b'rb') as fh:
1181 with open(bundlepath, b'rb') as fh:
1182 while fh.read(size):
1182 while fh.read(size):
1183 pass
1183 pass
1184
1184
1185 return run
1185 return run
1186
1186
1187 # bundle1
1187 # bundle1
1188
1188
1189 def deltaiter(bundle):
1189 def deltaiter(bundle):
1190 for delta in bundle.deltaiter():
1190 for delta in bundle.deltaiter():
1191 pass
1191 pass
1192
1192
1193 def iterchunks(bundle):
1193 def iterchunks(bundle):
1194 for chunk in bundle.getchunks():
1194 for chunk in bundle.getchunks():
1195 pass
1195 pass
1196
1196
1197 # bundle2
1197 # bundle2
1198
1198
1199 def forwardchunks(bundle):
1199 def forwardchunks(bundle):
1200 for chunk in bundle._forwardchunks():
1200 for chunk in bundle._forwardchunks():
1201 pass
1201 pass
1202
1202
1203 def iterparts(bundle):
1203 def iterparts(bundle):
1204 for part in bundle.iterparts():
1204 for part in bundle.iterparts():
1205 pass
1205 pass
1206
1206
1207 def iterpartsseekable(bundle):
1207 def iterpartsseekable(bundle):
1208 for part in bundle.iterparts(seekable=True):
1208 for part in bundle.iterparts(seekable=True):
1209 pass
1209 pass
1210
1210
1211 def seek(bundle):
1211 def seek(bundle):
1212 for part in bundle.iterparts(seekable=True):
1212 for part in bundle.iterparts(seekable=True):
1213 part.seek(0, os.SEEK_END)
1213 part.seek(0, os.SEEK_END)
1214
1214
1215 def makepartreadnbytes(size):
1215 def makepartreadnbytes(size):
1216 def run():
1216 def run():
1217 with open(bundlepath, b'rb') as fh:
1217 with open(bundlepath, b'rb') as fh:
1218 bundle = exchange.readbundle(ui, fh, bundlepath)
1218 bundle = exchange.readbundle(ui, fh, bundlepath)
1219 for part in bundle.iterparts():
1219 for part in bundle.iterparts():
1220 while part.read(size):
1220 while part.read(size):
1221 pass
1221 pass
1222
1222
1223 return run
1223 return run
1224
1224
1225 benches = [
1225 benches = [
1226 (makestdioread(8192), b'read(8k)'),
1226 (makestdioread(8192), b'read(8k)'),
1227 (makestdioread(16384), b'read(16k)'),
1227 (makestdioread(16384), b'read(16k)'),
1228 (makestdioread(32768), b'read(32k)'),
1228 (makestdioread(32768), b'read(32k)'),
1229 (makestdioread(131072), b'read(128k)'),
1229 (makestdioread(131072), b'read(128k)'),
1230 ]
1230 ]
1231
1231
1232 with open(bundlepath, b'rb') as fh:
1232 with open(bundlepath, b'rb') as fh:
1233 bundle = exchange.readbundle(ui, fh, bundlepath)
1233 bundle = exchange.readbundle(ui, fh, bundlepath)
1234
1234
1235 if isinstance(bundle, changegroup.cg1unpacker):
1235 if isinstance(bundle, changegroup.cg1unpacker):
1236 benches.extend(
1236 benches.extend(
1237 [
1237 [
1238 (makebench(deltaiter), b'cg1 deltaiter()'),
1238 (makebench(deltaiter), b'cg1 deltaiter()'),
1239 (makebench(iterchunks), b'cg1 getchunks()'),
1239 (makebench(iterchunks), b'cg1 getchunks()'),
1240 (makereadnbytes(8192), b'cg1 read(8k)'),
1240 (makereadnbytes(8192), b'cg1 read(8k)'),
1241 (makereadnbytes(16384), b'cg1 read(16k)'),
1241 (makereadnbytes(16384), b'cg1 read(16k)'),
1242 (makereadnbytes(32768), b'cg1 read(32k)'),
1242 (makereadnbytes(32768), b'cg1 read(32k)'),
1243 (makereadnbytes(131072), b'cg1 read(128k)'),
1243 (makereadnbytes(131072), b'cg1 read(128k)'),
1244 ]
1244 ]
1245 )
1245 )
1246 elif isinstance(bundle, bundle2.unbundle20):
1246 elif isinstance(bundle, bundle2.unbundle20):
1247 benches.extend(
1247 benches.extend(
1248 [
1248 [
1249 (makebench(forwardchunks), b'bundle2 forwardchunks()'),
1249 (makebench(forwardchunks), b'bundle2 forwardchunks()'),
1250 (makebench(iterparts), b'bundle2 iterparts()'),
1250 (makebench(iterparts), b'bundle2 iterparts()'),
1251 (
1251 (
1252 makebench(iterpartsseekable),
1252 makebench(iterpartsseekable),
1253 b'bundle2 iterparts() seekable',
1253 b'bundle2 iterparts() seekable',
1254 ),
1254 ),
1255 (makebench(seek), b'bundle2 part seek()'),
1255 (makebench(seek), b'bundle2 part seek()'),
1256 (makepartreadnbytes(8192), b'bundle2 part read(8k)'),
1256 (makepartreadnbytes(8192), b'bundle2 part read(8k)'),
1257 (makepartreadnbytes(16384), b'bundle2 part read(16k)'),
1257 (makepartreadnbytes(16384), b'bundle2 part read(16k)'),
1258 (makepartreadnbytes(32768), b'bundle2 part read(32k)'),
1258 (makepartreadnbytes(32768), b'bundle2 part read(32k)'),
1259 (makepartreadnbytes(131072), b'bundle2 part read(128k)'),
1259 (makepartreadnbytes(131072), b'bundle2 part read(128k)'),
1260 ]
1260 ]
1261 )
1261 )
1262 elif isinstance(bundle, streamclone.streamcloneapplier):
1262 elif isinstance(bundle, streamclone.streamcloneapplier):
1263 raise error.Abort(b'stream clone bundles not supported')
1263 raise error.Abort(b'stream clone bundles not supported')
1264 else:
1264 else:
1265 raise error.Abort(b'unhandled bundle type: %s' % type(bundle))
1265 raise error.Abort(b'unhandled bundle type: %s' % type(bundle))
1266
1266
1267 for fn, title in benches:
1267 for fn, title in benches:
1268 timer, fm = gettimer(ui, opts)
1268 timer, fm = gettimer(ui, opts)
1269 timer(fn, title=title)
1269 timer(fn, title=title)
1270 fm.end()
1270 fm.end()
1271
1271
1272
1272
1273 @command(
1273 @command(
1274 b'perf::changegroupchangelog|perfchangegroupchangelog',
1274 b'perf::changegroupchangelog|perfchangegroupchangelog',
1275 formatteropts
1275 formatteropts
1276 + [
1276 + [
1277 (b'', b'cgversion', b'02', b'changegroup version'),
1277 (b'', b'cgversion', b'02', b'changegroup version'),
1278 (b'r', b'rev', b'', b'revisions to add to changegroup'),
1278 (b'r', b'rev', b'', b'revisions to add to changegroup'),
1279 ],
1279 ],
1280 )
1280 )
1281 def perfchangegroupchangelog(ui, repo, cgversion=b'02', rev=None, **opts):
1281 def perfchangegroupchangelog(ui, repo, cgversion=b'02', rev=None, **opts):
1282 """Benchmark producing a changelog group for a changegroup.
1282 """Benchmark producing a changelog group for a changegroup.
1283
1283
1284 This measures the time spent processing the changelog during a
1284 This measures the time spent processing the changelog during a
1285 bundle operation. This occurs during `hg bundle` and on a server
1285 bundle operation. This occurs during `hg bundle` and on a server
1286 processing a `getbundle` wire protocol request (handles clones
1286 processing a `getbundle` wire protocol request (handles clones
1287 and pull requests).
1287 and pull requests).
1288
1288
1289 By default, all revisions are added to the changegroup.
1289 By default, all revisions are added to the changegroup.
1290 """
1290 """
1291 opts = _byteskwargs(opts)
1291 opts = _byteskwargs(opts)
1292 cl = repo.changelog
1292 cl = repo.changelog
1293 nodes = [cl.lookup(r) for r in repo.revs(rev or b'all()')]
1293 nodes = [cl.lookup(r) for r in repo.revs(rev or b'all()')]
1294 bundler = changegroup.getbundler(cgversion, repo)
1294 bundler = changegroup.getbundler(cgversion, repo)
1295
1295
1296 def d():
1296 def d():
1297 state, chunks = bundler._generatechangelog(cl, nodes)
1297 state, chunks = bundler._generatechangelog(cl, nodes)
1298 for chunk in chunks:
1298 for chunk in chunks:
1299 pass
1299 pass
1300
1300
1301 timer, fm = gettimer(ui, opts)
1301 timer, fm = gettimer(ui, opts)
1302
1302
1303 # Terminal printing can interfere with timing. So disable it.
1303 # Terminal printing can interfere with timing. So disable it.
1304 with ui.configoverride({(b'progress', b'disable'): True}):
1304 with ui.configoverride({(b'progress', b'disable'): True}):
1305 timer(d)
1305 timer(d)
1306
1306
1307 fm.end()
1307 fm.end()
1308
1308
1309
1309
1310 @command(b'perf::dirs|perfdirs', formatteropts)
1310 @command(b'perf::dirs|perfdirs', formatteropts)
1311 def perfdirs(ui, repo, **opts):
1311 def perfdirs(ui, repo, **opts):
1312 opts = _byteskwargs(opts)
1312 opts = _byteskwargs(opts)
1313 timer, fm = gettimer(ui, opts)
1313 timer, fm = gettimer(ui, opts)
1314 dirstate = repo.dirstate
1314 dirstate = repo.dirstate
1315 b'a' in dirstate
1315 b'a' in dirstate
1316
1316
1317 def d():
1317 def d():
1318 dirstate.hasdir(b'a')
1318 dirstate.hasdir(b'a')
1319 try:
1319 try:
1320 del dirstate._map._dirs
1320 del dirstate._map._dirs
1321 except AttributeError:
1321 except AttributeError:
1322 pass
1322 pass
1323
1323
1324 timer(d)
1324 timer(d)
1325 fm.end()
1325 fm.end()
1326
1326
1327
1327
1328 @command(
1328 @command(
1329 b'perf::dirstate|perfdirstate',
1329 b'perf::dirstate|perfdirstate',
1330 [
1330 [
1331 (
1331 (
1332 b'',
1332 b'',
1333 b'iteration',
1333 b'iteration',
1334 None,
1334 None,
1335 b'benchmark a full iteration for the dirstate',
1335 b'benchmark a full iteration for the dirstate',
1336 ),
1336 ),
1337 (
1337 (
1338 b'',
1338 b'',
1339 b'contains',
1339 b'contains',
1340 None,
1340 None,
1341 b'benchmark a large amount of `nf in dirstate` calls',
1341 b'benchmark a large amount of `nf in dirstate` calls',
1342 ),
1342 ),
1343 ]
1343 ]
1344 + formatteropts,
1344 + formatteropts,
1345 )
1345 )
1346 def perfdirstate(ui, repo, **opts):
1346 def perfdirstate(ui, repo, **opts):
1347 """benchmap the time of various distate operations
1347 """benchmap the time of various distate operations
1348
1348
1349 By default benchmark the time necessary to load a dirstate from scratch.
1349 By default benchmark the time necessary to load a dirstate from scratch.
1350 The dirstate is loaded to the point were a "contains" request can be
1350 The dirstate is loaded to the point were a "contains" request can be
1351 answered.
1351 answered.
1352 """
1352 """
1353 opts = _byteskwargs(opts)
1353 opts = _byteskwargs(opts)
1354 timer, fm = gettimer(ui, opts)
1354 timer, fm = gettimer(ui, opts)
1355 b"a" in repo.dirstate
1355 b"a" in repo.dirstate
1356
1356
1357 if opts[b'iteration'] and opts[b'contains']:
1357 if opts[b'iteration'] and opts[b'contains']:
1358 msg = b'only specify one of --iteration or --contains'
1358 msg = b'only specify one of --iteration or --contains'
1359 raise error.Abort(msg)
1359 raise error.Abort(msg)
1360
1360
1361 if opts[b'iteration']:
1361 if opts[b'iteration']:
1362 setup = None
1362 setup = None
1363 dirstate = repo.dirstate
1363 dirstate = repo.dirstate
1364
1364
1365 def d():
1365 def d():
1366 for f in dirstate:
1366 for f in dirstate:
1367 pass
1367 pass
1368
1368
1369 elif opts[b'contains']:
1369 elif opts[b'contains']:
1370 setup = None
1370 setup = None
1371 dirstate = repo.dirstate
1371 dirstate = repo.dirstate
1372 allfiles = list(dirstate)
1372 allfiles = list(dirstate)
1373 # also add file path that will be "missing" from the dirstate
1373 # also add file path that will be "missing" from the dirstate
1374 allfiles.extend([f[::-1] for f in allfiles])
1374 allfiles.extend([f[::-1] for f in allfiles])
1375
1375
1376 def d():
1376 def d():
1377 for f in allfiles:
1377 for f in allfiles:
1378 f in dirstate
1378 f in dirstate
1379
1379
1380 else:
1380 else:
1381
1381
1382 def setup():
1382 def setup():
1383 repo.dirstate.invalidate()
1383 repo.dirstate.invalidate()
1384
1384
1385 def d():
1385 def d():
1386 b"a" in repo.dirstate
1386 b"a" in repo.dirstate
1387
1387
1388 timer(d, setup=setup)
1388 timer(d, setup=setup)
1389 fm.end()
1389 fm.end()
1390
1390
1391
1391
1392 @command(b'perf::dirstatedirs|perfdirstatedirs', formatteropts)
1392 @command(b'perf::dirstatedirs|perfdirstatedirs', formatteropts)
1393 def perfdirstatedirs(ui, repo, **opts):
1393 def perfdirstatedirs(ui, repo, **opts):
1394 """benchmap a 'dirstate.hasdir' call from an empty `dirs` cache"""
1394 """benchmap a 'dirstate.hasdir' call from an empty `dirs` cache"""
1395 opts = _byteskwargs(opts)
1395 opts = _byteskwargs(opts)
1396 timer, fm = gettimer(ui, opts)
1396 timer, fm = gettimer(ui, opts)
1397 repo.dirstate.hasdir(b"a")
1397 repo.dirstate.hasdir(b"a")
1398
1398
1399 def setup():
1399 def setup():
1400 try:
1400 try:
1401 del repo.dirstate._map._dirs
1401 del repo.dirstate._map._dirs
1402 except AttributeError:
1402 except AttributeError:
1403 pass
1403 pass
1404
1404
1405 def d():
1405 def d():
1406 repo.dirstate.hasdir(b"a")
1406 repo.dirstate.hasdir(b"a")
1407
1407
1408 timer(d, setup=setup)
1408 timer(d, setup=setup)
1409 fm.end()
1409 fm.end()
1410
1410
1411
1411
1412 @command(b'perf::dirstatefoldmap|perfdirstatefoldmap', formatteropts)
1412 @command(b'perf::dirstatefoldmap|perfdirstatefoldmap', formatteropts)
1413 def perfdirstatefoldmap(ui, repo, **opts):
1413 def perfdirstatefoldmap(ui, repo, **opts):
1414 """benchmap a `dirstate._map.filefoldmap.get()` request
1414 """benchmap a `dirstate._map.filefoldmap.get()` request
1415
1415
1416 The dirstate filefoldmap cache is dropped between every request.
1416 The dirstate filefoldmap cache is dropped between every request.
1417 """
1417 """
1418 opts = _byteskwargs(opts)
1418 opts = _byteskwargs(opts)
1419 timer, fm = gettimer(ui, opts)
1419 timer, fm = gettimer(ui, opts)
1420 dirstate = repo.dirstate
1420 dirstate = repo.dirstate
1421 dirstate._map.filefoldmap.get(b'a')
1421 dirstate._map.filefoldmap.get(b'a')
1422
1422
1423 def setup():
1423 def setup():
1424 del dirstate._map.filefoldmap
1424 del dirstate._map.filefoldmap
1425
1425
1426 def d():
1426 def d():
1427 dirstate._map.filefoldmap.get(b'a')
1427 dirstate._map.filefoldmap.get(b'a')
1428
1428
1429 timer(d, setup=setup)
1429 timer(d, setup=setup)
1430 fm.end()
1430 fm.end()
1431
1431
1432
1432
1433 @command(b'perf::dirfoldmap|perfdirfoldmap', formatteropts)
1433 @command(b'perf::dirfoldmap|perfdirfoldmap', formatteropts)
1434 def perfdirfoldmap(ui, repo, **opts):
1434 def perfdirfoldmap(ui, repo, **opts):
1435 """benchmap a `dirstate._map.dirfoldmap.get()` request
1435 """benchmap a `dirstate._map.dirfoldmap.get()` request
1436
1436
1437 The dirstate dirfoldmap cache is dropped between every request.
1437 The dirstate dirfoldmap cache is dropped between every request.
1438 """
1438 """
1439 opts = _byteskwargs(opts)
1439 opts = _byteskwargs(opts)
1440 timer, fm = gettimer(ui, opts)
1440 timer, fm = gettimer(ui, opts)
1441 dirstate = repo.dirstate
1441 dirstate = repo.dirstate
1442 dirstate._map.dirfoldmap.get(b'a')
1442 dirstate._map.dirfoldmap.get(b'a')
1443
1443
1444 def setup():
1444 def setup():
1445 del dirstate._map.dirfoldmap
1445 del dirstate._map.dirfoldmap
1446 try:
1446 try:
1447 del dirstate._map._dirs
1447 del dirstate._map._dirs
1448 except AttributeError:
1448 except AttributeError:
1449 pass
1449 pass
1450
1450
1451 def d():
1451 def d():
1452 dirstate._map.dirfoldmap.get(b'a')
1452 dirstate._map.dirfoldmap.get(b'a')
1453
1453
1454 timer(d, setup=setup)
1454 timer(d, setup=setup)
1455 fm.end()
1455 fm.end()
1456
1456
1457
1457
1458 @command(b'perf::dirstatewrite|perfdirstatewrite', formatteropts)
1458 @command(b'perf::dirstatewrite|perfdirstatewrite', formatteropts)
1459 def perfdirstatewrite(ui, repo, **opts):
1459 def perfdirstatewrite(ui, repo, **opts):
1460 """benchmap the time it take to write a dirstate on disk"""
1460 """benchmap the time it take to write a dirstate on disk"""
1461 opts = _byteskwargs(opts)
1461 opts = _byteskwargs(opts)
1462 timer, fm = gettimer(ui, opts)
1462 timer, fm = gettimer(ui, opts)
1463 ds = repo.dirstate
1463 ds = repo.dirstate
1464 b"a" in ds
1464 b"a" in ds
1465
1465
1466 def setup():
1466 def setup():
1467 ds._dirty = True
1467 ds._dirty = True
1468
1468
1469 def d():
1469 def d():
1470 ds.write(repo.currenttransaction())
1470 ds.write(repo.currenttransaction())
1471
1471
1472 timer(d, setup=setup)
1472 timer(d, setup=setup)
1473 fm.end()
1473 fm.end()
1474
1474
1475
1475
1476 def _getmergerevs(repo, opts):
1476 def _getmergerevs(repo, opts):
1477 """parse command argument to return rev involved in merge
1477 """parse command argument to return rev involved in merge
1478
1478
1479 input: options dictionnary with `rev`, `from` and `bse`
1479 input: options dictionnary with `rev`, `from` and `bse`
1480 output: (localctx, otherctx, basectx)
1480 output: (localctx, otherctx, basectx)
1481 """
1481 """
1482 if opts[b'from']:
1482 if opts[b'from']:
1483 fromrev = scmutil.revsingle(repo, opts[b'from'])
1483 fromrev = scmutil.revsingle(repo, opts[b'from'])
1484 wctx = repo[fromrev]
1484 wctx = repo[fromrev]
1485 else:
1485 else:
1486 wctx = repo[None]
1486 wctx = repo[None]
1487 # we don't want working dir files to be stat'd in the benchmark, so
1487 # we don't want working dir files to be stat'd in the benchmark, so
1488 # prime that cache
1488 # prime that cache
1489 wctx.dirty()
1489 wctx.dirty()
1490 rctx = scmutil.revsingle(repo, opts[b'rev'], opts[b'rev'])
1490 rctx = scmutil.revsingle(repo, opts[b'rev'], opts[b'rev'])
1491 if opts[b'base']:
1491 if opts[b'base']:
1492 fromrev = scmutil.revsingle(repo, opts[b'base'])
1492 fromrev = scmutil.revsingle(repo, opts[b'base'])
1493 ancestor = repo[fromrev]
1493 ancestor = repo[fromrev]
1494 else:
1494 else:
1495 ancestor = wctx.ancestor(rctx)
1495 ancestor = wctx.ancestor(rctx)
1496 return (wctx, rctx, ancestor)
1496 return (wctx, rctx, ancestor)
1497
1497
1498
1498
1499 @command(
1499 @command(
1500 b'perf::mergecalculate|perfmergecalculate',
1500 b'perf::mergecalculate|perfmergecalculate',
1501 [
1501 [
1502 (b'r', b'rev', b'.', b'rev to merge against'),
1502 (b'r', b'rev', b'.', b'rev to merge against'),
1503 (b'', b'from', b'', b'rev to merge from'),
1503 (b'', b'from', b'', b'rev to merge from'),
1504 (b'', b'base', b'', b'the revision to use as base'),
1504 (b'', b'base', b'', b'the revision to use as base'),
1505 ]
1505 ]
1506 + formatteropts,
1506 + formatteropts,
1507 )
1507 )
1508 def perfmergecalculate(ui, repo, **opts):
1508 def perfmergecalculate(ui, repo, **opts):
1509 opts = _byteskwargs(opts)
1509 opts = _byteskwargs(opts)
1510 timer, fm = gettimer(ui, opts)
1510 timer, fm = gettimer(ui, opts)
1511
1511
1512 wctx, rctx, ancestor = _getmergerevs(repo, opts)
1512 wctx, rctx, ancestor = _getmergerevs(repo, opts)
1513
1513
1514 def d():
1514 def d():
1515 # acceptremote is True because we don't want prompts in the middle of
1515 # acceptremote is True because we don't want prompts in the middle of
1516 # our benchmark
1516 # our benchmark
1517 merge.calculateupdates(
1517 merge.calculateupdates(
1518 repo,
1518 repo,
1519 wctx,
1519 wctx,
1520 rctx,
1520 rctx,
1521 [ancestor],
1521 [ancestor],
1522 branchmerge=False,
1522 branchmerge=False,
1523 force=False,
1523 force=False,
1524 acceptremote=True,
1524 acceptremote=True,
1525 followcopies=True,
1525 followcopies=True,
1526 )
1526 )
1527
1527
1528 timer(d)
1528 timer(d)
1529 fm.end()
1529 fm.end()
1530
1530
1531
1531
1532 @command(
1532 @command(
1533 b'perf::mergecopies|perfmergecopies',
1533 b'perf::mergecopies|perfmergecopies',
1534 [
1534 [
1535 (b'r', b'rev', b'.', b'rev to merge against'),
1535 (b'r', b'rev', b'.', b'rev to merge against'),
1536 (b'', b'from', b'', b'rev to merge from'),
1536 (b'', b'from', b'', b'rev to merge from'),
1537 (b'', b'base', b'', b'the revision to use as base'),
1537 (b'', b'base', b'', b'the revision to use as base'),
1538 ]
1538 ]
1539 + formatteropts,
1539 + formatteropts,
1540 )
1540 )
1541 def perfmergecopies(ui, repo, **opts):
1541 def perfmergecopies(ui, repo, **opts):
1542 """measure runtime of `copies.mergecopies`"""
1542 """measure runtime of `copies.mergecopies`"""
1543 opts = _byteskwargs(opts)
1543 opts = _byteskwargs(opts)
1544 timer, fm = gettimer(ui, opts)
1544 timer, fm = gettimer(ui, opts)
1545 wctx, rctx, ancestor = _getmergerevs(repo, opts)
1545 wctx, rctx, ancestor = _getmergerevs(repo, opts)
1546
1546
1547 def d():
1547 def d():
1548 # acceptremote is True because we don't want prompts in the middle of
1548 # acceptremote is True because we don't want prompts in the middle of
1549 # our benchmark
1549 # our benchmark
1550 copies.mergecopies(repo, wctx, rctx, ancestor)
1550 copies.mergecopies(repo, wctx, rctx, ancestor)
1551
1551
1552 timer(d)
1552 timer(d)
1553 fm.end()
1553 fm.end()
1554
1554
1555
1555
1556 @command(b'perf::pathcopies|perfpathcopies', [], b"REV REV")
1556 @command(b'perf::pathcopies|perfpathcopies', [], b"REV REV")
1557 def perfpathcopies(ui, repo, rev1, rev2, **opts):
1557 def perfpathcopies(ui, repo, rev1, rev2, **opts):
1558 """benchmark the copy tracing logic"""
1558 """benchmark the copy tracing logic"""
1559 opts = _byteskwargs(opts)
1559 opts = _byteskwargs(opts)
1560 timer, fm = gettimer(ui, opts)
1560 timer, fm = gettimer(ui, opts)
1561 ctx1 = scmutil.revsingle(repo, rev1, rev1)
1561 ctx1 = scmutil.revsingle(repo, rev1, rev1)
1562 ctx2 = scmutil.revsingle(repo, rev2, rev2)
1562 ctx2 = scmutil.revsingle(repo, rev2, rev2)
1563
1563
1564 def d():
1564 def d():
1565 copies.pathcopies(ctx1, ctx2)
1565 copies.pathcopies(ctx1, ctx2)
1566
1566
1567 timer(d)
1567 timer(d)
1568 fm.end()
1568 fm.end()
1569
1569
1570
1570
1571 @command(
1571 @command(
1572 b'perf::phases|perfphases',
1572 b'perf::phases|perfphases',
1573 [
1573 [
1574 (b'', b'full', False, b'include file reading time too'),
1574 (b'', b'full', False, b'include file reading time too'),
1575 ],
1575 ],
1576 b"",
1576 b"",
1577 )
1577 )
1578 def perfphases(ui, repo, **opts):
1578 def perfphases(ui, repo, **opts):
1579 """benchmark phasesets computation"""
1579 """benchmark phasesets computation"""
1580 opts = _byteskwargs(opts)
1580 opts = _byteskwargs(opts)
1581 timer, fm = gettimer(ui, opts)
1581 timer, fm = gettimer(ui, opts)
1582 _phases = repo._phasecache
1582 _phases = repo._phasecache
1583 full = opts.get(b'full')
1583 full = opts.get(b'full')
1584
1584
1585 def d():
1585 def d():
1586 phases = _phases
1586 phases = _phases
1587 if full:
1587 if full:
1588 clearfilecache(repo, b'_phasecache')
1588 clearfilecache(repo, b'_phasecache')
1589 phases = repo._phasecache
1589 phases = repo._phasecache
1590 phases.invalidate()
1590 phases.invalidate()
1591 phases.loadphaserevs(repo)
1591 phases.loadphaserevs(repo)
1592
1592
1593 timer(d)
1593 timer(d)
1594 fm.end()
1594 fm.end()
1595
1595
1596
1596
1597 @command(b'perf::phasesremote|perfphasesremote', [], b"[DEST]")
1597 @command(b'perf::phasesremote|perfphasesremote', [], b"[DEST]")
1598 def perfphasesremote(ui, repo, dest=None, **opts):
1598 def perfphasesremote(ui, repo, dest=None, **opts):
1599 """benchmark time needed to analyse phases of the remote server"""
1599 """benchmark time needed to analyse phases of the remote server"""
1600 from mercurial.node import bin
1600 from mercurial.node import bin
1601 from mercurial import (
1601 from mercurial import (
1602 exchange,
1602 exchange,
1603 hg,
1603 hg,
1604 phases,
1604 phases,
1605 )
1605 )
1606
1606
1607 opts = _byteskwargs(opts)
1607 opts = _byteskwargs(opts)
1608 timer, fm = gettimer(ui, opts)
1608 timer, fm = gettimer(ui, opts)
1609
1609
1610 path = ui.getpath(dest, default=(b'default-push', b'default'))
1610 path = ui.getpath(dest, default=(b'default-push', b'default'))
1611 if not path:
1611 if not path:
1612 raise error.Abort(
1612 raise error.Abort(
1613 b'default repository not configured!',
1613 b'default repository not configured!',
1614 hint=b"see 'hg help config.paths'",
1614 hint=b"see 'hg help config.paths'",
1615 )
1615 )
1616 dest = path.pushloc or path.loc
1616 dest = path.pushloc or path.loc
1617 ui.statusnoi18n(b'analysing phase of %s\n' % util.hidepassword(dest))
1617 ui.statusnoi18n(b'analysing phase of %s\n' % util.hidepassword(dest))
1618 other = hg.peer(repo, opts, dest)
1618 other = hg.peer(repo, opts, dest)
1619
1619
1620 # easier to perform discovery through the operation
1620 # easier to perform discovery through the operation
1621 op = exchange.pushoperation(repo, other)
1621 op = exchange.pushoperation(repo, other)
1622 exchange._pushdiscoverychangeset(op)
1622 exchange._pushdiscoverychangeset(op)
1623
1623
1624 remotesubset = op.fallbackheads
1624 remotesubset = op.fallbackheads
1625
1625
1626 with other.commandexecutor() as e:
1626 with other.commandexecutor() as e:
1627 remotephases = e.callcommand(
1627 remotephases = e.callcommand(
1628 b'listkeys', {b'namespace': b'phases'}
1628 b'listkeys', {b'namespace': b'phases'}
1629 ).result()
1629 ).result()
1630 del other
1630 del other
1631 publishing = remotephases.get(b'publishing', False)
1631 publishing = remotephases.get(b'publishing', False)
1632 if publishing:
1632 if publishing:
1633 ui.statusnoi18n(b'publishing: yes\n')
1633 ui.statusnoi18n(b'publishing: yes\n')
1634 else:
1634 else:
1635 ui.statusnoi18n(b'publishing: no\n')
1635 ui.statusnoi18n(b'publishing: no\n')
1636
1636
1637 has_node = getattr(repo.changelog.index, 'has_node', None)
1637 has_node = getattr(repo.changelog.index, 'has_node', None)
1638 if has_node is None:
1638 if has_node is None:
1639 has_node = repo.changelog.nodemap.__contains__
1639 has_node = repo.changelog.nodemap.__contains__
1640 nonpublishroots = 0
1640 nonpublishroots = 0
1641 for nhex, phase in remotephases.iteritems():
1641 for nhex, phase in remotephases.iteritems():
1642 if nhex == b'publishing': # ignore data related to publish option
1642 if nhex == b'publishing': # ignore data related to publish option
1643 continue
1643 continue
1644 node = bin(nhex)
1644 node = bin(nhex)
1645 if has_node(node) and int(phase):
1645 if has_node(node) and int(phase):
1646 nonpublishroots += 1
1646 nonpublishroots += 1
1647 ui.statusnoi18n(b'number of roots: %d\n' % len(remotephases))
1647 ui.statusnoi18n(b'number of roots: %d\n' % len(remotephases))
1648 ui.statusnoi18n(b'number of known non public roots: %d\n' % nonpublishroots)
1648 ui.statusnoi18n(b'number of known non public roots: %d\n' % nonpublishroots)
1649
1649
1650 def d():
1650 def d():
1651 phases.remotephasessummary(repo, remotesubset, remotephases)
1651 phases.remotephasessummary(repo, remotesubset, remotephases)
1652
1652
1653 timer(d)
1653 timer(d)
1654 fm.end()
1654 fm.end()
1655
1655
1656
1656
1657 @command(
1657 @command(
1658 b'perf::manifest|perfmanifest',
1658 b'perf::manifest|perfmanifest',
1659 [
1659 [
1660 (b'm', b'manifest-rev', False, b'Look up a manifest node revision'),
1660 (b'm', b'manifest-rev', False, b'Look up a manifest node revision'),
1661 (b'', b'clear-disk', False, b'clear on-disk caches too'),
1661 (b'', b'clear-disk', False, b'clear on-disk caches too'),
1662 ]
1662 ]
1663 + formatteropts,
1663 + formatteropts,
1664 b'REV|NODE',
1664 b'REV|NODE',
1665 )
1665 )
1666 def perfmanifest(ui, repo, rev, manifest_rev=False, clear_disk=False, **opts):
1666 def perfmanifest(ui, repo, rev, manifest_rev=False, clear_disk=False, **opts):
1667 """benchmark the time to read a manifest from disk and return a usable
1667 """benchmark the time to read a manifest from disk and return a usable
1668 dict-like object
1668 dict-like object
1669
1669
1670 Manifest caches are cleared before retrieval."""
1670 Manifest caches are cleared before retrieval."""
1671 opts = _byteskwargs(opts)
1671 opts = _byteskwargs(opts)
1672 timer, fm = gettimer(ui, opts)
1672 timer, fm = gettimer(ui, opts)
1673 if not manifest_rev:
1673 if not manifest_rev:
1674 ctx = scmutil.revsingle(repo, rev, rev)
1674 ctx = scmutil.revsingle(repo, rev, rev)
1675 t = ctx.manifestnode()
1675 t = ctx.manifestnode()
1676 else:
1676 else:
1677 from mercurial.node import bin
1677 from mercurial.node import bin
1678
1678
1679 if len(rev) == 40:
1679 if len(rev) == 40:
1680 t = bin(rev)
1680 t = bin(rev)
1681 else:
1681 else:
1682 try:
1682 try:
1683 rev = int(rev)
1683 rev = int(rev)
1684
1684
1685 if util.safehasattr(repo.manifestlog, b'getstorage'):
1685 if util.safehasattr(repo.manifestlog, b'getstorage'):
1686 t = repo.manifestlog.getstorage(b'').node(rev)
1686 t = repo.manifestlog.getstorage(b'').node(rev)
1687 else:
1687 else:
1688 t = repo.manifestlog._revlog.lookup(rev)
1688 t = repo.manifestlog._revlog.lookup(rev)
1689 except ValueError:
1689 except ValueError:
1690 raise error.Abort(
1690 raise error.Abort(
1691 b'manifest revision must be integer or full node'
1691 b'manifest revision must be integer or full node'
1692 )
1692 )
1693
1693
1694 def d():
1694 def d():
1695 repo.manifestlog.clearcaches(clear_persisted_data=clear_disk)
1695 repo.manifestlog.clearcaches(clear_persisted_data=clear_disk)
1696 repo.manifestlog[t].read()
1696 repo.manifestlog[t].read()
1697
1697
1698 timer(d)
1698 timer(d)
1699 fm.end()
1699 fm.end()
1700
1700
1701
1701
1702 @command(b'perf::changeset|perfchangeset', formatteropts)
1702 @command(b'perf::changeset|perfchangeset', formatteropts)
1703 def perfchangeset(ui, repo, rev, **opts):
1703 def perfchangeset(ui, repo, rev, **opts):
1704 opts = _byteskwargs(opts)
1704 opts = _byteskwargs(opts)
1705 timer, fm = gettimer(ui, opts)
1705 timer, fm = gettimer(ui, opts)
1706 n = scmutil.revsingle(repo, rev).node()
1706 n = scmutil.revsingle(repo, rev).node()
1707
1707
1708 def d():
1708 def d():
1709 repo.changelog.read(n)
1709 repo.changelog.read(n)
1710 # repo.changelog._cache = None
1710 # repo.changelog._cache = None
1711
1711
1712 timer(d)
1712 timer(d)
1713 fm.end()
1713 fm.end()
1714
1714
1715
1715
1716 @command(b'perf::ignore|perfignore', formatteropts)
1716 @command(b'perf::ignore|perfignore', formatteropts)
1717 def perfignore(ui, repo, **opts):
1717 def perfignore(ui, repo, **opts):
1718 """benchmark operation related to computing ignore"""
1718 """benchmark operation related to computing ignore"""
1719 opts = _byteskwargs(opts)
1719 opts = _byteskwargs(opts)
1720 timer, fm = gettimer(ui, opts)
1720 timer, fm = gettimer(ui, opts)
1721 dirstate = repo.dirstate
1721 dirstate = repo.dirstate
1722
1722
1723 def setupone():
1723 def setupone():
1724 dirstate.invalidate()
1724 dirstate.invalidate()
1725 clearfilecache(dirstate, b'_ignore')
1725 clearfilecache(dirstate, b'_ignore')
1726
1726
1727 def runone():
1727 def runone():
1728 dirstate._ignore
1728 dirstate._ignore
1729
1729
1730 timer(runone, setup=setupone, title=b"load")
1730 timer(runone, setup=setupone, title=b"load")
1731 fm.end()
1731 fm.end()
1732
1732
1733
1733
1734 @command(
1734 @command(
1735 b'perf::index|perfindex',
1735 b'perf::index|perfindex',
1736 [
1736 [
1737 (b'', b'rev', [], b'revision to be looked up (default tip)'),
1737 (b'', b'rev', [], b'revision to be looked up (default tip)'),
1738 (b'', b'no-lookup', None, b'do not revision lookup post creation'),
1738 (b'', b'no-lookup', None, b'do not revision lookup post creation'),
1739 ]
1739 ]
1740 + formatteropts,
1740 + formatteropts,
1741 )
1741 )
1742 def perfindex(ui, repo, **opts):
1742 def perfindex(ui, repo, **opts):
1743 """benchmark index creation time followed by a lookup
1743 """benchmark index creation time followed by a lookup
1744
1744
1745 The default is to look `tip` up. Depending on the index implementation,
1745 The default is to look `tip` up. Depending on the index implementation,
1746 the revision looked up can matters. For example, an implementation
1746 the revision looked up can matters. For example, an implementation
1747 scanning the index will have a faster lookup time for `--rev tip` than for
1747 scanning the index will have a faster lookup time for `--rev tip` than for
1748 `--rev 0`. The number of looked up revisions and their order can also
1748 `--rev 0`. The number of looked up revisions and their order can also
1749 matters.
1749 matters.
1750
1750
1751 Example of useful set to test:
1751 Example of useful set to test:
1752
1752
1753 * tip
1753 * tip
1754 * 0
1754 * 0
1755 * -10:
1755 * -10:
1756 * :10
1756 * :10
1757 * -10: + :10
1757 * -10: + :10
1758 * :10: + -10:
1758 * :10: + -10:
1759 * -10000:
1759 * -10000:
1760 * -10000: + 0
1760 * -10000: + 0
1761
1761
1762 It is not currently possible to check for lookup of a missing node. For
1762 It is not currently possible to check for lookup of a missing node. For
1763 deeper lookup benchmarking, checkout the `perfnodemap` command."""
1763 deeper lookup benchmarking, checkout the `perfnodemap` command."""
1764 import mercurial.revlog
1764 import mercurial.revlog
1765
1765
1766 opts = _byteskwargs(opts)
1766 opts = _byteskwargs(opts)
1767 timer, fm = gettimer(ui, opts)
1767 timer, fm = gettimer(ui, opts)
1768 mercurial.revlog._prereadsize = 2 ** 24 # disable lazy parser in old hg
1768 mercurial.revlog._prereadsize = 2 ** 24 # disable lazy parser in old hg
1769 if opts[b'no_lookup']:
1769 if opts[b'no_lookup']:
1770 if opts['rev']:
1770 if opts['rev']:
1771 raise error.Abort('--no-lookup and --rev are mutually exclusive')
1771 raise error.Abort('--no-lookup and --rev are mutually exclusive')
1772 nodes = []
1772 nodes = []
1773 elif not opts[b'rev']:
1773 elif not opts[b'rev']:
1774 nodes = [repo[b"tip"].node()]
1774 nodes = [repo[b"tip"].node()]
1775 else:
1775 else:
1776 revs = scmutil.revrange(repo, opts[b'rev'])
1776 revs = scmutil.revrange(repo, opts[b'rev'])
1777 cl = repo.changelog
1777 cl = repo.changelog
1778 nodes = [cl.node(r) for r in revs]
1778 nodes = [cl.node(r) for r in revs]
1779
1779
1780 unfi = repo.unfiltered()
1780 unfi = repo.unfiltered()
1781 # find the filecache func directly
1781 # find the filecache func directly
1782 # This avoid polluting the benchmark with the filecache logic
1782 # This avoid polluting the benchmark with the filecache logic
1783 makecl = unfi.__class__.changelog.func
1783 makecl = unfi.__class__.changelog.func
1784
1784
1785 def setup():
1785 def setup():
1786 # probably not necessary, but for good measure
1786 # probably not necessary, but for good measure
1787 clearchangelog(unfi)
1787 clearchangelog(unfi)
1788
1788
1789 def d():
1789 def d():
1790 cl = makecl(unfi)
1790 cl = makecl(unfi)
1791 for n in nodes:
1791 for n in nodes:
1792 cl.rev(n)
1792 cl.rev(n)
1793
1793
1794 timer(d, setup=setup)
1794 timer(d, setup=setup)
1795 fm.end()
1795 fm.end()
1796
1796
1797
1797
1798 @command(
1798 @command(
1799 b'perf::nodemap|perfnodemap',
1799 b'perf::nodemap|perfnodemap',
1800 [
1800 [
1801 (b'', b'rev', [], b'revision to be looked up (default tip)'),
1801 (b'', b'rev', [], b'revision to be looked up (default tip)'),
1802 (b'', b'clear-caches', True, b'clear revlog cache between calls'),
1802 (b'', b'clear-caches', True, b'clear revlog cache between calls'),
1803 ]
1803 ]
1804 + formatteropts,
1804 + formatteropts,
1805 )
1805 )
1806 def perfnodemap(ui, repo, **opts):
1806 def perfnodemap(ui, repo, **opts):
1807 """benchmark the time necessary to look up revision from a cold nodemap
1807 """benchmark the time necessary to look up revision from a cold nodemap
1808
1808
1809 Depending on the implementation, the amount and order of revision we look
1809 Depending on the implementation, the amount and order of revision we look
1810 up can varies. Example of useful set to test:
1810 up can varies. Example of useful set to test:
1811 * tip
1811 * tip
1812 * 0
1812 * 0
1813 * -10:
1813 * -10:
1814 * :10
1814 * :10
1815 * -10: + :10
1815 * -10: + :10
1816 * :10: + -10:
1816 * :10: + -10:
1817 * -10000:
1817 * -10000:
1818 * -10000: + 0
1818 * -10000: + 0
1819
1819
1820 The command currently focus on valid binary lookup. Benchmarking for
1820 The command currently focus on valid binary lookup. Benchmarking for
1821 hexlookup, prefix lookup and missing lookup would also be valuable.
1821 hexlookup, prefix lookup and missing lookup would also be valuable.
1822 """
1822 """
1823 import mercurial.revlog
1823 import mercurial.revlog
1824
1824
1825 opts = _byteskwargs(opts)
1825 opts = _byteskwargs(opts)
1826 timer, fm = gettimer(ui, opts)
1826 timer, fm = gettimer(ui, opts)
1827 mercurial.revlog._prereadsize = 2 ** 24 # disable lazy parser in old hg
1827 mercurial.revlog._prereadsize = 2 ** 24 # disable lazy parser in old hg
1828
1828
1829 unfi = repo.unfiltered()
1829 unfi = repo.unfiltered()
1830 clearcaches = opts[b'clear_caches']
1830 clearcaches = opts[b'clear_caches']
1831 # find the filecache func directly
1831 # find the filecache func directly
1832 # This avoid polluting the benchmark with the filecache logic
1832 # This avoid polluting the benchmark with the filecache logic
1833 makecl = unfi.__class__.changelog.func
1833 makecl = unfi.__class__.changelog.func
1834 if not opts[b'rev']:
1834 if not opts[b'rev']:
1835 raise error.Abort(b'use --rev to specify revisions to look up')
1835 raise error.Abort(b'use --rev to specify revisions to look up')
1836 revs = scmutil.revrange(repo, opts[b'rev'])
1836 revs = scmutil.revrange(repo, opts[b'rev'])
1837 cl = repo.changelog
1837 cl = repo.changelog
1838 nodes = [cl.node(r) for r in revs]
1838 nodes = [cl.node(r) for r in revs]
1839
1839
1840 # use a list to pass reference to a nodemap from one closure to the next
1840 # use a list to pass reference to a nodemap from one closure to the next
1841 nodeget = [None]
1841 nodeget = [None]
1842
1842
1843 def setnodeget():
1843 def setnodeget():
1844 # probably not necessary, but for good measure
1844 # probably not necessary, but for good measure
1845 clearchangelog(unfi)
1845 clearchangelog(unfi)
1846 cl = makecl(unfi)
1846 cl = makecl(unfi)
1847 if util.safehasattr(cl.index, 'get_rev'):
1847 if util.safehasattr(cl.index, 'get_rev'):
1848 nodeget[0] = cl.index.get_rev
1848 nodeget[0] = cl.index.get_rev
1849 else:
1849 else:
1850 nodeget[0] = cl.nodemap.get
1850 nodeget[0] = cl.nodemap.get
1851
1851
1852 def d():
1852 def d():
1853 get = nodeget[0]
1853 get = nodeget[0]
1854 for n in nodes:
1854 for n in nodes:
1855 get(n)
1855 get(n)
1856
1856
1857 setup = None
1857 setup = None
1858 if clearcaches:
1858 if clearcaches:
1859
1859
1860 def setup():
1860 def setup():
1861 setnodeget()
1861 setnodeget()
1862
1862
1863 else:
1863 else:
1864 setnodeget()
1864 setnodeget()
1865 d() # prewarm the data structure
1865 d() # prewarm the data structure
1866 timer(d, setup=setup)
1866 timer(d, setup=setup)
1867 fm.end()
1867 fm.end()
1868
1868
1869
1869
1870 @command(b'perf::startup|perfstartup', formatteropts)
1870 @command(b'perf::startup|perfstartup', formatteropts)
1871 def perfstartup(ui, repo, **opts):
1871 def perfstartup(ui, repo, **opts):
1872 opts = _byteskwargs(opts)
1872 opts = _byteskwargs(opts)
1873 timer, fm = gettimer(ui, opts)
1873 timer, fm = gettimer(ui, opts)
1874
1874
1875 def d():
1875 def d():
1876 if os.name != 'nt':
1876 if os.name != 'nt':
1877 os.system(
1877 os.system(
1878 b"HGRCPATH= %s version -q > /dev/null" % fsencode(sys.argv[0])
1878 b"HGRCPATH= %s version -q > /dev/null" % fsencode(sys.argv[0])
1879 )
1879 )
1880 else:
1880 else:
1881 os.environ['HGRCPATH'] = r' '
1881 os.environ['HGRCPATH'] = r' '
1882 os.system("%s version -q > NUL" % sys.argv[0])
1882 os.system("%s version -q > NUL" % sys.argv[0])
1883
1883
1884 timer(d)
1884 timer(d)
1885 fm.end()
1885 fm.end()
1886
1886
1887
1887
1888 @command(b'perf::parents|perfparents', formatteropts)
1888 @command(b'perf::parents|perfparents', formatteropts)
1889 def perfparents(ui, repo, **opts):
1889 def perfparents(ui, repo, **opts):
1890 """benchmark the time necessary to fetch one changeset's parents.
1890 """benchmark the time necessary to fetch one changeset's parents.
1891
1891
1892 The fetch is done using the `node identifier`, traversing all object layers
1892 The fetch is done using the `node identifier`, traversing all object layers
1893 from the repository object. The first N revisions will be used for this
1893 from the repository object. The first N revisions will be used for this
1894 benchmark. N is controlled by the ``perf.parentscount`` config option
1894 benchmark. N is controlled by the ``perf.parentscount`` config option
1895 (default: 1000).
1895 (default: 1000).
1896 """
1896 """
1897 opts = _byteskwargs(opts)
1897 opts = _byteskwargs(opts)
1898 timer, fm = gettimer(ui, opts)
1898 timer, fm = gettimer(ui, opts)
1899 # control the number of commits perfparents iterates over
1899 # control the number of commits perfparents iterates over
1900 # experimental config: perf.parentscount
1900 # experimental config: perf.parentscount
1901 count = getint(ui, b"perf", b"parentscount", 1000)
1901 count = getint(ui, b"perf", b"parentscount", 1000)
1902 if len(repo.changelog) < count:
1902 if len(repo.changelog) < count:
1903 raise error.Abort(b"repo needs %d commits for this test" % count)
1903 raise error.Abort(b"repo needs %d commits for this test" % count)
1904 repo = repo.unfiltered()
1904 repo = repo.unfiltered()
1905 nl = [repo.changelog.node(i) for i in _xrange(count)]
1905 nl = [repo.changelog.node(i) for i in _xrange(count)]
1906
1906
1907 def d():
1907 def d():
1908 for n in nl:
1908 for n in nl:
1909 repo.changelog.parents(n)
1909 repo.changelog.parents(n)
1910
1910
1911 timer(d)
1911 timer(d)
1912 fm.end()
1912 fm.end()
1913
1913
1914
1914
1915 @command(b'perf::ctxfiles|perfctxfiles', formatteropts)
1915 @command(b'perf::ctxfiles|perfctxfiles', formatteropts)
1916 def perfctxfiles(ui, repo, x, **opts):
1916 def perfctxfiles(ui, repo, x, **opts):
1917 opts = _byteskwargs(opts)
1917 opts = _byteskwargs(opts)
1918 x = int(x)
1918 x = int(x)
1919 timer, fm = gettimer(ui, opts)
1919 timer, fm = gettimer(ui, opts)
1920
1920
1921 def d():
1921 def d():
1922 len(repo[x].files())
1922 len(repo[x].files())
1923
1923
1924 timer(d)
1924 timer(d)
1925 fm.end()
1925 fm.end()
1926
1926
1927
1927
1928 @command(b'perf::rawfiles|perfrawfiles', formatteropts)
1928 @command(b'perf::rawfiles|perfrawfiles', formatteropts)
1929 def perfrawfiles(ui, repo, x, **opts):
1929 def perfrawfiles(ui, repo, x, **opts):
1930 opts = _byteskwargs(opts)
1930 opts = _byteskwargs(opts)
1931 x = int(x)
1931 x = int(x)
1932 timer, fm = gettimer(ui, opts)
1932 timer, fm = gettimer(ui, opts)
1933 cl = repo.changelog
1933 cl = repo.changelog
1934
1934
1935 def d():
1935 def d():
1936 len(cl.read(x)[3])
1936 len(cl.read(x)[3])
1937
1937
1938 timer(d)
1938 timer(d)
1939 fm.end()
1939 fm.end()
1940
1940
1941
1941
1942 @command(b'perf::lookup|perflookup', formatteropts)
1942 @command(b'perf::lookup|perflookup', formatteropts)
1943 def perflookup(ui, repo, rev, **opts):
1943 def perflookup(ui, repo, rev, **opts):
1944 opts = _byteskwargs(opts)
1944 opts = _byteskwargs(opts)
1945 timer, fm = gettimer(ui, opts)
1945 timer, fm = gettimer(ui, opts)
1946 timer(lambda: len(repo.lookup(rev)))
1946 timer(lambda: len(repo.lookup(rev)))
1947 fm.end()
1947 fm.end()
1948
1948
1949
1949
1950 @command(
1950 @command(
1951 b'perf::linelogedits|perflinelogedits',
1951 b'perf::linelogedits|perflinelogedits',
1952 [
1952 [
1953 (b'n', b'edits', 10000, b'number of edits'),
1953 (b'n', b'edits', 10000, b'number of edits'),
1954 (b'', b'max-hunk-lines', 10, b'max lines in a hunk'),
1954 (b'', b'max-hunk-lines', 10, b'max lines in a hunk'),
1955 ],
1955 ],
1956 norepo=True,
1956 norepo=True,
1957 )
1957 )
1958 def perflinelogedits(ui, **opts):
1958 def perflinelogedits(ui, **opts):
1959 from mercurial import linelog
1959 from mercurial import linelog
1960
1960
1961 opts = _byteskwargs(opts)
1961 opts = _byteskwargs(opts)
1962
1962
1963 edits = opts[b'edits']
1963 edits = opts[b'edits']
1964 maxhunklines = opts[b'max_hunk_lines']
1964 maxhunklines = opts[b'max_hunk_lines']
1965
1965
1966 maxb1 = 100000
1966 maxb1 = 100000
1967 random.seed(0)
1967 random.seed(0)
1968 randint = random.randint
1968 randint = random.randint
1969 currentlines = 0
1969 currentlines = 0
1970 arglist = []
1970 arglist = []
1971 for rev in _xrange(edits):
1971 for rev in _xrange(edits):
1972 a1 = randint(0, currentlines)
1972 a1 = randint(0, currentlines)
1973 a2 = randint(a1, min(currentlines, a1 + maxhunklines))
1973 a2 = randint(a1, min(currentlines, a1 + maxhunklines))
1974 b1 = randint(0, maxb1)
1974 b1 = randint(0, maxb1)
1975 b2 = randint(b1, b1 + maxhunklines)
1975 b2 = randint(b1, b1 + maxhunklines)
1976 currentlines += (b2 - b1) - (a2 - a1)
1976 currentlines += (b2 - b1) - (a2 - a1)
1977 arglist.append((rev, a1, a2, b1, b2))
1977 arglist.append((rev, a1, a2, b1, b2))
1978
1978
1979 def d():
1979 def d():
1980 ll = linelog.linelog()
1980 ll = linelog.linelog()
1981 for args in arglist:
1981 for args in arglist:
1982 ll.replacelines(*args)
1982 ll.replacelines(*args)
1983
1983
1984 timer, fm = gettimer(ui, opts)
1984 timer, fm = gettimer(ui, opts)
1985 timer(d)
1985 timer(d)
1986 fm.end()
1986 fm.end()
1987
1987
1988
1988
1989 @command(b'perf::revrange|perfrevrange', formatteropts)
1989 @command(b'perf::revrange|perfrevrange', formatteropts)
1990 def perfrevrange(ui, repo, *specs, **opts):
1990 def perfrevrange(ui, repo, *specs, **opts):
1991 opts = _byteskwargs(opts)
1991 opts = _byteskwargs(opts)
1992 timer, fm = gettimer(ui, opts)
1992 timer, fm = gettimer(ui, opts)
1993 revrange = scmutil.revrange
1993 revrange = scmutil.revrange
1994 timer(lambda: len(revrange(repo, specs)))
1994 timer(lambda: len(revrange(repo, specs)))
1995 fm.end()
1995 fm.end()
1996
1996
1997
1997
1998 @command(b'perf::nodelookup|perfnodelookup', formatteropts)
1998 @command(b'perf::nodelookup|perfnodelookup', formatteropts)
1999 def perfnodelookup(ui, repo, rev, **opts):
1999 def perfnodelookup(ui, repo, rev, **opts):
2000 opts = _byteskwargs(opts)
2000 opts = _byteskwargs(opts)
2001 timer, fm = gettimer(ui, opts)
2001 timer, fm = gettimer(ui, opts)
2002 import mercurial.revlog
2002 import mercurial.revlog
2003
2003
2004 mercurial.revlog._prereadsize = 2 ** 24 # disable lazy parser in old hg
2004 mercurial.revlog._prereadsize = 2 ** 24 # disable lazy parser in old hg
2005 n = scmutil.revsingle(repo, rev).node()
2005 n = scmutil.revsingle(repo, rev).node()
2006
2006
2007 try:
2007 try:
2008 cl = revlog(getsvfs(repo), radix=b"00changelog")
2008 cl = revlog(getsvfs(repo), radix=b"00changelog")
2009 except TypeError:
2009 except TypeError:
2010 cl = revlog(getsvfs(repo), indexfile=b"00changelog.i")
2010 cl = revlog(getsvfs(repo), indexfile=b"00changelog.i")
2011
2011
2012 def d():
2012 def d():
2013 cl.rev(n)
2013 cl.rev(n)
2014 clearcaches(cl)
2014 clearcaches(cl)
2015
2015
2016 timer(d)
2016 timer(d)
2017 fm.end()
2017 fm.end()
2018
2018
2019
2019
2020 @command(
2020 @command(
2021 b'perf::log|perflog',
2021 b'perf::log|perflog',
2022 [(b'', b'rename', False, b'ask log to follow renames')] + formatteropts,
2022 [(b'', b'rename', False, b'ask log to follow renames')] + formatteropts,
2023 )
2023 )
2024 def perflog(ui, repo, rev=None, **opts):
2024 def perflog(ui, repo, rev=None, **opts):
2025 opts = _byteskwargs(opts)
2025 opts = _byteskwargs(opts)
2026 if rev is None:
2026 if rev is None:
2027 rev = []
2027 rev = []
2028 timer, fm = gettimer(ui, opts)
2028 timer, fm = gettimer(ui, opts)
2029 ui.pushbuffer()
2029 ui.pushbuffer()
2030 timer(
2030 timer(
2031 lambda: commands.log(
2031 lambda: commands.log(
2032 ui, repo, rev=rev, date=b'', user=b'', copies=opts.get(b'rename')
2032 ui, repo, rev=rev, date=b'', user=b'', copies=opts.get(b'rename')
2033 )
2033 )
2034 )
2034 )
2035 ui.popbuffer()
2035 ui.popbuffer()
2036 fm.end()
2036 fm.end()
2037
2037
2038
2038
2039 @command(b'perf::moonwalk|perfmoonwalk', formatteropts)
2039 @command(b'perf::moonwalk|perfmoonwalk', formatteropts)
2040 def perfmoonwalk(ui, repo, **opts):
2040 def perfmoonwalk(ui, repo, **opts):
2041 """benchmark walking the changelog backwards
2041 """benchmark walking the changelog backwards
2042
2042
2043 This also loads the changelog data for each revision in the changelog.
2043 This also loads the changelog data for each revision in the changelog.
2044 """
2044 """
2045 opts = _byteskwargs(opts)
2045 opts = _byteskwargs(opts)
2046 timer, fm = gettimer(ui, opts)
2046 timer, fm = gettimer(ui, opts)
2047
2047
2048 def moonwalk():
2048 def moonwalk():
2049 for i in repo.changelog.revs(start=(len(repo) - 1), stop=-1):
2049 for i in repo.changelog.revs(start=(len(repo) - 1), stop=-1):
2050 ctx = repo[i]
2050 ctx = repo[i]
2051 ctx.branch() # read changelog data (in addition to the index)
2051 ctx.branch() # read changelog data (in addition to the index)
2052
2052
2053 timer(moonwalk)
2053 timer(moonwalk)
2054 fm.end()
2054 fm.end()
2055
2055
2056
2056
2057 @command(
2057 @command(
2058 b'perf::templating|perftemplating',
2058 b'perf::templating|perftemplating',
2059 [
2059 [
2060 (b'r', b'rev', [], b'revisions to run the template on'),
2060 (b'r', b'rev', [], b'revisions to run the template on'),
2061 ]
2061 ]
2062 + formatteropts,
2062 + formatteropts,
2063 )
2063 )
2064 def perftemplating(ui, repo, testedtemplate=None, **opts):
2064 def perftemplating(ui, repo, testedtemplate=None, **opts):
2065 """test the rendering time of a given template"""
2065 """test the rendering time of a given template"""
2066 if makelogtemplater is None:
2066 if makelogtemplater is None:
2067 raise error.Abort(
2067 raise error.Abort(
2068 b"perftemplating not available with this Mercurial",
2068 b"perftemplating not available with this Mercurial",
2069 hint=b"use 4.3 or later",
2069 hint=b"use 4.3 or later",
2070 )
2070 )
2071
2071
2072 opts = _byteskwargs(opts)
2072 opts = _byteskwargs(opts)
2073
2073
2074 nullui = ui.copy()
2074 nullui = ui.copy()
2075 nullui.fout = open(os.devnull, 'wb')
2075 nullui.fout = open(os.devnull, 'wb')
2076 nullui.disablepager()
2076 nullui.disablepager()
2077 revs = opts.get(b'rev')
2077 revs = opts.get(b'rev')
2078 if not revs:
2078 if not revs:
2079 revs = [b'all()']
2079 revs = [b'all()']
2080 revs = list(scmutil.revrange(repo, revs))
2080 revs = list(scmutil.revrange(repo, revs))
2081
2081
2082 defaulttemplate = (
2082 defaulttemplate = (
2083 b'{date|shortdate} [{rev}:{node|short}]'
2083 b'{date|shortdate} [{rev}:{node|short}]'
2084 b' {author|person}: {desc|firstline}\n'
2084 b' {author|person}: {desc|firstline}\n'
2085 )
2085 )
2086 if testedtemplate is None:
2086 if testedtemplate is None:
2087 testedtemplate = defaulttemplate
2087 testedtemplate = defaulttemplate
2088 displayer = makelogtemplater(nullui, repo, testedtemplate)
2088 displayer = makelogtemplater(nullui, repo, testedtemplate)
2089
2089
2090 def format():
2090 def format():
2091 for r in revs:
2091 for r in revs:
2092 ctx = repo[r]
2092 ctx = repo[r]
2093 displayer.show(ctx)
2093 displayer.show(ctx)
2094 displayer.flush(ctx)
2094 displayer.flush(ctx)
2095
2095
2096 timer, fm = gettimer(ui, opts)
2096 timer, fm = gettimer(ui, opts)
2097 timer(format)
2097 timer(format)
2098 fm.end()
2098 fm.end()
2099
2099
2100
2100
2101 def _displaystats(ui, opts, entries, data):
2101 def _displaystats(ui, opts, entries, data):
2102 # use a second formatter because the data are quite different, not sure
2102 # use a second formatter because the data are quite different, not sure
2103 # how it flies with the templater.
2103 # how it flies with the templater.
2104 fm = ui.formatter(b'perf-stats', opts)
2104 fm = ui.formatter(b'perf-stats', opts)
2105 for key, title in entries:
2105 for key, title in entries:
2106 values = data[key]
2106 values = data[key]
2107 nbvalues = len(data)
2107 nbvalues = len(data)
2108 values.sort()
2108 values.sort()
2109 stats = {
2109 stats = {
2110 'key': key,
2110 'key': key,
2111 'title': title,
2111 'title': title,
2112 'nbitems': len(values),
2112 'nbitems': len(values),
2113 'min': values[0][0],
2113 'min': values[0][0],
2114 '10%': values[(nbvalues * 10) // 100][0],
2114 '10%': values[(nbvalues * 10) // 100][0],
2115 '25%': values[(nbvalues * 25) // 100][0],
2115 '25%': values[(nbvalues * 25) // 100][0],
2116 '50%': values[(nbvalues * 50) // 100][0],
2116 '50%': values[(nbvalues * 50) // 100][0],
2117 '75%': values[(nbvalues * 75) // 100][0],
2117 '75%': values[(nbvalues * 75) // 100][0],
2118 '80%': values[(nbvalues * 80) // 100][0],
2118 '80%': values[(nbvalues * 80) // 100][0],
2119 '85%': values[(nbvalues * 85) // 100][0],
2119 '85%': values[(nbvalues * 85) // 100][0],
2120 '90%': values[(nbvalues * 90) // 100][0],
2120 '90%': values[(nbvalues * 90) // 100][0],
2121 '95%': values[(nbvalues * 95) // 100][0],
2121 '95%': values[(nbvalues * 95) // 100][0],
2122 '99%': values[(nbvalues * 99) // 100][0],
2122 '99%': values[(nbvalues * 99) // 100][0],
2123 'max': values[-1][0],
2123 'max': values[-1][0],
2124 }
2124 }
2125 fm.startitem()
2125 fm.startitem()
2126 fm.data(**stats)
2126 fm.data(**stats)
2127 # make node pretty for the human output
2127 # make node pretty for the human output
2128 fm.plain('### %s (%d items)\n' % (title, len(values)))
2128 fm.plain('### %s (%d items)\n' % (title, len(values)))
2129 lines = [
2129 lines = [
2130 'min',
2130 'min',
2131 '10%',
2131 '10%',
2132 '25%',
2132 '25%',
2133 '50%',
2133 '50%',
2134 '75%',
2134 '75%',
2135 '80%',
2135 '80%',
2136 '85%',
2136 '85%',
2137 '90%',
2137 '90%',
2138 '95%',
2138 '95%',
2139 '99%',
2139 '99%',
2140 'max',
2140 'max',
2141 ]
2141 ]
2142 for l in lines:
2142 for l in lines:
2143 fm.plain('%s: %s\n' % (l, stats[l]))
2143 fm.plain('%s: %s\n' % (l, stats[l]))
2144 fm.end()
2144 fm.end()
2145
2145
2146
2146
2147 @command(
2147 @command(
2148 b'perf::helper-mergecopies|perfhelper-mergecopies',
2148 b'perf::helper-mergecopies|perfhelper-mergecopies',
2149 formatteropts
2149 formatteropts
2150 + [
2150 + [
2151 (b'r', b'revs', [], b'restrict search to these revisions'),
2151 (b'r', b'revs', [], b'restrict search to these revisions'),
2152 (b'', b'timing', False, b'provides extra data (costly)'),
2152 (b'', b'timing', False, b'provides extra data (costly)'),
2153 (b'', b'stats', False, b'provides statistic about the measured data'),
2153 (b'', b'stats', False, b'provides statistic about the measured data'),
2154 ],
2154 ],
2155 )
2155 )
2156 def perfhelpermergecopies(ui, repo, revs=[], **opts):
2156 def perfhelpermergecopies(ui, repo, revs=[], **opts):
2157 """find statistics about potential parameters for `perfmergecopies`
2157 """find statistics about potential parameters for `perfmergecopies`
2158
2158
2159 This command find (base, p1, p2) triplet relevant for copytracing
2159 This command find (base, p1, p2) triplet relevant for copytracing
2160 benchmarking in the context of a merge. It reports values for some of the
2160 benchmarking in the context of a merge. It reports values for some of the
2161 parameters that impact merge copy tracing time during merge.
2161 parameters that impact merge copy tracing time during merge.
2162
2162
2163 If `--timing` is set, rename detection is run and the associated timing
2163 If `--timing` is set, rename detection is run and the associated timing
2164 will be reported. The extra details come at the cost of slower command
2164 will be reported. The extra details come at the cost of slower command
2165 execution.
2165 execution.
2166
2166
2167 Since rename detection is only run once, other factors might easily
2167 Since rename detection is only run once, other factors might easily
2168 affect the precision of the timing. However it should give a good
2168 affect the precision of the timing. However it should give a good
2169 approximation of which revision triplets are very costly.
2169 approximation of which revision triplets are very costly.
2170 """
2170 """
2171 opts = _byteskwargs(opts)
2171 opts = _byteskwargs(opts)
2172 fm = ui.formatter(b'perf', opts)
2172 fm = ui.formatter(b'perf', opts)
2173 dotiming = opts[b'timing']
2173 dotiming = opts[b'timing']
2174 dostats = opts[b'stats']
2174 dostats = opts[b'stats']
2175
2175
2176 output_template = [
2176 output_template = [
2177 ("base", "%(base)12s"),
2177 ("base", "%(base)12s"),
2178 ("p1", "%(p1.node)12s"),
2178 ("p1", "%(p1.node)12s"),
2179 ("p2", "%(p2.node)12s"),
2179 ("p2", "%(p2.node)12s"),
2180 ("p1.nb-revs", "%(p1.nbrevs)12d"),
2180 ("p1.nb-revs", "%(p1.nbrevs)12d"),
2181 ("p1.nb-files", "%(p1.nbmissingfiles)12d"),
2181 ("p1.nb-files", "%(p1.nbmissingfiles)12d"),
2182 ("p1.renames", "%(p1.renamedfiles)12d"),
2182 ("p1.renames", "%(p1.renamedfiles)12d"),
2183 ("p1.time", "%(p1.time)12.3f"),
2183 ("p1.time", "%(p1.time)12.3f"),
2184 ("p2.nb-revs", "%(p2.nbrevs)12d"),
2184 ("p2.nb-revs", "%(p2.nbrevs)12d"),
2185 ("p2.nb-files", "%(p2.nbmissingfiles)12d"),
2185 ("p2.nb-files", "%(p2.nbmissingfiles)12d"),
2186 ("p2.renames", "%(p2.renamedfiles)12d"),
2186 ("p2.renames", "%(p2.renamedfiles)12d"),
2187 ("p2.time", "%(p2.time)12.3f"),
2187 ("p2.time", "%(p2.time)12.3f"),
2188 ("renames", "%(nbrenamedfiles)12d"),
2188 ("renames", "%(nbrenamedfiles)12d"),
2189 ("total.time", "%(time)12.3f"),
2189 ("total.time", "%(time)12.3f"),
2190 ]
2190 ]
2191 if not dotiming:
2191 if not dotiming:
2192 output_template = [
2192 output_template = [
2193 i
2193 i
2194 for i in output_template
2194 for i in output_template
2195 if not ('time' in i[0] or 'renames' in i[0])
2195 if not ('time' in i[0] or 'renames' in i[0])
2196 ]
2196 ]
2197 header_names = [h for (h, v) in output_template]
2197 header_names = [h for (h, v) in output_template]
2198 output = ' '.join([v for (h, v) in output_template]) + '\n'
2198 output = ' '.join([v for (h, v) in output_template]) + '\n'
2199 header = ' '.join(['%12s'] * len(header_names)) + '\n'
2199 header = ' '.join(['%12s'] * len(header_names)) + '\n'
2200 fm.plain(header % tuple(header_names))
2200 fm.plain(header % tuple(header_names))
2201
2201
2202 if not revs:
2202 if not revs:
2203 revs = ['all()']
2203 revs = ['all()']
2204 revs = scmutil.revrange(repo, revs)
2204 revs = scmutil.revrange(repo, revs)
2205
2205
2206 if dostats:
2206 if dostats:
2207 alldata = {
2207 alldata = {
2208 'nbrevs': [],
2208 'nbrevs': [],
2209 'nbmissingfiles': [],
2209 'nbmissingfiles': [],
2210 }
2210 }
2211 if dotiming:
2211 if dotiming:
2212 alldata['parentnbrenames'] = []
2212 alldata['parentnbrenames'] = []
2213 alldata['totalnbrenames'] = []
2213 alldata['totalnbrenames'] = []
2214 alldata['parenttime'] = []
2214 alldata['parenttime'] = []
2215 alldata['totaltime'] = []
2215 alldata['totaltime'] = []
2216
2216
2217 roi = repo.revs('merge() and %ld', revs)
2217 roi = repo.revs('merge() and %ld', revs)
2218 for r in roi:
2218 for r in roi:
2219 ctx = repo[r]
2219 ctx = repo[r]
2220 p1 = ctx.p1()
2220 p1 = ctx.p1()
2221 p2 = ctx.p2()
2221 p2 = ctx.p2()
2222 bases = repo.changelog._commonancestorsheads(p1.rev(), p2.rev())
2222 bases = repo.changelog._commonancestorsheads(p1.rev(), p2.rev())
2223 for b in bases:
2223 for b in bases:
2224 b = repo[b]
2224 b = repo[b]
2225 p1missing = copies._computeforwardmissing(b, p1)
2225 p1missing = copies._computeforwardmissing(b, p1)
2226 p2missing = copies._computeforwardmissing(b, p2)
2226 p2missing = copies._computeforwardmissing(b, p2)
2227 data = {
2227 data = {
2228 b'base': b.hex(),
2228 b'base': b.hex(),
2229 b'p1.node': p1.hex(),
2229 b'p1.node': p1.hex(),
2230 b'p1.nbrevs': len(repo.revs('only(%d, %d)', p1.rev(), b.rev())),
2230 b'p1.nbrevs': len(repo.revs('only(%d, %d)', p1.rev(), b.rev())),
2231 b'p1.nbmissingfiles': len(p1missing),
2231 b'p1.nbmissingfiles': len(p1missing),
2232 b'p2.node': p2.hex(),
2232 b'p2.node': p2.hex(),
2233 b'p2.nbrevs': len(repo.revs('only(%d, %d)', p2.rev(), b.rev())),
2233 b'p2.nbrevs': len(repo.revs('only(%d, %d)', p2.rev(), b.rev())),
2234 b'p2.nbmissingfiles': len(p2missing),
2234 b'p2.nbmissingfiles': len(p2missing),
2235 }
2235 }
2236 if dostats:
2236 if dostats:
2237 if p1missing:
2237 if p1missing:
2238 alldata['nbrevs'].append(
2238 alldata['nbrevs'].append(
2239 (data['p1.nbrevs'], b.hex(), p1.hex())
2239 (data['p1.nbrevs'], b.hex(), p1.hex())
2240 )
2240 )
2241 alldata['nbmissingfiles'].append(
2241 alldata['nbmissingfiles'].append(
2242 (data['p1.nbmissingfiles'], b.hex(), p1.hex())
2242 (data['p1.nbmissingfiles'], b.hex(), p1.hex())
2243 )
2243 )
2244 if p2missing:
2244 if p2missing:
2245 alldata['nbrevs'].append(
2245 alldata['nbrevs'].append(
2246 (data['p2.nbrevs'], b.hex(), p2.hex())
2246 (data['p2.nbrevs'], b.hex(), p2.hex())
2247 )
2247 )
2248 alldata['nbmissingfiles'].append(
2248 alldata['nbmissingfiles'].append(
2249 (data['p2.nbmissingfiles'], b.hex(), p2.hex())
2249 (data['p2.nbmissingfiles'], b.hex(), p2.hex())
2250 )
2250 )
2251 if dotiming:
2251 if dotiming:
2252 begin = util.timer()
2252 begin = util.timer()
2253 mergedata = copies.mergecopies(repo, p1, p2, b)
2253 mergedata = copies.mergecopies(repo, p1, p2, b)
2254 end = util.timer()
2254 end = util.timer()
2255 # not very stable timing since we did only one run
2255 # not very stable timing since we did only one run
2256 data['time'] = end - begin
2256 data['time'] = end - begin
2257 # mergedata contains five dicts: "copy", "movewithdir",
2257 # mergedata contains five dicts: "copy", "movewithdir",
2258 # "diverge", "renamedelete" and "dirmove".
2258 # "diverge", "renamedelete" and "dirmove".
2259 # The first 4 are about renamed file so lets count that.
2259 # The first 4 are about renamed file so lets count that.
2260 renames = len(mergedata[0])
2260 renames = len(mergedata[0])
2261 renames += len(mergedata[1])
2261 renames += len(mergedata[1])
2262 renames += len(mergedata[2])
2262 renames += len(mergedata[2])
2263 renames += len(mergedata[3])
2263 renames += len(mergedata[3])
2264 data['nbrenamedfiles'] = renames
2264 data['nbrenamedfiles'] = renames
2265 begin = util.timer()
2265 begin = util.timer()
2266 p1renames = copies.pathcopies(b, p1)
2266 p1renames = copies.pathcopies(b, p1)
2267 end = util.timer()
2267 end = util.timer()
2268 data['p1.time'] = end - begin
2268 data['p1.time'] = end - begin
2269 begin = util.timer()
2269 begin = util.timer()
2270 p2renames = copies.pathcopies(b, p2)
2270 p2renames = copies.pathcopies(b, p2)
2271 end = util.timer()
2271 end = util.timer()
2272 data['p2.time'] = end - begin
2272 data['p2.time'] = end - begin
2273 data['p1.renamedfiles'] = len(p1renames)
2273 data['p1.renamedfiles'] = len(p1renames)
2274 data['p2.renamedfiles'] = len(p2renames)
2274 data['p2.renamedfiles'] = len(p2renames)
2275
2275
2276 if dostats:
2276 if dostats:
2277 if p1missing:
2277 if p1missing:
2278 alldata['parentnbrenames'].append(
2278 alldata['parentnbrenames'].append(
2279 (data['p1.renamedfiles'], b.hex(), p1.hex())
2279 (data['p1.renamedfiles'], b.hex(), p1.hex())
2280 )
2280 )
2281 alldata['parenttime'].append(
2281 alldata['parenttime'].append(
2282 (data['p1.time'], b.hex(), p1.hex())
2282 (data['p1.time'], b.hex(), p1.hex())
2283 )
2283 )
2284 if p2missing:
2284 if p2missing:
2285 alldata['parentnbrenames'].append(
2285 alldata['parentnbrenames'].append(
2286 (data['p2.renamedfiles'], b.hex(), p2.hex())
2286 (data['p2.renamedfiles'], b.hex(), p2.hex())
2287 )
2287 )
2288 alldata['parenttime'].append(
2288 alldata['parenttime'].append(
2289 (data['p2.time'], b.hex(), p2.hex())
2289 (data['p2.time'], b.hex(), p2.hex())
2290 )
2290 )
2291 if p1missing or p2missing:
2291 if p1missing or p2missing:
2292 alldata['totalnbrenames'].append(
2292 alldata['totalnbrenames'].append(
2293 (
2293 (
2294 data['nbrenamedfiles'],
2294 data['nbrenamedfiles'],
2295 b.hex(),
2295 b.hex(),
2296 p1.hex(),
2296 p1.hex(),
2297 p2.hex(),
2297 p2.hex(),
2298 )
2298 )
2299 )
2299 )
2300 alldata['totaltime'].append(
2300 alldata['totaltime'].append(
2301 (data['time'], b.hex(), p1.hex(), p2.hex())
2301 (data['time'], b.hex(), p1.hex(), p2.hex())
2302 )
2302 )
2303 fm.startitem()
2303 fm.startitem()
2304 fm.data(**data)
2304 fm.data(**data)
2305 # make node pretty for the human output
2305 # make node pretty for the human output
2306 out = data.copy()
2306 out = data.copy()
2307 out['base'] = fm.hexfunc(b.node())
2307 out['base'] = fm.hexfunc(b.node())
2308 out['p1.node'] = fm.hexfunc(p1.node())
2308 out['p1.node'] = fm.hexfunc(p1.node())
2309 out['p2.node'] = fm.hexfunc(p2.node())
2309 out['p2.node'] = fm.hexfunc(p2.node())
2310 fm.plain(output % out)
2310 fm.plain(output % out)
2311
2311
2312 fm.end()
2312 fm.end()
2313 if dostats:
2313 if dostats:
2314 # use a second formatter because the data are quite different, not sure
2314 # use a second formatter because the data are quite different, not sure
2315 # how it flies with the templater.
2315 # how it flies with the templater.
2316 entries = [
2316 entries = [
2317 ('nbrevs', 'number of revision covered'),
2317 ('nbrevs', 'number of revision covered'),
2318 ('nbmissingfiles', 'number of missing files at head'),
2318 ('nbmissingfiles', 'number of missing files at head'),
2319 ]
2319 ]
2320 if dotiming:
2320 if dotiming:
2321 entries.append(
2321 entries.append(
2322 ('parentnbrenames', 'rename from one parent to base')
2322 ('parentnbrenames', 'rename from one parent to base')
2323 )
2323 )
2324 entries.append(('totalnbrenames', 'total number of renames'))
2324 entries.append(('totalnbrenames', 'total number of renames'))
2325 entries.append(('parenttime', 'time for one parent'))
2325 entries.append(('parenttime', 'time for one parent'))
2326 entries.append(('totaltime', 'time for both parents'))
2326 entries.append(('totaltime', 'time for both parents'))
2327 _displaystats(ui, opts, entries, alldata)
2327 _displaystats(ui, opts, entries, alldata)
2328
2328
2329
2329
2330 @command(
2330 @command(
2331 b'perf::helper-pathcopies|perfhelper-pathcopies',
2331 b'perf::helper-pathcopies|perfhelper-pathcopies',
2332 formatteropts
2332 formatteropts
2333 + [
2333 + [
2334 (b'r', b'revs', [], b'restrict search to these revisions'),
2334 (b'r', b'revs', [], b'restrict search to these revisions'),
2335 (b'', b'timing', False, b'provides extra data (costly)'),
2335 (b'', b'timing', False, b'provides extra data (costly)'),
2336 (b'', b'stats', False, b'provides statistic about the measured data'),
2336 (b'', b'stats', False, b'provides statistic about the measured data'),
2337 ],
2337 ],
2338 )
2338 )
2339 def perfhelperpathcopies(ui, repo, revs=[], **opts):
2339 def perfhelperpathcopies(ui, repo, revs=[], **opts):
2340 """find statistic about potential parameters for the `perftracecopies`
2340 """find statistic about potential parameters for the `perftracecopies`
2341
2341
2342 This command find source-destination pair relevant for copytracing testing.
2342 This command find source-destination pair relevant for copytracing testing.
2343 It report value for some of the parameters that impact copy tracing time.
2343 It report value for some of the parameters that impact copy tracing time.
2344
2344
2345 If `--timing` is set, rename detection is run and the associated timing
2345 If `--timing` is set, rename detection is run and the associated timing
2346 will be reported. The extra details comes at the cost of a slower command
2346 will be reported. The extra details comes at the cost of a slower command
2347 execution.
2347 execution.
2348
2348
2349 Since the rename detection is only run once, other factors might easily
2349 Since the rename detection is only run once, other factors might easily
2350 affect the precision of the timing. However it should give a good
2350 affect the precision of the timing. However it should give a good
2351 approximation of which revision pairs are very costly.
2351 approximation of which revision pairs are very costly.
2352 """
2352 """
2353 opts = _byteskwargs(opts)
2353 opts = _byteskwargs(opts)
2354 fm = ui.formatter(b'perf', opts)
2354 fm = ui.formatter(b'perf', opts)
2355 dotiming = opts[b'timing']
2355 dotiming = opts[b'timing']
2356 dostats = opts[b'stats']
2356 dostats = opts[b'stats']
2357
2357
2358 if dotiming:
2358 if dotiming:
2359 header = '%12s %12s %12s %12s %12s %12s\n'
2359 header = '%12s %12s %12s %12s %12s %12s\n'
2360 output = (
2360 output = (
2361 "%(source)12s %(destination)12s "
2361 "%(source)12s %(destination)12s "
2362 "%(nbrevs)12d %(nbmissingfiles)12d "
2362 "%(nbrevs)12d %(nbmissingfiles)12d "
2363 "%(nbrenamedfiles)12d %(time)18.5f\n"
2363 "%(nbrenamedfiles)12d %(time)18.5f\n"
2364 )
2364 )
2365 header_names = (
2365 header_names = (
2366 "source",
2366 "source",
2367 "destination",
2367 "destination",
2368 "nb-revs",
2368 "nb-revs",
2369 "nb-files",
2369 "nb-files",
2370 "nb-renames",
2370 "nb-renames",
2371 "time",
2371 "time",
2372 )
2372 )
2373 fm.plain(header % header_names)
2373 fm.plain(header % header_names)
2374 else:
2374 else:
2375 header = '%12s %12s %12s %12s\n'
2375 header = '%12s %12s %12s %12s\n'
2376 output = (
2376 output = (
2377 "%(source)12s %(destination)12s "
2377 "%(source)12s %(destination)12s "
2378 "%(nbrevs)12d %(nbmissingfiles)12d\n"
2378 "%(nbrevs)12d %(nbmissingfiles)12d\n"
2379 )
2379 )
2380 fm.plain(header % ("source", "destination", "nb-revs", "nb-files"))
2380 fm.plain(header % ("source", "destination", "nb-revs", "nb-files"))
2381
2381
2382 if not revs:
2382 if not revs:
2383 revs = ['all()']
2383 revs = ['all()']
2384 revs = scmutil.revrange(repo, revs)
2384 revs = scmutil.revrange(repo, revs)
2385
2385
2386 if dostats:
2386 if dostats:
2387 alldata = {
2387 alldata = {
2388 'nbrevs': [],
2388 'nbrevs': [],
2389 'nbmissingfiles': [],
2389 'nbmissingfiles': [],
2390 }
2390 }
2391 if dotiming:
2391 if dotiming:
2392 alldata['nbrenames'] = []
2392 alldata['nbrenames'] = []
2393 alldata['time'] = []
2393 alldata['time'] = []
2394
2394
2395 roi = repo.revs('merge() and %ld', revs)
2395 roi = repo.revs('merge() and %ld', revs)
2396 for r in roi:
2396 for r in roi:
2397 ctx = repo[r]
2397 ctx = repo[r]
2398 p1 = ctx.p1().rev()
2398 p1 = ctx.p1().rev()
2399 p2 = ctx.p2().rev()
2399 p2 = ctx.p2().rev()
2400 bases = repo.changelog._commonancestorsheads(p1, p2)
2400 bases = repo.changelog._commonancestorsheads(p1, p2)
2401 for p in (p1, p2):
2401 for p in (p1, p2):
2402 for b in bases:
2402 for b in bases:
2403 base = repo[b]
2403 base = repo[b]
2404 parent = repo[p]
2404 parent = repo[p]
2405 missing = copies._computeforwardmissing(base, parent)
2405 missing = copies._computeforwardmissing(base, parent)
2406 if not missing:
2406 if not missing:
2407 continue
2407 continue
2408 data = {
2408 data = {
2409 b'source': base.hex(),
2409 b'source': base.hex(),
2410 b'destination': parent.hex(),
2410 b'destination': parent.hex(),
2411 b'nbrevs': len(repo.revs('only(%d, %d)', p, b)),
2411 b'nbrevs': len(repo.revs('only(%d, %d)', p, b)),
2412 b'nbmissingfiles': len(missing),
2412 b'nbmissingfiles': len(missing),
2413 }
2413 }
2414 if dostats:
2414 if dostats:
2415 alldata['nbrevs'].append(
2415 alldata['nbrevs'].append(
2416 (
2416 (
2417 data['nbrevs'],
2417 data['nbrevs'],
2418 base.hex(),
2418 base.hex(),
2419 parent.hex(),
2419 parent.hex(),
2420 )
2420 )
2421 )
2421 )
2422 alldata['nbmissingfiles'].append(
2422 alldata['nbmissingfiles'].append(
2423 (
2423 (
2424 data['nbmissingfiles'],
2424 data['nbmissingfiles'],
2425 base.hex(),
2425 base.hex(),
2426 parent.hex(),
2426 parent.hex(),
2427 )
2427 )
2428 )
2428 )
2429 if dotiming:
2429 if dotiming:
2430 begin = util.timer()
2430 begin = util.timer()
2431 renames = copies.pathcopies(base, parent)
2431 renames = copies.pathcopies(base, parent)
2432 end = util.timer()
2432 end = util.timer()
2433 # not very stable timing since we did only one run
2433 # not very stable timing since we did only one run
2434 data['time'] = end - begin
2434 data['time'] = end - begin
2435 data['nbrenamedfiles'] = len(renames)
2435 data['nbrenamedfiles'] = len(renames)
2436 if dostats:
2436 if dostats:
2437 alldata['time'].append(
2437 alldata['time'].append(
2438 (
2438 (
2439 data['time'],
2439 data['time'],
2440 base.hex(),
2440 base.hex(),
2441 parent.hex(),
2441 parent.hex(),
2442 )
2442 )
2443 )
2443 )
2444 alldata['nbrenames'].append(
2444 alldata['nbrenames'].append(
2445 (
2445 (
2446 data['nbrenamedfiles'],
2446 data['nbrenamedfiles'],
2447 base.hex(),
2447 base.hex(),
2448 parent.hex(),
2448 parent.hex(),
2449 )
2449 )
2450 )
2450 )
2451 fm.startitem()
2451 fm.startitem()
2452 fm.data(**data)
2452 fm.data(**data)
2453 out = data.copy()
2453 out = data.copy()
2454 out['source'] = fm.hexfunc(base.node())
2454 out['source'] = fm.hexfunc(base.node())
2455 out['destination'] = fm.hexfunc(parent.node())
2455 out['destination'] = fm.hexfunc(parent.node())
2456 fm.plain(output % out)
2456 fm.plain(output % out)
2457
2457
2458 fm.end()
2458 fm.end()
2459 if dostats:
2459 if dostats:
2460 entries = [
2460 entries = [
2461 ('nbrevs', 'number of revision covered'),
2461 ('nbrevs', 'number of revision covered'),
2462 ('nbmissingfiles', 'number of missing files at head'),
2462 ('nbmissingfiles', 'number of missing files at head'),
2463 ]
2463 ]
2464 if dotiming:
2464 if dotiming:
2465 entries.append(('nbrenames', 'renamed files'))
2465 entries.append(('nbrenames', 'renamed files'))
2466 entries.append(('time', 'time'))
2466 entries.append(('time', 'time'))
2467 _displaystats(ui, opts, entries, alldata)
2467 _displaystats(ui, opts, entries, alldata)
2468
2468
2469
2469
2470 @command(b'perf::cca|perfcca', formatteropts)
2470 @command(b'perf::cca|perfcca', formatteropts)
2471 def perfcca(ui, repo, **opts):
2471 def perfcca(ui, repo, **opts):
2472 opts = _byteskwargs(opts)
2472 opts = _byteskwargs(opts)
2473 timer, fm = gettimer(ui, opts)
2473 timer, fm = gettimer(ui, opts)
2474 timer(lambda: scmutil.casecollisionauditor(ui, False, repo.dirstate))
2474 timer(lambda: scmutil.casecollisionauditor(ui, False, repo.dirstate))
2475 fm.end()
2475 fm.end()
2476
2476
2477
2477
2478 @command(b'perf::fncacheload|perffncacheload', formatteropts)
2478 @command(b'perf::fncacheload|perffncacheload', formatteropts)
2479 def perffncacheload(ui, repo, **opts):
2479 def perffncacheload(ui, repo, **opts):
2480 opts = _byteskwargs(opts)
2480 opts = _byteskwargs(opts)
2481 timer, fm = gettimer(ui, opts)
2481 timer, fm = gettimer(ui, opts)
2482 s = repo.store
2482 s = repo.store
2483
2483
2484 def d():
2484 def d():
2485 s.fncache._load()
2485 s.fncache._load()
2486
2486
2487 timer(d)
2487 timer(d)
2488 fm.end()
2488 fm.end()
2489
2489
2490
2490
2491 @command(b'perf::fncachewrite|perffncachewrite', formatteropts)
2491 @command(b'perf::fncachewrite|perffncachewrite', formatteropts)
2492 def perffncachewrite(ui, repo, **opts):
2492 def perffncachewrite(ui, repo, **opts):
2493 opts = _byteskwargs(opts)
2493 opts = _byteskwargs(opts)
2494 timer, fm = gettimer(ui, opts)
2494 timer, fm = gettimer(ui, opts)
2495 s = repo.store
2495 s = repo.store
2496 lock = repo.lock()
2496 lock = repo.lock()
2497 s.fncache._load()
2497 s.fncache._load()
2498 tr = repo.transaction(b'perffncachewrite')
2498 tr = repo.transaction(b'perffncachewrite')
2499 tr.addbackup(b'fncache')
2499 tr.addbackup(b'fncache')
2500
2500
2501 def d():
2501 def d():
2502 s.fncache._dirty = True
2502 s.fncache._dirty = True
2503 s.fncache.write(tr)
2503 s.fncache.write(tr)
2504
2504
2505 timer(d)
2505 timer(d)
2506 tr.close()
2506 tr.close()
2507 lock.release()
2507 lock.release()
2508 fm.end()
2508 fm.end()
2509
2509
2510
2510
2511 @command(b'perf::fncacheencode|perffncacheencode', formatteropts)
2511 @command(b'perf::fncacheencode|perffncacheencode', formatteropts)
2512 def perffncacheencode(ui, repo, **opts):
2512 def perffncacheencode(ui, repo, **opts):
2513 opts = _byteskwargs(opts)
2513 opts = _byteskwargs(opts)
2514 timer, fm = gettimer(ui, opts)
2514 timer, fm = gettimer(ui, opts)
2515 s = repo.store
2515 s = repo.store
2516 s.fncache._load()
2516 s.fncache._load()
2517
2517
2518 def d():
2518 def d():
2519 for p in s.fncache.entries:
2519 for p in s.fncache.entries:
2520 s.encode(p)
2520 s.encode(p)
2521
2521
2522 timer(d)
2522 timer(d)
2523 fm.end()
2523 fm.end()
2524
2524
2525
2525
2526 def _bdiffworker(q, blocks, xdiff, ready, done):
2526 def _bdiffworker(q, blocks, xdiff, ready, done):
2527 while not done.is_set():
2527 while not done.is_set():
2528 pair = q.get()
2528 pair = q.get()
2529 while pair is not None:
2529 while pair is not None:
2530 if xdiff:
2530 if xdiff:
2531 mdiff.bdiff.xdiffblocks(*pair)
2531 mdiff.bdiff.xdiffblocks(*pair)
2532 elif blocks:
2532 elif blocks:
2533 mdiff.bdiff.blocks(*pair)
2533 mdiff.bdiff.blocks(*pair)
2534 else:
2534 else:
2535 mdiff.textdiff(*pair)
2535 mdiff.textdiff(*pair)
2536 q.task_done()
2536 q.task_done()
2537 pair = q.get()
2537 pair = q.get()
2538 q.task_done() # for the None one
2538 q.task_done() # for the None one
2539 with ready:
2539 with ready:
2540 ready.wait()
2540 ready.wait()
2541
2541
2542
2542
2543 def _manifestrevision(repo, mnode):
2543 def _manifestrevision(repo, mnode):
2544 ml = repo.manifestlog
2544 ml = repo.manifestlog
2545
2545
2546 if util.safehasattr(ml, b'getstorage'):
2546 if util.safehasattr(ml, b'getstorage'):
2547 store = ml.getstorage(b'')
2547 store = ml.getstorage(b'')
2548 else:
2548 else:
2549 store = ml._revlog
2549 store = ml._revlog
2550
2550
2551 return store.revision(mnode)
2551 return store.revision(mnode)
2552
2552
2553
2553
2554 @command(
2554 @command(
2555 b'perf::bdiff|perfbdiff',
2555 b'perf::bdiff|perfbdiff',
2556 revlogopts
2556 revlogopts
2557 + formatteropts
2557 + formatteropts
2558 + [
2558 + [
2559 (
2559 (
2560 b'',
2560 b'',
2561 b'count',
2561 b'count',
2562 1,
2562 1,
2563 b'number of revisions to test (when using --startrev)',
2563 b'number of revisions to test (when using --startrev)',
2564 ),
2564 ),
2565 (b'', b'alldata', False, b'test bdiffs for all associated revisions'),
2565 (b'', b'alldata', False, b'test bdiffs for all associated revisions'),
2566 (b'', b'threads', 0, b'number of thread to use (disable with 0)'),
2566 (b'', b'threads', 0, b'number of thread to use (disable with 0)'),
2567 (b'', b'blocks', False, b'test computing diffs into blocks'),
2567 (b'', b'blocks', False, b'test computing diffs into blocks'),
2568 (b'', b'xdiff', False, b'use xdiff algorithm'),
2568 (b'', b'xdiff', False, b'use xdiff algorithm'),
2569 ],
2569 ],
2570 b'-c|-m|FILE REV',
2570 b'-c|-m|FILE REV',
2571 )
2571 )
2572 def perfbdiff(ui, repo, file_, rev=None, count=None, threads=0, **opts):
2572 def perfbdiff(ui, repo, file_, rev=None, count=None, threads=0, **opts):
2573 """benchmark a bdiff between revisions
2573 """benchmark a bdiff between revisions
2574
2574
2575 By default, benchmark a bdiff between its delta parent and itself.
2575 By default, benchmark a bdiff between its delta parent and itself.
2576
2576
2577 With ``--count``, benchmark bdiffs between delta parents and self for N
2577 With ``--count``, benchmark bdiffs between delta parents and self for N
2578 revisions starting at the specified revision.
2578 revisions starting at the specified revision.
2579
2579
2580 With ``--alldata``, assume the requested revision is a changeset and
2580 With ``--alldata``, assume the requested revision is a changeset and
2581 measure bdiffs for all changes related to that changeset (manifest
2581 measure bdiffs for all changes related to that changeset (manifest
2582 and filelogs).
2582 and filelogs).
2583 """
2583 """
2584 opts = _byteskwargs(opts)
2584 opts = _byteskwargs(opts)
2585
2585
2586 if opts[b'xdiff'] and not opts[b'blocks']:
2586 if opts[b'xdiff'] and not opts[b'blocks']:
2587 raise error.CommandError(b'perfbdiff', b'--xdiff requires --blocks')
2587 raise error.CommandError(b'perfbdiff', b'--xdiff requires --blocks')
2588
2588
2589 if opts[b'alldata']:
2589 if opts[b'alldata']:
2590 opts[b'changelog'] = True
2590 opts[b'changelog'] = True
2591
2591
2592 if opts.get(b'changelog') or opts.get(b'manifest'):
2592 if opts.get(b'changelog') or opts.get(b'manifest'):
2593 file_, rev = None, file_
2593 file_, rev = None, file_
2594 elif rev is None:
2594 elif rev is None:
2595 raise error.CommandError(b'perfbdiff', b'invalid arguments')
2595 raise error.CommandError(b'perfbdiff', b'invalid arguments')
2596
2596
2597 blocks = opts[b'blocks']
2597 blocks = opts[b'blocks']
2598 xdiff = opts[b'xdiff']
2598 xdiff = opts[b'xdiff']
2599 textpairs = []
2599 textpairs = []
2600
2600
2601 r = cmdutil.openrevlog(repo, b'perfbdiff', file_, opts)
2601 r = cmdutil.openrevlog(repo, b'perfbdiff', file_, opts)
2602
2602
2603 startrev = r.rev(r.lookup(rev))
2603 startrev = r.rev(r.lookup(rev))
2604 for rev in range(startrev, min(startrev + count, len(r) - 1)):
2604 for rev in range(startrev, min(startrev + count, len(r) - 1)):
2605 if opts[b'alldata']:
2605 if opts[b'alldata']:
2606 # Load revisions associated with changeset.
2606 # Load revisions associated with changeset.
2607 ctx = repo[rev]
2607 ctx = repo[rev]
2608 mtext = _manifestrevision(repo, ctx.manifestnode())
2608 mtext = _manifestrevision(repo, ctx.manifestnode())
2609 for pctx in ctx.parents():
2609 for pctx in ctx.parents():
2610 pman = _manifestrevision(repo, pctx.manifestnode())
2610 pman = _manifestrevision(repo, pctx.manifestnode())
2611 textpairs.append((pman, mtext))
2611 textpairs.append((pman, mtext))
2612
2612
2613 # Load filelog revisions by iterating manifest delta.
2613 # Load filelog revisions by iterating manifest delta.
2614 man = ctx.manifest()
2614 man = ctx.manifest()
2615 pman = ctx.p1().manifest()
2615 pman = ctx.p1().manifest()
2616 for filename, change in pman.diff(man).items():
2616 for filename, change in pman.diff(man).items():
2617 fctx = repo.file(filename)
2617 fctx = repo.file(filename)
2618 f1 = fctx.revision(change[0][0] or -1)
2618 f1 = fctx.revision(change[0][0] or -1)
2619 f2 = fctx.revision(change[1][0] or -1)
2619 f2 = fctx.revision(change[1][0] or -1)
2620 textpairs.append((f1, f2))
2620 textpairs.append((f1, f2))
2621 else:
2621 else:
2622 dp = r.deltaparent(rev)
2622 dp = r.deltaparent(rev)
2623 textpairs.append((r.revision(dp), r.revision(rev)))
2623 textpairs.append((r.revision(dp), r.revision(rev)))
2624
2624
2625 withthreads = threads > 0
2625 withthreads = threads > 0
2626 if not withthreads:
2626 if not withthreads:
2627
2627
2628 def d():
2628 def d():
2629 for pair in textpairs:
2629 for pair in textpairs:
2630 if xdiff:
2630 if xdiff:
2631 mdiff.bdiff.xdiffblocks(*pair)
2631 mdiff.bdiff.xdiffblocks(*pair)
2632 elif blocks:
2632 elif blocks:
2633 mdiff.bdiff.blocks(*pair)
2633 mdiff.bdiff.blocks(*pair)
2634 else:
2634 else:
2635 mdiff.textdiff(*pair)
2635 mdiff.textdiff(*pair)
2636
2636
2637 else:
2637 else:
2638 q = queue()
2638 q = queue()
2639 for i in _xrange(threads):
2639 for i in _xrange(threads):
2640 q.put(None)
2640 q.put(None)
2641 ready = threading.Condition()
2641 ready = threading.Condition()
2642 done = threading.Event()
2642 done = threading.Event()
2643 for i in _xrange(threads):
2643 for i in _xrange(threads):
2644 threading.Thread(
2644 threading.Thread(
2645 target=_bdiffworker, args=(q, blocks, xdiff, ready, done)
2645 target=_bdiffworker, args=(q, blocks, xdiff, ready, done)
2646 ).start()
2646 ).start()
2647 q.join()
2647 q.join()
2648
2648
2649 def d():
2649 def d():
2650 for pair in textpairs:
2650 for pair in textpairs:
2651 q.put(pair)
2651 q.put(pair)
2652 for i in _xrange(threads):
2652 for i in _xrange(threads):
2653 q.put(None)
2653 q.put(None)
2654 with ready:
2654 with ready:
2655 ready.notify_all()
2655 ready.notify_all()
2656 q.join()
2656 q.join()
2657
2657
2658 timer, fm = gettimer(ui, opts)
2658 timer, fm = gettimer(ui, opts)
2659 timer(d)
2659 timer(d)
2660 fm.end()
2660 fm.end()
2661
2661
2662 if withthreads:
2662 if withthreads:
2663 done.set()
2663 done.set()
2664 for i in _xrange(threads):
2664 for i in _xrange(threads):
2665 q.put(None)
2665 q.put(None)
2666 with ready:
2666 with ready:
2667 ready.notify_all()
2667 ready.notify_all()
2668
2668
2669
2669
2670 @command(
2670 @command(
2671 b'perf::unbundle',
2671 b'perf::unbundle',
2672 formatteropts,
2672 formatteropts,
2673 b'BUNDLE_FILE',
2673 b'BUNDLE_FILE',
2674 )
2674 )
2675 def perf_unbundle(ui, repo, fname, **opts):
2675 def perf_unbundle(ui, repo, fname, **opts):
2676 """benchmark application of a bundle in a repository.
2676 """benchmark application of a bundle in a repository.
2677
2677
2678 This does not include the final transaction processing"""
2678 This does not include the final transaction processing"""
2679
2679 from mercurial import exchange
2680 from mercurial import exchange
2680 from mercurial import bundle2
2681 from mercurial import bundle2
2682 from mercurial import transaction
2681
2683
2682 opts = _byteskwargs(opts)
2684 opts = _byteskwargs(opts)
2683
2685
2686 ### some compatibility hotfix
2687 #
2688 # the data attribute is dropped in 63edc384d3b7 a changeset introducing a
2689 # critical regression that break transaction rollback for files that are
2690 # de-inlined.
2691 method = transaction.transaction._addentry
2692 pre_63edc384d3b7 = "data" in getargspec(method).args
2693 # the `detailed_exit_code` attribute is introduced in 33c0c25d0b0f
2694 # a changeset that is a close descendant of 18415fc918a1, the changeset
2695 # that conclude the fix run for the bug introduced in 63edc384d3b7.
2696 args = getargspec(error.Abort.__init__).args
2697 post_18415fc918a1 = "detailed_exit_code" in args
2698
2699 old_max_inline = None
2700 try:
2701 if not (pre_63edc384d3b7 or post_18415fc918a1):
2702 # disable inlining
2703 old_max_inline = mercurial.revlog._maxinline
2704 # large enough to never happen
2705 mercurial.revlog._maxinline = 2 ** 50
2706
2684 with repo.lock():
2707 with repo.lock():
2685 bundle = [None, None]
2708 bundle = [None, None]
2686 orig_quiet = repo.ui.quiet
2709 orig_quiet = repo.ui.quiet
2687 try:
2710 try:
2688 repo.ui.quiet = True
2711 repo.ui.quiet = True
2689 with open(fname, mode="rb") as f:
2712 with open(fname, mode="rb") as f:
2690
2713
2691 def noop_report(*args, **kwargs):
2714 def noop_report(*args, **kwargs):
2692 pass
2715 pass
2693
2716
2694 def setup():
2717 def setup():
2695 gen, tr = bundle
2718 gen, tr = bundle
2696 if tr is not None:
2719 if tr is not None:
2697 tr.abort()
2720 tr.abort()
2698 bundle[:] = [None, None]
2721 bundle[:] = [None, None]
2699 f.seek(0)
2722 f.seek(0)
2700 bundle[0] = exchange.readbundle(ui, f, fname)
2723 bundle[0] = exchange.readbundle(ui, f, fname)
2701 bundle[1] = repo.transaction(b'perf::unbundle')
2724 bundle[1] = repo.transaction(b'perf::unbundle')
2702 bundle[1]._report = noop_report # silence the transaction
2725 # silence the transaction
2726 bundle[1]._report = noop_report
2703
2727
2704 def apply():
2728 def apply():
2705 gen, tr = bundle
2729 gen, tr = bundle
2706 bundle2.applybundle(
2730 bundle2.applybundle(
2707 repo,
2731 repo,
2708 gen,
2732 gen,
2709 tr,
2733 tr,
2710 source=b'perf::unbundle',
2734 source=b'perf::unbundle',
2711 url=fname,
2735 url=fname,
2712 )
2736 )
2713
2737
2714 timer, fm = gettimer(ui, opts)
2738 timer, fm = gettimer(ui, opts)
2715 timer(apply, setup=setup)
2739 timer(apply, setup=setup)
2716 fm.end()
2740 fm.end()
2717 finally:
2741 finally:
2718 repo.ui.quiet == orig_quiet
2742 repo.ui.quiet == orig_quiet
2719 gen, tr = bundle
2743 gen, tr = bundle
2720 if tr is not None:
2744 if tr is not None:
2721 tr.abort()
2745 tr.abort()
2746 finally:
2747 if old_max_inline is not None:
2748 mercurial.revlog._maxinline = old_max_inline
2722
2749
2723
2750
2724 @command(
2751 @command(
2725 b'perf::unidiff|perfunidiff',
2752 b'perf::unidiff|perfunidiff',
2726 revlogopts
2753 revlogopts
2727 + formatteropts
2754 + formatteropts
2728 + [
2755 + [
2729 (
2756 (
2730 b'',
2757 b'',
2731 b'count',
2758 b'count',
2732 1,
2759 1,
2733 b'number of revisions to test (when using --startrev)',
2760 b'number of revisions to test (when using --startrev)',
2734 ),
2761 ),
2735 (b'', b'alldata', False, b'test unidiffs for all associated revisions'),
2762 (b'', b'alldata', False, b'test unidiffs for all associated revisions'),
2736 ],
2763 ],
2737 b'-c|-m|FILE REV',
2764 b'-c|-m|FILE REV',
2738 )
2765 )
2739 def perfunidiff(ui, repo, file_, rev=None, count=None, **opts):
2766 def perfunidiff(ui, repo, file_, rev=None, count=None, **opts):
2740 """benchmark a unified diff between revisions
2767 """benchmark a unified diff between revisions
2741
2768
2742 This doesn't include any copy tracing - it's just a unified diff
2769 This doesn't include any copy tracing - it's just a unified diff
2743 of the texts.
2770 of the texts.
2744
2771
2745 By default, benchmark a diff between its delta parent and itself.
2772 By default, benchmark a diff between its delta parent and itself.
2746
2773
2747 With ``--count``, benchmark diffs between delta parents and self for N
2774 With ``--count``, benchmark diffs between delta parents and self for N
2748 revisions starting at the specified revision.
2775 revisions starting at the specified revision.
2749
2776
2750 With ``--alldata``, assume the requested revision is a changeset and
2777 With ``--alldata``, assume the requested revision is a changeset and
2751 measure diffs for all changes related to that changeset (manifest
2778 measure diffs for all changes related to that changeset (manifest
2752 and filelogs).
2779 and filelogs).
2753 """
2780 """
2754 opts = _byteskwargs(opts)
2781 opts = _byteskwargs(opts)
2755 if opts[b'alldata']:
2782 if opts[b'alldata']:
2756 opts[b'changelog'] = True
2783 opts[b'changelog'] = True
2757
2784
2758 if opts.get(b'changelog') or opts.get(b'manifest'):
2785 if opts.get(b'changelog') or opts.get(b'manifest'):
2759 file_, rev = None, file_
2786 file_, rev = None, file_
2760 elif rev is None:
2787 elif rev is None:
2761 raise error.CommandError(b'perfunidiff', b'invalid arguments')
2788 raise error.CommandError(b'perfunidiff', b'invalid arguments')
2762
2789
2763 textpairs = []
2790 textpairs = []
2764
2791
2765 r = cmdutil.openrevlog(repo, b'perfunidiff', file_, opts)
2792 r = cmdutil.openrevlog(repo, b'perfunidiff', file_, opts)
2766
2793
2767 startrev = r.rev(r.lookup(rev))
2794 startrev = r.rev(r.lookup(rev))
2768 for rev in range(startrev, min(startrev + count, len(r) - 1)):
2795 for rev in range(startrev, min(startrev + count, len(r) - 1)):
2769 if opts[b'alldata']:
2796 if opts[b'alldata']:
2770 # Load revisions associated with changeset.
2797 # Load revisions associated with changeset.
2771 ctx = repo[rev]
2798 ctx = repo[rev]
2772 mtext = _manifestrevision(repo, ctx.manifestnode())
2799 mtext = _manifestrevision(repo, ctx.manifestnode())
2773 for pctx in ctx.parents():
2800 for pctx in ctx.parents():
2774 pman = _manifestrevision(repo, pctx.manifestnode())
2801 pman = _manifestrevision(repo, pctx.manifestnode())
2775 textpairs.append((pman, mtext))
2802 textpairs.append((pman, mtext))
2776
2803
2777 # Load filelog revisions by iterating manifest delta.
2804 # Load filelog revisions by iterating manifest delta.
2778 man = ctx.manifest()
2805 man = ctx.manifest()
2779 pman = ctx.p1().manifest()
2806 pman = ctx.p1().manifest()
2780 for filename, change in pman.diff(man).items():
2807 for filename, change in pman.diff(man).items():
2781 fctx = repo.file(filename)
2808 fctx = repo.file(filename)
2782 f1 = fctx.revision(change[0][0] or -1)
2809 f1 = fctx.revision(change[0][0] or -1)
2783 f2 = fctx.revision(change[1][0] or -1)
2810 f2 = fctx.revision(change[1][0] or -1)
2784 textpairs.append((f1, f2))
2811 textpairs.append((f1, f2))
2785 else:
2812 else:
2786 dp = r.deltaparent(rev)
2813 dp = r.deltaparent(rev)
2787 textpairs.append((r.revision(dp), r.revision(rev)))
2814 textpairs.append((r.revision(dp), r.revision(rev)))
2788
2815
2789 def d():
2816 def d():
2790 for left, right in textpairs:
2817 for left, right in textpairs:
2791 # The date strings don't matter, so we pass empty strings.
2818 # The date strings don't matter, so we pass empty strings.
2792 headerlines, hunks = mdiff.unidiff(
2819 headerlines, hunks = mdiff.unidiff(
2793 left, b'', right, b'', b'left', b'right', binary=False
2820 left, b'', right, b'', b'left', b'right', binary=False
2794 )
2821 )
2795 # consume iterators in roughly the way patch.py does
2822 # consume iterators in roughly the way patch.py does
2796 b'\n'.join(headerlines)
2823 b'\n'.join(headerlines)
2797 b''.join(sum((list(hlines) for hrange, hlines in hunks), []))
2824 b''.join(sum((list(hlines) for hrange, hlines in hunks), []))
2798
2825
2799 timer, fm = gettimer(ui, opts)
2826 timer, fm = gettimer(ui, opts)
2800 timer(d)
2827 timer(d)
2801 fm.end()
2828 fm.end()
2802
2829
2803
2830
2804 @command(b'perf::diffwd|perfdiffwd', formatteropts)
2831 @command(b'perf::diffwd|perfdiffwd', formatteropts)
2805 def perfdiffwd(ui, repo, **opts):
2832 def perfdiffwd(ui, repo, **opts):
2806 """Profile diff of working directory changes"""
2833 """Profile diff of working directory changes"""
2807 opts = _byteskwargs(opts)
2834 opts = _byteskwargs(opts)
2808 timer, fm = gettimer(ui, opts)
2835 timer, fm = gettimer(ui, opts)
2809 options = {
2836 options = {
2810 'w': 'ignore_all_space',
2837 'w': 'ignore_all_space',
2811 'b': 'ignore_space_change',
2838 'b': 'ignore_space_change',
2812 'B': 'ignore_blank_lines',
2839 'B': 'ignore_blank_lines',
2813 }
2840 }
2814
2841
2815 for diffopt in ('', 'w', 'b', 'B', 'wB'):
2842 for diffopt in ('', 'w', 'b', 'B', 'wB'):
2816 opts = {options[c]: b'1' for c in diffopt}
2843 opts = {options[c]: b'1' for c in diffopt}
2817
2844
2818 def d():
2845 def d():
2819 ui.pushbuffer()
2846 ui.pushbuffer()
2820 commands.diff(ui, repo, **opts)
2847 commands.diff(ui, repo, **opts)
2821 ui.popbuffer()
2848 ui.popbuffer()
2822
2849
2823 diffopt = diffopt.encode('ascii')
2850 diffopt = diffopt.encode('ascii')
2824 title = b'diffopts: %s' % (diffopt and (b'-' + diffopt) or b'none')
2851 title = b'diffopts: %s' % (diffopt and (b'-' + diffopt) or b'none')
2825 timer(d, title=title)
2852 timer(d, title=title)
2826 fm.end()
2853 fm.end()
2827
2854
2828
2855
2829 @command(
2856 @command(
2830 b'perf::revlogindex|perfrevlogindex',
2857 b'perf::revlogindex|perfrevlogindex',
2831 revlogopts + formatteropts,
2858 revlogopts + formatteropts,
2832 b'-c|-m|FILE',
2859 b'-c|-m|FILE',
2833 )
2860 )
2834 def perfrevlogindex(ui, repo, file_=None, **opts):
2861 def perfrevlogindex(ui, repo, file_=None, **opts):
2835 """Benchmark operations against a revlog index.
2862 """Benchmark operations against a revlog index.
2836
2863
2837 This tests constructing a revlog instance, reading index data,
2864 This tests constructing a revlog instance, reading index data,
2838 parsing index data, and performing various operations related to
2865 parsing index data, and performing various operations related to
2839 index data.
2866 index data.
2840 """
2867 """
2841
2868
2842 opts = _byteskwargs(opts)
2869 opts = _byteskwargs(opts)
2843
2870
2844 rl = cmdutil.openrevlog(repo, b'perfrevlogindex', file_, opts)
2871 rl = cmdutil.openrevlog(repo, b'perfrevlogindex', file_, opts)
2845
2872
2846 opener = getattr(rl, 'opener') # trick linter
2873 opener = getattr(rl, 'opener') # trick linter
2847 # compat with hg <= 5.8
2874 # compat with hg <= 5.8
2848 radix = getattr(rl, 'radix', None)
2875 radix = getattr(rl, 'radix', None)
2849 indexfile = getattr(rl, '_indexfile', None)
2876 indexfile = getattr(rl, '_indexfile', None)
2850 if indexfile is None:
2877 if indexfile is None:
2851 # compatibility with <= hg-5.8
2878 # compatibility with <= hg-5.8
2852 indexfile = getattr(rl, 'indexfile')
2879 indexfile = getattr(rl, 'indexfile')
2853 data = opener.read(indexfile)
2880 data = opener.read(indexfile)
2854
2881
2855 header = struct.unpack(b'>I', data[0:4])[0]
2882 header = struct.unpack(b'>I', data[0:4])[0]
2856 version = header & 0xFFFF
2883 version = header & 0xFFFF
2857 if version == 1:
2884 if version == 1:
2858 inline = header & (1 << 16)
2885 inline = header & (1 << 16)
2859 else:
2886 else:
2860 raise error.Abort(b'unsupported revlog version: %d' % version)
2887 raise error.Abort(b'unsupported revlog version: %d' % version)
2861
2888
2862 parse_index_v1 = getattr(mercurial.revlog, 'parse_index_v1', None)
2889 parse_index_v1 = getattr(mercurial.revlog, 'parse_index_v1', None)
2863 if parse_index_v1 is None:
2890 if parse_index_v1 is None:
2864 parse_index_v1 = mercurial.revlog.revlogio().parseindex
2891 parse_index_v1 = mercurial.revlog.revlogio().parseindex
2865
2892
2866 rllen = len(rl)
2893 rllen = len(rl)
2867
2894
2868 node0 = rl.node(0)
2895 node0 = rl.node(0)
2869 node25 = rl.node(rllen // 4)
2896 node25 = rl.node(rllen // 4)
2870 node50 = rl.node(rllen // 2)
2897 node50 = rl.node(rllen // 2)
2871 node75 = rl.node(rllen // 4 * 3)
2898 node75 = rl.node(rllen // 4 * 3)
2872 node100 = rl.node(rllen - 1)
2899 node100 = rl.node(rllen - 1)
2873
2900
2874 allrevs = range(rllen)
2901 allrevs = range(rllen)
2875 allrevsrev = list(reversed(allrevs))
2902 allrevsrev = list(reversed(allrevs))
2876 allnodes = [rl.node(rev) for rev in range(rllen)]
2903 allnodes = [rl.node(rev) for rev in range(rllen)]
2877 allnodesrev = list(reversed(allnodes))
2904 allnodesrev = list(reversed(allnodes))
2878
2905
2879 def constructor():
2906 def constructor():
2880 if radix is not None:
2907 if radix is not None:
2881 revlog(opener, radix=radix)
2908 revlog(opener, radix=radix)
2882 else:
2909 else:
2883 # hg <= 5.8
2910 # hg <= 5.8
2884 revlog(opener, indexfile=indexfile)
2911 revlog(opener, indexfile=indexfile)
2885
2912
2886 def read():
2913 def read():
2887 with opener(indexfile) as fh:
2914 with opener(indexfile) as fh:
2888 fh.read()
2915 fh.read()
2889
2916
2890 def parseindex():
2917 def parseindex():
2891 parse_index_v1(data, inline)
2918 parse_index_v1(data, inline)
2892
2919
2893 def getentry(revornode):
2920 def getentry(revornode):
2894 index = parse_index_v1(data, inline)[0]
2921 index = parse_index_v1(data, inline)[0]
2895 index[revornode]
2922 index[revornode]
2896
2923
2897 def getentries(revs, count=1):
2924 def getentries(revs, count=1):
2898 index = parse_index_v1(data, inline)[0]
2925 index = parse_index_v1(data, inline)[0]
2899
2926
2900 for i in range(count):
2927 for i in range(count):
2901 for rev in revs:
2928 for rev in revs:
2902 index[rev]
2929 index[rev]
2903
2930
2904 def resolvenode(node):
2931 def resolvenode(node):
2905 index = parse_index_v1(data, inline)[0]
2932 index = parse_index_v1(data, inline)[0]
2906 rev = getattr(index, 'rev', None)
2933 rev = getattr(index, 'rev', None)
2907 if rev is None:
2934 if rev is None:
2908 nodemap = getattr(parse_index_v1(data, inline)[0], 'nodemap', None)
2935 nodemap = getattr(parse_index_v1(data, inline)[0], 'nodemap', None)
2909 # This only works for the C code.
2936 # This only works for the C code.
2910 if nodemap is None:
2937 if nodemap is None:
2911 return
2938 return
2912 rev = nodemap.__getitem__
2939 rev = nodemap.__getitem__
2913
2940
2914 try:
2941 try:
2915 rev(node)
2942 rev(node)
2916 except error.RevlogError:
2943 except error.RevlogError:
2917 pass
2944 pass
2918
2945
2919 def resolvenodes(nodes, count=1):
2946 def resolvenodes(nodes, count=1):
2920 index = parse_index_v1(data, inline)[0]
2947 index = parse_index_v1(data, inline)[0]
2921 rev = getattr(index, 'rev', None)
2948 rev = getattr(index, 'rev', None)
2922 if rev is None:
2949 if rev is None:
2923 nodemap = getattr(parse_index_v1(data, inline)[0], 'nodemap', None)
2950 nodemap = getattr(parse_index_v1(data, inline)[0], 'nodemap', None)
2924 # This only works for the C code.
2951 # This only works for the C code.
2925 if nodemap is None:
2952 if nodemap is None:
2926 return
2953 return
2927 rev = nodemap.__getitem__
2954 rev = nodemap.__getitem__
2928
2955
2929 for i in range(count):
2956 for i in range(count):
2930 for node in nodes:
2957 for node in nodes:
2931 try:
2958 try:
2932 rev(node)
2959 rev(node)
2933 except error.RevlogError:
2960 except error.RevlogError:
2934 pass
2961 pass
2935
2962
2936 benches = [
2963 benches = [
2937 (constructor, b'revlog constructor'),
2964 (constructor, b'revlog constructor'),
2938 (read, b'read'),
2965 (read, b'read'),
2939 (parseindex, b'create index object'),
2966 (parseindex, b'create index object'),
2940 (lambda: getentry(0), b'retrieve index entry for rev 0'),
2967 (lambda: getentry(0), b'retrieve index entry for rev 0'),
2941 (lambda: resolvenode(b'a' * 20), b'look up missing node'),
2968 (lambda: resolvenode(b'a' * 20), b'look up missing node'),
2942 (lambda: resolvenode(node0), b'look up node at rev 0'),
2969 (lambda: resolvenode(node0), b'look up node at rev 0'),
2943 (lambda: resolvenode(node25), b'look up node at 1/4 len'),
2970 (lambda: resolvenode(node25), b'look up node at 1/4 len'),
2944 (lambda: resolvenode(node50), b'look up node at 1/2 len'),
2971 (lambda: resolvenode(node50), b'look up node at 1/2 len'),
2945 (lambda: resolvenode(node75), b'look up node at 3/4 len'),
2972 (lambda: resolvenode(node75), b'look up node at 3/4 len'),
2946 (lambda: resolvenode(node100), b'look up node at tip'),
2973 (lambda: resolvenode(node100), b'look up node at tip'),
2947 # 2x variation is to measure caching impact.
2974 # 2x variation is to measure caching impact.
2948 (lambda: resolvenodes(allnodes), b'look up all nodes (forward)'),
2975 (lambda: resolvenodes(allnodes), b'look up all nodes (forward)'),
2949 (lambda: resolvenodes(allnodes, 2), b'look up all nodes 2x (forward)'),
2976 (lambda: resolvenodes(allnodes, 2), b'look up all nodes 2x (forward)'),
2950 (lambda: resolvenodes(allnodesrev), b'look up all nodes (reverse)'),
2977 (lambda: resolvenodes(allnodesrev), b'look up all nodes (reverse)'),
2951 (
2978 (
2952 lambda: resolvenodes(allnodesrev, 2),
2979 lambda: resolvenodes(allnodesrev, 2),
2953 b'look up all nodes 2x (reverse)',
2980 b'look up all nodes 2x (reverse)',
2954 ),
2981 ),
2955 (lambda: getentries(allrevs), b'retrieve all index entries (forward)'),
2982 (lambda: getentries(allrevs), b'retrieve all index entries (forward)'),
2956 (
2983 (
2957 lambda: getentries(allrevs, 2),
2984 lambda: getentries(allrevs, 2),
2958 b'retrieve all index entries 2x (forward)',
2985 b'retrieve all index entries 2x (forward)',
2959 ),
2986 ),
2960 (
2987 (
2961 lambda: getentries(allrevsrev),
2988 lambda: getentries(allrevsrev),
2962 b'retrieve all index entries (reverse)',
2989 b'retrieve all index entries (reverse)',
2963 ),
2990 ),
2964 (
2991 (
2965 lambda: getentries(allrevsrev, 2),
2992 lambda: getentries(allrevsrev, 2),
2966 b'retrieve all index entries 2x (reverse)',
2993 b'retrieve all index entries 2x (reverse)',
2967 ),
2994 ),
2968 ]
2995 ]
2969
2996
2970 for fn, title in benches:
2997 for fn, title in benches:
2971 timer, fm = gettimer(ui, opts)
2998 timer, fm = gettimer(ui, opts)
2972 timer(fn, title=title)
2999 timer(fn, title=title)
2973 fm.end()
3000 fm.end()
2974
3001
2975
3002
2976 @command(
3003 @command(
2977 b'perf::revlogrevisions|perfrevlogrevisions',
3004 b'perf::revlogrevisions|perfrevlogrevisions',
2978 revlogopts
3005 revlogopts
2979 + formatteropts
3006 + formatteropts
2980 + [
3007 + [
2981 (b'd', b'dist', 100, b'distance between the revisions'),
3008 (b'd', b'dist', 100, b'distance between the revisions'),
2982 (b's', b'startrev', 0, b'revision to start reading at'),
3009 (b's', b'startrev', 0, b'revision to start reading at'),
2983 (b'', b'reverse', False, b'read in reverse'),
3010 (b'', b'reverse', False, b'read in reverse'),
2984 ],
3011 ],
2985 b'-c|-m|FILE',
3012 b'-c|-m|FILE',
2986 )
3013 )
2987 def perfrevlogrevisions(
3014 def perfrevlogrevisions(
2988 ui, repo, file_=None, startrev=0, reverse=False, **opts
3015 ui, repo, file_=None, startrev=0, reverse=False, **opts
2989 ):
3016 ):
2990 """Benchmark reading a series of revisions from a revlog.
3017 """Benchmark reading a series of revisions from a revlog.
2991
3018
2992 By default, we read every ``-d/--dist`` revision from 0 to tip of
3019 By default, we read every ``-d/--dist`` revision from 0 to tip of
2993 the specified revlog.
3020 the specified revlog.
2994
3021
2995 The start revision can be defined via ``-s/--startrev``.
3022 The start revision can be defined via ``-s/--startrev``.
2996 """
3023 """
2997 opts = _byteskwargs(opts)
3024 opts = _byteskwargs(opts)
2998
3025
2999 rl = cmdutil.openrevlog(repo, b'perfrevlogrevisions', file_, opts)
3026 rl = cmdutil.openrevlog(repo, b'perfrevlogrevisions', file_, opts)
3000 rllen = getlen(ui)(rl)
3027 rllen = getlen(ui)(rl)
3001
3028
3002 if startrev < 0:
3029 if startrev < 0:
3003 startrev = rllen + startrev
3030 startrev = rllen + startrev
3004
3031
3005 def d():
3032 def d():
3006 rl.clearcaches()
3033 rl.clearcaches()
3007
3034
3008 beginrev = startrev
3035 beginrev = startrev
3009 endrev = rllen
3036 endrev = rllen
3010 dist = opts[b'dist']
3037 dist = opts[b'dist']
3011
3038
3012 if reverse:
3039 if reverse:
3013 beginrev, endrev = endrev - 1, beginrev - 1
3040 beginrev, endrev = endrev - 1, beginrev - 1
3014 dist = -1 * dist
3041 dist = -1 * dist
3015
3042
3016 for x in _xrange(beginrev, endrev, dist):
3043 for x in _xrange(beginrev, endrev, dist):
3017 # Old revisions don't support passing int.
3044 # Old revisions don't support passing int.
3018 n = rl.node(x)
3045 n = rl.node(x)
3019 rl.revision(n)
3046 rl.revision(n)
3020
3047
3021 timer, fm = gettimer(ui, opts)
3048 timer, fm = gettimer(ui, opts)
3022 timer(d)
3049 timer(d)
3023 fm.end()
3050 fm.end()
3024
3051
3025
3052
3026 @command(
3053 @command(
3027 b'perf::revlogwrite|perfrevlogwrite',
3054 b'perf::revlogwrite|perfrevlogwrite',
3028 revlogopts
3055 revlogopts
3029 + formatteropts
3056 + formatteropts
3030 + [
3057 + [
3031 (b's', b'startrev', 1000, b'revision to start writing at'),
3058 (b's', b'startrev', 1000, b'revision to start writing at'),
3032 (b'', b'stoprev', -1, b'last revision to write'),
3059 (b'', b'stoprev', -1, b'last revision to write'),
3033 (b'', b'count', 3, b'number of passes to perform'),
3060 (b'', b'count', 3, b'number of passes to perform'),
3034 (b'', b'details', False, b'print timing for every revisions tested'),
3061 (b'', b'details', False, b'print timing for every revisions tested'),
3035 (b'', b'source', b'full', b'the kind of data feed in the revlog'),
3062 (b'', b'source', b'full', b'the kind of data feed in the revlog'),
3036 (b'', b'lazydeltabase', True, b'try the provided delta first'),
3063 (b'', b'lazydeltabase', True, b'try the provided delta first'),
3037 (b'', b'clear-caches', True, b'clear revlog cache between calls'),
3064 (b'', b'clear-caches', True, b'clear revlog cache between calls'),
3038 ],
3065 ],
3039 b'-c|-m|FILE',
3066 b'-c|-m|FILE',
3040 )
3067 )
3041 def perfrevlogwrite(ui, repo, file_=None, startrev=1000, stoprev=-1, **opts):
3068 def perfrevlogwrite(ui, repo, file_=None, startrev=1000, stoprev=-1, **opts):
3042 """Benchmark writing a series of revisions to a revlog.
3069 """Benchmark writing a series of revisions to a revlog.
3043
3070
3044 Possible source values are:
3071 Possible source values are:
3045 * `full`: add from a full text (default).
3072 * `full`: add from a full text (default).
3046 * `parent-1`: add from a delta to the first parent
3073 * `parent-1`: add from a delta to the first parent
3047 * `parent-2`: add from a delta to the second parent if it exists
3074 * `parent-2`: add from a delta to the second parent if it exists
3048 (use a delta from the first parent otherwise)
3075 (use a delta from the first parent otherwise)
3049 * `parent-smallest`: add from the smallest delta (either p1 or p2)
3076 * `parent-smallest`: add from the smallest delta (either p1 or p2)
3050 * `storage`: add from the existing precomputed deltas
3077 * `storage`: add from the existing precomputed deltas
3051
3078
3052 Note: This performance command measures performance in a custom way. As a
3079 Note: This performance command measures performance in a custom way. As a
3053 result some of the global configuration of the 'perf' command does not
3080 result some of the global configuration of the 'perf' command does not
3054 apply to it:
3081 apply to it:
3055
3082
3056 * ``pre-run``: disabled
3083 * ``pre-run``: disabled
3057
3084
3058 * ``profile-benchmark``: disabled
3085 * ``profile-benchmark``: disabled
3059
3086
3060 * ``run-limits``: disabled use --count instead
3087 * ``run-limits``: disabled use --count instead
3061 """
3088 """
3062 opts = _byteskwargs(opts)
3089 opts = _byteskwargs(opts)
3063
3090
3064 rl = cmdutil.openrevlog(repo, b'perfrevlogwrite', file_, opts)
3091 rl = cmdutil.openrevlog(repo, b'perfrevlogwrite', file_, opts)
3065 rllen = getlen(ui)(rl)
3092 rllen = getlen(ui)(rl)
3066 if startrev < 0:
3093 if startrev < 0:
3067 startrev = rllen + startrev
3094 startrev = rllen + startrev
3068 if stoprev < 0:
3095 if stoprev < 0:
3069 stoprev = rllen + stoprev
3096 stoprev = rllen + stoprev
3070
3097
3071 lazydeltabase = opts['lazydeltabase']
3098 lazydeltabase = opts['lazydeltabase']
3072 source = opts['source']
3099 source = opts['source']
3073 clearcaches = opts['clear_caches']
3100 clearcaches = opts['clear_caches']
3074 validsource = (
3101 validsource = (
3075 b'full',
3102 b'full',
3076 b'parent-1',
3103 b'parent-1',
3077 b'parent-2',
3104 b'parent-2',
3078 b'parent-smallest',
3105 b'parent-smallest',
3079 b'storage',
3106 b'storage',
3080 )
3107 )
3081 if source not in validsource:
3108 if source not in validsource:
3082 raise error.Abort('invalid source type: %s' % source)
3109 raise error.Abort('invalid source type: %s' % source)
3083
3110
3084 ### actually gather results
3111 ### actually gather results
3085 count = opts['count']
3112 count = opts['count']
3086 if count <= 0:
3113 if count <= 0:
3087 raise error.Abort('invalide run count: %d' % count)
3114 raise error.Abort('invalide run count: %d' % count)
3088 allresults = []
3115 allresults = []
3089 for c in range(count):
3116 for c in range(count):
3090 timing = _timeonewrite(
3117 timing = _timeonewrite(
3091 ui,
3118 ui,
3092 rl,
3119 rl,
3093 source,
3120 source,
3094 startrev,
3121 startrev,
3095 stoprev,
3122 stoprev,
3096 c + 1,
3123 c + 1,
3097 lazydeltabase=lazydeltabase,
3124 lazydeltabase=lazydeltabase,
3098 clearcaches=clearcaches,
3125 clearcaches=clearcaches,
3099 )
3126 )
3100 allresults.append(timing)
3127 allresults.append(timing)
3101
3128
3102 ### consolidate the results in a single list
3129 ### consolidate the results in a single list
3103 results = []
3130 results = []
3104 for idx, (rev, t) in enumerate(allresults[0]):
3131 for idx, (rev, t) in enumerate(allresults[0]):
3105 ts = [t]
3132 ts = [t]
3106 for other in allresults[1:]:
3133 for other in allresults[1:]:
3107 orev, ot = other[idx]
3134 orev, ot = other[idx]
3108 assert orev == rev
3135 assert orev == rev
3109 ts.append(ot)
3136 ts.append(ot)
3110 results.append((rev, ts))
3137 results.append((rev, ts))
3111 resultcount = len(results)
3138 resultcount = len(results)
3112
3139
3113 ### Compute and display relevant statistics
3140 ### Compute and display relevant statistics
3114
3141
3115 # get a formatter
3142 # get a formatter
3116 fm = ui.formatter(b'perf', opts)
3143 fm = ui.formatter(b'perf', opts)
3117 displayall = ui.configbool(b"perf", b"all-timing", False)
3144 displayall = ui.configbool(b"perf", b"all-timing", False)
3118
3145
3119 # print individual details if requested
3146 # print individual details if requested
3120 if opts['details']:
3147 if opts['details']:
3121 for idx, item in enumerate(results, 1):
3148 for idx, item in enumerate(results, 1):
3122 rev, data = item
3149 rev, data = item
3123 title = 'revisions #%d of %d, rev %d' % (idx, resultcount, rev)
3150 title = 'revisions #%d of %d, rev %d' % (idx, resultcount, rev)
3124 formatone(fm, data, title=title, displayall=displayall)
3151 formatone(fm, data, title=title, displayall=displayall)
3125
3152
3126 # sorts results by median time
3153 # sorts results by median time
3127 results.sort(key=lambda x: sorted(x[1])[len(x[1]) // 2])
3154 results.sort(key=lambda x: sorted(x[1])[len(x[1]) // 2])
3128 # list of (name, index) to display)
3155 # list of (name, index) to display)
3129 relevants = [
3156 relevants = [
3130 ("min", 0),
3157 ("min", 0),
3131 ("10%", resultcount * 10 // 100),
3158 ("10%", resultcount * 10 // 100),
3132 ("25%", resultcount * 25 // 100),
3159 ("25%", resultcount * 25 // 100),
3133 ("50%", resultcount * 70 // 100),
3160 ("50%", resultcount * 70 // 100),
3134 ("75%", resultcount * 75 // 100),
3161 ("75%", resultcount * 75 // 100),
3135 ("90%", resultcount * 90 // 100),
3162 ("90%", resultcount * 90 // 100),
3136 ("95%", resultcount * 95 // 100),
3163 ("95%", resultcount * 95 // 100),
3137 ("99%", resultcount * 99 // 100),
3164 ("99%", resultcount * 99 // 100),
3138 ("99.9%", resultcount * 999 // 1000),
3165 ("99.9%", resultcount * 999 // 1000),
3139 ("99.99%", resultcount * 9999 // 10000),
3166 ("99.99%", resultcount * 9999 // 10000),
3140 ("99.999%", resultcount * 99999 // 100000),
3167 ("99.999%", resultcount * 99999 // 100000),
3141 ("max", -1),
3168 ("max", -1),
3142 ]
3169 ]
3143 if not ui.quiet:
3170 if not ui.quiet:
3144 for name, idx in relevants:
3171 for name, idx in relevants:
3145 data = results[idx]
3172 data = results[idx]
3146 title = '%s of %d, rev %d' % (name, resultcount, data[0])
3173 title = '%s of %d, rev %d' % (name, resultcount, data[0])
3147 formatone(fm, data[1], title=title, displayall=displayall)
3174 formatone(fm, data[1], title=title, displayall=displayall)
3148
3175
3149 # XXX summing that many float will not be very precise, we ignore this fact
3176 # XXX summing that many float will not be very precise, we ignore this fact
3150 # for now
3177 # for now
3151 totaltime = []
3178 totaltime = []
3152 for item in allresults:
3179 for item in allresults:
3153 totaltime.append(
3180 totaltime.append(
3154 (
3181 (
3155 sum(x[1][0] for x in item),
3182 sum(x[1][0] for x in item),
3156 sum(x[1][1] for x in item),
3183 sum(x[1][1] for x in item),
3157 sum(x[1][2] for x in item),
3184 sum(x[1][2] for x in item),
3158 )
3185 )
3159 )
3186 )
3160 formatone(
3187 formatone(
3161 fm,
3188 fm,
3162 totaltime,
3189 totaltime,
3163 title="total time (%d revs)" % resultcount,
3190 title="total time (%d revs)" % resultcount,
3164 displayall=displayall,
3191 displayall=displayall,
3165 )
3192 )
3166 fm.end()
3193 fm.end()
3167
3194
3168
3195
3169 class _faketr:
3196 class _faketr:
3170 def add(s, x, y, z=None):
3197 def add(s, x, y, z=None):
3171 return None
3198 return None
3172
3199
3173
3200
3174 def _timeonewrite(
3201 def _timeonewrite(
3175 ui,
3202 ui,
3176 orig,
3203 orig,
3177 source,
3204 source,
3178 startrev,
3205 startrev,
3179 stoprev,
3206 stoprev,
3180 runidx=None,
3207 runidx=None,
3181 lazydeltabase=True,
3208 lazydeltabase=True,
3182 clearcaches=True,
3209 clearcaches=True,
3183 ):
3210 ):
3184 timings = []
3211 timings = []
3185 tr = _faketr()
3212 tr = _faketr()
3186 with _temprevlog(ui, orig, startrev) as dest:
3213 with _temprevlog(ui, orig, startrev) as dest:
3187 dest._lazydeltabase = lazydeltabase
3214 dest._lazydeltabase = lazydeltabase
3188 revs = list(orig.revs(startrev, stoprev))
3215 revs = list(orig.revs(startrev, stoprev))
3189 total = len(revs)
3216 total = len(revs)
3190 topic = 'adding'
3217 topic = 'adding'
3191 if runidx is not None:
3218 if runidx is not None:
3192 topic += ' (run #%d)' % runidx
3219 topic += ' (run #%d)' % runidx
3193 # Support both old and new progress API
3220 # Support both old and new progress API
3194 if util.safehasattr(ui, 'makeprogress'):
3221 if util.safehasattr(ui, 'makeprogress'):
3195 progress = ui.makeprogress(topic, unit='revs', total=total)
3222 progress = ui.makeprogress(topic, unit='revs', total=total)
3196
3223
3197 def updateprogress(pos):
3224 def updateprogress(pos):
3198 progress.update(pos)
3225 progress.update(pos)
3199
3226
3200 def completeprogress():
3227 def completeprogress():
3201 progress.complete()
3228 progress.complete()
3202
3229
3203 else:
3230 else:
3204
3231
3205 def updateprogress(pos):
3232 def updateprogress(pos):
3206 ui.progress(topic, pos, unit='revs', total=total)
3233 ui.progress(topic, pos, unit='revs', total=total)
3207
3234
3208 def completeprogress():
3235 def completeprogress():
3209 ui.progress(topic, None, unit='revs', total=total)
3236 ui.progress(topic, None, unit='revs', total=total)
3210
3237
3211 for idx, rev in enumerate(revs):
3238 for idx, rev in enumerate(revs):
3212 updateprogress(idx)
3239 updateprogress(idx)
3213 addargs, addkwargs = _getrevisionseed(orig, rev, tr, source)
3240 addargs, addkwargs = _getrevisionseed(orig, rev, tr, source)
3214 if clearcaches:
3241 if clearcaches:
3215 dest.index.clearcaches()
3242 dest.index.clearcaches()
3216 dest.clearcaches()
3243 dest.clearcaches()
3217 with timeone() as r:
3244 with timeone() as r:
3218 dest.addrawrevision(*addargs, **addkwargs)
3245 dest.addrawrevision(*addargs, **addkwargs)
3219 timings.append((rev, r[0]))
3246 timings.append((rev, r[0]))
3220 updateprogress(total)
3247 updateprogress(total)
3221 completeprogress()
3248 completeprogress()
3222 return timings
3249 return timings
3223
3250
3224
3251
3225 def _getrevisionseed(orig, rev, tr, source):
3252 def _getrevisionseed(orig, rev, tr, source):
3226 from mercurial.node import nullid
3253 from mercurial.node import nullid
3227
3254
3228 linkrev = orig.linkrev(rev)
3255 linkrev = orig.linkrev(rev)
3229 node = orig.node(rev)
3256 node = orig.node(rev)
3230 p1, p2 = orig.parents(node)
3257 p1, p2 = orig.parents(node)
3231 flags = orig.flags(rev)
3258 flags = orig.flags(rev)
3232 cachedelta = None
3259 cachedelta = None
3233 text = None
3260 text = None
3234
3261
3235 if source == b'full':
3262 if source == b'full':
3236 text = orig.revision(rev)
3263 text = orig.revision(rev)
3237 elif source == b'parent-1':
3264 elif source == b'parent-1':
3238 baserev = orig.rev(p1)
3265 baserev = orig.rev(p1)
3239 cachedelta = (baserev, orig.revdiff(p1, rev))
3266 cachedelta = (baserev, orig.revdiff(p1, rev))
3240 elif source == b'parent-2':
3267 elif source == b'parent-2':
3241 parent = p2
3268 parent = p2
3242 if p2 == nullid:
3269 if p2 == nullid:
3243 parent = p1
3270 parent = p1
3244 baserev = orig.rev(parent)
3271 baserev = orig.rev(parent)
3245 cachedelta = (baserev, orig.revdiff(parent, rev))
3272 cachedelta = (baserev, orig.revdiff(parent, rev))
3246 elif source == b'parent-smallest':
3273 elif source == b'parent-smallest':
3247 p1diff = orig.revdiff(p1, rev)
3274 p1diff = orig.revdiff(p1, rev)
3248 parent = p1
3275 parent = p1
3249 diff = p1diff
3276 diff = p1diff
3250 if p2 != nullid:
3277 if p2 != nullid:
3251 p2diff = orig.revdiff(p2, rev)
3278 p2diff = orig.revdiff(p2, rev)
3252 if len(p1diff) > len(p2diff):
3279 if len(p1diff) > len(p2diff):
3253 parent = p2
3280 parent = p2
3254 diff = p2diff
3281 diff = p2diff
3255 baserev = orig.rev(parent)
3282 baserev = orig.rev(parent)
3256 cachedelta = (baserev, diff)
3283 cachedelta = (baserev, diff)
3257 elif source == b'storage':
3284 elif source == b'storage':
3258 baserev = orig.deltaparent(rev)
3285 baserev = orig.deltaparent(rev)
3259 cachedelta = (baserev, orig.revdiff(orig.node(baserev), rev))
3286 cachedelta = (baserev, orig.revdiff(orig.node(baserev), rev))
3260
3287
3261 return (
3288 return (
3262 (text, tr, linkrev, p1, p2),
3289 (text, tr, linkrev, p1, p2),
3263 {'node': node, 'flags': flags, 'cachedelta': cachedelta},
3290 {'node': node, 'flags': flags, 'cachedelta': cachedelta},
3264 )
3291 )
3265
3292
3266
3293
3267 @contextlib.contextmanager
3294 @contextlib.contextmanager
3268 def _temprevlog(ui, orig, truncaterev):
3295 def _temprevlog(ui, orig, truncaterev):
3269 from mercurial import vfs as vfsmod
3296 from mercurial import vfs as vfsmod
3270
3297
3271 if orig._inline:
3298 if orig._inline:
3272 raise error.Abort('not supporting inline revlog (yet)')
3299 raise error.Abort('not supporting inline revlog (yet)')
3273 revlogkwargs = {}
3300 revlogkwargs = {}
3274 k = 'upperboundcomp'
3301 k = 'upperboundcomp'
3275 if util.safehasattr(orig, k):
3302 if util.safehasattr(orig, k):
3276 revlogkwargs[k] = getattr(orig, k)
3303 revlogkwargs[k] = getattr(orig, k)
3277
3304
3278 indexfile = getattr(orig, '_indexfile', None)
3305 indexfile = getattr(orig, '_indexfile', None)
3279 if indexfile is None:
3306 if indexfile is None:
3280 # compatibility with <= hg-5.8
3307 # compatibility with <= hg-5.8
3281 indexfile = getattr(orig, 'indexfile')
3308 indexfile = getattr(orig, 'indexfile')
3282 origindexpath = orig.opener.join(indexfile)
3309 origindexpath = orig.opener.join(indexfile)
3283
3310
3284 datafile = getattr(orig, '_datafile', getattr(orig, 'datafile'))
3311 datafile = getattr(orig, '_datafile', getattr(orig, 'datafile'))
3285 origdatapath = orig.opener.join(datafile)
3312 origdatapath = orig.opener.join(datafile)
3286 radix = b'revlog'
3313 radix = b'revlog'
3287 indexname = b'revlog.i'
3314 indexname = b'revlog.i'
3288 dataname = b'revlog.d'
3315 dataname = b'revlog.d'
3289
3316
3290 tmpdir = tempfile.mkdtemp(prefix='tmp-hgperf-')
3317 tmpdir = tempfile.mkdtemp(prefix='tmp-hgperf-')
3291 try:
3318 try:
3292 # copy the data file in a temporary directory
3319 # copy the data file in a temporary directory
3293 ui.debug('copying data in %s\n' % tmpdir)
3320 ui.debug('copying data in %s\n' % tmpdir)
3294 destindexpath = os.path.join(tmpdir, 'revlog.i')
3321 destindexpath = os.path.join(tmpdir, 'revlog.i')
3295 destdatapath = os.path.join(tmpdir, 'revlog.d')
3322 destdatapath = os.path.join(tmpdir, 'revlog.d')
3296 shutil.copyfile(origindexpath, destindexpath)
3323 shutil.copyfile(origindexpath, destindexpath)
3297 shutil.copyfile(origdatapath, destdatapath)
3324 shutil.copyfile(origdatapath, destdatapath)
3298
3325
3299 # remove the data we want to add again
3326 # remove the data we want to add again
3300 ui.debug('truncating data to be rewritten\n')
3327 ui.debug('truncating data to be rewritten\n')
3301 with open(destindexpath, 'ab') as index:
3328 with open(destindexpath, 'ab') as index:
3302 index.seek(0)
3329 index.seek(0)
3303 index.truncate(truncaterev * orig._io.size)
3330 index.truncate(truncaterev * orig._io.size)
3304 with open(destdatapath, 'ab') as data:
3331 with open(destdatapath, 'ab') as data:
3305 data.seek(0)
3332 data.seek(0)
3306 data.truncate(orig.start(truncaterev))
3333 data.truncate(orig.start(truncaterev))
3307
3334
3308 # instantiate a new revlog from the temporary copy
3335 # instantiate a new revlog from the temporary copy
3309 ui.debug('truncating adding to be rewritten\n')
3336 ui.debug('truncating adding to be rewritten\n')
3310 vfs = vfsmod.vfs(tmpdir)
3337 vfs = vfsmod.vfs(tmpdir)
3311 vfs.options = getattr(orig.opener, 'options', None)
3338 vfs.options = getattr(orig.opener, 'options', None)
3312
3339
3313 try:
3340 try:
3314 dest = revlog(vfs, radix=radix, **revlogkwargs)
3341 dest = revlog(vfs, radix=radix, **revlogkwargs)
3315 except TypeError:
3342 except TypeError:
3316 dest = revlog(
3343 dest = revlog(
3317 vfs, indexfile=indexname, datafile=dataname, **revlogkwargs
3344 vfs, indexfile=indexname, datafile=dataname, **revlogkwargs
3318 )
3345 )
3319 if dest._inline:
3346 if dest._inline:
3320 raise error.Abort('not supporting inline revlog (yet)')
3347 raise error.Abort('not supporting inline revlog (yet)')
3321 # make sure internals are initialized
3348 # make sure internals are initialized
3322 dest.revision(len(dest) - 1)
3349 dest.revision(len(dest) - 1)
3323 yield dest
3350 yield dest
3324 del dest, vfs
3351 del dest, vfs
3325 finally:
3352 finally:
3326 shutil.rmtree(tmpdir, True)
3353 shutil.rmtree(tmpdir, True)
3327
3354
3328
3355
3329 @command(
3356 @command(
3330 b'perf::revlogchunks|perfrevlogchunks',
3357 b'perf::revlogchunks|perfrevlogchunks',
3331 revlogopts
3358 revlogopts
3332 + formatteropts
3359 + formatteropts
3333 + [
3360 + [
3334 (b'e', b'engines', b'', b'compression engines to use'),
3361 (b'e', b'engines', b'', b'compression engines to use'),
3335 (b's', b'startrev', 0, b'revision to start at'),
3362 (b's', b'startrev', 0, b'revision to start at'),
3336 ],
3363 ],
3337 b'-c|-m|FILE',
3364 b'-c|-m|FILE',
3338 )
3365 )
3339 def perfrevlogchunks(ui, repo, file_=None, engines=None, startrev=0, **opts):
3366 def perfrevlogchunks(ui, repo, file_=None, engines=None, startrev=0, **opts):
3340 """Benchmark operations on revlog chunks.
3367 """Benchmark operations on revlog chunks.
3341
3368
3342 Logically, each revlog is a collection of fulltext revisions. However,
3369 Logically, each revlog is a collection of fulltext revisions. However,
3343 stored within each revlog are "chunks" of possibly compressed data. This
3370 stored within each revlog are "chunks" of possibly compressed data. This
3344 data needs to be read and decompressed or compressed and written.
3371 data needs to be read and decompressed or compressed and written.
3345
3372
3346 This command measures the time it takes to read+decompress and recompress
3373 This command measures the time it takes to read+decompress and recompress
3347 chunks in a revlog. It effectively isolates I/O and compression performance.
3374 chunks in a revlog. It effectively isolates I/O and compression performance.
3348 For measurements of higher-level operations like resolving revisions,
3375 For measurements of higher-level operations like resolving revisions,
3349 see ``perfrevlogrevisions`` and ``perfrevlogrevision``.
3376 see ``perfrevlogrevisions`` and ``perfrevlogrevision``.
3350 """
3377 """
3351 opts = _byteskwargs(opts)
3378 opts = _byteskwargs(opts)
3352
3379
3353 rl = cmdutil.openrevlog(repo, b'perfrevlogchunks', file_, opts)
3380 rl = cmdutil.openrevlog(repo, b'perfrevlogchunks', file_, opts)
3354
3381
3355 # _chunkraw was renamed to _getsegmentforrevs.
3382 # _chunkraw was renamed to _getsegmentforrevs.
3356 try:
3383 try:
3357 segmentforrevs = rl._getsegmentforrevs
3384 segmentforrevs = rl._getsegmentforrevs
3358 except AttributeError:
3385 except AttributeError:
3359 segmentforrevs = rl._chunkraw
3386 segmentforrevs = rl._chunkraw
3360
3387
3361 # Verify engines argument.
3388 # Verify engines argument.
3362 if engines:
3389 if engines:
3363 engines = {e.strip() for e in engines.split(b',')}
3390 engines = {e.strip() for e in engines.split(b',')}
3364 for engine in engines:
3391 for engine in engines:
3365 try:
3392 try:
3366 util.compressionengines[engine]
3393 util.compressionengines[engine]
3367 except KeyError:
3394 except KeyError:
3368 raise error.Abort(b'unknown compression engine: %s' % engine)
3395 raise error.Abort(b'unknown compression engine: %s' % engine)
3369 else:
3396 else:
3370 engines = []
3397 engines = []
3371 for e in util.compengines:
3398 for e in util.compengines:
3372 engine = util.compengines[e]
3399 engine = util.compengines[e]
3373 try:
3400 try:
3374 if engine.available():
3401 if engine.available():
3375 engine.revlogcompressor().compress(b'dummy')
3402 engine.revlogcompressor().compress(b'dummy')
3376 engines.append(e)
3403 engines.append(e)
3377 except NotImplementedError:
3404 except NotImplementedError:
3378 pass
3405 pass
3379
3406
3380 revs = list(rl.revs(startrev, len(rl) - 1))
3407 revs = list(rl.revs(startrev, len(rl) - 1))
3381
3408
3382 def rlfh(rl):
3409 def rlfh(rl):
3383 if rl._inline:
3410 if rl._inline:
3384 indexfile = getattr(rl, '_indexfile', None)
3411 indexfile = getattr(rl, '_indexfile', None)
3385 if indexfile is None:
3412 if indexfile is None:
3386 # compatibility with <= hg-5.8
3413 # compatibility with <= hg-5.8
3387 indexfile = getattr(rl, 'indexfile')
3414 indexfile = getattr(rl, 'indexfile')
3388 return getsvfs(repo)(indexfile)
3415 return getsvfs(repo)(indexfile)
3389 else:
3416 else:
3390 datafile = getattr(rl, 'datafile', getattr(rl, 'datafile'))
3417 datafile = getattr(rl, 'datafile', getattr(rl, 'datafile'))
3391 return getsvfs(repo)(datafile)
3418 return getsvfs(repo)(datafile)
3392
3419
3393 def doread():
3420 def doread():
3394 rl.clearcaches()
3421 rl.clearcaches()
3395 for rev in revs:
3422 for rev in revs:
3396 segmentforrevs(rev, rev)
3423 segmentforrevs(rev, rev)
3397
3424
3398 def doreadcachedfh():
3425 def doreadcachedfh():
3399 rl.clearcaches()
3426 rl.clearcaches()
3400 fh = rlfh(rl)
3427 fh = rlfh(rl)
3401 for rev in revs:
3428 for rev in revs:
3402 segmentforrevs(rev, rev, df=fh)
3429 segmentforrevs(rev, rev, df=fh)
3403
3430
3404 def doreadbatch():
3431 def doreadbatch():
3405 rl.clearcaches()
3432 rl.clearcaches()
3406 segmentforrevs(revs[0], revs[-1])
3433 segmentforrevs(revs[0], revs[-1])
3407
3434
3408 def doreadbatchcachedfh():
3435 def doreadbatchcachedfh():
3409 rl.clearcaches()
3436 rl.clearcaches()
3410 fh = rlfh(rl)
3437 fh = rlfh(rl)
3411 segmentforrevs(revs[0], revs[-1], df=fh)
3438 segmentforrevs(revs[0], revs[-1], df=fh)
3412
3439
3413 def dochunk():
3440 def dochunk():
3414 rl.clearcaches()
3441 rl.clearcaches()
3415 fh = rlfh(rl)
3442 fh = rlfh(rl)
3416 for rev in revs:
3443 for rev in revs:
3417 rl._chunk(rev, df=fh)
3444 rl._chunk(rev, df=fh)
3418
3445
3419 chunks = [None]
3446 chunks = [None]
3420
3447
3421 def dochunkbatch():
3448 def dochunkbatch():
3422 rl.clearcaches()
3449 rl.clearcaches()
3423 fh = rlfh(rl)
3450 fh = rlfh(rl)
3424 # Save chunks as a side-effect.
3451 # Save chunks as a side-effect.
3425 chunks[0] = rl._chunks(revs, df=fh)
3452 chunks[0] = rl._chunks(revs, df=fh)
3426
3453
3427 def docompress(compressor):
3454 def docompress(compressor):
3428 rl.clearcaches()
3455 rl.clearcaches()
3429
3456
3430 try:
3457 try:
3431 # Swap in the requested compression engine.
3458 # Swap in the requested compression engine.
3432 oldcompressor = rl._compressor
3459 oldcompressor = rl._compressor
3433 rl._compressor = compressor
3460 rl._compressor = compressor
3434 for chunk in chunks[0]:
3461 for chunk in chunks[0]:
3435 rl.compress(chunk)
3462 rl.compress(chunk)
3436 finally:
3463 finally:
3437 rl._compressor = oldcompressor
3464 rl._compressor = oldcompressor
3438
3465
3439 benches = [
3466 benches = [
3440 (lambda: doread(), b'read'),
3467 (lambda: doread(), b'read'),
3441 (lambda: doreadcachedfh(), b'read w/ reused fd'),
3468 (lambda: doreadcachedfh(), b'read w/ reused fd'),
3442 (lambda: doreadbatch(), b'read batch'),
3469 (lambda: doreadbatch(), b'read batch'),
3443 (lambda: doreadbatchcachedfh(), b'read batch w/ reused fd'),
3470 (lambda: doreadbatchcachedfh(), b'read batch w/ reused fd'),
3444 (lambda: dochunk(), b'chunk'),
3471 (lambda: dochunk(), b'chunk'),
3445 (lambda: dochunkbatch(), b'chunk batch'),
3472 (lambda: dochunkbatch(), b'chunk batch'),
3446 ]
3473 ]
3447
3474
3448 for engine in sorted(engines):
3475 for engine in sorted(engines):
3449 compressor = util.compengines[engine].revlogcompressor()
3476 compressor = util.compengines[engine].revlogcompressor()
3450 benches.append(
3477 benches.append(
3451 (
3478 (
3452 functools.partial(docompress, compressor),
3479 functools.partial(docompress, compressor),
3453 b'compress w/ %s' % engine,
3480 b'compress w/ %s' % engine,
3454 )
3481 )
3455 )
3482 )
3456
3483
3457 for fn, title in benches:
3484 for fn, title in benches:
3458 timer, fm = gettimer(ui, opts)
3485 timer, fm = gettimer(ui, opts)
3459 timer(fn, title=title)
3486 timer(fn, title=title)
3460 fm.end()
3487 fm.end()
3461
3488
3462
3489
3463 @command(
3490 @command(
3464 b'perf::revlogrevision|perfrevlogrevision',
3491 b'perf::revlogrevision|perfrevlogrevision',
3465 revlogopts
3492 revlogopts
3466 + formatteropts
3493 + formatteropts
3467 + [(b'', b'cache', False, b'use caches instead of clearing')],
3494 + [(b'', b'cache', False, b'use caches instead of clearing')],
3468 b'-c|-m|FILE REV',
3495 b'-c|-m|FILE REV',
3469 )
3496 )
3470 def perfrevlogrevision(ui, repo, file_, rev=None, cache=None, **opts):
3497 def perfrevlogrevision(ui, repo, file_, rev=None, cache=None, **opts):
3471 """Benchmark obtaining a revlog revision.
3498 """Benchmark obtaining a revlog revision.
3472
3499
3473 Obtaining a revlog revision consists of roughly the following steps:
3500 Obtaining a revlog revision consists of roughly the following steps:
3474
3501
3475 1. Compute the delta chain
3502 1. Compute the delta chain
3476 2. Slice the delta chain if applicable
3503 2. Slice the delta chain if applicable
3477 3. Obtain the raw chunks for that delta chain
3504 3. Obtain the raw chunks for that delta chain
3478 4. Decompress each raw chunk
3505 4. Decompress each raw chunk
3479 5. Apply binary patches to obtain fulltext
3506 5. Apply binary patches to obtain fulltext
3480 6. Verify hash of fulltext
3507 6. Verify hash of fulltext
3481
3508
3482 This command measures the time spent in each of these phases.
3509 This command measures the time spent in each of these phases.
3483 """
3510 """
3484 opts = _byteskwargs(opts)
3511 opts = _byteskwargs(opts)
3485
3512
3486 if opts.get(b'changelog') or opts.get(b'manifest'):
3513 if opts.get(b'changelog') or opts.get(b'manifest'):
3487 file_, rev = None, file_
3514 file_, rev = None, file_
3488 elif rev is None:
3515 elif rev is None:
3489 raise error.CommandError(b'perfrevlogrevision', b'invalid arguments')
3516 raise error.CommandError(b'perfrevlogrevision', b'invalid arguments')
3490
3517
3491 r = cmdutil.openrevlog(repo, b'perfrevlogrevision', file_, opts)
3518 r = cmdutil.openrevlog(repo, b'perfrevlogrevision', file_, opts)
3492
3519
3493 # _chunkraw was renamed to _getsegmentforrevs.
3520 # _chunkraw was renamed to _getsegmentforrevs.
3494 try:
3521 try:
3495 segmentforrevs = r._getsegmentforrevs
3522 segmentforrevs = r._getsegmentforrevs
3496 except AttributeError:
3523 except AttributeError:
3497 segmentforrevs = r._chunkraw
3524 segmentforrevs = r._chunkraw
3498
3525
3499 node = r.lookup(rev)
3526 node = r.lookup(rev)
3500 rev = r.rev(node)
3527 rev = r.rev(node)
3501
3528
3502 def getrawchunks(data, chain):
3529 def getrawchunks(data, chain):
3503 start = r.start
3530 start = r.start
3504 length = r.length
3531 length = r.length
3505 inline = r._inline
3532 inline = r._inline
3506 try:
3533 try:
3507 iosize = r.index.entry_size
3534 iosize = r.index.entry_size
3508 except AttributeError:
3535 except AttributeError:
3509 iosize = r._io.size
3536 iosize = r._io.size
3510 buffer = util.buffer
3537 buffer = util.buffer
3511
3538
3512 chunks = []
3539 chunks = []
3513 ladd = chunks.append
3540 ladd = chunks.append
3514 for idx, item in enumerate(chain):
3541 for idx, item in enumerate(chain):
3515 offset = start(item[0])
3542 offset = start(item[0])
3516 bits = data[idx]
3543 bits = data[idx]
3517 for rev in item:
3544 for rev in item:
3518 chunkstart = start(rev)
3545 chunkstart = start(rev)
3519 if inline:
3546 if inline:
3520 chunkstart += (rev + 1) * iosize
3547 chunkstart += (rev + 1) * iosize
3521 chunklength = length(rev)
3548 chunklength = length(rev)
3522 ladd(buffer(bits, chunkstart - offset, chunklength))
3549 ladd(buffer(bits, chunkstart - offset, chunklength))
3523
3550
3524 return chunks
3551 return chunks
3525
3552
3526 def dodeltachain(rev):
3553 def dodeltachain(rev):
3527 if not cache:
3554 if not cache:
3528 r.clearcaches()
3555 r.clearcaches()
3529 r._deltachain(rev)
3556 r._deltachain(rev)
3530
3557
3531 def doread(chain):
3558 def doread(chain):
3532 if not cache:
3559 if not cache:
3533 r.clearcaches()
3560 r.clearcaches()
3534 for item in slicedchain:
3561 for item in slicedchain:
3535 segmentforrevs(item[0], item[-1])
3562 segmentforrevs(item[0], item[-1])
3536
3563
3537 def doslice(r, chain, size):
3564 def doslice(r, chain, size):
3538 for s in slicechunk(r, chain, targetsize=size):
3565 for s in slicechunk(r, chain, targetsize=size):
3539 pass
3566 pass
3540
3567
3541 def dorawchunks(data, chain):
3568 def dorawchunks(data, chain):
3542 if not cache:
3569 if not cache:
3543 r.clearcaches()
3570 r.clearcaches()
3544 getrawchunks(data, chain)
3571 getrawchunks(data, chain)
3545
3572
3546 def dodecompress(chunks):
3573 def dodecompress(chunks):
3547 decomp = r.decompress
3574 decomp = r.decompress
3548 for chunk in chunks:
3575 for chunk in chunks:
3549 decomp(chunk)
3576 decomp(chunk)
3550
3577
3551 def dopatch(text, bins):
3578 def dopatch(text, bins):
3552 if not cache:
3579 if not cache:
3553 r.clearcaches()
3580 r.clearcaches()
3554 mdiff.patches(text, bins)
3581 mdiff.patches(text, bins)
3555
3582
3556 def dohash(text):
3583 def dohash(text):
3557 if not cache:
3584 if not cache:
3558 r.clearcaches()
3585 r.clearcaches()
3559 r.checkhash(text, node, rev=rev)
3586 r.checkhash(text, node, rev=rev)
3560
3587
3561 def dorevision():
3588 def dorevision():
3562 if not cache:
3589 if not cache:
3563 r.clearcaches()
3590 r.clearcaches()
3564 r.revision(node)
3591 r.revision(node)
3565
3592
3566 try:
3593 try:
3567 from mercurial.revlogutils.deltas import slicechunk
3594 from mercurial.revlogutils.deltas import slicechunk
3568 except ImportError:
3595 except ImportError:
3569 slicechunk = getattr(revlog, '_slicechunk', None)
3596 slicechunk = getattr(revlog, '_slicechunk', None)
3570
3597
3571 size = r.length(rev)
3598 size = r.length(rev)
3572 chain = r._deltachain(rev)[0]
3599 chain = r._deltachain(rev)[0]
3573 if not getattr(r, '_withsparseread', False):
3600 if not getattr(r, '_withsparseread', False):
3574 slicedchain = (chain,)
3601 slicedchain = (chain,)
3575 else:
3602 else:
3576 slicedchain = tuple(slicechunk(r, chain, targetsize=size))
3603 slicedchain = tuple(slicechunk(r, chain, targetsize=size))
3577 data = [segmentforrevs(seg[0], seg[-1])[1] for seg in slicedchain]
3604 data = [segmentforrevs(seg[0], seg[-1])[1] for seg in slicedchain]
3578 rawchunks = getrawchunks(data, slicedchain)
3605 rawchunks = getrawchunks(data, slicedchain)
3579 bins = r._chunks(chain)
3606 bins = r._chunks(chain)
3580 text = bytes(bins[0])
3607 text = bytes(bins[0])
3581 bins = bins[1:]
3608 bins = bins[1:]
3582 text = mdiff.patches(text, bins)
3609 text = mdiff.patches(text, bins)
3583
3610
3584 benches = [
3611 benches = [
3585 (lambda: dorevision(), b'full'),
3612 (lambda: dorevision(), b'full'),
3586 (lambda: dodeltachain(rev), b'deltachain'),
3613 (lambda: dodeltachain(rev), b'deltachain'),
3587 (lambda: doread(chain), b'read'),
3614 (lambda: doread(chain), b'read'),
3588 ]
3615 ]
3589
3616
3590 if getattr(r, '_withsparseread', False):
3617 if getattr(r, '_withsparseread', False):
3591 slicing = (lambda: doslice(r, chain, size), b'slice-sparse-chain')
3618 slicing = (lambda: doslice(r, chain, size), b'slice-sparse-chain')
3592 benches.append(slicing)
3619 benches.append(slicing)
3593
3620
3594 benches.extend(
3621 benches.extend(
3595 [
3622 [
3596 (lambda: dorawchunks(data, slicedchain), b'rawchunks'),
3623 (lambda: dorawchunks(data, slicedchain), b'rawchunks'),
3597 (lambda: dodecompress(rawchunks), b'decompress'),
3624 (lambda: dodecompress(rawchunks), b'decompress'),
3598 (lambda: dopatch(text, bins), b'patch'),
3625 (lambda: dopatch(text, bins), b'patch'),
3599 (lambda: dohash(text), b'hash'),
3626 (lambda: dohash(text), b'hash'),
3600 ]
3627 ]
3601 )
3628 )
3602
3629
3603 timer, fm = gettimer(ui, opts)
3630 timer, fm = gettimer(ui, opts)
3604 for fn, title in benches:
3631 for fn, title in benches:
3605 timer(fn, title=title)
3632 timer(fn, title=title)
3606 fm.end()
3633 fm.end()
3607
3634
3608
3635
3609 @command(
3636 @command(
3610 b'perf::revset|perfrevset',
3637 b'perf::revset|perfrevset',
3611 [
3638 [
3612 (b'C', b'clear', False, b'clear volatile cache between each call.'),
3639 (b'C', b'clear', False, b'clear volatile cache between each call.'),
3613 (b'', b'contexts', False, b'obtain changectx for each revision'),
3640 (b'', b'contexts', False, b'obtain changectx for each revision'),
3614 ]
3641 ]
3615 + formatteropts,
3642 + formatteropts,
3616 b"REVSET",
3643 b"REVSET",
3617 )
3644 )
3618 def perfrevset(ui, repo, expr, clear=False, contexts=False, **opts):
3645 def perfrevset(ui, repo, expr, clear=False, contexts=False, **opts):
3619 """benchmark the execution time of a revset
3646 """benchmark the execution time of a revset
3620
3647
3621 Use the --clean option if need to evaluate the impact of build volatile
3648 Use the --clean option if need to evaluate the impact of build volatile
3622 revisions set cache on the revset execution. Volatile cache hold filtered
3649 revisions set cache on the revset execution. Volatile cache hold filtered
3623 and obsolete related cache."""
3650 and obsolete related cache."""
3624 opts = _byteskwargs(opts)
3651 opts = _byteskwargs(opts)
3625
3652
3626 timer, fm = gettimer(ui, opts)
3653 timer, fm = gettimer(ui, opts)
3627
3654
3628 def d():
3655 def d():
3629 if clear:
3656 if clear:
3630 repo.invalidatevolatilesets()
3657 repo.invalidatevolatilesets()
3631 if contexts:
3658 if contexts:
3632 for ctx in repo.set(expr):
3659 for ctx in repo.set(expr):
3633 pass
3660 pass
3634 else:
3661 else:
3635 for r in repo.revs(expr):
3662 for r in repo.revs(expr):
3636 pass
3663 pass
3637
3664
3638 timer(d)
3665 timer(d)
3639 fm.end()
3666 fm.end()
3640
3667
3641
3668
3642 @command(
3669 @command(
3643 b'perf::volatilesets|perfvolatilesets',
3670 b'perf::volatilesets|perfvolatilesets',
3644 [
3671 [
3645 (b'', b'clear-obsstore', False, b'drop obsstore between each call.'),
3672 (b'', b'clear-obsstore', False, b'drop obsstore between each call.'),
3646 ]
3673 ]
3647 + formatteropts,
3674 + formatteropts,
3648 )
3675 )
3649 def perfvolatilesets(ui, repo, *names, **opts):
3676 def perfvolatilesets(ui, repo, *names, **opts):
3650 """benchmark the computation of various volatile set
3677 """benchmark the computation of various volatile set
3651
3678
3652 Volatile set computes element related to filtering and obsolescence."""
3679 Volatile set computes element related to filtering and obsolescence."""
3653 opts = _byteskwargs(opts)
3680 opts = _byteskwargs(opts)
3654 timer, fm = gettimer(ui, opts)
3681 timer, fm = gettimer(ui, opts)
3655 repo = repo.unfiltered()
3682 repo = repo.unfiltered()
3656
3683
3657 def getobs(name):
3684 def getobs(name):
3658 def d():
3685 def d():
3659 repo.invalidatevolatilesets()
3686 repo.invalidatevolatilesets()
3660 if opts[b'clear_obsstore']:
3687 if opts[b'clear_obsstore']:
3661 clearfilecache(repo, b'obsstore')
3688 clearfilecache(repo, b'obsstore')
3662 obsolete.getrevs(repo, name)
3689 obsolete.getrevs(repo, name)
3663
3690
3664 return d
3691 return d
3665
3692
3666 allobs = sorted(obsolete.cachefuncs)
3693 allobs = sorted(obsolete.cachefuncs)
3667 if names:
3694 if names:
3668 allobs = [n for n in allobs if n in names]
3695 allobs = [n for n in allobs if n in names]
3669
3696
3670 for name in allobs:
3697 for name in allobs:
3671 timer(getobs(name), title=name)
3698 timer(getobs(name), title=name)
3672
3699
3673 def getfiltered(name):
3700 def getfiltered(name):
3674 def d():
3701 def d():
3675 repo.invalidatevolatilesets()
3702 repo.invalidatevolatilesets()
3676 if opts[b'clear_obsstore']:
3703 if opts[b'clear_obsstore']:
3677 clearfilecache(repo, b'obsstore')
3704 clearfilecache(repo, b'obsstore')
3678 repoview.filterrevs(repo, name)
3705 repoview.filterrevs(repo, name)
3679
3706
3680 return d
3707 return d
3681
3708
3682 allfilter = sorted(repoview.filtertable)
3709 allfilter = sorted(repoview.filtertable)
3683 if names:
3710 if names:
3684 allfilter = [n for n in allfilter if n in names]
3711 allfilter = [n for n in allfilter if n in names]
3685
3712
3686 for name in allfilter:
3713 for name in allfilter:
3687 timer(getfiltered(name), title=name)
3714 timer(getfiltered(name), title=name)
3688 fm.end()
3715 fm.end()
3689
3716
3690
3717
3691 @command(
3718 @command(
3692 b'perf::branchmap|perfbranchmap',
3719 b'perf::branchmap|perfbranchmap',
3693 [
3720 [
3694 (b'f', b'full', False, b'Includes build time of subset'),
3721 (b'f', b'full', False, b'Includes build time of subset'),
3695 (
3722 (
3696 b'',
3723 b'',
3697 b'clear-revbranch',
3724 b'clear-revbranch',
3698 False,
3725 False,
3699 b'purge the revbranch cache between computation',
3726 b'purge the revbranch cache between computation',
3700 ),
3727 ),
3701 ]
3728 ]
3702 + formatteropts,
3729 + formatteropts,
3703 )
3730 )
3704 def perfbranchmap(ui, repo, *filternames, **opts):
3731 def perfbranchmap(ui, repo, *filternames, **opts):
3705 """benchmark the update of a branchmap
3732 """benchmark the update of a branchmap
3706
3733
3707 This benchmarks the full repo.branchmap() call with read and write disabled
3734 This benchmarks the full repo.branchmap() call with read and write disabled
3708 """
3735 """
3709 opts = _byteskwargs(opts)
3736 opts = _byteskwargs(opts)
3710 full = opts.get(b"full", False)
3737 full = opts.get(b"full", False)
3711 clear_revbranch = opts.get(b"clear_revbranch", False)
3738 clear_revbranch = opts.get(b"clear_revbranch", False)
3712 timer, fm = gettimer(ui, opts)
3739 timer, fm = gettimer(ui, opts)
3713
3740
3714 def getbranchmap(filtername):
3741 def getbranchmap(filtername):
3715 """generate a benchmark function for the filtername"""
3742 """generate a benchmark function for the filtername"""
3716 if filtername is None:
3743 if filtername is None:
3717 view = repo
3744 view = repo
3718 else:
3745 else:
3719 view = repo.filtered(filtername)
3746 view = repo.filtered(filtername)
3720 if util.safehasattr(view._branchcaches, '_per_filter'):
3747 if util.safehasattr(view._branchcaches, '_per_filter'):
3721 filtered = view._branchcaches._per_filter
3748 filtered = view._branchcaches._per_filter
3722 else:
3749 else:
3723 # older versions
3750 # older versions
3724 filtered = view._branchcaches
3751 filtered = view._branchcaches
3725
3752
3726 def d():
3753 def d():
3727 if clear_revbranch:
3754 if clear_revbranch:
3728 repo.revbranchcache()._clear()
3755 repo.revbranchcache()._clear()
3729 if full:
3756 if full:
3730 view._branchcaches.clear()
3757 view._branchcaches.clear()
3731 else:
3758 else:
3732 filtered.pop(filtername, None)
3759 filtered.pop(filtername, None)
3733 view.branchmap()
3760 view.branchmap()
3734
3761
3735 return d
3762 return d
3736
3763
3737 # add filter in smaller subset to bigger subset
3764 # add filter in smaller subset to bigger subset
3738 possiblefilters = set(repoview.filtertable)
3765 possiblefilters = set(repoview.filtertable)
3739 if filternames:
3766 if filternames:
3740 possiblefilters &= set(filternames)
3767 possiblefilters &= set(filternames)
3741 subsettable = getbranchmapsubsettable()
3768 subsettable = getbranchmapsubsettable()
3742 allfilters = []
3769 allfilters = []
3743 while possiblefilters:
3770 while possiblefilters:
3744 for name in possiblefilters:
3771 for name in possiblefilters:
3745 subset = subsettable.get(name)
3772 subset = subsettable.get(name)
3746 if subset not in possiblefilters:
3773 if subset not in possiblefilters:
3747 break
3774 break
3748 else:
3775 else:
3749 assert False, b'subset cycle %s!' % possiblefilters
3776 assert False, b'subset cycle %s!' % possiblefilters
3750 allfilters.append(name)
3777 allfilters.append(name)
3751 possiblefilters.remove(name)
3778 possiblefilters.remove(name)
3752
3779
3753 # warm the cache
3780 # warm the cache
3754 if not full:
3781 if not full:
3755 for name in allfilters:
3782 for name in allfilters:
3756 repo.filtered(name).branchmap()
3783 repo.filtered(name).branchmap()
3757 if not filternames or b'unfiltered' in filternames:
3784 if not filternames or b'unfiltered' in filternames:
3758 # add unfiltered
3785 # add unfiltered
3759 allfilters.append(None)
3786 allfilters.append(None)
3760
3787
3761 if util.safehasattr(branchmap.branchcache, 'fromfile'):
3788 if util.safehasattr(branchmap.branchcache, 'fromfile'):
3762 branchcacheread = safeattrsetter(branchmap.branchcache, b'fromfile')
3789 branchcacheread = safeattrsetter(branchmap.branchcache, b'fromfile')
3763 branchcacheread.set(classmethod(lambda *args: None))
3790 branchcacheread.set(classmethod(lambda *args: None))
3764 else:
3791 else:
3765 # older versions
3792 # older versions
3766 branchcacheread = safeattrsetter(branchmap, b'read')
3793 branchcacheread = safeattrsetter(branchmap, b'read')
3767 branchcacheread.set(lambda *args: None)
3794 branchcacheread.set(lambda *args: None)
3768 branchcachewrite = safeattrsetter(branchmap.branchcache, b'write')
3795 branchcachewrite = safeattrsetter(branchmap.branchcache, b'write')
3769 branchcachewrite.set(lambda *args: None)
3796 branchcachewrite.set(lambda *args: None)
3770 try:
3797 try:
3771 for name in allfilters:
3798 for name in allfilters:
3772 printname = name
3799 printname = name
3773 if name is None:
3800 if name is None:
3774 printname = b'unfiltered'
3801 printname = b'unfiltered'
3775 timer(getbranchmap(name), title=printname)
3802 timer(getbranchmap(name), title=printname)
3776 finally:
3803 finally:
3777 branchcacheread.restore()
3804 branchcacheread.restore()
3778 branchcachewrite.restore()
3805 branchcachewrite.restore()
3779 fm.end()
3806 fm.end()
3780
3807
3781
3808
3782 @command(
3809 @command(
3783 b'perf::branchmapupdate|perfbranchmapupdate',
3810 b'perf::branchmapupdate|perfbranchmapupdate',
3784 [
3811 [
3785 (b'', b'base', [], b'subset of revision to start from'),
3812 (b'', b'base', [], b'subset of revision to start from'),
3786 (b'', b'target', [], b'subset of revision to end with'),
3813 (b'', b'target', [], b'subset of revision to end with'),
3787 (b'', b'clear-caches', False, b'clear cache between each runs'),
3814 (b'', b'clear-caches', False, b'clear cache between each runs'),
3788 ]
3815 ]
3789 + formatteropts,
3816 + formatteropts,
3790 )
3817 )
3791 def perfbranchmapupdate(ui, repo, base=(), target=(), **opts):
3818 def perfbranchmapupdate(ui, repo, base=(), target=(), **opts):
3792 """benchmark branchmap update from for <base> revs to <target> revs
3819 """benchmark branchmap update from for <base> revs to <target> revs
3793
3820
3794 If `--clear-caches` is passed, the following items will be reset before
3821 If `--clear-caches` is passed, the following items will be reset before
3795 each update:
3822 each update:
3796 * the changelog instance and associated indexes
3823 * the changelog instance and associated indexes
3797 * the rev-branch-cache instance
3824 * the rev-branch-cache instance
3798
3825
3799 Examples:
3826 Examples:
3800
3827
3801 # update for the one last revision
3828 # update for the one last revision
3802 $ hg perfbranchmapupdate --base 'not tip' --target 'tip'
3829 $ hg perfbranchmapupdate --base 'not tip' --target 'tip'
3803
3830
3804 $ update for change coming with a new branch
3831 $ update for change coming with a new branch
3805 $ hg perfbranchmapupdate --base 'stable' --target 'default'
3832 $ hg perfbranchmapupdate --base 'stable' --target 'default'
3806 """
3833 """
3807 from mercurial import branchmap
3834 from mercurial import branchmap
3808 from mercurial import repoview
3835 from mercurial import repoview
3809
3836
3810 opts = _byteskwargs(opts)
3837 opts = _byteskwargs(opts)
3811 timer, fm = gettimer(ui, opts)
3838 timer, fm = gettimer(ui, opts)
3812 clearcaches = opts[b'clear_caches']
3839 clearcaches = opts[b'clear_caches']
3813 unfi = repo.unfiltered()
3840 unfi = repo.unfiltered()
3814 x = [None] # used to pass data between closure
3841 x = [None] # used to pass data between closure
3815
3842
3816 # we use a `list` here to avoid possible side effect from smartset
3843 # we use a `list` here to avoid possible side effect from smartset
3817 baserevs = list(scmutil.revrange(repo, base))
3844 baserevs = list(scmutil.revrange(repo, base))
3818 targetrevs = list(scmutil.revrange(repo, target))
3845 targetrevs = list(scmutil.revrange(repo, target))
3819 if not baserevs:
3846 if not baserevs:
3820 raise error.Abort(b'no revisions selected for --base')
3847 raise error.Abort(b'no revisions selected for --base')
3821 if not targetrevs:
3848 if not targetrevs:
3822 raise error.Abort(b'no revisions selected for --target')
3849 raise error.Abort(b'no revisions selected for --target')
3823
3850
3824 # make sure the target branchmap also contains the one in the base
3851 # make sure the target branchmap also contains the one in the base
3825 targetrevs = list(set(baserevs) | set(targetrevs))
3852 targetrevs = list(set(baserevs) | set(targetrevs))
3826 targetrevs.sort()
3853 targetrevs.sort()
3827
3854
3828 cl = repo.changelog
3855 cl = repo.changelog
3829 allbaserevs = list(cl.ancestors(baserevs, inclusive=True))
3856 allbaserevs = list(cl.ancestors(baserevs, inclusive=True))
3830 allbaserevs.sort()
3857 allbaserevs.sort()
3831 alltargetrevs = frozenset(cl.ancestors(targetrevs, inclusive=True))
3858 alltargetrevs = frozenset(cl.ancestors(targetrevs, inclusive=True))
3832
3859
3833 newrevs = list(alltargetrevs.difference(allbaserevs))
3860 newrevs = list(alltargetrevs.difference(allbaserevs))
3834 newrevs.sort()
3861 newrevs.sort()
3835
3862
3836 allrevs = frozenset(unfi.changelog.revs())
3863 allrevs = frozenset(unfi.changelog.revs())
3837 basefilterrevs = frozenset(allrevs.difference(allbaserevs))
3864 basefilterrevs = frozenset(allrevs.difference(allbaserevs))
3838 targetfilterrevs = frozenset(allrevs.difference(alltargetrevs))
3865 targetfilterrevs = frozenset(allrevs.difference(alltargetrevs))
3839
3866
3840 def basefilter(repo, visibilityexceptions=None):
3867 def basefilter(repo, visibilityexceptions=None):
3841 return basefilterrevs
3868 return basefilterrevs
3842
3869
3843 def targetfilter(repo, visibilityexceptions=None):
3870 def targetfilter(repo, visibilityexceptions=None):
3844 return targetfilterrevs
3871 return targetfilterrevs
3845
3872
3846 msg = b'benchmark of branchmap with %d revisions with %d new ones\n'
3873 msg = b'benchmark of branchmap with %d revisions with %d new ones\n'
3847 ui.status(msg % (len(allbaserevs), len(newrevs)))
3874 ui.status(msg % (len(allbaserevs), len(newrevs)))
3848 if targetfilterrevs:
3875 if targetfilterrevs:
3849 msg = b'(%d revisions still filtered)\n'
3876 msg = b'(%d revisions still filtered)\n'
3850 ui.status(msg % len(targetfilterrevs))
3877 ui.status(msg % len(targetfilterrevs))
3851
3878
3852 try:
3879 try:
3853 repoview.filtertable[b'__perf_branchmap_update_base'] = basefilter
3880 repoview.filtertable[b'__perf_branchmap_update_base'] = basefilter
3854 repoview.filtertable[b'__perf_branchmap_update_target'] = targetfilter
3881 repoview.filtertable[b'__perf_branchmap_update_target'] = targetfilter
3855
3882
3856 baserepo = repo.filtered(b'__perf_branchmap_update_base')
3883 baserepo = repo.filtered(b'__perf_branchmap_update_base')
3857 targetrepo = repo.filtered(b'__perf_branchmap_update_target')
3884 targetrepo = repo.filtered(b'__perf_branchmap_update_target')
3858
3885
3859 # try to find an existing branchmap to reuse
3886 # try to find an existing branchmap to reuse
3860 subsettable = getbranchmapsubsettable()
3887 subsettable = getbranchmapsubsettable()
3861 candidatefilter = subsettable.get(None)
3888 candidatefilter = subsettable.get(None)
3862 while candidatefilter is not None:
3889 while candidatefilter is not None:
3863 candidatebm = repo.filtered(candidatefilter).branchmap()
3890 candidatebm = repo.filtered(candidatefilter).branchmap()
3864 if candidatebm.validfor(baserepo):
3891 if candidatebm.validfor(baserepo):
3865 filtered = repoview.filterrevs(repo, candidatefilter)
3892 filtered = repoview.filterrevs(repo, candidatefilter)
3866 missing = [r for r in allbaserevs if r in filtered]
3893 missing = [r for r in allbaserevs if r in filtered]
3867 base = candidatebm.copy()
3894 base = candidatebm.copy()
3868 base.update(baserepo, missing)
3895 base.update(baserepo, missing)
3869 break
3896 break
3870 candidatefilter = subsettable.get(candidatefilter)
3897 candidatefilter = subsettable.get(candidatefilter)
3871 else:
3898 else:
3872 # no suitable subset where found
3899 # no suitable subset where found
3873 base = branchmap.branchcache()
3900 base = branchmap.branchcache()
3874 base.update(baserepo, allbaserevs)
3901 base.update(baserepo, allbaserevs)
3875
3902
3876 def setup():
3903 def setup():
3877 x[0] = base.copy()
3904 x[0] = base.copy()
3878 if clearcaches:
3905 if clearcaches:
3879 unfi._revbranchcache = None
3906 unfi._revbranchcache = None
3880 clearchangelog(repo)
3907 clearchangelog(repo)
3881
3908
3882 def bench():
3909 def bench():
3883 x[0].update(targetrepo, newrevs)
3910 x[0].update(targetrepo, newrevs)
3884
3911
3885 timer(bench, setup=setup)
3912 timer(bench, setup=setup)
3886 fm.end()
3913 fm.end()
3887 finally:
3914 finally:
3888 repoview.filtertable.pop(b'__perf_branchmap_update_base', None)
3915 repoview.filtertable.pop(b'__perf_branchmap_update_base', None)
3889 repoview.filtertable.pop(b'__perf_branchmap_update_target', None)
3916 repoview.filtertable.pop(b'__perf_branchmap_update_target', None)
3890
3917
3891
3918
3892 @command(
3919 @command(
3893 b'perf::branchmapload|perfbranchmapload',
3920 b'perf::branchmapload|perfbranchmapload',
3894 [
3921 [
3895 (b'f', b'filter', b'', b'Specify repoview filter'),
3922 (b'f', b'filter', b'', b'Specify repoview filter'),
3896 (b'', b'list', False, b'List brachmap filter caches'),
3923 (b'', b'list', False, b'List brachmap filter caches'),
3897 (b'', b'clear-revlogs', False, b'refresh changelog and manifest'),
3924 (b'', b'clear-revlogs', False, b'refresh changelog and manifest'),
3898 ]
3925 ]
3899 + formatteropts,
3926 + formatteropts,
3900 )
3927 )
3901 def perfbranchmapload(ui, repo, filter=b'', list=False, **opts):
3928 def perfbranchmapload(ui, repo, filter=b'', list=False, **opts):
3902 """benchmark reading the branchmap"""
3929 """benchmark reading the branchmap"""
3903 opts = _byteskwargs(opts)
3930 opts = _byteskwargs(opts)
3904 clearrevlogs = opts[b'clear_revlogs']
3931 clearrevlogs = opts[b'clear_revlogs']
3905
3932
3906 if list:
3933 if list:
3907 for name, kind, st in repo.cachevfs.readdir(stat=True):
3934 for name, kind, st in repo.cachevfs.readdir(stat=True):
3908 if name.startswith(b'branch2'):
3935 if name.startswith(b'branch2'):
3909 filtername = name.partition(b'-')[2] or b'unfiltered'
3936 filtername = name.partition(b'-')[2] or b'unfiltered'
3910 ui.status(
3937 ui.status(
3911 b'%s - %s\n' % (filtername, util.bytecount(st.st_size))
3938 b'%s - %s\n' % (filtername, util.bytecount(st.st_size))
3912 )
3939 )
3913 return
3940 return
3914 if not filter:
3941 if not filter:
3915 filter = None
3942 filter = None
3916 subsettable = getbranchmapsubsettable()
3943 subsettable = getbranchmapsubsettable()
3917 if filter is None:
3944 if filter is None:
3918 repo = repo.unfiltered()
3945 repo = repo.unfiltered()
3919 else:
3946 else:
3920 repo = repoview.repoview(repo, filter)
3947 repo = repoview.repoview(repo, filter)
3921
3948
3922 repo.branchmap() # make sure we have a relevant, up to date branchmap
3949 repo.branchmap() # make sure we have a relevant, up to date branchmap
3923
3950
3924 try:
3951 try:
3925 fromfile = branchmap.branchcache.fromfile
3952 fromfile = branchmap.branchcache.fromfile
3926 except AttributeError:
3953 except AttributeError:
3927 # older versions
3954 # older versions
3928 fromfile = branchmap.read
3955 fromfile = branchmap.read
3929
3956
3930 currentfilter = filter
3957 currentfilter = filter
3931 # try once without timer, the filter may not be cached
3958 # try once without timer, the filter may not be cached
3932 while fromfile(repo) is None:
3959 while fromfile(repo) is None:
3933 currentfilter = subsettable.get(currentfilter)
3960 currentfilter = subsettable.get(currentfilter)
3934 if currentfilter is None:
3961 if currentfilter is None:
3935 raise error.Abort(
3962 raise error.Abort(
3936 b'No branchmap cached for %s repo' % (filter or b'unfiltered')
3963 b'No branchmap cached for %s repo' % (filter or b'unfiltered')
3937 )
3964 )
3938 repo = repo.filtered(currentfilter)
3965 repo = repo.filtered(currentfilter)
3939 timer, fm = gettimer(ui, opts)
3966 timer, fm = gettimer(ui, opts)
3940
3967
3941 def setup():
3968 def setup():
3942 if clearrevlogs:
3969 if clearrevlogs:
3943 clearchangelog(repo)
3970 clearchangelog(repo)
3944
3971
3945 def bench():
3972 def bench():
3946 fromfile(repo)
3973 fromfile(repo)
3947
3974
3948 timer(bench, setup=setup)
3975 timer(bench, setup=setup)
3949 fm.end()
3976 fm.end()
3950
3977
3951
3978
3952 @command(b'perf::loadmarkers|perfloadmarkers')
3979 @command(b'perf::loadmarkers|perfloadmarkers')
3953 def perfloadmarkers(ui, repo):
3980 def perfloadmarkers(ui, repo):
3954 """benchmark the time to parse the on-disk markers for a repo
3981 """benchmark the time to parse the on-disk markers for a repo
3955
3982
3956 Result is the number of markers in the repo."""
3983 Result is the number of markers in the repo."""
3957 timer, fm = gettimer(ui)
3984 timer, fm = gettimer(ui)
3958 svfs = getsvfs(repo)
3985 svfs = getsvfs(repo)
3959 timer(lambda: len(obsolete.obsstore(repo, svfs)))
3986 timer(lambda: len(obsolete.obsstore(repo, svfs)))
3960 fm.end()
3987 fm.end()
3961
3988
3962
3989
3963 @command(
3990 @command(
3964 b'perf::lrucachedict|perflrucachedict',
3991 b'perf::lrucachedict|perflrucachedict',
3965 formatteropts
3992 formatteropts
3966 + [
3993 + [
3967 (b'', b'costlimit', 0, b'maximum total cost of items in cache'),
3994 (b'', b'costlimit', 0, b'maximum total cost of items in cache'),
3968 (b'', b'mincost', 0, b'smallest cost of items in cache'),
3995 (b'', b'mincost', 0, b'smallest cost of items in cache'),
3969 (b'', b'maxcost', 100, b'maximum cost of items in cache'),
3996 (b'', b'maxcost', 100, b'maximum cost of items in cache'),
3970 (b'', b'size', 4, b'size of cache'),
3997 (b'', b'size', 4, b'size of cache'),
3971 (b'', b'gets', 10000, b'number of key lookups'),
3998 (b'', b'gets', 10000, b'number of key lookups'),
3972 (b'', b'sets', 10000, b'number of key sets'),
3999 (b'', b'sets', 10000, b'number of key sets'),
3973 (b'', b'mixed', 10000, b'number of mixed mode operations'),
4000 (b'', b'mixed', 10000, b'number of mixed mode operations'),
3974 (
4001 (
3975 b'',
4002 b'',
3976 b'mixedgetfreq',
4003 b'mixedgetfreq',
3977 50,
4004 50,
3978 b'frequency of get vs set ops in mixed mode',
4005 b'frequency of get vs set ops in mixed mode',
3979 ),
4006 ),
3980 ],
4007 ],
3981 norepo=True,
4008 norepo=True,
3982 )
4009 )
3983 def perflrucache(
4010 def perflrucache(
3984 ui,
4011 ui,
3985 mincost=0,
4012 mincost=0,
3986 maxcost=100,
4013 maxcost=100,
3987 costlimit=0,
4014 costlimit=0,
3988 size=4,
4015 size=4,
3989 gets=10000,
4016 gets=10000,
3990 sets=10000,
4017 sets=10000,
3991 mixed=10000,
4018 mixed=10000,
3992 mixedgetfreq=50,
4019 mixedgetfreq=50,
3993 **opts
4020 **opts
3994 ):
4021 ):
3995 opts = _byteskwargs(opts)
4022 opts = _byteskwargs(opts)
3996
4023
3997 def doinit():
4024 def doinit():
3998 for i in _xrange(10000):
4025 for i in _xrange(10000):
3999 util.lrucachedict(size)
4026 util.lrucachedict(size)
4000
4027
4001 costrange = list(range(mincost, maxcost + 1))
4028 costrange = list(range(mincost, maxcost + 1))
4002
4029
4003 values = []
4030 values = []
4004 for i in _xrange(size):
4031 for i in _xrange(size):
4005 values.append(random.randint(0, _maxint))
4032 values.append(random.randint(0, _maxint))
4006
4033
4007 # Get mode fills the cache and tests raw lookup performance with no
4034 # Get mode fills the cache and tests raw lookup performance with no
4008 # eviction.
4035 # eviction.
4009 getseq = []
4036 getseq = []
4010 for i in _xrange(gets):
4037 for i in _xrange(gets):
4011 getseq.append(random.choice(values))
4038 getseq.append(random.choice(values))
4012
4039
4013 def dogets():
4040 def dogets():
4014 d = util.lrucachedict(size)
4041 d = util.lrucachedict(size)
4015 for v in values:
4042 for v in values:
4016 d[v] = v
4043 d[v] = v
4017 for key in getseq:
4044 for key in getseq:
4018 value = d[key]
4045 value = d[key]
4019 value # silence pyflakes warning
4046 value # silence pyflakes warning
4020
4047
4021 def dogetscost():
4048 def dogetscost():
4022 d = util.lrucachedict(size, maxcost=costlimit)
4049 d = util.lrucachedict(size, maxcost=costlimit)
4023 for i, v in enumerate(values):
4050 for i, v in enumerate(values):
4024 d.insert(v, v, cost=costs[i])
4051 d.insert(v, v, cost=costs[i])
4025 for key in getseq:
4052 for key in getseq:
4026 try:
4053 try:
4027 value = d[key]
4054 value = d[key]
4028 value # silence pyflakes warning
4055 value # silence pyflakes warning
4029 except KeyError:
4056 except KeyError:
4030 pass
4057 pass
4031
4058
4032 # Set mode tests insertion speed with cache eviction.
4059 # Set mode tests insertion speed with cache eviction.
4033 setseq = []
4060 setseq = []
4034 costs = []
4061 costs = []
4035 for i in _xrange(sets):
4062 for i in _xrange(sets):
4036 setseq.append(random.randint(0, _maxint))
4063 setseq.append(random.randint(0, _maxint))
4037 costs.append(random.choice(costrange))
4064 costs.append(random.choice(costrange))
4038
4065
4039 def doinserts():
4066 def doinserts():
4040 d = util.lrucachedict(size)
4067 d = util.lrucachedict(size)
4041 for v in setseq:
4068 for v in setseq:
4042 d.insert(v, v)
4069 d.insert(v, v)
4043
4070
4044 def doinsertscost():
4071 def doinsertscost():
4045 d = util.lrucachedict(size, maxcost=costlimit)
4072 d = util.lrucachedict(size, maxcost=costlimit)
4046 for i, v in enumerate(setseq):
4073 for i, v in enumerate(setseq):
4047 d.insert(v, v, cost=costs[i])
4074 d.insert(v, v, cost=costs[i])
4048
4075
4049 def dosets():
4076 def dosets():
4050 d = util.lrucachedict(size)
4077 d = util.lrucachedict(size)
4051 for v in setseq:
4078 for v in setseq:
4052 d[v] = v
4079 d[v] = v
4053
4080
4054 # Mixed mode randomly performs gets and sets with eviction.
4081 # Mixed mode randomly performs gets and sets with eviction.
4055 mixedops = []
4082 mixedops = []
4056 for i in _xrange(mixed):
4083 for i in _xrange(mixed):
4057 r = random.randint(0, 100)
4084 r = random.randint(0, 100)
4058 if r < mixedgetfreq:
4085 if r < mixedgetfreq:
4059 op = 0
4086 op = 0
4060 else:
4087 else:
4061 op = 1
4088 op = 1
4062
4089
4063 mixedops.append(
4090 mixedops.append(
4064 (op, random.randint(0, size * 2), random.choice(costrange))
4091 (op, random.randint(0, size * 2), random.choice(costrange))
4065 )
4092 )
4066
4093
4067 def domixed():
4094 def domixed():
4068 d = util.lrucachedict(size)
4095 d = util.lrucachedict(size)
4069
4096
4070 for op, v, cost in mixedops:
4097 for op, v, cost in mixedops:
4071 if op == 0:
4098 if op == 0:
4072 try:
4099 try:
4073 d[v]
4100 d[v]
4074 except KeyError:
4101 except KeyError:
4075 pass
4102 pass
4076 else:
4103 else:
4077 d[v] = v
4104 d[v] = v
4078
4105
4079 def domixedcost():
4106 def domixedcost():
4080 d = util.lrucachedict(size, maxcost=costlimit)
4107 d = util.lrucachedict(size, maxcost=costlimit)
4081
4108
4082 for op, v, cost in mixedops:
4109 for op, v, cost in mixedops:
4083 if op == 0:
4110 if op == 0:
4084 try:
4111 try:
4085 d[v]
4112 d[v]
4086 except KeyError:
4113 except KeyError:
4087 pass
4114 pass
4088 else:
4115 else:
4089 d.insert(v, v, cost=cost)
4116 d.insert(v, v, cost=cost)
4090
4117
4091 benches = [
4118 benches = [
4092 (doinit, b'init'),
4119 (doinit, b'init'),
4093 ]
4120 ]
4094
4121
4095 if costlimit:
4122 if costlimit:
4096 benches.extend(
4123 benches.extend(
4097 [
4124 [
4098 (dogetscost, b'gets w/ cost limit'),
4125 (dogetscost, b'gets w/ cost limit'),
4099 (doinsertscost, b'inserts w/ cost limit'),
4126 (doinsertscost, b'inserts w/ cost limit'),
4100 (domixedcost, b'mixed w/ cost limit'),
4127 (domixedcost, b'mixed w/ cost limit'),
4101 ]
4128 ]
4102 )
4129 )
4103 else:
4130 else:
4104 benches.extend(
4131 benches.extend(
4105 [
4132 [
4106 (dogets, b'gets'),
4133 (dogets, b'gets'),
4107 (doinserts, b'inserts'),
4134 (doinserts, b'inserts'),
4108 (dosets, b'sets'),
4135 (dosets, b'sets'),
4109 (domixed, b'mixed'),
4136 (domixed, b'mixed'),
4110 ]
4137 ]
4111 )
4138 )
4112
4139
4113 for fn, title in benches:
4140 for fn, title in benches:
4114 timer, fm = gettimer(ui, opts)
4141 timer, fm = gettimer(ui, opts)
4115 timer(fn, title=title)
4142 timer(fn, title=title)
4116 fm.end()
4143 fm.end()
4117
4144
4118
4145
4119 @command(
4146 @command(
4120 b'perf::write|perfwrite',
4147 b'perf::write|perfwrite',
4121 formatteropts
4148 formatteropts
4122 + [
4149 + [
4123 (b'', b'write-method', b'write', b'ui write method'),
4150 (b'', b'write-method', b'write', b'ui write method'),
4124 (b'', b'nlines', 100, b'number of lines'),
4151 (b'', b'nlines', 100, b'number of lines'),
4125 (b'', b'nitems', 100, b'number of items (per line)'),
4152 (b'', b'nitems', 100, b'number of items (per line)'),
4126 (b'', b'item', b'x', b'item that is written'),
4153 (b'', b'item', b'x', b'item that is written'),
4127 (b'', b'batch-line', None, b'pass whole line to write method at once'),
4154 (b'', b'batch-line', None, b'pass whole line to write method at once'),
4128 (b'', b'flush-line', None, b'flush after each line'),
4155 (b'', b'flush-line', None, b'flush after each line'),
4129 ],
4156 ],
4130 )
4157 )
4131 def perfwrite(ui, repo, **opts):
4158 def perfwrite(ui, repo, **opts):
4132 """microbenchmark ui.write (and others)"""
4159 """microbenchmark ui.write (and others)"""
4133 opts = _byteskwargs(opts)
4160 opts = _byteskwargs(opts)
4134
4161
4135 write = getattr(ui, _sysstr(opts[b'write_method']))
4162 write = getattr(ui, _sysstr(opts[b'write_method']))
4136 nlines = int(opts[b'nlines'])
4163 nlines = int(opts[b'nlines'])
4137 nitems = int(opts[b'nitems'])
4164 nitems = int(opts[b'nitems'])
4138 item = opts[b'item']
4165 item = opts[b'item']
4139 batch_line = opts.get(b'batch_line')
4166 batch_line = opts.get(b'batch_line')
4140 flush_line = opts.get(b'flush_line')
4167 flush_line = opts.get(b'flush_line')
4141
4168
4142 if batch_line:
4169 if batch_line:
4143 line = item * nitems + b'\n'
4170 line = item * nitems + b'\n'
4144
4171
4145 def benchmark():
4172 def benchmark():
4146 for i in pycompat.xrange(nlines):
4173 for i in pycompat.xrange(nlines):
4147 if batch_line:
4174 if batch_line:
4148 write(line)
4175 write(line)
4149 else:
4176 else:
4150 for i in pycompat.xrange(nitems):
4177 for i in pycompat.xrange(nitems):
4151 write(item)
4178 write(item)
4152 write(b'\n')
4179 write(b'\n')
4153 if flush_line:
4180 if flush_line:
4154 ui.flush()
4181 ui.flush()
4155 ui.flush()
4182 ui.flush()
4156
4183
4157 timer, fm = gettimer(ui, opts)
4184 timer, fm = gettimer(ui, opts)
4158 timer(benchmark)
4185 timer(benchmark)
4159 fm.end()
4186 fm.end()
4160
4187
4161
4188
4162 def uisetup(ui):
4189 def uisetup(ui):
4163 if util.safehasattr(cmdutil, b'openrevlog') and not util.safehasattr(
4190 if util.safehasattr(cmdutil, b'openrevlog') and not util.safehasattr(
4164 commands, b'debugrevlogopts'
4191 commands, b'debugrevlogopts'
4165 ):
4192 ):
4166 # for "historical portability":
4193 # for "historical portability":
4167 # In this case, Mercurial should be 1.9 (or a79fea6b3e77) -
4194 # In this case, Mercurial should be 1.9 (or a79fea6b3e77) -
4168 # 3.7 (or 5606f7d0d063). Therefore, '--dir' option for
4195 # 3.7 (or 5606f7d0d063). Therefore, '--dir' option for
4169 # openrevlog() should cause failure, because it has been
4196 # openrevlog() should cause failure, because it has been
4170 # available since 3.5 (or 49c583ca48c4).
4197 # available since 3.5 (or 49c583ca48c4).
4171 def openrevlog(orig, repo, cmd, file_, opts):
4198 def openrevlog(orig, repo, cmd, file_, opts):
4172 if opts.get(b'dir') and not util.safehasattr(repo, b'dirlog'):
4199 if opts.get(b'dir') and not util.safehasattr(repo, b'dirlog'):
4173 raise error.Abort(
4200 raise error.Abort(
4174 b"This version doesn't support --dir option",
4201 b"This version doesn't support --dir option",
4175 hint=b"use 3.5 or later",
4202 hint=b"use 3.5 or later",
4176 )
4203 )
4177 return orig(repo, cmd, file_, opts)
4204 return orig(repo, cmd, file_, opts)
4178
4205
4179 extensions.wrapfunction(cmdutil, b'openrevlog', openrevlog)
4206 extensions.wrapfunction(cmdutil, b'openrevlog', openrevlog)
4180
4207
4181
4208
4182 @command(
4209 @command(
4183 b'perf::progress|perfprogress',
4210 b'perf::progress|perfprogress',
4184 formatteropts
4211 formatteropts
4185 + [
4212 + [
4186 (b'', b'topic', b'topic', b'topic for progress messages'),
4213 (b'', b'topic', b'topic', b'topic for progress messages'),
4187 (b'c', b'total', 1000000, b'total value we are progressing to'),
4214 (b'c', b'total', 1000000, b'total value we are progressing to'),
4188 ],
4215 ],
4189 norepo=True,
4216 norepo=True,
4190 )
4217 )
4191 def perfprogress(ui, topic=None, total=None, **opts):
4218 def perfprogress(ui, topic=None, total=None, **opts):
4192 """printing of progress bars"""
4219 """printing of progress bars"""
4193 opts = _byteskwargs(opts)
4220 opts = _byteskwargs(opts)
4194
4221
4195 timer, fm = gettimer(ui, opts)
4222 timer, fm = gettimer(ui, opts)
4196
4223
4197 def doprogress():
4224 def doprogress():
4198 with ui.makeprogress(topic, total=total) as progress:
4225 with ui.makeprogress(topic, total=total) as progress:
4199 for i in _xrange(total):
4226 for i in _xrange(total):
4200 progress.increment()
4227 progress.increment()
4201
4228
4202 timer(doprogress)
4229 timer(doprogress)
4203 fm.end()
4230 fm.end()
@@ -1,337 +1,337 b''
1 # bzr.py - bzr support for the convert extension
1 # bzr.py - bzr support for the convert extension
2 #
2 #
3 # Copyright 2008, 2009 Marek Kubica <marek@xivilization.net> and others
3 # Copyright 2008, 2009 Marek Kubica <marek@xivilization.net> and others
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 # This module is for handling Breezy imports or `brz`, but it's also compatible
8 # This module is for handling Breezy imports or `brz`, but it's also compatible
9 # with Bazaar or `bzr`, that was formerly known as Bazaar-NG;
9 # with Bazaar or `bzr`, that was formerly known as Bazaar-NG;
10 # it cannot access `bar` repositories, but they were never used very much.
10 # it cannot access `bar` repositories, but they were never used very much.
11
11
12 import os
12 import os
13
13
14 from mercurial.i18n import _
14 from mercurial.i18n import _
15 from mercurial import (
15 from mercurial import (
16 demandimport,
16 demandimport,
17 error,
17 error,
18 util,
18 util,
19 )
19 )
20 from . import common
20 from . import common
21
21
22
22
23 # these do not work with demandimport, blacklist
23 # these do not work with demandimport, blacklist
24 demandimport.IGNORES.update(
24 demandimport.IGNORES.update(
25 [
25 [
26 b'breezy.transactions',
26 'breezy.transactions',
27 b'breezy.urlutils',
27 'breezy.urlutils',
28 b'ElementPath',
28 'ElementPath',
29 ]
29 ]
30 )
30 )
31
31
32 try:
32 try:
33 # bazaar imports
33 # bazaar imports
34 import breezy.bzr.bzrdir
34 import breezy.bzr.bzrdir
35 import breezy.errors
35 import breezy.errors
36 import breezy.revision
36 import breezy.revision
37 import breezy.revisionspec
37 import breezy.revisionspec
38
38
39 bzrdir = breezy.bzr.bzrdir
39 bzrdir = breezy.bzr.bzrdir
40 errors = breezy.errors
40 errors = breezy.errors
41 revision = breezy.revision
41 revision = breezy.revision
42 revisionspec = breezy.revisionspec
42 revisionspec = breezy.revisionspec
43 revisionspec.RevisionSpec
43 revisionspec.RevisionSpec
44 except ImportError:
44 except ImportError:
45 pass
45 pass
46
46
47 supportedkinds = ('file', 'symlink')
47 supportedkinds = ('file', 'symlink')
48
48
49
49
50 class bzr_source(common.converter_source):
50 class bzr_source(common.converter_source):
51 """Reads Bazaar repositories by using the Bazaar Python libraries"""
51 """Reads Bazaar repositories by using the Bazaar Python libraries"""
52
52
53 def __init__(self, ui, repotype, path, revs=None):
53 def __init__(self, ui, repotype, path, revs=None):
54 super(bzr_source, self).__init__(ui, repotype, path, revs=revs)
54 super(bzr_source, self).__init__(ui, repotype, path, revs=revs)
55
55
56 if not os.path.exists(os.path.join(path, b'.bzr')):
56 if not os.path.exists(os.path.join(path, b'.bzr')):
57 raise common.NoRepo(
57 raise common.NoRepo(
58 _(b'%s does not look like a Bazaar repository') % path
58 _(b'%s does not look like a Bazaar repository') % path
59 )
59 )
60
60
61 try:
61 try:
62 # access breezy stuff
62 # access breezy stuff
63 bzrdir
63 bzrdir
64 except NameError:
64 except NameError:
65 raise common.NoRepo(_(b'Bazaar modules could not be loaded'))
65 raise common.NoRepo(_(b'Bazaar modules could not be loaded'))
66
66
67 path = util.abspath(path)
67 path = util.abspath(path)
68 self._checkrepotype(path)
68 self._checkrepotype(path)
69 try:
69 try:
70 bzr_dir = bzrdir.BzrDir.open(path.decode())
70 bzr_dir = bzrdir.BzrDir.open(path.decode())
71 self.sourcerepo = bzr_dir.open_repository()
71 self.sourcerepo = bzr_dir.open_repository()
72 except errors.NoRepositoryPresent:
72 except errors.NoRepositoryPresent:
73 raise common.NoRepo(
73 raise common.NoRepo(
74 _(b'%s does not look like a Bazaar repository') % path
74 _(b'%s does not look like a Bazaar repository') % path
75 )
75 )
76 self._parentids = {}
76 self._parentids = {}
77 self._saverev = ui.configbool(b'convert', b'bzr.saverev')
77 self._saverev = ui.configbool(b'convert', b'bzr.saverev')
78
78
79 def _checkrepotype(self, path):
79 def _checkrepotype(self, path):
80 # Lightweight checkouts detection is informational but probably
80 # Lightweight checkouts detection is informational but probably
81 # fragile at API level. It should not terminate the conversion.
81 # fragile at API level. It should not terminate the conversion.
82 try:
82 try:
83 dir = bzrdir.BzrDir.open_containing(path.decode())[0]
83 dir = bzrdir.BzrDir.open_containing(path.decode())[0]
84 try:
84 try:
85 tree = dir.open_workingtree(recommend_upgrade=False)
85 tree = dir.open_workingtree(recommend_upgrade=False)
86 branch = tree.branch
86 branch = tree.branch
87 except (errors.NoWorkingTree, errors.NotLocalUrl):
87 except (errors.NoWorkingTree, errors.NotLocalUrl):
88 tree = None
88 tree = None
89 branch = dir.open_branch()
89 branch = dir.open_branch()
90 if (
90 if (
91 tree is not None
91 tree is not None
92 and tree.controldir.root_transport.base
92 and tree.controldir.root_transport.base
93 != branch.controldir.root_transport.base
93 != branch.controldir.root_transport.base
94 ):
94 ):
95 self.ui.warn(
95 self.ui.warn(
96 _(
96 _(
97 b'warning: lightweight checkouts may cause '
97 b'warning: lightweight checkouts may cause '
98 b'conversion failures, try with a regular '
98 b'conversion failures, try with a regular '
99 b'branch instead.\n'
99 b'branch instead.\n'
100 )
100 )
101 )
101 )
102 except Exception:
102 except Exception:
103 self.ui.note(_(b'bzr source type could not be determined\n'))
103 self.ui.note(_(b'bzr source type could not be determined\n'))
104
104
105 def before(self):
105 def before(self):
106 """Before the conversion begins, acquire a read lock
106 """Before the conversion begins, acquire a read lock
107 for all the operations that might need it. Fortunately
107 for all the operations that might need it. Fortunately
108 read locks don't block other reads or writes to the
108 read locks don't block other reads or writes to the
109 repository, so this shouldn't have any impact on the usage of
109 repository, so this shouldn't have any impact on the usage of
110 the source repository.
110 the source repository.
111
111
112 The alternative would be locking on every operation that
112 The alternative would be locking on every operation that
113 needs locks (there are currently two: getting the file and
113 needs locks (there are currently two: getting the file and
114 getting the parent map) and releasing immediately after,
114 getting the parent map) and releasing immediately after,
115 but this approach can take even 40% longer."""
115 but this approach can take even 40% longer."""
116 self.sourcerepo.lock_read()
116 self.sourcerepo.lock_read()
117
117
118 def after(self):
118 def after(self):
119 self.sourcerepo.unlock()
119 self.sourcerepo.unlock()
120
120
121 def _bzrbranches(self):
121 def _bzrbranches(self):
122 return self.sourcerepo.find_branches(using=True)
122 return self.sourcerepo.find_branches(using=True)
123
123
124 def getheads(self):
124 def getheads(self):
125 if not self.revs:
125 if not self.revs:
126 # Set using=True to avoid nested repositories (see issue3254)
126 # Set using=True to avoid nested repositories (see issue3254)
127 heads = sorted([b.last_revision() for b in self._bzrbranches()])
127 heads = sorted([b.last_revision() for b in self._bzrbranches()])
128 else:
128 else:
129 revid = None
129 revid = None
130 for branch in self._bzrbranches():
130 for branch in self._bzrbranches():
131 try:
131 try:
132 revspec = self.revs[0].decode()
132 revspec = self.revs[0].decode()
133 r = revisionspec.RevisionSpec.from_string(revspec)
133 r = revisionspec.RevisionSpec.from_string(revspec)
134 info = r.in_history(branch)
134 info = r.in_history(branch)
135 except errors.BzrError:
135 except errors.BzrError:
136 pass
136 pass
137 revid = info.rev_id
137 revid = info.rev_id
138 if revid is None:
138 if revid is None:
139 raise error.Abort(
139 raise error.Abort(
140 _(b'%s is not a valid revision') % self.revs[0]
140 _(b'%s is not a valid revision') % self.revs[0]
141 )
141 )
142 heads = [revid]
142 heads = [revid]
143 # Empty repositories return 'null:', which cannot be retrieved
143 # Empty repositories return 'null:', which cannot be retrieved
144 heads = [h for h in heads if h != b'null:']
144 heads = [h for h in heads if h != b'null:']
145 return heads
145 return heads
146
146
147 def getfile(self, name, rev):
147 def getfile(self, name, rev):
148 name = name.decode()
148 name = name.decode()
149 revtree = self.sourcerepo.revision_tree(rev)
149 revtree = self.sourcerepo.revision_tree(rev)
150
150
151 try:
151 try:
152 kind = revtree.kind(name)
152 kind = revtree.kind(name)
153 except breezy.errors.NoSuchFile:
153 except breezy.errors.NoSuchFile:
154 return None, None
154 return None, None
155 if kind not in supportedkinds:
155 if kind not in supportedkinds:
156 # the file is not available anymore - was deleted
156 # the file is not available anymore - was deleted
157 return None, None
157 return None, None
158 mode = self._modecache[(name.encode(), rev)]
158 mode = self._modecache[(name.encode(), rev)]
159 if kind == 'symlink':
159 if kind == 'symlink':
160 target = revtree.get_symlink_target(name)
160 target = revtree.get_symlink_target(name)
161 if target is None:
161 if target is None:
162 raise error.Abort(
162 raise error.Abort(
163 _(b'%s.%s symlink has no target') % (name, rev)
163 _(b'%s.%s symlink has no target') % (name, rev)
164 )
164 )
165 return target.encode(), mode
165 return target.encode(), mode
166 else:
166 else:
167 sio = revtree.get_file(name)
167 sio = revtree.get_file(name)
168 return sio.read(), mode
168 return sio.read(), mode
169
169
170 def getchanges(self, version, full):
170 def getchanges(self, version, full):
171 if full:
171 if full:
172 raise error.Abort(_(b"convert from cvs does not support --full"))
172 raise error.Abort(_(b"convert from cvs does not support --full"))
173 self._modecache = {}
173 self._modecache = {}
174 self._revtree = self.sourcerepo.revision_tree(version)
174 self._revtree = self.sourcerepo.revision_tree(version)
175 # get the parentids from the cache
175 # get the parentids from the cache
176 parentids = self._parentids.pop(version)
176 parentids = self._parentids.pop(version)
177 # only diff against first parent id
177 # only diff against first parent id
178 prevtree = self.sourcerepo.revision_tree(parentids[0])
178 prevtree = self.sourcerepo.revision_tree(parentids[0])
179 files, changes = self._gettreechanges(self._revtree, prevtree)
179 files, changes = self._gettreechanges(self._revtree, prevtree)
180 return files, changes, set()
180 return files, changes, set()
181
181
182 def getcommit(self, version):
182 def getcommit(self, version):
183 rev = self.sourcerepo.get_revision(version)
183 rev = self.sourcerepo.get_revision(version)
184 # populate parent id cache
184 # populate parent id cache
185 if not rev.parent_ids:
185 if not rev.parent_ids:
186 parents = []
186 parents = []
187 self._parentids[version] = (revision.NULL_REVISION,)
187 self._parentids[version] = (revision.NULL_REVISION,)
188 else:
188 else:
189 parents = self._filterghosts(rev.parent_ids)
189 parents = self._filterghosts(rev.parent_ids)
190 self._parentids[version] = parents
190 self._parentids[version] = parents
191
191
192 branch = rev.properties.get('branch-nick', 'default')
192 branch = rev.properties.get('branch-nick', 'default')
193 if branch == 'trunk':
193 if branch == 'trunk':
194 branch = 'default'
194 branch = 'default'
195 return common.commit(
195 return common.commit(
196 parents=parents,
196 parents=parents,
197 date=b'%d %d' % (rev.timestamp, -rev.timezone),
197 date=b'%d %d' % (rev.timestamp, -rev.timezone),
198 author=self.recode(rev.committer),
198 author=self.recode(rev.committer),
199 desc=self.recode(rev.message),
199 desc=self.recode(rev.message),
200 branch=branch.encode('utf8'),
200 branch=branch.encode('utf8'),
201 rev=version,
201 rev=version,
202 saverev=self._saverev,
202 saverev=self._saverev,
203 )
203 )
204
204
205 def gettags(self):
205 def gettags(self):
206 bytetags = {}
206 bytetags = {}
207 for branch in self._bzrbranches():
207 for branch in self._bzrbranches():
208 if not branch.supports_tags():
208 if not branch.supports_tags():
209 return {}
209 return {}
210 tagdict = branch.tags.get_tag_dict()
210 tagdict = branch.tags.get_tag_dict()
211 for name, rev in tagdict.items():
211 for name, rev in tagdict.items():
212 bytetags[self.recode(name)] = rev
212 bytetags[self.recode(name)] = rev
213 return bytetags
213 return bytetags
214
214
215 def getchangedfiles(self, rev, i):
215 def getchangedfiles(self, rev, i):
216 self._modecache = {}
216 self._modecache = {}
217 curtree = self.sourcerepo.revision_tree(rev)
217 curtree = self.sourcerepo.revision_tree(rev)
218 if i is not None:
218 if i is not None:
219 parentid = self._parentids[rev][i]
219 parentid = self._parentids[rev][i]
220 else:
220 else:
221 # no parent id, get the empty revision
221 # no parent id, get the empty revision
222 parentid = revision.NULL_REVISION
222 parentid = revision.NULL_REVISION
223
223
224 prevtree = self.sourcerepo.revision_tree(parentid)
224 prevtree = self.sourcerepo.revision_tree(parentid)
225 changes = [e[0] for e in self._gettreechanges(curtree, prevtree)[0]]
225 changes = [e[0] for e in self._gettreechanges(curtree, prevtree)[0]]
226 return changes
226 return changes
227
227
228 def _gettreechanges(self, current, origin):
228 def _gettreechanges(self, current, origin):
229 revid = current._revision_id
229 revid = current._revision_id
230 changes = []
230 changes = []
231 renames = {}
231 renames = {}
232 seen = set()
232 seen = set()
233
233
234 # Fall back to the deprecated attribute for legacy installations.
234 # Fall back to the deprecated attribute for legacy installations.
235 try:
235 try:
236 inventory = origin.root_inventory
236 inventory = origin.root_inventory
237 except AttributeError:
237 except AttributeError:
238 inventory = origin.inventory
238 inventory = origin.inventory
239
239
240 # Process the entries by reverse lexicographic name order to
240 # Process the entries by reverse lexicographic name order to
241 # handle nested renames correctly, most specific first.
241 # handle nested renames correctly, most specific first.
242
242
243 def key(c):
243 def key(c):
244 return c.path[0] or c.path[1] or ""
244 return c.path[0] or c.path[1] or ""
245
245
246 curchanges = sorted(
246 curchanges = sorted(
247 current.iter_changes(origin),
247 current.iter_changes(origin),
248 key=key,
248 key=key,
249 reverse=True,
249 reverse=True,
250 )
250 )
251 for change in curchanges:
251 for change in curchanges:
252 paths = change.path
252 paths = change.path
253 kind = change.kind
253 kind = change.kind
254 executable = change.executable
254 executable = change.executable
255 if paths[0] == u'' or paths[1] == u'':
255 if paths[0] == u'' or paths[1] == u'':
256 # ignore changes to tree root
256 # ignore changes to tree root
257 continue
257 continue
258
258
259 # bazaar tracks directories, mercurial does not, so
259 # bazaar tracks directories, mercurial does not, so
260 # we have to rename the directory contents
260 # we have to rename the directory contents
261 if kind[1] == 'directory':
261 if kind[1] == 'directory':
262 if kind[0] not in (None, 'directory'):
262 if kind[0] not in (None, 'directory'):
263 # Replacing 'something' with a directory, record it
263 # Replacing 'something' with a directory, record it
264 # so it can be removed.
264 # so it can be removed.
265 changes.append((self.recode(paths[0]), revid))
265 changes.append((self.recode(paths[0]), revid))
266
266
267 if kind[0] == 'directory' and None not in paths:
267 if kind[0] == 'directory' and None not in paths:
268 renaming = paths[0] != paths[1]
268 renaming = paths[0] != paths[1]
269 # neither an add nor an delete - a move
269 # neither an add nor an delete - a move
270 # rename all directory contents manually
270 # rename all directory contents manually
271 subdir = inventory.path2id(paths[0])
271 subdir = inventory.path2id(paths[0])
272 # get all child-entries of the directory
272 # get all child-entries of the directory
273 for name, entry in inventory.iter_entries(subdir):
273 for name, entry in inventory.iter_entries(subdir):
274 # hg does not track directory renames
274 # hg does not track directory renames
275 if entry.kind == 'directory':
275 if entry.kind == 'directory':
276 continue
276 continue
277 frompath = self.recode(paths[0] + '/' + name)
277 frompath = self.recode(paths[0] + '/' + name)
278 if frompath in seen:
278 if frompath in seen:
279 # Already handled by a more specific change entry
279 # Already handled by a more specific change entry
280 # This is important when you have:
280 # This is important when you have:
281 # a => b
281 # a => b
282 # a/c => a/c
282 # a/c => a/c
283 # Here a/c must not be renamed into b/c
283 # Here a/c must not be renamed into b/c
284 continue
284 continue
285 seen.add(frompath)
285 seen.add(frompath)
286 if not renaming:
286 if not renaming:
287 continue
287 continue
288 topath = self.recode(paths[1] + '/' + name)
288 topath = self.recode(paths[1] + '/' + name)
289 # register the files as changed
289 # register the files as changed
290 changes.append((frompath, revid))
290 changes.append((frompath, revid))
291 changes.append((topath, revid))
291 changes.append((topath, revid))
292 # add to mode cache
292 # add to mode cache
293 mode = (
293 mode = (
294 (entry.executable and b'x')
294 (entry.executable and b'x')
295 or (entry.kind == 'symlink' and b's')
295 or (entry.kind == 'symlink' and b's')
296 or b''
296 or b''
297 )
297 )
298 self._modecache[(topath, revid)] = mode
298 self._modecache[(topath, revid)] = mode
299 # register the change as move
299 # register the change as move
300 renames[topath] = frompath
300 renames[topath] = frompath
301
301
302 # no further changes, go to the next change
302 # no further changes, go to the next change
303 continue
303 continue
304
304
305 # we got unicode paths, need to convert them
305 # we got unicode paths, need to convert them
306 path, topath = paths
306 path, topath = paths
307 if path is not None:
307 if path is not None:
308 path = self.recode(path)
308 path = self.recode(path)
309 if topath is not None:
309 if topath is not None:
310 topath = self.recode(topath)
310 topath = self.recode(topath)
311 seen.add(path or topath)
311 seen.add(path or topath)
312
312
313 if topath is None:
313 if topath is None:
314 # file deleted
314 # file deleted
315 changes.append((path, revid))
315 changes.append((path, revid))
316 continue
316 continue
317
317
318 # renamed
318 # renamed
319 if path and path != topath:
319 if path and path != topath:
320 renames[topath] = path
320 renames[topath] = path
321 changes.append((path, revid))
321 changes.append((path, revid))
322
322
323 # populate the mode cache
323 # populate the mode cache
324 kind, executable = [e[1] for e in (kind, executable)]
324 kind, executable = [e[1] for e in (kind, executable)]
325 mode = (executable and b'x') or (kind == 'symlink' and b'l') or b''
325 mode = (executable and b'x') or (kind == 'symlink' and b'l') or b''
326 self._modecache[(topath, revid)] = mode
326 self._modecache[(topath, revid)] = mode
327 changes.append((topath, revid))
327 changes.append((topath, revid))
328
328
329 return changes, renames
329 return changes, renames
330
330
331 def _filterghosts(self, ids):
331 def _filterghosts(self, ids):
332 """Filters out ghost revisions which hg does not support, see
332 """Filters out ghost revisions which hg does not support, see
333 <http://bazaar-vcs.org/GhostRevision>
333 <http://bazaar-vcs.org/GhostRevision>
334 """
334 """
335 parentmap = self.sourcerepo.get_parent_map(ids)
335 parentmap = self.sourcerepo.get_parent_map(ids)
336 parents = tuple([parent for parent in ids if parent in parentmap])
336 parents = tuple([parent for parent in ids if parent in parentmap])
337 return parents
337 return parents
@@ -1,100 +1,100 b''
1 # highlight.py - highlight extension implementation file
1 # highlight.py - highlight extension implementation file
2 #
2 #
3 # Copyright 2007-2009 Adam Hupp <adam@hupp.org> and others
3 # Copyright 2007-2009 Adam Hupp <adam@hupp.org> and others
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7 #
7 #
8 # The original module was split in an interface and an implementation
8 # The original module was split in an interface and an implementation
9 # file to defer pygments loading and speedup extension setup.
9 # file to defer pygments loading and speedup extension setup.
10
10
11
11
12 from mercurial import demandimport
12 from mercurial import demandimport
13
13
14 demandimport.IGNORES.update([b'pkgutil', b'pkg_resources', b'__main__'])
14 demandimport.IGNORES.update(['pkgutil', 'pkg_resources', '__main__'])
15
15
16 from mercurial import (
16 from mercurial import (
17 encoding,
17 encoding,
18 pycompat,
18 pycompat,
19 )
19 )
20
20
21 from mercurial.utils import stringutil
21 from mercurial.utils import stringutil
22
22
23 with demandimport.deactivated():
23 with demandimport.deactivated():
24 import pygments
24 import pygments
25 import pygments.formatters
25 import pygments.formatters
26 import pygments.lexers
26 import pygments.lexers
27 import pygments.plugin
27 import pygments.plugin
28 import pygments.util
28 import pygments.util
29
29
30 for unused in pygments.plugin.find_plugin_lexers():
30 for unused in pygments.plugin.find_plugin_lexers():
31 pass
31 pass
32
32
33 highlight = pygments.highlight
33 highlight = pygments.highlight
34 ClassNotFound = pygments.util.ClassNotFound
34 ClassNotFound = pygments.util.ClassNotFound
35 guess_lexer = pygments.lexers.guess_lexer
35 guess_lexer = pygments.lexers.guess_lexer
36 guess_lexer_for_filename = pygments.lexers.guess_lexer_for_filename
36 guess_lexer_for_filename = pygments.lexers.guess_lexer_for_filename
37 TextLexer = pygments.lexers.TextLexer
37 TextLexer = pygments.lexers.TextLexer
38 HtmlFormatter = pygments.formatters.HtmlFormatter
38 HtmlFormatter = pygments.formatters.HtmlFormatter
39
39
40 SYNTAX_CSS = (
40 SYNTAX_CSS = (
41 b'\n<link rel="stylesheet" href="{url}highlightcss" type="text/css" />'
41 b'\n<link rel="stylesheet" href="{url}highlightcss" type="text/css" />'
42 )
42 )
43
43
44
44
45 def pygmentize(field, fctx, style, tmpl, guessfilenameonly=False):
45 def pygmentize(field, fctx, style, tmpl, guessfilenameonly=False):
46
46
47 # append a <link ...> to the syntax highlighting css
47 # append a <link ...> to the syntax highlighting css
48 tmpl.load(b'header')
48 tmpl.load(b'header')
49 old_header = tmpl.cache[b'header']
49 old_header = tmpl.cache[b'header']
50 if SYNTAX_CSS not in old_header:
50 if SYNTAX_CSS not in old_header:
51 new_header = old_header + SYNTAX_CSS
51 new_header = old_header + SYNTAX_CSS
52 tmpl.cache[b'header'] = new_header
52 tmpl.cache[b'header'] = new_header
53
53
54 text = fctx.data()
54 text = fctx.data()
55 if stringutil.binary(text):
55 if stringutil.binary(text):
56 return
56 return
57
57
58 # str.splitlines() != unicode.splitlines() because "reasons"
58 # str.splitlines() != unicode.splitlines() because "reasons"
59 for c in b"\x0c", b"\x1c", b"\x1d", b"\x1e":
59 for c in b"\x0c", b"\x1c", b"\x1d", b"\x1e":
60 if c in text:
60 if c in text:
61 text = text.replace(c, b'')
61 text = text.replace(c, b'')
62
62
63 # Pygments is best used with Unicode strings:
63 # Pygments is best used with Unicode strings:
64 # <http://pygments.org/docs/unicode/>
64 # <http://pygments.org/docs/unicode/>
65 text = text.decode(pycompat.sysstr(encoding.encoding), 'replace')
65 text = text.decode(pycompat.sysstr(encoding.encoding), 'replace')
66
66
67 # To get multi-line strings right, we can't format line-by-line
67 # To get multi-line strings right, we can't format line-by-line
68 try:
68 try:
69 path = pycompat.sysstr(fctx.path())
69 path = pycompat.sysstr(fctx.path())
70 lexer = guess_lexer_for_filename(path, text[:1024], stripnl=False)
70 lexer = guess_lexer_for_filename(path, text[:1024], stripnl=False)
71 except (ClassNotFound, ValueError):
71 except (ClassNotFound, ValueError):
72 # guess_lexer will return a lexer if *any* lexer matches. There is
72 # guess_lexer will return a lexer if *any* lexer matches. There is
73 # no way to specify a minimum match score. This can give a high rate of
73 # no way to specify a minimum match score. This can give a high rate of
74 # false positives on files with an unknown filename pattern.
74 # false positives on files with an unknown filename pattern.
75 if guessfilenameonly:
75 if guessfilenameonly:
76 return
76 return
77
77
78 try:
78 try:
79 lexer = guess_lexer(text[:1024], stripnl=False)
79 lexer = guess_lexer(text[:1024], stripnl=False)
80 except (ClassNotFound, ValueError):
80 except (ClassNotFound, ValueError):
81 # Don't highlight unknown files
81 # Don't highlight unknown files
82 return
82 return
83
83
84 # Don't highlight text files
84 # Don't highlight text files
85 if isinstance(lexer, TextLexer):
85 if isinstance(lexer, TextLexer):
86 return
86 return
87
87
88 formatter = HtmlFormatter(nowrap=True, style=pycompat.sysstr(style))
88 formatter = HtmlFormatter(nowrap=True, style=pycompat.sysstr(style))
89
89
90 colorized = highlight(text, lexer, formatter)
90 colorized = highlight(text, lexer, formatter)
91 coloriter = (
91 coloriter = (
92 s.encode(pycompat.sysstr(encoding.encoding), 'replace')
92 s.encode(pycompat.sysstr(encoding.encoding), 'replace')
93 for s in colorized.splitlines()
93 for s in colorized.splitlines()
94 )
94 )
95
95
96 tmpl._filters[b'colorize'] = lambda x: next(coloriter)
96 tmpl._filters[b'colorize'] = lambda x: next(coloriter)
97
97
98 oldl = tmpl.cache[field]
98 oldl = tmpl.cache[field]
99 newl = oldl.replace(b'line|escape', b'line|colorize')
99 newl = oldl.replace(b'line|escape', b'line|colorize')
100 tmpl.cache[field] = newl
100 tmpl.cache[field] = newl
@@ -1,773 +1,789 b''
1 # blobstore.py - local and remote (speaking Git-LFS protocol) blob storages
1 # blobstore.py - local and remote (speaking Git-LFS protocol) blob storages
2 #
2 #
3 # Copyright 2017 Facebook, Inc.
3 # Copyright 2017 Facebook, Inc.
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8
8
9 import contextlib
9 import contextlib
10 import errno
10 import errno
11 import hashlib
11 import hashlib
12 import json
12 import json
13 import os
13 import os
14 import re
14 import re
15 import socket
15 import socket
16
16
17 from mercurial.i18n import _
17 from mercurial.i18n import _
18 from mercurial.pycompat import getattr
18 from mercurial.pycompat import getattr
19 from mercurial.node import hex
19 from mercurial.node import hex
20
20
21 from mercurial import (
21 from mercurial import (
22 encoding,
22 encoding,
23 error,
23 error,
24 httpconnection as httpconnectionmod,
24 httpconnection as httpconnectionmod,
25 pathutil,
25 pathutil,
26 pycompat,
26 pycompat,
27 url as urlmod,
27 url as urlmod,
28 util,
28 util,
29 vfs as vfsmod,
29 vfs as vfsmod,
30 worker,
30 worker,
31 )
31 )
32
32
33 from mercurial.utils import (
33 from mercurial.utils import (
34 stringutil,
34 stringutil,
35 urlutil,
35 urlutil,
36 )
36 )
37
37
38 from ..largefiles import lfutil
38 from ..largefiles import lfutil
39
39
40 # 64 bytes for SHA256
40 # 64 bytes for SHA256
41 _lfsre = re.compile(br'\A[a-f0-9]{64}\Z')
41 _lfsre = re.compile(br'\A[a-f0-9]{64}\Z')
42
42
43
43
44 class lfsvfs(vfsmod.vfs):
44 class lfsvfs(vfsmod.vfs):
45 def join(self, path):
45 def join(self, path):
46 """split the path at first two characters, like: XX/XXXXX..."""
46 """split the path at first two characters, like: XX/XXXXX..."""
47 if not _lfsre.match(path):
47 if not _lfsre.match(path):
48 raise error.ProgrammingError(b'unexpected lfs path: %s' % path)
48 raise error.ProgrammingError(b'unexpected lfs path: %s' % path)
49 return super(lfsvfs, self).join(path[0:2], path[2:])
49 return super(lfsvfs, self).join(path[0:2], path[2:])
50
50
51 def walk(self, path=None, onerror=None):
51 def walk(self, path=None, onerror=None):
52 """Yield (dirpath, [], oids) tuple for blobs under path
52 """Yield (dirpath, [], oids) tuple for blobs under path
53
53
54 Oids only exist in the root of this vfs, so dirpath is always ''.
54 Oids only exist in the root of this vfs, so dirpath is always ''.
55 """
55 """
56 root = os.path.normpath(self.base)
56 root = os.path.normpath(self.base)
57 # when dirpath == root, dirpath[prefixlen:] becomes empty
57 # when dirpath == root, dirpath[prefixlen:] becomes empty
58 # because len(dirpath) < prefixlen.
58 # because len(dirpath) < prefixlen.
59 prefixlen = len(pathutil.normasprefix(root))
59 prefixlen = len(pathutil.normasprefix(root))
60 oids = []
60 oids = []
61
61
62 for dirpath, dirs, files in os.walk(
62 for dirpath, dirs, files in os.walk(
63 self.reljoin(self.base, path or b''), onerror=onerror
63 self.reljoin(self.base, path or b''), onerror=onerror
64 ):
64 ):
65 dirpath = dirpath[prefixlen:]
65 dirpath = dirpath[prefixlen:]
66
66
67 # Silently skip unexpected files and directories
67 # Silently skip unexpected files and directories
68 if len(dirpath) == 2:
68 if len(dirpath) == 2:
69 oids.extend(
69 oids.extend(
70 [dirpath + f for f in files if _lfsre.match(dirpath + f)]
70 [dirpath + f for f in files if _lfsre.match(dirpath + f)]
71 )
71 )
72
72
73 yield (b'', [], oids)
73 yield (b'', [], oids)
74
74
75
75
76 class nullvfs(lfsvfs):
76 class nullvfs(lfsvfs):
77 def __init__(self):
77 def __init__(self):
78 pass
78 pass
79
79
80 def exists(self, oid):
80 def exists(self, oid):
81 return False
81 return False
82
82
83 def read(self, oid):
83 def read(self, oid):
84 # store.read() calls into here if the blob doesn't exist in its
84 # store.read() calls into here if the blob doesn't exist in its
85 # self.vfs. Raise the same error as a normal vfs when asked to read a
85 # self.vfs. Raise the same error as a normal vfs when asked to read a
86 # file that doesn't exist. The only difference is the full file path
86 # file that doesn't exist. The only difference is the full file path
87 # isn't available in the error.
87 # isn't available in the error.
88 raise IOError(
88 raise IOError(
89 errno.ENOENT,
89 errno.ENOENT,
90 pycompat.sysstr(b'%s: No such file or directory' % oid),
90 pycompat.sysstr(b'%s: No such file or directory' % oid),
91 )
91 )
92
92
93 def walk(self, path=None, onerror=None):
93 def walk(self, path=None, onerror=None):
94 return (b'', [], [])
94 return (b'', [], [])
95
95
96 def write(self, oid, data):
96 def write(self, oid, data):
97 pass
97 pass
98
98
99
99
100 class lfsuploadfile(httpconnectionmod.httpsendfile):
100 class lfsuploadfile(httpconnectionmod.httpsendfile):
101 """a file-like object that supports keepalive."""
101 """a file-like object that supports keepalive."""
102
102
103 def __init__(self, ui, filename):
103 def __init__(self, ui, filename):
104 super(lfsuploadfile, self).__init__(ui, filename, b'rb')
104 super(lfsuploadfile, self).__init__(ui, filename, b'rb')
105 self.read = self._data.read
105 self.read = self._data.read
106
106
107 def _makeprogress(self):
107 def _makeprogress(self):
108 return None # progress is handled by the worker client
108 return None # progress is handled by the worker client
109
109
110
110
111 class local:
111 class local:
112 """Local blobstore for large file contents.
112 """Local blobstore for large file contents.
113
113
114 This blobstore is used both as a cache and as a staging area for large blobs
114 This blobstore is used both as a cache and as a staging area for large blobs
115 to be uploaded to the remote blobstore.
115 to be uploaded to the remote blobstore.
116 """
116 """
117
117
118 def __init__(self, repo):
118 def __init__(self, repo):
119 fullpath = repo.svfs.join(b'lfs/objects')
119 fullpath = repo.svfs.join(b'lfs/objects')
120 self.vfs = lfsvfs(fullpath)
120 self.vfs = lfsvfs(fullpath)
121
121
122 if repo.ui.configbool(b'experimental', b'lfs.disableusercache'):
122 if repo.ui.configbool(b'experimental', b'lfs.disableusercache'):
123 self.cachevfs = nullvfs()
123 self.cachevfs = nullvfs()
124 else:
124 else:
125 usercache = lfutil._usercachedir(repo.ui, b'lfs')
125 usercache = lfutil._usercachedir(repo.ui, b'lfs')
126 self.cachevfs = lfsvfs(usercache)
126 self.cachevfs = lfsvfs(usercache)
127 self.ui = repo.ui
127 self.ui = repo.ui
128
128
129 def open(self, oid):
129 def open(self, oid):
130 """Open a read-only file descriptor to the named blob, in either the
130 """Open a read-only file descriptor to the named blob, in either the
131 usercache or the local store."""
131 usercache or the local store."""
132 return open(self.path(oid), 'rb')
132 return open(self.path(oid), 'rb')
133
133
134 def path(self, oid):
134 def path(self, oid):
135 """Build the path for the given blob ``oid``.
135 """Build the path for the given blob ``oid``.
136
136
137 If the blob exists locally, the path may point to either the usercache
137 If the blob exists locally, the path may point to either the usercache
138 or the local store. If it doesn't, it will point to the local store.
138 or the local store. If it doesn't, it will point to the local store.
139 This is meant for situations where existing code that isn't LFS aware
139 This is meant for situations where existing code that isn't LFS aware
140 needs to open a blob. Generally, prefer the ``open`` method on this
140 needs to open a blob. Generally, prefer the ``open`` method on this
141 class.
141 class.
142 """
142 """
143 # The usercache is the most likely place to hold the file. Commit will
143 # The usercache is the most likely place to hold the file. Commit will
144 # write to both it and the local store, as will anything that downloads
144 # write to both it and the local store, as will anything that downloads
145 # the blobs. However, things like clone without an update won't
145 # the blobs. However, things like clone without an update won't
146 # populate the local store. For an init + push of a local clone,
146 # populate the local store. For an init + push of a local clone,
147 # the usercache is the only place it _could_ be. If not present, the
147 # the usercache is the only place it _could_ be. If not present, the
148 # missing file msg here will indicate the local repo, not the usercache.
148 # missing file msg here will indicate the local repo, not the usercache.
149 if self.cachevfs.exists(oid):
149 if self.cachevfs.exists(oid):
150 return self.cachevfs.join(oid)
150 return self.cachevfs.join(oid)
151
151
152 return self.vfs.join(oid)
152 return self.vfs.join(oid)
153
153
154 def download(self, oid, src, content_length):
154 def download(self, oid, src, content_length):
155 """Read the blob from the remote source in chunks, verify the content,
155 """Read the blob from the remote source in chunks, verify the content,
156 and write to this local blobstore."""
156 and write to this local blobstore."""
157 sha256 = hashlib.sha256()
157 sha256 = hashlib.sha256()
158 size = 0
158 size = 0
159
159
160 with self.vfs(oid, b'wb', atomictemp=True) as fp:
160 with self.vfs(oid, b'wb', atomictemp=True) as fp:
161 for chunk in util.filechunkiter(src, size=1048576):
161 for chunk in util.filechunkiter(src, size=1048576):
162 fp.write(chunk)
162 fp.write(chunk)
163 sha256.update(chunk)
163 sha256.update(chunk)
164 size += len(chunk)
164 size += len(chunk)
165
165
166 # If the server advertised a length longer than what we actually
166 # If the server advertised a length longer than what we actually
167 # received, then we should expect that the server crashed while
167 # received, then we should expect that the server crashed while
168 # producing the response (but the server has no way of telling us
168 # producing the response (but the server has no way of telling us
169 # that), and we really don't need to try to write the response to
169 # that), and we really don't need to try to write the response to
170 # the localstore, because it's not going to match the expected.
170 # the localstore, because it's not going to match the expected.
171 # The server also uses this method to store data uploaded by the
171 # The server also uses this method to store data uploaded by the
172 # client, so if this happens on the server side, it's possible
172 # client, so if this happens on the server side, it's possible
173 # that the client crashed or an antivirus interfered with the
173 # that the client crashed or an antivirus interfered with the
174 # upload.
174 # upload.
175 if content_length is not None and int(content_length) != size:
175 if content_length is not None and int(content_length) != size:
176 msg = (
176 msg = (
177 b"Response length (%d) does not match Content-Length "
177 b"Response length (%d) does not match Content-Length "
178 b"header (%d) for %s"
178 b"header (%d) for %s"
179 )
179 )
180 raise LfsRemoteError(_(msg) % (size, int(content_length), oid))
180 raise LfsRemoteError(_(msg) % (size, int(content_length), oid))
181
181
182 realoid = hex(sha256.digest())
182 realoid = hex(sha256.digest())
183 if realoid != oid:
183 if realoid != oid:
184 raise LfsCorruptionError(
184 raise LfsCorruptionError(
185 _(b'corrupt remote lfs object: %s') % oid
185 _(b'corrupt remote lfs object: %s') % oid
186 )
186 )
187
187
188 self._linktousercache(oid)
188 self._linktousercache(oid)
189
189
190 def write(self, oid, data):
190 def write(self, oid, data):
191 """Write blob to local blobstore.
191 """Write blob to local blobstore.
192
192
193 This should only be called from the filelog during a commit or similar.
193 This should only be called from the filelog during a commit or similar.
194 As such, there is no need to verify the data. Imports from a remote
194 As such, there is no need to verify the data. Imports from a remote
195 store must use ``download()`` instead."""
195 store must use ``download()`` instead."""
196 with self.vfs(oid, b'wb', atomictemp=True) as fp:
196 with self.vfs(oid, b'wb', atomictemp=True) as fp:
197 fp.write(data)
197 fp.write(data)
198
198
199 self._linktousercache(oid)
199 self._linktousercache(oid)
200
200
201 def linkfromusercache(self, oid):
201 def linkfromusercache(self, oid):
202 """Link blobs found in the user cache into this store.
202 """Link blobs found in the user cache into this store.
203
203
204 The server module needs to do this when it lets the client know not to
204 The server module needs to do this when it lets the client know not to
205 upload the blob, to ensure it is always available in this store.
205 upload the blob, to ensure it is always available in this store.
206 Normally this is done implicitly when the client reads or writes the
206 Normally this is done implicitly when the client reads or writes the
207 blob, but that doesn't happen when the server tells the client that it
207 blob, but that doesn't happen when the server tells the client that it
208 already has the blob.
208 already has the blob.
209 """
209 """
210 if not isinstance(self.cachevfs, nullvfs) and not self.vfs.exists(oid):
210 if not isinstance(self.cachevfs, nullvfs) and not self.vfs.exists(oid):
211 self.ui.note(_(b'lfs: found %s in the usercache\n') % oid)
211 self.ui.note(_(b'lfs: found %s in the usercache\n') % oid)
212 lfutil.link(self.cachevfs.join(oid), self.vfs.join(oid))
212 lfutil.link(self.cachevfs.join(oid), self.vfs.join(oid))
213
213
214 def _linktousercache(self, oid):
214 def _linktousercache(self, oid):
215 # XXX: should we verify the content of the cache, and hardlink back to
215 # XXX: should we verify the content of the cache, and hardlink back to
216 # the local store on success, but truncate, write and link on failure?
216 # the local store on success, but truncate, write and link on failure?
217 if not self.cachevfs.exists(oid) and not isinstance(
217 if not self.cachevfs.exists(oid) and not isinstance(
218 self.cachevfs, nullvfs
218 self.cachevfs, nullvfs
219 ):
219 ):
220 self.ui.note(_(b'lfs: adding %s to the usercache\n') % oid)
220 self.ui.note(_(b'lfs: adding %s to the usercache\n') % oid)
221 lfutil.link(self.vfs.join(oid), self.cachevfs.join(oid))
221 lfutil.link(self.vfs.join(oid), self.cachevfs.join(oid))
222
222
223 def read(self, oid, verify=True):
223 def read(self, oid, verify=True):
224 """Read blob from local blobstore."""
224 """Read blob from local blobstore."""
225 if not self.vfs.exists(oid):
225 if not self.vfs.exists(oid):
226 blob = self._read(self.cachevfs, oid, verify)
226 blob = self._read(self.cachevfs, oid, verify)
227
227
228 # Even if revlog will verify the content, it needs to be verified
228 # Even if revlog will verify the content, it needs to be verified
229 # now before making the hardlink to avoid propagating corrupt blobs.
229 # now before making the hardlink to avoid propagating corrupt blobs.
230 # Don't abort if corruption is detected, because `hg verify` will
230 # Don't abort if corruption is detected, because `hg verify` will
231 # give more useful info about the corruption- simply don't add the
231 # give more useful info about the corruption- simply don't add the
232 # hardlink.
232 # hardlink.
233 if verify or hex(hashlib.sha256(blob).digest()) == oid:
233 if verify or hex(hashlib.sha256(blob).digest()) == oid:
234 self.ui.note(_(b'lfs: found %s in the usercache\n') % oid)
234 self.ui.note(_(b'lfs: found %s in the usercache\n') % oid)
235 lfutil.link(self.cachevfs.join(oid), self.vfs.join(oid))
235 lfutil.link(self.cachevfs.join(oid), self.vfs.join(oid))
236 else:
236 else:
237 self.ui.note(_(b'lfs: found %s in the local lfs store\n') % oid)
237 self.ui.note(_(b'lfs: found %s in the local lfs store\n') % oid)
238 blob = self._read(self.vfs, oid, verify)
238 blob = self._read(self.vfs, oid, verify)
239 return blob
239 return blob
240
240
241 def _read(self, vfs, oid, verify):
241 def _read(self, vfs, oid, verify):
242 """Read blob (after verifying) from the given store"""
242 """Read blob (after verifying) from the given store"""
243 blob = vfs.read(oid)
243 blob = vfs.read(oid)
244 if verify:
244 if verify:
245 _verify(oid, blob)
245 _verify(oid, blob)
246 return blob
246 return blob
247
247
248 def verify(self, oid):
248 def verify(self, oid):
249 """Indicate whether or not the hash of the underlying file matches its
249 """Indicate whether or not the hash of the underlying file matches its
250 name."""
250 name."""
251 sha256 = hashlib.sha256()
251 sha256 = hashlib.sha256()
252
252
253 with self.open(oid) as fp:
253 with self.open(oid) as fp:
254 for chunk in util.filechunkiter(fp, size=1048576):
254 for chunk in util.filechunkiter(fp, size=1048576):
255 sha256.update(chunk)
255 sha256.update(chunk)
256
256
257 return oid == hex(sha256.digest())
257 return oid == hex(sha256.digest())
258
258
259 def has(self, oid):
259 def has(self, oid):
260 """Returns True if the local blobstore contains the requested blob,
260 """Returns True if the local blobstore contains the requested blob,
261 False otherwise."""
261 False otherwise."""
262 return self.cachevfs.exists(oid) or self.vfs.exists(oid)
262 return self.cachevfs.exists(oid) or self.vfs.exists(oid)
263
263
264
264
265 def _urlerrorreason(urlerror):
265 def _urlerrorreason(urlerror):
266 """Create a friendly message for the given URLError to be used in an
266 """Create a friendly message for the given URLError to be used in an
267 LfsRemoteError message.
267 LfsRemoteError message.
268 """
268 """
269 inst = urlerror
269 inst = urlerror
270
270
271 if isinstance(urlerror.reason, Exception):
271 if isinstance(urlerror.reason, Exception):
272 inst = urlerror.reason
272 inst = urlerror.reason
273
273
274 if util.safehasattr(inst, b'reason'):
274 if util.safehasattr(inst, b'reason'):
275 try: # usually it is in the form (errno, strerror)
275 try: # usually it is in the form (errno, strerror)
276 reason = inst.reason.args[1]
276 reason = inst.reason.args[1]
277 except (AttributeError, IndexError):
277 except (AttributeError, IndexError):
278 # it might be anything, for example a string
278 # it might be anything, for example a string
279 reason = inst.reason
279 reason = inst.reason
280 if isinstance(reason, str):
280 if isinstance(reason, str):
281 # SSLError of Python 2.7.9 contains a unicode
281 # SSLError of Python 2.7.9 contains a unicode
282 reason = encoding.unitolocal(reason)
282 reason = encoding.unitolocal(reason)
283 return reason
283 return reason
284 elif getattr(inst, "strerror", None):
284 elif getattr(inst, "strerror", None):
285 return encoding.strtolocal(inst.strerror)
285 return encoding.strtolocal(inst.strerror)
286 else:
286 else:
287 return stringutil.forcebytestr(urlerror)
287 return stringutil.forcebytestr(urlerror)
288
288
289
289
290 class lfsauthhandler(util.urlreq.basehandler):
290 class lfsauthhandler(util.urlreq.basehandler):
291 handler_order = 480 # Before HTTPDigestAuthHandler (== 490)
291 handler_order = 480 # Before HTTPDigestAuthHandler (== 490)
292
292
293 def http_error_401(self, req, fp, code, msg, headers):
293 def http_error_401(self, req, fp, code, msg, headers):
294 """Enforces that any authentication performed is HTTP Basic
294 """Enforces that any authentication performed is HTTP Basic
295 Authentication. No authentication is also acceptable.
295 Authentication. No authentication is also acceptable.
296 """
296 """
297 authreq = headers.get('www-authenticate', None)
297 authreq = headers.get('www-authenticate', None)
298 if authreq:
298 if authreq:
299 scheme = authreq.split()[0]
299 scheme = authreq.split()[0]
300
300
301 if scheme.lower() != 'basic':
301 if scheme.lower() != 'basic':
302 msg = _(b'the server must support Basic Authentication')
302 msg = _(b'the server must support Basic Authentication')
303 raise util.urlerr.httperror(
303 raise util.urlerr.httperror(
304 req.get_full_url(),
304 req.get_full_url(),
305 code,
305 code,
306 encoding.strfromlocal(msg),
306 encoding.strfromlocal(msg),
307 headers,
307 headers,
308 fp,
308 fp,
309 )
309 )
310 return None
310 return None
311
311
312
312
313 class _gitlfsremote:
313 class _gitlfsremote:
314 def __init__(self, repo, url):
314 def __init__(self, repo, url):
315 ui = repo.ui
315 ui = repo.ui
316 self.ui = ui
316 self.ui = ui
317 baseurl, authinfo = url.authinfo()
317 baseurl, authinfo = url.authinfo()
318 self.baseurl = baseurl.rstrip(b'/')
318 self.baseurl = baseurl.rstrip(b'/')
319 useragent = repo.ui.config(b'experimental', b'lfs.user-agent')
319 useragent = repo.ui.config(b'experimental', b'lfs.user-agent')
320 if not useragent:
320 if not useragent:
321 useragent = b'git-lfs/2.3.4 (Mercurial %s)' % util.version()
321 useragent = b'git-lfs/2.3.4 (Mercurial %s)' % util.version()
322 self.urlopener = urlmod.opener(ui, authinfo, useragent)
322 self.urlopener = urlmod.opener(ui, authinfo, useragent)
323 self.urlopener.add_handler(lfsauthhandler())
323 self.urlopener.add_handler(lfsauthhandler())
324 self.retry = ui.configint(b'lfs', b'retry')
324 self.retry = ui.configint(b'lfs', b'retry')
325
325
326 def writebatch(self, pointers, fromstore):
326 def writebatch(self, pointers, fromstore):
327 """Batch upload from local to remote blobstore."""
327 """Batch upload from local to remote blobstore."""
328 self._batch(_deduplicate(pointers), fromstore, b'upload')
328 self._batch(_deduplicate(pointers), fromstore, b'upload')
329
329
330 def readbatch(self, pointers, tostore):
330 def readbatch(self, pointers, tostore):
331 """Batch download from remote to local blostore."""
331 """Batch download from remote to local blostore."""
332 self._batch(_deduplicate(pointers), tostore, b'download')
332 self._batch(_deduplicate(pointers), tostore, b'download')
333
333
334 def _batchrequest(self, pointers, action):
334 def _batchrequest(self, pointers, action):
335 """Get metadata about objects pointed by pointers for given action
335 """Get metadata about objects pointed by pointers for given action
336
336
337 Return decoded JSON object like {'objects': [{'oid': '', 'size': 1}]}
337 Return decoded JSON object like {'objects': [{'oid': '', 'size': 1}]}
338 See https://github.com/git-lfs/git-lfs/blob/master/docs/api/batch.md
338 See https://github.com/git-lfs/git-lfs/blob/master/docs/api/batch.md
339 """
339 """
340 objects = [
340 objects = [
341 {'oid': pycompat.strurl(p.oid()), 'size': p.size()}
341 {'oid': pycompat.strurl(p.oid()), 'size': p.size()}
342 for p in pointers
342 for p in pointers
343 ]
343 ]
344 requestdata = pycompat.bytesurl(
344 requestdata = pycompat.bytesurl(
345 json.dumps(
345 json.dumps(
346 {
346 {
347 'objects': objects,
347 'objects': objects,
348 'operation': pycompat.strurl(action),
348 'operation': pycompat.strurl(action),
349 }
349 }
350 )
350 )
351 )
351 )
352 url = b'%s/objects/batch' % self.baseurl
352 url = b'%s/objects/batch' % self.baseurl
353 batchreq = util.urlreq.request(pycompat.strurl(url), data=requestdata)
353 batchreq = util.urlreq.request(pycompat.strurl(url), data=requestdata)
354 batchreq.add_header('Accept', 'application/vnd.git-lfs+json')
354 batchreq.add_header('Accept', 'application/vnd.git-lfs+json')
355 batchreq.add_header('Content-Type', 'application/vnd.git-lfs+json')
355 batchreq.add_header('Content-Type', 'application/vnd.git-lfs+json')
356 try:
356 try:
357 with contextlib.closing(self.urlopener.open(batchreq)) as rsp:
357 with contextlib.closing(self.urlopener.open(batchreq)) as rsp:
358 rawjson = rsp.read()
358 rawjson = rsp.read()
359 except util.urlerr.httperror as ex:
359 except util.urlerr.httperror as ex:
360 hints = {
360 hints = {
361 400: _(
361 400: _(
362 b'check that lfs serving is enabled on %s and "%s" is '
362 b'check that lfs serving is enabled on %s and "%s" is '
363 b'supported'
363 b'supported'
364 )
364 )
365 % (self.baseurl, action),
365 % (self.baseurl, action),
366 404: _(b'the "lfs.url" config may be used to override %s')
366 404: _(b'the "lfs.url" config may be used to override %s')
367 % self.baseurl,
367 % self.baseurl,
368 }
368 }
369 hint = hints.get(ex.code, _(b'api=%s, action=%s') % (url, action))
369 hint = hints.get(ex.code, _(b'api=%s, action=%s') % (url, action))
370 raise LfsRemoteError(
370 raise LfsRemoteError(
371 _(b'LFS HTTP error: %s') % stringutil.forcebytestr(ex),
371 _(b'LFS HTTP error: %s') % stringutil.forcebytestr(ex),
372 hint=hint,
372 hint=hint,
373 )
373 )
374 except util.urlerr.urlerror as ex:
374 except util.urlerr.urlerror as ex:
375 hint = (
375 hint = (
376 _(b'the "lfs.url" config may be used to override %s')
376 _(b'the "lfs.url" config may be used to override %s')
377 % self.baseurl
377 % self.baseurl
378 )
378 )
379 raise LfsRemoteError(
379 raise LfsRemoteError(
380 _(b'LFS error: %s') % _urlerrorreason(ex), hint=hint
380 _(b'LFS error: %s') % _urlerrorreason(ex), hint=hint
381 )
381 )
382 try:
382 try:
383 response = pycompat.json_loads(rawjson)
383 response = pycompat.json_loads(rawjson)
384 except ValueError:
384 except ValueError:
385 raise LfsRemoteError(
385 raise LfsRemoteError(
386 _(b'LFS server returns invalid JSON: %s')
386 _(b'LFS server returns invalid JSON: %s')
387 % rawjson.encode("utf-8")
387 % rawjson.encode("utf-8")
388 )
388 )
389
389
390 if self.ui.debugflag:
390 if self.ui.debugflag:
391 self.ui.debug(b'Status: %d\n' % rsp.status)
391 self.ui.debug(b'Status: %d\n' % rsp.status)
392 # lfs-test-server and hg serve return headers in different order
392 # lfs-test-server and hg serve return headers in different order
393 headers = pycompat.bytestr(rsp.info()).strip()
393 headers = pycompat.bytestr(rsp.info()).strip()
394 self.ui.debug(b'%s\n' % b'\n'.join(sorted(headers.splitlines())))
394 self.ui.debug(b'%s\n' % b'\n'.join(sorted(headers.splitlines())))
395
395
396 if 'objects' in response:
396 if 'objects' in response:
397 response['objects'] = sorted(
397 response['objects'] = sorted(
398 response['objects'], key=lambda p: p['oid']
398 response['objects'], key=lambda p: p['oid']
399 )
399 )
400 self.ui.debug(
400 self.ui.debug(
401 b'%s\n'
401 b'%s\n'
402 % pycompat.bytesurl(
402 % pycompat.bytesurl(
403 json.dumps(
403 json.dumps(
404 response,
404 response,
405 indent=2,
405 indent=2,
406 separators=('', ': '),
406 separators=('', ': '),
407 sort_keys=True,
407 sort_keys=True,
408 )
408 )
409 )
409 )
410 )
410 )
411
411
412 def encodestr(x):
412 def encodestr(x):
413 if isinstance(x, str):
413 if isinstance(x, str):
414 return x.encode('utf-8')
414 return x.encode('utf-8')
415 return x
415 return x
416
416
417 return pycompat.rapply(encodestr, response)
417 return pycompat.rapply(encodestr, response)
418
418
419 def _checkforservererror(self, pointers, responses, action):
419 def _checkforservererror(self, pointers, responses, action):
420 """Scans errors from objects
420 """Scans errors from objects
421
421
422 Raises LfsRemoteError if any objects have an error"""
422 Raises LfsRemoteError if any objects have an error"""
423 for response in responses:
423 for response in responses:
424 # The server should return 404 when objects cannot be found. Some
424 # The server should return 404 when objects cannot be found. Some
425 # server implementation (ex. lfs-test-server) does not set "error"
425 # server implementation (ex. lfs-test-server) does not set "error"
426 # but just removes "download" from "actions". Treat that case
426 # but just removes "download" from "actions". Treat that case
427 # as the same as 404 error.
427 # as the same as 404 error.
428 if b'error' not in response:
428 if b'error' not in response:
429 if action == b'download' and action not in response.get(
429 if action == b'download' and action not in response.get(
430 b'actions', []
430 b'actions', []
431 ):
431 ):
432 code = 404
432 code = 404
433 else:
433 else:
434 continue
434 continue
435 else:
435 else:
436 # An error dict without a code doesn't make much sense, so
436 # An error dict without a code doesn't make much sense, so
437 # treat as a server error.
437 # treat as a server error.
438 code = response.get(b'error').get(b'code', 500)
438 code = response.get(b'error').get(b'code', 500)
439
439
440 ptrmap = {p.oid(): p for p in pointers}
440 ptrmap = {p.oid(): p for p in pointers}
441 p = ptrmap.get(response[b'oid'], None)
441 p = ptrmap.get(response[b'oid'], None)
442 if p:
442 if p:
443 filename = getattr(p, 'filename', b'unknown')
443 filename = getattr(p, 'filename', b'unknown')
444 errors = {
444 errors = {
445 404: b'The object does not exist',
445 404: b'The object does not exist',
446 410: b'The object was removed by the owner',
446 410: b'The object was removed by the owner',
447 422: b'Validation error',
447 422: b'Validation error',
448 500: b'Internal server error',
448 500: b'Internal server error',
449 }
449 }
450 msg = errors.get(code, b'status code %d' % code)
450 msg = errors.get(code, b'status code %d' % code)
451 raise LfsRemoteError(
451 raise LfsRemoteError(
452 _(b'LFS server error for "%s": %s') % (filename, msg)
452 _(b'LFS server error for "%s": %s') % (filename, msg)
453 )
453 )
454 else:
454 else:
455 raise LfsRemoteError(
455 raise LfsRemoteError(
456 _(b'LFS server error. Unsolicited response for oid %s')
456 _(b'LFS server error. Unsolicited response for oid %s')
457 % response[b'oid']
457 % response[b'oid']
458 )
458 )
459
459
460 def _extractobjects(self, response, pointers, action):
460 def _extractobjects(self, response, pointers, action):
461 """extract objects from response of the batch API
461 """extract objects from response of the batch API
462
462
463 response: parsed JSON object returned by batch API
463 response: parsed JSON object returned by batch API
464 return response['objects'] filtered by action
464 return response['objects'] filtered by action
465 raise if any object has an error
465 raise if any object has an error
466 """
466 """
467 # Scan errors from objects - fail early
467 # Scan errors from objects - fail early
468 objects = response.get(b'objects', [])
468 objects = response.get(b'objects', [])
469 self._checkforservererror(pointers, objects, action)
469 self._checkforservererror(pointers, objects, action)
470
470
471 # Filter objects with given action. Practically, this skips uploading
471 # Filter objects with given action. Practically, this skips uploading
472 # objects which exist in the server.
472 # objects which exist in the server.
473 filteredobjects = [
473 filteredobjects = [
474 o for o in objects if action in o.get(b'actions', [])
474 o for o in objects if action in o.get(b'actions', [])
475 ]
475 ]
476
476
477 return filteredobjects
477 return filteredobjects
478
478
479 def _basictransfer(self, obj, action, localstore):
479 def _basictransfer(self, obj, action, localstore):
480 """Download or upload a single object using basic transfer protocol
480 """Download or upload a single object using basic transfer protocol
481
481
482 obj: dict, an object description returned by batch API
482 obj: dict, an object description returned by batch API
483 action: string, one of ['upload', 'download']
483 action: string, one of ['upload', 'download']
484 localstore: blobstore.local
484 localstore: blobstore.local
485
485
486 See https://github.com/git-lfs/git-lfs/blob/master/docs/api/\
486 See https://github.com/git-lfs/git-lfs/blob/master/docs/api/\
487 basic-transfers.md
487 basic-transfers.md
488 """
488 """
489 oid = obj[b'oid']
489 oid = obj[b'oid']
490 href = obj[b'actions'][action].get(b'href')
490 href = obj[b'actions'][action].get(b'href')
491 headers = obj[b'actions'][action].get(b'header', {}).items()
491 headers = obj[b'actions'][action].get(b'header', {}).items()
492
492
493 request = util.urlreq.request(pycompat.strurl(href))
493 request = util.urlreq.request(pycompat.strurl(href))
494 if action == b'upload':
494 if action == b'upload':
495 # If uploading blobs, read data from local blobstore.
495 # If uploading blobs, read data from local blobstore.
496 if not localstore.verify(oid):
496 if not localstore.verify(oid):
497 raise error.Abort(
497 raise error.Abort(
498 _(b'detected corrupt lfs object: %s') % oid,
498 _(b'detected corrupt lfs object: %s') % oid,
499 hint=_(b'run hg verify'),
499 hint=_(b'run hg verify'),
500 )
500 )
501
501
502 for k, v in headers:
502 for k, v in headers:
503 request.add_header(pycompat.strurl(k), pycompat.strurl(v))
503 request.add_header(pycompat.strurl(k), pycompat.strurl(v))
504
504
505 try:
505 try:
506 if action == b'upload':
506 if action == b'upload':
507 request.data = lfsuploadfile(self.ui, localstore.path(oid))
507 request.data = lfsuploadfile(self.ui, localstore.path(oid))
508 request.get_method = lambda: 'PUT'
508 request.get_method = lambda: 'PUT'
509 request.add_header('Content-Type', 'application/octet-stream')
509 request.add_header('Content-Type', 'application/octet-stream')
510 request.add_header('Content-Length', request.data.length)
510 request.add_header('Content-Length', request.data.length)
511
511
512 with contextlib.closing(self.urlopener.open(request)) as res:
512 with contextlib.closing(self.urlopener.open(request)) as res:
513 contentlength = res.info().get(b"content-length")
513 contentlength = res.info().get(b"content-length")
514 ui = self.ui # Shorten debug lines
514 ui = self.ui # Shorten debug lines
515 if self.ui.debugflag:
515 if self.ui.debugflag:
516 ui.debug(b'Status: %d\n' % res.status)
516 ui.debug(b'Status: %d\n' % res.status)
517 # lfs-test-server and hg serve return headers in different
517 # lfs-test-server and hg serve return headers in different
518 # order
518 # order
519 headers = pycompat.bytestr(res.info()).strip()
519 headers = pycompat.bytestr(res.info()).strip()
520 ui.debug(b'%s\n' % b'\n'.join(sorted(headers.splitlines())))
520 ui.debug(b'%s\n' % b'\n'.join(sorted(headers.splitlines())))
521
521
522 if action == b'download':
522 if action == b'download':
523 # If downloading blobs, store downloaded data to local
523 # If downloading blobs, store downloaded data to local
524 # blobstore
524 # blobstore
525 localstore.download(oid, res, contentlength)
525 localstore.download(oid, res, contentlength)
526 else:
526 else:
527 blocks = []
527 blocks = []
528 while True:
528 while True:
529 data = res.read(1048576)
529 data = res.read(1048576)
530 if not data:
530 if not data:
531 break
531 break
532 blocks.append(data)
532 blocks.append(data)
533
533
534 response = b"".join(blocks)
534 response = b"".join(blocks)
535 if response:
535 if response:
536 ui.debug(b'lfs %s response: %s' % (action, response))
536 ui.debug(b'lfs %s response: %s' % (action, response))
537 except util.urlerr.httperror as ex:
537 except util.urlerr.httperror as ex:
538 if self.ui.debugflag:
538 if self.ui.debugflag:
539 self.ui.debug(
539 self.ui.debug(
540 b'%s: %s\n' % (oid, ex.read())
540 b'%s: %s\n' % (oid, ex.read())
541 ) # XXX: also bytes?
541 ) # XXX: also bytes?
542 raise LfsRemoteError(
542 raise LfsRemoteError(
543 _(b'LFS HTTP error: %s (oid=%s, action=%s)')
543 _(b'LFS HTTP error: %s (oid=%s, action=%s)')
544 % (stringutil.forcebytestr(ex), oid, action)
544 % (stringutil.forcebytestr(ex), oid, action)
545 )
545 )
546 except util.urlerr.urlerror as ex:
546 except util.urlerr.urlerror as ex:
547 hint = _(b'attempted connection to %s') % pycompat.bytesurl(
547 hint = _(b'attempted connection to %s') % pycompat.bytesurl(
548 util.urllibcompat.getfullurl(request)
548 util.urllibcompat.getfullurl(request)
549 )
549 )
550 raise LfsRemoteError(
550 raise LfsRemoteError(
551 _(b'LFS error: %s') % _urlerrorreason(ex), hint=hint
551 _(b'LFS error: %s') % _urlerrorreason(ex), hint=hint
552 )
552 )
553 finally:
553 finally:
554 if request.data:
554 if request.data:
555 request.data.close()
555 request.data.close()
556
556
557 def _batch(self, pointers, localstore, action):
557 def _batch(self, pointers, localstore, action):
558 if action not in [b'upload', b'download']:
558 if action not in [b'upload', b'download']:
559 raise error.ProgrammingError(b'invalid Git-LFS action: %s' % action)
559 raise error.ProgrammingError(b'invalid Git-LFS action: %s' % action)
560
560
561 response = self._batchrequest(pointers, action)
561 response = self._batchrequest(pointers, action)
562 objects = self._extractobjects(response, pointers, action)
562 objects = self._extractobjects(response, pointers, action)
563 total = sum(x.get(b'size', 0) for x in objects)
563 total = sum(x.get(b'size', 0) for x in objects)
564 sizes = {}
564 sizes = {}
565 for obj in objects:
565 for obj in objects:
566 sizes[obj.get(b'oid')] = obj.get(b'size', 0)
566 sizes[obj.get(b'oid')] = obj.get(b'size', 0)
567 topic = {
567 topic = {
568 b'upload': _(b'lfs uploading'),
568 b'upload': _(b'lfs uploading'),
569 b'download': _(b'lfs downloading'),
569 b'download': _(b'lfs downloading'),
570 }[action]
570 }[action]
571 if len(objects) > 1:
571 if len(objects) > 1:
572 self.ui.note(
572 self.ui.note(
573 _(b'lfs: need to transfer %d objects (%s)\n')
573 _(b'lfs: need to transfer %d objects (%s)\n')
574 % (len(objects), util.bytecount(total))
574 % (len(objects), util.bytecount(total))
575 )
575 )
576
576
577 def transfer(chunk):
577 def transfer(chunk):
578 for obj in chunk:
578 for obj in chunk:
579 objsize = obj.get(b'size', 0)
579 objsize = obj.get(b'size', 0)
580 if self.ui.verbose:
580 if self.ui.verbose:
581 if action == b'download':
581 if action == b'download':
582 msg = _(b'lfs: downloading %s (%s)\n')
582 msg = _(b'lfs: downloading %s (%s)\n')
583 elif action == b'upload':
583 elif action == b'upload':
584 msg = _(b'lfs: uploading %s (%s)\n')
584 msg = _(b'lfs: uploading %s (%s)\n')
585 self.ui.note(
585 self.ui.note(
586 msg % (obj.get(b'oid'), util.bytecount(objsize))
586 msg % (obj.get(b'oid'), util.bytecount(objsize))
587 )
587 )
588 retry = self.retry
588 retry = self.retry
589 while True:
589 while True:
590 try:
590 try:
591 self._basictransfer(obj, action, localstore)
591 self._basictransfer(obj, action, localstore)
592 yield 1, obj.get(b'oid')
592 yield 1, obj.get(b'oid')
593 break
593 break
594 except socket.error as ex:
594 except socket.error as ex:
595 if retry > 0:
595 if retry > 0:
596 self.ui.note(
596 self.ui.note(
597 _(b'lfs: failed: %r (remaining retry %d)\n')
597 _(b'lfs: failed: %r (remaining retry %d)\n')
598 % (stringutil.forcebytestr(ex), retry)
598 % (stringutil.forcebytestr(ex), retry)
599 )
599 )
600 retry -= 1
600 retry -= 1
601 continue
601 continue
602 raise
602 raise
603
603
604 # Until https multiplexing gets sorted out
604 # Until https multiplexing gets sorted out. It's not clear if
605 # ConnectionManager.set_ready() is externally synchronized for thread
606 # safety with Windows workers.
605 if self.ui.configbool(b'experimental', b'lfs.worker-enable'):
607 if self.ui.configbool(b'experimental', b'lfs.worker-enable'):
608 # The POSIX workers are forks of this process, so before spinning
609 # them up, close all pooled connections. Otherwise, there's no way
610 # to coordinate between them about who is using what, and the
611 # transfers will get corrupted.
612 #
613 # TODO: add a function to keepalive.ConnectionManager to mark all
614 # ready connections as in use, and roll that back after the fork?
615 # That would allow the existing pool of connections in this process
616 # to be preserved.
617 def prefork():
618 for h in self.urlopener.handlers:
619 getattr(h, "close_all", lambda: None)()
620
606 oids = worker.worker(
621 oids = worker.worker(
607 self.ui,
622 self.ui,
608 0.1,
623 0.1,
609 transfer,
624 transfer,
610 (),
625 (),
611 sorted(objects, key=lambda o: o.get(b'oid')),
626 sorted(objects, key=lambda o: o.get(b'oid')),
627 prefork=prefork,
612 )
628 )
613 else:
629 else:
614 oids = transfer(sorted(objects, key=lambda o: o.get(b'oid')))
630 oids = transfer(sorted(objects, key=lambda o: o.get(b'oid')))
615
631
616 with self.ui.makeprogress(
632 with self.ui.makeprogress(
617 topic, unit=_(b"bytes"), total=total
633 topic, unit=_(b"bytes"), total=total
618 ) as progress:
634 ) as progress:
619 progress.update(0)
635 progress.update(0)
620 processed = 0
636 processed = 0
621 blobs = 0
637 blobs = 0
622 for _one, oid in oids:
638 for _one, oid in oids:
623 processed += sizes[oid]
639 processed += sizes[oid]
624 blobs += 1
640 blobs += 1
625 progress.update(processed)
641 progress.update(processed)
626 self.ui.note(_(b'lfs: processed: %s\n') % oid)
642 self.ui.note(_(b'lfs: processed: %s\n') % oid)
627
643
628 if blobs > 0:
644 if blobs > 0:
629 if action == b'upload':
645 if action == b'upload':
630 self.ui.status(
646 self.ui.status(
631 _(b'lfs: uploaded %d files (%s)\n')
647 _(b'lfs: uploaded %d files (%s)\n')
632 % (blobs, util.bytecount(processed))
648 % (blobs, util.bytecount(processed))
633 )
649 )
634 elif action == b'download':
650 elif action == b'download':
635 self.ui.status(
651 self.ui.status(
636 _(b'lfs: downloaded %d files (%s)\n')
652 _(b'lfs: downloaded %d files (%s)\n')
637 % (blobs, util.bytecount(processed))
653 % (blobs, util.bytecount(processed))
638 )
654 )
639
655
640 def __del__(self):
656 def __del__(self):
641 # copied from mercurial/httppeer.py
657 # copied from mercurial/httppeer.py
642 urlopener = getattr(self, 'urlopener', None)
658 urlopener = getattr(self, 'urlopener', None)
643 if urlopener:
659 if urlopener:
644 for h in urlopener.handlers:
660 for h in urlopener.handlers:
645 h.close()
661 h.close()
646 getattr(h, "close_all", lambda: None)()
662 getattr(h, "close_all", lambda: None)()
647
663
648
664
649 class _dummyremote:
665 class _dummyremote:
650 """Dummy store storing blobs to temp directory."""
666 """Dummy store storing blobs to temp directory."""
651
667
652 def __init__(self, repo, url):
668 def __init__(self, repo, url):
653 fullpath = repo.vfs.join(b'lfs', url.path)
669 fullpath = repo.vfs.join(b'lfs', url.path)
654 self.vfs = lfsvfs(fullpath)
670 self.vfs = lfsvfs(fullpath)
655
671
656 def writebatch(self, pointers, fromstore):
672 def writebatch(self, pointers, fromstore):
657 for p in _deduplicate(pointers):
673 for p in _deduplicate(pointers):
658 content = fromstore.read(p.oid(), verify=True)
674 content = fromstore.read(p.oid(), verify=True)
659 with self.vfs(p.oid(), b'wb', atomictemp=True) as fp:
675 with self.vfs(p.oid(), b'wb', atomictemp=True) as fp:
660 fp.write(content)
676 fp.write(content)
661
677
662 def readbatch(self, pointers, tostore):
678 def readbatch(self, pointers, tostore):
663 for p in _deduplicate(pointers):
679 for p in _deduplicate(pointers):
664 with self.vfs(p.oid(), b'rb') as fp:
680 with self.vfs(p.oid(), b'rb') as fp:
665 tostore.download(p.oid(), fp, None)
681 tostore.download(p.oid(), fp, None)
666
682
667
683
668 class _nullremote:
684 class _nullremote:
669 """Null store storing blobs to /dev/null."""
685 """Null store storing blobs to /dev/null."""
670
686
671 def __init__(self, repo, url):
687 def __init__(self, repo, url):
672 pass
688 pass
673
689
674 def writebatch(self, pointers, fromstore):
690 def writebatch(self, pointers, fromstore):
675 pass
691 pass
676
692
677 def readbatch(self, pointers, tostore):
693 def readbatch(self, pointers, tostore):
678 pass
694 pass
679
695
680
696
681 class _promptremote:
697 class _promptremote:
682 """Prompt user to set lfs.url when accessed."""
698 """Prompt user to set lfs.url when accessed."""
683
699
684 def __init__(self, repo, url):
700 def __init__(self, repo, url):
685 pass
701 pass
686
702
687 def writebatch(self, pointers, fromstore, ui=None):
703 def writebatch(self, pointers, fromstore, ui=None):
688 self._prompt()
704 self._prompt()
689
705
690 def readbatch(self, pointers, tostore, ui=None):
706 def readbatch(self, pointers, tostore, ui=None):
691 self._prompt()
707 self._prompt()
692
708
693 def _prompt(self):
709 def _prompt(self):
694 raise error.Abort(_(b'lfs.url needs to be configured'))
710 raise error.Abort(_(b'lfs.url needs to be configured'))
695
711
696
712
697 _storemap = {
713 _storemap = {
698 b'https': _gitlfsremote,
714 b'https': _gitlfsremote,
699 b'http': _gitlfsremote,
715 b'http': _gitlfsremote,
700 b'file': _dummyremote,
716 b'file': _dummyremote,
701 b'null': _nullremote,
717 b'null': _nullremote,
702 None: _promptremote,
718 None: _promptremote,
703 }
719 }
704
720
705
721
706 def _deduplicate(pointers):
722 def _deduplicate(pointers):
707 """Remove any duplicate oids that exist in the list"""
723 """Remove any duplicate oids that exist in the list"""
708 reduced = util.sortdict()
724 reduced = util.sortdict()
709 for p in pointers:
725 for p in pointers:
710 reduced[p.oid()] = p
726 reduced[p.oid()] = p
711 return reduced.values()
727 return reduced.values()
712
728
713
729
714 def _verify(oid, content):
730 def _verify(oid, content):
715 realoid = hex(hashlib.sha256(content).digest())
731 realoid = hex(hashlib.sha256(content).digest())
716 if realoid != oid:
732 if realoid != oid:
717 raise LfsCorruptionError(
733 raise LfsCorruptionError(
718 _(b'detected corrupt lfs object: %s') % oid,
734 _(b'detected corrupt lfs object: %s') % oid,
719 hint=_(b'run hg verify'),
735 hint=_(b'run hg verify'),
720 )
736 )
721
737
722
738
723 def remote(repo, remote=None):
739 def remote(repo, remote=None):
724 """remotestore factory. return a store in _storemap depending on config
740 """remotestore factory. return a store in _storemap depending on config
725
741
726 If ``lfs.url`` is specified, use that remote endpoint. Otherwise, try to
742 If ``lfs.url`` is specified, use that remote endpoint. Otherwise, try to
727 infer the endpoint, based on the remote repository using the same path
743 infer the endpoint, based on the remote repository using the same path
728 adjustments as git. As an extension, 'http' is supported as well so that
744 adjustments as git. As an extension, 'http' is supported as well so that
729 ``hg serve`` works out of the box.
745 ``hg serve`` works out of the box.
730
746
731 https://github.com/git-lfs/git-lfs/blob/master/docs/api/server-discovery.md
747 https://github.com/git-lfs/git-lfs/blob/master/docs/api/server-discovery.md
732 """
748 """
733 lfsurl = repo.ui.config(b'lfs', b'url')
749 lfsurl = repo.ui.config(b'lfs', b'url')
734 url = urlutil.url(lfsurl or b'')
750 url = urlutil.url(lfsurl or b'')
735 if lfsurl is None:
751 if lfsurl is None:
736 if remote:
752 if remote:
737 path = remote
753 path = remote
738 elif util.safehasattr(repo, b'_subtoppath'):
754 elif util.safehasattr(repo, b'_subtoppath'):
739 # The pull command sets this during the optional update phase, which
755 # The pull command sets this during the optional update phase, which
740 # tells exactly where the pull originated, whether 'paths.default'
756 # tells exactly where the pull originated, whether 'paths.default'
741 # or explicit.
757 # or explicit.
742 path = repo._subtoppath
758 path = repo._subtoppath
743 else:
759 else:
744 # TODO: investigate 'paths.remote:lfsurl' style path customization,
760 # TODO: investigate 'paths.remote:lfsurl' style path customization,
745 # and fall back to inferring from 'paths.remote' if unspecified.
761 # and fall back to inferring from 'paths.remote' if unspecified.
746 path = repo.ui.config(b'paths', b'default') or b''
762 path = repo.ui.config(b'paths', b'default') or b''
747
763
748 defaulturl = urlutil.url(path)
764 defaulturl = urlutil.url(path)
749
765
750 # TODO: support local paths as well.
766 # TODO: support local paths as well.
751 # TODO: consider the ssh -> https transformation that git applies
767 # TODO: consider the ssh -> https transformation that git applies
752 if defaulturl.scheme in (b'http', b'https'):
768 if defaulturl.scheme in (b'http', b'https'):
753 if defaulturl.path and defaulturl.path[:-1] != b'/':
769 if defaulturl.path and defaulturl.path[:-1] != b'/':
754 defaulturl.path += b'/'
770 defaulturl.path += b'/'
755 defaulturl.path = (defaulturl.path or b'') + b'.git/info/lfs'
771 defaulturl.path = (defaulturl.path or b'') + b'.git/info/lfs'
756
772
757 url = urlutil.url(bytes(defaulturl))
773 url = urlutil.url(bytes(defaulturl))
758 repo.ui.note(_(b'lfs: assuming remote store: %s\n') % url)
774 repo.ui.note(_(b'lfs: assuming remote store: %s\n') % url)
759
775
760 scheme = url.scheme
776 scheme = url.scheme
761 if scheme not in _storemap:
777 if scheme not in _storemap:
762 raise error.Abort(_(b'lfs: unknown url scheme: %s') % scheme)
778 raise error.Abort(_(b'lfs: unknown url scheme: %s') % scheme)
763 return _storemap[scheme](repo, url)
779 return _storemap[scheme](repo, url)
764
780
765
781
766 class LfsRemoteError(error.StorageError):
782 class LfsRemoteError(error.StorageError):
767 pass
783 pass
768
784
769
785
770 class LfsCorruptionError(error.Abort):
786 class LfsCorruptionError(error.Abort):
771 """Raised when a corrupt blob is detected, aborting an operation
787 """Raised when a corrupt blob is detected, aborting an operation
772
788
773 It exists to allow specialized handling on the server side."""
789 It exists to allow specialized handling on the server side."""
@@ -1,421 +1,421 b''
1 # v2.py - Pure-Python implementation of the dirstate-v2 file format
1 # v2.py - Pure-Python implementation of the dirstate-v2 file format
2 #
2 #
3 # Copyright Mercurial Contributors
3 # Copyright Mercurial Contributors
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8
8
9 import struct
9 import struct
10
10
11 from ..thirdparty import attr
11 from ..thirdparty import attr
12 from .. import error, policy
12 from .. import error, policy
13
13
14 parsers = policy.importmod('parsers')
14 parsers = policy.importmod('parsers')
15
15
16
16
17 # Must match the constant of the same name in
17 # Must match the constant of the same name in
18 # `rust/hg-core/src/dirstate_tree/on_disk.rs`
18 # `rust/hg-core/src/dirstate_tree/on_disk.rs`
19 TREE_METADATA_SIZE = 44
19 TREE_METADATA_SIZE = 44
20 NODE_SIZE = 44
20 NODE_SIZE = 44
21
21
22
22
23 # Must match the `TreeMetadata` Rust struct in
23 # Must match the `TreeMetadata` Rust struct in
24 # `rust/hg-core/src/dirstate_tree/on_disk.rs`. See doc-comments there.
24 # `rust/hg-core/src/dirstate_tree/on_disk.rs`. See doc-comments there.
25 #
25 #
26 # * 4 bytes: start offset of root nodes
26 # * 4 bytes: start offset of root nodes
27 # * 4 bytes: number of root nodes
27 # * 4 bytes: number of root nodes
28 # * 4 bytes: total number of nodes in the tree that have an entry
28 # * 4 bytes: total number of nodes in the tree that have an entry
29 # * 4 bytes: total number of nodes in the tree that have a copy source
29 # * 4 bytes: total number of nodes in the tree that have a copy source
30 # * 4 bytes: number of bytes in the data file that are not used anymore
30 # * 4 bytes: number of bytes in the data file that are not used anymore
31 # * 4 bytes: unused
31 # * 4 bytes: unused
32 # * 20 bytes: SHA-1 hash of ignore patterns
32 # * 20 bytes: SHA-1 hash of ignore patterns
33 TREE_METADATA = struct.Struct('>LLLLL4s20s')
33 TREE_METADATA = struct.Struct('>LLLLL4s20s')
34
34
35
35
36 # Must match the `Node` Rust struct in
36 # Must match the `Node` Rust struct in
37 # `rust/hg-core/src/dirstate_tree/on_disk.rs`. See doc-comments there.
37 # `rust/hg-core/src/dirstate_tree/on_disk.rs`. See doc-comments there.
38 #
38 #
39 # * 4 bytes: start offset of full path
39 # * 4 bytes: start offset of full path
40 # * 2 bytes: length of the full path
40 # * 2 bytes: length of the full path
41 # * 2 bytes: length within the full path before its "base name"
41 # * 2 bytes: length within the full path before its "base name"
42 # * 4 bytes: start offset of the copy source if any, or zero for no copy source
42 # * 4 bytes: start offset of the copy source if any, or zero for no copy source
43 # * 2 bytes: length of the copy source if any, or unused
43 # * 2 bytes: length of the copy source if any, or unused
44 # * 4 bytes: start offset of child nodes
44 # * 4 bytes: start offset of child nodes
45 # * 4 bytes: number of child nodes
45 # * 4 bytes: number of child nodes
46 # * 4 bytes: number of descendant nodes that have an entry
46 # * 4 bytes: number of descendant nodes that have an entry
47 # * 4 bytes: number of descendant nodes that have a "tracked" state
47 # * 4 bytes: number of descendant nodes that have a "tracked" state
48 # * 1 byte: flags
48 # * 1 byte: flags
49 # * 4 bytes: expected size
49 # * 4 bytes: expected size
50 # * 4 bytes: mtime seconds
50 # * 4 bytes: mtime seconds
51 # * 4 bytes: mtime nanoseconds
51 # * 4 bytes: mtime nanoseconds
52 NODE = struct.Struct('>LHHLHLLLLHlll')
52 NODE = struct.Struct('>LHHLHLLLLHlll')
53
53
54
54
55 assert TREE_METADATA_SIZE == TREE_METADATA.size
55 assert TREE_METADATA_SIZE == TREE_METADATA.size
56 assert NODE_SIZE == NODE.size
56 assert NODE_SIZE == NODE.size
57
57
58 # match constant in mercurial/pure/parsers.py
58 # match constant in mercurial/pure/parsers.py
59 DIRSTATE_V2_DIRECTORY = 1 << 5
59 DIRSTATE_V2_DIRECTORY = 1 << 13
60
60
61
61
62 def parse_dirstate(map, copy_map, data, tree_metadata):
62 def parse_dirstate(map, copy_map, data, tree_metadata):
63 """parse a full v2-dirstate from a binary data into dictionnaries:
63 """parse a full v2-dirstate from a binary data into dictionaries:
64
64
65 - map: a {path: entry} mapping that will be filled
65 - map: a {path: entry} mapping that will be filled
66 - copy_map: a {path: copy-source} mapping that will be filled
66 - copy_map: a {path: copy-source} mapping that will be filled
67 - data: a binary blob contains v2 nodes data
67 - data: a binary blob contains v2 nodes data
68 - tree_metadata:: a binary blob of the top level node (from the docket)
68 - tree_metadata:: a binary blob of the top level node (from the docket)
69 """
69 """
70 (
70 (
71 root_nodes_start,
71 root_nodes_start,
72 root_nodes_len,
72 root_nodes_len,
73 _nodes_with_entry_count,
73 _nodes_with_entry_count,
74 _nodes_with_copy_source_count,
74 _nodes_with_copy_source_count,
75 _unreachable_bytes,
75 _unreachable_bytes,
76 _unused,
76 _unused,
77 _ignore_patterns_hash,
77 _ignore_patterns_hash,
78 ) = TREE_METADATA.unpack(tree_metadata)
78 ) = TREE_METADATA.unpack(tree_metadata)
79 parse_nodes(map, copy_map, data, root_nodes_start, root_nodes_len)
79 parse_nodes(map, copy_map, data, root_nodes_start, root_nodes_len)
80
80
81
81
82 def parse_nodes(map, copy_map, data, start, len):
82 def parse_nodes(map, copy_map, data, start, len):
83 """parse <len> nodes from <data> starting at offset <start>
83 """parse <len> nodes from <data> starting at offset <start>
84
84
85 This is used by parse_dirstate to recursively fill `map` and `copy_map`.
85 This is used by parse_dirstate to recursively fill `map` and `copy_map`.
86
86
87 All directory specific information is ignored and do not need any
87 All directory specific information is ignored and do not need any
88 processing (DIRECTORY, ALL_UNKNOWN_RECORDED, ALL_IGNORED_RECORDED)
88 processing (DIRECTORY, ALL_UNKNOWN_RECORDED, ALL_IGNORED_RECORDED)
89 """
89 """
90 for i in range(len):
90 for i in range(len):
91 node_start = start + NODE_SIZE * i
91 node_start = start + NODE_SIZE * i
92 node_bytes = slice_with_len(data, node_start, NODE_SIZE)
92 node_bytes = slice_with_len(data, node_start, NODE_SIZE)
93 (
93 (
94 path_start,
94 path_start,
95 path_len,
95 path_len,
96 _basename_start,
96 _basename_start,
97 copy_source_start,
97 copy_source_start,
98 copy_source_len,
98 copy_source_len,
99 children_start,
99 children_start,
100 children_count,
100 children_count,
101 _descendants_with_entry_count,
101 _descendants_with_entry_count,
102 _tracked_descendants_count,
102 _tracked_descendants_count,
103 flags,
103 flags,
104 size,
104 size,
105 mtime_s,
105 mtime_s,
106 mtime_ns,
106 mtime_ns,
107 ) = NODE.unpack(node_bytes)
107 ) = NODE.unpack(node_bytes)
108
108
109 # Parse child nodes of this node recursively
109 # Parse child nodes of this node recursively
110 parse_nodes(map, copy_map, data, children_start, children_count)
110 parse_nodes(map, copy_map, data, children_start, children_count)
111
111
112 item = parsers.DirstateItem.from_v2_data(flags, size, mtime_s, mtime_ns)
112 item = parsers.DirstateItem.from_v2_data(flags, size, mtime_s, mtime_ns)
113 if not item.any_tracked:
113 if not item.any_tracked:
114 continue
114 continue
115 path = slice_with_len(data, path_start, path_len)
115 path = slice_with_len(data, path_start, path_len)
116 map[path] = item
116 map[path] = item
117 if copy_source_start:
117 if copy_source_start:
118 copy_map[path] = slice_with_len(
118 copy_map[path] = slice_with_len(
119 data, copy_source_start, copy_source_len
119 data, copy_source_start, copy_source_len
120 )
120 )
121
121
122
122
123 def slice_with_len(data, start, len):
123 def slice_with_len(data, start, len):
124 return data[start : start + len]
124 return data[start : start + len]
125
125
126
126
127 @attr.s
127 @attr.s
128 class Node:
128 class Node:
129 path = attr.ib()
129 path = attr.ib()
130 entry = attr.ib()
130 entry = attr.ib()
131 parent = attr.ib(default=None)
131 parent = attr.ib(default=None)
132 children_count = attr.ib(default=0)
132 children_count = attr.ib(default=0)
133 children_offset = attr.ib(default=0)
133 children_offset = attr.ib(default=0)
134 descendants_with_entry = attr.ib(default=0)
134 descendants_with_entry = attr.ib(default=0)
135 tracked_descendants = attr.ib(default=0)
135 tracked_descendants = attr.ib(default=0)
136
136
137 def pack(self, copy_map, paths_offset):
137 def pack(self, copy_map, paths_offset):
138 path = self.path
138 path = self.path
139 copy = copy_map.get(path)
139 copy = copy_map.get(path)
140 entry = self.entry
140 entry = self.entry
141
141
142 path_start = paths_offset
142 path_start = paths_offset
143 path_len = len(path)
143 path_len = len(path)
144 basename_start = path.rfind(b'/') + 1 # 0 if rfind returns -1
144 basename_start = path.rfind(b'/') + 1 # 0 if rfind returns -1
145 if copy is not None:
145 if copy is not None:
146 copy_source_start = paths_offset + len(path)
146 copy_source_start = paths_offset + len(path)
147 copy_source_len = len(copy)
147 copy_source_len = len(copy)
148 else:
148 else:
149 copy_source_start = 0
149 copy_source_start = 0
150 copy_source_len = 0
150 copy_source_len = 0
151 if entry is not None:
151 if entry is not None:
152 flags, size, mtime_s, mtime_ns = entry.v2_data()
152 flags, size, mtime_s, mtime_ns = entry.v2_data()
153 else:
153 else:
154 # There are no mtime-cached directories in the Python implementation
154 # There are no mtime-cached directories in the Python implementation
155 flags = DIRSTATE_V2_DIRECTORY
155 flags = DIRSTATE_V2_DIRECTORY
156 size = 0
156 size = 0
157 mtime_s = 0
157 mtime_s = 0
158 mtime_ns = 0
158 mtime_ns = 0
159 return NODE.pack(
159 return NODE.pack(
160 path_start,
160 path_start,
161 path_len,
161 path_len,
162 basename_start,
162 basename_start,
163 copy_source_start,
163 copy_source_start,
164 copy_source_len,
164 copy_source_len,
165 self.children_offset,
165 self.children_offset,
166 self.children_count,
166 self.children_count,
167 self.descendants_with_entry,
167 self.descendants_with_entry,
168 self.tracked_descendants,
168 self.tracked_descendants,
169 flags,
169 flags,
170 size,
170 size,
171 mtime_s,
171 mtime_s,
172 mtime_ns,
172 mtime_ns,
173 )
173 )
174
174
175
175
176 def pack_dirstate(map, copy_map):
176 def pack_dirstate(map, copy_map):
177 """
177 """
178 Pack `map` and `copy_map` into the dirstate v2 binary format and return
178 Pack `map` and `copy_map` into the dirstate v2 binary format and return
179 the bytearray.
179 the tuple of (data, metadata) bytearrays.
180
180
181 The on-disk format expects a tree-like structure where the leaves are
181 The on-disk format expects a tree-like structure where the leaves are
182 written first (and sorted per-directory), going up levels until the root
182 written first (and sorted per-directory), going up levels until the root
183 node and writing that one to the docket. See more details on the on-disk
183 node and writing that one to the docket. See more details on the on-disk
184 format in `mercurial/helptext/internals/dirstate-v2`.
184 format in `mercurial/helptext/internals/dirstate-v2`.
185
185
186 Since both `map` and `copy_map` are flat dicts we need to figure out the
186 Since both `map` and `copy_map` are flat dicts we need to figure out the
187 hierarchy. This algorithm does so without having to build the entire tree
187 hierarchy. This algorithm does so without having to build the entire tree
188 in-memory: it only keeps the minimum number of nodes around to satisfy the
188 in-memory: it only keeps the minimum number of nodes around to satisfy the
189 format.
189 format.
190
190
191 # Algorithm explanation
191 # Algorithm explanation
192
192
193 This explanation does not talk about the different counters for tracked
193 This explanation does not talk about the different counters for tracked
194 descendents and storing the copies, but that work is pretty simple once this
194 descendants and storing the copies, but that work is pretty simple once this
195 algorithm is in place.
195 algorithm is in place.
196
196
197 ## Building a subtree
197 ## Building a subtree
198
198
199 First, sort `map`: this makes it so the leaves of the tree are contiguous
199 First, sort `map`: this makes it so the leaves of the tree are contiguous
200 per directory (i.e. a/b/c and a/b/d will be next to each other in the list),
200 per directory (i.e. a/b/c and a/b/d will be next to each other in the list),
201 and enables us to use the ordering of folders to have a "cursor" of the
201 and enables us to use the ordering of folders to have a "cursor" of the
202 current folder we're in without ever going twice in the same branch of the
202 current folder we're in without ever going twice in the same branch of the
203 tree. The cursor is a node that remembers its parent and any information
203 tree. The cursor is a node that remembers its parent and any information
204 relevant to the format (see the `Node` class), building the relevant part
204 relevant to the format (see the `Node` class), building the relevant part
205 of the tree lazily.
205 of the tree lazily.
206 Then, for each file in `map`, move the cursor into the tree to the
206 Then, for each file in `map`, move the cursor into the tree to the
207 corresponding folder of the file: for example, if the very first file
207 corresponding folder of the file: for example, if the very first file
208 is "a/b/c", we start from `Node[""]`, create `Node["a"]` which points to
208 is "a/b/c", we start from `Node[""]`, create `Node["a"]` which points to
209 its parent `Node[""]`, then create `Node["a/b"]`, which points to its parent
209 its parent `Node[""]`, then create `Node["a/b"]`, which points to its parent
210 `Node["a"]`. These nodes are kept around in a stack.
210 `Node["a"]`. These nodes are kept around in a stack.
211 If the next file in `map` is in the same subtree ("a/b/d" or "a/b/e/f"), we
211 If the next file in `map` is in the same subtree ("a/b/d" or "a/b/e/f"), we
212 add it to the stack and keep looping with the same logic of creating the
212 add it to the stack and keep looping with the same logic of creating the
213 tree nodes as needed. If however the next file in `map` is *not* in the same
213 tree nodes as needed. If however the next file in `map` is *not* in the same
214 subtree ("a/other", if we're still in the "a/b" folder), then we know that
214 subtree ("a/other", if we're still in the "a/b" folder), then we know that
215 the subtree we're in is complete.
215 the subtree we're in is complete.
216
216
217 ## Writing the subtree
217 ## Writing the subtree
218
218
219 We have the entire subtree in the stack, so we start writing it to disk
219 We have the entire subtree in the stack, so we start writing it to disk
220 folder by folder. The way we write a folder is to pop the stack into a list
220 folder by folder. The way we write a folder is to pop the stack into a list
221 until the folder changes, revert this list of direct children (to satisfy
221 until the folder changes, revert this list of direct children (to satisfy
222 the format requirement that children be sorted). This process repeats until
222 the format requirement that children be sorted). This process repeats until
223 we hit the "other" subtree.
223 we hit the "other" subtree.
224
224
225 An example:
225 An example:
226 a
226 a
227 dir1/b
227 dir1/b
228 dir1/c
228 dir1/c
229 dir2/dir3/d
229 dir2/dir3/d
230 dir2/dir3/e
230 dir2/dir3/e
231 dir2/f
231 dir2/f
232
232
233 Would have us:
233 Would have us:
234 - add to the stack until "dir2/dir3/e"
234 - add to the stack until "dir2/dir3/e"
235 - realize that "dir2/f" is in a different subtree
235 - realize that "dir2/f" is in a different subtree
236 - pop "dir2/dir3/e", "dir2/dir3/d", reverse them so they're sorted and
236 - pop "dir2/dir3/e", "dir2/dir3/d", reverse them so they're sorted and
237 pack them since the next entry is "dir2/dir3"
237 pack them since the next entry is "dir2/dir3"
238 - go back up to "dir2"
238 - go back up to "dir2"
239 - add "dir2/f" to the stack
239 - add "dir2/f" to the stack
240 - realize we're done with the map
240 - realize we're done with the map
241 - pop "dir2/f", "dir2/dir3" from the stack, reverse and pack them
241 - pop "dir2/f", "dir2/dir3" from the stack, reverse and pack them
242 - go up to the root node, do the same to write "a", "dir1" and "dir2" in
242 - go up to the root node, do the same to write "a", "dir1" and "dir2" in
243 that order
243 that order
244
244
245 ## Special case for the root node
245 ## Special case for the root node
246
246
247 The root node is not serialized in the format, but its information is
247 The root node is not serialized in the format, but its information is
248 written to the docket. Again, see more details on the on-disk format in
248 written to the docket. Again, see more details on the on-disk format in
249 `mercurial/helptext/internals/dirstate-v2`.
249 `mercurial/helptext/internals/dirstate-v2`.
250 """
250 """
251 data = bytearray()
251 data = bytearray()
252 root_nodes_start = 0
252 root_nodes_start = 0
253 root_nodes_len = 0
253 root_nodes_len = 0
254 nodes_with_entry_count = 0
254 nodes_with_entry_count = 0
255 nodes_with_copy_source_count = 0
255 nodes_with_copy_source_count = 0
256 # Will always be 0 since this implementation always re-writes everything
256 # Will always be 0 since this implementation always re-writes everything
257 # to disk
257 # to disk
258 unreachable_bytes = 0
258 unreachable_bytes = 0
259 unused = b'\x00' * 4
259 unused = b'\x00' * 4
260 # This is an optimization that's only useful for the Rust implementation
260 # This is an optimization that's only useful for the Rust implementation
261 ignore_patterns_hash = b'\x00' * 20
261 ignore_patterns_hash = b'\x00' * 20
262
262
263 if len(map) == 0:
263 if len(map) == 0:
264 tree_metadata = TREE_METADATA.pack(
264 tree_metadata = TREE_METADATA.pack(
265 root_nodes_start,
265 root_nodes_start,
266 root_nodes_len,
266 root_nodes_len,
267 nodes_with_entry_count,
267 nodes_with_entry_count,
268 nodes_with_copy_source_count,
268 nodes_with_copy_source_count,
269 unreachable_bytes,
269 unreachable_bytes,
270 unused,
270 unused,
271 ignore_patterns_hash,
271 ignore_patterns_hash,
272 )
272 )
273 return data, tree_metadata
273 return data, tree_metadata
274
274
275 sorted_map = sorted(map.items(), key=lambda x: x[0])
275 sorted_map = sorted(map.items(), key=lambda x: x[0].split(b"/"))
276
276
277 # Use a stack to not have to only remember the nodes we currently need
277 # Use a stack to have to only remember the nodes we currently need
278 # instead of building the entire tree in memory
278 # instead of building the entire tree in memory
279 stack = []
279 stack = []
280 current_node = Node(b"", None)
280 current_node = Node(b"", None)
281 stack.append(current_node)
281 stack.append(current_node)
282
282
283 for index, (path, entry) in enumerate(sorted_map, 1):
283 for index, (path, entry) in enumerate(sorted_map, 1):
284 nodes_with_entry_count += 1
284 nodes_with_entry_count += 1
285 if path in copy_map:
285 if path in copy_map:
286 nodes_with_copy_source_count += 1
286 nodes_with_copy_source_count += 1
287 current_folder = get_folder(path)
287 current_folder = get_folder(path)
288 current_node = move_to_correct_node_in_tree(
288 current_node = move_to_correct_node_in_tree(
289 current_folder, current_node, stack
289 current_folder, current_node, stack
290 )
290 )
291
291
292 current_node.children_count += 1
292 current_node.children_count += 1
293 # Entries from `map` are never `None`
293 # Entries from `map` are never `None`
294 if entry.tracked:
294 if entry.tracked:
295 current_node.tracked_descendants += 1
295 current_node.tracked_descendants += 1
296 current_node.descendants_with_entry += 1
296 current_node.descendants_with_entry += 1
297 stack.append(Node(path, entry, current_node))
297 stack.append(Node(path, entry, current_node))
298
298
299 should_pack = True
299 should_pack = True
300 next_path = None
300 next_path = None
301 if index < len(sorted_map):
301 if index < len(sorted_map):
302 # Determine if the next entry is in the same sub-tree, if so don't
302 # Determine if the next entry is in the same sub-tree, if so don't
303 # pack yet
303 # pack yet
304 next_path = sorted_map[index][0]
304 next_path = sorted_map[index][0]
305 should_pack = not is_ancestor(next_path, current_folder)
305 should_pack = not is_ancestor(next_path, current_folder)
306 if should_pack:
306 if should_pack:
307 pack_directory_children(current_node, copy_map, data, stack)
307 pack_directory_children(current_node, copy_map, data, stack)
308 while stack and current_node.path != b"":
308 while stack and current_node.path != b"":
309 # Go up the tree and write until we reach the folder of the next
309 # Go up the tree and write until we reach the folder of the next
310 # entry (if any, otherwise the root)
310 # entry (if any, otherwise the root)
311 parent = current_node.parent
311 parent = current_node.parent
312 in_ancestor_of_next_path = next_path is not None and (
312 in_ancestor_of_next_path = next_path is not None and (
313 is_ancestor(next_path, get_folder(stack[-1].path))
313 is_ancestor(next_path, get_folder(stack[-1].path))
314 )
314 )
315 if parent is None or in_ancestor_of_next_path:
315 if parent is None or in_ancestor_of_next_path:
316 break
316 break
317 pack_directory_children(parent, copy_map, data, stack)
317 pack_directory_children(parent, copy_map, data, stack)
318 current_node = parent
318 current_node = parent
319
319
320 # Special case for the root node since we don't write it to disk, only its
320 # Special case for the root node since we don't write it to disk, only its
321 # children to the docket
321 # children to the docket
322 current_node = stack.pop()
322 current_node = stack.pop()
323 assert current_node.path == b"", current_node.path
323 assert current_node.path == b"", current_node.path
324 assert len(stack) == 0, len(stack)
324 assert len(stack) == 0, len(stack)
325
325
326 tree_metadata = TREE_METADATA.pack(
326 tree_metadata = TREE_METADATA.pack(
327 current_node.children_offset,
327 current_node.children_offset,
328 current_node.children_count,
328 current_node.children_count,
329 nodes_with_entry_count,
329 nodes_with_entry_count,
330 nodes_with_copy_source_count,
330 nodes_with_copy_source_count,
331 unreachable_bytes,
331 unreachable_bytes,
332 unused,
332 unused,
333 ignore_patterns_hash,
333 ignore_patterns_hash,
334 )
334 )
335
335
336 return data, tree_metadata
336 return data, tree_metadata
337
337
338
338
339 def get_folder(path):
339 def get_folder(path):
340 """
340 """
341 Return the folder of the path that's given, an empty string for root paths.
341 Return the folder of the path that's given, an empty string for root paths.
342 """
342 """
343 return path.rsplit(b'/', 1)[0] if b'/' in path else b''
343 return path.rsplit(b'/', 1)[0] if b'/' in path else b''
344
344
345
345
346 def is_ancestor(path, maybe_ancestor):
346 def is_ancestor(path, maybe_ancestor):
347 """Returns whether `maybe_ancestor` is an ancestor of `path`.
347 """Returns whether `maybe_ancestor` is an ancestor of `path`.
348
348
349 >>> is_ancestor(b"a", b"")
349 >>> is_ancestor(b"a", b"")
350 True
350 True
351 >>> is_ancestor(b"a/b/c", b"a/b/c")
351 >>> is_ancestor(b"a/b/c", b"a/b/c")
352 False
352 False
353 >>> is_ancestor(b"hgext3rd/__init__.py", b"hgext")
353 >>> is_ancestor(b"hgext3rd/__init__.py", b"hgext")
354 False
354 False
355 >>> is_ancestor(b"hgext3rd/__init__.py", b"hgext3rd")
355 >>> is_ancestor(b"hgext3rd/__init__.py", b"hgext3rd")
356 True
356 True
357 """
357 """
358 if maybe_ancestor == b"":
358 if maybe_ancestor == b"":
359 return True
359 return True
360 if path <= maybe_ancestor:
360 if path <= maybe_ancestor:
361 return False
361 return False
362 path_components = path.split(b"/")
362 path_components = path.split(b"/")
363 ancestor_components = maybe_ancestor.split(b"/")
363 ancestor_components = maybe_ancestor.split(b"/")
364 return all(c == o for c, o in zip(path_components, ancestor_components))
364 return all(c == o for c, o in zip(path_components, ancestor_components))
365
365
366
366
367 def move_to_correct_node_in_tree(target_folder, current_node, stack):
367 def move_to_correct_node_in_tree(target_folder, current_node, stack):
368 """
368 """
369 Move inside the dirstate node tree to the node corresponding to
369 Move inside the dirstate node tree to the node corresponding to
370 `target_folder`, creating the missing nodes along the way if needed.
370 `target_folder`, creating the missing nodes along the way if needed.
371 """
371 """
372 while target_folder != current_node.path:
372 while target_folder != current_node.path:
373 if is_ancestor(target_folder, current_node.path):
373 if is_ancestor(target_folder, current_node.path):
374 # We need to go down a folder
374 # We need to go down a folder
375 prefix = target_folder[len(current_node.path) :].lstrip(b'/')
375 prefix = target_folder[len(current_node.path) :].lstrip(b'/')
376 subfolder_name = prefix.split(b'/', 1)[0]
376 subfolder_name = prefix.split(b'/', 1)[0]
377 if current_node.path:
377 if current_node.path:
378 subfolder_path = current_node.path + b'/' + subfolder_name
378 subfolder_path = current_node.path + b'/' + subfolder_name
379 else:
379 else:
380 subfolder_path = subfolder_name
380 subfolder_path = subfolder_name
381 next_node = stack[-1]
381 next_node = stack[-1]
382 if next_node.path == target_folder:
382 if next_node.path == target_folder:
383 # This folder is now a file and only contains removed entries
383 # This folder is now a file and only contains removed entries
384 # merge with the last node
384 # merge with the last node
385 current_node = next_node
385 current_node = next_node
386 else:
386 else:
387 current_node.children_count += 1
387 current_node.children_count += 1
388 current_node = Node(subfolder_path, None, current_node)
388 current_node = Node(subfolder_path, None, current_node)
389 stack.append(current_node)
389 stack.append(current_node)
390 else:
390 else:
391 # We need to go up a folder
391 # We need to go up a folder
392 current_node = current_node.parent
392 current_node = current_node.parent
393 return current_node
393 return current_node
394
394
395
395
396 def pack_directory_children(node, copy_map, data, stack):
396 def pack_directory_children(node, copy_map, data, stack):
397 """
397 """
398 Write the binary representation of the direct sorted children of `node` to
398 Write the binary representation of the direct sorted children of `node` to
399 `data`
399 `data`
400 """
400 """
401 direct_children = []
401 direct_children = []
402
402
403 while stack[-1].path != b"" and get_folder(stack[-1].path) == node.path:
403 while stack[-1].path != b"" and get_folder(stack[-1].path) == node.path:
404 direct_children.append(stack.pop())
404 direct_children.append(stack.pop())
405 if not direct_children:
405 if not direct_children:
406 raise error.ProgrammingError(b"no direct children for %r" % node.path)
406 raise error.ProgrammingError(b"no direct children for %r" % node.path)
407
407
408 # Reverse the stack to get the correct sorted order
408 # Reverse the stack to get the correct sorted order
409 direct_children.reverse()
409 direct_children.reverse()
410 packed_children = bytearray()
410 packed_children = bytearray()
411 # Write the paths to `data`. Pack child nodes but don't write them yet
411 # Write the paths to `data`. Pack child nodes but don't write them yet
412 for child in direct_children:
412 for child in direct_children:
413 packed = child.pack(copy_map=copy_map, paths_offset=len(data))
413 packed = child.pack(copy_map=copy_map, paths_offset=len(data))
414 packed_children.extend(packed)
414 packed_children.extend(packed)
415 data.extend(child.path)
415 data.extend(child.path)
416 data.extend(copy_map.get(child.path, b""))
416 data.extend(copy_map.get(child.path, b""))
417 node.tracked_descendants += child.tracked_descendants
417 node.tracked_descendants += child.tracked_descendants
418 node.descendants_with_entry += child.descendants_with_entry
418 node.descendants_with_entry += child.descendants_with_entry
419 # Write the fixed-size child nodes all together
419 # Write the fixed-size child nodes all together
420 node.children_offset = len(data)
420 node.children_offset = len(data)
421 data.extend(packed_children)
421 data.extend(packed_children)
@@ -1,1180 +1,1181 b''
1 # help.py - help data for mercurial
1 # help.py - help data for mercurial
2 #
2 #
3 # Copyright 2006 Olivia Mackall <olivia@selenic.com>
3 # Copyright 2006 Olivia Mackall <olivia@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8
8
9 import itertools
9 import itertools
10 import re
10 import re
11 import textwrap
11 import textwrap
12
12
13 from .i18n import (
13 from .i18n import (
14 _,
14 _,
15 gettext,
15 gettext,
16 )
16 )
17 from .pycompat import getattr
17 from .pycompat import getattr
18 from . import (
18 from . import (
19 cmdutil,
19 cmdutil,
20 encoding,
20 encoding,
21 error,
21 error,
22 extensions,
22 extensions,
23 fancyopts,
23 fancyopts,
24 filemerge,
24 filemerge,
25 fileset,
25 fileset,
26 minirst,
26 minirst,
27 pycompat,
27 pycompat,
28 registrar,
28 registrar,
29 revset,
29 revset,
30 templatefilters,
30 templatefilters,
31 templatefuncs,
31 templatefuncs,
32 templatekw,
32 templatekw,
33 ui as uimod,
33 ui as uimod,
34 util,
34 util,
35 )
35 )
36 from .hgweb import webcommands
36 from .hgweb import webcommands
37 from .utils import (
37 from .utils import (
38 compression,
38 compression,
39 resourceutil,
39 resourceutil,
40 stringutil,
40 stringutil,
41 )
41 )
42
42
43 _exclkeywords = {
43 _exclkeywords = {
44 b"(ADVANCED)",
44 b"(ADVANCED)",
45 b"(DEPRECATED)",
45 b"(DEPRECATED)",
46 b"(EXPERIMENTAL)",
46 b"(EXPERIMENTAL)",
47 # i18n: "(ADVANCED)" is a keyword, must be translated consistently
47 # i18n: "(ADVANCED)" is a keyword, must be translated consistently
48 _(b"(ADVANCED)"),
48 _(b"(ADVANCED)"),
49 # i18n: "(DEPRECATED)" is a keyword, must be translated consistently
49 # i18n: "(DEPRECATED)" is a keyword, must be translated consistently
50 _(b"(DEPRECATED)"),
50 _(b"(DEPRECATED)"),
51 # i18n: "(EXPERIMENTAL)" is a keyword, must be translated consistently
51 # i18n: "(EXPERIMENTAL)" is a keyword, must be translated consistently
52 _(b"(EXPERIMENTAL)"),
52 _(b"(EXPERIMENTAL)"),
53 }
53 }
54
54
55 # The order in which command categories will be displayed.
55 # The order in which command categories will be displayed.
56 # Extensions with custom categories should insert them into this list
56 # Extensions with custom categories should insert them into this list
57 # after/before the appropriate item, rather than replacing the list or
57 # after/before the appropriate item, rather than replacing the list or
58 # assuming absolute positions.
58 # assuming absolute positions.
59 CATEGORY_ORDER = [
59 CATEGORY_ORDER = [
60 registrar.command.CATEGORY_REPO_CREATION,
60 registrar.command.CATEGORY_REPO_CREATION,
61 registrar.command.CATEGORY_REMOTE_REPO_MANAGEMENT,
61 registrar.command.CATEGORY_REMOTE_REPO_MANAGEMENT,
62 registrar.command.CATEGORY_COMMITTING,
62 registrar.command.CATEGORY_COMMITTING,
63 registrar.command.CATEGORY_CHANGE_MANAGEMENT,
63 registrar.command.CATEGORY_CHANGE_MANAGEMENT,
64 registrar.command.CATEGORY_CHANGE_ORGANIZATION,
64 registrar.command.CATEGORY_CHANGE_ORGANIZATION,
65 registrar.command.CATEGORY_FILE_CONTENTS,
65 registrar.command.CATEGORY_FILE_CONTENTS,
66 registrar.command.CATEGORY_CHANGE_NAVIGATION,
66 registrar.command.CATEGORY_CHANGE_NAVIGATION,
67 registrar.command.CATEGORY_WORKING_DIRECTORY,
67 registrar.command.CATEGORY_WORKING_DIRECTORY,
68 registrar.command.CATEGORY_IMPORT_EXPORT,
68 registrar.command.CATEGORY_IMPORT_EXPORT,
69 registrar.command.CATEGORY_MAINTENANCE,
69 registrar.command.CATEGORY_MAINTENANCE,
70 registrar.command.CATEGORY_HELP,
70 registrar.command.CATEGORY_HELP,
71 registrar.command.CATEGORY_MISC,
71 registrar.command.CATEGORY_MISC,
72 registrar.command.CATEGORY_NONE,
72 registrar.command.CATEGORY_NONE,
73 ]
73 ]
74
74
75 # Human-readable category names. These are translated.
75 # Human-readable category names. These are translated.
76 # Extensions with custom categories should add their names here.
76 # Extensions with custom categories should add their names here.
77 CATEGORY_NAMES = {
77 CATEGORY_NAMES = {
78 registrar.command.CATEGORY_REPO_CREATION: b'Repository creation',
78 registrar.command.CATEGORY_REPO_CREATION: b'Repository creation',
79 registrar.command.CATEGORY_REMOTE_REPO_MANAGEMENT: b'Remote repository management',
79 registrar.command.CATEGORY_REMOTE_REPO_MANAGEMENT: b'Remote repository management',
80 registrar.command.CATEGORY_COMMITTING: b'Change creation',
80 registrar.command.CATEGORY_COMMITTING: b'Change creation',
81 registrar.command.CATEGORY_CHANGE_NAVIGATION: b'Change navigation',
81 registrar.command.CATEGORY_CHANGE_NAVIGATION: b'Change navigation',
82 registrar.command.CATEGORY_CHANGE_MANAGEMENT: b'Change manipulation',
82 registrar.command.CATEGORY_CHANGE_MANAGEMENT: b'Change manipulation',
83 registrar.command.CATEGORY_CHANGE_ORGANIZATION: b'Change organization',
83 registrar.command.CATEGORY_CHANGE_ORGANIZATION: b'Change organization',
84 registrar.command.CATEGORY_WORKING_DIRECTORY: b'Working directory management',
84 registrar.command.CATEGORY_WORKING_DIRECTORY: b'Working directory management',
85 registrar.command.CATEGORY_FILE_CONTENTS: b'File content management',
85 registrar.command.CATEGORY_FILE_CONTENTS: b'File content management',
86 registrar.command.CATEGORY_IMPORT_EXPORT: b'Change import/export',
86 registrar.command.CATEGORY_IMPORT_EXPORT: b'Change import/export',
87 registrar.command.CATEGORY_MAINTENANCE: b'Repository maintenance',
87 registrar.command.CATEGORY_MAINTENANCE: b'Repository maintenance',
88 registrar.command.CATEGORY_HELP: b'Help',
88 registrar.command.CATEGORY_HELP: b'Help',
89 registrar.command.CATEGORY_MISC: b'Miscellaneous commands',
89 registrar.command.CATEGORY_MISC: b'Miscellaneous commands',
90 registrar.command.CATEGORY_NONE: b'Uncategorized commands',
90 registrar.command.CATEGORY_NONE: b'Uncategorized commands',
91 }
91 }
92
92
93 # Topic categories.
93 # Topic categories.
94 TOPIC_CATEGORY_IDS = b'ids'
94 TOPIC_CATEGORY_IDS = b'ids'
95 TOPIC_CATEGORY_OUTPUT = b'output'
95 TOPIC_CATEGORY_OUTPUT = b'output'
96 TOPIC_CATEGORY_CONFIG = b'config'
96 TOPIC_CATEGORY_CONFIG = b'config'
97 TOPIC_CATEGORY_CONCEPTS = b'concepts'
97 TOPIC_CATEGORY_CONCEPTS = b'concepts'
98 TOPIC_CATEGORY_MISC = b'misc'
98 TOPIC_CATEGORY_MISC = b'misc'
99 TOPIC_CATEGORY_NONE = b'none'
99 TOPIC_CATEGORY_NONE = b'none'
100
100
101 # The order in which topic categories will be displayed.
101 # The order in which topic categories will be displayed.
102 # Extensions with custom categories should insert them into this list
102 # Extensions with custom categories should insert them into this list
103 # after/before the appropriate item, rather than replacing the list or
103 # after/before the appropriate item, rather than replacing the list or
104 # assuming absolute positions.
104 # assuming absolute positions.
105 TOPIC_CATEGORY_ORDER = [
105 TOPIC_CATEGORY_ORDER = [
106 TOPIC_CATEGORY_IDS,
106 TOPIC_CATEGORY_IDS,
107 TOPIC_CATEGORY_OUTPUT,
107 TOPIC_CATEGORY_OUTPUT,
108 TOPIC_CATEGORY_CONFIG,
108 TOPIC_CATEGORY_CONFIG,
109 TOPIC_CATEGORY_CONCEPTS,
109 TOPIC_CATEGORY_CONCEPTS,
110 TOPIC_CATEGORY_MISC,
110 TOPIC_CATEGORY_MISC,
111 TOPIC_CATEGORY_NONE,
111 TOPIC_CATEGORY_NONE,
112 ]
112 ]
113
113
114 # Human-readable topic category names. These are translated.
114 # Human-readable topic category names. These are translated.
115 TOPIC_CATEGORY_NAMES = {
115 TOPIC_CATEGORY_NAMES = {
116 TOPIC_CATEGORY_IDS: b'Mercurial identifiers',
116 TOPIC_CATEGORY_IDS: b'Mercurial identifiers',
117 TOPIC_CATEGORY_OUTPUT: b'Mercurial output',
117 TOPIC_CATEGORY_OUTPUT: b'Mercurial output',
118 TOPIC_CATEGORY_CONFIG: b'Mercurial configuration',
118 TOPIC_CATEGORY_CONFIG: b'Mercurial configuration',
119 TOPIC_CATEGORY_CONCEPTS: b'Concepts',
119 TOPIC_CATEGORY_CONCEPTS: b'Concepts',
120 TOPIC_CATEGORY_MISC: b'Miscellaneous',
120 TOPIC_CATEGORY_MISC: b'Miscellaneous',
121 TOPIC_CATEGORY_NONE: b'Uncategorized topics',
121 TOPIC_CATEGORY_NONE: b'Uncategorized topics',
122 }
122 }
123
123
124
124
125 def listexts(header, exts, indent=1, showdeprecated=False):
125 def listexts(header, exts, indent=1, showdeprecated=False):
126 '''return a text listing of the given extensions'''
126 '''return a text listing of the given extensions'''
127 rst = []
127 rst = []
128 if exts:
128 if exts:
129 for name, desc in sorted(exts.items()):
129 for name, desc in sorted(exts.items()):
130 if not showdeprecated and any(w in desc for w in _exclkeywords):
130 if not showdeprecated and any(w in desc for w in _exclkeywords):
131 continue
131 continue
132 rst.append(b'%s:%s: %s\n' % (b' ' * indent, name, desc))
132 rst.append(b'%s:%s: %s\n' % (b' ' * indent, name, desc))
133 if rst:
133 if rst:
134 rst.insert(0, b'\n%s\n\n' % header)
134 rst.insert(0, b'\n%s\n\n' % header)
135 return rst
135 return rst
136
136
137
137
138 def extshelp(ui):
138 def extshelp(ui):
139 rst = loaddoc(b'extensions')(ui).splitlines(True)
139 rst = loaddoc(b'extensions')(ui).splitlines(True)
140 rst.extend(
140 rst.extend(
141 listexts(
141 listexts(
142 _(b'enabled extensions:'), extensions.enabled(), showdeprecated=True
142 _(b'enabled extensions:'), extensions.enabled(), showdeprecated=True
143 )
143 )
144 )
144 )
145 rst.extend(
145 rst.extend(
146 listexts(
146 listexts(
147 _(b'disabled extensions:'),
147 _(b'disabled extensions:'),
148 extensions.disabled(),
148 extensions.disabled(),
149 showdeprecated=ui.verbose,
149 showdeprecated=ui.verbose,
150 )
150 )
151 )
151 )
152 doc = b''.join(rst)
152 doc = b''.join(rst)
153 return doc
153 return doc
154
154
155
155
156 def parsedefaultmarker(text):
156 def parsedefaultmarker(text):
157 """given a text 'abc (DEFAULT: def.ghi)',
157 """given a text 'abc (DEFAULT: def.ghi)',
158 returns (b'abc', (b'def', b'ghi')). Otherwise return None"""
158 returns (b'abc', (b'def', b'ghi')). Otherwise return None"""
159 if text[-1:] == b')':
159 if text[-1:] == b')':
160 marker = b' (DEFAULT: '
160 marker = b' (DEFAULT: '
161 pos = text.find(marker)
161 pos = text.find(marker)
162 if pos >= 0:
162 if pos >= 0:
163 item = text[pos + len(marker) : -1]
163 item = text[pos + len(marker) : -1]
164 return text[:pos], item.split(b'.', 2)
164 return text[:pos], item.split(b'.', 2)
165
165
166
166
167 def optrst(header, options, verbose, ui):
167 def optrst(header, options, verbose, ui):
168 data = []
168 data = []
169 multioccur = False
169 multioccur = False
170 for option in options:
170 for option in options:
171 if len(option) == 5:
171 if len(option) == 5:
172 shortopt, longopt, default, desc, optlabel = option
172 shortopt, longopt, default, desc, optlabel = option
173 else:
173 else:
174 shortopt, longopt, default, desc = option
174 shortopt, longopt, default, desc = option
175 optlabel = _(b"VALUE") # default label
175 optlabel = _(b"VALUE") # default label
176
176
177 if not verbose and any(w in desc for w in _exclkeywords):
177 if not verbose and any(w in desc for w in _exclkeywords):
178 continue
178 continue
179 defaultstrsuffix = b''
179 defaultstrsuffix = b''
180 if default is None:
180 if default is None:
181 parseresult = parsedefaultmarker(desc)
181 parseresult = parsedefaultmarker(desc)
182 if parseresult is not None:
182 if parseresult is not None:
183 (desc, (section, name)) = parseresult
183 (desc, (section, name)) = parseresult
184 if ui.configbool(section, name):
184 if ui.configbool(section, name):
185 default = True
185 default = True
186 defaultstrsuffix = _(b' from config')
186 defaultstrsuffix = _(b' from config')
187 so = b''
187 so = b''
188 if shortopt:
188 if shortopt:
189 so = b'-' + shortopt
189 so = b'-' + shortopt
190 lo = b'--' + longopt
190 lo = b'--' + longopt
191 if default is True:
191 if default is True:
192 lo = b'--[no-]' + longopt
192 lo = b'--[no-]' + longopt
193
193
194 if isinstance(default, fancyopts.customopt):
194 if isinstance(default, fancyopts.customopt):
195 default = default.getdefaultvalue()
195 default = default.getdefaultvalue()
196 if default and not callable(default):
196 if default and not callable(default):
197 # default is of unknown type, and in Python 2 we abused
197 # default is of unknown type, and in Python 2 we abused
198 # the %s-shows-repr property to handle integers etc. To
198 # the %s-shows-repr property to handle integers etc. To
199 # match that behavior on Python 3, we do str(default) and
199 # match that behavior on Python 3, we do str(default) and
200 # then convert it to bytes.
200 # then convert it to bytes.
201 defaultstr = pycompat.bytestr(default)
201 defaultstr = pycompat.bytestr(default)
202 if default is True:
202 if default is True:
203 defaultstr = _(b"on")
203 defaultstr = _(b"on")
204 desc += _(b" (default: %s)") % (defaultstr + defaultstrsuffix)
204 desc += _(b" (default: %s)") % (defaultstr + defaultstrsuffix)
205
205
206 if isinstance(default, list):
206 if isinstance(default, list):
207 lo += b" %s [+]" % optlabel
207 lo += b" %s [+]" % optlabel
208 multioccur = True
208 multioccur = True
209 elif (default is not None) and not isinstance(default, bool):
209 elif (default is not None) and not isinstance(default, bool):
210 lo += b" %s" % optlabel
210 lo += b" %s" % optlabel
211
211
212 data.append((so, lo, desc))
212 data.append((so, lo, desc))
213
213
214 if multioccur:
214 if multioccur:
215 header += _(b" ([+] can be repeated)")
215 header += _(b" ([+] can be repeated)")
216
216
217 rst = [b'\n%s:\n\n' % header]
217 rst = [b'\n%s:\n\n' % header]
218 rst.extend(minirst.maketable(data, 1))
218 rst.extend(minirst.maketable(data, 1))
219
219
220 return b''.join(rst)
220 return b''.join(rst)
221
221
222
222
223 def indicateomitted(rst, omitted, notomitted=None):
223 def indicateomitted(rst, omitted, notomitted=None):
224 rst.append(b'\n\n.. container:: omitted\n\n %s\n\n' % omitted)
224 rst.append(b'\n\n.. container:: omitted\n\n %s\n\n' % omitted)
225 if notomitted:
225 if notomitted:
226 rst.append(b'\n\n.. container:: notomitted\n\n %s\n\n' % notomitted)
226 rst.append(b'\n\n.. container:: notomitted\n\n %s\n\n' % notomitted)
227
227
228
228
229 def filtercmd(ui, cmd, func, kw, doc):
229 def filtercmd(ui, cmd, func, kw, doc):
230 if not ui.debugflag and cmd.startswith(b"debug") and kw != b"debug":
230 if not ui.debugflag and cmd.startswith(b"debug") and kw != b"debug":
231 # Debug command, and user is not looking for those.
231 # Debug command, and user is not looking for those.
232 return True
232 return True
233 if not ui.verbose:
233 if not ui.verbose:
234 if not kw and not doc:
234 if not kw and not doc:
235 # Command had no documentation, no point in showing it by default.
235 # Command had no documentation, no point in showing it by default.
236 return True
236 return True
237 if getattr(func, 'alias', False) and not getattr(func, 'owndoc', False):
237 if getattr(func, 'alias', False) and not getattr(func, 'owndoc', False):
238 # Alias didn't have its own documentation.
238 # Alias didn't have its own documentation.
239 return True
239 return True
240 if doc and any(w in doc for w in _exclkeywords):
240 if doc and any(w in doc for w in _exclkeywords):
241 # Documentation has excluded keywords.
241 # Documentation has excluded keywords.
242 return True
242 return True
243 if kw == b"shortlist" and not getattr(func, 'helpbasic', False):
243 if kw == b"shortlist" and not getattr(func, 'helpbasic', False):
244 # We're presenting the short list but the command is not basic.
244 # We're presenting the short list but the command is not basic.
245 return True
245 return True
246 if ui.configbool(b'help', b'hidden-command.%s' % cmd):
246 if ui.configbool(b'help', b'hidden-command.%s' % cmd):
247 # Configuration explicitly hides the command.
247 # Configuration explicitly hides the command.
248 return True
248 return True
249 return False
249 return False
250
250
251
251
252 def filtertopic(ui, topic):
252 def filtertopic(ui, topic):
253 return ui.configbool(b'help', b'hidden-topic.%s' % topic, False)
253 return ui.configbool(b'help', b'hidden-topic.%s' % topic, False)
254
254
255
255
256 def topicmatch(ui, commands, kw):
256 def topicmatch(ui, commands, kw):
257 """Return help topics matching kw.
257 """Return help topics matching kw.
258
258
259 Returns {'section': [(name, summary), ...], ...} where section is
259 Returns {'section': [(name, summary), ...], ...} where section is
260 one of topics, commands, extensions, or extensioncommands.
260 one of topics, commands, extensions, or extensioncommands.
261 """
261 """
262 kw = encoding.lower(kw)
262 kw = encoding.lower(kw)
263
263
264 def lowercontains(container):
264 def lowercontains(container):
265 return kw in encoding.lower(container) # translated in helptable
265 return kw in encoding.lower(container) # translated in helptable
266
266
267 results = {
267 results = {
268 b'topics': [],
268 b'topics': [],
269 b'commands': [],
269 b'commands': [],
270 b'extensions': [],
270 b'extensions': [],
271 b'extensioncommands': [],
271 b'extensioncommands': [],
272 }
272 }
273 for topic in helptable:
273 for topic in helptable:
274 names, header, doc = topic[0:3]
274 names, header, doc = topic[0:3]
275 # Old extensions may use a str as doc.
275 # Old extensions may use a str as doc.
276 if (
276 if (
277 sum(map(lowercontains, names))
277 sum(map(lowercontains, names))
278 or lowercontains(header)
278 or lowercontains(header)
279 or (callable(doc) and lowercontains(doc(ui)))
279 or (callable(doc) and lowercontains(doc(ui)))
280 ):
280 ):
281 name = names[0]
281 name = names[0]
282 if not filtertopic(ui, name):
282 if not filtertopic(ui, name):
283 results[b'topics'].append((names[0], header))
283 results[b'topics'].append((names[0], header))
284 for cmd, entry in commands.table.items():
284 for cmd, entry in commands.table.items():
285 if len(entry) == 3:
285 if len(entry) == 3:
286 summary = entry[2]
286 summary = entry[2]
287 else:
287 else:
288 summary = b''
288 summary = b''
289 # translate docs *before* searching there
289 # translate docs *before* searching there
290 func = entry[0]
290 func = entry[0]
291 docs = _(pycompat.getdoc(func)) or b''
291 docs = _(pycompat.getdoc(func)) or b''
292 if kw in cmd or lowercontains(summary) or lowercontains(docs):
292 if kw in cmd or lowercontains(summary) or lowercontains(docs):
293 if docs:
293 if docs:
294 summary = stringutil.firstline(docs)
294 summary = stringutil.firstline(docs)
295 cmdname = cmdutil.parsealiases(cmd)[0]
295 cmdname = cmdutil.parsealiases(cmd)[0]
296 if filtercmd(ui, cmdname, func, kw, docs):
296 if filtercmd(ui, cmdname, func, kw, docs):
297 continue
297 continue
298 results[b'commands'].append((cmdname, summary))
298 results[b'commands'].append((cmdname, summary))
299 for name, docs in itertools.chain(
299 for name, docs in itertools.chain(
300 extensions.enabled(False).items(),
300 extensions.enabled(False).items(),
301 extensions.disabled().items(),
301 extensions.disabled().items(),
302 ):
302 ):
303 if not docs:
303 if not docs:
304 continue
304 continue
305 name = name.rpartition(b'.')[-1]
305 name = name.rpartition(b'.')[-1]
306 if lowercontains(name) or lowercontains(docs):
306 if lowercontains(name) or lowercontains(docs):
307 # extension docs are already translated
307 # extension docs are already translated
308 results[b'extensions'].append((name, stringutil.firstline(docs)))
308 results[b'extensions'].append((name, stringutil.firstline(docs)))
309 try:
309 try:
310 mod = extensions.load(ui, name, b'')
310 mod = extensions.load(ui, name, b'')
311 except ImportError:
311 except ImportError:
312 # debug message would be printed in extensions.load()
312 # debug message would be printed in extensions.load()
313 continue
313 continue
314 for cmd, entry in getattr(mod, 'cmdtable', {}).items():
314 for cmd, entry in getattr(mod, 'cmdtable', {}).items():
315 if kw in cmd or (len(entry) > 2 and lowercontains(entry[2])):
315 if kw in cmd or (len(entry) > 2 and lowercontains(entry[2])):
316 cmdname = cmdutil.parsealiases(cmd)[0]
316 cmdname = cmdutil.parsealiases(cmd)[0]
317 func = entry[0]
317 func = entry[0]
318 cmddoc = pycompat.getdoc(func)
318 cmddoc = pycompat.getdoc(func)
319 if cmddoc:
319 if cmddoc:
320 cmddoc = stringutil.firstline(gettext(cmddoc))
320 cmddoc = stringutil.firstline(gettext(cmddoc))
321 else:
321 else:
322 cmddoc = _(b'(no help text available)')
322 cmddoc = _(b'(no help text available)')
323 if filtercmd(ui, cmdname, func, kw, cmddoc):
323 if filtercmd(ui, cmdname, func, kw, cmddoc):
324 continue
324 continue
325 results[b'extensioncommands'].append((cmdname, cmddoc))
325 results[b'extensioncommands'].append((cmdname, cmddoc))
326 return results
326 return results
327
327
328
328
329 def loaddoc(topic, subdir=None):
329 def loaddoc(topic, subdir=None):
330 """Return a delayed loader for help/topic.txt."""
330 """Return a delayed loader for help/topic.txt."""
331
331
332 def loader(ui):
332 def loader(ui):
333 package = b'mercurial.helptext'
333 package = b'mercurial.helptext'
334 if subdir:
334 if subdir:
335 package += b'.' + subdir
335 package += b'.' + subdir
336 with resourceutil.open_resource(package, topic + b'.txt') as fp:
336 with resourceutil.open_resource(package, topic + b'.txt') as fp:
337 doc = gettext(fp.read())
337 doc = gettext(fp.read())
338 for rewriter in helphooks.get(topic, []):
338 for rewriter in helphooks.get(topic, []):
339 doc = rewriter(ui, topic, doc)
339 doc = rewriter(ui, topic, doc)
340 return doc
340 return doc
341
341
342 return loader
342 return loader
343
343
344
344
345 internalstable = sorted(
345 internalstable = sorted(
346 [
346 [
347 (
347 (
348 [b'bid-merge'],
348 [b'bid-merge'],
349 _(b'Bid Merge Algorithm'),
349 _(b'Bid Merge Algorithm'),
350 loaddoc(b'bid-merge', subdir=b'internals'),
350 loaddoc(b'bid-merge', subdir=b'internals'),
351 ),
351 ),
352 ([b'bundle2'], _(b'Bundle2'), loaddoc(b'bundle2', subdir=b'internals')),
352 ([b'bundle2'], _(b'Bundle2'), loaddoc(b'bundle2', subdir=b'internals')),
353 ([b'bundles'], _(b'Bundles'), loaddoc(b'bundles', subdir=b'internals')),
353 ([b'bundles'], _(b'Bundles'), loaddoc(b'bundles', subdir=b'internals')),
354 ([b'cbor'], _(b'CBOR'), loaddoc(b'cbor', subdir=b'internals')),
354 ([b'cbor'], _(b'CBOR'), loaddoc(b'cbor', subdir=b'internals')),
355 ([b'censor'], _(b'Censor'), loaddoc(b'censor', subdir=b'internals')),
355 ([b'censor'], _(b'Censor'), loaddoc(b'censor', subdir=b'internals')),
356 (
356 (
357 [b'changegroups'],
357 [b'changegroups'],
358 _(b'Changegroups'),
358 _(b'Changegroups'),
359 loaddoc(b'changegroups', subdir=b'internals'),
359 loaddoc(b'changegroups', subdir=b'internals'),
360 ),
360 ),
361 (
361 (
362 [b'config'],
362 [b'config'],
363 _(b'Config Registrar'),
363 _(b'Config Registrar'),
364 loaddoc(b'config', subdir=b'internals'),
364 loaddoc(b'config', subdir=b'internals'),
365 ),
365 ),
366 (
366 (
367 [b'dirstate-v2'],
367 [b'dirstate-v2'],
368 _(b'dirstate-v2 file format'),
368 _(b'dirstate-v2 file format'),
369 loaddoc(b'dirstate-v2', subdir=b'internals'),
369 loaddoc(b'dirstate-v2', subdir=b'internals'),
370 ),
370 ),
371 (
371 (
372 [b'extensions', b'extension'],
372 [b'extensions', b'extension'],
373 _(b'Extension API'),
373 _(b'Extension API'),
374 loaddoc(b'extensions', subdir=b'internals'),
374 loaddoc(b'extensions', subdir=b'internals'),
375 ),
375 ),
376 (
376 (
377 [b'mergestate'],
377 [b'mergestate'],
378 _(b'Mergestate'),
378 _(b'Mergestate'),
379 loaddoc(b'mergestate', subdir=b'internals'),
379 loaddoc(b'mergestate', subdir=b'internals'),
380 ),
380 ),
381 (
381 (
382 [b'requirements'],
382 [b'requirements'],
383 _(b'Repository Requirements'),
383 _(b'Repository Requirements'),
384 loaddoc(b'requirements', subdir=b'internals'),
384 loaddoc(b'requirements', subdir=b'internals'),
385 ),
385 ),
386 (
386 (
387 [b'revlogs'],
387 [b'revlogs'],
388 _(b'Revision Logs'),
388 _(b'Revision Logs'),
389 loaddoc(b'revlogs', subdir=b'internals'),
389 loaddoc(b'revlogs', subdir=b'internals'),
390 ),
390 ),
391 (
391 (
392 [b'wireprotocol'],
392 [b'wireprotocol'],
393 _(b'Wire Protocol'),
393 _(b'Wire Protocol'),
394 loaddoc(b'wireprotocol', subdir=b'internals'),
394 loaddoc(b'wireprotocol', subdir=b'internals'),
395 ),
395 ),
396 (
396 (
397 [b'wireprotocolrpc'],
397 [b'wireprotocolrpc'],
398 _(b'Wire Protocol RPC'),
398 _(b'Wire Protocol RPC'),
399 loaddoc(b'wireprotocolrpc', subdir=b'internals'),
399 loaddoc(b'wireprotocolrpc', subdir=b'internals'),
400 ),
400 ),
401 (
401 (
402 [b'wireprotocolv2'],
402 [b'wireprotocolv2'],
403 _(b'Wire Protocol Version 2'),
403 _(b'Wire Protocol Version 2'),
404 loaddoc(b'wireprotocolv2', subdir=b'internals'),
404 loaddoc(b'wireprotocolv2', subdir=b'internals'),
405 ),
405 ),
406 ]
406 ]
407 )
407 )
408
408
409
409
410 def internalshelp(ui):
410 def internalshelp(ui):
411 """Generate the index for the "internals" topic."""
411 """Generate the index for the "internals" topic."""
412 lines = [
412 lines = [
413 b'To access a subtopic, use "hg help internals.{subtopic-name}"\n',
413 b'To access a subtopic, use "hg help internals.{subtopic-name}"\n',
414 b'\n',
414 b'\n',
415 ]
415 ]
416 for names, header, doc in internalstable:
416 for names, header, doc in internalstable:
417 lines.append(b' :%s: %s\n' % (names[0], header))
417 lines.append(b' :%s: %s\n' % (names[0], header))
418
418
419 return b''.join(lines)
419 return b''.join(lines)
420
420
421
421
422 helptable = sorted(
422 helptable = sorted(
423 [
423 [
424 (
424 (
425 [b'bundlespec'],
425 [b'bundlespec'],
426 _(b"Bundle File Formats"),
426 _(b"Bundle File Formats"),
427 loaddoc(b'bundlespec'),
427 loaddoc(b'bundlespec'),
428 TOPIC_CATEGORY_CONCEPTS,
428 TOPIC_CATEGORY_CONCEPTS,
429 ),
429 ),
430 (
430 (
431 [b'color'],
431 [b'color'],
432 _(b"Colorizing Outputs"),
432 _(b"Colorizing Outputs"),
433 loaddoc(b'color'),
433 loaddoc(b'color'),
434 TOPIC_CATEGORY_OUTPUT,
434 TOPIC_CATEGORY_OUTPUT,
435 ),
435 ),
436 (
436 (
437 [b"config", b"hgrc"],
437 [b"config", b"hgrc"],
438 _(b"Configuration Files"),
438 _(b"Configuration Files"),
439 loaddoc(b'config'),
439 loaddoc(b'config'),
440 TOPIC_CATEGORY_CONFIG,
440 TOPIC_CATEGORY_CONFIG,
441 ),
441 ),
442 (
442 (
443 [b'deprecated'],
443 [b'deprecated'],
444 _(b"Deprecated Features"),
444 _(b"Deprecated Features"),
445 loaddoc(b'deprecated'),
445 loaddoc(b'deprecated'),
446 TOPIC_CATEGORY_MISC,
446 TOPIC_CATEGORY_MISC,
447 ),
447 ),
448 (
448 (
449 [b"dates"],
449 [b"dates"],
450 _(b"Date Formats"),
450 _(b"Date Formats"),
451 loaddoc(b'dates'),
451 loaddoc(b'dates'),
452 TOPIC_CATEGORY_OUTPUT,
452 TOPIC_CATEGORY_OUTPUT,
453 ),
453 ),
454 (
454 (
455 [b"flags"],
455 [b"flags"],
456 _(b"Command-line flags"),
456 _(b"Command-line flags"),
457 loaddoc(b'flags'),
457 loaddoc(b'flags'),
458 TOPIC_CATEGORY_CONFIG,
458 TOPIC_CATEGORY_CONFIG,
459 ),
459 ),
460 (
460 (
461 [b"patterns"],
461 [b"patterns"],
462 _(b"File Name Patterns"),
462 _(b"File Name Patterns"),
463 loaddoc(b'patterns'),
463 loaddoc(b'patterns'),
464 TOPIC_CATEGORY_IDS,
464 TOPIC_CATEGORY_IDS,
465 ),
465 ),
466 (
466 (
467 [b'environment', b'env'],
467 [b'environment', b'env'],
468 _(b'Environment Variables'),
468 _(b'Environment Variables'),
469 loaddoc(b'environment'),
469 loaddoc(b'environment'),
470 TOPIC_CATEGORY_CONFIG,
470 TOPIC_CATEGORY_CONFIG,
471 ),
471 ),
472 (
472 (
473 [
473 [
474 b'revisions',
474 b'revisions',
475 b'revs',
475 b'revs',
476 b'revsets',
476 b'revsets',
477 b'revset',
477 b'revset',
478 b'multirevs',
478 b'multirevs',
479 b'mrevs',
479 b'mrevs',
480 ],
480 ],
481 _(b'Specifying Revisions'),
481 _(b'Specifying Revisions'),
482 loaddoc(b'revisions'),
482 loaddoc(b'revisions'),
483 TOPIC_CATEGORY_IDS,
483 TOPIC_CATEGORY_IDS,
484 ),
484 ),
485 (
485 (
486 [
486 [
487 b'rust',
487 b'rust',
488 b'rustext',
488 b'rustext',
489 b'rhg',
489 ],
490 ],
490 _(b'Rust in Mercurial'),
491 _(b'Rust in Mercurial'),
491 loaddoc(b'rust'),
492 loaddoc(b'rust'),
492 TOPIC_CATEGORY_CONFIG,
493 TOPIC_CATEGORY_CONFIG,
493 ),
494 ),
494 (
495 (
495 [b'filesets', b'fileset'],
496 [b'filesets', b'fileset'],
496 _(b"Specifying File Sets"),
497 _(b"Specifying File Sets"),
497 loaddoc(b'filesets'),
498 loaddoc(b'filesets'),
498 TOPIC_CATEGORY_IDS,
499 TOPIC_CATEGORY_IDS,
499 ),
500 ),
500 (
501 (
501 [b'diffs'],
502 [b'diffs'],
502 _(b'Diff Formats'),
503 _(b'Diff Formats'),
503 loaddoc(b'diffs'),
504 loaddoc(b'diffs'),
504 TOPIC_CATEGORY_OUTPUT,
505 TOPIC_CATEGORY_OUTPUT,
505 ),
506 ),
506 (
507 (
507 [b'merge-tools', b'mergetools', b'mergetool'],
508 [b'merge-tools', b'mergetools', b'mergetool'],
508 _(b'Merge Tools'),
509 _(b'Merge Tools'),
509 loaddoc(b'merge-tools'),
510 loaddoc(b'merge-tools'),
510 TOPIC_CATEGORY_CONFIG,
511 TOPIC_CATEGORY_CONFIG,
511 ),
512 ),
512 (
513 (
513 [b'templating', b'templates', b'template', b'style'],
514 [b'templating', b'templates', b'template', b'style'],
514 _(b'Template Usage'),
515 _(b'Template Usage'),
515 loaddoc(b'templates'),
516 loaddoc(b'templates'),
516 TOPIC_CATEGORY_OUTPUT,
517 TOPIC_CATEGORY_OUTPUT,
517 ),
518 ),
518 ([b'urls'], _(b'URL Paths'), loaddoc(b'urls'), TOPIC_CATEGORY_IDS),
519 ([b'urls'], _(b'URL Paths'), loaddoc(b'urls'), TOPIC_CATEGORY_IDS),
519 (
520 (
520 [b"extensions"],
521 [b"extensions"],
521 _(b"Using Additional Features"),
522 _(b"Using Additional Features"),
522 extshelp,
523 extshelp,
523 TOPIC_CATEGORY_CONFIG,
524 TOPIC_CATEGORY_CONFIG,
524 ),
525 ),
525 (
526 (
526 [b"subrepos", b"subrepo"],
527 [b"subrepos", b"subrepo"],
527 _(b"Subrepositories"),
528 _(b"Subrepositories"),
528 loaddoc(b'subrepos'),
529 loaddoc(b'subrepos'),
529 TOPIC_CATEGORY_CONCEPTS,
530 TOPIC_CATEGORY_CONCEPTS,
530 ),
531 ),
531 (
532 (
532 [b"hgweb"],
533 [b"hgweb"],
533 _(b"Configuring hgweb"),
534 _(b"Configuring hgweb"),
534 loaddoc(b'hgweb'),
535 loaddoc(b'hgweb'),
535 TOPIC_CATEGORY_CONFIG,
536 TOPIC_CATEGORY_CONFIG,
536 ),
537 ),
537 (
538 (
538 [b"glossary"],
539 [b"glossary"],
539 _(b"Glossary"),
540 _(b"Glossary"),
540 loaddoc(b'glossary'),
541 loaddoc(b'glossary'),
541 TOPIC_CATEGORY_CONCEPTS,
542 TOPIC_CATEGORY_CONCEPTS,
542 ),
543 ),
543 (
544 (
544 [b"hgignore", b"ignore"],
545 [b"hgignore", b"ignore"],
545 _(b"Syntax for Mercurial Ignore Files"),
546 _(b"Syntax for Mercurial Ignore Files"),
546 loaddoc(b'hgignore'),
547 loaddoc(b'hgignore'),
547 TOPIC_CATEGORY_IDS,
548 TOPIC_CATEGORY_IDS,
548 ),
549 ),
549 (
550 (
550 [b"phases"],
551 [b"phases"],
551 _(b"Working with Phases"),
552 _(b"Working with Phases"),
552 loaddoc(b'phases'),
553 loaddoc(b'phases'),
553 TOPIC_CATEGORY_CONCEPTS,
554 TOPIC_CATEGORY_CONCEPTS,
554 ),
555 ),
555 (
556 (
556 [b"evolution"],
557 [b"evolution"],
557 _(b"Safely rewriting history (EXPERIMENTAL)"),
558 _(b"Safely rewriting history (EXPERIMENTAL)"),
558 loaddoc(b'evolution'),
559 loaddoc(b'evolution'),
559 TOPIC_CATEGORY_CONCEPTS,
560 TOPIC_CATEGORY_CONCEPTS,
560 ),
561 ),
561 (
562 (
562 [b'scripting'],
563 [b'scripting'],
563 _(b'Using Mercurial from scripts and automation'),
564 _(b'Using Mercurial from scripts and automation'),
564 loaddoc(b'scripting'),
565 loaddoc(b'scripting'),
565 TOPIC_CATEGORY_MISC,
566 TOPIC_CATEGORY_MISC,
566 ),
567 ),
567 (
568 (
568 [b'internals'],
569 [b'internals'],
569 _(b"Technical implementation topics"),
570 _(b"Technical implementation topics"),
570 internalshelp,
571 internalshelp,
571 TOPIC_CATEGORY_MISC,
572 TOPIC_CATEGORY_MISC,
572 ),
573 ),
573 (
574 (
574 [b'pager'],
575 [b'pager'],
575 _(b"Pager Support"),
576 _(b"Pager Support"),
576 loaddoc(b'pager'),
577 loaddoc(b'pager'),
577 TOPIC_CATEGORY_CONFIG,
578 TOPIC_CATEGORY_CONFIG,
578 ),
579 ),
579 ]
580 ]
580 )
581 )
581
582
582 # Maps topics with sub-topics to a list of their sub-topics.
583 # Maps topics with sub-topics to a list of their sub-topics.
583 subtopics = {
584 subtopics = {
584 b'internals': internalstable,
585 b'internals': internalstable,
585 }
586 }
586
587
587 # Map topics to lists of callable taking the current topic help and
588 # Map topics to lists of callable taking the current topic help and
588 # returning the updated version
589 # returning the updated version
589 helphooks = {}
590 helphooks = {}
590
591
591
592
592 def addtopichook(topic, rewriter):
593 def addtopichook(topic, rewriter):
593 helphooks.setdefault(topic, []).append(rewriter)
594 helphooks.setdefault(topic, []).append(rewriter)
594
595
595
596
596 def makeitemsdoc(ui, topic, doc, marker, items, dedent=False):
597 def makeitemsdoc(ui, topic, doc, marker, items, dedent=False):
597 """Extract docstring from the items key to function mapping, build a
598 """Extract docstring from the items key to function mapping, build a
598 single documentation block and use it to overwrite the marker in doc.
599 single documentation block and use it to overwrite the marker in doc.
599 """
600 """
600 entries = []
601 entries = []
601 for name in sorted(items):
602 for name in sorted(items):
602 text = (pycompat.getdoc(items[name]) or b'').rstrip()
603 text = (pycompat.getdoc(items[name]) or b'').rstrip()
603 if not text or not ui.verbose and any(w in text for w in _exclkeywords):
604 if not text or not ui.verbose and any(w in text for w in _exclkeywords):
604 continue
605 continue
605 text = gettext(text)
606 text = gettext(text)
606 if dedent:
607 if dedent:
607 # Abuse latin1 to use textwrap.dedent() on bytes.
608 # Abuse latin1 to use textwrap.dedent() on bytes.
608 text = textwrap.dedent(text.decode('latin1')).encode('latin1')
609 text = textwrap.dedent(text.decode('latin1')).encode('latin1')
609 lines = text.splitlines()
610 lines = text.splitlines()
610 doclines = [lines[0]]
611 doclines = [lines[0]]
611 for l in lines[1:]:
612 for l in lines[1:]:
612 # Stop once we find some Python doctest
613 # Stop once we find some Python doctest
613 if l.strip().startswith(b'>>>'):
614 if l.strip().startswith(b'>>>'):
614 break
615 break
615 if dedent:
616 if dedent:
616 doclines.append(l.rstrip())
617 doclines.append(l.rstrip())
617 else:
618 else:
618 doclines.append(b' ' + l.strip())
619 doclines.append(b' ' + l.strip())
619 entries.append(b'\n'.join(doclines))
620 entries.append(b'\n'.join(doclines))
620 entries = b'\n\n'.join(entries)
621 entries = b'\n\n'.join(entries)
621 return doc.replace(marker, entries)
622 return doc.replace(marker, entries)
622
623
623
624
624 def addtopicsymbols(topic, marker, symbols, dedent=False):
625 def addtopicsymbols(topic, marker, symbols, dedent=False):
625 def add(ui, topic, doc):
626 def add(ui, topic, doc):
626 return makeitemsdoc(ui, topic, doc, marker, symbols, dedent=dedent)
627 return makeitemsdoc(ui, topic, doc, marker, symbols, dedent=dedent)
627
628
628 addtopichook(topic, add)
629 addtopichook(topic, add)
629
630
630
631
631 addtopicsymbols(
632 addtopicsymbols(
632 b'bundlespec',
633 b'bundlespec',
633 b'.. bundlecompressionmarker',
634 b'.. bundlecompressionmarker',
634 compression.bundlecompressiontopics(),
635 compression.bundlecompressiontopics(),
635 )
636 )
636 addtopicsymbols(b'filesets', b'.. predicatesmarker', fileset.symbols)
637 addtopicsymbols(b'filesets', b'.. predicatesmarker', fileset.symbols)
637 addtopicsymbols(
638 addtopicsymbols(
638 b'merge-tools', b'.. internaltoolsmarker', filemerge.internalsdoc
639 b'merge-tools', b'.. internaltoolsmarker', filemerge.internalsdoc
639 )
640 )
640 addtopicsymbols(b'revisions', b'.. predicatesmarker', revset.symbols)
641 addtopicsymbols(b'revisions', b'.. predicatesmarker', revset.symbols)
641 addtopicsymbols(b'templates', b'.. keywordsmarker', templatekw.keywords)
642 addtopicsymbols(b'templates', b'.. keywordsmarker', templatekw.keywords)
642 addtopicsymbols(b'templates', b'.. filtersmarker', templatefilters.filters)
643 addtopicsymbols(b'templates', b'.. filtersmarker', templatefilters.filters)
643 addtopicsymbols(b'templates', b'.. functionsmarker', templatefuncs.funcs)
644 addtopicsymbols(b'templates', b'.. functionsmarker', templatefuncs.funcs)
644 addtopicsymbols(
645 addtopicsymbols(
645 b'hgweb', b'.. webcommandsmarker', webcommands.commands, dedent=True
646 b'hgweb', b'.. webcommandsmarker', webcommands.commands, dedent=True
646 )
647 )
647
648
648
649
649 def inserttweakrc(ui, topic, doc):
650 def inserttweakrc(ui, topic, doc):
650 marker = b'.. tweakdefaultsmarker'
651 marker = b'.. tweakdefaultsmarker'
651 repl = uimod.tweakrc
652 repl = uimod.tweakrc
652
653
653 def sub(m):
654 def sub(m):
654 lines = [m.group(1) + s for s in repl.splitlines()]
655 lines = [m.group(1) + s for s in repl.splitlines()]
655 return b'\n'.join(lines)
656 return b'\n'.join(lines)
656
657
657 return re.sub(br'( *)%s' % re.escape(marker), sub, doc)
658 return re.sub(br'( *)%s' % re.escape(marker), sub, doc)
658
659
659
660
660 def _getcategorizedhelpcmds(ui, cmdtable, name, select=None):
661 def _getcategorizedhelpcmds(ui, cmdtable, name, select=None):
661 # Category -> list of commands
662 # Category -> list of commands
662 cats = {}
663 cats = {}
663 # Command -> short description
664 # Command -> short description
664 h = {}
665 h = {}
665 # Command -> string showing synonyms
666 # Command -> string showing synonyms
666 syns = {}
667 syns = {}
667 for c, e in cmdtable.items():
668 for c, e in cmdtable.items():
668 fs = cmdutil.parsealiases(c)
669 fs = cmdutil.parsealiases(c)
669 f = fs[0]
670 f = fs[0]
670 syns[f] = fs
671 syns[f] = fs
671 func = e[0]
672 func = e[0]
672 if select and not select(f):
673 if select and not select(f):
673 continue
674 continue
674 doc = pycompat.getdoc(func)
675 doc = pycompat.getdoc(func)
675 if filtercmd(ui, f, func, name, doc):
676 if filtercmd(ui, f, func, name, doc):
676 continue
677 continue
677 doc = gettext(doc)
678 doc = gettext(doc)
678 if not doc:
679 if not doc:
679 doc = _(b"(no help text available)")
680 doc = _(b"(no help text available)")
680 h[f] = stringutil.firstline(doc).rstrip()
681 h[f] = stringutil.firstline(doc).rstrip()
681
682
682 cat = getattr(func, 'helpcategory', None) or (
683 cat = getattr(func, 'helpcategory', None) or (
683 registrar.command.CATEGORY_NONE
684 registrar.command.CATEGORY_NONE
684 )
685 )
685 cats.setdefault(cat, []).append(f)
686 cats.setdefault(cat, []).append(f)
686 return cats, h, syns
687 return cats, h, syns
687
688
688
689
689 def _getcategorizedhelptopics(ui, topictable):
690 def _getcategorizedhelptopics(ui, topictable):
690 # Group commands by category.
691 # Group commands by category.
691 topiccats = {}
692 topiccats = {}
692 syns = {}
693 syns = {}
693 for topic in topictable:
694 for topic in topictable:
694 names, header, doc = topic[0:3]
695 names, header, doc = topic[0:3]
695 if len(topic) > 3 and topic[3]:
696 if len(topic) > 3 and topic[3]:
696 category = topic[3]
697 category = topic[3]
697 else:
698 else:
698 category = TOPIC_CATEGORY_NONE
699 category = TOPIC_CATEGORY_NONE
699
700
700 topicname = names[0]
701 topicname = names[0]
701 syns[topicname] = list(names)
702 syns[topicname] = list(names)
702 if not filtertopic(ui, topicname):
703 if not filtertopic(ui, topicname):
703 topiccats.setdefault(category, []).append((topicname, header))
704 topiccats.setdefault(category, []).append((topicname, header))
704 return topiccats, syns
705 return topiccats, syns
705
706
706
707
707 addtopichook(b'config', inserttweakrc)
708 addtopichook(b'config', inserttweakrc)
708
709
709
710
710 def help_(
711 def help_(
711 ui,
712 ui,
712 commands,
713 commands,
713 name,
714 name,
714 unknowncmd=False,
715 unknowncmd=False,
715 full=True,
716 full=True,
716 subtopic=None,
717 subtopic=None,
717 fullname=None,
718 fullname=None,
718 **opts
719 **opts
719 ):
720 ):
720 """
721 """
721 Generate the help for 'name' as unformatted restructured text. If
722 Generate the help for 'name' as unformatted restructured text. If
722 'name' is None, describe the commands available.
723 'name' is None, describe the commands available.
723 """
724 """
724
725
725 opts = pycompat.byteskwargs(opts)
726 opts = pycompat.byteskwargs(opts)
726
727
727 def helpcmd(name, subtopic=None):
728 def helpcmd(name, subtopic=None):
728 try:
729 try:
729 aliases, entry = cmdutil.findcmd(
730 aliases, entry = cmdutil.findcmd(
730 name, commands.table, strict=unknowncmd
731 name, commands.table, strict=unknowncmd
731 )
732 )
732 except error.AmbiguousCommand as inst:
733 except error.AmbiguousCommand as inst:
733 # py3 fix: except vars can't be used outside the scope of the
734 # py3 fix: except vars can't be used outside the scope of the
734 # except block, nor can be used inside a lambda. python issue4617
735 # except block, nor can be used inside a lambda. python issue4617
735 prefix = inst.prefix
736 prefix = inst.prefix
736 select = lambda c: cmdutil.parsealiases(c)[0].startswith(prefix)
737 select = lambda c: cmdutil.parsealiases(c)[0].startswith(prefix)
737 rst = helplist(select)
738 rst = helplist(select)
738 return rst
739 return rst
739
740
740 rst = []
741 rst = []
741
742
742 # check if it's an invalid alias and display its error if it is
743 # check if it's an invalid alias and display its error if it is
743 if getattr(entry[0], 'badalias', None):
744 if getattr(entry[0], 'badalias', None):
744 rst.append(entry[0].badalias + b'\n')
745 rst.append(entry[0].badalias + b'\n')
745 if entry[0].unknowncmd:
746 if entry[0].unknowncmd:
746 try:
747 try:
747 rst.extend(helpextcmd(entry[0].cmdname))
748 rst.extend(helpextcmd(entry[0].cmdname))
748 except error.UnknownCommand:
749 except error.UnknownCommand:
749 pass
750 pass
750 return rst
751 return rst
751
752
752 # synopsis
753 # synopsis
753 if len(entry) > 2:
754 if len(entry) > 2:
754 if entry[2].startswith(b'hg'):
755 if entry[2].startswith(b'hg'):
755 rst.append(b"%s\n" % entry[2])
756 rst.append(b"%s\n" % entry[2])
756 else:
757 else:
757 rst.append(b'hg %s %s\n' % (aliases[0], entry[2]))
758 rst.append(b'hg %s %s\n' % (aliases[0], entry[2]))
758 else:
759 else:
759 rst.append(b'hg %s\n' % aliases[0])
760 rst.append(b'hg %s\n' % aliases[0])
760 # aliases
761 # aliases
761 if full and not ui.quiet and len(aliases) > 1:
762 if full and not ui.quiet and len(aliases) > 1:
762 rst.append(_(b"\naliases: %s\n") % b', '.join(aliases[1:]))
763 rst.append(_(b"\naliases: %s\n") % b', '.join(aliases[1:]))
763 rst.append(b'\n')
764 rst.append(b'\n')
764
765
765 # description
766 # description
766 doc = gettext(pycompat.getdoc(entry[0]))
767 doc = gettext(pycompat.getdoc(entry[0]))
767 if not doc:
768 if not doc:
768 doc = _(b"(no help text available)")
769 doc = _(b"(no help text available)")
769 if util.safehasattr(entry[0], b'definition'): # aliased command
770 if util.safehasattr(entry[0], b'definition'): # aliased command
770 source = entry[0].source
771 source = entry[0].source
771 if entry[0].definition.startswith(b'!'): # shell alias
772 if entry[0].definition.startswith(b'!'): # shell alias
772 doc = _(b'shell alias for: %s\n\n%s\n\ndefined by: %s\n') % (
773 doc = _(b'shell alias for: %s\n\n%s\n\ndefined by: %s\n') % (
773 entry[0].definition[1:],
774 entry[0].definition[1:],
774 doc,
775 doc,
775 source,
776 source,
776 )
777 )
777 else:
778 else:
778 doc = _(b'alias for: hg %s\n\n%s\n\ndefined by: %s\n') % (
779 doc = _(b'alias for: hg %s\n\n%s\n\ndefined by: %s\n') % (
779 entry[0].definition,
780 entry[0].definition,
780 doc,
781 doc,
781 source,
782 source,
782 )
783 )
783 doc = doc.splitlines(True)
784 doc = doc.splitlines(True)
784 if ui.quiet or not full:
785 if ui.quiet or not full:
785 rst.append(doc[0])
786 rst.append(doc[0])
786 else:
787 else:
787 rst.extend(doc)
788 rst.extend(doc)
788 rst.append(b'\n')
789 rst.append(b'\n')
789
790
790 # check if this command shadows a non-trivial (multi-line)
791 # check if this command shadows a non-trivial (multi-line)
791 # extension help text
792 # extension help text
792 try:
793 try:
793 mod = extensions.find(name)
794 mod = extensions.find(name)
794 doc = gettext(pycompat.getdoc(mod)) or b''
795 doc = gettext(pycompat.getdoc(mod)) or b''
795 if b'\n' in doc.strip():
796 if b'\n' in doc.strip():
796 msg = _(
797 msg = _(
797 b"(use 'hg help -e %s' to show help for "
798 b"(use 'hg help -e %s' to show help for "
798 b"the %s extension)"
799 b"the %s extension)"
799 ) % (name, name)
800 ) % (name, name)
800 rst.append(b'\n%s\n' % msg)
801 rst.append(b'\n%s\n' % msg)
801 except KeyError:
802 except KeyError:
802 pass
803 pass
803
804
804 # options
805 # options
805 if not ui.quiet and entry[1]:
806 if not ui.quiet and entry[1]:
806 rst.append(optrst(_(b"options"), entry[1], ui.verbose, ui))
807 rst.append(optrst(_(b"options"), entry[1], ui.verbose, ui))
807
808
808 if ui.verbose:
809 if ui.verbose:
809 rst.append(
810 rst.append(
810 optrst(
811 optrst(
811 _(b"global options"), commands.globalopts, ui.verbose, ui
812 _(b"global options"), commands.globalopts, ui.verbose, ui
812 )
813 )
813 )
814 )
814
815
815 if not ui.verbose:
816 if not ui.verbose:
816 if not full:
817 if not full:
817 rst.append(_(b"\n(use 'hg %s -h' to show more help)\n") % name)
818 rst.append(_(b"\n(use 'hg %s -h' to show more help)\n") % name)
818 elif not ui.quiet:
819 elif not ui.quiet:
819 rst.append(
820 rst.append(
820 _(
821 _(
821 b'\n(some details hidden, use --verbose '
822 b'\n(some details hidden, use --verbose '
822 b'to show complete help)'
823 b'to show complete help)'
823 )
824 )
824 )
825 )
825
826
826 return rst
827 return rst
827
828
828 def helplist(select=None, **opts):
829 def helplist(select=None, **opts):
829 cats, h, syns = _getcategorizedhelpcmds(
830 cats, h, syns = _getcategorizedhelpcmds(
830 ui, commands.table, name, select
831 ui, commands.table, name, select
831 )
832 )
832
833
833 rst = []
834 rst = []
834 if not h:
835 if not h:
835 if not ui.quiet:
836 if not ui.quiet:
836 rst.append(_(b'no commands defined\n'))
837 rst.append(_(b'no commands defined\n'))
837 return rst
838 return rst
838
839
839 # Output top header.
840 # Output top header.
840 if not ui.quiet:
841 if not ui.quiet:
841 if name == b"shortlist":
842 if name == b"shortlist":
842 rst.append(_(b'basic commands:\n\n'))
843 rst.append(_(b'basic commands:\n\n'))
843 elif name == b"debug":
844 elif name == b"debug":
844 rst.append(_(b'debug commands (internal and unsupported):\n\n'))
845 rst.append(_(b'debug commands (internal and unsupported):\n\n'))
845 else:
846 else:
846 rst.append(_(b'list of commands:\n'))
847 rst.append(_(b'list of commands:\n'))
847
848
848 def appendcmds(cmds):
849 def appendcmds(cmds):
849 cmds = sorted(cmds)
850 cmds = sorted(cmds)
850 for c in cmds:
851 for c in cmds:
851 display_cmd = c
852 display_cmd = c
852 if ui.verbose:
853 if ui.verbose:
853 display_cmd = b', '.join(syns[c])
854 display_cmd = b', '.join(syns[c])
854 display_cmd = display_cmd.replace(b':', br'\:')
855 display_cmd = display_cmd.replace(b':', br'\:')
855 rst.append(b' :%s: %s\n' % (display_cmd, h[c]))
856 rst.append(b' :%s: %s\n' % (display_cmd, h[c]))
856
857
857 if name in (b'shortlist', b'debug'):
858 if name in (b'shortlist', b'debug'):
858 # List without categories.
859 # List without categories.
859 appendcmds(h)
860 appendcmds(h)
860 else:
861 else:
861 # Check that all categories have an order.
862 # Check that all categories have an order.
862 missing_order = set(cats.keys()) - set(CATEGORY_ORDER)
863 missing_order = set(cats.keys()) - set(CATEGORY_ORDER)
863 if missing_order:
864 if missing_order:
864 ui.develwarn(
865 ui.develwarn(
865 b'help categories missing from CATEGORY_ORDER: %s'
866 b'help categories missing from CATEGORY_ORDER: %s'
866 % missing_order
867 % missing_order
867 )
868 )
868
869
869 # List per category.
870 # List per category.
870 for cat in CATEGORY_ORDER:
871 for cat in CATEGORY_ORDER:
871 catfns = cats.get(cat, [])
872 catfns = cats.get(cat, [])
872 if catfns:
873 if catfns:
873 if len(cats) > 1:
874 if len(cats) > 1:
874 catname = gettext(CATEGORY_NAMES[cat])
875 catname = gettext(CATEGORY_NAMES[cat])
875 rst.append(b"\n%s:\n" % catname)
876 rst.append(b"\n%s:\n" % catname)
876 rst.append(b"\n")
877 rst.append(b"\n")
877 appendcmds(catfns)
878 appendcmds(catfns)
878
879
879 ex = opts.get
880 ex = opts.get
880 anyopts = ex('keyword') or not (ex('command') or ex('extension'))
881 anyopts = ex('keyword') or not (ex('command') or ex('extension'))
881 if not name and anyopts:
882 if not name and anyopts:
882 exts = listexts(
883 exts = listexts(
883 _(b'enabled extensions:'),
884 _(b'enabled extensions:'),
884 extensions.enabled(),
885 extensions.enabled(),
885 showdeprecated=ui.verbose,
886 showdeprecated=ui.verbose,
886 )
887 )
887 if exts:
888 if exts:
888 rst.append(b'\n')
889 rst.append(b'\n')
889 rst.extend(exts)
890 rst.extend(exts)
890
891
891 rst.append(_(b"\nadditional help topics:\n"))
892 rst.append(_(b"\nadditional help topics:\n"))
892 topiccats, topicsyns = _getcategorizedhelptopics(ui, helptable)
893 topiccats, topicsyns = _getcategorizedhelptopics(ui, helptable)
893
894
894 # Check that all categories have an order.
895 # Check that all categories have an order.
895 missing_order = set(topiccats.keys()) - set(TOPIC_CATEGORY_ORDER)
896 missing_order = set(topiccats.keys()) - set(TOPIC_CATEGORY_ORDER)
896 if missing_order:
897 if missing_order:
897 ui.develwarn(
898 ui.develwarn(
898 b'help categories missing from TOPIC_CATEGORY_ORDER: %s'
899 b'help categories missing from TOPIC_CATEGORY_ORDER: %s'
899 % missing_order
900 % missing_order
900 )
901 )
901
902
902 # Output topics per category.
903 # Output topics per category.
903 for cat in TOPIC_CATEGORY_ORDER:
904 for cat in TOPIC_CATEGORY_ORDER:
904 topics = topiccats.get(cat, [])
905 topics = topiccats.get(cat, [])
905 if topics:
906 if topics:
906 if len(topiccats) > 1:
907 if len(topiccats) > 1:
907 catname = gettext(TOPIC_CATEGORY_NAMES[cat])
908 catname = gettext(TOPIC_CATEGORY_NAMES[cat])
908 rst.append(b"\n%s:\n" % catname)
909 rst.append(b"\n%s:\n" % catname)
909 rst.append(b"\n")
910 rst.append(b"\n")
910 for t, desc in topics:
911 for t, desc in topics:
911 rst.append(b" :%s: %s\n" % (t, desc))
912 rst.append(b" :%s: %s\n" % (t, desc))
912
913
913 if ui.quiet:
914 if ui.quiet:
914 pass
915 pass
915 elif ui.verbose:
916 elif ui.verbose:
916 rst.append(
917 rst.append(
917 b'\n%s\n'
918 b'\n%s\n'
918 % optrst(
919 % optrst(
919 _(b"global options"), commands.globalopts, ui.verbose, ui
920 _(b"global options"), commands.globalopts, ui.verbose, ui
920 )
921 )
921 )
922 )
922 if name == b'shortlist':
923 if name == b'shortlist':
923 rst.append(
924 rst.append(
924 _(b"\n(use 'hg help' for the full list of commands)\n")
925 _(b"\n(use 'hg help' for the full list of commands)\n")
925 )
926 )
926 else:
927 else:
927 if name == b'shortlist':
928 if name == b'shortlist':
928 rst.append(
929 rst.append(
929 _(
930 _(
930 b"\n(use 'hg help' for the full list of commands "
931 b"\n(use 'hg help' for the full list of commands "
931 b"or 'hg -v' for details)\n"
932 b"or 'hg -v' for details)\n"
932 )
933 )
933 )
934 )
934 elif name and not full:
935 elif name and not full:
935 rst.append(
936 rst.append(
936 _(b"\n(use 'hg help %s' to show the full help text)\n")
937 _(b"\n(use 'hg help %s' to show the full help text)\n")
937 % name
938 % name
938 )
939 )
939 elif name and syns and name in syns.keys():
940 elif name and syns and name in syns.keys():
940 rst.append(
941 rst.append(
941 _(
942 _(
942 b"\n(use 'hg help -v -e %s' to show built-in "
943 b"\n(use 'hg help -v -e %s' to show built-in "
943 b"aliases and global options)\n"
944 b"aliases and global options)\n"
944 )
945 )
945 % name
946 % name
946 )
947 )
947 else:
948 else:
948 rst.append(
949 rst.append(
949 _(
950 _(
950 b"\n(use 'hg help -v%s' to show built-in aliases "
951 b"\n(use 'hg help -v%s' to show built-in aliases "
951 b"and global options)\n"
952 b"and global options)\n"
952 )
953 )
953 % (name and b" " + name or b"")
954 % (name and b" " + name or b"")
954 )
955 )
955 return rst
956 return rst
956
957
957 def helptopic(name, subtopic=None):
958 def helptopic(name, subtopic=None):
958 # Look for sub-topic entry first.
959 # Look for sub-topic entry first.
959 header, doc = None, None
960 header, doc = None, None
960 if subtopic and name in subtopics:
961 if subtopic and name in subtopics:
961 for names, header, doc in subtopics[name]:
962 for names, header, doc in subtopics[name]:
962 if subtopic in names:
963 if subtopic in names:
963 break
964 break
964 if not any(subtopic in s[0] for s in subtopics[name]):
965 if not any(subtopic in s[0] for s in subtopics[name]):
965 raise error.UnknownCommand(name)
966 raise error.UnknownCommand(name)
966
967
967 if not header:
968 if not header:
968 for topic in helptable:
969 for topic in helptable:
969 names, header, doc = topic[0:3]
970 names, header, doc = topic[0:3]
970 if name in names:
971 if name in names:
971 break
972 break
972 else:
973 else:
973 raise error.UnknownCommand(name)
974 raise error.UnknownCommand(name)
974
975
975 rst = [minirst.section(header)]
976 rst = [minirst.section(header)]
976
977
977 # description
978 # description
978 if not doc:
979 if not doc:
979 rst.append(b" %s\n" % _(b"(no help text available)"))
980 rst.append(b" %s\n" % _(b"(no help text available)"))
980 if callable(doc):
981 if callable(doc):
981 rst += [b" %s\n" % l for l in doc(ui).splitlines()]
982 rst += [b" %s\n" % l for l in doc(ui).splitlines()]
982
983
983 if not ui.verbose:
984 if not ui.verbose:
984 omitted = _(
985 omitted = _(
985 b'(some details hidden, use --verbose'
986 b'(some details hidden, use --verbose'
986 b' to show complete help)'
987 b' to show complete help)'
987 )
988 )
988 indicateomitted(rst, omitted)
989 indicateomitted(rst, omitted)
989
990
990 try:
991 try:
991 cmdutil.findcmd(name, commands.table)
992 cmdutil.findcmd(name, commands.table)
992 rst.append(
993 rst.append(
993 _(b"\nuse 'hg help -c %s' to see help for the %s command\n")
994 _(b"\nuse 'hg help -c %s' to see help for the %s command\n")
994 % (name, name)
995 % (name, name)
995 )
996 )
996 except error.UnknownCommand:
997 except error.UnknownCommand:
997 pass
998 pass
998 return rst
999 return rst
999
1000
1000 def helpext(name, subtopic=None):
1001 def helpext(name, subtopic=None):
1001 try:
1002 try:
1002 mod = extensions.find(name)
1003 mod = extensions.find(name)
1003 doc = gettext(pycompat.getdoc(mod)) or _(b'no help text available')
1004 doc = gettext(pycompat.getdoc(mod)) or _(b'no help text available')
1004 except KeyError:
1005 except KeyError:
1005 mod = None
1006 mod = None
1006 doc = extensions.disabled_help(name)
1007 doc = extensions.disabled_help(name)
1007 if not doc:
1008 if not doc:
1008 raise error.UnknownCommand(name)
1009 raise error.UnknownCommand(name)
1009
1010
1010 if b'\n' not in doc:
1011 if b'\n' not in doc:
1011 head, tail = doc, b""
1012 head, tail = doc, b""
1012 else:
1013 else:
1013 head, tail = doc.split(b'\n', 1)
1014 head, tail = doc.split(b'\n', 1)
1014 rst = [_(b'%s extension - %s\n\n') % (name.rpartition(b'.')[-1], head)]
1015 rst = [_(b'%s extension - %s\n\n') % (name.rpartition(b'.')[-1], head)]
1015 if tail:
1016 if tail:
1016 rst.extend(tail.splitlines(True))
1017 rst.extend(tail.splitlines(True))
1017 rst.append(b'\n')
1018 rst.append(b'\n')
1018
1019
1019 if not ui.verbose:
1020 if not ui.verbose:
1020 omitted = _(
1021 omitted = _(
1021 b'(some details hidden, use --verbose'
1022 b'(some details hidden, use --verbose'
1022 b' to show complete help)'
1023 b' to show complete help)'
1023 )
1024 )
1024 indicateomitted(rst, omitted)
1025 indicateomitted(rst, omitted)
1025
1026
1026 if mod:
1027 if mod:
1027 try:
1028 try:
1028 ct = mod.cmdtable
1029 ct = mod.cmdtable
1029 except AttributeError:
1030 except AttributeError:
1030 ct = {}
1031 ct = {}
1031 modcmds = {c.partition(b'|')[0] for c in ct}
1032 modcmds = {c.partition(b'|')[0] for c in ct}
1032 rst.extend(helplist(modcmds.__contains__))
1033 rst.extend(helplist(modcmds.__contains__))
1033 else:
1034 else:
1034 rst.append(
1035 rst.append(
1035 _(
1036 _(
1036 b"(use 'hg help extensions' for information on enabling"
1037 b"(use 'hg help extensions' for information on enabling"
1037 b" extensions)\n"
1038 b" extensions)\n"
1038 )
1039 )
1039 )
1040 )
1040 return rst
1041 return rst
1041
1042
1042 def helpextcmd(name, subtopic=None):
1043 def helpextcmd(name, subtopic=None):
1043 cmd, ext, doc = extensions.disabledcmd(
1044 cmd, ext, doc = extensions.disabledcmd(
1044 ui, name, ui.configbool(b'ui', b'strict')
1045 ui, name, ui.configbool(b'ui', b'strict')
1045 )
1046 )
1046 doc = stringutil.firstline(doc)
1047 doc = stringutil.firstline(doc)
1047
1048
1048 rst = listexts(
1049 rst = listexts(
1049 _(b"'%s' is provided by the following extension:") % cmd,
1050 _(b"'%s' is provided by the following extension:") % cmd,
1050 {ext: doc},
1051 {ext: doc},
1051 indent=4,
1052 indent=4,
1052 showdeprecated=True,
1053 showdeprecated=True,
1053 )
1054 )
1054 rst.append(b'\n')
1055 rst.append(b'\n')
1055 rst.append(
1056 rst.append(
1056 _(
1057 _(
1057 b"(use 'hg help extensions' for information on enabling "
1058 b"(use 'hg help extensions' for information on enabling "
1058 b"extensions)\n"
1059 b"extensions)\n"
1059 )
1060 )
1060 )
1061 )
1061 return rst
1062 return rst
1062
1063
1063 rst = []
1064 rst = []
1064 kw = opts.get(b'keyword')
1065 kw = opts.get(b'keyword')
1065 if kw or name is None and any(opts[o] for o in opts):
1066 if kw or name is None and any(opts[o] for o in opts):
1066 matches = topicmatch(ui, commands, name or b'')
1067 matches = topicmatch(ui, commands, name or b'')
1067 helpareas = []
1068 helpareas = []
1068 if opts.get(b'extension'):
1069 if opts.get(b'extension'):
1069 helpareas += [(b'extensions', _(b'Extensions'))]
1070 helpareas += [(b'extensions', _(b'Extensions'))]
1070 if opts.get(b'command'):
1071 if opts.get(b'command'):
1071 helpareas += [(b'commands', _(b'Commands'))]
1072 helpareas += [(b'commands', _(b'Commands'))]
1072 if not helpareas:
1073 if not helpareas:
1073 helpareas = [
1074 helpareas = [
1074 (b'topics', _(b'Topics')),
1075 (b'topics', _(b'Topics')),
1075 (b'commands', _(b'Commands')),
1076 (b'commands', _(b'Commands')),
1076 (b'extensions', _(b'Extensions')),
1077 (b'extensions', _(b'Extensions')),
1077 (b'extensioncommands', _(b'Extension Commands')),
1078 (b'extensioncommands', _(b'Extension Commands')),
1078 ]
1079 ]
1079 for t, title in helpareas:
1080 for t, title in helpareas:
1080 if matches[t]:
1081 if matches[t]:
1081 rst.append(b'%s:\n\n' % title)
1082 rst.append(b'%s:\n\n' % title)
1082 rst.extend(minirst.maketable(sorted(matches[t]), 1))
1083 rst.extend(minirst.maketable(sorted(matches[t]), 1))
1083 rst.append(b'\n')
1084 rst.append(b'\n')
1084 if not rst:
1085 if not rst:
1085 msg = _(b'no matches')
1086 msg = _(b'no matches')
1086 hint = _(b"try 'hg help' for a list of topics")
1087 hint = _(b"try 'hg help' for a list of topics")
1087 raise error.InputError(msg, hint=hint)
1088 raise error.InputError(msg, hint=hint)
1088 elif name and name != b'shortlist':
1089 elif name and name != b'shortlist':
1089 queries = []
1090 queries = []
1090 if unknowncmd:
1091 if unknowncmd:
1091 queries += [helpextcmd]
1092 queries += [helpextcmd]
1092 if opts.get(b'extension'):
1093 if opts.get(b'extension'):
1093 queries += [helpext]
1094 queries += [helpext]
1094 if opts.get(b'command'):
1095 if opts.get(b'command'):
1095 queries += [helpcmd]
1096 queries += [helpcmd]
1096 if not queries:
1097 if not queries:
1097 queries = (helptopic, helpcmd, helpext, helpextcmd)
1098 queries = (helptopic, helpcmd, helpext, helpextcmd)
1098 for f in queries:
1099 for f in queries:
1099 try:
1100 try:
1100 rst = f(name, subtopic)
1101 rst = f(name, subtopic)
1101 break
1102 break
1102 except error.UnknownCommand:
1103 except error.UnknownCommand:
1103 pass
1104 pass
1104 else:
1105 else:
1105 if unknowncmd:
1106 if unknowncmd:
1106 raise error.UnknownCommand(name)
1107 raise error.UnknownCommand(name)
1107 else:
1108 else:
1108 if fullname:
1109 if fullname:
1109 formatname = fullname
1110 formatname = fullname
1110 else:
1111 else:
1111 formatname = name
1112 formatname = name
1112 if subtopic:
1113 if subtopic:
1113 hintname = subtopic
1114 hintname = subtopic
1114 else:
1115 else:
1115 hintname = name
1116 hintname = name
1116 msg = _(b'no such help topic: %s') % formatname
1117 msg = _(b'no such help topic: %s') % formatname
1117 hint = _(b"try 'hg help --keyword %s'") % hintname
1118 hint = _(b"try 'hg help --keyword %s'") % hintname
1118 raise error.InputError(msg, hint=hint)
1119 raise error.InputError(msg, hint=hint)
1119 else:
1120 else:
1120 # program name
1121 # program name
1121 if not ui.quiet:
1122 if not ui.quiet:
1122 rst = [_(b"Mercurial Distributed SCM\n"), b'\n']
1123 rst = [_(b"Mercurial Distributed SCM\n"), b'\n']
1123 rst.extend(helplist(None, **pycompat.strkwargs(opts)))
1124 rst.extend(helplist(None, **pycompat.strkwargs(opts)))
1124
1125
1125 return b''.join(rst)
1126 return b''.join(rst)
1126
1127
1127
1128
1128 def formattedhelp(
1129 def formattedhelp(
1129 ui, commands, fullname, keep=None, unknowncmd=False, full=True, **opts
1130 ui, commands, fullname, keep=None, unknowncmd=False, full=True, **opts
1130 ):
1131 ):
1131 """get help for a given topic (as a dotted name) as rendered rst
1132 """get help for a given topic (as a dotted name) as rendered rst
1132
1133
1133 Either returns the rendered help text or raises an exception.
1134 Either returns the rendered help text or raises an exception.
1134 """
1135 """
1135 if keep is None:
1136 if keep is None:
1136 keep = []
1137 keep = []
1137 else:
1138 else:
1138 keep = list(keep) # make a copy so we can mutate this later
1139 keep = list(keep) # make a copy so we can mutate this later
1139
1140
1140 # <fullname> := <name>[.<subtopic][.<section>]
1141 # <fullname> := <name>[.<subtopic][.<section>]
1141 name = subtopic = section = None
1142 name = subtopic = section = None
1142 if fullname is not None:
1143 if fullname is not None:
1143 nameparts = fullname.split(b'.')
1144 nameparts = fullname.split(b'.')
1144 name = nameparts.pop(0)
1145 name = nameparts.pop(0)
1145 if nameparts and name in subtopics:
1146 if nameparts and name in subtopics:
1146 subtopic = nameparts.pop(0)
1147 subtopic = nameparts.pop(0)
1147 if nameparts:
1148 if nameparts:
1148 section = encoding.lower(b'.'.join(nameparts))
1149 section = encoding.lower(b'.'.join(nameparts))
1149
1150
1150 textwidth = ui.configint(b'ui', b'textwidth')
1151 textwidth = ui.configint(b'ui', b'textwidth')
1151 termwidth = ui.termwidth() - 2
1152 termwidth = ui.termwidth() - 2
1152 if textwidth <= 0 or termwidth < textwidth:
1153 if textwidth <= 0 or termwidth < textwidth:
1153 textwidth = termwidth
1154 textwidth = termwidth
1154 text = help_(
1155 text = help_(
1155 ui,
1156 ui,
1156 commands,
1157 commands,
1157 name,
1158 name,
1158 fullname=fullname,
1159 fullname=fullname,
1159 subtopic=subtopic,
1160 subtopic=subtopic,
1160 unknowncmd=unknowncmd,
1161 unknowncmd=unknowncmd,
1161 full=full,
1162 full=full,
1162 **opts
1163 **opts
1163 )
1164 )
1164
1165
1165 blocks, pruned = minirst.parse(text, keep=keep)
1166 blocks, pruned = minirst.parse(text, keep=keep)
1166 if b'verbose' in pruned:
1167 if b'verbose' in pruned:
1167 keep.append(b'omitted')
1168 keep.append(b'omitted')
1168 else:
1169 else:
1169 keep.append(b'notomitted')
1170 keep.append(b'notomitted')
1170 blocks, pruned = minirst.parse(text, keep=keep)
1171 blocks, pruned = minirst.parse(text, keep=keep)
1171 if section:
1172 if section:
1172 blocks = minirst.filtersections(blocks, section)
1173 blocks = minirst.filtersections(blocks, section)
1173
1174
1174 # We could have been given a weird ".foo" section without a name
1175 # We could have been given a weird ".foo" section without a name
1175 # to look for, or we could have simply failed to found "foo.bar"
1176 # to look for, or we could have simply failed to found "foo.bar"
1176 # because bar isn't a section of foo
1177 # because bar isn't a section of foo
1177 if section and not (blocks and name):
1178 if section and not (blocks and name):
1178 raise error.InputError(_(b"help section not found: %s") % fullname)
1179 raise error.InputError(_(b"help section not found: %s") % fullname)
1179
1180
1180 return minirst.formatplain(blocks, textwidth)
1181 return minirst.formatplain(blocks, textwidth)
@@ -1,3287 +1,3332 b''
1 The Mercurial system uses a set of configuration files to control
1 The Mercurial system uses a set of configuration files to control
2 aspects of its behavior.
2 aspects of its behavior.
3
3
4 Troubleshooting
4 Troubleshooting
5 ===============
5 ===============
6
6
7 If you're having problems with your configuration,
7 If you're having problems with your configuration,
8 :hg:`config --source` can help you understand what is introducing
8 :hg:`config --source` can help you understand what is introducing
9 a setting into your environment.
9 a setting into your environment.
10
10
11 See :hg:`help config.syntax` and :hg:`help config.files`
11 See :hg:`help config.syntax` and :hg:`help config.files`
12 for information about how and where to override things.
12 for information about how and where to override things.
13
13
14 Structure
14 Structure
15 =========
15 =========
16
16
17 The configuration files use a simple ini-file format. A configuration
17 The configuration files use a simple ini-file format. A configuration
18 file consists of sections, led by a ``[section]`` header and followed
18 file consists of sections, led by a ``[section]`` header and followed
19 by ``name = value`` entries::
19 by ``name = value`` entries::
20
20
21 [ui]
21 [ui]
22 username = Firstname Lastname <firstname.lastname@example.net>
22 username = Firstname Lastname <firstname.lastname@example.net>
23 verbose = True
23 verbose = True
24
24
25 The above entries will be referred to as ``ui.username`` and
25 The above entries will be referred to as ``ui.username`` and
26 ``ui.verbose``, respectively. See :hg:`help config.syntax`.
26 ``ui.verbose``, respectively. See :hg:`help config.syntax`.
27
27
28 Files
28 Files
29 =====
29 =====
30
30
31 Mercurial reads configuration data from several files, if they exist.
31 Mercurial reads configuration data from several files, if they exist.
32 These files do not exist by default and you will have to create the
32 These files do not exist by default and you will have to create the
33 appropriate configuration files yourself:
33 appropriate configuration files yourself:
34
34
35 Local configuration is put into the per-repository ``<repo>/.hg/hgrc`` file.
35 Local configuration is put into the per-repository ``<repo>/.hg/hgrc`` file.
36
36
37 Global configuration like the username setting is typically put into:
37 Global configuration like the username setting is typically put into:
38
38
39 .. container:: windows
39 .. container:: windows
40
40
41 - ``%USERPROFILE%\mercurial.ini`` (on Windows)
41 - ``%USERPROFILE%\mercurial.ini`` (on Windows)
42
42
43 .. container:: unix.plan9
43 .. container:: unix.plan9
44
44
45 - ``$HOME/.hgrc`` (on Unix, Plan9)
45 - ``$HOME/.hgrc`` (on Unix, Plan9)
46
46
47 The names of these files depend on the system on which Mercurial is
47 The names of these files depend on the system on which Mercurial is
48 installed. ``*.rc`` files from a single directory are read in
48 installed. ``*.rc`` files from a single directory are read in
49 alphabetical order, later ones overriding earlier ones. Where multiple
49 alphabetical order, later ones overriding earlier ones. Where multiple
50 paths are given below, settings from earlier paths override later
50 paths are given below, settings from earlier paths override later
51 ones.
51 ones.
52
52
53 .. container:: verbose.unix
53 .. container:: verbose.unix
54
54
55 On Unix, the following files are consulted:
55 On Unix, the following files are consulted:
56
56
57 - ``<repo>/.hg/hgrc-not-shared`` (per-repository)
57 - ``<repo>/.hg/hgrc-not-shared`` (per-repository)
58 - ``<repo>/.hg/hgrc`` (per-repository)
58 - ``<repo>/.hg/hgrc`` (per-repository)
59 - ``$HOME/.hgrc`` (per-user)
59 - ``$HOME/.hgrc`` (per-user)
60 - ``${XDG_CONFIG_HOME:-$HOME/.config}/hg/hgrc`` (per-user)
60 - ``${XDG_CONFIG_HOME:-$HOME/.config}/hg/hgrc`` (per-user)
61 - ``<install-root>/etc/mercurial/hgrc`` (per-installation)
61 - ``<install-root>/etc/mercurial/hgrc`` (per-installation)
62 - ``<install-root>/etc/mercurial/hgrc.d/*.rc`` (per-installation)
62 - ``<install-root>/etc/mercurial/hgrc.d/*.rc`` (per-installation)
63 - ``/etc/mercurial/hgrc`` (per-system)
63 - ``/etc/mercurial/hgrc`` (per-system)
64 - ``/etc/mercurial/hgrc.d/*.rc`` (per-system)
64 - ``/etc/mercurial/hgrc.d/*.rc`` (per-system)
65 - ``<internal>/*.rc`` (defaults)
65 - ``<internal>/*.rc`` (defaults)
66
66
67 .. container:: verbose.windows
67 .. container:: verbose.windows
68
68
69 On Windows, the following files are consulted:
69 On Windows, the following files are consulted:
70
70
71 - ``<repo>/.hg/hgrc-not-shared`` (per-repository)
71 - ``<repo>/.hg/hgrc-not-shared`` (per-repository)
72 - ``<repo>/.hg/hgrc`` (per-repository)
72 - ``<repo>/.hg/hgrc`` (per-repository)
73 - ``%USERPROFILE%\.hgrc`` (per-user)
73 - ``%USERPROFILE%\.hgrc`` (per-user)
74 - ``%USERPROFILE%\Mercurial.ini`` (per-user)
74 - ``%USERPROFILE%\Mercurial.ini`` (per-user)
75 - ``%HOME%\.hgrc`` (per-user)
75 - ``%HOME%\.hgrc`` (per-user)
76 - ``%HOME%\Mercurial.ini`` (per-user)
76 - ``%HOME%\Mercurial.ini`` (per-user)
77 - ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial`` (per-system)
77 - ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial`` (per-system)
78 - ``<install-dir>\hgrc.d\*.rc`` (per-installation)
78 - ``<install-dir>\hgrc.d\*.rc`` (per-installation)
79 - ``<install-dir>\Mercurial.ini`` (per-installation)
79 - ``<install-dir>\Mercurial.ini`` (per-installation)
80 - ``%PROGRAMDATA%\Mercurial\hgrc`` (per-system)
80 - ``%PROGRAMDATA%\Mercurial\hgrc`` (per-system)
81 - ``%PROGRAMDATA%\Mercurial\Mercurial.ini`` (per-system)
81 - ``%PROGRAMDATA%\Mercurial\Mercurial.ini`` (per-system)
82 - ``%PROGRAMDATA%\Mercurial\hgrc.d\*.rc`` (per-system)
82 - ``%PROGRAMDATA%\Mercurial\hgrc.d\*.rc`` (per-system)
83 - ``<internal>/*.rc`` (defaults)
83 - ``<internal>/*.rc`` (defaults)
84
84
85 .. note::
85 .. note::
86
86
87 The registry key ``HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Mercurial``
87 The registry key ``HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Mercurial``
88 is used when running 32-bit Python on 64-bit Windows.
88 is used when running 32-bit Python on 64-bit Windows.
89
89
90 .. container:: verbose.plan9
90 .. container:: verbose.plan9
91
91
92 On Plan9, the following files are consulted:
92 On Plan9, the following files are consulted:
93
93
94 - ``<repo>/.hg/hgrc-not-shared`` (per-repository)
94 - ``<repo>/.hg/hgrc-not-shared`` (per-repository)
95 - ``<repo>/.hg/hgrc`` (per-repository)
95 - ``<repo>/.hg/hgrc`` (per-repository)
96 - ``$home/lib/hgrc`` (per-user)
96 - ``$home/lib/hgrc`` (per-user)
97 - ``<install-root>/lib/mercurial/hgrc`` (per-installation)
97 - ``<install-root>/lib/mercurial/hgrc`` (per-installation)
98 - ``<install-root>/lib/mercurial/hgrc.d/*.rc`` (per-installation)
98 - ``<install-root>/lib/mercurial/hgrc.d/*.rc`` (per-installation)
99 - ``/lib/mercurial/hgrc`` (per-system)
99 - ``/lib/mercurial/hgrc`` (per-system)
100 - ``/lib/mercurial/hgrc.d/*.rc`` (per-system)
100 - ``/lib/mercurial/hgrc.d/*.rc`` (per-system)
101 - ``<internal>/*.rc`` (defaults)
101 - ``<internal>/*.rc`` (defaults)
102
102
103 Per-repository configuration options only apply in a
103 Per-repository configuration options only apply in a
104 particular repository. This file is not version-controlled, and
104 particular repository. This file is not version-controlled, and
105 will not get transferred during a "clone" operation. Options in
105 will not get transferred during a "clone" operation. Options in
106 this file override options in all other configuration files.
106 this file override options in all other configuration files.
107
107
108 .. container:: unix.plan9
108 .. container:: unix.plan9
109
109
110 On Plan 9 and Unix, most of this file will be ignored if it doesn't
110 On Plan 9 and Unix, most of this file will be ignored if it doesn't
111 belong to a trusted user or to a trusted group. See
111 belong to a trusted user or to a trusted group. See
112 :hg:`help config.trusted` for more details.
112 :hg:`help config.trusted` for more details.
113
113
114 Per-user configuration file(s) are for the user running Mercurial. Options
114 Per-user configuration file(s) are for the user running Mercurial. Options
115 in these files apply to all Mercurial commands executed by this user in any
115 in these files apply to all Mercurial commands executed by this user in any
116 directory. Options in these files override per-system and per-installation
116 directory. Options in these files override per-system and per-installation
117 options.
117 options.
118
118
119 Per-installation configuration files are searched for in the
119 Per-installation configuration files are searched for in the
120 directory where Mercurial is installed. ``<install-root>`` is the
120 directory where Mercurial is installed. ``<install-root>`` is the
121 parent directory of the **hg** executable (or symlink) being run.
121 parent directory of the **hg** executable (or symlink) being run.
122
122
123 .. container:: unix.plan9
123 .. container:: unix.plan9
124
124
125 For example, if installed in ``/shared/tools/bin/hg``, Mercurial
125 For example, if installed in ``/shared/tools/bin/hg``, Mercurial
126 will look in ``/shared/tools/etc/mercurial/hgrc``. Options in these
126 will look in ``/shared/tools/etc/mercurial/hgrc``. Options in these
127 files apply to all Mercurial commands executed by any user in any
127 files apply to all Mercurial commands executed by any user in any
128 directory.
128 directory.
129
129
130 Per-installation configuration files are for the system on
130 Per-installation configuration files are for the system on
131 which Mercurial is running. Options in these files apply to all
131 which Mercurial is running. Options in these files apply to all
132 Mercurial commands executed by any user in any directory. Registry
132 Mercurial commands executed by any user in any directory. Registry
133 keys contain PATH-like strings, every part of which must reference
133 keys contain PATH-like strings, every part of which must reference
134 a ``Mercurial.ini`` file or be a directory where ``*.rc`` files will
134 a ``Mercurial.ini`` file or be a directory where ``*.rc`` files will
135 be read. Mercurial checks each of these locations in the specified
135 be read. Mercurial checks each of these locations in the specified
136 order until one or more configuration files are detected.
136 order until one or more configuration files are detected.
137
137
138 Per-system configuration files are for the system on which Mercurial
138 Per-system configuration files are for the system on which Mercurial
139 is running. Options in these files apply to all Mercurial commands
139 is running. Options in these files apply to all Mercurial commands
140 executed by any user in any directory. Options in these files
140 executed by any user in any directory. Options in these files
141 override per-installation options.
141 override per-installation options.
142
142
143 Mercurial comes with some default configuration. The default configuration
143 Mercurial comes with some default configuration. The default configuration
144 files are installed with Mercurial and will be overwritten on upgrades. Default
144 files are installed with Mercurial and will be overwritten on upgrades. Default
145 configuration files should never be edited by users or administrators but can
145 configuration files should never be edited by users or administrators but can
146 be overridden in other configuration files. So far the directory only contains
146 be overridden in other configuration files. So far the directory only contains
147 merge tool configuration but packagers can also put other default configuration
147 merge tool configuration but packagers can also put other default configuration
148 there.
148 there.
149
149
150 On versions 5.7 and later, if share-safe functionality is enabled,
150 On versions 5.7 and later, if share-safe functionality is enabled,
151 shares will read config file of share source too.
151 shares will read config file of share source too.
152 `<share-source/.hg/hgrc>` is read before reading `<repo/.hg/hgrc>`.
152 `<share-source/.hg/hgrc>` is read before reading `<repo/.hg/hgrc>`.
153
153
154 For configs which should not be shared, `<repo/.hg/hgrc-not-shared>`
154 For configs which should not be shared, `<repo/.hg/hgrc-not-shared>`
155 should be used.
155 should be used.
156
156
157 Syntax
157 Syntax
158 ======
158 ======
159
159
160 A configuration file consists of sections, led by a ``[section]`` header
160 A configuration file consists of sections, led by a ``[section]`` header
161 and followed by ``name = value`` entries (sometimes called
161 and followed by ``name = value`` entries (sometimes called
162 ``configuration keys``)::
162 ``configuration keys``)::
163
163
164 [spam]
164 [spam]
165 eggs=ham
165 eggs=ham
166 green=
166 green=
167 eggs
167 eggs
168
168
169 Each line contains one entry. If the lines that follow are indented,
169 Each line contains one entry. If the lines that follow are indented,
170 they are treated as continuations of that entry. Leading whitespace is
170 they are treated as continuations of that entry. Leading whitespace is
171 removed from values. Empty lines are skipped. Lines beginning with
171 removed from values. Empty lines are skipped. Lines beginning with
172 ``#`` or ``;`` are ignored and may be used to provide comments.
172 ``#`` or ``;`` are ignored and may be used to provide comments.
173
173
174 Configuration keys can be set multiple times, in which case Mercurial
174 Configuration keys can be set multiple times, in which case Mercurial
175 will use the value that was configured last. As an example::
175 will use the value that was configured last. As an example::
176
176
177 [spam]
177 [spam]
178 eggs=large
178 eggs=large
179 ham=serrano
179 ham=serrano
180 eggs=small
180 eggs=small
181
181
182 This would set the configuration key named ``eggs`` to ``small``.
182 This would set the configuration key named ``eggs`` to ``small``.
183
183
184 It is also possible to define a section multiple times. A section can
184 It is also possible to define a section multiple times. A section can
185 be redefined on the same and/or on different configuration files. For
185 be redefined on the same and/or on different configuration files. For
186 example::
186 example::
187
187
188 [foo]
188 [foo]
189 eggs=large
189 eggs=large
190 ham=serrano
190 ham=serrano
191 eggs=small
191 eggs=small
192
192
193 [bar]
193 [bar]
194 eggs=ham
194 eggs=ham
195 green=
195 green=
196 eggs
196 eggs
197
197
198 [foo]
198 [foo]
199 ham=prosciutto
199 ham=prosciutto
200 eggs=medium
200 eggs=medium
201 bread=toasted
201 bread=toasted
202
202
203 This would set the ``eggs``, ``ham``, and ``bread`` configuration keys
203 This would set the ``eggs``, ``ham``, and ``bread`` configuration keys
204 of the ``foo`` section to ``medium``, ``prosciutto``, and ``toasted``,
204 of the ``foo`` section to ``medium``, ``prosciutto``, and ``toasted``,
205 respectively. As you can see there only thing that matters is the last
205 respectively. As you can see there only thing that matters is the last
206 value that was set for each of the configuration keys.
206 value that was set for each of the configuration keys.
207
207
208 If a configuration key is set multiple times in different
208 If a configuration key is set multiple times in different
209 configuration files the final value will depend on the order in which
209 configuration files the final value will depend on the order in which
210 the different configuration files are read, with settings from earlier
210 the different configuration files are read, with settings from earlier
211 paths overriding later ones as described on the ``Files`` section
211 paths overriding later ones as described on the ``Files`` section
212 above.
212 above.
213
213
214 A line of the form ``%include file`` will include ``file`` into the
214 A line of the form ``%include file`` will include ``file`` into the
215 current configuration file. The inclusion is recursive, which means
215 current configuration file. The inclusion is recursive, which means
216 that included files can include other files. Filenames are relative to
216 that included files can include other files. Filenames are relative to
217 the configuration file in which the ``%include`` directive is found.
217 the configuration file in which the ``%include`` directive is found.
218 Environment variables and ``~user`` constructs are expanded in
218 Environment variables and ``~user`` constructs are expanded in
219 ``file``. This lets you do something like::
219 ``file``. This lets you do something like::
220
220
221 %include ~/.hgrc.d/$HOST.rc
221 %include ~/.hgrc.d/$HOST.rc
222
222
223 to include a different configuration file on each computer you use.
223 to include a different configuration file on each computer you use.
224
224
225 A line with ``%unset name`` will remove ``name`` from the current
225 A line with ``%unset name`` will remove ``name`` from the current
226 section, if it has been set previously.
226 section, if it has been set previously.
227
227
228 The values are either free-form text strings, lists of text strings,
228 The values are either free-form text strings, lists of text strings,
229 or Boolean values. Boolean values can be set to true using any of "1",
229 or Boolean values. Boolean values can be set to true using any of "1",
230 "yes", "true", or "on" and to false using "0", "no", "false", or "off"
230 "yes", "true", or "on" and to false using "0", "no", "false", or "off"
231 (all case insensitive).
231 (all case insensitive).
232
232
233 List values are separated by whitespace or comma, except when values are
233 List values are separated by whitespace or comma, except when values are
234 placed in double quotation marks::
234 placed in double quotation marks::
235
235
236 allow_read = "John Doe, PhD", brian, betty
236 allow_read = "John Doe, PhD", brian, betty
237
237
238 Quotation marks can be escaped by prefixing them with a backslash. Only
238 Quotation marks can be escaped by prefixing them with a backslash. Only
239 quotation marks at the beginning of a word is counted as a quotation
239 quotation marks at the beginning of a word is counted as a quotation
240 (e.g., ``foo"bar baz`` is the list of ``foo"bar`` and ``baz``).
240 (e.g., ``foo"bar baz`` is the list of ``foo"bar`` and ``baz``).
241
241
242 Sections
242 Sections
243 ========
243 ========
244
244
245 This section describes the different sections that may appear in a
245 This section describes the different sections that may appear in a
246 Mercurial configuration file, the purpose of each section, its possible
246 Mercurial configuration file, the purpose of each section, its possible
247 keys, and their possible values.
247 keys, and their possible values.
248
248
249 ``alias``
249 ``alias``
250 ---------
250 ---------
251
251
252 Defines command aliases.
252 Defines command aliases.
253
253
254 Aliases allow you to define your own commands in terms of other
254 Aliases allow you to define your own commands in terms of other
255 commands (or aliases), optionally including arguments. Positional
255 commands (or aliases), optionally including arguments. Positional
256 arguments in the form of ``$1``, ``$2``, etc. in the alias definition
256 arguments in the form of ``$1``, ``$2``, etc. in the alias definition
257 are expanded by Mercurial before execution. Positional arguments not
257 are expanded by Mercurial before execution. Positional arguments not
258 already used by ``$N`` in the definition are put at the end of the
258 already used by ``$N`` in the definition are put at the end of the
259 command to be executed.
259 command to be executed.
260
260
261 Alias definitions consist of lines of the form::
261 Alias definitions consist of lines of the form::
262
262
263 <alias> = <command> [<argument>]...
263 <alias> = <command> [<argument>]...
264
264
265 For example, this definition::
265 For example, this definition::
266
266
267 latest = log --limit 5
267 latest = log --limit 5
268
268
269 creates a new command ``latest`` that shows only the five most recent
269 creates a new command ``latest`` that shows only the five most recent
270 changesets. You can define subsequent aliases using earlier ones::
270 changesets. You can define subsequent aliases using earlier ones::
271
271
272 stable5 = latest -b stable
272 stable5 = latest -b stable
273
273
274 .. note::
274 .. note::
275
275
276 It is possible to create aliases with the same names as
276 It is possible to create aliases with the same names as
277 existing commands, which will then override the original
277 existing commands, which will then override the original
278 definitions. This is almost always a bad idea!
278 definitions. This is almost always a bad idea!
279
279
280 An alias can start with an exclamation point (``!``) to make it a
280 An alias can start with an exclamation point (``!``) to make it a
281 shell alias. A shell alias is executed with the shell and will let you
281 shell alias. A shell alias is executed with the shell and will let you
282 run arbitrary commands. As an example, ::
282 run arbitrary commands. As an example, ::
283
283
284 echo = !echo $@
284 echo = !echo $@
285
285
286 will let you do ``hg echo foo`` to have ``foo`` printed in your
286 will let you do ``hg echo foo`` to have ``foo`` printed in your
287 terminal. A better example might be::
287 terminal. A better example might be::
288
288
289 purge = !$HG status --no-status --unknown -0 re: | xargs -0 rm -f
289 purge = !$HG status --no-status --unknown -0 re: | xargs -0 rm -f
290
290
291 which will make ``hg purge`` delete all unknown files in the
291 which will make ``hg purge`` delete all unknown files in the
292 repository in the same manner as the purge extension.
292 repository in the same manner as the purge extension.
293
293
294 Positional arguments like ``$1``, ``$2``, etc. in the alias definition
294 Positional arguments like ``$1``, ``$2``, etc. in the alias definition
295 expand to the command arguments. Unmatched arguments are
295 expand to the command arguments. Unmatched arguments are
296 removed. ``$0`` expands to the alias name and ``$@`` expands to all
296 removed. ``$0`` expands to the alias name and ``$@`` expands to all
297 arguments separated by a space. ``"$@"`` (with quotes) expands to all
297 arguments separated by a space. ``"$@"`` (with quotes) expands to all
298 arguments quoted individually and separated by a space. These expansions
298 arguments quoted individually and separated by a space. These expansions
299 happen before the command is passed to the shell.
299 happen before the command is passed to the shell.
300
300
301 Shell aliases are executed in an environment where ``$HG`` expands to
301 Shell aliases are executed in an environment where ``$HG`` expands to
302 the path of the Mercurial that was used to execute the alias. This is
302 the path of the Mercurial that was used to execute the alias. This is
303 useful when you want to call further Mercurial commands in a shell
303 useful when you want to call further Mercurial commands in a shell
304 alias, as was done above for the purge alias. In addition,
304 alias, as was done above for the purge alias. In addition,
305 ``$HG_ARGS`` expands to the arguments given to Mercurial. In the ``hg
305 ``$HG_ARGS`` expands to the arguments given to Mercurial. In the ``hg
306 echo foo`` call above, ``$HG_ARGS`` would expand to ``echo foo``.
306 echo foo`` call above, ``$HG_ARGS`` would expand to ``echo foo``.
307
307
308 .. note::
308 .. note::
309
309
310 Some global configuration options such as ``-R`` are
310 Some global configuration options such as ``-R`` are
311 processed before shell aliases and will thus not be passed to
311 processed before shell aliases and will thus not be passed to
312 aliases.
312 aliases.
313
313
314
314
315 ``annotate``
315 ``annotate``
316 ------------
316 ------------
317
317
318 Settings used when displaying file annotations. All values are
318 Settings used when displaying file annotations. All values are
319 Booleans and default to False. See :hg:`help config.diff` for
319 Booleans and default to False. See :hg:`help config.diff` for
320 related options for the diff command.
320 related options for the diff command.
321
321
322 ``ignorews``
322 ``ignorews``
323 Ignore white space when comparing lines.
323 Ignore white space when comparing lines.
324
324
325 ``ignorewseol``
325 ``ignorewseol``
326 Ignore white space at the end of a line when comparing lines.
326 Ignore white space at the end of a line when comparing lines.
327
327
328 ``ignorewsamount``
328 ``ignorewsamount``
329 Ignore changes in the amount of white space.
329 Ignore changes in the amount of white space.
330
330
331 ``ignoreblanklines``
331 ``ignoreblanklines``
332 Ignore changes whose lines are all blank.
332 Ignore changes whose lines are all blank.
333
333
334
334
335 ``auth``
335 ``auth``
336 --------
336 --------
337
337
338 Authentication credentials and other authentication-like configuration
338 Authentication credentials and other authentication-like configuration
339 for HTTP connections. This section allows you to store usernames and
339 for HTTP connections. This section allows you to store usernames and
340 passwords for use when logging *into* HTTP servers. See
340 passwords for use when logging *into* HTTP servers. See
341 :hg:`help config.web` if you want to configure *who* can login to
341 :hg:`help config.web` if you want to configure *who* can login to
342 your HTTP server.
342 your HTTP server.
343
343
344 The following options apply to all hosts.
344 The following options apply to all hosts.
345
345
346 ``cookiefile``
346 ``cookiefile``
347 Path to a file containing HTTP cookie lines. Cookies matching a
347 Path to a file containing HTTP cookie lines. Cookies matching a
348 host will be sent automatically.
348 host will be sent automatically.
349
349
350 The file format uses the Mozilla cookies.txt format, which defines cookies
350 The file format uses the Mozilla cookies.txt format, which defines cookies
351 on their own lines. Each line contains 7 fields delimited by the tab
351 on their own lines. Each line contains 7 fields delimited by the tab
352 character (domain, is_domain_cookie, path, is_secure, expires, name,
352 character (domain, is_domain_cookie, path, is_secure, expires, name,
353 value). For more info, do an Internet search for "Netscape cookies.txt
353 value). For more info, do an Internet search for "Netscape cookies.txt
354 format."
354 format."
355
355
356 Note: the cookies parser does not handle port numbers on domains. You
356 Note: the cookies parser does not handle port numbers on domains. You
357 will need to remove ports from the domain for the cookie to be recognized.
357 will need to remove ports from the domain for the cookie to be recognized.
358 This could result in a cookie being disclosed to an unwanted server.
358 This could result in a cookie being disclosed to an unwanted server.
359
359
360 The cookies file is read-only.
360 The cookies file is read-only.
361
361
362 Other options in this section are grouped by name and have the following
362 Other options in this section are grouped by name and have the following
363 format::
363 format::
364
364
365 <name>.<argument> = <value>
365 <name>.<argument> = <value>
366
366
367 where ``<name>`` is used to group arguments into authentication
367 where ``<name>`` is used to group arguments into authentication
368 entries. Example::
368 entries. Example::
369
369
370 foo.prefix = hg.intevation.de/mercurial
370 foo.prefix = hg.intevation.de/mercurial
371 foo.username = foo
371 foo.username = foo
372 foo.password = bar
372 foo.password = bar
373 foo.schemes = http https
373 foo.schemes = http https
374
374
375 bar.prefix = secure.example.org
375 bar.prefix = secure.example.org
376 bar.key = path/to/file.key
376 bar.key = path/to/file.key
377 bar.cert = path/to/file.cert
377 bar.cert = path/to/file.cert
378 bar.schemes = https
378 bar.schemes = https
379
379
380 Supported arguments:
380 Supported arguments:
381
381
382 ``prefix``
382 ``prefix``
383 Either ``*`` or a URI prefix with or without the scheme part.
383 Either ``*`` or a URI prefix with or without the scheme part.
384 The authentication entry with the longest matching prefix is used
384 The authentication entry with the longest matching prefix is used
385 (where ``*`` matches everything and counts as a match of length
385 (where ``*`` matches everything and counts as a match of length
386 1). If the prefix doesn't include a scheme, the match is performed
386 1). If the prefix doesn't include a scheme, the match is performed
387 against the URI with its scheme stripped as well, and the schemes
387 against the URI with its scheme stripped as well, and the schemes
388 argument, q.v., is then subsequently consulted.
388 argument, q.v., is then subsequently consulted.
389
389
390 ``username``
390 ``username``
391 Optional. Username to authenticate with. If not given, and the
391 Optional. Username to authenticate with. If not given, and the
392 remote site requires basic or digest authentication, the user will
392 remote site requires basic or digest authentication, the user will
393 be prompted for it. Environment variables are expanded in the
393 be prompted for it. Environment variables are expanded in the
394 username letting you do ``foo.username = $USER``. If the URI
394 username letting you do ``foo.username = $USER``. If the URI
395 includes a username, only ``[auth]`` entries with a matching
395 includes a username, only ``[auth]`` entries with a matching
396 username or without a username will be considered.
396 username or without a username will be considered.
397
397
398 ``password``
398 ``password``
399 Optional. Password to authenticate with. If not given, and the
399 Optional. Password to authenticate with. If not given, and the
400 remote site requires basic or digest authentication, the user
400 remote site requires basic or digest authentication, the user
401 will be prompted for it.
401 will be prompted for it.
402
402
403 ``key``
403 ``key``
404 Optional. PEM encoded client certificate key file. Environment
404 Optional. PEM encoded client certificate key file. Environment
405 variables are expanded in the filename.
405 variables are expanded in the filename.
406
406
407 ``cert``
407 ``cert``
408 Optional. PEM encoded client certificate chain file. Environment
408 Optional. PEM encoded client certificate chain file. Environment
409 variables are expanded in the filename.
409 variables are expanded in the filename.
410
410
411 ``schemes``
411 ``schemes``
412 Optional. Space separated list of URI schemes to use this
412 Optional. Space separated list of URI schemes to use this
413 authentication entry with. Only used if the prefix doesn't include
413 authentication entry with. Only used if the prefix doesn't include
414 a scheme. Supported schemes are http and https. They will match
414 a scheme. Supported schemes are http and https. They will match
415 static-http and static-https respectively, as well.
415 static-http and static-https respectively, as well.
416 (default: https)
416 (default: https)
417
417
418 If no suitable authentication entry is found, the user is prompted
418 If no suitable authentication entry is found, the user is prompted
419 for credentials as usual if required by the remote.
419 for credentials as usual if required by the remote.
420
420
421 ``cmdserver``
421 ``cmdserver``
422 -------------
422 -------------
423
423
424 Controls command server settings. (ADVANCED)
424 Controls command server settings. (ADVANCED)
425
425
426 ``message-encodings``
426 ``message-encodings``
427 List of encodings for the ``m`` (message) channel. The first encoding
427 List of encodings for the ``m`` (message) channel. The first encoding
428 supported by the server will be selected and advertised in the hello
428 supported by the server will be selected and advertised in the hello
429 message. This is useful only when ``ui.message-output`` is set to
429 message. This is useful only when ``ui.message-output`` is set to
430 ``channel``. Supported encodings are ``cbor``.
430 ``channel``. Supported encodings are ``cbor``.
431
431
432 ``shutdown-on-interrupt``
432 ``shutdown-on-interrupt``
433 If set to false, the server's main loop will continue running after
433 If set to false, the server's main loop will continue running after
434 SIGINT received. ``runcommand`` requests can still be interrupted by
434 SIGINT received. ``runcommand`` requests can still be interrupted by
435 SIGINT. Close the write end of the pipe to shut down the server
435 SIGINT. Close the write end of the pipe to shut down the server
436 process gracefully.
436 process gracefully.
437 (default: True)
437 (default: True)
438
438
439 ``color``
439 ``color``
440 ---------
440 ---------
441
441
442 Configure the Mercurial color mode. For details about how to define your custom
442 Configure the Mercurial color mode. For details about how to define your custom
443 effect and style see :hg:`help color`.
443 effect and style see :hg:`help color`.
444
444
445 ``mode``
445 ``mode``
446 String: control the method used to output color. One of ``auto``, ``ansi``,
446 String: control the method used to output color. One of ``auto``, ``ansi``,
447 ``win32``, ``terminfo`` or ``debug``. In auto mode, Mercurial will
447 ``win32``, ``terminfo`` or ``debug``. In auto mode, Mercurial will
448 use ANSI mode by default (or win32 mode prior to Windows 10) if it detects a
448 use ANSI mode by default (or win32 mode prior to Windows 10) if it detects a
449 terminal. Any invalid value will disable color.
449 terminal. Any invalid value will disable color.
450
450
451 ``pagermode``
451 ``pagermode``
452 String: optional override of ``color.mode`` used with pager.
452 String: optional override of ``color.mode`` used with pager.
453
453
454 On some systems, terminfo mode may cause problems when using
454 On some systems, terminfo mode may cause problems when using
455 color with ``less -R`` as a pager program. less with the -R option
455 color with ``less -R`` as a pager program. less with the -R option
456 will only display ECMA-48 color codes, and terminfo mode may sometimes
456 will only display ECMA-48 color codes, and terminfo mode may sometimes
457 emit codes that less doesn't understand. You can work around this by
457 emit codes that less doesn't understand. You can work around this by
458 either using ansi mode (or auto mode), or by using less -r (which will
458 either using ansi mode (or auto mode), or by using less -r (which will
459 pass through all terminal control codes, not just color control
459 pass through all terminal control codes, not just color control
460 codes).
460 codes).
461
461
462 On some systems (such as MSYS in Windows), the terminal may support
462 On some systems (such as MSYS in Windows), the terminal may support
463 a different color mode than the pager program.
463 a different color mode than the pager program.
464
464
465 ``commands``
465 ``commands``
466 ------------
466 ------------
467
467
468 ``commit.post-status``
468 ``commit.post-status``
469 Show status of files in the working directory after successful commit.
469 Show status of files in the working directory after successful commit.
470 (default: False)
470 (default: False)
471
471
472 ``merge.require-rev``
472 ``merge.require-rev``
473 Require that the revision to merge the current commit with be specified on
473 Require that the revision to merge the current commit with be specified on
474 the command line. If this is enabled and a revision is not specified, the
474 the command line. If this is enabled and a revision is not specified, the
475 command aborts.
475 command aborts.
476 (default: False)
476 (default: False)
477
477
478 ``push.require-revs``
478 ``push.require-revs``
479 Require revisions to push be specified using one or more mechanisms such as
479 Require revisions to push be specified using one or more mechanisms such as
480 specifying them positionally on the command line, using ``-r``, ``-b``,
480 specifying them positionally on the command line, using ``-r``, ``-b``,
481 and/or ``-B`` on the command line, or using ``paths.<path>:pushrev`` in the
481 and/or ``-B`` on the command line, or using ``paths.<path>:pushrev`` in the
482 configuration. If this is enabled and revisions are not specified, the
482 configuration. If this is enabled and revisions are not specified, the
483 command aborts.
483 command aborts.
484 (default: False)
484 (default: False)
485
485
486 ``resolve.confirm``
486 ``resolve.confirm``
487 Confirm before performing action if no filename is passed.
487 Confirm before performing action if no filename is passed.
488 (default: False)
488 (default: False)
489
489
490 ``resolve.explicit-re-merge``
490 ``resolve.explicit-re-merge``
491 Require uses of ``hg resolve`` to specify which action it should perform,
491 Require uses of ``hg resolve`` to specify which action it should perform,
492 instead of re-merging files by default.
492 instead of re-merging files by default.
493 (default: False)
493 (default: False)
494
494
495 ``resolve.mark-check``
495 ``resolve.mark-check``
496 Determines what level of checking :hg:`resolve --mark` will perform before
496 Determines what level of checking :hg:`resolve --mark` will perform before
497 marking files as resolved. Valid values are ``none`, ``warn``, and
497 marking files as resolved. Valid values are ``none`, ``warn``, and
498 ``abort``. ``warn`` will output a warning listing the file(s) that still
498 ``abort``. ``warn`` will output a warning listing the file(s) that still
499 have conflict markers in them, but will still mark everything resolved.
499 have conflict markers in them, but will still mark everything resolved.
500 ``abort`` will output the same warning but will not mark things as resolved.
500 ``abort`` will output the same warning but will not mark things as resolved.
501 If --all is passed and this is set to ``abort``, only a warning will be
501 If --all is passed and this is set to ``abort``, only a warning will be
502 shown (an error will not be raised).
502 shown (an error will not be raised).
503 (default: ``none``)
503 (default: ``none``)
504
504
505 ``status.relative``
505 ``status.relative``
506 Make paths in :hg:`status` output relative to the current directory.
506 Make paths in :hg:`status` output relative to the current directory.
507 (default: False)
507 (default: False)
508
508
509 ``status.terse``
509 ``status.terse``
510 Default value for the --terse flag, which condenses status output.
510 Default value for the --terse flag, which condenses status output.
511 (default: empty)
511 (default: empty)
512
512
513 ``update.check``
513 ``update.check``
514 Determines what level of checking :hg:`update` will perform before moving
514 Determines what level of checking :hg:`update` will perform before moving
515 to a destination revision. Valid values are ``abort``, ``none``,
515 to a destination revision. Valid values are ``abort``, ``none``,
516 ``linear``, and ``noconflict``.
516 ``linear``, and ``noconflict``.
517
517
518 - ``abort`` always fails if the working directory has uncommitted changes.
518 - ``abort`` always fails if the working directory has uncommitted changes.
519
519
520 - ``none`` performs no checking, and may result in a merge with uncommitted changes.
520 - ``none`` performs no checking, and may result in a merge with uncommitted changes.
521
521
522 - ``linear`` allows any update as long as it follows a straight line in the
522 - ``linear`` allows any update as long as it follows a straight line in the
523 revision history, and may trigger a merge with uncommitted changes.
523 revision history, and may trigger a merge with uncommitted changes.
524
524
525 - ``noconflict`` will allow any update which would not trigger a merge with
525 - ``noconflict`` will allow any update which would not trigger a merge with
526 uncommitted changes, if any are present.
526 uncommitted changes, if any are present.
527
527
528 (default: ``linear``)
528 (default: ``linear``)
529
529
530 ``update.requiredest``
530 ``update.requiredest``
531 Require that the user pass a destination when running :hg:`update`.
531 Require that the user pass a destination when running :hg:`update`.
532 For example, :hg:`update .::` will be allowed, but a plain :hg:`update`
532 For example, :hg:`update .::` will be allowed, but a plain :hg:`update`
533 will be disallowed.
533 will be disallowed.
534 (default: False)
534 (default: False)
535
535
536 ``committemplate``
536 ``committemplate``
537 ------------------
537 ------------------
538
538
539 ``changeset``
539 ``changeset``
540 String: configuration in this section is used as the template to
540 String: configuration in this section is used as the template to
541 customize the text shown in the editor when committing.
541 customize the text shown in the editor when committing.
542
542
543 In addition to pre-defined template keywords, commit log specific one
543 In addition to pre-defined template keywords, commit log specific one
544 below can be used for customization:
544 below can be used for customization:
545
545
546 ``extramsg``
546 ``extramsg``
547 String: Extra message (typically 'Leave message empty to abort
547 String: Extra message (typically 'Leave message empty to abort
548 commit.'). This may be changed by some commands or extensions.
548 commit.'). This may be changed by some commands or extensions.
549
549
550 For example, the template configuration below shows as same text as
550 For example, the template configuration below shows as same text as
551 one shown by default::
551 one shown by default::
552
552
553 [committemplate]
553 [committemplate]
554 changeset = {desc}\n\n
554 changeset = {desc}\n\n
555 HG: Enter commit message. Lines beginning with 'HG:' are removed.
555 HG: Enter commit message. Lines beginning with 'HG:' are removed.
556 HG: {extramsg}
556 HG: {extramsg}
557 HG: --
557 HG: --
558 HG: user: {author}\n{ifeq(p2rev, "-1", "",
558 HG: user: {author}\n{ifeq(p2rev, "-1", "",
559 "HG: branch merge\n")
559 "HG: branch merge\n")
560 }HG: branch '{branch}'\n{if(activebookmark,
560 }HG: branch '{branch}'\n{if(activebookmark,
561 "HG: bookmark '{activebookmark}'\n") }{subrepos %
561 "HG: bookmark '{activebookmark}'\n") }{subrepos %
562 "HG: subrepo {subrepo}\n" }{file_adds %
562 "HG: subrepo {subrepo}\n" }{file_adds %
563 "HG: added {file}\n" }{file_mods %
563 "HG: added {file}\n" }{file_mods %
564 "HG: changed {file}\n" }{file_dels %
564 "HG: changed {file}\n" }{file_dels %
565 "HG: removed {file}\n" }{if(files, "",
565 "HG: removed {file}\n" }{if(files, "",
566 "HG: no files changed\n")}
566 "HG: no files changed\n")}
567
567
568 ``diff()``
568 ``diff()``
569 String: show the diff (see :hg:`help templates` for detail)
569 String: show the diff (see :hg:`help templates` for detail)
570
570
571 Sometimes it is helpful to show the diff of the changeset in the editor without
571 Sometimes it is helpful to show the diff of the changeset in the editor without
572 having to prefix 'HG: ' to each line so that highlighting works correctly. For
572 having to prefix 'HG: ' to each line so that highlighting works correctly. For
573 this, Mercurial provides a special string which will ignore everything below
573 this, Mercurial provides a special string which will ignore everything below
574 it::
574 it::
575
575
576 HG: ------------------------ >8 ------------------------
576 HG: ------------------------ >8 ------------------------
577
577
578 For example, the template configuration below will show the diff below the
578 For example, the template configuration below will show the diff below the
579 extra message::
579 extra message::
580
580
581 [committemplate]
581 [committemplate]
582 changeset = {desc}\n\n
582 changeset = {desc}\n\n
583 HG: Enter commit message. Lines beginning with 'HG:' are removed.
583 HG: Enter commit message. Lines beginning with 'HG:' are removed.
584 HG: {extramsg}
584 HG: {extramsg}
585 HG: ------------------------ >8 ------------------------
585 HG: ------------------------ >8 ------------------------
586 HG: Do not touch the line above.
586 HG: Do not touch the line above.
587 HG: Everything below will be removed.
587 HG: Everything below will be removed.
588 {diff()}
588 {diff()}
589
589
590 .. note::
590 .. note::
591
591
592 For some problematic encodings (see :hg:`help win32mbcs` for
592 For some problematic encodings (see :hg:`help win32mbcs` for
593 detail), this customization should be configured carefully, to
593 detail), this customization should be configured carefully, to
594 avoid showing broken characters.
594 avoid showing broken characters.
595
595
596 For example, if a multibyte character ending with backslash (0x5c) is
596 For example, if a multibyte character ending with backslash (0x5c) is
597 followed by the ASCII character 'n' in the customized template,
597 followed by the ASCII character 'n' in the customized template,
598 the sequence of backslash and 'n' is treated as line-feed unexpectedly
598 the sequence of backslash and 'n' is treated as line-feed unexpectedly
599 (and the multibyte character is broken, too).
599 (and the multibyte character is broken, too).
600
600
601 Customized template is used for commands below (``--edit`` may be
601 Customized template is used for commands below (``--edit`` may be
602 required):
602 required):
603
603
604 - :hg:`backout`
604 - :hg:`backout`
605 - :hg:`commit`
605 - :hg:`commit`
606 - :hg:`fetch` (for merge commit only)
606 - :hg:`fetch` (for merge commit only)
607 - :hg:`graft`
607 - :hg:`graft`
608 - :hg:`histedit`
608 - :hg:`histedit`
609 - :hg:`import`
609 - :hg:`import`
610 - :hg:`qfold`, :hg:`qnew` and :hg:`qrefresh`
610 - :hg:`qfold`, :hg:`qnew` and :hg:`qrefresh`
611 - :hg:`rebase`
611 - :hg:`rebase`
612 - :hg:`shelve`
612 - :hg:`shelve`
613 - :hg:`sign`
613 - :hg:`sign`
614 - :hg:`tag`
614 - :hg:`tag`
615 - :hg:`transplant`
615 - :hg:`transplant`
616
616
617 Configuring items below instead of ``changeset`` allows showing
617 Configuring items below instead of ``changeset`` allows showing
618 customized message only for specific actions, or showing different
618 customized message only for specific actions, or showing different
619 messages for each action.
619 messages for each action.
620
620
621 - ``changeset.backout`` for :hg:`backout`
621 - ``changeset.backout`` for :hg:`backout`
622 - ``changeset.commit.amend.merge`` for :hg:`commit --amend` on merges
622 - ``changeset.commit.amend.merge`` for :hg:`commit --amend` on merges
623 - ``changeset.commit.amend.normal`` for :hg:`commit --amend` on other
623 - ``changeset.commit.amend.normal`` for :hg:`commit --amend` on other
624 - ``changeset.commit.normal.merge`` for :hg:`commit` on merges
624 - ``changeset.commit.normal.merge`` for :hg:`commit` on merges
625 - ``changeset.commit.normal.normal`` for :hg:`commit` on other
625 - ``changeset.commit.normal.normal`` for :hg:`commit` on other
626 - ``changeset.fetch`` for :hg:`fetch` (impling merge commit)
626 - ``changeset.fetch`` for :hg:`fetch` (impling merge commit)
627 - ``changeset.gpg.sign`` for :hg:`sign`
627 - ``changeset.gpg.sign`` for :hg:`sign`
628 - ``changeset.graft`` for :hg:`graft`
628 - ``changeset.graft`` for :hg:`graft`
629 - ``changeset.histedit.edit`` for ``edit`` of :hg:`histedit`
629 - ``changeset.histedit.edit`` for ``edit`` of :hg:`histedit`
630 - ``changeset.histedit.fold`` for ``fold`` of :hg:`histedit`
630 - ``changeset.histedit.fold`` for ``fold`` of :hg:`histedit`
631 - ``changeset.histedit.mess`` for ``mess`` of :hg:`histedit`
631 - ``changeset.histedit.mess`` for ``mess`` of :hg:`histedit`
632 - ``changeset.histedit.pick`` for ``pick`` of :hg:`histedit`
632 - ``changeset.histedit.pick`` for ``pick`` of :hg:`histedit`
633 - ``changeset.import.bypass`` for :hg:`import --bypass`
633 - ``changeset.import.bypass`` for :hg:`import --bypass`
634 - ``changeset.import.normal.merge`` for :hg:`import` on merges
634 - ``changeset.import.normal.merge`` for :hg:`import` on merges
635 - ``changeset.import.normal.normal`` for :hg:`import` on other
635 - ``changeset.import.normal.normal`` for :hg:`import` on other
636 - ``changeset.mq.qnew`` for :hg:`qnew`
636 - ``changeset.mq.qnew`` for :hg:`qnew`
637 - ``changeset.mq.qfold`` for :hg:`qfold`
637 - ``changeset.mq.qfold`` for :hg:`qfold`
638 - ``changeset.mq.qrefresh`` for :hg:`qrefresh`
638 - ``changeset.mq.qrefresh`` for :hg:`qrefresh`
639 - ``changeset.rebase.collapse`` for :hg:`rebase --collapse`
639 - ``changeset.rebase.collapse`` for :hg:`rebase --collapse`
640 - ``changeset.rebase.merge`` for :hg:`rebase` on merges
640 - ``changeset.rebase.merge`` for :hg:`rebase` on merges
641 - ``changeset.rebase.normal`` for :hg:`rebase` on other
641 - ``changeset.rebase.normal`` for :hg:`rebase` on other
642 - ``changeset.shelve.shelve`` for :hg:`shelve`
642 - ``changeset.shelve.shelve`` for :hg:`shelve`
643 - ``changeset.tag.add`` for :hg:`tag` without ``--remove``
643 - ``changeset.tag.add`` for :hg:`tag` without ``--remove``
644 - ``changeset.tag.remove`` for :hg:`tag --remove`
644 - ``changeset.tag.remove`` for :hg:`tag --remove`
645 - ``changeset.transplant.merge`` for :hg:`transplant` on merges
645 - ``changeset.transplant.merge`` for :hg:`transplant` on merges
646 - ``changeset.transplant.normal`` for :hg:`transplant` on other
646 - ``changeset.transplant.normal`` for :hg:`transplant` on other
647
647
648 These dot-separated lists of names are treated as hierarchical ones.
648 These dot-separated lists of names are treated as hierarchical ones.
649 For example, ``changeset.tag.remove`` customizes the commit message
649 For example, ``changeset.tag.remove`` customizes the commit message
650 only for :hg:`tag --remove`, but ``changeset.tag`` customizes the
650 only for :hg:`tag --remove`, but ``changeset.tag`` customizes the
651 commit message for :hg:`tag` regardless of ``--remove`` option.
651 commit message for :hg:`tag` regardless of ``--remove`` option.
652
652
653 When the external editor is invoked for a commit, the corresponding
653 When the external editor is invoked for a commit, the corresponding
654 dot-separated list of names without the ``changeset.`` prefix
654 dot-separated list of names without the ``changeset.`` prefix
655 (e.g. ``commit.normal.normal``) is in the ``HGEDITFORM`` environment
655 (e.g. ``commit.normal.normal``) is in the ``HGEDITFORM`` environment
656 variable.
656 variable.
657
657
658 In this section, items other than ``changeset`` can be referred from
658 In this section, items other than ``changeset`` can be referred from
659 others. For example, the configuration to list committed files up
659 others. For example, the configuration to list committed files up
660 below can be referred as ``{listupfiles}``::
660 below can be referred as ``{listupfiles}``::
661
661
662 [committemplate]
662 [committemplate]
663 listupfiles = {file_adds %
663 listupfiles = {file_adds %
664 "HG: added {file}\n" }{file_mods %
664 "HG: added {file}\n" }{file_mods %
665 "HG: changed {file}\n" }{file_dels %
665 "HG: changed {file}\n" }{file_dels %
666 "HG: removed {file}\n" }{if(files, "",
666 "HG: removed {file}\n" }{if(files, "",
667 "HG: no files changed\n")}
667 "HG: no files changed\n")}
668
668
669 ``decode/encode``
669 ``decode/encode``
670 -----------------
670 -----------------
671
671
672 Filters for transforming files on checkout/checkin. This would
672 Filters for transforming files on checkout/checkin. This would
673 typically be used for newline processing or other
673 typically be used for newline processing or other
674 localization/canonicalization of files.
674 localization/canonicalization of files.
675
675
676 Filters consist of a filter pattern followed by a filter command.
676 Filters consist of a filter pattern followed by a filter command.
677 Filter patterns are globs by default, rooted at the repository root.
677 Filter patterns are globs by default, rooted at the repository root.
678 For example, to match any file ending in ``.txt`` in the root
678 For example, to match any file ending in ``.txt`` in the root
679 directory only, use the pattern ``*.txt``. To match any file ending
679 directory only, use the pattern ``*.txt``. To match any file ending
680 in ``.c`` anywhere in the repository, use the pattern ``**.c``.
680 in ``.c`` anywhere in the repository, use the pattern ``**.c``.
681 For each file only the first matching filter applies.
681 For each file only the first matching filter applies.
682
682
683 The filter command can start with a specifier, either ``pipe:`` or
683 The filter command can start with a specifier, either ``pipe:`` or
684 ``tempfile:``. If no specifier is given, ``pipe:`` is used by default.
684 ``tempfile:``. If no specifier is given, ``pipe:`` is used by default.
685
685
686 A ``pipe:`` command must accept data on stdin and return the transformed
686 A ``pipe:`` command must accept data on stdin and return the transformed
687 data on stdout.
687 data on stdout.
688
688
689 Pipe example::
689 Pipe example::
690
690
691 [encode]
691 [encode]
692 # uncompress gzip files on checkin to improve delta compression
692 # uncompress gzip files on checkin to improve delta compression
693 # note: not necessarily a good idea, just an example
693 # note: not necessarily a good idea, just an example
694 *.gz = pipe: gunzip
694 *.gz = pipe: gunzip
695
695
696 [decode]
696 [decode]
697 # recompress gzip files when writing them to the working dir (we
697 # recompress gzip files when writing them to the working dir (we
698 # can safely omit "pipe:", because it's the default)
698 # can safely omit "pipe:", because it's the default)
699 *.gz = gzip
699 *.gz = gzip
700
700
701 A ``tempfile:`` command is a template. The string ``INFILE`` is replaced
701 A ``tempfile:`` command is a template. The string ``INFILE`` is replaced
702 with the name of a temporary file that contains the data to be
702 with the name of a temporary file that contains the data to be
703 filtered by the command. The string ``OUTFILE`` is replaced with the name
703 filtered by the command. The string ``OUTFILE`` is replaced with the name
704 of an empty temporary file, where the filtered data must be written by
704 of an empty temporary file, where the filtered data must be written by
705 the command.
705 the command.
706
706
707 .. container:: windows
707 .. container:: windows
708
708
709 .. note::
709 .. note::
710
710
711 The tempfile mechanism is recommended for Windows systems,
711 The tempfile mechanism is recommended for Windows systems,
712 where the standard shell I/O redirection operators often have
712 where the standard shell I/O redirection operators often have
713 strange effects and may corrupt the contents of your files.
713 strange effects and may corrupt the contents of your files.
714
714
715 This filter mechanism is used internally by the ``eol`` extension to
715 This filter mechanism is used internally by the ``eol`` extension to
716 translate line ending characters between Windows (CRLF) and Unix (LF)
716 translate line ending characters between Windows (CRLF) and Unix (LF)
717 format. We suggest you use the ``eol`` extension for convenience.
717 format. We suggest you use the ``eol`` extension for convenience.
718
718
719
719
720 ``defaults``
720 ``defaults``
721 ------------
721 ------------
722
722
723 (defaults are deprecated. Don't use them. Use aliases instead.)
723 (defaults are deprecated. Don't use them. Use aliases instead.)
724
724
725 Use the ``[defaults]`` section to define command defaults, i.e. the
725 Use the ``[defaults]`` section to define command defaults, i.e. the
726 default options/arguments to pass to the specified commands.
726 default options/arguments to pass to the specified commands.
727
727
728 The following example makes :hg:`log` run in verbose mode, and
728 The following example makes :hg:`log` run in verbose mode, and
729 :hg:`status` show only the modified files, by default::
729 :hg:`status` show only the modified files, by default::
730
730
731 [defaults]
731 [defaults]
732 log = -v
732 log = -v
733 status = -m
733 status = -m
734
734
735 The actual commands, instead of their aliases, must be used when
735 The actual commands, instead of their aliases, must be used when
736 defining command defaults. The command defaults will also be applied
736 defining command defaults. The command defaults will also be applied
737 to the aliases of the commands defined.
737 to the aliases of the commands defined.
738
738
739
739
740 ``diff``
740 ``diff``
741 --------
741 --------
742
742
743 Settings used when displaying diffs. Everything except for ``unified``
743 Settings used when displaying diffs. Everything except for ``unified``
744 is a Boolean and defaults to False. See :hg:`help config.annotate`
744 is a Boolean and defaults to False. See :hg:`help config.annotate`
745 for related options for the annotate command.
745 for related options for the annotate command.
746
746
747 ``git``
747 ``git``
748 Use git extended diff format.
748 Use git extended diff format.
749
749
750 ``nobinary``
750 ``nobinary``
751 Omit git binary patches.
751 Omit git binary patches.
752
752
753 ``nodates``
753 ``nodates``
754 Don't include dates in diff headers.
754 Don't include dates in diff headers.
755
755
756 ``noprefix``
756 ``noprefix``
757 Omit 'a/' and 'b/' prefixes from filenames. Ignored in plain mode.
757 Omit 'a/' and 'b/' prefixes from filenames. Ignored in plain mode.
758
758
759 ``showfunc``
759 ``showfunc``
760 Show which function each change is in.
760 Show which function each change is in.
761
761
762 ``ignorews``
762 ``ignorews``
763 Ignore white space when comparing lines.
763 Ignore white space when comparing lines.
764
764
765 ``ignorewsamount``
765 ``ignorewsamount``
766 Ignore changes in the amount of white space.
766 Ignore changes in the amount of white space.
767
767
768 ``ignoreblanklines``
768 ``ignoreblanklines``
769 Ignore changes whose lines are all blank.
769 Ignore changes whose lines are all blank.
770
770
771 ``unified``
771 ``unified``
772 Number of lines of context to show.
772 Number of lines of context to show.
773
773
774 ``word-diff``
774 ``word-diff``
775 Highlight changed words.
775 Highlight changed words.
776
776
777 ``email``
777 ``email``
778 ---------
778 ---------
779
779
780 Settings for extensions that send email messages.
780 Settings for extensions that send email messages.
781
781
782 ``from``
782 ``from``
783 Optional. Email address to use in "From" header and SMTP envelope
783 Optional. Email address to use in "From" header and SMTP envelope
784 of outgoing messages.
784 of outgoing messages.
785
785
786 ``to``
786 ``to``
787 Optional. Comma-separated list of recipients' email addresses.
787 Optional. Comma-separated list of recipients' email addresses.
788
788
789 ``cc``
789 ``cc``
790 Optional. Comma-separated list of carbon copy recipients'
790 Optional. Comma-separated list of carbon copy recipients'
791 email addresses.
791 email addresses.
792
792
793 ``bcc``
793 ``bcc``
794 Optional. Comma-separated list of blind carbon copy recipients'
794 Optional. Comma-separated list of blind carbon copy recipients'
795 email addresses.
795 email addresses.
796
796
797 ``method``
797 ``method``
798 Optional. Method to use to send email messages. If value is ``smtp``
798 Optional. Method to use to send email messages. If value is ``smtp``
799 (default), use SMTP (see the ``[smtp]`` section for configuration).
799 (default), use SMTP (see the ``[smtp]`` section for configuration).
800 Otherwise, use as name of program to run that acts like sendmail
800 Otherwise, use as name of program to run that acts like sendmail
801 (takes ``-f`` option for sender, list of recipients on command line,
801 (takes ``-f`` option for sender, list of recipients on command line,
802 message on stdin). Normally, setting this to ``sendmail`` or
802 message on stdin). Normally, setting this to ``sendmail`` or
803 ``/usr/sbin/sendmail`` is enough to use sendmail to send messages.
803 ``/usr/sbin/sendmail`` is enough to use sendmail to send messages.
804
804
805 ``charsets``
805 ``charsets``
806 Optional. Comma-separated list of character sets considered
806 Optional. Comma-separated list of character sets considered
807 convenient for recipients. Addresses, headers, and parts not
807 convenient for recipients. Addresses, headers, and parts not
808 containing patches of outgoing messages will be encoded in the
808 containing patches of outgoing messages will be encoded in the
809 first character set to which conversion from local encoding
809 first character set to which conversion from local encoding
810 (``$HGENCODING``, ``ui.fallbackencoding``) succeeds. If correct
810 (``$HGENCODING``, ``ui.fallbackencoding``) succeeds. If correct
811 conversion fails, the text in question is sent as is.
811 conversion fails, the text in question is sent as is.
812 (default: '')
812 (default: '')
813
813
814 Order of outgoing email character sets:
814 Order of outgoing email character sets:
815
815
816 1. ``us-ascii``: always first, regardless of settings
816 1. ``us-ascii``: always first, regardless of settings
817 2. ``email.charsets``: in order given by user
817 2. ``email.charsets``: in order given by user
818 3. ``ui.fallbackencoding``: if not in email.charsets
818 3. ``ui.fallbackencoding``: if not in email.charsets
819 4. ``$HGENCODING``: if not in email.charsets
819 4. ``$HGENCODING``: if not in email.charsets
820 5. ``utf-8``: always last, regardless of settings
820 5. ``utf-8``: always last, regardless of settings
821
821
822 Email example::
822 Email example::
823
823
824 [email]
824 [email]
825 from = Joseph User <joe.user@example.com>
825 from = Joseph User <joe.user@example.com>
826 method = /usr/sbin/sendmail
826 method = /usr/sbin/sendmail
827 # charsets for western Europeans
827 # charsets for western Europeans
828 # us-ascii, utf-8 omitted, as they are tried first and last
828 # us-ascii, utf-8 omitted, as they are tried first and last
829 charsets = iso-8859-1, iso-8859-15, windows-1252
829 charsets = iso-8859-1, iso-8859-15, windows-1252
830
830
831
831
832 ``extensions``
832 ``extensions``
833 --------------
833 --------------
834
834
835 Mercurial has an extension mechanism for adding new features. To
835 Mercurial has an extension mechanism for adding new features. To
836 enable an extension, create an entry for it in this section.
836 enable an extension, create an entry for it in this section.
837
837
838 If you know that the extension is already in Python's search path,
838 If you know that the extension is already in Python's search path,
839 you can give the name of the module, followed by ``=``, with nothing
839 you can give the name of the module, followed by ``=``, with nothing
840 after the ``=``.
840 after the ``=``.
841
841
842 Otherwise, give a name that you choose, followed by ``=``, followed by
842 Otherwise, give a name that you choose, followed by ``=``, followed by
843 the path to the ``.py`` file (including the file name extension) that
843 the path to the ``.py`` file (including the file name extension) that
844 defines the extension.
844 defines the extension.
845
845
846 To explicitly disable an extension that is enabled in an hgrc of
846 To explicitly disable an extension that is enabled in an hgrc of
847 broader scope, prepend its path with ``!``, as in ``foo = !/ext/path``
847 broader scope, prepend its path with ``!``, as in ``foo = !/ext/path``
848 or ``foo = !`` when path is not supplied.
848 or ``foo = !`` when path is not supplied.
849
849
850 Example for ``~/.hgrc``::
850 Example for ``~/.hgrc``::
851
851
852 [extensions]
852 [extensions]
853 # (the churn extension will get loaded from Mercurial's path)
853 # (the churn extension will get loaded from Mercurial's path)
854 churn =
854 churn =
855 # (this extension will get loaded from the file specified)
855 # (this extension will get loaded from the file specified)
856 myfeature = ~/.hgext/myfeature.py
856 myfeature = ~/.hgext/myfeature.py
857
857
858 If an extension fails to load, a warning will be issued, and Mercurial will
858 If an extension fails to load, a warning will be issued, and Mercurial will
859 proceed. To enforce that an extension must be loaded, one can set the `required`
859 proceed. To enforce that an extension must be loaded, one can set the `required`
860 suboption in the config::
860 suboption in the config::
861
861
862 [extensions]
862 [extensions]
863 myfeature = ~/.hgext/myfeature.py
863 myfeature = ~/.hgext/myfeature.py
864 myfeature:required = yes
864 myfeature:required = yes
865
865
866 To debug extension loading issue, one can add `--traceback` to their mercurial
866 To debug extension loading issue, one can add `--traceback` to their mercurial
867 invocation.
867 invocation.
868
868
869 A default setting can we set using the special `*` extension key::
869 A default setting can we set using the special `*` extension key::
870
870
871 [extensions]
871 [extensions]
872 *:required = yes
872 *:required = yes
873 myfeature = ~/.hgext/myfeature.py
873 myfeature = ~/.hgext/myfeature.py
874 rebase=
874 rebase=
875
875
876
876
877 ``format``
877 ``format``
878 ----------
878 ----------
879
879
880 Configuration that controls the repository format. Newer format options are more
880 Configuration that controls the repository format. Newer format options are more
881 powerful, but incompatible with some older versions of Mercurial. Format options
881 powerful, but incompatible with some older versions of Mercurial. Format options
882 are considered at repository initialization only. You need to make a new clone
882 are considered at repository initialization only. You need to make a new clone
883 for config changes to be taken into account.
883 for config changes to be taken into account.
884
884
885 For more details about repository format and version compatibility, see
885 For more details about repository format and version compatibility, see
886 https://www.mercurial-scm.org/wiki/MissingRequirement
886 https://www.mercurial-scm.org/wiki/MissingRequirement
887
887
888 ``usegeneraldelta``
888 ``usegeneraldelta``
889 Enable or disable the "generaldelta" repository format which improves
889 Enable or disable the "generaldelta" repository format which improves
890 repository compression by allowing "revlog" to store deltas against
890 repository compression by allowing "revlog" to store deltas against
891 arbitrary revisions instead of the previously stored one. This provides
891 arbitrary revisions instead of the previously stored one. This provides
892 significant improvement for repositories with branches.
892 significant improvement for repositories with branches.
893
893
894 Repositories with this on-disk format require Mercurial version 1.9.
894 Repositories with this on-disk format require Mercurial version 1.9.
895
895
896 Enabled by default.
896 Enabled by default.
897
897
898 ``dotencode``
898 ``dotencode``
899 Enable or disable the "dotencode" repository format which enhances
899 Enable or disable the "dotencode" repository format which enhances
900 the "fncache" repository format (which has to be enabled to use
900 the "fncache" repository format (which has to be enabled to use
901 dotencode) to avoid issues with filenames starting with "._" on
901 dotencode) to avoid issues with filenames starting with "._" on
902 Mac OS X and spaces on Windows.
902 Mac OS X and spaces on Windows.
903
903
904 Repositories with this on-disk format require Mercurial version 1.7.
904 Repositories with this on-disk format require Mercurial version 1.7.
905
905
906 Enabled by default.
906 Enabled by default.
907
907
908 ``usefncache``
908 ``usefncache``
909 Enable or disable the "fncache" repository format which enhances
909 Enable or disable the "fncache" repository format which enhances
910 the "store" repository format (which has to be enabled to use
910 the "store" repository format (which has to be enabled to use
911 fncache) to allow longer filenames and avoids using Windows
911 fncache) to allow longer filenames and avoids using Windows
912 reserved names, e.g. "nul".
912 reserved names, e.g. "nul".
913
913
914 Repositories with this on-disk format require Mercurial version 1.1.
914 Repositories with this on-disk format require Mercurial version 1.1.
915
915
916 Enabled by default.
916 Enabled by default.
917
917
918 ``use-dirstate-v2``
918 ``use-dirstate-v2``
919 Enable or disable the experimental "dirstate-v2" feature. The dirstate
919 Enable or disable the experimental "dirstate-v2" feature. The dirstate
920 functionality is shared by all commands interacting with the working copy.
920 functionality is shared by all commands interacting with the working copy.
921 The new version is more robust, faster and stores more information.
921 The new version is more robust, faster and stores more information.
922
922
923 The performance-improving version of this feature is currently only
923 The performance-improving version of this feature is currently only
924 implemented in Rust (see :hg:`help rust`), so people not using a version of
924 implemented in Rust (see :hg:`help rust`), so people not using a version of
925 Mercurial compiled with the Rust parts might actually suffer some slowdown.
925 Mercurial compiled with the Rust parts might actually suffer some slowdown.
926 For this reason, such versions will by default refuse to access repositories
926 For this reason, such versions will by default refuse to access repositories
927 with "dirstate-v2" enabled.
927 with "dirstate-v2" enabled.
928
928
929 This behavior can be adjusted via configuration: check
929 This behavior can be adjusted via configuration: check
930 :hg:`help config.storage.dirstate-v2.slow-path` for details.
930 :hg:`help config.storage.dirstate-v2.slow-path` for details.
931
931
932 Repositories with this on-disk format require Mercurial 6.0 or above.
932 Repositories with this on-disk format require Mercurial 6.0 or above.
933
933
934 By default this format variant is disabled if the fast implementation is not
934 By default this format variant is disabled if the fast implementation is not
935 available, and enabled by default if the fast implementation is available.
935 available, and enabled by default if the fast implementation is available.
936
936
937 To accomodate installations of Mercurial without the fast implementation,
937 To accomodate installations of Mercurial without the fast implementation,
938 you can downgrade your repository. To do so run the following command:
938 you can downgrade your repository. To do so run the following command:
939
939
940 $ hg debugupgraderepo \
940 $ hg debugupgraderepo \
941 --run \
941 --run \
942 --config format.use-dirstate-v2=False \
942 --config format.use-dirstate-v2=False \
943 --config storage.dirstate-v2.slow-path=allow
943 --config storage.dirstate-v2.slow-path=allow
944
944
945 For a more comprehensive guide, see :hg:`help internals.dirstate-v2`.
945 For a more comprehensive guide, see :hg:`help internals.dirstate-v2`.
946
946
947 ``use-dirstate-v2.automatic-upgrade-of-mismatching-repositories``
947 ``use-dirstate-v2.automatic-upgrade-of-mismatching-repositories``
948 When enabled, an automatic upgrade will be triggered when a repository format
948 When enabled, an automatic upgrade will be triggered when a repository format
949 does not match its `use-dirstate-v2` config.
949 does not match its `use-dirstate-v2` config.
950
950
951 This is an advanced behavior that most users will not need. We recommend you
951 This is an advanced behavior that most users will not need. We recommend you
952 don't use this unless you are a seasoned administrator of a Mercurial install
952 don't use this unless you are a seasoned administrator of a Mercurial install
953 base.
953 base.
954
954
955 Automatic upgrade means that any process accessing the repository will
955 Automatic upgrade means that any process accessing the repository will
956 upgrade the repository format to use `dirstate-v2`. This only triggers if a
956 upgrade the repository format to use `dirstate-v2`. This only triggers if a
957 change is needed. This also applies to operations that would have been
957 change is needed. This also applies to operations that would have been
958 read-only (like hg status).
958 read-only (like hg status).
959
959
960 If the repository cannot be locked, the automatic-upgrade operation will be
960 If the repository cannot be locked, the automatic-upgrade operation will be
961 skipped. The next operation will attempt it again.
961 skipped. The next operation will attempt it again.
962
962
963 This configuration will apply for moves in any direction, either adding the
963 This configuration will apply for moves in any direction, either adding the
964 `dirstate-v2` format if `format.use-dirstate-v2=yes` or removing the
964 `dirstate-v2` format if `format.use-dirstate-v2=yes` or removing the
965 `dirstate-v2` requirement if `format.use-dirstate-v2=no`. So we recommend
965 `dirstate-v2` requirement if `format.use-dirstate-v2=no`. So we recommend
966 setting both this value and `format.use-dirstate-v2` at the same time.
966 setting both this value and `format.use-dirstate-v2` at the same time.
967
967
968 ``use-dirstate-v2.automatic-upgrade-of-mismatching-repositories:quiet``
968 ``use-dirstate-v2.automatic-upgrade-of-mismatching-repositories:quiet``
969 Hide message when performing such automatic upgrade.
969 Hide message when performing such automatic upgrade.
970
970
971 ``use-dirstate-tracked-hint``
971 ``use-dirstate-tracked-hint``
972 Enable or disable the writing of "tracked key" file alongside the dirstate.
972 Enable or disable the writing of "tracked key" file alongside the dirstate.
973 (default to disabled)
973 (default to disabled)
974
974
975 That "tracked-hint" can help external automations to detect changes to the
975 That "tracked-hint" can help external automations to detect changes to the
976 set of tracked files. (i.e the result of `hg files` or `hg status -macd`)
976 set of tracked files. (i.e the result of `hg files` or `hg status -macd`)
977
977
978 The tracked-hint is written in a new `.hg/dirstate-tracked-hint`. That file
978 The tracked-hint is written in a new `.hg/dirstate-tracked-hint`. That file
979 contains two lines:
979 contains two lines:
980 - the first line is the file version (currently: 1),
980 - the first line is the file version (currently: 1),
981 - the second line contains the "tracked-hint".
981 - the second line contains the "tracked-hint".
982 That file is written right after the dirstate is written.
982 That file is written right after the dirstate is written.
983
983
984 The tracked-hint changes whenever the set of file tracked in the dirstate
984 The tracked-hint changes whenever the set of file tracked in the dirstate
985 changes. The general idea is:
985 changes. The general idea is:
986 - if the hint is identical, the set of tracked file SHOULD be identical,
986 - if the hint is identical, the set of tracked file SHOULD be identical,
987 - if the hint is different, the set of tracked file MIGHT be different.
987 - if the hint is different, the set of tracked file MIGHT be different.
988
988
989 The "hint is identical" case uses `SHOULD` as the dirstate and the hint file
989 The "hint is identical" case uses `SHOULD` as the dirstate and the hint file
990 are two distinct files and therefore that cannot be read or written to in an
990 are two distinct files and therefore that cannot be read or written to in an
991 atomic way. If the key is identical, nothing garantees that the dirstate is
991 atomic way. If the key is identical, nothing garantees that the dirstate is
992 not updated right after the hint file. This is considered a negligible
992 not updated right after the hint file. This is considered a negligible
993 limitation for the intended usecase. It is actually possible to prevent this
993 limitation for the intended usecase. It is actually possible to prevent this
994 race by taking the repository lock during read operations.
994 race by taking the repository lock during read operations.
995
995
996 They are two "ways" to use this feature:
996 They are two "ways" to use this feature:
997
997
998 1) monitoring changes to the `.hg/dirstate-tracked-hint`, if the file
998 1) monitoring changes to the `.hg/dirstate-tracked-hint`, if the file
999 changes, the tracked set might have changed.
999 changes, the tracked set might have changed.
1000
1000
1001 2) storing the value and comparing it to a later value.
1001 2) storing the value and comparing it to a later value.
1002
1002
1003
1003
1004 ``use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories``
1004 ``use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories``
1005 When enabled, an automatic upgrade will be triggered when a repository format
1005 When enabled, an automatic upgrade will be triggered when a repository format
1006 does not match its `use-dirstate-tracked-hint` config.
1006 does not match its `use-dirstate-tracked-hint` config.
1007
1007
1008 This is an advanced behavior that most users will not need. We recommend you
1008 This is an advanced behavior that most users will not need. We recommend you
1009 don't use this unless you are a seasoned administrator of a Mercurial install
1009 don't use this unless you are a seasoned administrator of a Mercurial install
1010 base.
1010 base.
1011
1011
1012 Automatic upgrade means that any process accessing the repository will
1012 Automatic upgrade means that any process accessing the repository will
1013 upgrade the repository format to use `dirstate-tracked-hint`. This only
1013 upgrade the repository format to use `dirstate-tracked-hint`. This only
1014 triggers if a change is needed. This also applies to operations that would
1014 triggers if a change is needed. This also applies to operations that would
1015 have been read-only (like hg status).
1015 have been read-only (like hg status).
1016
1016
1017 If the repository cannot be locked, the automatic-upgrade operation will be
1017 If the repository cannot be locked, the automatic-upgrade operation will be
1018 skipped. The next operation will attempt it again.
1018 skipped. The next operation will attempt it again.
1019
1019
1020 This configuration will apply for moves in any direction, either adding the
1020 This configuration will apply for moves in any direction, either adding the
1021 `dirstate-tracked-hint` format if `format.use-dirstate-tracked-hint=yes` or
1021 `dirstate-tracked-hint` format if `format.use-dirstate-tracked-hint=yes` or
1022 removing the `dirstate-tracked-hint` requirement if
1022 removing the `dirstate-tracked-hint` requirement if
1023 `format.use-dirstate-tracked-hint=no`. So we recommend setting both this
1023 `format.use-dirstate-tracked-hint=no`. So we recommend setting both this
1024 value and `format.use-dirstate-tracked-hint` at the same time.
1024 value and `format.use-dirstate-tracked-hint` at the same time.
1025
1025
1026
1026
1027 ``use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories:quiet``
1027 ``use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories:quiet``
1028 Hide message when performing such automatic upgrade.
1028 Hide message when performing such automatic upgrade.
1029
1029
1030
1030
1031 ``use-persistent-nodemap``
1031 ``use-persistent-nodemap``
1032 Enable or disable the "persistent-nodemap" feature which improves
1032 Enable or disable the "persistent-nodemap" feature which improves
1033 performance if the Rust extensions are available.
1033 performance if the Rust extensions are available.
1034
1034
1035 The "persistent-nodemap" persist the "node -> rev" on disk removing the
1035 The "persistent-nodemap" persist the "node -> rev" on disk removing the
1036 need to dynamically build that mapping for each Mercurial invocation. This
1036 need to dynamically build that mapping for each Mercurial invocation. This
1037 significantly reduces the startup cost of various local and server-side
1037 significantly reduces the startup cost of various local and server-side
1038 operation for larger repositories.
1038 operation for larger repositories.
1039
1039
1040 The performance-improving version of this feature is currently only
1040 The performance-improving version of this feature is currently only
1041 implemented in Rust (see :hg:`help rust`), so people not using a version of
1041 implemented in Rust (see :hg:`help rust`), so people not using a version of
1042 Mercurial compiled with the Rust parts might actually suffer some slowdown.
1042 Mercurial compiled with the Rust parts might actually suffer some slowdown.
1043 For this reason, such versions will by default refuse to access repositories
1043 For this reason, such versions will by default refuse to access repositories
1044 with "persistent-nodemap".
1044 with "persistent-nodemap".
1045
1045
1046 This behavior can be adjusted via configuration: check
1046 This behavior can be adjusted via configuration: check
1047 :hg:`help config.storage.revlog.persistent-nodemap.slow-path` for details.
1047 :hg:`help config.storage.revlog.persistent-nodemap.slow-path` for details.
1048
1048
1049 Repositories with this on-disk format require Mercurial 5.4 or above.
1049 Repositories with this on-disk format require Mercurial 5.4 or above.
1050
1050
1051 By default this format variant is disabled if the fast implementation is not
1051 By default this format variant is disabled if the fast implementation is not
1052 available, and enabled by default if the fast implementation is available.
1052 available, and enabled by default if the fast implementation is available.
1053
1053
1054 To accomodate installations of Mercurial without the fast implementation,
1054 To accomodate installations of Mercurial without the fast implementation,
1055 you can downgrade your repository. To do so run the following command:
1055 you can downgrade your repository. To do so run the following command:
1056
1056
1057 $ hg debugupgraderepo \
1057 $ hg debugupgraderepo \
1058 --run \
1058 --run \
1059 --config format.use-persistent-nodemap=False \
1059 --config format.use-persistent-nodemap=False \
1060 --config storage.revlog.persistent-nodemap.slow-path=allow
1060 --config storage.revlog.persistent-nodemap.slow-path=allow
1061
1061
1062 ``use-share-safe``
1062 ``use-share-safe``
1063 Enforce "safe" behaviors for all "shares" that access this repository.
1063 Enforce "safe" behaviors for all "shares" that access this repository.
1064
1064
1065 With this feature, "shares" using this repository as a source will:
1065 With this feature, "shares" using this repository as a source will:
1066
1066
1067 * read the source repository's configuration (`<source>/.hg/hgrc`).
1067 * read the source repository's configuration (`<source>/.hg/hgrc`).
1068 * read and use the source repository's "requirements"
1068 * read and use the source repository's "requirements"
1069 (except the working copy specific one).
1069 (except the working copy specific one).
1070
1070
1071 Without this feature, "shares" using this repository as a source will:
1071 Without this feature, "shares" using this repository as a source will:
1072
1072
1073 * keep tracking the repository "requirements" in the share only, ignoring
1073 * keep tracking the repository "requirements" in the share only, ignoring
1074 the source "requirements", possibly diverging from them.
1074 the source "requirements", possibly diverging from them.
1075 * ignore source repository config. This can create problems, like silently
1075 * ignore source repository config. This can create problems, like silently
1076 ignoring important hooks.
1076 ignoring important hooks.
1077
1077
1078 Beware that existing shares will not be upgraded/downgraded, and by
1078 Beware that existing shares will not be upgraded/downgraded, and by
1079 default, Mercurial will refuse to interact with them until the mismatch
1079 default, Mercurial will refuse to interact with them until the mismatch
1080 is resolved. See :hg:`help config.share.safe-mismatch.source-safe` and
1080 is resolved. See :hg:`help config.share.safe-mismatch.source-safe` and
1081 :hg:`help config.share.safe-mismatch.source-not-safe` for details.
1081 :hg:`help config.share.safe-mismatch.source-not-safe` for details.
1082
1082
1083 Introduced in Mercurial 5.7.
1083 Introduced in Mercurial 5.7.
1084
1084
1085 Enabled by default in Mercurial 6.1.
1085 Enabled by default in Mercurial 6.1.
1086
1086
1087 ``use-share-safe.automatic-upgrade-of-mismatching-repositories``
1087 ``use-share-safe.automatic-upgrade-of-mismatching-repositories``
1088 When enabled, an automatic upgrade will be triggered when a repository format
1088 When enabled, an automatic upgrade will be triggered when a repository format
1089 does not match its `use-share-safe` config.
1089 does not match its `use-share-safe` config.
1090
1090
1091 This is an advanced behavior that most users will not need. We recommend you
1091 This is an advanced behavior that most users will not need. We recommend you
1092 don't use this unless you are a seasoned administrator of a Mercurial install
1092 don't use this unless you are a seasoned administrator of a Mercurial install
1093 base.
1093 base.
1094
1094
1095 Automatic upgrade means that any process accessing the repository will
1095 Automatic upgrade means that any process accessing the repository will
1096 upgrade the repository format to use `share-safe`. This only triggers if a
1096 upgrade the repository format to use `share-safe`. This only triggers if a
1097 change is needed. This also applies to operation that would have been
1097 change is needed. This also applies to operation that would have been
1098 read-only (like hg status).
1098 read-only (like hg status).
1099
1099
1100 If the repository cannot be locked, the automatic-upgrade operation will be
1100 If the repository cannot be locked, the automatic-upgrade operation will be
1101 skipped. The next operation will attempt it again.
1101 skipped. The next operation will attempt it again.
1102
1102
1103 This configuration will apply for moves in any direction, either adding the
1103 This configuration will apply for moves in any direction, either adding the
1104 `share-safe` format if `format.use-share-safe=yes` or removing the
1104 `share-safe` format if `format.use-share-safe=yes` or removing the
1105 `share-safe` requirement if `format.use-share-safe=no`. So we recommend
1105 `share-safe` requirement if `format.use-share-safe=no`. So we recommend
1106 setting both this value and `format.use-share-safe` at the same time.
1106 setting both this value and `format.use-share-safe` at the same time.
1107
1107
1108 ``use-share-safe.automatic-upgrade-of-mismatching-repositories:quiet``
1108 ``use-share-safe.automatic-upgrade-of-mismatching-repositories:quiet``
1109 Hide message when performing such automatic upgrade.
1109 Hide message when performing such automatic upgrade.
1110
1110
1111 ``usestore``
1111 ``usestore``
1112 Enable or disable the "store" repository format which improves
1112 Enable or disable the "store" repository format which improves
1113 compatibility with systems that fold case or otherwise mangle
1113 compatibility with systems that fold case or otherwise mangle
1114 filenames. Disabling this option will allow you to store longer filenames
1114 filenames. Disabling this option will allow you to store longer filenames
1115 in some situations at the expense of compatibility.
1115 in some situations at the expense of compatibility.
1116
1116
1117 Repositories with this on-disk format require Mercurial version 0.9.4.
1117 Repositories with this on-disk format require Mercurial version 0.9.4.
1118
1118
1119 Enabled by default.
1119 Enabled by default.
1120
1120
1121 ``sparse-revlog``
1121 ``sparse-revlog``
1122 Enable or disable the ``sparse-revlog`` delta strategy. This format improves
1122 Enable or disable the ``sparse-revlog`` delta strategy. This format improves
1123 delta re-use inside revlog. For very branchy repositories, it results in a
1123 delta re-use inside revlog. For very branchy repositories, it results in a
1124 smaller store. For repositories with many revisions, it also helps
1124 smaller store. For repositories with many revisions, it also helps
1125 performance (by using shortened delta chains.)
1125 performance (by using shortened delta chains.)
1126
1126
1127 Repositories with this on-disk format require Mercurial version 4.7
1127 Repositories with this on-disk format require Mercurial version 4.7
1128
1128
1129 Enabled by default.
1129 Enabled by default.
1130
1130
1131 ``revlog-compression``
1131 ``revlog-compression``
1132 Compression algorithm used by revlog. Supported values are `zlib` and
1132 Compression algorithm used by revlog. Supported values are `zlib` and
1133 `zstd`. The `zlib` engine is the historical default of Mercurial. `zstd` is
1133 `zstd`. The `zlib` engine is the historical default of Mercurial. `zstd` is
1134 a newer format that is usually a net win over `zlib`, operating faster at
1134 a newer format that is usually a net win over `zlib`, operating faster at
1135 better compression rates. Use `zstd` to reduce CPU usage. Multiple values
1135 better compression rates. Use `zstd` to reduce CPU usage. Multiple values
1136 can be specified, the first available one will be used.
1136 can be specified, the first available one will be used.
1137
1137
1138 On some systems, the Mercurial installation may lack `zstd` support.
1138 On some systems, the Mercurial installation may lack `zstd` support.
1139
1139
1140 Default is `zstd` if available, `zlib` otherwise.
1140 Default is `zstd` if available, `zlib` otherwise.
1141
1141
1142 ``bookmarks-in-store``
1142 ``bookmarks-in-store``
1143 Store bookmarks in .hg/store/. This means that bookmarks are shared when
1143 Store bookmarks in .hg/store/. This means that bookmarks are shared when
1144 using `hg share` regardless of the `-B` option.
1144 using `hg share` regardless of the `-B` option.
1145
1145
1146 Repositories with this on-disk format require Mercurial version 5.1.
1146 Repositories with this on-disk format require Mercurial version 5.1.
1147
1147
1148 Disabled by default.
1148 Disabled by default.
1149
1149
1150
1150
1151 ``graph``
1151 ``graph``
1152 ---------
1152 ---------
1153
1153
1154 Web graph view configuration. This section let you change graph
1154 Web graph view configuration. This section let you change graph
1155 elements display properties by branches, for instance to make the
1155 elements display properties by branches, for instance to make the
1156 ``default`` branch stand out.
1156 ``default`` branch stand out.
1157
1157
1158 Each line has the following format::
1158 Each line has the following format::
1159
1159
1160 <branch>.<argument> = <value>
1160 <branch>.<argument> = <value>
1161
1161
1162 where ``<branch>`` is the name of the branch being
1162 where ``<branch>`` is the name of the branch being
1163 customized. Example::
1163 customized. Example::
1164
1164
1165 [graph]
1165 [graph]
1166 # 2px width
1166 # 2px width
1167 default.width = 2
1167 default.width = 2
1168 # red color
1168 # red color
1169 default.color = FF0000
1169 default.color = FF0000
1170
1170
1171 Supported arguments:
1171 Supported arguments:
1172
1172
1173 ``width``
1173 ``width``
1174 Set branch edges width in pixels.
1174 Set branch edges width in pixels.
1175
1175
1176 ``color``
1176 ``color``
1177 Set branch edges color in hexadecimal RGB notation.
1177 Set branch edges color in hexadecimal RGB notation.
1178
1178
1179 ``hooks``
1179 ``hooks``
1180 ---------
1180 ---------
1181
1181
1182 Commands or Python functions that get automatically executed by
1182 Commands or Python functions that get automatically executed by
1183 various actions such as starting or finishing a commit. Multiple
1183 various actions such as starting or finishing a commit. Multiple
1184 hooks can be run for the same action by appending a suffix to the
1184 hooks can be run for the same action by appending a suffix to the
1185 action. Overriding a site-wide hook can be done by changing its
1185 action. Overriding a site-wide hook can be done by changing its
1186 value or setting it to an empty string. Hooks can be prioritized
1186 value or setting it to an empty string. Hooks can be prioritized
1187 by adding a prefix of ``priority.`` to the hook name on a new line
1187 by adding a prefix of ``priority.`` to the hook name on a new line
1188 and setting the priority. The default priority is 0.
1188 and setting the priority. The default priority is 0.
1189
1189
1190 Example ``.hg/hgrc``::
1190 Example ``.hg/hgrc``::
1191
1191
1192 [hooks]
1192 [hooks]
1193 # update working directory after adding changesets
1193 # update working directory after adding changesets
1194 changegroup.update = hg update
1194 changegroup.update = hg update
1195 # do not use the site-wide hook
1195 # do not use the site-wide hook
1196 incoming =
1196 incoming =
1197 incoming.email = /my/email/hook
1197 incoming.email = /my/email/hook
1198 incoming.autobuild = /my/build/hook
1198 incoming.autobuild = /my/build/hook
1199 # force autobuild hook to run before other incoming hooks
1199 # force autobuild hook to run before other incoming hooks
1200 priority.incoming.autobuild = 1
1200 priority.incoming.autobuild = 1
1201 ### control HGPLAIN setting when running autobuild hook
1201 ### control HGPLAIN setting when running autobuild hook
1202 # HGPLAIN always set (default from Mercurial 5.7)
1202 # HGPLAIN always set (default from Mercurial 5.7)
1203 incoming.autobuild:run-with-plain = yes
1203 incoming.autobuild:run-with-plain = yes
1204 # HGPLAIN never set
1204 # HGPLAIN never set
1205 incoming.autobuild:run-with-plain = no
1205 incoming.autobuild:run-with-plain = no
1206 # HGPLAIN inherited from environment (default before Mercurial 5.7)
1206 # HGPLAIN inherited from environment (default before Mercurial 5.7)
1207 incoming.autobuild:run-with-plain = auto
1207 incoming.autobuild:run-with-plain = auto
1208
1208
1209 Most hooks are run with environment variables set that give useful
1209 Most hooks are run with environment variables set that give useful
1210 additional information. For each hook below, the environment variables
1210 additional information. For each hook below, the environment variables
1211 it is passed are listed with names in the form ``$HG_foo``. The
1211 it is passed are listed with names in the form ``$HG_foo``. The
1212 ``$HG_HOOKTYPE`` and ``$HG_HOOKNAME`` variables are set for all hooks.
1212 ``$HG_HOOKTYPE`` and ``$HG_HOOKNAME`` variables are set for all hooks.
1213 They contain the type of hook which triggered the run and the full name
1213 They contain the type of hook which triggered the run and the full name
1214 of the hook in the config, respectively. In the example above, this will
1214 of the hook in the config, respectively. In the example above, this will
1215 be ``$HG_HOOKTYPE=incoming`` and ``$HG_HOOKNAME=incoming.email``.
1215 be ``$HG_HOOKTYPE=incoming`` and ``$HG_HOOKNAME=incoming.email``.
1216
1216
1217 .. container:: windows
1217 .. container:: windows
1218
1218
1219 Some basic Unix syntax can be enabled for portability, including ``$VAR``
1219 Some basic Unix syntax can be enabled for portability, including ``$VAR``
1220 and ``${VAR}`` style variables. A ``~`` followed by ``\`` or ``/`` will
1220 and ``${VAR}`` style variables. A ``~`` followed by ``\`` or ``/`` will
1221 be expanded to ``%USERPROFILE%`` to simulate a subset of tilde expansion
1221 be expanded to ``%USERPROFILE%`` to simulate a subset of tilde expansion
1222 on Unix. To use a literal ``$`` or ``~``, it must be escaped with a back
1222 on Unix. To use a literal ``$`` or ``~``, it must be escaped with a back
1223 slash or inside of a strong quote. Strong quotes will be replaced by
1223 slash or inside of a strong quote. Strong quotes will be replaced by
1224 double quotes after processing.
1224 double quotes after processing.
1225
1225
1226 This feature is enabled by adding a prefix of ``tonative.`` to the hook
1226 This feature is enabled by adding a prefix of ``tonative.`` to the hook
1227 name on a new line, and setting it to ``True``. For example::
1227 name on a new line, and setting it to ``True``. For example::
1228
1228
1229 [hooks]
1229 [hooks]
1230 incoming.autobuild = /my/build/hook
1230 incoming.autobuild = /my/build/hook
1231 # enable translation to cmd.exe syntax for autobuild hook
1231 # enable translation to cmd.exe syntax for autobuild hook
1232 tonative.incoming.autobuild = True
1232 tonative.incoming.autobuild = True
1233
1233
1234 ``changegroup``
1234 ``changegroup``
1235 Run after a changegroup has been added via push, pull or unbundle. The ID of
1235 Run after a changegroup has been added via push, pull or unbundle. The ID of
1236 the first new changeset is in ``$HG_NODE`` and last is in ``$HG_NODE_LAST``.
1236 the first new changeset is in ``$HG_NODE`` and last is in ``$HG_NODE_LAST``.
1237 The URL from which changes came is in ``$HG_URL``.
1237 The URL from which changes came is in ``$HG_URL``.
1238
1238
1239 ``commit``
1239 ``commit``
1240 Run after a changeset has been created in the local repository. The ID
1240 Run after a changeset has been created in the local repository. The ID
1241 of the newly created changeset is in ``$HG_NODE``. Parent changeset
1241 of the newly created changeset is in ``$HG_NODE``. Parent changeset
1242 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1242 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1243
1243
1244 ``incoming``
1244 ``incoming``
1245 Run after a changeset has been pulled, pushed, or unbundled into
1245 Run after a changeset has been pulled, pushed, or unbundled into
1246 the local repository. The ID of the newly arrived changeset is in
1246 the local repository. The ID of the newly arrived changeset is in
1247 ``$HG_NODE``. The URL that was source of the changes is in ``$HG_URL``.
1247 ``$HG_NODE``. The URL that was source of the changes is in ``$HG_URL``.
1248
1248
1249 ``outgoing``
1249 ``outgoing``
1250 Run after sending changes from the local repository to another. The ID of
1250 Run after sending changes from the local repository to another. The ID of
1251 first changeset sent is in ``$HG_NODE``. The source of operation is in
1251 first changeset sent is in ``$HG_NODE``. The source of operation is in
1252 ``$HG_SOURCE``. Also see :hg:`help config.hooks.preoutgoing`.
1252 ``$HG_SOURCE``. Also see :hg:`help config.hooks.preoutgoing`.
1253
1253
1254 ``post-<command>``
1254 ``post-<command>``
1255 Run after successful invocations of the associated command. The
1255 Run after successful invocations of the associated command. The
1256 contents of the command line are passed as ``$HG_ARGS`` and the result
1256 contents of the command line are passed as ``$HG_ARGS`` and the result
1257 code in ``$HG_RESULT``. Parsed command line arguments are passed as
1257 code in ``$HG_RESULT``. Parsed command line arguments are passed as
1258 ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
1258 ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
1259 the python data internally passed to <command>. ``$HG_OPTS`` is a
1259 the python data internally passed to <command>. ``$HG_OPTS`` is a
1260 dictionary of options (with unspecified options set to their defaults).
1260 dictionary of options (with unspecified options set to their defaults).
1261 ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
1261 ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
1262
1262
1263 ``fail-<command>``
1263 ``fail-<command>``
1264 Run after a failed invocation of an associated command. The contents
1264 Run after a failed invocation of an associated command. The contents
1265 of the command line are passed as ``$HG_ARGS``. Parsed command line
1265 of the command line are passed as ``$HG_ARGS``. Parsed command line
1266 arguments are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain
1266 arguments are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain
1267 string representations of the python data internally passed to
1267 string representations of the python data internally passed to
1268 <command>. ``$HG_OPTS`` is a dictionary of options (with unspecified
1268 <command>. ``$HG_OPTS`` is a dictionary of options (with unspecified
1269 options set to their defaults). ``$HG_PATS`` is a list of arguments.
1269 options set to their defaults). ``$HG_PATS`` is a list of arguments.
1270 Hook failure is ignored.
1270 Hook failure is ignored.
1271
1271
1272 ``pre-<command>``
1272 ``pre-<command>``
1273 Run before executing the associated command. The contents of the
1273 Run before executing the associated command. The contents of the
1274 command line are passed as ``$HG_ARGS``. Parsed command line arguments
1274 command line are passed as ``$HG_ARGS``. Parsed command line arguments
1275 are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
1275 are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
1276 representations of the data internally passed to <command>. ``$HG_OPTS``
1276 representations of the data internally passed to <command>. ``$HG_OPTS``
1277 is a dictionary of options (with unspecified options set to their
1277 is a dictionary of options (with unspecified options set to their
1278 defaults). ``$HG_PATS`` is a list of arguments. If the hook returns
1278 defaults). ``$HG_PATS`` is a list of arguments. If the hook returns
1279 failure, the command doesn't execute and Mercurial returns the failure
1279 failure, the command doesn't execute and Mercurial returns the failure
1280 code.
1280 code.
1281
1281
1282 ``prechangegroup``
1282 ``prechangegroup``
1283 Run before a changegroup is added via push, pull or unbundle. Exit
1283 Run before a changegroup is added via push, pull or unbundle. Exit
1284 status 0 allows the changegroup to proceed. A non-zero status will
1284 status 0 allows the changegroup to proceed. A non-zero status will
1285 cause the push, pull or unbundle to fail. The URL from which changes
1285 cause the push, pull or unbundle to fail. The URL from which changes
1286 will come is in ``$HG_URL``.
1286 will come is in ``$HG_URL``.
1287
1287
1288 ``precommit``
1288 ``precommit``
1289 Run before starting a local commit. Exit status 0 allows the
1289 Run before starting a local commit. Exit status 0 allows the
1290 commit to proceed. A non-zero status will cause the commit to fail.
1290 commit to proceed. A non-zero status will cause the commit to fail.
1291 Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1291 Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1292
1292
1293 ``prelistkeys``
1293 ``prelistkeys``
1294 Run before listing pushkeys (like bookmarks) in the
1294 Run before listing pushkeys (like bookmarks) in the
1295 repository. A non-zero status will cause failure. The key namespace is
1295 repository. A non-zero status will cause failure. The key namespace is
1296 in ``$HG_NAMESPACE``.
1296 in ``$HG_NAMESPACE``.
1297
1297
1298 ``preoutgoing``
1298 ``preoutgoing``
1299 Run before collecting changes to send from the local repository to
1299 Run before collecting changes to send from the local repository to
1300 another. A non-zero status will cause failure. This lets you prevent
1300 another. A non-zero status will cause failure. This lets you prevent
1301 pull over HTTP or SSH. It can also prevent propagating commits (via
1301 pull over HTTP or SSH. It can also prevent propagating commits (via
1302 local pull, push (outbound) or bundle commands), but not completely,
1302 local pull, push (outbound) or bundle commands), but not completely,
1303 since you can just copy files instead. The source of operation is in
1303 since you can just copy files instead. The source of operation is in
1304 ``$HG_SOURCE``. If "serve", the operation is happening on behalf of a remote
1304 ``$HG_SOURCE``. If "serve", the operation is happening on behalf of a remote
1305 SSH or HTTP repository. If "push", "pull" or "bundle", the operation
1305 SSH or HTTP repository. If "push", "pull" or "bundle", the operation
1306 is happening on behalf of a repository on same system.
1306 is happening on behalf of a repository on same system.
1307
1307
1308 ``prepushkey``
1308 ``prepushkey``
1309 Run before a pushkey (like a bookmark) is added to the
1309 Run before a pushkey (like a bookmark) is added to the
1310 repository. A non-zero status will cause the key to be rejected. The
1310 repository. A non-zero status will cause the key to be rejected. The
1311 key namespace is in ``$HG_NAMESPACE``, the key is in ``$HG_KEY``,
1311 key namespace is in ``$HG_NAMESPACE``, the key is in ``$HG_KEY``,
1312 the old value (if any) is in ``$HG_OLD``, and the new value is in
1312 the old value (if any) is in ``$HG_OLD``, and the new value is in
1313 ``$HG_NEW``.
1313 ``$HG_NEW``.
1314
1314
1315 ``pretag``
1315 ``pretag``
1316 Run before creating a tag. Exit status 0 allows the tag to be
1316 Run before creating a tag. Exit status 0 allows the tag to be
1317 created. A non-zero status will cause the tag to fail. The ID of the
1317 created. A non-zero status will cause the tag to fail. The ID of the
1318 changeset to tag is in ``$HG_NODE``. The name of tag is in ``$HG_TAG``. The
1318 changeset to tag is in ``$HG_NODE``. The name of tag is in ``$HG_TAG``. The
1319 tag is local if ``$HG_LOCAL=1``, or in the repository if ``$HG_LOCAL=0``.
1319 tag is local if ``$HG_LOCAL=1``, or in the repository if ``$HG_LOCAL=0``.
1320
1320
1321 ``pretxnopen``
1321 ``pretxnopen``
1322 Run before any new repository transaction is open. The reason for the
1322 Run before any new repository transaction is open. The reason for the
1323 transaction will be in ``$HG_TXNNAME``, and a unique identifier for the
1323 transaction will be in ``$HG_TXNNAME``, and a unique identifier for the
1324 transaction will be in ``$HG_TXNID``. A non-zero status will prevent the
1324 transaction will be in ``$HG_TXNID``. A non-zero status will prevent the
1325 transaction from being opened.
1325 transaction from being opened.
1326
1326
1327 ``pretxnclose``
1327 ``pretxnclose``
1328 Run right before the transaction is actually finalized. Any repository change
1328 Run right before the transaction is actually finalized. Any repository change
1329 will be visible to the hook program. This lets you validate the transaction
1329 will be visible to the hook program. This lets you validate the transaction
1330 content or change it. Exit status 0 allows the commit to proceed. A non-zero
1330 content or change it. Exit status 0 allows the commit to proceed. A non-zero
1331 status will cause the transaction to be rolled back. The reason for the
1331 status will cause the transaction to be rolled back. The reason for the
1332 transaction opening will be in ``$HG_TXNNAME``, and a unique identifier for
1332 transaction opening will be in ``$HG_TXNNAME``, and a unique identifier for
1333 the transaction will be in ``$HG_TXNID``. The rest of the available data will
1333 the transaction will be in ``$HG_TXNID``. The rest of the available data will
1334 vary according the transaction type. Changes unbundled to the repository will
1334 vary according the transaction type. Changes unbundled to the repository will
1335 add ``$HG_URL`` and ``$HG_SOURCE``. New changesets will add ``$HG_NODE`` (the
1335 add ``$HG_URL`` and ``$HG_SOURCE``. New changesets will add ``$HG_NODE`` (the
1336 ID of the first added changeset), ``$HG_NODE_LAST`` (the ID of the last added
1336 ID of the first added changeset), ``$HG_NODE_LAST`` (the ID of the last added
1337 changeset). Bookmark and phase changes will set ``$HG_BOOKMARK_MOVED`` and
1337 changeset). Bookmark and phase changes will set ``$HG_BOOKMARK_MOVED`` and
1338 ``$HG_PHASES_MOVED`` to ``1`` respectively. The number of new obsmarkers, if
1338 ``$HG_PHASES_MOVED`` to ``1`` respectively. The number of new obsmarkers, if
1339 any, will be in ``$HG_NEW_OBSMARKERS``, etc.
1339 any, will be in ``$HG_NEW_OBSMARKERS``, etc.
1340
1340
1341 ``pretxnclose-bookmark``
1341 ``pretxnclose-bookmark``
1342 Run right before a bookmark change is actually finalized. Any repository
1342 Run right before a bookmark change is actually finalized. Any repository
1343 change will be visible to the hook program. This lets you validate the
1343 change will be visible to the hook program. This lets you validate the
1344 transaction content or change it. Exit status 0 allows the commit to
1344 transaction content or change it. Exit status 0 allows the commit to
1345 proceed. A non-zero status will cause the transaction to be rolled back.
1345 proceed. A non-zero status will cause the transaction to be rolled back.
1346 The name of the bookmark will be available in ``$HG_BOOKMARK``, the new
1346 The name of the bookmark will be available in ``$HG_BOOKMARK``, the new
1347 bookmark location will be available in ``$HG_NODE`` while the previous
1347 bookmark location will be available in ``$HG_NODE`` while the previous
1348 location will be available in ``$HG_OLDNODE``. In case of a bookmark
1348 location will be available in ``$HG_OLDNODE``. In case of a bookmark
1349 creation ``$HG_OLDNODE`` will be empty. In case of deletion ``$HG_NODE``
1349 creation ``$HG_OLDNODE`` will be empty. In case of deletion ``$HG_NODE``
1350 will be empty.
1350 will be empty.
1351 In addition, the reason for the transaction opening will be in
1351 In addition, the reason for the transaction opening will be in
1352 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1352 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1353 ``$HG_TXNID``.
1353 ``$HG_TXNID``.
1354
1354
1355 ``pretxnclose-phase``
1355 ``pretxnclose-phase``
1356 Run right before a phase change is actually finalized. Any repository change
1356 Run right before a phase change is actually finalized. Any repository change
1357 will be visible to the hook program. This lets you validate the transaction
1357 will be visible to the hook program. This lets you validate the transaction
1358 content or change it. Exit status 0 allows the commit to proceed. A non-zero
1358 content or change it. Exit status 0 allows the commit to proceed. A non-zero
1359 status will cause the transaction to be rolled back. The hook is called
1359 status will cause the transaction to be rolled back. The hook is called
1360 multiple times, once for each revision affected by a phase change.
1360 multiple times, once for each revision affected by a phase change.
1361 The affected node is available in ``$HG_NODE``, the phase in ``$HG_PHASE``
1361 The affected node is available in ``$HG_NODE``, the phase in ``$HG_PHASE``
1362 while the previous ``$HG_OLDPHASE``. In case of new node, ``$HG_OLDPHASE``
1362 while the previous ``$HG_OLDPHASE``. In case of new node, ``$HG_OLDPHASE``
1363 will be empty. In addition, the reason for the transaction opening will be in
1363 will be empty. In addition, the reason for the transaction opening will be in
1364 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1364 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1365 ``$HG_TXNID``. The hook is also run for newly added revisions. In this case
1365 ``$HG_TXNID``. The hook is also run for newly added revisions. In this case
1366 the ``$HG_OLDPHASE`` entry will be empty.
1366 the ``$HG_OLDPHASE`` entry will be empty.
1367
1367
1368 ``txnclose``
1368 ``txnclose``
1369 Run after any repository transaction has been committed. At this
1369 Run after any repository transaction has been committed. At this
1370 point, the transaction can no longer be rolled back. The hook will run
1370 point, the transaction can no longer be rolled back. The hook will run
1371 after the lock is released. See :hg:`help config.hooks.pretxnclose` for
1371 after the lock is released. See :hg:`help config.hooks.pretxnclose` for
1372 details about available variables.
1372 details about available variables.
1373
1373
1374 ``txnclose-bookmark``
1374 ``txnclose-bookmark``
1375 Run after any bookmark change has been committed. At this point, the
1375 Run after any bookmark change has been committed. At this point, the
1376 transaction can no longer be rolled back. The hook will run after the lock
1376 transaction can no longer be rolled back. The hook will run after the lock
1377 is released. See :hg:`help config.hooks.pretxnclose-bookmark` for details
1377 is released. See :hg:`help config.hooks.pretxnclose-bookmark` for details
1378 about available variables.
1378 about available variables.
1379
1379
1380 ``txnclose-phase``
1380 ``txnclose-phase``
1381 Run after any phase change has been committed. At this point, the
1381 Run after any phase change has been committed. At this point, the
1382 transaction can no longer be rolled back. The hook will run after the lock
1382 transaction can no longer be rolled back. The hook will run after the lock
1383 is released. See :hg:`help config.hooks.pretxnclose-phase` for details about
1383 is released. See :hg:`help config.hooks.pretxnclose-phase` for details about
1384 available variables.
1384 available variables.
1385
1385
1386 ``txnabort``
1386 ``txnabort``
1387 Run when a transaction is aborted. See :hg:`help config.hooks.pretxnclose`
1387 Run when a transaction is aborted. See :hg:`help config.hooks.pretxnclose`
1388 for details about available variables.
1388 for details about available variables.
1389
1389
1390 ``pretxnchangegroup``
1390 ``pretxnchangegroup``
1391 Run after a changegroup has been added via push, pull or unbundle, but before
1391 Run after a changegroup has been added via push, pull or unbundle, but before
1392 the transaction has been committed. The changegroup is visible to the hook
1392 the transaction has been committed. The changegroup is visible to the hook
1393 program. This allows validation of incoming changes before accepting them.
1393 program. This allows validation of incoming changes before accepting them.
1394 The ID of the first new changeset is in ``$HG_NODE`` and last is in
1394 The ID of the first new changeset is in ``$HG_NODE`` and last is in
1395 ``$HG_NODE_LAST``. Exit status 0 allows the transaction to commit. A non-zero
1395 ``$HG_NODE_LAST``. Exit status 0 allows the transaction to commit. A non-zero
1396 status will cause the transaction to be rolled back, and the push, pull or
1396 status will cause the transaction to be rolled back, and the push, pull or
1397 unbundle will fail. The URL that was the source of changes is in ``$HG_URL``.
1397 unbundle will fail. The URL that was the source of changes is in ``$HG_URL``.
1398
1398
1399 ``pretxncommit``
1399 ``pretxncommit``
1400 Run after a changeset has been created, but before the transaction is
1400 Run after a changeset has been created, but before the transaction is
1401 committed. The changeset is visible to the hook program. This allows
1401 committed. The changeset is visible to the hook program. This allows
1402 validation of the commit message and changes. Exit status 0 allows the
1402 validation of the commit message and changes. Exit status 0 allows the
1403 commit to proceed. A non-zero status will cause the transaction to
1403 commit to proceed. A non-zero status will cause the transaction to
1404 be rolled back. The ID of the new changeset is in ``$HG_NODE``. The parent
1404 be rolled back. The ID of the new changeset is in ``$HG_NODE``. The parent
1405 changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1405 changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1406
1406
1407 ``preupdate``
1407 ``preupdate``
1408 Run before updating the working directory. Exit status 0 allows
1408 Run before updating the working directory. Exit status 0 allows
1409 the update to proceed. A non-zero status will prevent the update.
1409 the update to proceed. A non-zero status will prevent the update.
1410 The changeset ID of first new parent is in ``$HG_PARENT1``. If updating to a
1410 The changeset ID of first new parent is in ``$HG_PARENT1``. If updating to a
1411 merge, the ID of second new parent is in ``$HG_PARENT2``.
1411 merge, the ID of second new parent is in ``$HG_PARENT2``.
1412
1412
1413 ``listkeys``
1413 ``listkeys``
1414 Run after listing pushkeys (like bookmarks) in the repository. The
1414 Run after listing pushkeys (like bookmarks) in the repository. The
1415 key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
1415 key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
1416 dictionary containing the keys and values.
1416 dictionary containing the keys and values.
1417
1417
1418 ``pushkey``
1418 ``pushkey``
1419 Run after a pushkey (like a bookmark) is added to the
1419 Run after a pushkey (like a bookmark) is added to the
1420 repository. The key namespace is in ``$HG_NAMESPACE``, the key is in
1420 repository. The key namespace is in ``$HG_NAMESPACE``, the key is in
1421 ``$HG_KEY``, the old value (if any) is in ``$HG_OLD``, and the new
1421 ``$HG_KEY``, the old value (if any) is in ``$HG_OLD``, and the new
1422 value is in ``$HG_NEW``.
1422 value is in ``$HG_NEW``.
1423
1423
1424 ``tag``
1424 ``tag``
1425 Run after a tag is created. The ID of the tagged changeset is in ``$HG_NODE``.
1425 Run after a tag is created. The ID of the tagged changeset is in ``$HG_NODE``.
1426 The name of tag is in ``$HG_TAG``. The tag is local if ``$HG_LOCAL=1``, or in
1426 The name of tag is in ``$HG_TAG``. The tag is local if ``$HG_LOCAL=1``, or in
1427 the repository if ``$HG_LOCAL=0``.
1427 the repository if ``$HG_LOCAL=0``.
1428
1428
1429 ``update``
1429 ``update``
1430 Run after updating the working directory. The changeset ID of first
1430 Run after updating the working directory. The changeset ID of first
1431 new parent is in ``$HG_PARENT1``. If updating to a merge, the ID of second new
1431 new parent is in ``$HG_PARENT1``. If updating to a merge, the ID of second new
1432 parent is in ``$HG_PARENT2``. If the update succeeded, ``$HG_ERROR=0``. If the
1432 parent is in ``$HG_PARENT2``. If the update succeeded, ``$HG_ERROR=0``. If the
1433 update failed (e.g. because conflicts were not resolved), ``$HG_ERROR=1``.
1433 update failed (e.g. because conflicts were not resolved), ``$HG_ERROR=1``.
1434
1434
1435 .. note::
1435 .. note::
1436
1436
1437 It is generally better to use standard hooks rather than the
1437 It is generally better to use standard hooks rather than the
1438 generic pre- and post- command hooks, as they are guaranteed to be
1438 generic pre- and post- command hooks, as they are guaranteed to be
1439 called in the appropriate contexts for influencing transactions.
1439 called in the appropriate contexts for influencing transactions.
1440 Also, hooks like "commit" will be called in all contexts that
1440 Also, hooks like "commit" will be called in all contexts that
1441 generate a commit (e.g. tag) and not just the commit command.
1441 generate a commit (e.g. tag) and not just the commit command.
1442
1442
1443 .. note::
1443 .. note::
1444
1444
1445 Environment variables with empty values may not be passed to
1445 Environment variables with empty values may not be passed to
1446 hooks on platforms such as Windows. As an example, ``$HG_PARENT2``
1446 hooks on platforms such as Windows. As an example, ``$HG_PARENT2``
1447 will have an empty value under Unix-like platforms for non-merge
1447 will have an empty value under Unix-like platforms for non-merge
1448 changesets, while it will not be available at all under Windows.
1448 changesets, while it will not be available at all under Windows.
1449
1449
1450 The syntax for Python hooks is as follows::
1450 The syntax for Python hooks is as follows::
1451
1451
1452 hookname = python:modulename.submodule.callable
1452 hookname = python:modulename.submodule.callable
1453 hookname = python:/path/to/python/module.py:callable
1453 hookname = python:/path/to/python/module.py:callable
1454
1454
1455 Python hooks are run within the Mercurial process. Each hook is
1455 Python hooks are run within the Mercurial process. Each hook is
1456 called with at least three keyword arguments: a ui object (keyword
1456 called with at least three keyword arguments: a ui object (keyword
1457 ``ui``), a repository object (keyword ``repo``), and a ``hooktype``
1457 ``ui``), a repository object (keyword ``repo``), and a ``hooktype``
1458 keyword that tells what kind of hook is used. Arguments listed as
1458 keyword that tells what kind of hook is used. Arguments listed as
1459 environment variables above are passed as keyword arguments, with no
1459 environment variables above are passed as keyword arguments, with no
1460 ``HG_`` prefix, and names in lower case.
1460 ``HG_`` prefix, and names in lower case.
1461
1461
1462 If a Python hook returns a "true" value or raises an exception, this
1462 If a Python hook returns a "true" value or raises an exception, this
1463 is treated as a failure.
1463 is treated as a failure.
1464
1464
1465
1465
1466 ``hostfingerprints``
1466 ``hostfingerprints``
1467 --------------------
1467 --------------------
1468
1468
1469 (Deprecated. Use ``[hostsecurity]``'s ``fingerprints`` options instead.)
1469 (Deprecated. Use ``[hostsecurity]``'s ``fingerprints`` options instead.)
1470
1470
1471 Fingerprints of the certificates of known HTTPS servers.
1471 Fingerprints of the certificates of known HTTPS servers.
1472
1472
1473 A HTTPS connection to a server with a fingerprint configured here will
1473 A HTTPS connection to a server with a fingerprint configured here will
1474 only succeed if the servers certificate matches the fingerprint.
1474 only succeed if the servers certificate matches the fingerprint.
1475 This is very similar to how ssh known hosts works.
1475 This is very similar to how ssh known hosts works.
1476
1476
1477 The fingerprint is the SHA-1 hash value of the DER encoded certificate.
1477 The fingerprint is the SHA-1 hash value of the DER encoded certificate.
1478 Multiple values can be specified (separated by spaces or commas). This can
1478 Multiple values can be specified (separated by spaces or commas). This can
1479 be used to define both old and new fingerprints while a host transitions
1479 be used to define both old and new fingerprints while a host transitions
1480 to a new certificate.
1480 to a new certificate.
1481
1481
1482 The CA chain and web.cacerts is not used for servers with a fingerprint.
1482 The CA chain and web.cacerts is not used for servers with a fingerprint.
1483
1483
1484 For example::
1484 For example::
1485
1485
1486 [hostfingerprints]
1486 [hostfingerprints]
1487 hg.intevation.de = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1487 hg.intevation.de = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1488 hg.intevation.org = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1488 hg.intevation.org = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1489
1489
1490 ``hostsecurity``
1490 ``hostsecurity``
1491 ----------------
1491 ----------------
1492
1492
1493 Used to specify global and per-host security settings for connecting to
1493 Used to specify global and per-host security settings for connecting to
1494 other machines.
1494 other machines.
1495
1495
1496 The following options control default behavior for all hosts.
1496 The following options control default behavior for all hosts.
1497
1497
1498 ``ciphers``
1498 ``ciphers``
1499 Defines the cryptographic ciphers to use for connections.
1499 Defines the cryptographic ciphers to use for connections.
1500
1500
1501 Value must be a valid OpenSSL Cipher List Format as documented at
1501 Value must be a valid OpenSSL Cipher List Format as documented at
1502 https://www.openssl.org/docs/manmaster/apps/ciphers.html#CIPHER-LIST-FORMAT.
1502 https://www.openssl.org/docs/manmaster/apps/ciphers.html#CIPHER-LIST-FORMAT.
1503
1503
1504 This setting is for advanced users only. Setting to incorrect values
1504 This setting is for advanced users only. Setting to incorrect values
1505 can significantly lower connection security or decrease performance.
1505 can significantly lower connection security or decrease performance.
1506 You have been warned.
1506 You have been warned.
1507
1507
1508 This option requires Python 2.7.
1508 This option requires Python 2.7.
1509
1509
1510 ``minimumprotocol``
1510 ``minimumprotocol``
1511 Defines the minimum channel encryption protocol to use.
1511 Defines the minimum channel encryption protocol to use.
1512
1512
1513 By default, the highest version of TLS supported by both client and server
1513 By default, the highest version of TLS supported by both client and server
1514 is used.
1514 is used.
1515
1515
1516 Allowed values are: ``tls1.0``, ``tls1.1``, ``tls1.2``.
1516 Allowed values are: ``tls1.0``, ``tls1.1``, ``tls1.2``.
1517
1517
1518 When running on an old Python version, only ``tls1.0`` is allowed since
1518 When running on an old Python version, only ``tls1.0`` is allowed since
1519 old versions of Python only support up to TLS 1.0.
1519 old versions of Python only support up to TLS 1.0.
1520
1520
1521 When running a Python that supports modern TLS versions, the default is
1521 When running a Python that supports modern TLS versions, the default is
1522 ``tls1.1``. ``tls1.0`` can still be used to allow TLS 1.0. However, this
1522 ``tls1.1``. ``tls1.0`` can still be used to allow TLS 1.0. However, this
1523 weakens security and should only be used as a feature of last resort if
1523 weakens security and should only be used as a feature of last resort if
1524 a server does not support TLS 1.1+.
1524 a server does not support TLS 1.1+.
1525
1525
1526 Options in the ``[hostsecurity]`` section can have the form
1526 Options in the ``[hostsecurity]`` section can have the form
1527 ``hostname``:``setting``. This allows multiple settings to be defined on a
1527 ``hostname``:``setting``. This allows multiple settings to be defined on a
1528 per-host basis.
1528 per-host basis.
1529
1529
1530 The following per-host settings can be defined.
1530 The following per-host settings can be defined.
1531
1531
1532 ``ciphers``
1532 ``ciphers``
1533 This behaves like ``ciphers`` as described above except it only applies
1533 This behaves like ``ciphers`` as described above except it only applies
1534 to the host on which it is defined.
1534 to the host on which it is defined.
1535
1535
1536 ``fingerprints``
1536 ``fingerprints``
1537 A list of hashes of the DER encoded peer/remote certificate. Values have
1537 A list of hashes of the DER encoded peer/remote certificate. Values have
1538 the form ``algorithm``:``fingerprint``. e.g.
1538 the form ``algorithm``:``fingerprint``. e.g.
1539 ``sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2``.
1539 ``sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2``.
1540 In addition, colons (``:``) can appear in the fingerprint part.
1540 In addition, colons (``:``) can appear in the fingerprint part.
1541
1541
1542 The following algorithms/prefixes are supported: ``sha1``, ``sha256``,
1542 The following algorithms/prefixes are supported: ``sha1``, ``sha256``,
1543 ``sha512``.
1543 ``sha512``.
1544
1544
1545 Use of ``sha256`` or ``sha512`` is preferred.
1545 Use of ``sha256`` or ``sha512`` is preferred.
1546
1546
1547 If a fingerprint is specified, the CA chain is not validated for this
1547 If a fingerprint is specified, the CA chain is not validated for this
1548 host and Mercurial will require the remote certificate to match one
1548 host and Mercurial will require the remote certificate to match one
1549 of the fingerprints specified. This means if the server updates its
1549 of the fingerprints specified. This means if the server updates its
1550 certificate, Mercurial will abort until a new fingerprint is defined.
1550 certificate, Mercurial will abort until a new fingerprint is defined.
1551 This can provide stronger security than traditional CA-based validation
1551 This can provide stronger security than traditional CA-based validation
1552 at the expense of convenience.
1552 at the expense of convenience.
1553
1553
1554 This option takes precedence over ``verifycertsfile``.
1554 This option takes precedence over ``verifycertsfile``.
1555
1555
1556 ``minimumprotocol``
1556 ``minimumprotocol``
1557 This behaves like ``minimumprotocol`` as described above except it
1557 This behaves like ``minimumprotocol`` as described above except it
1558 only applies to the host on which it is defined.
1558 only applies to the host on which it is defined.
1559
1559
1560 ``verifycertsfile``
1560 ``verifycertsfile``
1561 Path to file a containing a list of PEM encoded certificates used to
1561 Path to file a containing a list of PEM encoded certificates used to
1562 verify the server certificate. Environment variables and ``~user``
1562 verify the server certificate. Environment variables and ``~user``
1563 constructs are expanded in the filename.
1563 constructs are expanded in the filename.
1564
1564
1565 The server certificate or the certificate's certificate authority (CA)
1565 The server certificate or the certificate's certificate authority (CA)
1566 must match a certificate from this file or certificate verification
1566 must match a certificate from this file or certificate verification
1567 will fail and connections to the server will be refused.
1567 will fail and connections to the server will be refused.
1568
1568
1569 If defined, only certificates provided by this file will be used:
1569 If defined, only certificates provided by this file will be used:
1570 ``web.cacerts`` and any system/default certificates will not be
1570 ``web.cacerts`` and any system/default certificates will not be
1571 used.
1571 used.
1572
1572
1573 This option has no effect if the per-host ``fingerprints`` option
1573 This option has no effect if the per-host ``fingerprints`` option
1574 is set.
1574 is set.
1575
1575
1576 The format of the file is as follows::
1576 The format of the file is as follows::
1577
1577
1578 -----BEGIN CERTIFICATE-----
1578 -----BEGIN CERTIFICATE-----
1579 ... (certificate in base64 PEM encoding) ...
1579 ... (certificate in base64 PEM encoding) ...
1580 -----END CERTIFICATE-----
1580 -----END CERTIFICATE-----
1581 -----BEGIN CERTIFICATE-----
1581 -----BEGIN CERTIFICATE-----
1582 ... (certificate in base64 PEM encoding) ...
1582 ... (certificate in base64 PEM encoding) ...
1583 -----END CERTIFICATE-----
1583 -----END CERTIFICATE-----
1584
1584
1585 For example::
1585 For example::
1586
1586
1587 [hostsecurity]
1587 [hostsecurity]
1588 hg.example.com:fingerprints = sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2
1588 hg.example.com:fingerprints = sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2
1589 hg2.example.com:fingerprints = sha1:914f1aff87249c09b6859b88b1906d30756491ca, sha1:fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1589 hg2.example.com:fingerprints = sha1:914f1aff87249c09b6859b88b1906d30756491ca, sha1:fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1590 hg3.example.com:fingerprints = sha256:9a:b0:dc:e2:75:ad:8a:b7:84:58:e5:1f:07:32:f1:87:e6:bd:24:22:af:b7:ce:8e:9c:b4:10:cf:b9:f4:0e:d2
1590 hg3.example.com:fingerprints = sha256:9a:b0:dc:e2:75:ad:8a:b7:84:58:e5:1f:07:32:f1:87:e6:bd:24:22:af:b7:ce:8e:9c:b4:10:cf:b9:f4:0e:d2
1591 foo.example.com:verifycertsfile = /etc/ssl/trusted-ca-certs.pem
1591 foo.example.com:verifycertsfile = /etc/ssl/trusted-ca-certs.pem
1592
1592
1593 To change the default minimum protocol version to TLS 1.2 but to allow TLS 1.1
1593 To change the default minimum protocol version to TLS 1.2 but to allow TLS 1.1
1594 when connecting to ``hg.example.com``::
1594 when connecting to ``hg.example.com``::
1595
1595
1596 [hostsecurity]
1596 [hostsecurity]
1597 minimumprotocol = tls1.2
1597 minimumprotocol = tls1.2
1598 hg.example.com:minimumprotocol = tls1.1
1598 hg.example.com:minimumprotocol = tls1.1
1599
1599
1600 ``http_proxy``
1600 ``http_proxy``
1601 --------------
1601 --------------
1602
1602
1603 Used to access web-based Mercurial repositories through a HTTP
1603 Used to access web-based Mercurial repositories through a HTTP
1604 proxy.
1604 proxy.
1605
1605
1606 ``host``
1606 ``host``
1607 Host name and (optional) port of the proxy server, for example
1607 Host name and (optional) port of the proxy server, for example
1608 "myproxy:8000".
1608 "myproxy:8000".
1609
1609
1610 ``no``
1610 ``no``
1611 Optional. Comma-separated list of host names that should bypass
1611 Optional. Comma-separated list of host names that should bypass
1612 the proxy.
1612 the proxy.
1613
1613
1614 ``passwd``
1614 ``passwd``
1615 Optional. Password to authenticate with at the proxy server.
1615 Optional. Password to authenticate with at the proxy server.
1616
1616
1617 ``user``
1617 ``user``
1618 Optional. User name to authenticate with at the proxy server.
1618 Optional. User name to authenticate with at the proxy server.
1619
1619
1620 ``always``
1620 ``always``
1621 Optional. Always use the proxy, even for localhost and any entries
1621 Optional. Always use the proxy, even for localhost and any entries
1622 in ``http_proxy.no``. (default: False)
1622 in ``http_proxy.no``. (default: False)
1623
1623
1624 ``http``
1624 ``http``
1625 ----------
1625 ----------
1626
1626
1627 Used to configure access to Mercurial repositories via HTTP.
1627 Used to configure access to Mercurial repositories via HTTP.
1628
1628
1629 ``timeout``
1629 ``timeout``
1630 If set, blocking operations will timeout after that many seconds.
1630 If set, blocking operations will timeout after that many seconds.
1631 (default: None)
1631 (default: None)
1632
1632
1633 ``merge``
1633 ``merge``
1634 ---------
1634 ---------
1635
1635
1636 This section specifies behavior during merges and updates.
1636 This section specifies behavior during merges and updates.
1637
1637
1638 ``checkignored``
1638 ``checkignored``
1639 Controls behavior when an ignored file on disk has the same name as a tracked
1639 Controls behavior when an ignored file on disk has the same name as a tracked
1640 file in the changeset being merged or updated to, and has different
1640 file in the changeset being merged or updated to, and has different
1641 contents. Options are ``abort``, ``warn`` and ``ignore``. With ``abort``,
1641 contents. Options are ``abort``, ``warn`` and ``ignore``. With ``abort``,
1642 abort on such files. With ``warn``, warn on such files and back them up as
1642 abort on such files. With ``warn``, warn on such files and back them up as
1643 ``.orig``. With ``ignore``, don't print a warning and back them up as
1643 ``.orig``. With ``ignore``, don't print a warning and back them up as
1644 ``.orig``. (default: ``abort``)
1644 ``.orig``. (default: ``abort``)
1645
1645
1646 ``checkunknown``
1646 ``checkunknown``
1647 Controls behavior when an unknown file that isn't ignored has the same name
1647 Controls behavior when an unknown file that isn't ignored has the same name
1648 as a tracked file in the changeset being merged or updated to, and has
1648 as a tracked file in the changeset being merged or updated to, and has
1649 different contents. Similar to ``merge.checkignored``, except for files that
1649 different contents. Similar to ``merge.checkignored``, except for files that
1650 are not ignored. (default: ``abort``)
1650 are not ignored. (default: ``abort``)
1651
1651
1652 ``on-failure``
1652 ``on-failure``
1653 When set to ``continue`` (the default), the merge process attempts to
1653 When set to ``continue`` (the default), the merge process attempts to
1654 merge all unresolved files using the merge chosen tool, regardless of
1654 merge all unresolved files using the merge chosen tool, regardless of
1655 whether previous file merge attempts during the process succeeded or not.
1655 whether previous file merge attempts during the process succeeded or not.
1656 Setting this to ``prompt`` will prompt after any merge failure continue
1656 Setting this to ``prompt`` will prompt after any merge failure continue
1657 or halt the merge process. Setting this to ``halt`` will automatically
1657 or halt the merge process. Setting this to ``halt`` will automatically
1658 halt the merge process on any merge tool failure. The merge process
1658 halt the merge process on any merge tool failure. The merge process
1659 can be restarted by using the ``resolve`` command. When a merge is
1659 can be restarted by using the ``resolve`` command. When a merge is
1660 halted, the repository is left in a normal ``unresolved`` merge state.
1660 halted, the repository is left in a normal ``unresolved`` merge state.
1661 (default: ``continue``)
1661 (default: ``continue``)
1662
1662
1663 ``strict-capability-check``
1663 ``strict-capability-check``
1664 Whether capabilities of internal merge tools are checked strictly
1664 Whether capabilities of internal merge tools are checked strictly
1665 or not, while examining rules to decide merge tool to be used.
1665 or not, while examining rules to decide merge tool to be used.
1666 (default: False)
1666 (default: False)
1667
1667
1668 ``merge-patterns``
1668 ``merge-patterns``
1669 ------------------
1669 ------------------
1670
1670
1671 This section specifies merge tools to associate with particular file
1671 This section specifies merge tools to associate with particular file
1672 patterns. Tools matched here will take precedence over the default
1672 patterns. Tools matched here will take precedence over the default
1673 merge tool. Patterns are globs by default, rooted at the repository
1673 merge tool. Patterns are globs by default, rooted at the repository
1674 root.
1674 root.
1675
1675
1676 Example::
1676 Example::
1677
1677
1678 [merge-patterns]
1678 [merge-patterns]
1679 **.c = kdiff3
1679 **.c = kdiff3
1680 **.jpg = myimgmerge
1680 **.jpg = myimgmerge
1681
1681
1682 ``merge-tools``
1682 ``merge-tools``
1683 ---------------
1683 ---------------
1684
1684
1685 This section configures external merge tools to use for file-level
1685 This section configures external merge tools to use for file-level
1686 merges. This section has likely been preconfigured at install time.
1686 merges. This section has likely been preconfigured at install time.
1687 Use :hg:`config merge-tools` to check the existing configuration.
1687 Use :hg:`config merge-tools` to check the existing configuration.
1688 Also see :hg:`help merge-tools` for more details.
1688 Also see :hg:`help merge-tools` for more details.
1689
1689
1690 Example ``~/.hgrc``::
1690 Example ``~/.hgrc``::
1691
1691
1692 [merge-tools]
1692 [merge-tools]
1693 # Override stock tool location
1693 # Override stock tool location
1694 kdiff3.executable = ~/bin/kdiff3
1694 kdiff3.executable = ~/bin/kdiff3
1695 # Specify command line
1695 # Specify command line
1696 kdiff3.args = $base $local $other -o $output
1696 kdiff3.args = $base $local $other -o $output
1697 # Give higher priority
1697 # Give higher priority
1698 kdiff3.priority = 1
1698 kdiff3.priority = 1
1699
1699
1700 # Changing the priority of preconfigured tool
1700 # Changing the priority of preconfigured tool
1701 meld.priority = 0
1701 meld.priority = 0
1702
1702
1703 # Disable a preconfigured tool
1703 # Disable a preconfigured tool
1704 vimdiff.disabled = yes
1704 vimdiff.disabled = yes
1705
1705
1706 # Define new tool
1706 # Define new tool
1707 myHtmlTool.args = -m $local $other $base $output
1707 myHtmlTool.args = -m $local $other $base $output
1708 myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
1708 myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
1709 myHtmlTool.priority = 1
1709 myHtmlTool.priority = 1
1710
1710
1711 Supported arguments:
1711 Supported arguments:
1712
1712
1713 ``priority``
1713 ``priority``
1714 The priority in which to evaluate this tool.
1714 The priority in which to evaluate this tool.
1715 (default: 0)
1715 (default: 0)
1716
1716
1717 ``executable``
1717 ``executable``
1718 Either just the name of the executable or its pathname.
1718 Either just the name of the executable or its pathname.
1719
1719
1720 .. container:: windows
1720 .. container:: windows
1721
1721
1722 On Windows, the path can use environment variables with ${ProgramFiles}
1722 On Windows, the path can use environment variables with ${ProgramFiles}
1723 syntax.
1723 syntax.
1724
1724
1725 (default: the tool name)
1725 (default: the tool name)
1726
1726
1727 ``args``
1727 ``args``
1728 The arguments to pass to the tool executable. You can refer to the
1728 The arguments to pass to the tool executable. You can refer to the
1729 files being merged as well as the output file through these
1729 files being merged as well as the output file through these
1730 variables: ``$base``, ``$local``, ``$other``, ``$output``.
1730 variables: ``$base``, ``$local``, ``$other``, ``$output``.
1731
1731
1732 The meaning of ``$local`` and ``$other`` can vary depending on which action is
1732 The meaning of ``$local`` and ``$other`` can vary depending on which action is
1733 being performed. During an update or merge, ``$local`` represents the original
1733 being performed. During an update or merge, ``$local`` represents the original
1734 state of the file, while ``$other`` represents the commit you are updating to or
1734 state of the file, while ``$other`` represents the commit you are updating to or
1735 the commit you are merging with. During a rebase, ``$local`` represents the
1735 the commit you are merging with. During a rebase, ``$local`` represents the
1736 destination of the rebase, and ``$other`` represents the commit being rebased.
1736 destination of the rebase, and ``$other`` represents the commit being rebased.
1737
1737
1738 Some operations define custom labels to assist with identifying the revisions,
1738 Some operations define custom labels to assist with identifying the revisions,
1739 accessible via ``$labellocal``, ``$labelother``, and ``$labelbase``. If custom
1739 accessible via ``$labellocal``, ``$labelother``, and ``$labelbase``. If custom
1740 labels are not available, these will be ``local``, ``other``, and ``base``,
1740 labels are not available, these will be ``local``, ``other``, and ``base``,
1741 respectively.
1741 respectively.
1742 (default: ``$local $base $other``)
1742 (default: ``$local $base $other``)
1743
1743
1744 ``premerge``
1744 ``premerge``
1745 Attempt to run internal non-interactive 3-way merge tool before
1745 Attempt to run internal non-interactive 3-way merge tool before
1746 launching external tool. Options are ``true``, ``false``, ``keep``,
1746 launching external tool. Options are ``true``, ``false``, ``keep``,
1747 ``keep-merge3``, or ``keep-mergediff`` (experimental). The ``keep`` option
1747 ``keep-merge3``, or ``keep-mergediff`` (experimental). The ``keep`` option
1748 will leave markers in the file if the premerge fails. The ``keep-merge3``
1748 will leave markers in the file if the premerge fails. The ``keep-merge3``
1749 will do the same but include information about the base of the merge in the
1749 will do the same but include information about the base of the merge in the
1750 marker (see internal :merge3 in :hg:`help merge-tools`). The
1750 marker (see internal :merge3 in :hg:`help merge-tools`). The
1751 ``keep-mergediff`` option is similar but uses a different marker style
1751 ``keep-mergediff`` option is similar but uses a different marker style
1752 (see internal :merge3 in :hg:`help merge-tools`). (default: True)
1752 (see internal :merge3 in :hg:`help merge-tools`). (default: True)
1753
1753
1754 ``binary``
1754 ``binary``
1755 This tool can merge binary files. (default: False, unless tool
1755 This tool can merge binary files. (default: False, unless tool
1756 was selected by file pattern match)
1756 was selected by file pattern match)
1757
1757
1758 ``symlink``
1758 ``symlink``
1759 This tool can merge symlinks. (default: False)
1759 This tool can merge symlinks. (default: False)
1760
1760
1761 ``check``
1761 ``check``
1762 A list of merge success-checking options:
1762 A list of merge success-checking options:
1763
1763
1764 ``changed``
1764 ``changed``
1765 Ask whether merge was successful when the merged file shows no changes.
1765 Ask whether merge was successful when the merged file shows no changes.
1766 ``conflicts``
1766 ``conflicts``
1767 Check whether there are conflicts even though the tool reported success.
1767 Check whether there are conflicts even though the tool reported success.
1768 ``prompt``
1768 ``prompt``
1769 Always prompt for merge success, regardless of success reported by tool.
1769 Always prompt for merge success, regardless of success reported by tool.
1770
1770
1771 ``fixeol``
1771 ``fixeol``
1772 Attempt to fix up EOL changes caused by the merge tool.
1772 Attempt to fix up EOL changes caused by the merge tool.
1773 (default: False)
1773 (default: False)
1774
1774
1775 ``gui``
1775 ``gui``
1776 This tool requires a graphical interface to run. (default: False)
1776 This tool requires a graphical interface to run. (default: False)
1777
1777
1778 ``mergemarkers``
1778 ``mergemarkers``
1779 Controls whether the labels passed via ``$labellocal``, ``$labelother``, and
1779 Controls whether the labels passed via ``$labellocal``, ``$labelother``, and
1780 ``$labelbase`` are ``detailed`` (respecting ``mergemarkertemplate``) or
1780 ``$labelbase`` are ``detailed`` (respecting ``mergemarkertemplate``) or
1781 ``basic``. If ``premerge`` is ``keep`` or ``keep-merge3``, the conflict
1781 ``basic``. If ``premerge`` is ``keep`` or ``keep-merge3``, the conflict
1782 markers generated during premerge will be ``detailed`` if either this option or
1782 markers generated during premerge will be ``detailed`` if either this option or
1783 the corresponding option in the ``[ui]`` section is ``detailed``.
1783 the corresponding option in the ``[ui]`` section is ``detailed``.
1784 (default: ``basic``)
1784 (default: ``basic``)
1785
1785
1786 ``mergemarkertemplate``
1786 ``mergemarkertemplate``
1787 This setting can be used to override ``mergemarker`` from the
1787 This setting can be used to override ``mergemarker`` from the
1788 ``[command-templates]`` section on a per-tool basis; this applies to the
1788 ``[command-templates]`` section on a per-tool basis; this applies to the
1789 ``$label``-prefixed variables and to the conflict markers that are generated
1789 ``$label``-prefixed variables and to the conflict markers that are generated
1790 if ``premerge`` is ``keep` or ``keep-merge3``. See the corresponding variable
1790 if ``premerge`` is ``keep` or ``keep-merge3``. See the corresponding variable
1791 in ``[ui]`` for more information.
1791 in ``[ui]`` for more information.
1792
1792
1793 .. container:: windows
1793 .. container:: windows
1794
1794
1795 ``regkey``
1795 ``regkey``
1796 Windows registry key which describes install location of this
1796 Windows registry key which describes install location of this
1797 tool. Mercurial will search for this key first under
1797 tool. Mercurial will search for this key first under
1798 ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
1798 ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
1799 (default: None)
1799 (default: None)
1800
1800
1801 ``regkeyalt``
1801 ``regkeyalt``
1802 An alternate Windows registry key to try if the first key is not
1802 An alternate Windows registry key to try if the first key is not
1803 found. The alternate key uses the same ``regname`` and ``regappend``
1803 found. The alternate key uses the same ``regname`` and ``regappend``
1804 semantics of the primary key. The most common use for this key
1804 semantics of the primary key. The most common use for this key
1805 is to search for 32bit applications on 64bit operating systems.
1805 is to search for 32bit applications on 64bit operating systems.
1806 (default: None)
1806 (default: None)
1807
1807
1808 ``regname``
1808 ``regname``
1809 Name of value to read from specified registry key.
1809 Name of value to read from specified registry key.
1810 (default: the unnamed (default) value)
1810 (default: the unnamed (default) value)
1811
1811
1812 ``regappend``
1812 ``regappend``
1813 String to append to the value read from the registry, typically
1813 String to append to the value read from the registry, typically
1814 the executable name of the tool.
1814 the executable name of the tool.
1815 (default: None)
1815 (default: None)
1816
1816
1817 ``pager``
1817 ``pager``
1818 ---------
1818 ---------
1819
1819
1820 Setting used to control when to paginate and with what external tool. See
1820 Setting used to control when to paginate and with what external tool. See
1821 :hg:`help pager` for details.
1821 :hg:`help pager` for details.
1822
1822
1823 ``pager``
1823 ``pager``
1824 Define the external tool used as pager.
1824 Define the external tool used as pager.
1825
1825
1826 If no pager is set, Mercurial uses the environment variable $PAGER.
1826 If no pager is set, Mercurial uses the environment variable $PAGER.
1827 If neither pager.pager, nor $PAGER is set, a default pager will be
1827 If neither pager.pager, nor $PAGER is set, a default pager will be
1828 used, typically `less` on Unix and `more` on Windows. Example::
1828 used, typically `less` on Unix and `more` on Windows. Example::
1829
1829
1830 [pager]
1830 [pager]
1831 pager = less -FRX
1831 pager = less -FRX
1832
1832
1833 ``ignore``
1833 ``ignore``
1834 List of commands to disable the pager for. Example::
1834 List of commands to disable the pager for. Example::
1835
1835
1836 [pager]
1836 [pager]
1837 ignore = version, help, update
1837 ignore = version, help, update
1838
1838
1839 ``patch``
1839 ``patch``
1840 ---------
1840 ---------
1841
1841
1842 Settings used when applying patches, for instance through the 'import'
1842 Settings used when applying patches, for instance through the 'import'
1843 command or with Mercurial Queues extension.
1843 command or with Mercurial Queues extension.
1844
1844
1845 ``eol``
1845 ``eol``
1846 When set to 'strict' patch content and patched files end of lines
1846 When set to 'strict' patch content and patched files end of lines
1847 are preserved. When set to ``lf`` or ``crlf``, both files end of
1847 are preserved. When set to ``lf`` or ``crlf``, both files end of
1848 lines are ignored when patching and the result line endings are
1848 lines are ignored when patching and the result line endings are
1849 normalized to either LF (Unix) or CRLF (Windows). When set to
1849 normalized to either LF (Unix) or CRLF (Windows). When set to
1850 ``auto``, end of lines are again ignored while patching but line
1850 ``auto``, end of lines are again ignored while patching but line
1851 endings in patched files are normalized to their original setting
1851 endings in patched files are normalized to their original setting
1852 on a per-file basis. If target file does not exist or has no end
1852 on a per-file basis. If target file does not exist or has no end
1853 of line, patch line endings are preserved.
1853 of line, patch line endings are preserved.
1854 (default: strict)
1854 (default: strict)
1855
1855
1856 ``fuzz``
1856 ``fuzz``
1857 The number of lines of 'fuzz' to allow when applying patches. This
1857 The number of lines of 'fuzz' to allow when applying patches. This
1858 controls how much context the patcher is allowed to ignore when
1858 controls how much context the patcher is allowed to ignore when
1859 trying to apply a patch.
1859 trying to apply a patch.
1860 (default: 2)
1860 (default: 2)
1861
1861
1862 ``paths``
1862 ``paths``
1863 ---------
1863 ---------
1864
1864
1865 Assigns symbolic names and behavior to repositories.
1865 Assigns symbolic names and behavior to repositories.
1866
1866
1867 Options are symbolic names defining the URL or directory that is the
1867 Options are symbolic names defining the URL or directory that is the
1868 location of the repository. Example::
1868 location of the repository. Example::
1869
1869
1870 [paths]
1870 [paths]
1871 my_server = https://example.com/my_repo
1871 my_server = https://example.com/my_repo
1872 local_path = /home/me/repo
1872 local_path = /home/me/repo
1873
1873
1874 These symbolic names can be used from the command line. To pull
1874 These symbolic names can be used from the command line. To pull
1875 from ``my_server``: :hg:`pull my_server`. To push to ``local_path``:
1875 from ``my_server``: :hg:`pull my_server`. To push to ``local_path``:
1876 :hg:`push local_path`. You can check :hg:`help urls` for details about
1876 :hg:`push local_path`. You can check :hg:`help urls` for details about
1877 valid URLs.
1877 valid URLs.
1878
1878
1879 Options containing colons (``:``) denote sub-options that can influence
1879 Options containing colons (``:``) denote sub-options that can influence
1880 behavior for that specific path. Example::
1880 behavior for that specific path. Example::
1881
1881
1882 [paths]
1882 [paths]
1883 my_server = https://example.com/my_path
1883 my_server = https://example.com/my_path
1884 my_server:pushurl = ssh://example.com/my_path
1884 my_server:pushurl = ssh://example.com/my_path
1885
1885
1886 Paths using the `path://otherpath` scheme will inherit the sub-options value from
1886 Paths using the `path://otherpath` scheme will inherit the sub-options value from
1887 the path they point to.
1887 the path they point to.
1888
1888
1889 The following sub-options can be defined:
1889 The following sub-options can be defined:
1890
1890
1891 ``multi-urls``
1891 ``multi-urls``
1892 A boolean option. When enabled the value of the `[paths]` entry will be
1892 A boolean option. When enabled the value of the `[paths]` entry will be
1893 parsed as a list and the alias will resolve to multiple destination. If some
1893 parsed as a list and the alias will resolve to multiple destination. If some
1894 of the list entry use the `path://` syntax, the suboption will be inherited
1894 of the list entry use the `path://` syntax, the suboption will be inherited
1895 individually.
1895 individually.
1896
1896
1897 ``pushurl``
1897 ``pushurl``
1898 The URL to use for push operations. If not defined, the location
1898 The URL to use for push operations. If not defined, the location
1899 defined by the path's main entry is used.
1899 defined by the path's main entry is used.
1900
1900
1901 ``pushrev``
1901 ``pushrev``
1902 A revset defining which revisions to push by default.
1902 A revset defining which revisions to push by default.
1903
1903
1904 When :hg:`push` is executed without a ``-r`` argument, the revset
1904 When :hg:`push` is executed without a ``-r`` argument, the revset
1905 defined by this sub-option is evaluated to determine what to push.
1905 defined by this sub-option is evaluated to determine what to push.
1906
1906
1907 For example, a value of ``.`` will push the working directory's
1907 For example, a value of ``.`` will push the working directory's
1908 revision by default.
1908 revision by default.
1909
1909
1910 Revsets specifying bookmarks will not result in the bookmark being
1910 Revsets specifying bookmarks will not result in the bookmark being
1911 pushed.
1911 pushed.
1912
1912
1913 ``bookmarks.mode``
1913 ``bookmarks.mode``
1914 How bookmark will be dealt during the exchange. It support the following value
1914 How bookmark will be dealt during the exchange. It support the following value
1915
1915
1916 - ``default``: the default behavior, local and remote bookmarks are "merged"
1916 - ``default``: the default behavior, local and remote bookmarks are "merged"
1917 on push/pull.
1917 on push/pull.
1918
1918
1919 - ``mirror``: when pulling, replace local bookmarks by remote bookmarks. This
1919 - ``mirror``: when pulling, replace local bookmarks by remote bookmarks. This
1920 is useful to replicate a repository, or as an optimization.
1920 is useful to replicate a repository, or as an optimization.
1921
1921
1922 - ``ignore``: ignore bookmarks during exchange.
1922 - ``ignore``: ignore bookmarks during exchange.
1923 (This currently only affect pulling)
1923 (This currently only affect pulling)
1924
1924
1925 The following special named paths exist:
1925 The following special named paths exist:
1926
1926
1927 ``default``
1927 ``default``
1928 The URL or directory to use when no source or remote is specified.
1928 The URL or directory to use when no source or remote is specified.
1929
1929
1930 :hg:`clone` will automatically define this path to the location the
1930 :hg:`clone` will automatically define this path to the location the
1931 repository was cloned from.
1931 repository was cloned from.
1932
1932
1933 ``default-push``
1933 ``default-push``
1934 (deprecated) The URL or directory for the default :hg:`push` location.
1934 (deprecated) The URL or directory for the default :hg:`push` location.
1935 ``default:pushurl`` should be used instead.
1935 ``default:pushurl`` should be used instead.
1936
1936
1937 ``phases``
1937 ``phases``
1938 ----------
1938 ----------
1939
1939
1940 Specifies default handling of phases. See :hg:`help phases` for more
1940 Specifies default handling of phases. See :hg:`help phases` for more
1941 information about working with phases.
1941 information about working with phases.
1942
1942
1943 ``publish``
1943 ``publish``
1944 Controls draft phase behavior when working as a server. When true,
1944 Controls draft phase behavior when working as a server. When true,
1945 pushed changesets are set to public in both client and server and
1945 pushed changesets are set to public in both client and server and
1946 pulled or cloned changesets are set to public in the client.
1946 pulled or cloned changesets are set to public in the client.
1947 (default: True)
1947 (default: True)
1948
1948
1949 ``new-commit``
1949 ``new-commit``
1950 Phase of newly-created commits.
1950 Phase of newly-created commits.
1951 (default: draft)
1951 (default: draft)
1952
1952
1953 ``checksubrepos``
1953 ``checksubrepos``
1954 Check the phase of the current revision of each subrepository. Allowed
1954 Check the phase of the current revision of each subrepository. Allowed
1955 values are "ignore", "follow" and "abort". For settings other than
1955 values are "ignore", "follow" and "abort". For settings other than
1956 "ignore", the phase of the current revision of each subrepository is
1956 "ignore", the phase of the current revision of each subrepository is
1957 checked before committing the parent repository. If any of those phases is
1957 checked before committing the parent repository. If any of those phases is
1958 greater than the phase of the parent repository (e.g. if a subrepo is in a
1958 greater than the phase of the parent repository (e.g. if a subrepo is in a
1959 "secret" phase while the parent repo is in "draft" phase), the commit is
1959 "secret" phase while the parent repo is in "draft" phase), the commit is
1960 either aborted (if checksubrepos is set to "abort") or the higher phase is
1960 either aborted (if checksubrepos is set to "abort") or the higher phase is
1961 used for the parent repository commit (if set to "follow").
1961 used for the parent repository commit (if set to "follow").
1962 (default: follow)
1962 (default: follow)
1963
1963
1964
1964
1965 ``profiling``
1965 ``profiling``
1966 -------------
1966 -------------
1967
1967
1968 Specifies profiling type, format, and file output. Two profilers are
1968 Specifies profiling type, format, and file output. Two profilers are
1969 supported: an instrumenting profiler (named ``ls``), and a sampling
1969 supported: an instrumenting profiler (named ``ls``), and a sampling
1970 profiler (named ``stat``).
1970 profiler (named ``stat``).
1971
1971
1972 In this section description, 'profiling data' stands for the raw data
1972 In this section description, 'profiling data' stands for the raw data
1973 collected during profiling, while 'profiling report' stands for a
1973 collected during profiling, while 'profiling report' stands for a
1974 statistical text report generated from the profiling data.
1974 statistical text report generated from the profiling data.
1975
1975
1976 ``enabled``
1976 ``enabled``
1977 Enable the profiler.
1977 Enable the profiler.
1978 (default: false)
1978 (default: false)
1979
1979
1980 This is equivalent to passing ``--profile`` on the command line.
1980 This is equivalent to passing ``--profile`` on the command line.
1981
1981
1982 ``type``
1982 ``type``
1983 The type of profiler to use.
1983 The type of profiler to use.
1984 (default: stat)
1984 (default: stat)
1985
1985
1986 ``ls``
1986 ``ls``
1987 Use Python's built-in instrumenting profiler. This profiler
1987 Use Python's built-in instrumenting profiler. This profiler
1988 works on all platforms, but each line number it reports is the
1988 works on all platforms, but each line number it reports is the
1989 first line of a function. This restriction makes it difficult to
1989 first line of a function. This restriction makes it difficult to
1990 identify the expensive parts of a non-trivial function.
1990 identify the expensive parts of a non-trivial function.
1991 ``stat``
1991 ``stat``
1992 Use a statistical profiler, statprof. This profiler is most
1992 Use a statistical profiler, statprof. This profiler is most
1993 useful for profiling commands that run for longer than about 0.1
1993 useful for profiling commands that run for longer than about 0.1
1994 seconds.
1994 seconds.
1995
1995
1996 ``format``
1996 ``format``
1997 Profiling format. Specific to the ``ls`` instrumenting profiler.
1997 Profiling format. Specific to the ``ls`` instrumenting profiler.
1998 (default: text)
1998 (default: text)
1999
1999
2000 ``text``
2000 ``text``
2001 Generate a profiling report. When saving to a file, it should be
2001 Generate a profiling report. When saving to a file, it should be
2002 noted that only the report is saved, and the profiling data is
2002 noted that only the report is saved, and the profiling data is
2003 not kept.
2003 not kept.
2004 ``kcachegrind``
2004 ``kcachegrind``
2005 Format profiling data for kcachegrind use: when saving to a
2005 Format profiling data for kcachegrind use: when saving to a
2006 file, the generated file can directly be loaded into
2006 file, the generated file can directly be loaded into
2007 kcachegrind.
2007 kcachegrind.
2008
2008
2009 ``statformat``
2009 ``statformat``
2010 Profiling format for the ``stat`` profiler.
2010 Profiling format for the ``stat`` profiler.
2011 (default: hotpath)
2011 (default: hotpath)
2012
2012
2013 ``hotpath``
2013 ``hotpath``
2014 Show a tree-based display containing the hot path of execution (where
2014 Show a tree-based display containing the hot path of execution (where
2015 most time was spent).
2015 most time was spent).
2016 ``bymethod``
2016 ``bymethod``
2017 Show a table of methods ordered by how frequently they are active.
2017 Show a table of methods ordered by how frequently they are active.
2018 ``byline``
2018 ``byline``
2019 Show a table of lines in files ordered by how frequently they are active.
2019 Show a table of lines in files ordered by how frequently they are active.
2020 ``json``
2020 ``json``
2021 Render profiling data as JSON.
2021 Render profiling data as JSON.
2022
2022
2023 ``freq``
2023 ``freq``
2024 Sampling frequency. Specific to the ``stat`` sampling profiler.
2024 Sampling frequency. Specific to the ``stat`` sampling profiler.
2025 (default: 1000)
2025 (default: 1000)
2026
2026
2027 ``output``
2027 ``output``
2028 File path where profiling data or report should be saved. If the
2028 File path where profiling data or report should be saved. If the
2029 file exists, it is replaced. (default: None, data is printed on
2029 file exists, it is replaced. (default: None, data is printed on
2030 stderr)
2030 stderr)
2031
2031
2032 ``sort``
2032 ``sort``
2033 Sort field. Specific to the ``ls`` instrumenting profiler.
2033 Sort field. Specific to the ``ls`` instrumenting profiler.
2034 One of ``callcount``, ``reccallcount``, ``totaltime`` and
2034 One of ``callcount``, ``reccallcount``, ``totaltime`` and
2035 ``inlinetime``.
2035 ``inlinetime``.
2036 (default: inlinetime)
2036 (default: inlinetime)
2037
2037
2038 ``time-track``
2038 ``time-track``
2039 Control if the stat profiler track ``cpu`` or ``real`` time.
2039 Control if the stat profiler track ``cpu`` or ``real`` time.
2040 (default: ``cpu`` on Windows, otherwise ``real``)
2040 (default: ``cpu`` on Windows, otherwise ``real``)
2041
2041
2042 ``limit``
2042 ``limit``
2043 Number of lines to show. Specific to the ``ls`` instrumenting profiler.
2043 Number of lines to show. Specific to the ``ls`` instrumenting profiler.
2044 (default: 30)
2044 (default: 30)
2045
2045
2046 ``nested``
2046 ``nested``
2047 Show at most this number of lines of drill-down info after each main entry.
2047 Show at most this number of lines of drill-down info after each main entry.
2048 This can help explain the difference between Total and Inline.
2048 This can help explain the difference between Total and Inline.
2049 Specific to the ``ls`` instrumenting profiler.
2049 Specific to the ``ls`` instrumenting profiler.
2050 (default: 0)
2050 (default: 0)
2051
2051
2052 ``showmin``
2052 ``showmin``
2053 Minimum fraction of samples an entry must have for it to be displayed.
2053 Minimum fraction of samples an entry must have for it to be displayed.
2054 Can be specified as a float between ``0.0`` and ``1.0`` or can have a
2054 Can be specified as a float between ``0.0`` and ``1.0`` or can have a
2055 ``%`` afterwards to allow values up to ``100``. e.g. ``5%``.
2055 ``%`` afterwards to allow values up to ``100``. e.g. ``5%``.
2056
2056
2057 Only used by the ``stat`` profiler.
2057 Only used by the ``stat`` profiler.
2058
2058
2059 For the ``hotpath`` format, default is ``0.05``.
2059 For the ``hotpath`` format, default is ``0.05``.
2060 For the ``chrome`` format, default is ``0.005``.
2060 For the ``chrome`` format, default is ``0.005``.
2061
2061
2062 The option is unused on other formats.
2062 The option is unused on other formats.
2063
2063
2064 ``showmax``
2064 ``showmax``
2065 Maximum fraction of samples an entry can have before it is ignored in
2065 Maximum fraction of samples an entry can have before it is ignored in
2066 display. Values format is the same as ``showmin``.
2066 display. Values format is the same as ``showmin``.
2067
2067
2068 Only used by the ``stat`` profiler.
2068 Only used by the ``stat`` profiler.
2069
2069
2070 For the ``chrome`` format, default is ``0.999``.
2070 For the ``chrome`` format, default is ``0.999``.
2071
2071
2072 The option is unused on other formats.
2072 The option is unused on other formats.
2073
2073
2074 ``showtime``
2074 ``showtime``
2075 Show time taken as absolute durations, in addition to percentages.
2075 Show time taken as absolute durations, in addition to percentages.
2076 Only used by the ``hotpath`` format.
2076 Only used by the ``hotpath`` format.
2077 (default: true)
2077 (default: true)
2078
2078
2079 ``progress``
2079 ``progress``
2080 ------------
2080 ------------
2081
2081
2082 Mercurial commands can draw progress bars that are as informative as
2082 Mercurial commands can draw progress bars that are as informative as
2083 possible. Some progress bars only offer indeterminate information, while others
2083 possible. Some progress bars only offer indeterminate information, while others
2084 have a definite end point.
2084 have a definite end point.
2085
2085
2086 ``debug``
2086 ``debug``
2087 Whether to print debug info when updating the progress bar. (default: False)
2087 Whether to print debug info when updating the progress bar. (default: False)
2088
2088
2089 ``delay``
2089 ``delay``
2090 Number of seconds (float) before showing the progress bar. (default: 3)
2090 Number of seconds (float) before showing the progress bar. (default: 3)
2091
2091
2092 ``changedelay``
2092 ``changedelay``
2093 Minimum delay before showing a new topic. When set to less than 3 * refresh,
2093 Minimum delay before showing a new topic. When set to less than 3 * refresh,
2094 that value will be used instead. (default: 1)
2094 that value will be used instead. (default: 1)
2095
2095
2096 ``estimateinterval``
2096 ``estimateinterval``
2097 Maximum sampling interval in seconds for speed and estimated time
2097 Maximum sampling interval in seconds for speed and estimated time
2098 calculation. (default: 60)
2098 calculation. (default: 60)
2099
2099
2100 ``refresh``
2100 ``refresh``
2101 Time in seconds between refreshes of the progress bar. (default: 0.1)
2101 Time in seconds between refreshes of the progress bar. (default: 0.1)
2102
2102
2103 ``format``
2103 ``format``
2104 Format of the progress bar.
2104 Format of the progress bar.
2105
2105
2106 Valid entries for the format field are ``topic``, ``bar``, ``number``,
2106 Valid entries for the format field are ``topic``, ``bar``, ``number``,
2107 ``unit``, ``estimate``, ``speed``, and ``item``. ``item`` defaults to the
2107 ``unit``, ``estimate``, ``speed``, and ``item``. ``item`` defaults to the
2108 last 20 characters of the item, but this can be changed by adding either
2108 last 20 characters of the item, but this can be changed by adding either
2109 ``-<num>`` which would take the last num characters, or ``+<num>`` for the
2109 ``-<num>`` which would take the last num characters, or ``+<num>`` for the
2110 first num characters.
2110 first num characters.
2111
2111
2112 (default: topic bar number estimate)
2112 (default: topic bar number estimate)
2113
2113
2114 ``width``
2114 ``width``
2115 If set, the maximum width of the progress information (that is, min(width,
2115 If set, the maximum width of the progress information (that is, min(width,
2116 term width) will be used).
2116 term width) will be used).
2117
2117
2118 ``clear-complete``
2118 ``clear-complete``
2119 Clear the progress bar after it's done. (default: True)
2119 Clear the progress bar after it's done. (default: True)
2120
2120
2121 ``disable``
2121 ``disable``
2122 If true, don't show a progress bar.
2122 If true, don't show a progress bar.
2123
2123
2124 ``assume-tty``
2124 ``assume-tty``
2125 If true, ALWAYS show a progress bar, unless disable is given.
2125 If true, ALWAYS show a progress bar, unless disable is given.
2126
2126
2127 ``rebase``
2127 ``rebase``
2128 ----------
2128 ----------
2129
2129
2130 ``evolution.allowdivergence``
2130 ``evolution.allowdivergence``
2131 Default to False, when True allow creating divergence when performing
2131 Default to False, when True allow creating divergence when performing
2132 rebase of obsolete changesets.
2132 rebase of obsolete changesets.
2133
2133
2134 ``revsetalias``
2134 ``revsetalias``
2135 ---------------
2135 ---------------
2136
2136
2137 Alias definitions for revsets. See :hg:`help revsets` for details.
2137 Alias definitions for revsets. See :hg:`help revsets` for details.
2138
2138
2139 ``rewrite``
2139 ``rewrite``
2140 -----------
2140 -----------
2141
2141
2142 ``backup-bundle``
2142 ``backup-bundle``
2143 Whether to save stripped changesets to a bundle file. (default: True)
2143 Whether to save stripped changesets to a bundle file. (default: True)
2144
2144
2145 ``update-timestamp``
2145 ``update-timestamp``
2146 If true, updates the date and time of the changeset to current. It is only
2146 If true, updates the date and time of the changeset to current. It is only
2147 applicable for `hg amend`, `hg commit --amend` and `hg uncommit` in the
2147 applicable for `hg amend`, `hg commit --amend` and `hg uncommit` in the
2148 current version.
2148 current version.
2149
2149
2150 ``empty-successor``
2150 ``empty-successor``
2151
2151
2152 Control what happens with empty successors that are the result of rewrite
2152 Control what happens with empty successors that are the result of rewrite
2153 operations. If set to ``skip``, the successor is not created. If set to
2153 operations. If set to ``skip``, the successor is not created. If set to
2154 ``keep``, the empty successor is created and kept.
2154 ``keep``, the empty successor is created and kept.
2155
2155
2156 Currently, only the rebase and absorb commands consider this configuration.
2156 Currently, only the rebase and absorb commands consider this configuration.
2157 (EXPERIMENTAL)
2157 (EXPERIMENTAL)
2158
2158
2159 ``rhg``
2160 -------
2161
2162 The pure Rust fast-path for Mercurial. See `rust/README.rst` in the Mercurial repository.
2163
2164 ``fallback-executable``
2165 Path to the executable to run in a sub-process when falling back to
2166 another implementation of Mercurial.
2167
2168 ``fallback-immediately``
2169 Fall back to ``fallback-executable`` as soon as possible, regardless of
2170 the `rhg.on-unsupported` configuration. Useful for debugging, for example to
2171 bypass `rhg` if the deault `hg` points to `rhg`.
2172
2173 Note that because this requires loading the configuration, it is possible
2174 that `rhg` error out before being able to fall back.
2175
2176 ``ignored-extensions``
2177 Controls which extensions should be ignored by `rhg`. By default, `rhg`
2178 triggers the `rhg.on-unsupported` behavior any unsupported extensions.
2179 Users can disable that behavior when they know that a given extension
2180 does not need support from `rhg`.
2181
2182 Expects a list of extension names, or ``*`` to ignore all extensions.
2183
2184 Note: ``*:<suboption>`` is also a valid extension name for this
2185 configuration option.
2186 As of this writing, the only valid "global" suboption is ``required``.
2187
2188 ``on-unsupported``
2189 Controls the behavior of `rhg` when detecting unsupported features.
2190
2191 Possible values are `abort` (default), `abort-silent` and `fallback`.
2192
2193 ``abort``
2194 Print an error message describing what feature is not supported,
2195 and exit with code 252
2196
2197 ``abort-silent``
2198 Silently exit with code 252
2199
2200 ``fallback``
2201 Try running the fallback executable with the same parameters
2202 (and trace the fallback reason, use `RUST_LOG=trace` to see).
2203
2159 ``share``
2204 ``share``
2160 ---------
2205 ---------
2161
2206
2162 ``safe-mismatch.source-safe``
2207 ``safe-mismatch.source-safe``
2163 Controls what happens when the shared repository does not use the
2208 Controls what happens when the shared repository does not use the
2164 share-safe mechanism but its source repository does.
2209 share-safe mechanism but its source repository does.
2165
2210
2166 Possible values are `abort` (default), `allow`, `upgrade-abort` and
2211 Possible values are `abort` (default), `allow`, `upgrade-abort` and
2167 `upgrade-allow`.
2212 `upgrade-allow`.
2168
2213
2169 ``abort``
2214 ``abort``
2170 Disallows running any command and aborts
2215 Disallows running any command and aborts
2171 ``allow``
2216 ``allow``
2172 Respects the feature presence in the share source
2217 Respects the feature presence in the share source
2173 ``upgrade-abort``
2218 ``upgrade-abort``
2174 tries to upgrade the share to use share-safe; if it fails, aborts
2219 Tries to upgrade the share to use share-safe; if it fails, aborts
2175 ``upgrade-allow``
2220 ``upgrade-allow``
2176 tries to upgrade the share; if it fails, continue by
2221 Tries to upgrade the share; if it fails, continue by
2177 respecting the share source setting
2222 respecting the share source setting
2178
2223
2179 Check :hg:`help config.format.use-share-safe` for details about the
2224 Check :hg:`help config.format.use-share-safe` for details about the
2180 share-safe feature.
2225 share-safe feature.
2181
2226
2182 ``safe-mismatch.source-safe:verbose-upgrade``
2227 ``safe-mismatch.source-safe:verbose-upgrade``
2183 Display a message when upgrading, (default: True)
2228 Display a message when upgrading, (default: True)
2184
2229
2185 ``safe-mismatch.source-safe.warn``
2230 ``safe-mismatch.source-safe.warn``
2186 Shows a warning on operations if the shared repository does not use
2231 Shows a warning on operations if the shared repository does not use
2187 share-safe, but the source repository does.
2232 share-safe, but the source repository does.
2188 (default: True)
2233 (default: True)
2189
2234
2190 ``safe-mismatch.source-not-safe``
2235 ``safe-mismatch.source-not-safe``
2191 Controls what happens when the shared repository uses the share-safe
2236 Controls what happens when the shared repository uses the share-safe
2192 mechanism but its source does not.
2237 mechanism but its source does not.
2193
2238
2194 Possible values are `abort` (default), `allow`, `downgrade-abort` and
2239 Possible values are `abort` (default), `allow`, `downgrade-abort` and
2195 `downgrade-allow`.
2240 `downgrade-allow`.
2196
2241
2197 ``abort``
2242 ``abort``
2198 Disallows running any command and aborts
2243 Disallows running any command and aborts
2199 ``allow``
2244 ``allow``
2200 Respects the feature presence in the share source
2245 Respects the feature presence in the share source
2201 ``downgrade-abort``
2246 ``downgrade-abort``
2202 tries to downgrade the share to not use share-safe; if it fails, aborts
2247 Tries to downgrade the share to not use share-safe; if it fails, aborts
2203 ``downgrade-allow``
2248 ``downgrade-allow``
2204 tries to downgrade the share to not use share-safe;
2249 Tries to downgrade the share to not use share-safe;
2205 if it fails, continue by respecting the shared source setting
2250 if it fails, continue by respecting the shared source setting
2206
2251
2207 Check :hg:`help config.format.use-share-safe` for details about the
2252 Check :hg:`help config.format.use-share-safe` for details about the
2208 share-safe feature.
2253 share-safe feature.
2209
2254
2210 ``safe-mismatch.source-not-safe:verbose-upgrade``
2255 ``safe-mismatch.source-not-safe:verbose-upgrade``
2211 Display a message when upgrading, (default: True)
2256 Display a message when upgrading, (default: True)
2212
2257
2213 ``safe-mismatch.source-not-safe.warn``
2258 ``safe-mismatch.source-not-safe.warn``
2214 Shows a warning on operations if the shared repository uses share-safe,
2259 Shows a warning on operations if the shared repository uses share-safe,
2215 but the source repository does not.
2260 but the source repository does not.
2216 (default: True)
2261 (default: True)
2217
2262
2218 ``storage``
2263 ``storage``
2219 -----------
2264 -----------
2220
2265
2221 Control the strategy Mercurial uses internally to store history. Options in this
2266 Control the strategy Mercurial uses internally to store history. Options in this
2222 category impact performance and repository size.
2267 category impact performance and repository size.
2223
2268
2224 ``revlog.issue6528.fix-incoming``
2269 ``revlog.issue6528.fix-incoming``
2225 Version 5.8 of Mercurial had a bug leading to altering the parent of file
2270 Version 5.8 of Mercurial had a bug leading to altering the parent of file
2226 revision with copy information (or any other metadata) on exchange. This
2271 revision with copy information (or any other metadata) on exchange. This
2227 leads to the copy metadata to be overlooked by various internal logic. The
2272 leads to the copy metadata to be overlooked by various internal logic. The
2228 issue was fixed in Mercurial 5.8.1.
2273 issue was fixed in Mercurial 5.8.1.
2229 (See https://bz.mercurial-scm.org/show_bug.cgi?id=6528 for details)
2274 (See https://bz.mercurial-scm.org/show_bug.cgi?id=6528 for details)
2230
2275
2231 As a result Mercurial is now checking and fixing incoming file revisions to
2276 As a result Mercurial is now checking and fixing incoming file revisions to
2232 make sure there parents are in the right order. This behavior can be
2277 make sure there parents are in the right order. This behavior can be
2233 disabled by setting this option to `no`. This apply to revisions added
2278 disabled by setting this option to `no`. This apply to revisions added
2234 through push, pull, clone and unbundle.
2279 through push, pull, clone and unbundle.
2235
2280
2236 To fix affected revisions that already exist within the repository, one can
2281 To fix affected revisions that already exist within the repository, one can
2237 use :hg:`debug-repair-issue-6528`.
2282 use :hg:`debug-repair-issue-6528`.
2238
2283
2239 ``revlog.optimize-delta-parent-choice``
2284 ``revlog.optimize-delta-parent-choice``
2240 When storing a merge revision, both parents will be equally considered as
2285 When storing a merge revision, both parents will be equally considered as
2241 a possible delta base. This results in better delta selection and improved
2286 a possible delta base. This results in better delta selection and improved
2242 revlog compression. This option is enabled by default.
2287 revlog compression. This option is enabled by default.
2243
2288
2244 Turning this option off can result in large increase of repository size for
2289 Turning this option off can result in large increase of repository size for
2245 repository with many merges.
2290 repository with many merges.
2246
2291
2247 ``revlog.persistent-nodemap.mmap``
2292 ``revlog.persistent-nodemap.mmap``
2248 Whether to use the Operating System "memory mapping" feature (when
2293 Whether to use the Operating System "memory mapping" feature (when
2249 possible) to access the persistent nodemap data. This improve performance
2294 possible) to access the persistent nodemap data. This improve performance
2250 and reduce memory pressure.
2295 and reduce memory pressure.
2251
2296
2252 Default to True.
2297 Default to True.
2253
2298
2254 For details on the "persistent-nodemap" feature, see:
2299 For details on the "persistent-nodemap" feature, see:
2255 :hg:`help config.format.use-persistent-nodemap`.
2300 :hg:`help config.format.use-persistent-nodemap`.
2256
2301
2257 ``revlog.persistent-nodemap.slow-path``
2302 ``revlog.persistent-nodemap.slow-path``
2258 Control the behavior of Merucrial when using a repository with "persistent"
2303 Control the behavior of Merucrial when using a repository with "persistent"
2259 nodemap with an installation of Mercurial without a fast implementation for
2304 nodemap with an installation of Mercurial without a fast implementation for
2260 the feature:
2305 the feature:
2261
2306
2262 ``allow``: Silently use the slower implementation to access the repository.
2307 ``allow``: Silently use the slower implementation to access the repository.
2263 ``warn``: Warn, but use the slower implementation to access the repository.
2308 ``warn``: Warn, but use the slower implementation to access the repository.
2264 ``abort``: Prevent access to such repositories. (This is the default)
2309 ``abort``: Prevent access to such repositories. (This is the default)
2265
2310
2266 For details on the "persistent-nodemap" feature, see:
2311 For details on the "persistent-nodemap" feature, see:
2267 :hg:`help config.format.use-persistent-nodemap`.
2312 :hg:`help config.format.use-persistent-nodemap`.
2268
2313
2269 ``revlog.reuse-external-delta-parent``
2314 ``revlog.reuse-external-delta-parent``
2270 Control the order in which delta parents are considered when adding new
2315 Control the order in which delta parents are considered when adding new
2271 revisions from an external source.
2316 revisions from an external source.
2272 (typically: apply bundle from `hg pull` or `hg push`).
2317 (typically: apply bundle from `hg pull` or `hg push`).
2273
2318
2274 New revisions are usually provided as a delta against other revisions. By
2319 New revisions are usually provided as a delta against other revisions. By
2275 default, Mercurial will try to reuse this delta first, therefore using the
2320 default, Mercurial will try to reuse this delta first, therefore using the
2276 same "delta parent" as the source. Directly using delta's from the source
2321 same "delta parent" as the source. Directly using delta's from the source
2277 reduces CPU usage and usually speeds up operation. However, in some case,
2322 reduces CPU usage and usually speeds up operation. However, in some case,
2278 the source might have sub-optimal delta bases and forcing their reevaluation
2323 the source might have sub-optimal delta bases and forcing their reevaluation
2279 is useful. For example, pushes from an old client could have sub-optimal
2324 is useful. For example, pushes from an old client could have sub-optimal
2280 delta's parent that the server want to optimize. (lack of general delta, bad
2325 delta's parent that the server want to optimize. (lack of general delta, bad
2281 parents, choice, lack of sparse-revlog, etc).
2326 parents, choice, lack of sparse-revlog, etc).
2282
2327
2283 This option is enabled by default. Turning it off will ensure bad delta
2328 This option is enabled by default. Turning it off will ensure bad delta
2284 parent choices from older client do not propagate to this repository, at
2329 parent choices from older client do not propagate to this repository, at
2285 the cost of a small increase in CPU consumption.
2330 the cost of a small increase in CPU consumption.
2286
2331
2287 Note: this option only control the order in which delta parents are
2332 Note: this option only control the order in which delta parents are
2288 considered. Even when disabled, the existing delta from the source will be
2333 considered. Even when disabled, the existing delta from the source will be
2289 reused if the same delta parent is selected.
2334 reused if the same delta parent is selected.
2290
2335
2291 ``revlog.reuse-external-delta``
2336 ``revlog.reuse-external-delta``
2292 Control the reuse of delta from external source.
2337 Control the reuse of delta from external source.
2293 (typically: apply bundle from `hg pull` or `hg push`).
2338 (typically: apply bundle from `hg pull` or `hg push`).
2294
2339
2295 New revisions are usually provided as a delta against another revision. By
2340 New revisions are usually provided as a delta against another revision. By
2296 default, Mercurial will not recompute the same delta again, trusting
2341 default, Mercurial will not recompute the same delta again, trusting
2297 externally provided deltas. There have been rare cases of small adjustment
2342 externally provided deltas. There have been rare cases of small adjustment
2298 to the diffing algorithm in the past. So in some rare case, recomputing
2343 to the diffing algorithm in the past. So in some rare case, recomputing
2299 delta provided by ancient clients can provides better results. Disabling
2344 delta provided by ancient clients can provides better results. Disabling
2300 this option means going through a full delta recomputation for all incoming
2345 this option means going through a full delta recomputation for all incoming
2301 revisions. It means a large increase in CPU usage and will slow operations
2346 revisions. It means a large increase in CPU usage and will slow operations
2302 down.
2347 down.
2303
2348
2304 This option is enabled by default. When disabled, it also disables the
2349 This option is enabled by default. When disabled, it also disables the
2305 related ``storage.revlog.reuse-external-delta-parent`` option.
2350 related ``storage.revlog.reuse-external-delta-parent`` option.
2306
2351
2307 ``revlog.zlib.level``
2352 ``revlog.zlib.level``
2308 Zlib compression level used when storing data into the repository. Accepted
2353 Zlib compression level used when storing data into the repository. Accepted
2309 Value range from 1 (lowest compression) to 9 (highest compression). Zlib
2354 Value range from 1 (lowest compression) to 9 (highest compression). Zlib
2310 default value is 6.
2355 default value is 6.
2311
2356
2312
2357
2313 ``revlog.zstd.level``
2358 ``revlog.zstd.level``
2314 zstd compression level used when storing data into the repository. Accepted
2359 zstd compression level used when storing data into the repository. Accepted
2315 Value range from 1 (lowest compression) to 22 (highest compression).
2360 Value range from 1 (lowest compression) to 22 (highest compression).
2316 (default 3)
2361 (default 3)
2317
2362
2318 ``server``
2363 ``server``
2319 ----------
2364 ----------
2320
2365
2321 Controls generic server settings.
2366 Controls generic server settings.
2322
2367
2323 ``bookmarks-pushkey-compat``
2368 ``bookmarks-pushkey-compat``
2324 Trigger pushkey hook when being pushed bookmark updates. This config exist
2369 Trigger pushkey hook when being pushed bookmark updates. This config exist
2325 for compatibility purpose (default to True)
2370 for compatibility purpose (default to True)
2326
2371
2327 If you use ``pushkey`` and ``pre-pushkey`` hooks to control bookmark
2372 If you use ``pushkey`` and ``pre-pushkey`` hooks to control bookmark
2328 movement we recommend you migrate them to ``txnclose-bookmark`` and
2373 movement we recommend you migrate them to ``txnclose-bookmark`` and
2329 ``pretxnclose-bookmark``.
2374 ``pretxnclose-bookmark``.
2330
2375
2331 ``compressionengines``
2376 ``compressionengines``
2332 List of compression engines and their relative priority to advertise
2377 List of compression engines and their relative priority to advertise
2333 to clients.
2378 to clients.
2334
2379
2335 The order of compression engines determines their priority, the first
2380 The order of compression engines determines their priority, the first
2336 having the highest priority. If a compression engine is not listed
2381 having the highest priority. If a compression engine is not listed
2337 here, it won't be advertised to clients.
2382 here, it won't be advertised to clients.
2338
2383
2339 If not set (the default), built-in defaults are used. Run
2384 If not set (the default), built-in defaults are used. Run
2340 :hg:`debuginstall` to list available compression engines and their
2385 :hg:`debuginstall` to list available compression engines and their
2341 default wire protocol priority.
2386 default wire protocol priority.
2342
2387
2343 Older Mercurial clients only support zlib compression and this setting
2388 Older Mercurial clients only support zlib compression and this setting
2344 has no effect for legacy clients.
2389 has no effect for legacy clients.
2345
2390
2346 ``uncompressed``
2391 ``uncompressed``
2347 Whether to allow clients to clone a repository using the
2392 Whether to allow clients to clone a repository using the
2348 uncompressed streaming protocol. This transfers about 40% more
2393 uncompressed streaming protocol. This transfers about 40% more
2349 data than a regular clone, but uses less memory and CPU on both
2394 data than a regular clone, but uses less memory and CPU on both
2350 server and client. Over a LAN (100 Mbps or better) or a very fast
2395 server and client. Over a LAN (100 Mbps or better) or a very fast
2351 WAN, an uncompressed streaming clone is a lot faster (~10x) than a
2396 WAN, an uncompressed streaming clone is a lot faster (~10x) than a
2352 regular clone. Over most WAN connections (anything slower than
2397 regular clone. Over most WAN connections (anything slower than
2353 about 6 Mbps), uncompressed streaming is slower, because of the
2398 about 6 Mbps), uncompressed streaming is slower, because of the
2354 extra data transfer overhead. This mode will also temporarily hold
2399 extra data transfer overhead. This mode will also temporarily hold
2355 the write lock while determining what data to transfer.
2400 the write lock while determining what data to transfer.
2356 (default: True)
2401 (default: True)
2357
2402
2358 ``uncompressedallowsecret``
2403 ``uncompressedallowsecret``
2359 Whether to allow stream clones when the repository contains secret
2404 Whether to allow stream clones when the repository contains secret
2360 changesets. (default: False)
2405 changesets. (default: False)
2361
2406
2362 ``preferuncompressed``
2407 ``preferuncompressed``
2363 When set, clients will try to use the uncompressed streaming
2408 When set, clients will try to use the uncompressed streaming
2364 protocol. (default: False)
2409 protocol. (default: False)
2365
2410
2366 ``disablefullbundle``
2411 ``disablefullbundle``
2367 When set, servers will refuse attempts to do pull-based clones.
2412 When set, servers will refuse attempts to do pull-based clones.
2368 If this option is set, ``preferuncompressed`` and/or clone bundles
2413 If this option is set, ``preferuncompressed`` and/or clone bundles
2369 are highly recommended. Partial clones will still be allowed.
2414 are highly recommended. Partial clones will still be allowed.
2370 (default: False)
2415 (default: False)
2371
2416
2372 ``streamunbundle``
2417 ``streamunbundle``
2373 When set, servers will apply data sent from the client directly,
2418 When set, servers will apply data sent from the client directly,
2374 otherwise it will be written to a temporary file first. This option
2419 otherwise it will be written to a temporary file first. This option
2375 effectively prevents concurrent pushes.
2420 effectively prevents concurrent pushes.
2376
2421
2377 ``pullbundle``
2422 ``pullbundle``
2378 When set, the server will check pullbundles.manifest for bundles
2423 When set, the server will check pullbundles.manifest for bundles
2379 covering the requested heads and common nodes. The first matching
2424 covering the requested heads and common nodes. The first matching
2380 entry will be streamed to the client.
2425 entry will be streamed to the client.
2381
2426
2382 For HTTP transport, the stream will still use zlib compression
2427 For HTTP transport, the stream will still use zlib compression
2383 for older clients.
2428 for older clients.
2384
2429
2385 ``concurrent-push-mode``
2430 ``concurrent-push-mode``
2386 Level of allowed race condition between two pushing clients.
2431 Level of allowed race condition between two pushing clients.
2387
2432
2388 - 'strict': push is abort if another client touched the repository
2433 - 'strict': push is abort if another client touched the repository
2389 while the push was preparing.
2434 while the push was preparing.
2390 - 'check-related': push is only aborted if it affects head that got also
2435 - 'check-related': push is only aborted if it affects head that got also
2391 affected while the push was preparing. (default since 5.4)
2436 affected while the push was preparing. (default since 5.4)
2392
2437
2393 'check-related' only takes effect for compatible clients (version
2438 'check-related' only takes effect for compatible clients (version
2394 4.3 and later). Older clients will use 'strict'.
2439 4.3 and later). Older clients will use 'strict'.
2395
2440
2396 ``validate``
2441 ``validate``
2397 Whether to validate the completeness of pushed changesets by
2442 Whether to validate the completeness of pushed changesets by
2398 checking that all new file revisions specified in manifests are
2443 checking that all new file revisions specified in manifests are
2399 present. (default: False)
2444 present. (default: False)
2400
2445
2401 ``maxhttpheaderlen``
2446 ``maxhttpheaderlen``
2402 Instruct HTTP clients not to send request headers longer than this
2447 Instruct HTTP clients not to send request headers longer than this
2403 many bytes. (default: 1024)
2448 many bytes. (default: 1024)
2404
2449
2405 ``bundle1``
2450 ``bundle1``
2406 Whether to allow clients to push and pull using the legacy bundle1
2451 Whether to allow clients to push and pull using the legacy bundle1
2407 exchange format. (default: True)
2452 exchange format. (default: True)
2408
2453
2409 ``bundle1gd``
2454 ``bundle1gd``
2410 Like ``bundle1`` but only used if the repository is using the
2455 Like ``bundle1`` but only used if the repository is using the
2411 *generaldelta* storage format. (default: True)
2456 *generaldelta* storage format. (default: True)
2412
2457
2413 ``bundle1.push``
2458 ``bundle1.push``
2414 Whether to allow clients to push using the legacy bundle1 exchange
2459 Whether to allow clients to push using the legacy bundle1 exchange
2415 format. (default: True)
2460 format. (default: True)
2416
2461
2417 ``bundle1gd.push``
2462 ``bundle1gd.push``
2418 Like ``bundle1.push`` but only used if the repository is using the
2463 Like ``bundle1.push`` but only used if the repository is using the
2419 *generaldelta* storage format. (default: True)
2464 *generaldelta* storage format. (default: True)
2420
2465
2421 ``bundle1.pull``
2466 ``bundle1.pull``
2422 Whether to allow clients to pull using the legacy bundle1 exchange
2467 Whether to allow clients to pull using the legacy bundle1 exchange
2423 format. (default: True)
2468 format. (default: True)
2424
2469
2425 ``bundle1gd.pull``
2470 ``bundle1gd.pull``
2426 Like ``bundle1.pull`` but only used if the repository is using the
2471 Like ``bundle1.pull`` but only used if the repository is using the
2427 *generaldelta* storage format. (default: True)
2472 *generaldelta* storage format. (default: True)
2428
2473
2429 Large repositories using the *generaldelta* storage format should
2474 Large repositories using the *generaldelta* storage format should
2430 consider setting this option because converting *generaldelta*
2475 consider setting this option because converting *generaldelta*
2431 repositories to the exchange format required by the bundle1 data
2476 repositories to the exchange format required by the bundle1 data
2432 format can consume a lot of CPU.
2477 format can consume a lot of CPU.
2433
2478
2434 ``bundle2.stream``
2479 ``bundle2.stream``
2435 Whether to allow clients to pull using the bundle2 streaming protocol.
2480 Whether to allow clients to pull using the bundle2 streaming protocol.
2436 (default: True)
2481 (default: True)
2437
2482
2438 ``zliblevel``
2483 ``zliblevel``
2439 Integer between ``-1`` and ``9`` that controls the zlib compression level
2484 Integer between ``-1`` and ``9`` that controls the zlib compression level
2440 for wire protocol commands that send zlib compressed output (notably the
2485 for wire protocol commands that send zlib compressed output (notably the
2441 commands that send repository history data).
2486 commands that send repository history data).
2442
2487
2443 The default (``-1``) uses the default zlib compression level, which is
2488 The default (``-1``) uses the default zlib compression level, which is
2444 likely equivalent to ``6``. ``0`` means no compression. ``9`` means
2489 likely equivalent to ``6``. ``0`` means no compression. ``9`` means
2445 maximum compression.
2490 maximum compression.
2446
2491
2447 Setting this option allows server operators to make trade-offs between
2492 Setting this option allows server operators to make trade-offs between
2448 bandwidth and CPU used. Lowering the compression lowers CPU utilization
2493 bandwidth and CPU used. Lowering the compression lowers CPU utilization
2449 but sends more bytes to clients.
2494 but sends more bytes to clients.
2450
2495
2451 This option only impacts the HTTP server.
2496 This option only impacts the HTTP server.
2452
2497
2453 ``zstdlevel``
2498 ``zstdlevel``
2454 Integer between ``1`` and ``22`` that controls the zstd compression level
2499 Integer between ``1`` and ``22`` that controls the zstd compression level
2455 for wire protocol commands. ``1`` is the minimal amount of compression and
2500 for wire protocol commands. ``1`` is the minimal amount of compression and
2456 ``22`` is the highest amount of compression.
2501 ``22`` is the highest amount of compression.
2457
2502
2458 The default (``3``) should be significantly faster than zlib while likely
2503 The default (``3``) should be significantly faster than zlib while likely
2459 delivering better compression ratios.
2504 delivering better compression ratios.
2460
2505
2461 This option only impacts the HTTP server.
2506 This option only impacts the HTTP server.
2462
2507
2463 See also ``server.zliblevel``.
2508 See also ``server.zliblevel``.
2464
2509
2465 ``view``
2510 ``view``
2466 Repository filter used when exchanging revisions with the peer.
2511 Repository filter used when exchanging revisions with the peer.
2467
2512
2468 The default view (``served``) excludes secret and hidden changesets.
2513 The default view (``served``) excludes secret and hidden changesets.
2469 Another useful value is ``immutable`` (no draft, secret or hidden
2514 Another useful value is ``immutable`` (no draft, secret or hidden
2470 changesets). (EXPERIMENTAL)
2515 changesets). (EXPERIMENTAL)
2471
2516
2472 ``smtp``
2517 ``smtp``
2473 --------
2518 --------
2474
2519
2475 Configuration for extensions that need to send email messages.
2520 Configuration for extensions that need to send email messages.
2476
2521
2477 ``host``
2522 ``host``
2478 Host name of mail server, e.g. "mail.example.com".
2523 Host name of mail server, e.g. "mail.example.com".
2479
2524
2480 ``port``
2525 ``port``
2481 Optional. Port to connect to on mail server. (default: 465 if
2526 Optional. Port to connect to on mail server. (default: 465 if
2482 ``tls`` is smtps; 25 otherwise)
2527 ``tls`` is smtps; 25 otherwise)
2483
2528
2484 ``tls``
2529 ``tls``
2485 Optional. Method to enable TLS when connecting to mail server: starttls,
2530 Optional. Method to enable TLS when connecting to mail server: starttls,
2486 smtps or none. (default: none)
2531 smtps or none. (default: none)
2487
2532
2488 ``username``
2533 ``username``
2489 Optional. User name for authenticating with the SMTP server.
2534 Optional. User name for authenticating with the SMTP server.
2490 (default: None)
2535 (default: None)
2491
2536
2492 ``password``
2537 ``password``
2493 Optional. Password for authenticating with the SMTP server. If not
2538 Optional. Password for authenticating with the SMTP server. If not
2494 specified, interactive sessions will prompt the user for a
2539 specified, interactive sessions will prompt the user for a
2495 password; non-interactive sessions will fail. (default: None)
2540 password; non-interactive sessions will fail. (default: None)
2496
2541
2497 ``local_hostname``
2542 ``local_hostname``
2498 Optional. The hostname that the sender can use to identify
2543 Optional. The hostname that the sender can use to identify
2499 itself to the MTA.
2544 itself to the MTA.
2500
2545
2501
2546
2502 ``subpaths``
2547 ``subpaths``
2503 ------------
2548 ------------
2504
2549
2505 Subrepository source URLs can go stale if a remote server changes name
2550 Subrepository source URLs can go stale if a remote server changes name
2506 or becomes temporarily unavailable. This section lets you define
2551 or becomes temporarily unavailable. This section lets you define
2507 rewrite rules of the form::
2552 rewrite rules of the form::
2508
2553
2509 <pattern> = <replacement>
2554 <pattern> = <replacement>
2510
2555
2511 where ``pattern`` is a regular expression matching a subrepository
2556 where ``pattern`` is a regular expression matching a subrepository
2512 source URL and ``replacement`` is the replacement string used to
2557 source URL and ``replacement`` is the replacement string used to
2513 rewrite it. Groups can be matched in ``pattern`` and referenced in
2558 rewrite it. Groups can be matched in ``pattern`` and referenced in
2514 ``replacements``. For instance::
2559 ``replacements``. For instance::
2515
2560
2516 http://server/(.*)-hg/ = http://hg.server/\1/
2561 http://server/(.*)-hg/ = http://hg.server/\1/
2517
2562
2518 rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
2563 rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
2519
2564
2520 Relative subrepository paths are first made absolute, and the
2565 Relative subrepository paths are first made absolute, and the
2521 rewrite rules are then applied on the full (absolute) path. If ``pattern``
2566 rewrite rules are then applied on the full (absolute) path. If ``pattern``
2522 doesn't match the full path, an attempt is made to apply it on the
2567 doesn't match the full path, an attempt is made to apply it on the
2523 relative path alone. The rules are applied in definition order.
2568 relative path alone. The rules are applied in definition order.
2524
2569
2525 ``subrepos``
2570 ``subrepos``
2526 ------------
2571 ------------
2527
2572
2528 This section contains options that control the behavior of the
2573 This section contains options that control the behavior of the
2529 subrepositories feature. See also :hg:`help subrepos`.
2574 subrepositories feature. See also :hg:`help subrepos`.
2530
2575
2531 Security note: auditing in Mercurial is known to be insufficient to
2576 Security note: auditing in Mercurial is known to be insufficient to
2532 prevent clone-time code execution with carefully constructed Git
2577 prevent clone-time code execution with carefully constructed Git
2533 subrepos. It is unknown if a similar detect is present in Subversion
2578 subrepos. It is unknown if a similar detect is present in Subversion
2534 subrepos. Both Git and Subversion subrepos are disabled by default
2579 subrepos. Both Git and Subversion subrepos are disabled by default
2535 out of security concerns. These subrepo types can be enabled using
2580 out of security concerns. These subrepo types can be enabled using
2536 the respective options below.
2581 the respective options below.
2537
2582
2538 ``allowed``
2583 ``allowed``
2539 Whether subrepositories are allowed in the working directory.
2584 Whether subrepositories are allowed in the working directory.
2540
2585
2541 When false, commands involving subrepositories (like :hg:`update`)
2586 When false, commands involving subrepositories (like :hg:`update`)
2542 will fail for all subrepository types.
2587 will fail for all subrepository types.
2543 (default: true)
2588 (default: true)
2544
2589
2545 ``hg:allowed``
2590 ``hg:allowed``
2546 Whether Mercurial subrepositories are allowed in the working
2591 Whether Mercurial subrepositories are allowed in the working
2547 directory. This option only has an effect if ``subrepos.allowed``
2592 directory. This option only has an effect if ``subrepos.allowed``
2548 is true.
2593 is true.
2549 (default: true)
2594 (default: true)
2550
2595
2551 ``git:allowed``
2596 ``git:allowed``
2552 Whether Git subrepositories are allowed in the working directory.
2597 Whether Git subrepositories are allowed in the working directory.
2553 This option only has an effect if ``subrepos.allowed`` is true.
2598 This option only has an effect if ``subrepos.allowed`` is true.
2554
2599
2555 See the security note above before enabling Git subrepos.
2600 See the security note above before enabling Git subrepos.
2556 (default: false)
2601 (default: false)
2557
2602
2558 ``svn:allowed``
2603 ``svn:allowed``
2559 Whether Subversion subrepositories are allowed in the working
2604 Whether Subversion subrepositories are allowed in the working
2560 directory. This option only has an effect if ``subrepos.allowed``
2605 directory. This option only has an effect if ``subrepos.allowed``
2561 is true.
2606 is true.
2562
2607
2563 See the security note above before enabling Subversion subrepos.
2608 See the security note above before enabling Subversion subrepos.
2564 (default: false)
2609 (default: false)
2565
2610
2566 ``templatealias``
2611 ``templatealias``
2567 -----------------
2612 -----------------
2568
2613
2569 Alias definitions for templates. See :hg:`help templates` for details.
2614 Alias definitions for templates. See :hg:`help templates` for details.
2570
2615
2571 ``templates``
2616 ``templates``
2572 -------------
2617 -------------
2573
2618
2574 Use the ``[templates]`` section to define template strings.
2619 Use the ``[templates]`` section to define template strings.
2575 See :hg:`help templates` for details.
2620 See :hg:`help templates` for details.
2576
2621
2577 ``trusted``
2622 ``trusted``
2578 -----------
2623 -----------
2579
2624
2580 Mercurial will not use the settings in the
2625 Mercurial will not use the settings in the
2581 ``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
2626 ``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
2582 user or to a trusted group, as various hgrc features allow arbitrary
2627 user or to a trusted group, as various hgrc features allow arbitrary
2583 commands to be run. This issue is often encountered when configuring
2628 commands to be run. This issue is often encountered when configuring
2584 hooks or extensions for shared repositories or servers. However,
2629 hooks or extensions for shared repositories or servers. However,
2585 the web interface will use some safe settings from the ``[web]``
2630 the web interface will use some safe settings from the ``[web]``
2586 section.
2631 section.
2587
2632
2588 This section specifies what users and groups are trusted. The
2633 This section specifies what users and groups are trusted. The
2589 current user is always trusted. To trust everybody, list a user or a
2634 current user is always trusted. To trust everybody, list a user or a
2590 group with name ``*``. These settings must be placed in an
2635 group with name ``*``. These settings must be placed in an
2591 *already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
2636 *already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
2592 user or service running Mercurial.
2637 user or service running Mercurial.
2593
2638
2594 ``users``
2639 ``users``
2595 Comma-separated list of trusted users.
2640 Comma-separated list of trusted users.
2596
2641
2597 ``groups``
2642 ``groups``
2598 Comma-separated list of trusted groups.
2643 Comma-separated list of trusted groups.
2599
2644
2600
2645
2601 ``ui``
2646 ``ui``
2602 ------
2647 ------
2603
2648
2604 User interface controls.
2649 User interface controls.
2605
2650
2606 ``archivemeta``
2651 ``archivemeta``
2607 Whether to include the .hg_archival.txt file containing meta data
2652 Whether to include the .hg_archival.txt file containing meta data
2608 (hashes for the repository base and for tip) in archives created
2653 (hashes for the repository base and for tip) in archives created
2609 by the :hg:`archive` command or downloaded via hgweb.
2654 by the :hg:`archive` command or downloaded via hgweb.
2610 (default: True)
2655 (default: True)
2611
2656
2612 ``askusername``
2657 ``askusername``
2613 Whether to prompt for a username when committing. If True, and
2658 Whether to prompt for a username when committing. If True, and
2614 neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
2659 neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
2615 be prompted to enter a username. If no username is entered, the
2660 be prompted to enter a username. If no username is entered, the
2616 default ``USER@HOST`` is used instead.
2661 default ``USER@HOST`` is used instead.
2617 (default: False)
2662 (default: False)
2618
2663
2619 ``clonebundles``
2664 ``clonebundles``
2620 Whether the "clone bundles" feature is enabled.
2665 Whether the "clone bundles" feature is enabled.
2621
2666
2622 When enabled, :hg:`clone` may download and apply a server-advertised
2667 When enabled, :hg:`clone` may download and apply a server-advertised
2623 bundle file from a URL instead of using the normal exchange mechanism.
2668 bundle file from a URL instead of using the normal exchange mechanism.
2624
2669
2625 This can likely result in faster and more reliable clones.
2670 This can likely result in faster and more reliable clones.
2626
2671
2627 (default: True)
2672 (default: True)
2628
2673
2629 ``clonebundlefallback``
2674 ``clonebundlefallback``
2630 Whether failure to apply an advertised "clone bundle" from a server
2675 Whether failure to apply an advertised "clone bundle" from a server
2631 should result in fallback to a regular clone.
2676 should result in fallback to a regular clone.
2632
2677
2633 This is disabled by default because servers advertising "clone
2678 This is disabled by default because servers advertising "clone
2634 bundles" often do so to reduce server load. If advertised bundles
2679 bundles" often do so to reduce server load. If advertised bundles
2635 start mass failing and clients automatically fall back to a regular
2680 start mass failing and clients automatically fall back to a regular
2636 clone, this would add significant and unexpected load to the server
2681 clone, this would add significant and unexpected load to the server
2637 since the server is expecting clone operations to be offloaded to
2682 since the server is expecting clone operations to be offloaded to
2638 pre-generated bundles. Failing fast (the default behavior) ensures
2683 pre-generated bundles. Failing fast (the default behavior) ensures
2639 clients don't overwhelm the server when "clone bundle" application
2684 clients don't overwhelm the server when "clone bundle" application
2640 fails.
2685 fails.
2641
2686
2642 (default: False)
2687 (default: False)
2643
2688
2644 ``clonebundleprefers``
2689 ``clonebundleprefers``
2645 Defines preferences for which "clone bundles" to use.
2690 Defines preferences for which "clone bundles" to use.
2646
2691
2647 Servers advertising "clone bundles" may advertise multiple available
2692 Servers advertising "clone bundles" may advertise multiple available
2648 bundles. Each bundle may have different attributes, such as the bundle
2693 bundles. Each bundle may have different attributes, such as the bundle
2649 type and compression format. This option is used to prefer a particular
2694 type and compression format. This option is used to prefer a particular
2650 bundle over another.
2695 bundle over another.
2651
2696
2652 The following keys are defined by Mercurial:
2697 The following keys are defined by Mercurial:
2653
2698
2654 BUNDLESPEC
2699 BUNDLESPEC
2655 A bundle type specifier. These are strings passed to :hg:`bundle -t`.
2700 A bundle type specifier. These are strings passed to :hg:`bundle -t`.
2656 e.g. ``gzip-v2`` or ``bzip2-v1``.
2701 e.g. ``gzip-v2`` or ``bzip2-v1``.
2657
2702
2658 COMPRESSION
2703 COMPRESSION
2659 The compression format of the bundle. e.g. ``gzip`` and ``bzip2``.
2704 The compression format of the bundle. e.g. ``gzip`` and ``bzip2``.
2660
2705
2661 Server operators may define custom keys.
2706 Server operators may define custom keys.
2662
2707
2663 Example values: ``COMPRESSION=bzip2``,
2708 Example values: ``COMPRESSION=bzip2``,
2664 ``BUNDLESPEC=gzip-v2, COMPRESSION=gzip``.
2709 ``BUNDLESPEC=gzip-v2, COMPRESSION=gzip``.
2665
2710
2666 By default, the first bundle advertised by the server is used.
2711 By default, the first bundle advertised by the server is used.
2667
2712
2668 ``color``
2713 ``color``
2669 When to colorize output. Possible value are Boolean ("yes" or "no"), or
2714 When to colorize output. Possible value are Boolean ("yes" or "no"), or
2670 "debug", or "always". (default: "yes"). "yes" will use color whenever it
2715 "debug", or "always". (default: "yes"). "yes" will use color whenever it
2671 seems possible. See :hg:`help color` for details.
2716 seems possible. See :hg:`help color` for details.
2672
2717
2673 ``commitsubrepos``
2718 ``commitsubrepos``
2674 Whether to commit modified subrepositories when committing the
2719 Whether to commit modified subrepositories when committing the
2675 parent repository. If False and one subrepository has uncommitted
2720 parent repository. If False and one subrepository has uncommitted
2676 changes, abort the commit.
2721 changes, abort the commit.
2677 (default: False)
2722 (default: False)
2678
2723
2679 ``debug``
2724 ``debug``
2680 Print debugging information. (default: False)
2725 Print debugging information. (default: False)
2681
2726
2682 ``editor``
2727 ``editor``
2683 The editor to use during a commit. (default: ``$EDITOR`` or ``vi``)
2728 The editor to use during a commit. (default: ``$EDITOR`` or ``vi``)
2684
2729
2685 ``fallbackencoding``
2730 ``fallbackencoding``
2686 Encoding to try if it's not possible to decode the changelog using
2731 Encoding to try if it's not possible to decode the changelog using
2687 UTF-8. (default: ISO-8859-1)
2732 UTF-8. (default: ISO-8859-1)
2688
2733
2689 ``graphnodetemplate``
2734 ``graphnodetemplate``
2690 (DEPRECATED) Use ``command-templates.graphnode`` instead.
2735 (DEPRECATED) Use ``command-templates.graphnode`` instead.
2691
2736
2692 ``ignore``
2737 ``ignore``
2693 A file to read per-user ignore patterns from. This file should be
2738 A file to read per-user ignore patterns from. This file should be
2694 in the same format as a repository-wide .hgignore file. Filenames
2739 in the same format as a repository-wide .hgignore file. Filenames
2695 are relative to the repository root. This option supports hook syntax,
2740 are relative to the repository root. This option supports hook syntax,
2696 so if you want to specify multiple ignore files, you can do so by
2741 so if you want to specify multiple ignore files, you can do so by
2697 setting something like ``ignore.other = ~/.hgignore2``. For details
2742 setting something like ``ignore.other = ~/.hgignore2``. For details
2698 of the ignore file format, see the ``hgignore(5)`` man page.
2743 of the ignore file format, see the ``hgignore(5)`` man page.
2699
2744
2700 ``interactive``
2745 ``interactive``
2701 Allow to prompt the user. (default: True)
2746 Allow to prompt the user. (default: True)
2702
2747
2703 ``interface``
2748 ``interface``
2704 Select the default interface for interactive features (default: text).
2749 Select the default interface for interactive features (default: text).
2705 Possible values are 'text' and 'curses'.
2750 Possible values are 'text' and 'curses'.
2706
2751
2707 ``interface.chunkselector``
2752 ``interface.chunkselector``
2708 Select the interface for change recording (e.g. :hg:`commit -i`).
2753 Select the interface for change recording (e.g. :hg:`commit -i`).
2709 Possible values are 'text' and 'curses'.
2754 Possible values are 'text' and 'curses'.
2710 This config overrides the interface specified by ui.interface.
2755 This config overrides the interface specified by ui.interface.
2711
2756
2712 ``large-file-limit``
2757 ``large-file-limit``
2713 Largest file size that gives no memory use warning.
2758 Largest file size that gives no memory use warning.
2714 Possible values are integers or 0 to disable the check.
2759 Possible values are integers or 0 to disable the check.
2715 Value is expressed in bytes by default, one can use standard units for
2760 Value is expressed in bytes by default, one can use standard units for
2716 convenience (e.g. 10MB, 0.1GB, etc) (default: 10MB)
2761 convenience (e.g. 10MB, 0.1GB, etc) (default: 10MB)
2717
2762
2718 ``logtemplate``
2763 ``logtemplate``
2719 (DEPRECATED) Use ``command-templates.log`` instead.
2764 (DEPRECATED) Use ``command-templates.log`` instead.
2720
2765
2721 ``merge``
2766 ``merge``
2722 The conflict resolution program to use during a manual merge.
2767 The conflict resolution program to use during a manual merge.
2723 For more information on merge tools see :hg:`help merge-tools`.
2768 For more information on merge tools see :hg:`help merge-tools`.
2724 For configuring merge tools see the ``[merge-tools]`` section.
2769 For configuring merge tools see the ``[merge-tools]`` section.
2725
2770
2726 ``mergemarkers``
2771 ``mergemarkers``
2727 Sets the merge conflict marker label styling. The ``detailed`` style
2772 Sets the merge conflict marker label styling. The ``detailed`` style
2728 uses the ``command-templates.mergemarker`` setting to style the labels.
2773 uses the ``command-templates.mergemarker`` setting to style the labels.
2729 The ``basic`` style just uses 'local' and 'other' as the marker label.
2774 The ``basic`` style just uses 'local' and 'other' as the marker label.
2730 One of ``basic`` or ``detailed``.
2775 One of ``basic`` or ``detailed``.
2731 (default: ``basic``)
2776 (default: ``basic``)
2732
2777
2733 ``mergemarkertemplate``
2778 ``mergemarkertemplate``
2734 (DEPRECATED) Use ``command-templates.mergemarker`` instead.
2779 (DEPRECATED) Use ``command-templates.mergemarker`` instead.
2735
2780
2736 ``message-output``
2781 ``message-output``
2737 Where to write status and error messages. (default: ``stdio``)
2782 Where to write status and error messages. (default: ``stdio``)
2738
2783
2739 ``channel``
2784 ``channel``
2740 Use separate channel for structured output. (Command-server only)
2785 Use separate channel for structured output. (Command-server only)
2741 ``stderr``
2786 ``stderr``
2742 Everything to stderr.
2787 Everything to stderr.
2743 ``stdio``
2788 ``stdio``
2744 Status to stdout, and error to stderr.
2789 Status to stdout, and error to stderr.
2745
2790
2746 ``origbackuppath``
2791 ``origbackuppath``
2747 The path to a directory used to store generated .orig files. If the path is
2792 The path to a directory used to store generated .orig files. If the path is
2748 not a directory, one will be created. If set, files stored in this
2793 not a directory, one will be created. If set, files stored in this
2749 directory have the same name as the original file and do not have a .orig
2794 directory have the same name as the original file and do not have a .orig
2750 suffix.
2795 suffix.
2751
2796
2752 ``paginate``
2797 ``paginate``
2753 Control the pagination of command output (default: True). See :hg:`help pager`
2798 Control the pagination of command output (default: True). See :hg:`help pager`
2754 for details.
2799 for details.
2755
2800
2756 ``patch``
2801 ``patch``
2757 An optional external tool that ``hg import`` and some extensions
2802 An optional external tool that ``hg import`` and some extensions
2758 will use for applying patches. By default Mercurial uses an
2803 will use for applying patches. By default Mercurial uses an
2759 internal patch utility. The external tool must work as the common
2804 internal patch utility. The external tool must work as the common
2760 Unix ``patch`` program. In particular, it must accept a ``-p``
2805 Unix ``patch`` program. In particular, it must accept a ``-p``
2761 argument to strip patch headers, a ``-d`` argument to specify the
2806 argument to strip patch headers, a ``-d`` argument to specify the
2762 current directory, a file name to patch, and a patch file to take
2807 current directory, a file name to patch, and a patch file to take
2763 from stdin.
2808 from stdin.
2764
2809
2765 It is possible to specify a patch tool together with extra
2810 It is possible to specify a patch tool together with extra
2766 arguments. For example, setting this option to ``patch --merge``
2811 arguments. For example, setting this option to ``patch --merge``
2767 will use the ``patch`` program with its 2-way merge option.
2812 will use the ``patch`` program with its 2-way merge option.
2768
2813
2769 ``portablefilenames``
2814 ``portablefilenames``
2770 Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.
2815 Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.
2771 (default: ``warn``)
2816 (default: ``warn``)
2772
2817
2773 ``warn``
2818 ``warn``
2774 Print a warning message on POSIX platforms, if a file with a non-portable
2819 Print a warning message on POSIX platforms, if a file with a non-portable
2775 filename is added (e.g. a file with a name that can't be created on
2820 filename is added (e.g. a file with a name that can't be created on
2776 Windows because it contains reserved parts like ``AUX``, reserved
2821 Windows because it contains reserved parts like ``AUX``, reserved
2777 characters like ``:``, or would cause a case collision with an existing
2822 characters like ``:``, or would cause a case collision with an existing
2778 file).
2823 file).
2779
2824
2780 ``ignore``
2825 ``ignore``
2781 Don't print a warning.
2826 Don't print a warning.
2782
2827
2783 ``abort``
2828 ``abort``
2784 The command is aborted.
2829 The command is aborted.
2785
2830
2786 ``true``
2831 ``true``
2787 Alias for ``warn``.
2832 Alias for ``warn``.
2788
2833
2789 ``false``
2834 ``false``
2790 Alias for ``ignore``.
2835 Alias for ``ignore``.
2791
2836
2792 .. container:: windows
2837 .. container:: windows
2793
2838
2794 On Windows, this configuration option is ignored and the command aborted.
2839 On Windows, this configuration option is ignored and the command aborted.
2795
2840
2796 ``pre-merge-tool-output-template``
2841 ``pre-merge-tool-output-template``
2797 (DEPRECATED) Use ``command-template.pre-merge-tool-output`` instead.
2842 (DEPRECATED) Use ``command-template.pre-merge-tool-output`` instead.
2798
2843
2799 ``quiet``
2844 ``quiet``
2800 Reduce the amount of output printed.
2845 Reduce the amount of output printed.
2801 (default: False)
2846 (default: False)
2802
2847
2803 ``relative-paths``
2848 ``relative-paths``
2804 Prefer relative paths in the UI.
2849 Prefer relative paths in the UI.
2805
2850
2806 ``remotecmd``
2851 ``remotecmd``
2807 Remote command to use for clone/push/pull operations.
2852 Remote command to use for clone/push/pull operations.
2808 (default: ``hg``)
2853 (default: ``hg``)
2809
2854
2810 ``report_untrusted``
2855 ``report_untrusted``
2811 Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
2856 Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
2812 trusted user or group.
2857 trusted user or group.
2813 (default: True)
2858 (default: True)
2814
2859
2815 ``slash``
2860 ``slash``
2816 (Deprecated. Use ``slashpath`` template filter instead.)
2861 (Deprecated. Use ``slashpath`` template filter instead.)
2817
2862
2818 Display paths using a slash (``/``) as the path separator. This
2863 Display paths using a slash (``/``) as the path separator. This
2819 only makes a difference on systems where the default path
2864 only makes a difference on systems where the default path
2820 separator is not the slash character (e.g. Windows uses the
2865 separator is not the slash character (e.g. Windows uses the
2821 backslash character (``\``)).
2866 backslash character (``\``)).
2822 (default: False)
2867 (default: False)
2823
2868
2824 ``statuscopies``
2869 ``statuscopies``
2825 Display copies in the status command.
2870 Display copies in the status command.
2826
2871
2827 ``ssh``
2872 ``ssh``
2828 Command to use for SSH connections. (default: ``ssh``)
2873 Command to use for SSH connections. (default: ``ssh``)
2829
2874
2830 ``ssherrorhint``
2875 ``ssherrorhint``
2831 A hint shown to the user in the case of SSH error (e.g.
2876 A hint shown to the user in the case of SSH error (e.g.
2832 ``Please see http://company/internalwiki/ssh.html``)
2877 ``Please see http://company/internalwiki/ssh.html``)
2833
2878
2834 ``strict``
2879 ``strict``
2835 Require exact command names, instead of allowing unambiguous
2880 Require exact command names, instead of allowing unambiguous
2836 abbreviations. (default: False)
2881 abbreviations. (default: False)
2837
2882
2838 ``style``
2883 ``style``
2839 Name of style to use for command output.
2884 Name of style to use for command output.
2840
2885
2841 ``supportcontact``
2886 ``supportcontact``
2842 A URL where users should report a Mercurial traceback. Use this if you are a
2887 A URL where users should report a Mercurial traceback. Use this if you are a
2843 large organisation with its own Mercurial deployment process and crash
2888 large organisation with its own Mercurial deployment process and crash
2844 reports should be addressed to your internal support.
2889 reports should be addressed to your internal support.
2845
2890
2846 ``textwidth``
2891 ``textwidth``
2847 Maximum width of help text. A longer line generated by ``hg help`` or
2892 Maximum width of help text. A longer line generated by ``hg help`` or
2848 ``hg subcommand --help`` will be broken after white space to get this
2893 ``hg subcommand --help`` will be broken after white space to get this
2849 width or the terminal width, whichever comes first.
2894 width or the terminal width, whichever comes first.
2850 A non-positive value will disable this and the terminal width will be
2895 A non-positive value will disable this and the terminal width will be
2851 used. (default: 78)
2896 used. (default: 78)
2852
2897
2853 ``timeout``
2898 ``timeout``
2854 The timeout used when a lock is held (in seconds), a negative value
2899 The timeout used when a lock is held (in seconds), a negative value
2855 means no timeout. (default: 600)
2900 means no timeout. (default: 600)
2856
2901
2857 ``timeout.warn``
2902 ``timeout.warn``
2858 Time (in seconds) before a warning is printed about held lock. A negative
2903 Time (in seconds) before a warning is printed about held lock. A negative
2859 value means no warning. (default: 0)
2904 value means no warning. (default: 0)
2860
2905
2861 ``traceback``
2906 ``traceback``
2862 Mercurial always prints a traceback when an unknown exception
2907 Mercurial always prints a traceback when an unknown exception
2863 occurs. Setting this to True will make Mercurial print a traceback
2908 occurs. Setting this to True will make Mercurial print a traceback
2864 on all exceptions, even those recognized by Mercurial (such as
2909 on all exceptions, even those recognized by Mercurial (such as
2865 IOError or MemoryError). (default: False)
2910 IOError or MemoryError). (default: False)
2866
2911
2867 ``tweakdefaults``
2912 ``tweakdefaults``
2868
2913
2869 By default Mercurial's behavior changes very little from release
2914 By default Mercurial's behavior changes very little from release
2870 to release, but over time the recommended config settings
2915 to release, but over time the recommended config settings
2871 shift. Enable this config to opt in to get automatic tweaks to
2916 shift. Enable this config to opt in to get automatic tweaks to
2872 Mercurial's behavior over time. This config setting will have no
2917 Mercurial's behavior over time. This config setting will have no
2873 effect if ``HGPLAIN`` is set or ``HGPLAINEXCEPT`` is set and does
2918 effect if ``HGPLAIN`` is set or ``HGPLAINEXCEPT`` is set and does
2874 not include ``tweakdefaults``. (default: False)
2919 not include ``tweakdefaults``. (default: False)
2875
2920
2876 It currently means::
2921 It currently means::
2877
2922
2878 .. tweakdefaultsmarker
2923 .. tweakdefaultsmarker
2879
2924
2880 ``username``
2925 ``username``
2881 The committer of a changeset created when running "commit".
2926 The committer of a changeset created when running "commit".
2882 Typically a person's name and email address, e.g. ``Fred Widget
2927 Typically a person's name and email address, e.g. ``Fred Widget
2883 <fred@example.com>``. Environment variables in the
2928 <fred@example.com>``. Environment variables in the
2884 username are expanded.
2929 username are expanded.
2885
2930
2886 (default: ``$EMAIL`` or ``username@hostname``. If the username in
2931 (default: ``$EMAIL`` or ``username@hostname``. If the username in
2887 hgrc is empty, e.g. if the system admin set ``username =`` in the
2932 hgrc is empty, e.g. if the system admin set ``username =`` in the
2888 system hgrc, it has to be specified manually or in a different
2933 system hgrc, it has to be specified manually or in a different
2889 hgrc file)
2934 hgrc file)
2890
2935
2891 ``verbose``
2936 ``verbose``
2892 Increase the amount of output printed. (default: False)
2937 Increase the amount of output printed. (default: False)
2893
2938
2894
2939
2895 ``command-templates``
2940 ``command-templates``
2896 ---------------------
2941 ---------------------
2897
2942
2898 Templates used for customizing the output of commands.
2943 Templates used for customizing the output of commands.
2899
2944
2900 ``graphnode``
2945 ``graphnode``
2901 The template used to print changeset nodes in an ASCII revision graph.
2946 The template used to print changeset nodes in an ASCII revision graph.
2902 (default: ``{graphnode}``)
2947 (default: ``{graphnode}``)
2903
2948
2904 ``log``
2949 ``log``
2905 Template string for commands that print changesets.
2950 Template string for commands that print changesets.
2906
2951
2907 ``mergemarker``
2952 ``mergemarker``
2908 The template used to print the commit description next to each conflict
2953 The template used to print the commit description next to each conflict
2909 marker during merge conflicts. See :hg:`help templates` for the template
2954 marker during merge conflicts. See :hg:`help templates` for the template
2910 format.
2955 format.
2911
2956
2912 Defaults to showing the hash, tags, branches, bookmarks, author, and
2957 Defaults to showing the hash, tags, branches, bookmarks, author, and
2913 the first line of the commit description.
2958 the first line of the commit description.
2914
2959
2915 If you use non-ASCII characters in names for tags, branches, bookmarks,
2960 If you use non-ASCII characters in names for tags, branches, bookmarks,
2916 authors, and/or commit descriptions, you must pay attention to encodings of
2961 authors, and/or commit descriptions, you must pay attention to encodings of
2917 managed files. At template expansion, non-ASCII characters use the encoding
2962 managed files. At template expansion, non-ASCII characters use the encoding
2918 specified by the ``--encoding`` global option, ``HGENCODING`` or other
2963 specified by the ``--encoding`` global option, ``HGENCODING`` or other
2919 environment variables that govern your locale. If the encoding of the merge
2964 environment variables that govern your locale. If the encoding of the merge
2920 markers is different from the encoding of the merged files,
2965 markers is different from the encoding of the merged files,
2921 serious problems may occur.
2966 serious problems may occur.
2922
2967
2923 Can be overridden per-merge-tool, see the ``[merge-tools]`` section.
2968 Can be overridden per-merge-tool, see the ``[merge-tools]`` section.
2924
2969
2925 ``oneline-summary``
2970 ``oneline-summary``
2926 A template used by `hg rebase` and other commands for showing a one-line
2971 A template used by `hg rebase` and other commands for showing a one-line
2927 summary of a commit. If the template configured here is longer than one
2972 summary of a commit. If the template configured here is longer than one
2928 line, then only the first line is used.
2973 line, then only the first line is used.
2929
2974
2930 The template can be overridden per command by defining a template in
2975 The template can be overridden per command by defining a template in
2931 `oneline-summary.<command>`, where `<command>` can be e.g. "rebase".
2976 `oneline-summary.<command>`, where `<command>` can be e.g. "rebase".
2932
2977
2933 ``pre-merge-tool-output``
2978 ``pre-merge-tool-output``
2934 A template that is printed before executing an external merge tool. This can
2979 A template that is printed before executing an external merge tool. This can
2935 be used to print out additional context that might be useful to have during
2980 be used to print out additional context that might be useful to have during
2936 the conflict resolution, such as the description of the various commits
2981 the conflict resolution, such as the description of the various commits
2937 involved or bookmarks/tags.
2982 involved or bookmarks/tags.
2938
2983
2939 Additional information is available in the ``local`, ``base``, and ``other``
2984 Additional information is available in the ``local`, ``base``, and ``other``
2940 dicts. For example: ``{local.label}``, ``{base.name}``, or
2985 dicts. For example: ``{local.label}``, ``{base.name}``, or
2941 ``{other.islink}``.
2986 ``{other.islink}``.
2942
2987
2943
2988
2944 ``web``
2989 ``web``
2945 -------
2990 -------
2946
2991
2947 Web interface configuration. The settings in this section apply to
2992 Web interface configuration. The settings in this section apply to
2948 both the builtin webserver (started by :hg:`serve`) and the script you
2993 both the builtin webserver (started by :hg:`serve`) and the script you
2949 run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
2994 run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
2950 and WSGI).
2995 and WSGI).
2951
2996
2952 The Mercurial webserver does no authentication (it does not prompt for
2997 The Mercurial webserver does no authentication (it does not prompt for
2953 usernames and passwords to validate *who* users are), but it does do
2998 usernames and passwords to validate *who* users are), but it does do
2954 authorization (it grants or denies access for *authenticated users*
2999 authorization (it grants or denies access for *authenticated users*
2955 based on settings in this section). You must either configure your
3000 based on settings in this section). You must either configure your
2956 webserver to do authentication for you, or disable the authorization
3001 webserver to do authentication for you, or disable the authorization
2957 checks.
3002 checks.
2958
3003
2959 For a quick setup in a trusted environment, e.g., a private LAN, where
3004 For a quick setup in a trusted environment, e.g., a private LAN, where
2960 you want it to accept pushes from anybody, you can use the following
3005 you want it to accept pushes from anybody, you can use the following
2961 command line::
3006 command line::
2962
3007
2963 $ hg --config web.allow-push=* --config web.push_ssl=False serve
3008 $ hg --config web.allow-push=* --config web.push_ssl=False serve
2964
3009
2965 Note that this will allow anybody to push anything to the server and
3010 Note that this will allow anybody to push anything to the server and
2966 that this should not be used for public servers.
3011 that this should not be used for public servers.
2967
3012
2968 The full set of options is:
3013 The full set of options is:
2969
3014
2970 ``accesslog``
3015 ``accesslog``
2971 Where to output the access log. (default: stdout)
3016 Where to output the access log. (default: stdout)
2972
3017
2973 ``address``
3018 ``address``
2974 Interface address to bind to. (default: all)
3019 Interface address to bind to. (default: all)
2975
3020
2976 ``allow-archive``
3021 ``allow-archive``
2977 List of archive format (bz2, gz, zip) allowed for downloading.
3022 List of archive format (bz2, gz, zip) allowed for downloading.
2978 (default: empty)
3023 (default: empty)
2979
3024
2980 ``allowbz2``
3025 ``allowbz2``
2981 (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
3026 (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
2982 revisions.
3027 revisions.
2983 (default: False)
3028 (default: False)
2984
3029
2985 ``allowgz``
3030 ``allowgz``
2986 (DEPRECATED) Whether to allow .tar.gz downloading of repository
3031 (DEPRECATED) Whether to allow .tar.gz downloading of repository
2987 revisions.
3032 revisions.
2988 (default: False)
3033 (default: False)
2989
3034
2990 ``allow-pull``
3035 ``allow-pull``
2991 Whether to allow pulling from the repository. (default: True)
3036 Whether to allow pulling from the repository. (default: True)
2992
3037
2993 ``allow-push``
3038 ``allow-push``
2994 Whether to allow pushing to the repository. If empty or not set,
3039 Whether to allow pushing to the repository. If empty or not set,
2995 pushing is not allowed. If the special value ``*``, any remote
3040 pushing is not allowed. If the special value ``*``, any remote
2996 user can push, including unauthenticated users. Otherwise, the
3041 user can push, including unauthenticated users. Otherwise, the
2997 remote user must have been authenticated, and the authenticated
3042 remote user must have been authenticated, and the authenticated
2998 user name must be present in this list. The contents of the
3043 user name must be present in this list. The contents of the
2999 allow-push list are examined after the deny_push list.
3044 allow-push list are examined after the deny_push list.
3000
3045
3001 ``allow_read``
3046 ``allow_read``
3002 If the user has not already been denied repository access due to
3047 If the user has not already been denied repository access due to
3003 the contents of deny_read, this list determines whether to grant
3048 the contents of deny_read, this list determines whether to grant
3004 repository access to the user. If this list is not empty, and the
3049 repository access to the user. If this list is not empty, and the
3005 user is unauthenticated or not present in the list, then access is
3050 user is unauthenticated or not present in the list, then access is
3006 denied for the user. If the list is empty or not set, then access
3051 denied for the user. If the list is empty or not set, then access
3007 is permitted to all users by default. Setting allow_read to the
3052 is permitted to all users by default. Setting allow_read to the
3008 special value ``*`` is equivalent to it not being set (i.e. access
3053 special value ``*`` is equivalent to it not being set (i.e. access
3009 is permitted to all users). The contents of the allow_read list are
3054 is permitted to all users). The contents of the allow_read list are
3010 examined after the deny_read list.
3055 examined after the deny_read list.
3011
3056
3012 ``allowzip``
3057 ``allowzip``
3013 (DEPRECATED) Whether to allow .zip downloading of repository
3058 (DEPRECATED) Whether to allow .zip downloading of repository
3014 revisions. This feature creates temporary files.
3059 revisions. This feature creates temporary files.
3015 (default: False)
3060 (default: False)
3016
3061
3017 ``archivesubrepos``
3062 ``archivesubrepos``
3018 Whether to recurse into subrepositories when archiving.
3063 Whether to recurse into subrepositories when archiving.
3019 (default: False)
3064 (default: False)
3020
3065
3021 ``baseurl``
3066 ``baseurl``
3022 Base URL to use when publishing URLs in other locations, so
3067 Base URL to use when publishing URLs in other locations, so
3023 third-party tools like email notification hooks can construct
3068 third-party tools like email notification hooks can construct
3024 URLs. Example: ``http://hgserver/repos/``.
3069 URLs. Example: ``http://hgserver/repos/``.
3025
3070
3026 ``cacerts``
3071 ``cacerts``
3027 Path to file containing a list of PEM encoded certificate
3072 Path to file containing a list of PEM encoded certificate
3028 authority certificates. Environment variables and ``~user``
3073 authority certificates. Environment variables and ``~user``
3029 constructs are expanded in the filename. If specified on the
3074 constructs are expanded in the filename. If specified on the
3030 client, then it will verify the identity of remote HTTPS servers
3075 client, then it will verify the identity of remote HTTPS servers
3031 with these certificates.
3076 with these certificates.
3032
3077
3033 To disable SSL verification temporarily, specify ``--insecure`` from
3078 To disable SSL verification temporarily, specify ``--insecure`` from
3034 command line.
3079 command line.
3035
3080
3036 You can use OpenSSL's CA certificate file if your platform has
3081 You can use OpenSSL's CA certificate file if your platform has
3037 one. On most Linux systems this will be
3082 one. On most Linux systems this will be
3038 ``/etc/ssl/certs/ca-certificates.crt``. Otherwise you will have to
3083 ``/etc/ssl/certs/ca-certificates.crt``. Otherwise you will have to
3039 generate this file manually. The form must be as follows::
3084 generate this file manually. The form must be as follows::
3040
3085
3041 -----BEGIN CERTIFICATE-----
3086 -----BEGIN CERTIFICATE-----
3042 ... (certificate in base64 PEM encoding) ...
3087 ... (certificate in base64 PEM encoding) ...
3043 -----END CERTIFICATE-----
3088 -----END CERTIFICATE-----
3044 -----BEGIN CERTIFICATE-----
3089 -----BEGIN CERTIFICATE-----
3045 ... (certificate in base64 PEM encoding) ...
3090 ... (certificate in base64 PEM encoding) ...
3046 -----END CERTIFICATE-----
3091 -----END CERTIFICATE-----
3047
3092
3048 ``cache``
3093 ``cache``
3049 Whether to support caching in hgweb. (default: True)
3094 Whether to support caching in hgweb. (default: True)
3050
3095
3051 ``certificate``
3096 ``certificate``
3052 Certificate to use when running :hg:`serve`.
3097 Certificate to use when running :hg:`serve`.
3053
3098
3054 ``collapse``
3099 ``collapse``
3055 With ``descend`` enabled, repositories in subdirectories are shown at
3100 With ``descend`` enabled, repositories in subdirectories are shown at
3056 a single level alongside repositories in the current path. With
3101 a single level alongside repositories in the current path. With
3057 ``collapse`` also enabled, repositories residing at a deeper level than
3102 ``collapse`` also enabled, repositories residing at a deeper level than
3058 the current path are grouped behind navigable directory entries that
3103 the current path are grouped behind navigable directory entries that
3059 lead to the locations of these repositories. In effect, this setting
3104 lead to the locations of these repositories. In effect, this setting
3060 collapses each collection of repositories found within a subdirectory
3105 collapses each collection of repositories found within a subdirectory
3061 into a single entry for that subdirectory. (default: False)
3106 into a single entry for that subdirectory. (default: False)
3062
3107
3063 ``comparisoncontext``
3108 ``comparisoncontext``
3064 Number of lines of context to show in side-by-side file comparison. If
3109 Number of lines of context to show in side-by-side file comparison. If
3065 negative or the value ``full``, whole files are shown. (default: 5)
3110 negative or the value ``full``, whole files are shown. (default: 5)
3066
3111
3067 This setting can be overridden by a ``context`` request parameter to the
3112 This setting can be overridden by a ``context`` request parameter to the
3068 ``comparison`` command, taking the same values.
3113 ``comparison`` command, taking the same values.
3069
3114
3070 ``contact``
3115 ``contact``
3071 Name or email address of the person in charge of the repository.
3116 Name or email address of the person in charge of the repository.
3072 (default: ui.username or ``$EMAIL`` or "unknown" if unset or empty)
3117 (default: ui.username or ``$EMAIL`` or "unknown" if unset or empty)
3073
3118
3074 ``csp``
3119 ``csp``
3075 Send a ``Content-Security-Policy`` HTTP header with this value.
3120 Send a ``Content-Security-Policy`` HTTP header with this value.
3076
3121
3077 The value may contain a special string ``%nonce%``, which will be replaced
3122 The value may contain a special string ``%nonce%``, which will be replaced
3078 by a randomly-generated one-time use value. If the value contains
3123 by a randomly-generated one-time use value. If the value contains
3079 ``%nonce%``, ``web.cache`` will be disabled, as caching undermines the
3124 ``%nonce%``, ``web.cache`` will be disabled, as caching undermines the
3080 one-time property of the nonce. This nonce will also be inserted into
3125 one-time property of the nonce. This nonce will also be inserted into
3081 ``<script>`` elements containing inline JavaScript.
3126 ``<script>`` elements containing inline JavaScript.
3082
3127
3083 Note: lots of HTML content sent by the server is derived from repository
3128 Note: lots of HTML content sent by the server is derived from repository
3084 data. Please consider the potential for malicious repository data to
3129 data. Please consider the potential for malicious repository data to
3085 "inject" itself into generated HTML content as part of your security
3130 "inject" itself into generated HTML content as part of your security
3086 threat model.
3131 threat model.
3087
3132
3088 ``deny_push``
3133 ``deny_push``
3089 Whether to deny pushing to the repository. If empty or not set,
3134 Whether to deny pushing to the repository. If empty or not set,
3090 push is not denied. If the special value ``*``, all remote users are
3135 push is not denied. If the special value ``*``, all remote users are
3091 denied push. Otherwise, unauthenticated users are all denied, and
3136 denied push. Otherwise, unauthenticated users are all denied, and
3092 any authenticated user name present in this list is also denied. The
3137 any authenticated user name present in this list is also denied. The
3093 contents of the deny_push list are examined before the allow-push list.
3138 contents of the deny_push list are examined before the allow-push list.
3094
3139
3095 ``deny_read``
3140 ``deny_read``
3096 Whether to deny reading/viewing of the repository. If this list is
3141 Whether to deny reading/viewing of the repository. If this list is
3097 not empty, unauthenticated users are all denied, and any
3142 not empty, unauthenticated users are all denied, and any
3098 authenticated user name present in this list is also denied access to
3143 authenticated user name present in this list is also denied access to
3099 the repository. If set to the special value ``*``, all remote users
3144 the repository. If set to the special value ``*``, all remote users
3100 are denied access (rarely needed ;). If deny_read is empty or not set,
3145 are denied access (rarely needed ;). If deny_read is empty or not set,
3101 the determination of repository access depends on the presence and
3146 the determination of repository access depends on the presence and
3102 content of the allow_read list (see description). If both
3147 content of the allow_read list (see description). If both
3103 deny_read and allow_read are empty or not set, then access is
3148 deny_read and allow_read are empty or not set, then access is
3104 permitted to all users by default. If the repository is being
3149 permitted to all users by default. If the repository is being
3105 served via hgwebdir, denied users will not be able to see it in
3150 served via hgwebdir, denied users will not be able to see it in
3106 the list of repositories. The contents of the deny_read list have
3151 the list of repositories. The contents of the deny_read list have
3107 priority over (are examined before) the contents of the allow_read
3152 priority over (are examined before) the contents of the allow_read
3108 list.
3153 list.
3109
3154
3110 ``descend``
3155 ``descend``
3111 hgwebdir indexes will not descend into subdirectories. Only repositories
3156 hgwebdir indexes will not descend into subdirectories. Only repositories
3112 directly in the current path will be shown (other repositories are still
3157 directly in the current path will be shown (other repositories are still
3113 available from the index corresponding to their containing path).
3158 available from the index corresponding to their containing path).
3114
3159
3115 ``description``
3160 ``description``
3116 Textual description of the repository's purpose or contents.
3161 Textual description of the repository's purpose or contents.
3117 (default: "unknown")
3162 (default: "unknown")
3118
3163
3119 ``encoding``
3164 ``encoding``
3120 Character encoding name. (default: the current locale charset)
3165 Character encoding name. (default: the current locale charset)
3121 Example: "UTF-8".
3166 Example: "UTF-8".
3122
3167
3123 ``errorlog``
3168 ``errorlog``
3124 Where to output the error log. (default: stderr)
3169 Where to output the error log. (default: stderr)
3125
3170
3126 ``guessmime``
3171 ``guessmime``
3127 Control MIME types for raw download of file content.
3172 Control MIME types for raw download of file content.
3128 Set to True to let hgweb guess the content type from the file
3173 Set to True to let hgweb guess the content type from the file
3129 extension. This will serve HTML files as ``text/html`` and might
3174 extension. This will serve HTML files as ``text/html`` and might
3130 allow cross-site scripting attacks when serving untrusted
3175 allow cross-site scripting attacks when serving untrusted
3131 repositories. (default: False)
3176 repositories. (default: False)
3132
3177
3133 ``hidden``
3178 ``hidden``
3134 Whether to hide the repository in the hgwebdir index.
3179 Whether to hide the repository in the hgwebdir index.
3135 (default: False)
3180 (default: False)
3136
3181
3137 ``ipv6``
3182 ``ipv6``
3138 Whether to use IPv6. (default: False)
3183 Whether to use IPv6. (default: False)
3139
3184
3140 ``labels``
3185 ``labels``
3141 List of string *labels* associated with the repository.
3186 List of string *labels* associated with the repository.
3142
3187
3143 Labels are exposed as a template keyword and can be used to customize
3188 Labels are exposed as a template keyword and can be used to customize
3144 output. e.g. the ``index`` template can group or filter repositories
3189 output. e.g. the ``index`` template can group or filter repositories
3145 by labels and the ``summary`` template can display additional content
3190 by labels and the ``summary`` template can display additional content
3146 if a specific label is present.
3191 if a specific label is present.
3147
3192
3148 ``logoimg``
3193 ``logoimg``
3149 File name of the logo image that some templates display on each page.
3194 File name of the logo image that some templates display on each page.
3150 The file name is relative to ``staticurl``. That is, the full path to
3195 The file name is relative to ``staticurl``. That is, the full path to
3151 the logo image is "staticurl/logoimg".
3196 the logo image is "staticurl/logoimg".
3152 If unset, ``hglogo.png`` will be used.
3197 If unset, ``hglogo.png`` will be used.
3153
3198
3154 ``logourl``
3199 ``logourl``
3155 Base URL to use for logos. If unset, ``https://mercurial-scm.org/``
3200 Base URL to use for logos. If unset, ``https://mercurial-scm.org/``
3156 will be used.
3201 will be used.
3157
3202
3158 ``maxchanges``
3203 ``maxchanges``
3159 Maximum number of changes to list on the changelog. (default: 10)
3204 Maximum number of changes to list on the changelog. (default: 10)
3160
3205
3161 ``maxfiles``
3206 ``maxfiles``
3162 Maximum number of files to list per changeset. (default: 10)
3207 Maximum number of files to list per changeset. (default: 10)
3163
3208
3164 ``maxshortchanges``
3209 ``maxshortchanges``
3165 Maximum number of changes to list on the shortlog, graph or filelog
3210 Maximum number of changes to list on the shortlog, graph or filelog
3166 pages. (default: 60)
3211 pages. (default: 60)
3167
3212
3168 ``name``
3213 ``name``
3169 Repository name to use in the web interface.
3214 Repository name to use in the web interface.
3170 (default: current working directory)
3215 (default: current working directory)
3171
3216
3172 ``port``
3217 ``port``
3173 Port to listen on. (default: 8000)
3218 Port to listen on. (default: 8000)
3174
3219
3175 ``prefix``
3220 ``prefix``
3176 Prefix path to serve from. (default: '' (server root))
3221 Prefix path to serve from. (default: '' (server root))
3177
3222
3178 ``push_ssl``
3223 ``push_ssl``
3179 Whether to require that inbound pushes be transported over SSL to
3224 Whether to require that inbound pushes be transported over SSL to
3180 prevent password sniffing. (default: True)
3225 prevent password sniffing. (default: True)
3181
3226
3182 ``refreshinterval``
3227 ``refreshinterval``
3183 How frequently directory listings re-scan the filesystem for new
3228 How frequently directory listings re-scan the filesystem for new
3184 repositories, in seconds. This is relevant when wildcards are used
3229 repositories, in seconds. This is relevant when wildcards are used
3185 to define paths. Depending on how much filesystem traversal is
3230 to define paths. Depending on how much filesystem traversal is
3186 required, refreshing may negatively impact performance.
3231 required, refreshing may negatively impact performance.
3187
3232
3188 Values less than or equal to 0 always refresh.
3233 Values less than or equal to 0 always refresh.
3189 (default: 20)
3234 (default: 20)
3190
3235
3191 ``server-header``
3236 ``server-header``
3192 Value for HTTP ``Server`` response header.
3237 Value for HTTP ``Server`` response header.
3193
3238
3194 ``static``
3239 ``static``
3195 Directory where static files are served from.
3240 Directory where static files are served from.
3196
3241
3197 ``staticurl``
3242 ``staticurl``
3198 Base URL to use for static files. If unset, static files (e.g. the
3243 Base URL to use for static files. If unset, static files (e.g. the
3199 hgicon.png favicon) will be served by the CGI script itself. Use
3244 hgicon.png favicon) will be served by the CGI script itself. Use
3200 this setting to serve them directly with the HTTP server.
3245 this setting to serve them directly with the HTTP server.
3201 Example: ``http://hgserver/static/``.
3246 Example: ``http://hgserver/static/``.
3202
3247
3203 ``stripes``
3248 ``stripes``
3204 How many lines a "zebra stripe" should span in multi-line output.
3249 How many lines a "zebra stripe" should span in multi-line output.
3205 Set to 0 to disable. (default: 1)
3250 Set to 0 to disable. (default: 1)
3206
3251
3207 ``style``
3252 ``style``
3208 Which template map style to use. The available options are the names of
3253 Which template map style to use. The available options are the names of
3209 subdirectories in the HTML templates path. (default: ``paper``)
3254 subdirectories in the HTML templates path. (default: ``paper``)
3210 Example: ``monoblue``.
3255 Example: ``monoblue``.
3211
3256
3212 ``templates``
3257 ``templates``
3213 Where to find the HTML templates. The default path to the HTML templates
3258 Where to find the HTML templates. The default path to the HTML templates
3214 can be obtained from ``hg debuginstall``.
3259 can be obtained from ``hg debuginstall``.
3215
3260
3216 ``websub``
3261 ``websub``
3217 ----------
3262 ----------
3218
3263
3219 Web substitution filter definition. You can use this section to
3264 Web substitution filter definition. You can use this section to
3220 define a set of regular expression substitution patterns which
3265 define a set of regular expression substitution patterns which
3221 let you automatically modify the hgweb server output.
3266 let you automatically modify the hgweb server output.
3222
3267
3223 The default hgweb templates only apply these substitution patterns
3268 The default hgweb templates only apply these substitution patterns
3224 on the revision description fields. You can apply them anywhere
3269 on the revision description fields. You can apply them anywhere
3225 you want when you create your own templates by adding calls to the
3270 you want when you create your own templates by adding calls to the
3226 "websub" filter (usually after calling the "escape" filter).
3271 "websub" filter (usually after calling the "escape" filter).
3227
3272
3228 This can be used, for example, to convert issue references to links
3273 This can be used, for example, to convert issue references to links
3229 to your issue tracker, or to convert "markdown-like" syntax into
3274 to your issue tracker, or to convert "markdown-like" syntax into
3230 HTML (see the examples below).
3275 HTML (see the examples below).
3231
3276
3232 Each entry in this section names a substitution filter.
3277 Each entry in this section names a substitution filter.
3233 The value of each entry defines the substitution expression itself.
3278 The value of each entry defines the substitution expression itself.
3234 The websub expressions follow the old interhg extension syntax,
3279 The websub expressions follow the old interhg extension syntax,
3235 which in turn imitates the Unix sed replacement syntax::
3280 which in turn imitates the Unix sed replacement syntax::
3236
3281
3237 patternname = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i]
3282 patternname = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i]
3238
3283
3239 You can use any separator other than "/". The final "i" is optional
3284 You can use any separator other than "/". The final "i" is optional
3240 and indicates that the search must be case insensitive.
3285 and indicates that the search must be case insensitive.
3241
3286
3242 Examples::
3287 Examples::
3243
3288
3244 [websub]
3289 [websub]
3245 issues = s|issue(\d+)|<a href="http://bts.example.org/issue\1">issue\1</a>|i
3290 issues = s|issue(\d+)|<a href="http://bts.example.org/issue\1">issue\1</a>|i
3246 italic = s/\b_(\S+)_\b/<i>\1<\/i>/
3291 italic = s/\b_(\S+)_\b/<i>\1<\/i>/
3247 bold = s/\*\b(\S+)\b\*/<b>\1<\/b>/
3292 bold = s/\*\b(\S+)\b\*/<b>\1<\/b>/
3248
3293
3249 ``worker``
3294 ``worker``
3250 ----------
3295 ----------
3251
3296
3252 Parallel master/worker configuration. We currently perform working
3297 Parallel master/worker configuration. We currently perform working
3253 directory updates in parallel on Unix-like systems, which greatly
3298 directory updates in parallel on Unix-like systems, which greatly
3254 helps performance.
3299 helps performance.
3255
3300
3256 ``enabled``
3301 ``enabled``
3257 Whether to enable workers code to be used.
3302 Whether to enable workers code to be used.
3258 (default: true)
3303 (default: true)
3259
3304
3260 ``numcpus``
3305 ``numcpus``
3261 Number of CPUs to use for parallel operations. A zero or
3306 Number of CPUs to use for parallel operations. A zero or
3262 negative value is treated as ``use the default``.
3307 negative value is treated as ``use the default``.
3263 (default: 4 or the number of CPUs on the system, whichever is larger)
3308 (default: 4 or the number of CPUs on the system, whichever is larger)
3264
3309
3265 ``backgroundclose``
3310 ``backgroundclose``
3266 Whether to enable closing file handles on background threads during certain
3311 Whether to enable closing file handles on background threads during certain
3267 operations. Some platforms aren't very efficient at closing file
3312 operations. Some platforms aren't very efficient at closing file
3268 handles that have been written or appended to. By performing file closing
3313 handles that have been written or appended to. By performing file closing
3269 on background threads, file write rate can increase substantially.
3314 on background threads, file write rate can increase substantially.
3270 (default: true on Windows, false elsewhere)
3315 (default: true on Windows, false elsewhere)
3271
3316
3272 ``backgroundcloseminfilecount``
3317 ``backgroundcloseminfilecount``
3273 Minimum number of files required to trigger background file closing.
3318 Minimum number of files required to trigger background file closing.
3274 Operations not writing this many files won't start background close
3319 Operations not writing this many files won't start background close
3275 threads.
3320 threads.
3276 (default: 2048)
3321 (default: 2048)
3277
3322
3278 ``backgroundclosemaxqueue``
3323 ``backgroundclosemaxqueue``
3279 The maximum number of opened file handles waiting to be closed in the
3324 The maximum number of opened file handles waiting to be closed in the
3280 background. This option only has an effect if ``backgroundclose`` is
3325 background. This option only has an effect if ``backgroundclose`` is
3281 enabled.
3326 enabled.
3282 (default: 384)
3327 (default: 384)
3283
3328
3284 ``backgroundclosethreadcount``
3329 ``backgroundclosethreadcount``
3285 Number of threads to process background file closes. Only relevant if
3330 Number of threads to process background file closes. Only relevant if
3286 ``backgroundclose`` is enabled.
3331 ``backgroundclose`` is enabled.
3287 (default: 4)
3332 (default: 4)
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now