Compare commits
7216 Commits
Author | SHA1 | Date | |
---|---|---|---|
d949117b02 | |||
853a6ec9dc | |||
fe3bccf3ce | |||
979519d34c | |||
7829a93251 | |||
d4b76823a2 | |||
00cc16455c | |||
f0fb13310f | |||
396469aa0c | |||
6e222c573b | |||
6f9e0dca51 | |||
d2c3c37f4d | |||
c2204dc322 | |||
b797cc9af8 | |||
9d207a968a | |||
cc915df10e | |||
fe53424710 | |||
6cfd4cb633 | |||
4d38f91bd5 | |||
4f63f08aeb | |||
e7e7fab1a9 | |||
4b6b3419c2 | |||
b3a7739eaa | |||
1214367503 | |||
0876723e1b | |||
d24adda700 | |||
eb89f4636b | |||
7da247ffd6 | |||
cadcf27ebc | |||
61b882d426 | |||
e4d780417d | |||
4d01e3a16a | |||
52a1627d81 | |||
d5b9d91a75 | |||
cd507b10e0 | |||
bb3e8200f1 | |||
f7a96272c1 | |||
a8d1f55544 | |||
fb8ca19327 | |||
0ae39c01df | |||
341bea48f8 | |||
aa336e7d8a | |||
77f9b6a88c | |||
3b94c2798c | |||
1a91b52435 | |||
70f97382a4 | |||
e7b98fbae3 | |||
ad3a635f59 | |||
eea9ba10fd | |||
f2dc033067 | |||
bf37ee9cf6 | |||
9b4fe5930e | |||
a4e950343a | |||
af54e7ebc2 | |||
8edb4eae3b | |||
694b8e111c | |||
cccaf0e72c | |||
7d65817acd | |||
43f159cd81 | |||
6e2f355aa6 | |||
e2f868df52 | |||
4920130604 | |||
898f0f4481 | |||
615b7842db | |||
2bc6499f1b | |||
0da16d513a | |||
9175af4abe | |||
3046fe0f0b | |||
6822608c14 | |||
177ddb4117 | |||
3b876413c1 | |||
6397c8e07c | |||
9fce9fcb7b | |||
0eec3eefd6 | |||
83ce5a2107 | |||
4ea6a03b4b | |||
085403a13f | |||
fd8fd7f893 | |||
bdf12aab0f | |||
299527fe16 | |||
86fa1add98 | |||
e14c086fed | |||
fbf707cde2 | |||
80dd5d7b6f | |||
45a6bc8ae2 | |||
360037c6cc | |||
71c578f866 | |||
8d133d6ffc | |||
5cf3819743 | |||
d3315c2fa6 | |||
f7f3244b3d | |||
b3f2aa6cf5 | |||
6a2c5f28f3 | |||
d6211327db | |||
76f87011a2 | |||
c6fc0302d2 | |||
843c813f86 | |||
7c65799758 | |||
57742ad871 | |||
7db510b5ca | |||
ec3be18494 | |||
9895f5b448 | |||
1490fbb721 | |||
dd4400f8dd | |||
a81696321a | |||
5e94250701 | |||
64ef42aafd | |||
76fff58b57 | |||
4279ee1962 | |||
558f45a48c | |||
6a76167637 | |||
f56ad3408c | |||
8e688b7f28 | |||
6d737ce119 | |||
2075e16767 | |||
2c4b1798ad | |||
b040f78f70 | |||
c221cb7ccb | |||
8a51e21310 | |||
31b73f0d82 | |||
9177c2ef6d | |||
777748d79e | |||
d0f97e85d2 | |||
2eff7523c3 | |||
12d4803c5c | |||
fdbee350b8 | |||
78f47516b8 | |||
088c0c7f85 | |||
809e475e29 | |||
8b776ed9e5 | |||
984475b9d0 | |||
894f68f2ae | |||
684547081b | |||
f6e47f648e | |||
796d8d4406 | |||
7ac6cad18c | |||
b3abc8f161 | |||
e80296fa85 | |||
d0779b88e0 | |||
acd7765159 | |||
0a51031334 | |||
0f7c0341c5 | |||
d40669c7bd | |||
fe8360e870 | |||
72fd2ec424 | |||
7e7d4086cd | |||
f5d26a1555 | |||
08926e737d | |||
540fb6c9f6 | |||
12681eda36 | |||
a05dbef337 | |||
3344c50a9e | |||
487c5b143b | |||
886b7d9256 | |||
d0e7b4988f | |||
4e753238f3 | |||
f30da1da71 | |||
c1c0bf4fdf | |||
a8581510e5 | |||
bbba7551b7 | |||
a129114603 | |||
392ec623c0 | |||
f39f6d23c7 | |||
acc234a822 | |||
641bdcff31 | |||
b3945d758a | |||
4272ea97db | |||
5e438b84e1 | |||
ff79a31066 | |||
5ba6436454 | |||
225264a283 | |||
9d6001c4db | |||
8a5a160645 | |||
5cbadc09f9 | |||
7aa87d397e | |||
693eceb80f | |||
7d8fc14159 | |||
4687bb95cb | |||
e3ec07da76 | |||
089ac7c42f | |||
910801d305 | |||
5ad0b128aa | |||
5cbeea4fb3 | |||
a6e18736d6 | |||
373b90e3b5 | |||
f6c2afb71e | |||
974ef0fa34 | |||
92f9b226fe | |||
0ac6553840 | |||
41a2241ae1 | |||
9bb1a5b80a | |||
0e59107eee | |||
c9fe68b812 | |||
e7b9688602 | |||
a962e60de9 | |||
e5611f9165 | |||
540ad13265 | |||
2849426092 | |||
c4a2b4e975 | |||
d508f5dc09 | |||
81ce8b0469 | |||
5a3a661e91 | |||
bb5c6bd68d | |||
9dfabeab52 | |||
ff269590f0 | |||
46a7ce666e | |||
ad07330bf1 | |||
74011e50e3 | |||
3dfdbf544a | |||
4bf0b79c2a | |||
cc0ea0b3f8 | |||
62d765125d | |||
b5b45d9a27 | |||
8e098710c1 | |||
6dfb369b55 | |||
817522ff97 | |||
8b5b90d247 | |||
b670097592 | |||
7b6a115adc | |||
77fba4aee3 | |||
7e1712c8cd | |||
b7affb1d34 | |||
d7fd90c4c3 | |||
1d94782463 | |||
c7a05c3f09 | |||
2dc58a82b7 | |||
755dbbab00 | |||
b470fe22f1 | |||
5b2560ddf7 | |||
be429c527c | |||
65fd537200 | |||
6e43c7f06f | |||
5867b5c000 | |||
05887cf8b0 | |||
c43721d489 | |||
0bf75d52d7 | |||
c35af2dc69 | |||
73a9835a27 | |||
87ab15f754 | |||
6bc608c081 | |||
cbea1d8691 | |||
58f21a69aa | |||
426c5b9a24 | |||
511e90efd1 | |||
bc7b856654 | |||
d50d2f9ca0 | |||
1b53defab3 | |||
3e612921f3 | |||
ec51d43490 | |||
80dc5028f7 | |||
2329c4a75f | |||
ae76cc1ca2 | |||
e4f79f046a | |||
622d837ea1 | |||
c0aa9a8bd4 | |||
9b1052f023 | |||
c77c2f8bd6 | |||
402eaa8f12 | |||
212e8c3654 | |||
7c77b16517 | |||
e5bb0bcba3 | |||
ca4a7d8771 | |||
663f97265a | |||
b91f3048ef | |||
4fe0bf1236 | |||
dd35af3c55 | |||
68f24e47cd | |||
968223a953 | |||
2f287874e3 | |||
c35e7406cd | |||
34b2cca492 | |||
e1bfc04451 | |||
ef0ba7b0c4 | |||
0a2d8880ba | |||
8dcd7e6966 | |||
b744fd6167 | |||
5bcc5c919a | |||
01e12329e9 | |||
98851ece17 | |||
471bf57835 | |||
b246beab3e | |||
abc8161a08 | |||
64ba8248d2 | |||
206d222455 | |||
2e114d7c29 | |||
5190c25be0 | |||
5704919b3a | |||
c3e51f51b6 | |||
8c35edb6e8 | |||
2f2b4094f6 | |||
413a9b4269 | |||
a698aa8a5b | |||
0f79526566 | |||
1ffbab7338 | |||
3a71c45a89 | |||
8f062f918b | |||
c140e255aa | |||
ba5307c4b9 | |||
4d30c7eba5 | |||
3722b78fe1 | |||
2f05d00219 | |||
b48ca92675 | |||
4a31cf0a09 | |||
82620ee327 | |||
16b02ec246 | |||
6d284b4124 | |||
83fa8cbf0f | |||
9ba4b030ed | |||
272cc3d3c9 | |||
b5590a38fe | |||
443a350bad | |||
7013e618de | |||
363b60385b | |||
90635ffc4e | |||
056f850268 | |||
336f2d88e9 | |||
e16b4062b5 | |||
747dacf3b1 | |||
13a7538695 | |||
f00a71922f | |||
c97c9d4ece | |||
9d3f8672d9 | |||
fe48cd4236 | |||
587d3aa612 | |||
8a951940fd | |||
b726ef8a2e | |||
25e360e175 | |||
1d9ec253fb | |||
3cf1aa00fa | |||
36a5d0ee3f | |||
f5e5174045 | |||
ba2301ebfe | |||
0dfe115931 | |||
1f13d33515 | |||
df651a2157 | |||
2d2c1d5f2d | |||
9665c5c67d | |||
fae939a28a | |||
0f93581ff5 | |||
397452a7fe | |||
cd3157361a | |||
9a49489043 | |||
c3f101937c | |||
29a89f185a | |||
2f7a5c2967 | |||
f07ed53f7e | |||
7348a6a62f | |||
9d22bc6d5f | |||
b7ba53eb60 | |||
e389d6a96b | |||
e4c55d8da3 | |||
554508d1c4 | |||
70abe24e34 | |||
0238dffc7a | |||
666445e8f7 | |||
36bada8feb | |||
b4946f4db1 | |||
f3d485da53 | |||
3342122be2 | |||
f59751853a | |||
a60c55c6df | |||
3bad5883bb | |||
de9180e557 | |||
627341f55d | |||
2b36f4a5ce | |||
d4c30866b7 | |||
7c92ce771f | |||
4601359ebe | |||
04b1130837 | |||
c377617b5a | |||
222e8f66df | |||
87e2f5f414 | |||
7de05700e9 | |||
841f41da2f | |||
b7ff0cf2b5 | |||
73dcde7780 | |||
377ff52222 | |||
7c071ed1cc | |||
e4b5609d78 | |||
c93497af10 | |||
99dda66bbc | |||
4ce68f817d | |||
1c027be106 | |||
4a94074595 | |||
b49f6c3f86 | |||
9c8fe9277d | |||
a7c70e6912 | |||
28156a5a6b | |||
a3cfb9e5e4 | |||
d2e3698ad1 | |||
25ccc6a9f9 | |||
8d1904c185 | |||
85cc221d50 | |||
588b00de45 | |||
656a1f8294 | |||
1dd37c5020 | |||
916a040aa0 | |||
3c40dc1f49 | |||
6d560caf06 | |||
07f3301e32 | |||
9410a293f7 | |||
a0704eddb0 | |||
245517a4b0 | |||
44319488ec | |||
672491c66c | |||
bd91c45d1f | |||
47112ddc3c | |||
57463583d6 | |||
a179105dbf | |||
5c4dbd30ce | |||
4fb415f5cd | |||
49cb380f3c | |||
3710449ee8 | |||
8925c9b7e5 | |||
556e10462b | |||
f77cdb7148 | |||
a89dcb0681 | |||
c3f643d43f | |||
0baef01395 | |||
a3e35986b3 | |||
4efa028044 | |||
4f519d2079 | |||
0ead426fd1 | |||
22cb71b4c6 | |||
590b40185e | |||
89094b908f | |||
3bfd6fca5c | |||
250af65410 | |||
f4307aa549 | |||
e6afc487df | |||
380f9d5ec5 | |||
449943cf9e | |||
ca9b8b57da | |||
0be909957b | |||
23aed49a79 | |||
8ddb6d4b6f | |||
114479321e | |||
1e5a783e7f | |||
035b91bec2 | |||
0993f788a1 | |||
b27afb9eed | |||
7bdb136c27 | |||
c0ad32eaf7 | |||
f61592cb35 | |||
0df173b415 | |||
a6c01f4658 | |||
5ea1af44d3 | |||
3821795ec5 | |||
7878a4365c | |||
5b7dafe142 | |||
e1888a038c | |||
e3afd3f933 | |||
055276ead9 | |||
fbdeec84e3 | |||
04676de783 | |||
766d3daf0d | |||
9480eff096 | |||
cb748e0897 | |||
90feb1810f | |||
a05212923b | |||
a6293d21c2 | |||
581307c334 | |||
5b2e633589 | |||
f56dc8c6ae | |||
dd99a7b32d | |||
6bc5c12051 | |||
048d0c445f | |||
0a50f7dba7 | |||
3218db5815 | |||
5ca19879b6 | |||
13a7e9be0a | |||
c95a2552d0 | |||
78a31b74c7 | |||
8450d882f9 | |||
19f33f830c | |||
e6fc7f1307 | |||
b0e3abe61f | |||
e1b2bc1a05 | |||
8c0d1fde45 | |||
6516ed3586 | |||
4e8975a539 | |||
66e8b1211b | |||
e42b59bec6 | |||
452f2be6c8 | |||
a38553da29 | |||
1a28f790fc | |||
afa3c46ce3 | |||
8224c84556 | |||
b619688d80 | |||
106b4442a0 | |||
fc98457add | |||
1ec5917518 | |||
ab0b067916 | |||
35645278a2 | |||
cc20a0ee95 | |||
0c0c2be67b | |||
c6b69babc2 | |||
696d6a823d | |||
cf47e2a1b3 | |||
d5faa2c8b7 | |||
e9f785e2b0 | |||
c881c3b7f2 | |||
bdb213dca6 | |||
0291766588 | |||
dabf1d4159 | |||
71f9cb27b6 | |||
cdc0a7fb09 | |||
f4cf4a7e4a | |||
d8c519d008 | |||
ed4dea214d | |||
af95d472fa | |||
20c80810f1 | |||
94760792af | |||
ce9d2dc3d2 | |||
fcd365b8f6 | |||
50dafd2452 | |||
ca4abcb497 | |||
deb9c1e1e1 | |||
2b349bfc8a | |||
49aae758a9 | |||
308882234c | |||
acbc75d077 | |||
ce4d73fcad | |||
8b20cd9082 | |||
fe01e4693f | |||
1506a2738a | |||
0eca1ddbf1 | |||
859a8d1a11 | |||
0fdaffc677 | |||
8017493ff5 | |||
d18e8d2eaf | |||
49fbadbd29 | |||
64505f65f9 | |||
9327b08219 | |||
f893d8b8e2 | |||
dfc70e7482 | |||
e54f0831b8 | |||
c3d77c1de0 | |||
59c61e2e3d | |||
82f78d0cc4 | |||
d9290eae8e | |||
7175052a00 | |||
9008e84c98 | |||
67c70db758 | |||
d8a244b648 | |||
2602846b2f | |||
e19bf3a376 | |||
2a09cbbd07 | |||
60428ddb87 | |||
a2590af4f8 | |||
4641123f08 | |||
8d9460e1ce | |||
4cc52ee578 | |||
a93d794b11 | |||
90ae127cdb | |||
2ffae18d8b | |||
87d4038fc6 | |||
3838b2abe7 | |||
a7fa00be9a | |||
bb9143d493 | |||
aafedd7ccb | |||
f2b62bce8e | |||
db9f717656 | |||
e1cfd82254 | |||
3ddcf457df | |||
8066d356b0 | |||
365423e598 | |||
5b20aca1f2 | |||
20c30cf0d1 | |||
9ed6cb8cf4 | |||
3bb383f0f1 | |||
6de334e50a | |||
16159c6a29 | |||
2acea1ed99 | |||
3454bfd213 | |||
b0c25bcbb6 | |||
553e560b75 | |||
1e33229daa | |||
16c9c14f6c | |||
ba56947ca5 | |||
f5858f3338 | |||
d804fb132c | |||
f276e4ccab | |||
9287cc3732 | |||
5b498416ef | |||
7e41166390 | |||
8ae9a8d5d6 | |||
6e46651de2 | |||
df9d6b9a40 | |||
52770ec758 | |||
9087d7b91b | |||
8aaf77d4b4 | |||
10977e6750 | |||
66d8dda0f5 | |||
25ae6df095 | |||
63cd54d6fc | |||
7fc51b1ee0 | |||
7622aba453 | |||
61722fa099 | |||
61f37368f4 | |||
5196bc4548 | |||
3adb4b3c58 | |||
f37282112c | |||
2096b1dbd5 | |||
c5d86f6018 | |||
d3806a8337 | |||
d35429b356 | |||
17dc821c79 | |||
3e86ba91d6 | |||
b10db9e370 | |||
955be1f20d | |||
c965b27ca0 | |||
c3bd4490dd | |||
7c69bd249d | |||
0ccfdb16eb | |||
6479772571 | |||
6711688734 | |||
0458ba9373 | |||
e3c973fb61 | |||
28f26004c4 | |||
516132c32b | |||
46f0649343 | |||
2d4c30522d | |||
f207525ba3 | |||
13bb6eb6d7 | |||
796cd88ccf | |||
6b14d87d27 | |||
def9c3ce5b | |||
0ac8e0c517 | |||
eb3a37bd2b | |||
bd559f7bf5 | |||
bcce78c37b | |||
667bea4589 | |||
b9838204b2 | |||
6a29022335 | |||
5af47aa3f3 | |||
dc18f97d88 | |||
ec38da3c45 | |||
29905ba071 | |||
e0c57b1691 | |||
a9dd25e045 | |||
cd9d9b8f20 | |||
5d1413f733 | |||
395abe0e5c | |||
03b68b12e5 | |||
1a9a742dbe | |||
ed0938346d | |||
643739514e | |||
63720baa73 | |||
dc8aa1fc13 | |||
a1c86e011a | |||
2cbbf4af7e | |||
62d0409b57 | |||
f8325ad5a8 | |||
35371ee0a4 | |||
998032c6c8 | |||
a34bdd8557 | |||
249b991185 | |||
bc6d037341 | |||
a4a1fa0746 | |||
d73e26e0c4 | |||
372688b723 | |||
a5ab68ab02 | |||
e7297ce6b8 | |||
a88b39e50d | |||
a0988c250d | |||
3a52759090 | |||
ddb07a7ba9 | |||
b5ad5a5f6f | |||
a46073f3e4 | |||
f03ea5c115 | |||
f7569b715d | |||
6e19d21575 | |||
4eb155696c | |||
1157e2d04b | |||
247532e3c4 | |||
4a2f61de9f | |||
654cf1982e | |||
e0a0406825 | |||
d6d14b4170 | |||
cbeb32808a | |||
a295e123bc | |||
c56b660c92 | |||
6a5bc99a55 | |||
833895e797 | |||
fa080ce0a4 | |||
2482b9df74 | |||
bf66b54c9a | |||
1ba7b67e70 | |||
feffbbd980 | |||
e0c5ac5271 | |||
50656dc7d3 | |||
cbeea86a13 | |||
5a6bdd756a | |||
cf7bb8cff7 | |||
b898fd0ec1 | |||
f8f98ab7f0 | |||
0f8da123b8 | |||
aa9e1acb91 | |||
61e4995c14 | |||
078ce28b8a | |||
88fe28df8d | |||
e14b055651 | |||
e5a09cbeaa | |||
b5ade89763 | |||
2c63d16774 | |||
36fcde29ae | |||
c5aca1b7f7 | |||
4307fa24a7 | |||
d8d36cf4c7 | |||
1374213308 | |||
31a9466bf8 | |||
181e4fd2fc | |||
03ba6b39ec | |||
c063c70b07 | |||
89fcf86bb4 | |||
faf6b514e6 | |||
7564c3c2bd | |||
fc9d4f96a7 | |||
c6d46fcdd0 | |||
8331d1019f | |||
900c5f7976 | |||
d2a04db49f | |||
7793c5e5df | |||
69e0ae76c7 | |||
c134602cbd | |||
d96b066658 | |||
b0da802abe | |||
2c4d87aef8 | |||
11b38a7a4c | |||
84df96429c | |||
adbe5977cd | |||
4c303d358b | |||
eba3475a1b | |||
8bb4ceaaac | |||
a89c0d4797 | |||
a8e16b0ba6 | |||
7de4e8b001 | |||
b4cd74056e | |||
9db9c5e936 | |||
247afe6a7b | |||
90bc087ad6 | |||
6049fa23a7 | |||
4821f77304 | |||
c348f442cc | |||
c23fab5b34 | |||
8d429f064b | |||
d3277306cf | |||
4e0423cb1e | |||
0f08d3e3a3 | |||
0c35939001 | |||
06edb0e157 | |||
c0f9716b1e | |||
d10e07b67b | |||
22cf253183 | |||
56d57bbd84 | |||
aeb836da76 | |||
e4440ca0dc | |||
8c4cf779ce | |||
c8f003950a | |||
f4aafd5be3 | |||
bd978f29a0 | |||
76719cdc4a | |||
36cfc3648f | |||
7e80fd2e98 | |||
f1a04a3bd0 | |||
9699b3837b | |||
d2e95c2246 | |||
893b92439c | |||
8819372d2e | |||
b9cea968e5 | |||
6846a7cef5 | |||
eee3fb8b5f | |||
6245ecc8f4 | |||
d2e9ec9494 | |||
4208110d57 | |||
ff5e03a8b1 | |||
57851cef9a | |||
e7cb3c0a85 | |||
620ebc751c | |||
c7a8523b77 | |||
df4d370524 | |||
71ba5d9c4c | |||
d216ad7da9 | |||
6cc1751924 | |||
69b589a401 | |||
db73b1f268 | |||
9ac0e982d6 | |||
cb25c225e9 | |||
5b31d4de20 | |||
14f8c73b08 | |||
529075f64c | |||
dba102e74f | |||
0f3f8b6bf9 | |||
83028b9b73 | |||
1fe766cb16 | |||
6b45eb0d3d | |||
6b0087ab69 | |||
e60fd8d6ab | |||
88a1d83323 | |||
e21a8df0f3 | |||
93f37b506b | |||
fca3480e37 | |||
966547db54 | |||
09dbe44bca | |||
b7ce6b7400 | |||
78f169cd24 | |||
d0e11f1ec4 | |||
912a706de9 | |||
9b5c8a8254 | |||
e5adc630af | |||
c56c6401d6 | |||
0e64df3bbf | |||
e497903bf4 | |||
f1ff913cbe | |||
3a00d32ce0 | |||
f0f698f411 | |||
22c6468a5d | |||
a60072a431 | |||
dcc6f17c9c | |||
15ce148b99 | |||
3b73d5a5cb | |||
1fd3054006 | |||
2db1434929 | |||
a171671fe5 | |||
9160a1d71e | |||
a896560a3c | |||
e43b4ed540 | |||
8b446e2791 | |||
d72b0e4cee | |||
22996ea21e | |||
d55770cc16 | |||
5c98ca180a | |||
10bb75ce0e | |||
b9e3686fcf | |||
4ae1046571 | |||
147c6c4548 | |||
354338180b | |||
5939e19f72 | |||
f72a6df55a | |||
9c95b98f3a | |||
55a8ba0905 | |||
04037b3d2d | |||
4943c84655 | |||
42a8160768 | |||
33d3a25928 | |||
c2acff81c6 | |||
214d4b0c3f | |||
bd4cf61c2b | |||
b592ee2fed | |||
c57e1cca25 | |||
335f345ce3 | |||
b7be93c569 | |||
cd01a7b727 | |||
b96e73a002 | |||
0bf22ddf29 | |||
1c4dc382a8 | |||
71c5566f2b | |||
6621859567 | |||
6437967e60 | |||
c5a926c50c | |||
85ab691b68 | |||
4d3e0ab599 | |||
02663a149e | |||
a8fdc4798d | |||
6290b0f3bf | |||
411e0334d0 | |||
b174977bc7 | |||
2111b67e2c | |||
b96cfcd14d | |||
086f713752 | |||
fd67e09cf0 | |||
6f4ca47532 | |||
f97f23c8a5 | |||
b62985faf4 | |||
09c761aa31 | |||
8089a938f3 | |||
35b3fef7c5 | |||
f31aa43c6a | |||
b03f8db06b | |||
27e70a169e | |||
6a1d17dda2 | |||
95bf60c252 | |||
31bc6dd48c | |||
6054315d84 | |||
2a7059ddeb | |||
e2e7e59722 | |||
8b373bda8e | |||
d6806dc1f6 | |||
a753698ae7 | |||
3eec9cb0bb | |||
cd8ef0c1ff | |||
bd196ad963 | |||
1ad93838c9 | |||
a9252fd741 | |||
376067324b | |||
dd7ab2f647 | |||
1d6d146fb2 | |||
3ae1f13323 | |||
0b0a8f8218 | |||
f070b22355 | |||
c5a0e28420 | |||
70e9ea1d5e | |||
89d294524a | |||
5e25ee2996 | |||
5935dbf1d1 | |||
f7542c988d | |||
e90414bded | |||
78882dcff0 | |||
1ac1443070 | |||
b5405e9313 | |||
c7eef01fd5 | |||
26f61d35bb | |||
765776c429 | |||
f9a43b537f | |||
9f54074d03 | |||
f23078df1c | |||
a35bf54a02 | |||
4867698ac9 | |||
e84e575017 | |||
c585a0b276 | |||
ad89139e07 | |||
ebc053aca5 | |||
96da7f0322 | |||
8ae9e59d9d | |||
c94dc87cb8 | |||
20512a59b3 | |||
b3f9216c54 | |||
1cda0360e9 | |||
7f75117bfa | |||
5a70345499 | |||
5114a3a2ea | |||
93ab219124 | |||
61bf6d33b2 | |||
3fc687a2d4 | |||
8da04fd7e2 | |||
cb54f8f6d1 | |||
6ecfe073e7 | |||
ea2648f08f | |||
40adf7acd2 | |||
850af216bd | |||
bf6200d55c | |||
93bb85ffaa | |||
2fa7745886 | |||
2714907aef | |||
0d61e45cc6 | |||
541cef55b8 | |||
e3863ac076 | |||
0e2379caa6 | |||
a17c486f81 | |||
e4aaff5e34 | |||
97fda9d362 | |||
7a06423bc7 | |||
26374ef476 | |||
6324a1a1e8 | |||
b751e23e93 | |||
72ee65843d | |||
d413dd9257 | |||
433adf4668 | |||
d78267d7ee | |||
0c16492d1c | |||
eda437995f | |||
379286c366 | |||
3f344f2c0c | |||
d050c8e3b2 | |||
b13f140b86 | |||
7066a2a577 | |||
a8ebaa6784 | |||
60ff7e86b8 | |||
44b7ed0e6e | |||
afed3a0899 | |||
28265b30d2 | |||
a97172cea6 | |||
605741182d | |||
2c94a87be4 | |||
6f98d5aa20 | |||
3d08e70101 | |||
bdf56c0a6f | |||
b9b3860e6b | |||
b0554bbf17 | |||
b31f1812d2 | |||
04292d09e1 | |||
1081eab9db | |||
4023b24209 | |||
bac9ab08d1 | |||
75bf8a5086 | |||
3ffae30b95 | |||
2fda9cf539 | |||
c8b9a425b8 | |||
62865d7d88 | |||
3afd24fcd7 | |||
fd582aad75 | |||
f9155772f5 | |||
2e4313bf18 | |||
5ad320ee4b | |||
d46543ae16 | |||
2f23bad3bc | |||
6d288271cd | |||
b4daa76aeb | |||
5bd8067328 | |||
9ccc42f556 | |||
3ee4f43eb5 | |||
d1bf47a5c0 | |||
ccf9cfa332 | |||
773f8a9aea | |||
dd62e166a1 | |||
2fb72d5aa6 | |||
46f0818765 | |||
96569ae4aa | |||
f2b1e5f93e | |||
2326894a2b | |||
c15f02ddbf | |||
7708084331 | |||
696a414e95 | |||
c16dfb2dcb | |||
c979c4774c | |||
e82281d273 | |||
27c22d5e33 | |||
6acc545b66 | |||
609ec0989f | |||
b702621a04 | |||
89041a6744 | |||
c485c109e6 | |||
29a49d5f71 | |||
a5fafc4864 | |||
a921504bcf | |||
027154a4d3 | |||
bf1a1368ff | |||
097ffbf8a3 | |||
ec076d1560 | |||
8dadfa2111 | |||
c8ee6ead0b | |||
018e4c501d | |||
99a0b70cfa | |||
314a1352ec | |||
901e6be21e | |||
d58dde950e | |||
8ac18b74df | |||
2846c38ff5 | |||
d44efce225 | |||
d3dca7e808 | |||
41e3828eea | |||
9e76b4d28e | |||
ef03497350 | |||
e5a2aeb145 | |||
229a4ea56c | |||
f20e6d3768 | |||
1d210eb6e3 | |||
d8422a979f | |||
0cf6d39f02 | |||
076c20a3b7 | |||
0cfb0ba890 | |||
44a7e9387e | |||
e71954ee34 | |||
9cd9e84be6 | |||
25af9c4227 | |||
72a99bf9a6 | |||
f1228523cb | |||
a45d368115 | |||
16433dc183 | |||
0a956fdc73 | |||
75396f491b | |||
66a064e78b | |||
c4f8c4c7b4 | |||
22bbafa659 | |||
8cdfaba20c | |||
7da82826fb | |||
9a46a64cad | |||
33198d693d | |||
eaeb7021d5 | |||
b443acd43b | |||
616883648f | |||
7873f94848 | |||
17d1832dad | |||
f034e2cd65 | |||
19de73f9da | |||
00acbccd7f | |||
77d8e202d3 | |||
44df8cf0c5 | |||
e694568674 | |||
163f805f3b | |||
492512f527 | |||
73a4ac599c | |||
4aedf76f1f | |||
2d38113c66 | |||
445e1b7bd9 | |||
019ac7ae31 | |||
2b3b025bd8 | |||
57bc90ad03 | |||
089e16020e | |||
0c4f31794d | |||
cdffe9b355 | |||
5a28cf9e87 | |||
3b05de7f30 | |||
79b2f1652b | |||
b32e0e7cce | |||
1f9fbbee22 | |||
8c9f325c9f | |||
9bf1e35bf4 | |||
32e830a1c5 | |||
561bae071f | |||
08b6942c59 | |||
4564f9a46c | |||
58a1c6d2c8 | |||
97acec340c | |||
52790a6954 | |||
af6249a741 | |||
17064ab3c8 | |||
1487bf4ff5 | |||
e8c0858558 | |||
56fa3fe8f2 | |||
583813883c | |||
c69f95bdce | |||
b3df403980 | |||
90ce75ee21 | |||
1c5fcfe094 | |||
45c1fb42ee | |||
64bd493996 | |||
ec6029409e | |||
c0fc31c69a | |||
b5d0188f21 | |||
0ccbaf4bd6 | |||
ed43fb2071 | |||
d67ebd957e | |||
19d360a543 | |||
7dc41ebcea | |||
1eb7c727f3 | |||
ede8171408 | |||
2538f3d8f6 | |||
ac64f5e395 | |||
1a7a731b54 | |||
86f4d48bcb | |||
83536bee88 | |||
abfd6ea1dc | |||
688e873f7a | |||
c88df08350 | |||
82586590a7 | |||
88c66f30f2 | |||
9132592717 | |||
c0ffab768a | |||
69190081c8 | |||
093206cf1e | |||
a0110b7570 | |||
6d65feca4c | |||
95be0242b6 | |||
79e121c3af | |||
676ac2fe46 | |||
8eabdab53a | |||
957fb09ffc | |||
4bffe117a9 | |||
05b01a13c8 | |||
08e21c1a5d | |||
4d5245605d | |||
453548d614 | |||
95a0614ae1 | |||
36ea17a6b7 | |||
dc986959fd | |||
845e2881fa | |||
2e4be9310c | |||
a2faa6fd59 | |||
0a78846e8d | |||
4063a5aaee | |||
b1c81b696f | |||
0017f236a7 | |||
19d5e64063 | |||
22435a2bf5 | |||
a7def63137 | |||
3703a170e7 | |||
73fbfbd7cb | |||
acae3b8753 | |||
a618f901fc | |||
6d4918f0ab | |||
7f2c4d2e7a | |||
fd6d361e1a | |||
b5f0924651 | |||
1600dd4759 | |||
c777746b69 | |||
9f5466a41f | |||
4d1e4801bf | |||
5e469ff9c0 | |||
2f3eedea5b | |||
5c5d6dc1e2 | |||
fbe31ce64f | |||
0b082138c8 | |||
966e598f10 | |||
e998340387 | |||
f6b27cc5f9 | |||
f3dbf1e139 | |||
627d84fc91 | |||
8cde8c01df | |||
983b8c1f54 | |||
d666d8ea1a | |||
3ed81c3a78 | |||
4afec2e2b6 | |||
db83d238d5 | |||
fdcf7b3b7a | |||
53aafcf86b | |||
aec84f6d67 | |||
01e9f82d24 | |||
2eff45e65c | |||
13203c3e2b | |||
82c5e0e43d | |||
a1575f404b | |||
e1509506dc | |||
0c1d0d7b05 | |||
ad70856af0 | |||
8615f120ce | |||
0d0477d661 | |||
b31dc30878 | |||
6e392f4cfb | |||
cc3bdc331e | |||
76faf77a1c | |||
d8c0e5bf3a | |||
28c4c320cc | |||
e81403ec3f | |||
f11424f73a | |||
fa8b977016 | |||
d181846339 | |||
1956919886 | |||
0f66498965 | |||
918cd152b1 | |||
d3222df396 | |||
a84ffd8c7e | |||
6d0f9120b8 | |||
aafb4a7f2a | |||
ae432ff237 | |||
cdc318c71a | |||
94d1cec8a9 | |||
c0bc19ea59 | |||
6f07714cd9 | |||
a9d2cac23c | |||
693b46126b | |||
bbff9710bf | |||
358e122775 | |||
3818468932 | |||
3d2554fbe1 | |||
4309603317 | |||
f733c9ea77 | |||
775ee01171 | |||
33ec790137 | |||
0c575c888c | |||
24f7e51e3a | |||
0a0cf97c55 | |||
16b988d097 | |||
5edc0ff6ef | |||
375b96e508 | |||
1e72b12074 | |||
4a6d52f78e | |||
35dd580e74 | |||
79836ef1de | |||
8cb06f9c6c | |||
215a36e7a9 | |||
247f6b86a5 | |||
a9d42f1e6a | |||
4e03c2523a | |||
418b476725 | |||
783e4ccb35 | |||
6b7fb55658 | |||
3d5361cd11 | |||
2c4349c630 | |||
3589417b58 | |||
55203e0b64 | |||
a918288e3b | |||
e183138d2c | |||
d3e42862ed | |||
8860eec254 | |||
97e7e60cea | |||
44aaf7acbb | |||
9b721fae27 | |||
c3f412e3bb | |||
ee738a29f0 | |||
6c6544bf9b | |||
3d57b944ca | |||
acf003b1b4 | |||
52e108d32f | |||
7b96f96025 | |||
8db5e7e043 | |||
25fb5c1293 | |||
37f0498def | |||
02110f93d7 | |||
195dfc2c47 | |||
541b6cf9eb | |||
2c26b77afc | |||
99bcec5597 | |||
781190a65d | |||
3763480280 | |||
6fad5ebedb | |||
0690194aa1 | |||
03b94e2be3 | |||
18e34b3cbe | |||
a0bb3ace61 | |||
920ad67633 | |||
8b8f72129c | |||
b9b11e722c | |||
eddd458744 | |||
439ea20a89 | |||
cec223c8e7 | |||
25cb188d00 | |||
31007a8d96 | |||
a4fa8db69b | |||
6193835ea1 | |||
0c78e9e4ac | |||
58c409e7fa | |||
9577eed524 | |||
76f32cd064 | |||
92d9c17095 | |||
b0396df33f | |||
c17572c76f | |||
5c91e072a6 | |||
4991d0f965 | |||
45b74e1ce5 | |||
ccb4b9a9ba | |||
dd635071d6 | |||
fe1448dfae | |||
56855bc54d | |||
b51fa8df5a | |||
3aa979cb11 | |||
c95f75bc6c | |||
b13a636f89 | |||
8de55cef31 | |||
cb781f42e3 | |||
b59292dc24 | |||
03b793d7e2 | |||
bee18d1cfb | |||
d8698181f4 | |||
47f5d97eaf | |||
cb3c5e56fd | |||
39b76c08de | |||
c3c8cc21ff | |||
6dba1b6d8b | |||
381fe70a79 | |||
feb927c2e4 | |||
e77bd4c188 | |||
43436fc49e | |||
d738f797ec | |||
b5de97f785 | |||
b0c1b0895d | |||
8e60932f81 | |||
7d14cd74f2 | |||
717f1610f5 | |||
f1abe6497f | |||
046129a57d | |||
90d300a490 | |||
a2d506c0db | |||
58748a24da | |||
639e8a4a1d | |||
48ebaf5c5a | |||
1aaccb1e6b | |||
f05a7f9f14 | |||
98ddb348b0 | |||
a4aa85ebab | |||
516efe56f4 | |||
a4d72d5bbc | |||
24b8ec16f1 | |||
ac25fef555 | |||
8302f082a2 | |||
7546ef7a8e | |||
f598c70a4f | |||
422da21de5 | |||
f530fb3241 | |||
5d39bb7466 | |||
041cba72b6 | |||
892b3e273f | |||
91faf5756d | |||
e239390ebf | |||
b24764d679 | |||
4d5a568fd7 | |||
5ab55e71e0 | |||
929d63ecf8 | |||
0ef7f3715f | |||
2298f3901a | |||
3005f1937a | |||
f48eec2e93 | |||
754d304e54 | |||
9b8d08a668 | |||
1b672a1ace | |||
60d6e98c67 | |||
11f05285a1 | |||
2bd1842da1 | |||
57544068e9 | |||
60cfea9f94 | |||
eece001376 | |||
98d8ef8e1a | |||
0e43042217 | |||
c8e6714207 | |||
824e779eb2 | |||
83ea898780 | |||
5af3233fd6 | |||
08ff2f3173 | |||
22657b66d7 | |||
8b6c7a6061 | |||
1f197f6688 | |||
1055e61bb4 | |||
7ad0aa82fc | |||
d3f5576570 | |||
45141d1391 | |||
de9ac9fd43 | |||
c53d5272d6 | |||
18c78192ec | |||
632d67eef4 | |||
c23aa48688 | |||
95f3e429b4 | |||
8635fcfe84 | |||
d861537d9a | |||
631ee99f60 | |||
ffa1441ccd | |||
2f3e947027 | |||
a62aecfdfe | |||
5f829c68f2 | |||
0290d74aeb | |||
f6bc16007d | |||
ad5752f09b | |||
55565f1718 | |||
5f96d17b8c | |||
fd22406e0a | |||
64fe542c1e | |||
fae1dc8dbb | |||
6f2b673021 | |||
b26679ca14 | |||
04ba1430ca | |||
53f3758abc | |||
c6742f5533 | |||
cb44591a47 | |||
e02abb509f | |||
eff6be9643 | |||
348dbd7107 | |||
f74ea14d8b | |||
a671632fde | |||
e344622c9e | |||
06d7483ca3 | |||
7fe041fc2c | |||
3f18e5476a | |||
2a31613fe8 | |||
ded0c8a3bc | |||
f3d9e07c5e | |||
eb3ba95114 | |||
7951dcada6 | |||
06951a39c6 | |||
abe29f21f0 | |||
f57eab3008 | |||
6d4b2348ac | |||
397ca6ef0c | |||
d6e5ee2851 | |||
98d62e826b | |||
7b5ce8f70c | |||
2010a9a458 | |||
f787058c17 | |||
87ccae0d90 | |||
07d95c6ed7 | |||
514823f7d2 | |||
fb4feb24f3 | |||
5caa0e0722 | |||
0406b420c8 | |||
9d72b9779e | |||
fdc47e4a38 | |||
0566e964c0 | |||
896fbf9a5c | |||
126c8c101e | |||
3cb7cc01e4 | |||
2b3d15bf45 | |||
4049bdadcb | |||
2042ba37d8 | |||
41a4ba62b0 | |||
21558d25b1 | |||
06622bfbfd | |||
16fd2e3938 | |||
040d7670ec | |||
23761eacc1 | |||
5790bed766 | |||
2f88da67e8 | |||
21091cbf1a | |||
808949a884 | |||
06334273dc | |||
5399c04dff | |||
cd051d4093 | |||
0ca6e8ccfb | |||
bd075919f3 | |||
c229425534 | |||
e89b1826ce | |||
4ef19e19cc | |||
ff58301729 | |||
4ae05272c3 | |||
d14dafc871 | |||
022a077726 | |||
d5bd86b07a | |||
66e1eee010 | |||
ddb125f458 | |||
e6a157a101 | |||
0a437fba6a | |||
39f2e80dc1 | |||
13f9eb0d18 | |||
575b829799 | |||
02e50fadae | |||
a02f191034 | |||
d73d0f178f | |||
d542a61f5a | |||
e0486aaa24 | |||
02bf76fb3c | |||
8a3ece4a70 | |||
c553dc02a9 | |||
ff71caa47e | |||
2bd8227e20 | |||
5c61de3ae9 | |||
cff46f2d59 | |||
bbbaacc350 | |||
60f84d5e30 | |||
5218aa3c43 | |||
4b2ea0c0c3 | |||
9b865ef849 | |||
9344113ae4 | |||
4448ac9d2a | |||
9aff143d40 | |||
fc14f418cb | |||
b99253ff47 | |||
9cb844cbbb | |||
285aedef2f | |||
5121d64022 | |||
8b80910d70 | |||
a5ff655eed | |||
cc9c63c33e | |||
87eef72289 | |||
8e8ba3d052 | |||
fea27b900c | |||
7ad91a76cd | |||
a62b674722 | |||
350f35b08d | |||
f405321abc | |||
0d077f6ce5 | |||
dffa6accb0 | |||
b5abcd5ae5 | |||
72a9e676c1 | |||
3658b396d3 | |||
537acab16d | |||
8c6fe91c71 | |||
3c344331af | |||
d14ce2a37f | |||
33d272d4b0 | |||
57f5c15670 | |||
487faa69c6 | |||
9148a1e564 | |||
4c3f5e1e1a | |||
b0bf0824dd | |||
dea5991e01 | |||
739932a280 | |||
1f8bc5b490 | |||
753ffd401b | |||
0d1bab45a0 | |||
17cc439de3 | |||
5d03e300fb | |||
a20408bed1 | |||
ed0ccd6f13 | |||
bb1138efb5 | |||
82b36aaca7 | |||
688044429e | |||
7bbfc8e6d4 | |||
85513aa5c3 | |||
67254cc30c | |||
b055844973 | |||
9ba03848f2 | |||
5b96ab89fd | |||
6a4d8f7404 | |||
219d03b8dd | |||
523654f2eb | |||
b9b8cb9f63 | |||
94f2cd4257 | |||
26248774c2 | |||
99299ba06f | |||
6e42eaa26c | |||
ae7b621e3d | |||
f2ced20c42 | |||
e4f256d5cd | |||
ca1dac4cc3 | |||
8fc2729fab | |||
24c19efd52 | |||
a3edd829a6 | |||
9ec475fa40 | |||
aad06c583e | |||
f821e35cb0 | |||
14313291d5 | |||
b818352a04 | |||
c0c34fbb41 | |||
b372dc21d6 | |||
3d576cd06b | |||
438dcc4c6f | |||
de4ac2c830 | |||
f46443a5e3 | |||
69e90b7ff1 | |||
5089ec9826 | |||
372df93c18 | |||
1d2ddeedde | |||
4df2f1f756 | |||
f10c1c4730 | |||
92b556e54f | |||
b46ae7a651 | |||
9f3a3c5f51 | |||
b5071237fd | |||
1d2bebf17a | |||
9086822b94 | |||
d90d3c5a0f | |||
a3203e5775 | |||
5f24b41250 | |||
b577c0adb7 | |||
a9ad0fde9e | |||
9974b6070e | |||
bd5e4f3d94 | |||
e0adb1133d | |||
3cdb4f5b2a | |||
248401f534 | |||
1228a06a90 | |||
b5cd215643 | |||
7604667b55 | |||
3a278d8079 | |||
adcc484528 | |||
798553e96a | |||
068b717a75 | |||
785cf597ad | |||
ee70fe85c0 | |||
2e31816979 | |||
e4237c9511 | |||
0bc6967dbc | |||
2301769419 | |||
42c5f732a2 | |||
2428b564fd | |||
bb0e96a163 | |||
bb733c5811 | |||
ffeaf55c4e | |||
a12bb1d9ce | |||
313f2a667e | |||
d5d0be5824 | |||
3fa28bb46d | |||
eb90fab640 | |||
099d65032a | |||
e96feb36cd | |||
eb6d01c21e | |||
03d7dc8971 | |||
09d5f5a083 | |||
1a41b3fb64 | |||
f958550061 | |||
1e8e7ec4a4 | |||
83c4e38fa5 | |||
607d2fedb7 | |||
627ada56b7 | |||
9ce06fdc4e | |||
bb63ae6d87 | |||
a4182621da | |||
0534261759 | |||
c7baa66a4d | |||
1732606581 | |||
68cdd2c2c8 | |||
ea03b6c19c | |||
b83eb41df3 | |||
e6c68dc5bc | |||
76a953819e | |||
3a2ad48bd6 | |||
674d5bae8a | |||
5e983641b6 | |||
96d4665880 | |||
889ddf6a38 | |||
158e613e29 | |||
255c52db26 | |||
072c81177f | |||
e5c7fc93e2 | |||
5b7b217b9c | |||
06cedaef4b | |||
6972e8a3db | |||
18ba0148ae | |||
dea019ebdc | |||
e27e93aa9a | |||
c9ee7d477d | |||
e9deb13ce4 | |||
cdac238f6d | |||
e2c5e2c7fb | |||
0c3f819200 | |||
3673230fdf | |||
f2cb07ac95 | |||
484cf9d8a2 | |||
5b20be8cfd | |||
4dbe622a4a | |||
9a4dec57d1 | |||
f5c5178f95 | |||
727cf84080 | |||
80a257e85f | |||
ad3c15df9b | |||
c665bd2321 | |||
948bae9f95 | |||
a1c10b4ea3 | |||
f36df81d9a | |||
2fd9eb6c68 | |||
8894d14130 | |||
4039e74a82 | |||
0af3faf6ff | |||
0520b69c18 | |||
e11a775bed | |||
b4ed4623e1 | |||
9ee9653c7d | |||
e55a16d917 | |||
3458a0b22c | |||
ddcfa735e0 | |||
3370240541 | |||
c0cec4716e | |||
08b239e87a | |||
84132e794a | |||
425d70f261 | |||
420954ed00 | |||
45edd330f5 | |||
6a0e2bcad3 | |||
d67d3e0167 | |||
cd4f3d9a66 | |||
5c6db35c9b | |||
887bea4328 | |||
def5095d77 | |||
ab66662ff6 | |||
2d84433a62 | |||
b8e61787d4 | |||
669825a35d | |||
31b25ca169 | |||
a6ee92fbd5 | |||
5ff1a59a99 | |||
4f65eb4d65 | |||
39328c7368 | |||
2f5f3e1b51 | |||
022285806b | |||
bb60c2ac48 | |||
a4ee1e9805 | |||
bf0a8c1e62 | |||
d2b10ef4e6 | |||
9f3fca8fd7 | |||
9404819dbe | |||
d959f5096b | |||
bd3710a60f | |||
3d43f3a2b3 | |||
6194c156bd | |||
850c26dc13 | |||
eda0f7327e | |||
bf597495ff | |||
20025f254c | |||
ec76acd3a6 | |||
1e2acfb296 | |||
2bd4a680ad | |||
4ce504a1e1 | |||
d2f071b8b2 | |||
fdbd7b977a | |||
d19961b7a0 | |||
c156254600 | |||
9b5c6ece90 | |||
bf91efc756 | |||
a253fd5001 | |||
52af129c8b | |||
3942463ac9 | |||
ff572eef7f | |||
2740dfea87 | |||
324112b73b | |||
1d7dee8314 | |||
2d23819944 | |||
17f3b4125b | |||
c8a1024e24 | |||
9a2d2e2d89 | |||
b7af234427 | |||
a374e351e2 | |||
562f88555c | |||
167c5297fa | |||
b281d09694 | |||
853a0ac5ea | |||
ea948cfc3f | |||
fdd13390fb | |||
b2f6f8b3c1 | |||
cd12162b6f | |||
79717d1d64 | |||
e56cbf0baa | |||
05232414ad | |||
4bbc7d9662 | |||
3805b7f287 | |||
63620409a9 | |||
ba423a79e3 | |||
8806ba76eb | |||
9e73260230 | |||
c0125b83d1 | |||
1fa297fb73 | |||
57557748e2 | |||
8b79212a6e | |||
f4af4ec4dc | |||
2e150f4bf4 | |||
4f4aa051c9 | |||
da1dd7448e | |||
0fd47eeee0 | |||
54c9d7283a | |||
848db5f7de | |||
5fb32fe0e9 | |||
adf5b4ca0c | |||
16bfb1dbfe | |||
e5421b8a9f | |||
f9f1a22e3b | |||
9533809631 | |||
6d7c11f1b1 | |||
0286c72256 | |||
763aaa2926 | |||
ae4af7dd13 | |||
4ae2ea32e9 | |||
434298cba6 | |||
a2fa688cde | |||
895462ac7f | |||
e883714446 | |||
e1a235b4e8 | |||
ffa2c59df7 | |||
3f19dc55fa | |||
66c2148a63 | |||
28850f534c | |||
c40c11a822 | |||
b334e1aa00 | |||
b48986bfd6 | |||
ced63baed6 | |||
880635d615 | |||
d9f8c8d3b1 | |||
8155841a1d | |||
30f83d8f3f | |||
96c86160df | |||
b7ea128132 | |||
4bee8e9bfe | |||
bc195e771e | |||
0bc3e94052 | |||
3eb3523b52 | |||
8e2f84a989 | |||
143ec7463f | |||
4a5fd08e51 | |||
0306635a45 | |||
0a4d32cdb5 | |||
d590992d1d | |||
e8766946dd | |||
8c35189b37 | |||
e6390cde97 | |||
db976a6408 | |||
031c3ed055 | |||
cb391f08b9 | |||
5387a6287e | |||
0e4544b2da | |||
e0cbb7bede | |||
ed45b73274 | |||
cadcb586a7 | |||
9e31270459 | |||
dc07f046f2 | |||
5032bbafb1 | |||
1540bfb3a1 | |||
f3f5851118 | |||
9810edcd1a | |||
e334b9162a | |||
836c676057 | |||
1abadd9c5d | |||
e8bd1d8237 | |||
8a7470500a | |||
75689c665d | |||
d84f4f676b | |||
c97b859963 | |||
6b8f4ee1d5 | |||
3532789c35 | |||
267905b5e7 | |||
1626bd7a18 | |||
7106830be9 | |||
3b1946d65c | |||
6dedf4d44f | |||
fe5e2584b1 | |||
8fae38deca | |||
7f8e322e9c | |||
4d0f76f9e8 | |||
5d2b42960b | |||
0098dacdff | |||
51666fbf0e | |||
defb9120fd | |||
11ec72ce8c | |||
f67bd69ecc | |||
db2c29a6e1 | |||
e22e522245 | |||
7c8f4c0405 | |||
01ab21e4c0 | |||
534a2912e1 | |||
1456f4e227 | |||
63e11451ba | |||
7f80674cf2 | |||
16f4ca5fbf | |||
701ba59bd8 | |||
8c6705bccb | |||
e4542c4ac4 | |||
45eea1d6de | |||
4aa94d5a13 | |||
b0253e11bf | |||
1a4a3714c7 | |||
999090dbdb | |||
13e3b515c9 | |||
b6062a94b9 | |||
d0b26e9f69 | |||
d6ae34929e | |||
a51c9d2b2d | |||
6c45ccc73d | |||
6459c7bfad | |||
e6c1b0cf54 | |||
c8558810ad | |||
b0eb0b1de7 | |||
6bdf31efda | |||
3cd2971cec | |||
58784ebbfc | |||
de24a6e71b | |||
8c8a5a4f5e | |||
7f41a1ef09 | |||
15e1169f62 | |||
de92677b69 | |||
377ed95130 | |||
1b1c7ad3b1 | |||
e4e0fb0f35 | |||
bf0cbf24e4 | |||
7d454a4c7b | |||
680f1470cf | |||
1854fd307f | |||
6239f9da75 | |||
40e39b82e8 | |||
c71e671311 | |||
2ea6eb09e6 | |||
55c39a12bc | |||
14cb65eb6a | |||
a753459a6d | |||
bbce4451aa | |||
1e378dd986 | |||
3db2b60b92 | |||
2317a7df55 | |||
c53fcde12a | |||
4be5eb39ff | |||
5ef31a96ea | |||
0d017c30e2 | |||
92d85fa8a7 | |||
c2a0daedeb | |||
51642bc4cc | |||
c821208b5d | |||
a3d536bd51 | |||
f7262d12e6 | |||
bec888da19 | |||
2e6246e385 | |||
a9a0bf01ad | |||
8dd3c76fa4 | |||
a7c22399d8 | |||
04cb8a2fe0 | |||
494739f771 | |||
6fbcc9a244 | |||
d016f59867 | |||
88f8f3938c | |||
1322fd97f6 | |||
7f617df4e8 | |||
b02542f3be | |||
5fd620556e | |||
218d64d8df | |||
e8291eb00e | |||
f8619e382b | |||
83c35328ed | |||
f548d78907 | |||
5aca8b41af | |||
a7b6f3fa19 | |||
afb989d72e | |||
12c96c7a74 | |||
79bfffd77b | |||
58d68e7e31 | |||
499352e51c | |||
03fbd51fab | |||
bd73cac1a1 | |||
0c43fda86d | |||
a64b8fb310 | |||
316d39f24c | |||
265e2930f1 | |||
9511cf8d8a | |||
b86f0a7d9c | |||
19be847624 | |||
15e45ac4ec | |||
86572635df | |||
4a5c51d7a3 | |||
8530cf3535 | |||
eec54831ef | |||
a41e98910d | |||
be985466a3 | |||
98fb46957a | |||
2abc35058b | |||
35f97a6013 | |||
b8d509eb12 | |||
d6f13be95f | |||
4dad27bb76 | |||
efe1686c05 | |||
09462e6877 | |||
612a0397a7 | |||
3576ebd14f | |||
2a190d579c | |||
67abc107c5 | |||
9ec2052428 | |||
657423207b | |||
19aaff2345 | |||
8873c51f2b | |||
2ba24ba56b | |||
52f5d21480 | |||
0405cda9d6 | |||
b422e79896 | |||
181d4d5ea4 | |||
f30ddbf175 | |||
2c3b8d8925 | |||
2e2c6aef83 | |||
e511538ba6 | |||
c12e08ef01 | |||
0970944ee4 | |||
4eabe91cee | |||
cf747f1e07 | |||
e5a1da7136 | |||
27b6cf436b | |||
e4866a8265 | |||
d90cc02e5a | |||
23a1a8e3f5 | |||
b8f1c0df09 | |||
ed1f249aaf | |||
eef7539c2d | |||
1bb35bf545 | |||
2b9cb4a257 | |||
209cff8888 | |||
9e253ac7a3 | |||
27c5b16957 | |||
2f1df3be7d | |||
bb4a28ecd8 | |||
54c20b26cc | |||
4a71b952b6 | |||
3d7f628014 | |||
c63529ea99 | |||
d43bdcc1a2 | |||
a4aa6c5ab9 | |||
6d3e1bb40a | |||
9428347cb6 | |||
618666abf1 | |||
9423bc4ea7 | |||
95b9e4dfd9 | |||
61c6a2ab57 | |||
c89f7aaaed | |||
c2d72e71aa | |||
af93cf2adb | |||
7a75a8c254 | |||
0aa7dacbca | |||
9d41a52d3b | |||
c943303a45 | |||
b2a5b3c3c4 | |||
495d4b82cf | |||
ea2a200302 | |||
c531b26821 | |||
cade6c6c38 | |||
c56821300a | |||
346821f0d6 | |||
0da97c5da3 | |||
f0e013e1f8 | |||
8a144f3c35 | |||
f48bb5a40a | |||
3abde67671 | |||
59b2e2dba1 | |||
479f21f4f3 | |||
4a0f10ea99 | |||
9a24e4ade1 | |||
4691e896a1 | |||
869411a977 | |||
68bd40d2a4 | |||
cb8fe24a77 | |||
eb65949b69 | |||
fdf6f68624 | |||
d0e01768ab | |||
fd3d389557 | |||
3d63e12c9e | |||
ac6770bdff | |||
2ad2ce6c3b | |||
fcbe1dd8eb | |||
df618d1aa2 | |||
b846f16e6c | |||
51ab9746de | |||
ae10d0c7fd | |||
a443426d83 | |||
f2aa4d4484 | |||
4579dc9385 | |||
8ef8c97072 | |||
84fcd1c1b5 | |||
d0e6bcd784 | |||
1142ff884e | |||
29080e9d7d | |||
04c3191795 | |||
9d75225bd5 | |||
ce85bd26df | |||
ba0e46b465 | |||
5616b7550f | |||
fcd6159b42 | |||
02e5e1bc1e | |||
6d83a00728 | |||
d697c2ac9e | |||
c917aec401 | |||
89c1b94a12 | |||
46b9760179 | |||
ff66e66f21 | |||
b1f62f74cd | |||
a0d0f1f98b | |||
f08f064bc6 | |||
20d653798c | |||
a9e08dd587 | |||
5dba4a2201 | |||
c964870416 | |||
cfbf081cac | |||
bad429e853 | |||
8ce7466dc1 | |||
1ffa067d5f | |||
b595763446 | |||
e7180ac82a | |||
1d3c4b6f90 | |||
891809a13a | |||
67eeb4b69a | |||
f6b157167d | |||
d768314f03 | |||
3ede0a50f0 | |||
8828251204 | |||
019788670e | |||
3285f24fe9 | |||
c7d0537bf9 | |||
2254a5960e | |||
af4a06f91d | |||
3e95b59be8 | |||
bb24ec4a9f | |||
5a4b675791 | |||
5328303c32 | |||
3f6212e799 | |||
1803d3ee2b | |||
421a2b0cd9 | |||
533ae0ea89 | |||
df5add04e2 | |||
174e743904 | |||
76a6d94bbe | |||
6d76771b16 | |||
fca066fe52 | |||
aa3c0346c8 | |||
bafec0d974 | |||
f3f605a90f | |||
a9a9f26aa0 | |||
4eb143c265 | |||
e597b2177c | |||
2ae4501de6 | |||
f1029fceff | |||
b67d3a504b | |||
12a5998a07 | |||
fbe2096098 | |||
d7faa0a0fd | |||
8bd54493a3 | |||
225243ba93 | |||
21bd35accd | |||
4acca4c6f5 | |||
c106ff8290 | |||
296ba4606d | |||
54dd602be4 | |||
9cac8d36ad | |||
d407e9ffba | |||
26025b564e | |||
4cacc2a9e6 | |||
16ef405670 | |||
642aad28ac | |||
e5feda69c8 | |||
aa89d1dffe | |||
662f269a94 | |||
6f80100ee6 | |||
38d3154ddf | |||
e16a718bde | |||
a40429e219 | |||
e5602a86a2 | |||
7d4d8bff93 | |||
d028ebfdf1 | |||
a5aeb2a3c1 | |||
410bd5ab9c | |||
f4823d962a | |||
9aa35f3488 | |||
d2a7e5dc4d | |||
f7cb44c343 | |||
ae67cc8a51 | |||
454d628f93 | |||
e60e8dc9ba | |||
382fe5cd47 | |||
86e53552c0 | |||
6296d63197 | |||
ed1a7bb887 | |||
273bc78db3 | |||
261a3ecee3 | |||
8f0ac61634 | |||
5a7b275ee3 | |||
54e106ec74 | |||
51690b47a3 | |||
9ab129ba89 | |||
b39a67534c | |||
2d717cbf01 | |||
c4f284aaf1 | |||
e40a9089e0 | |||
8cf849e590 | |||
03e113b063 | |||
d9305b1e63 | |||
182fa7d803 | |||
4dd41cffe3 | |||
9bf3df1e87 | |||
2e08c29c64 | |||
75afd30008 | |||
7652d2c7e3 | |||
7e6a2d08e2 | |||
c1dbe235dc | |||
eb2ccf06a5 | |||
e202f24592 | |||
d11f87f0cc | |||
8f54ec4f4a | |||
64534efe71 | |||
1235ced355 | |||
23d383be67 | |||
fb90ff2fbb | |||
4706aa95e6 | |||
8981414705 | |||
7ec978fcdb | |||
d58803a058 | |||
fe6b7dc1e3 | |||
c9f0988b95 | |||
cd9a52706c | |||
bfdb1b4af9 | |||
e5174b4a29 | |||
8feb60c30d | |||
6bd7fb64ab | |||
b9602243d3 | |||
b7a930ef18 | |||
add206ae2d | |||
28ce095fb4 | |||
13952a4b79 | |||
05ec398346 | |||
dea2dd52be | |||
debe3cda4b | |||
5b5aa2c721 | |||
e201ddd74c | |||
4a1580169d | |||
001ca7de60 | |||
184be4e27b | |||
7652645dda | |||
ef6016857b | |||
e449ca2c95 | |||
b0f00773d6 | |||
451eee549b | |||
77da261fea | |||
e23c9ee608 | |||
37cb87a9c6 | |||
211db8e0f0 | |||
d074d60dad | |||
0bff5e2236 | |||
dca986eb2e | |||
326eb1135b | |||
b2f7b4e6b9 | |||
5129d6aa6b | |||
a8cf334616 | |||
3b4d06a1e5 | |||
c7969476b0 | |||
7bf24df03a | |||
5ef41294e4 | |||
2eb68655c7 | |||
23049439c0 | |||
ce6cd40b92 | |||
c36b0c16b0 | |||
c15f182377 | |||
165cb345b4 | |||
9b6d2beb4d | |||
722c39a6ff | |||
e344749d2f | |||
fe782bc3b6 | |||
d372cbad74 | |||
1e1198f4ec | |||
5effc96cff | |||
b8d4a1be05 | |||
36a25e6efa | |||
1240e7914d | |||
e4683b1ea1 | |||
749c22a0c3 | |||
6867774627 | |||
80944972e9 | |||
c1f608c0d8 | |||
4dfbb08db3 | |||
ead1dffd98 | |||
5a16e4d132 | |||
a89491e343 | |||
b1b00ae886 | |||
cde5bd87d8 | |||
3231d5d179 | |||
03e49ea2bf | |||
7d3eef092c | |||
30d0410b49 | |||
eb2a887f77 | |||
e77b8d29cf | |||
490ec299c5 | |||
e47c2aa24d | |||
3eb9fdca6a | |||
a4173a93b7 | |||
ad762cf239 | |||
5a478607dc | |||
4abc6eb387 | |||
c313bba288 | |||
73eaf97afb | |||
8d25df5d4e | |||
4a05f16050 | |||
3ef1423263 | |||
898652189b | |||
2976edf333 | |||
248be11e4d | |||
19ec8c36e2 | |||
90d989e358 | |||
19eea3a615 | |||
7b81b9786d | |||
292d302a3d | |||
557594e34d | |||
48393c3765 | |||
022cd666eb | |||
2d0eedb132 | |||
5d3d664ce6 | |||
d1c12d8294 | |||
947a67fcd2 | |||
9b9540b857 | |||
a3b748ffe3 | |||
9a3a7a3444 | |||
5c8ca15ee2 | |||
cd3807a3d8 | |||
2a884d6f38 | |||
6efeb60c41 | |||
dcdab5b218 | |||
288fbda54f | |||
03bc91fd1e | |||
1c5cf29540 | |||
631ddc0af2 | |||
1d593df5af | |||
1d3a8bb7bf | |||
0dc9c183b5 | |||
05ab43f309 | |||
f4153ade92 | |||
44e84b46b8 | |||
3fe71e7bdc | |||
5d4d8a3422 | |||
f06199230c | |||
da9a6b835a | |||
0afc2cd2cb | |||
9e2f7fb048 | |||
3fa694c65f | |||
300d84c5d8 | |||
efed00f58b | |||
99c4ebe046 | |||
699231fd92 | |||
c18f112f31 | |||
605d04580c | |||
143211f276 | |||
4ca152da7c | |||
1c1f69fa50 | |||
147ccd6c96 | |||
c8b9906ef3 | |||
cd94a9fac1 | |||
20a9472ee2 | |||
c652a2f122 | |||
ce174d507d | |||
f66b1b644f | |||
5b460f0b4e | |||
ab8d116f11 | |||
0535e9c68f | |||
93b52fbdb3 | |||
aab1eb0d36 | |||
c07fcc171c | |||
8e5b7d2578 | |||
37b1e9037f | |||
7c0999ac9f | |||
5ce1c9d77f | |||
14dcb58afa | |||
04068025c6 | |||
2cd0c7a407 | |||
f3592c4782 | |||
1e5934895d | |||
0f5d932726 | |||
4125726be9 | |||
bcb692caf0 | |||
ff9a1a1f55 | |||
faef6d82ff | |||
d3a123373e | |||
7c66f024ed | |||
20c7259174 | |||
16a4c072a9 | |||
254e8d48f2 | |||
52fe374aaa | |||
f776725096 | |||
6e864c2631 | |||
4221554dc8 | |||
6b50fdae43 | |||
7bae6b2e8f | |||
5c6a0f22c0 | |||
a9b755fa1d | |||
72bdf9e0d7 | |||
cbf8b23385 | |||
4aacd0d23a | |||
69202ed752 | |||
aa762821ce | |||
8a7bb6bc5a | |||
35cb4d4cc3 | |||
8ceda3eab1 | |||
cc1233e8d5 | |||
70883c0869 | |||
fe9de98dd1 | |||
ecde91ff25 | |||
240ad49a43 | |||
10adb23e71 | |||
c2fc099439 | |||
723a38da68 | |||
74037fd605 | |||
e917796fce | |||
5661798601 | |||
a8adac9c5a | |||
c62018f984 | |||
06f2d4425c | |||
090da6cfb6 | |||
28dbf10a31 | |||
7a66d0feda | |||
e23ddf118e | |||
11d6588249 | |||
30db0cd4f4 | |||
692b57a1ad | |||
7505c65401 | |||
54a735ffd9 | |||
6a20d9036c | |||
c338846d63 | |||
c419ad68bb | |||
51c486c15a | |||
306ff3d919 | |||
d667b8ae8b | |||
72d728eb47 | |||
801ab862a3 | |||
d7b4dd2d4c | |||
1d3f74c8bb | |||
c3f73c0de3 | |||
1fc2fc7a11 | |||
13ea1898b6 | |||
586303f47e | |||
ce86a838f2 | |||
21e69251e3 | |||
a42323a527 | |||
14da3023d8 | |||
7eb5f57478 | |||
2cb443df8a | |||
961769ebd0 | |||
3266cc8e3b | |||
3dec14b89d | |||
a67f989dda | |||
2d05464b17 | |||
a39082e565 | |||
d1f567eade | |||
b9fdd54538 | |||
7243aec213 | |||
1fb582c35d | |||
c6da0409b0 | |||
50d4b55f73 | |||
c6a7e90c1a | |||
5cbc2e96e7 | |||
23a96c07ae | |||
7a787fc945 | |||
ce43de0c57 | |||
eaf47d3739 | |||
5eebdb6774 | |||
51db1593d6 | |||
223c71ce8b | |||
127afdb5c1 | |||
f34706f9f0 | |||
f76ce54109 | |||
f67fa6a5d6 | |||
5ad6d77973 | |||
69d1acc797 | |||
0c0235a56e | |||
7b0558dc8e | |||
77be2fa9d5 | |||
8f320337e0 | |||
2327b97fa3 | |||
a411a6a81a | |||
d66f1f5513 | |||
7503fde48c | |||
20c8916610 | |||
5a2a933b64 | |||
ffc0e996db | |||
a02ad104ee | |||
625876ff07 | |||
b935275fd9 | |||
4c032e9e6a | |||
1b770c66cd | |||
96259dfb49 | |||
e4d9e3e22e | |||
fbfab88257 | |||
708f8b49df | |||
323e5e14a3 | |||
5bbaa48b49 | |||
cd91e48713 | |||
7444bd06e4 | |||
0017e687db | |||
5865fd5022 | |||
4b941a5145 | |||
3c5d809cf9 | |||
ba101015f6 | |||
6999abe1ca | |||
cb295e20d4 | |||
c6df43363f | |||
81cec36b68 | |||
47c1ffe53f | |||
90a9051827 | |||
8bea3dd21e | |||
e164b1f169 | |||
383765f5fe | |||
25a59fff4a | |||
03af471f65 | |||
d189deefb4 | |||
e957180618 | |||
47d8d3cdb1 | |||
f364451a96 | |||
2c51b31c62 | |||
0dcf240faf | |||
88bc1c64d2 | |||
84bd8a6e98 | |||
0d657fc646 | |||
64b85ac1f9 | |||
81c1cc6728 | |||
098879585a | |||
fc91077430 | |||
b71a04943b | |||
dd4fb68e5b | |||
a085a2a557 | |||
fa84e34def | |||
8c3f377fc0 | |||
f9d14c64ce | |||
fc687f9fc0 | |||
57071d7bc8 | |||
324a246189 | |||
a706f81760 | |||
ab3aab9c22 | |||
fd2e55e444 | |||
04b8eafacb | |||
e2d0b7c5f7 | |||
db1a124ffb | |||
0dcfbe8581 | |||
0e1b872777 | |||
ed5b159fb6 | |||
9b7ca76b99 | |||
eeebb99ca3 | |||
e2b18cf9db | |||
955ba91770 | |||
c0e9f91bdc | |||
259f0b5aad | |||
02419dcdd1 | |||
4a66c91cac | |||
48ac996d77 | |||
82b4debcac | |||
5f5f71bf37 | |||
ae33fc3031 | |||
f63a9ed1a0 | |||
9843f66bb6 | |||
b2c1846ebb | |||
8e5a9251d6 | |||
3a59e2a5c4 | |||
38ff3e5e89 | |||
1f0653985a | |||
a4fa61e5f6 | |||
b68eae6f7d | |||
2d7c5cabab | |||
42e731369e | |||
7d2627551b | |||
f4bde164bf | |||
bb751793c8 | |||
c68141119c | |||
163d1a195d | |||
6de4f6a3ac | |||
89a52703f6 | |||
4f7eeea14e | |||
bbddd72780 | |||
ac099aa513 | |||
ece5401121 | |||
fd7b11518c | |||
9a70b4487c | |||
19af02e71b | |||
619aa05e14 | |||
cc60958b30 | |||
bd2f35a241 | |||
cf78987fab | |||
f8e6b51e9d | |||
2b1436e303 | |||
cf772bb9e0 | |||
fd75008499 | |||
e113c12768 | |||
3acda5b342 | |||
bbea9d7a27 | |||
b0125adfe9 | |||
d3b28a98be | |||
c679654ada | |||
26f3cffe5c | |||
8f0d82d219 | |||
6fec929656 | |||
ec68d2a0e6 | |||
f6afb9a3f0 | |||
70bb6d999e | |||
e9074a8ec1 | |||
9b730e784f | |||
57852821f5 | |||
87061ecfc0 | |||
d555d2f3f6 | |||
3b3fac98ad | |||
285a30f67a | |||
fa83304697 | |||
e42ef4b2f8 | |||
cc3908cdb3 | |||
e3def45c83 | |||
4fe4cdb7bf | |||
11a9b10a54 | |||
5164402e27 | |||
20f32e94a8 | |||
35aad4ebf9 | |||
d60e4f8fe4 | |||
e5a5eb3547 | |||
fbb4b13898 | |||
573f1ddf76 | |||
ead0f284f2 | |||
6ff659fb99 | |||
194c0f14cb | |||
7ab78fff3f | |||
eabe24bb3e | |||
c01fae5fcd | |||
c088e0fd55 | |||
cb1dbe7662 | |||
03f8d6693d | |||
6813a6ea63 | |||
4cd18a1b28 | |||
90907c6306 | |||
c67b2be9d2 | |||
8d6c5dcd65 | |||
e5fa6fa55a | |||
748c92436f | |||
e98c6e69d4 | |||
c389aa0b99 | |||
8696710ad1 | |||
ce3bf91b29 | |||
2f5f397d33 | |||
b196bad75f | |||
b97dfa841a | |||
31cf2671f5 | |||
56c8e43ce8 | |||
d7dc70c679 | |||
ed0d7b75b5 | |||
7649f88173 | |||
e9b8035eae | |||
46486704ab | |||
a6cee23591 | |||
33b5ade2b1 | |||
0299eb1d24 | |||
4f9ea39554 | |||
a2a49636e0 | |||
609fd131eb | |||
08a3fb76fb | |||
d5c38ef336 | |||
03d2b6eabe | |||
cbcd59c996 | |||
c5dc7475a6 | |||
40dff0381b | |||
39a1834a75 | |||
84694d55ad | |||
605920b421 | |||
c2a420a291 | |||
037a77a573 | |||
b366e5dbf7 | |||
a277072968 | |||
5523b554f1 | |||
6ae9dee982 | |||
dae4577b43 | |||
6ac9c74028 | |||
a7ef9c7c27 | |||
08f57558da | |||
28694859c9 | |||
be7cef29d8 | |||
e914c84ad3 | |||
193b209c92 | |||
d5b25dde3d | |||
931aa297cd | |||
fa10249893 | |||
14a708b3df | |||
d9f535f98a | |||
e51cb43283 | |||
bbcdd5ed0d | |||
3c13d6c195 | |||
61d89d1777 | |||
bede4a3a42 | |||
befa436087 | |||
59cf53e083 | |||
76a4e9e520 | |||
af635cdc0d | |||
cbf3b3e9ea | |||
b0be248ca5 | |||
2828ec76b4 | |||
de1f94a596 | |||
d16d4d83ea | |||
ff8adbbd37 | |||
a47ba2df3c | |||
909fc71543 | |||
7f13f6f915 | |||
f58fc9b531 | |||
82649dad39 | |||
7e3cda904a | |||
c921b2ca7b | |||
2afd02152d | |||
f3e9e2ec5f | |||
d39ae86915 | |||
51f0c2a5f8 | |||
003927418c | |||
da92cabe4c | |||
45a58e1a39 | |||
0e1a6a3d5f | |||
34969519d4 | |||
4f235e1d62 | |||
7d0dc49435 | |||
8fed8f77ad | |||
1c2728bbfb | |||
fd543bcee1 | |||
24b7705094 | |||
6b96f9b446 | |||
933dc6be31 | |||
d6e3fb46ee | |||
efc05edca3 | |||
aa3d384f47 | |||
a5aa5cf059 | |||
ccd8859d7f | |||
a28399e31d | |||
61f63a9996 | |||
de93c5c9d6 | |||
94865815c7 | |||
33754933d5 | |||
560b6db480 | |||
4c71167535 | |||
707484709a | |||
274be7c1bc | |||
3f176a6b6b | |||
fc8a5ff95f | |||
25f84d000b | |||
31b7826dce | |||
2d4aa52fa5 | |||
eee8008bb2 | |||
a5ae509f9f | |||
8f117b5079 | |||
0b5d0349d4 | |||
8a0660cbd6 | |||
f7a0b91ec1 | |||
1ecd1c1e54 | |||
fccbbb6fb7 | |||
d1886b039e | |||
79c61f01c8 | |||
e50c9266b4 | |||
fd27bd94e2 | |||
05f99f3855 | |||
31ef763c05 | |||
c0abcbea24 | |||
a73383cd87 | |||
951bfeefb1 | |||
fc7125b8cd | |||
26bcdbc766 | |||
fb1fcbe0b9 | |||
2c45f803e4 | |||
fbdd2fc470 | |||
0558631982 | |||
63e1c5807e | |||
a3cc1f2ef0 | |||
5318684e5c | |||
b3b9651cd8 | |||
86e528e5df | |||
c46a69e1bd | |||
9b0d1a23dc | |||
db038723f4 | |||
a193e1cbf3 | |||
493f1b98c2 | |||
926b60df3d | |||
d8a162fb6e | |||
4cf3249e0b | |||
407f26b1dc | |||
0159588eed | |||
6f7be7eb09 | |||
09a53718bb | |||
5655f22397 | |||
791d0abb34 | |||
13d9930955 | |||
c4f40d68e9 | |||
9951370321 | |||
0119ad452b | |||
3d3016fdca | |||
262798d577 | |||
cf206e64a7 | |||
5ac4135a13 | |||
5176eaf4ba | |||
514417e888 | |||
f83e85dc36 | |||
9592a77cff | |||
33a893ba31 | |||
f89cdadde8 | |||
7d2aa28e1f | |||
9df4429fc2 | |||
843a2491ef | |||
d64fb15ac2 | |||
3671e7f18c | |||
899bf98f45 | |||
4230ba513f | |||
18f1b4d8c1 | |||
75776687bc | |||
b5ebd14589 | |||
67ba64b0a1 | |||
b26e8311c1 | |||
0033aab03e | |||
1037fe0b14 | |||
6c688b9684 | |||
601e17ed0f | |||
ad86c16bc9 | |||
791db983c7 | |||
d7a7382d00 | |||
e842a00402 | |||
78a8c8c1be | |||
a7c093a0eb | |||
86956c1e7b | |||
54539001f1 | |||
4321cbf41a | |||
8d9941bfd2 | |||
f9e38deee7 | |||
89fd044b00 | |||
039f88d14c | |||
d3f9eb38a9 | |||
768d97ac6c | |||
154078d46f | |||
d74c6a30c8 | |||
1407d5be8d | |||
721c06e157 | |||
a0265f18d9 | |||
8948475cad | |||
faed5349fb | |||
7bcaf956e7 | |||
31c2a80758 | |||
150e4b842c | |||
b970f64639 | |||
08bd13b2cd | |||
6e3d6125c2 | |||
143d5f69c1 | |||
156ddd24fa | |||
cf2c147f4f | |||
ce1903b2fa | |||
ccdfe5ac86 | |||
b0ef98dd63 | |||
5c8e62bd90 | |||
6674d76d6d | |||
dea747a9a9 | |||
a32ace1dcb | |||
4785f0a4dd | |||
8249d8a0f5 | |||
234bc30369 | |||
b7a081b9a4 | |||
88c925017d | |||
a3c2a9ac61 | |||
7cad6302b7 | |||
4b34090376 | |||
ac554a27b6 | |||
e1ea7200cf | |||
802fec6bf3 | |||
67aee9bdc6 | |||
975ad2f8ab | |||
b0814166f5 | |||
8f397865fd | |||
8ffa7525c5 | |||
6048a26511 | |||
1a8a7fc27f | |||
64901dfc22 | |||
6a28497d33 | |||
ed1ec2300d | |||
edfde494fa | |||
a3cc573e4d | |||
44fe70ae44 | |||
d05a9295b3 | |||
7aa4cd8104 | |||
4a6088b6b9 | |||
d949680d5a | |||
0cd7380af0 | |||
a3afcd2a6e | |||
bd6c7a8c3d | |||
920955657d | |||
d975ea1509 | |||
ba5c49a8df | |||
9f6c7180b2 | |||
ef70f4d547 | |||
8c061b1f07 | |||
0aed8fdb5b | |||
6125a99381 | |||
83b54b7be1 | |||
047222b3ee | |||
2fe1ab83f5 | |||
5372058c33 | |||
a08261a798 | |||
869985f005 | |||
97b5c473c1 | |||
337db3daab | |||
10da82607d | |||
7f49824783 | |||
5d8bc73063 | |||
82675384c4 | |||
3dc663f4d8 | |||
2b0fcdf95c | |||
d0120f1427 | |||
ac34109da3 | |||
d5c96eee32 | |||
7b252369e9 | |||
9d48358f2a | |||
2dcd7db797 | |||
c267cf0e9c | |||
403820cf14 | |||
6d667e2d78 | |||
258a19fdf5 | |||
1a593a1ced | |||
b8ac57a5b3 | |||
b93f3ff445 | |||
5984edb7f4 | |||
603bd2692e | |||
2e61bdf88f | |||
e6aa73197a | |||
b2f9353be1 | |||
5cba59932b | |||
809340e629 | |||
bb6a188883 | |||
24674d354c | |||
e93562b1db | |||
f7099cf6aa | |||
d88f012d82 | |||
f96767d3dc | |||
6666786b7a | |||
eccbe8e018 | |||
aac87539ae | |||
a8995d2bed | |||
7f40698bba | |||
c4f4c3138c | |||
3b9c7db481 | |||
649f650da6 | |||
4c83265de4 | |||
ad7b62fa3d | |||
650df97e50 | |||
6f75125cf5 | |||
26c05a8d5f | |||
fc4e47cec6 | |||
c39f1341aa | |||
a39d1e0886 | |||
435f51a777 | |||
de2c12c1df | |||
ae43af999b | |||
14a10eeef8 | |||
180be49824 | |||
5faa756f1c | |||
06db29dd43 | |||
6d317937c7 | |||
522c990278 | |||
e584ebe7de | |||
1422bd8540 | |||
fe18e71538 | |||
e5699f674b | |||
203db44b4e | |||
69c5f5b9e5 | |||
5a16dfced3 | |||
cb46ef9e6c | |||
3b810e9b8d | |||
663dcecb8e | |||
fbb5671f89 | |||
47d348359f | |||
ab2f460f35 | |||
c77e3a9396 | |||
014c43f79b | |||
21fb3813dd | |||
9a039a747a | |||
17578a4615 | |||
abb68d6f59 | |||
3c443344a5 | |||
2887017d12 | |||
f2286fb1be | |||
bdd11a14ff | |||
18f6e5af4d | |||
83b07e0caf | |||
840a5ac4b4 | |||
4923311168 | |||
748423dfe8 | |||
2f4e610900 | |||
d39ec97b9a | |||
0d08bd3ad1 | |||
3343738bb3 | |||
373b0b7850 | |||
aa24da72b9 | |||
aecc5f3c6e | |||
3d4ef48ceb | |||
9bb74a17d8 | |||
b654dfb237 | |||
1bca8c81a4 | |||
4d35fd4ab3 | |||
bf5ea23bc6 | |||
b4c1f695a8 | |||
de3d966835 | |||
bcdb1ab1d8 | |||
63944792b0 | |||
3895b133a3 | |||
4371b81ef3 | |||
cd93a5ab6b | |||
d9a8443081 | |||
918d3b46f0 | |||
f53597845e | |||
e65a3efc3c | |||
d74fcad9f4 | |||
19b88fd986 | |||
12105ab85c | |||
723817e3f8 | |||
101fc51787 | |||
58a5f88943 | |||
2e35d0e178 | |||
319efbeb4b | |||
04e6833e22 | |||
748c882ba1 | |||
ab7d2959ea | |||
56d3485d49 | |||
119ab7b2c0 | |||
d1ea4e4fa4 | |||
de5ab80038 | |||
2d23f3e5d4 | |||
77d1580ee3 | |||
a20906bc12 | |||
ffbf70d72b | |||
caa3ff616c | |||
7a102ee920 | |||
8451f34302 | |||
e4bd8e3106 | |||
bc4945c584 | |||
fa96deb1de | |||
a27217dc62 | |||
2dfb637e2f | |||
9387c2c771 | |||
e7e8ed55c2 | |||
cf067ca51b | |||
1b7517c05c | |||
103b3b916b | |||
fa91174b1a | |||
10e3595a82 | |||
965beebc66 | |||
83ab1a3b7c | |||
7ac83575d4 | |||
831f73d715 | |||
245b4ebe63 | |||
060f30d0bf | |||
f84b2c5160 | |||
4e56ef636b | |||
59d0cf666f | |||
54cc574405 | |||
97d16523b5 | |||
80086d76a8 | |||
5bf1161884 | |||
f49954223a | |||
98d9efc8d6 | |||
59f338a0b7 | |||
e1eac5c390 | |||
4c818d0359 | |||
63d4ccc058 | |||
1b85ab8b54 | |||
906c7eb7ec | |||
2207d836f1 | |||
a9cd27e012 | |||
eb24cf5f84 | |||
fae396dc0d | |||
c70393c7ef | |||
a9da79cc58 | |||
4c57405945 | |||
ad8f347989 | |||
68595be323 | |||
69b855a1e7 | |||
6ea96efe68 | |||
499a231432 | |||
0054fe0886 | |||
c59798e9c4 | |||
80483ba76f | |||
5c792c9e09 | |||
fdae221ca5 | |||
ba165ddd4f | |||
14e4d2d675 | |||
d505771d96 | |||
d8c1c51a21 | |||
71cbe716f9 | |||
f4df850d25 | |||
4d538c61b1 | |||
17e6179fec | |||
b7b2f16925 | |||
a7f6bcf36c | |||
590ca4ef56 | |||
04726b3ee4 | |||
eb2b523800 | |||
73b461f8d0 | |||
15be593bbd | |||
73c89ac28d | |||
45679fa29e | |||
861e5b1530 | |||
d5019f61ce | |||
78dd1b0476 | |||
72d5c11811 | |||
aefb81b7f0 | |||
55cc32ce0f | |||
060fc46e4f | |||
4bb3d60b6c | |||
4222d24d51 | |||
6c76866f28 | |||
50be6595bd | |||
91136d2551 | |||
2e822c5878 | |||
894dca2eef | |||
48355129c5 | |||
edc9429e84 | |||
f1a222fbb3 | |||
40bbc5850f | |||
70baa4087c | |||
8e4f56bd52 | |||
3800780ef2 | |||
6e154f6cbc | |||
673b6d6733 | |||
6185b93b59 | |||
9bbaae9dea | |||
6c856aba48 | |||
33de4cccfc | |||
6a79c8a27a | |||
631deb9ce7 | |||
cb2dd464f1 | |||
dca376cb46 | |||
89d6c83504 | |||
2ea3baf36e | |||
3338dcac1c | |||
0b9a2ee8ec | |||
78ac1ee15d | |||
886e9ab511 | |||
3c80621dac | |||
6b4ff4ce2c | |||
b22aa778e1 | |||
1c440ed36c | |||
70f56d5920 | |||
8a1d5bbc57 | |||
956370592f | |||
afd479ac69 | |||
39a4be5641 | |||
70fcd053cd | |||
c9869922f7 | |||
8b6a333cd2 | |||
ae329e371a | |||
cf7c3c2bf7 | |||
3d21d2724e | |||
df64a93808 | |||
6068d384a4 | |||
3c0292f074 | |||
371acc84a8 | |||
cd9feccf6e | |||
f1f3dffc97 | |||
e4f298acac | |||
e93b030bfe | |||
64a7abe53a | |||
784a40e2ed | |||
9ecd27dc85 | |||
72ef23786b | |||
28da78fc78 | |||
c345e81902 | |||
1b39742919 | |||
bc33b32522 | |||
4671f08b64 | |||
9f6f74df59 | |||
872c99e033 | |||
cb6e8a6937 | |||
7c16f8f134 | |||
ad11b61af2 | |||
120b82ae00 | |||
7cf6c97d3f | |||
2262acf12b | |||
ca3f97c42f | |||
8731055786 | |||
e943c55a91 | |||
be05b6aa90 | |||
0b4d94faf2 | |||
9f8f677125 | |||
949d6bf584 | |||
9fc2d2b76b | |||
d9935ada9d | |||
b4076b53e8 | |||
53c81918a5 | |||
7c11736992 | |||
49f168b7b3 | |||
104092702a | |||
2ed8341403 | |||
e5a196918f | |||
907ae760e0 | |||
37f7c4e0f9 | |||
fe107cd23f | |||
a830c1e812 | |||
8eb85acb88 | |||
ea8f510eff | |||
cbec44bb73 | |||
ac44ed56e0 | |||
dbf2f99c4e | |||
3b04ca229f | |||
5b1a171d27 | |||
9138c6c70a | |||
f1092f910a | |||
ebc9ddfeb1 | |||
201b4d6ec0 | |||
3b375929c1 | |||
ed7031981b | |||
0eace936b0 | |||
0d70743a47 | |||
778a0f7e8d | |||
a8cf6ee8a2 | |||
06a150a558 | |||
c551e5cd0a | |||
776ded0b7e | |||
9e3d99ec39 | |||
6c9c7328bb | |||
2961a2ed53 | |||
12836b9f60 | |||
17cef99ce8 | |||
2194fe43d2 | |||
06fef563e3 | |||
c38eeddc55 | |||
84ec33afb3 | |||
4b30132d06 | |||
38942aef25 | |||
200e8330d8 | |||
86092fc955 | |||
50cd4cb3ce | |||
7c857118fa | |||
4e1b18e2bb | |||
5fe3c1c61f | |||
270bd98a10 | |||
02bf5afe0b | |||
c878f63f99 | |||
8083935b47 | |||
c7d11132e5 | |||
69442a49f1 | |||
5f9ef0ff62 | |||
0888cc4f97 | |||
6821a9a0a4 | |||
003e8a979b | |||
08e8050ca5 | |||
8d5c3c5cdd | |||
dcc4214dcb | |||
ded55a1440 | |||
e0ff03068a | |||
60c05cab55 | |||
9c480580ba | |||
f3c3f397eb | |||
f6c7f61ec3 | |||
aae5cce175 | |||
8a9bea4603 | |||
0e3f6acb0a | |||
bbe621109f | |||
35f47bdfb7 | |||
8ca0be5a4d | |||
b6bd7cce6d | |||
a7cbb3941a | |||
8957720c94 | |||
452915478b | |||
962c80fff8 | |||
aef06c7f61 | |||
52be5746c6 | |||
b2ff64733d | |||
85cf36ac4a | |||
5fda21373e | |||
1ada87ca31 | |||
0554565b30 | |||
315284d5f5 | |||
99b1e391a6 | |||
9b50e85d0d | |||
e394474dad | |||
7d1761de4f | |||
dfd4c967b7 | |||
71305461d4 | |||
04a29ece3b | |||
99dd6f3e50 | |||
8f6048191d | |||
ee0fa71605 | |||
475a68924e | |||
c0a544351b | |||
15201a927e | |||
efa567f965 | |||
e1df1c255a | |||
64e34d0ef5 | |||
2e12befb8b | |||
98eee27b93 | |||
8ed853a3b3 | |||
8fd4a816a6 | |||
b12c4c5fa0 | |||
6473da7114 | |||
bb78ae59d4 | |||
459f3c4a93 | |||
e014b30915 | |||
cc5a388106 | |||
5de93f8cc4 | |||
ad1b708da5 | |||
c7ff36b314 | |||
f367480857 | |||
475809b1a0 | |||
fce7fdb3b7 | |||
b2c72f1d75 | |||
f0ac7d2c16 | |||
7099a3b394 | |||
3e985d8554 | |||
f94e8c9719 | |||
bbe1442c28 | |||
3a248d7707 | |||
0bb1f16d2a | |||
0837756152 | |||
23236c96cb | |||
6ead5c3800 | |||
64db865e1e | |||
1b2399745d | |||
94acf60100 | |||
a4298e8c19 | |||
76985838c4 | |||
d24964e900 | |||
f4fde8f5f7 | |||
3461dd6464 | |||
560671b57f | |||
abf3962d91 | |||
f53a85fcd1 | |||
73730355b8 | |||
8827721605 | |||
2497413c60 | |||
a6537ef282 | |||
c92adc36c6 | |||
a64f71f186 | |||
0c766a2714 | |||
6b7c49431a | |||
4b37121b75 | |||
120c7b9730 | |||
1aa233ca47 | |||
14e6e492dd | |||
17bdf55bcc | |||
1ae6508a43 | |||
b7b6cef880 | |||
52b5c56da9 | |||
85ba9e96a0 | |||
b4e15cb27f | |||
068cfe5e3e | |||
c0449a633d | |||
7dfce5e306 | |||
fd53f7476e | |||
ceb541ad8a | |||
d92ced6c6b | |||
0847088391 | |||
a128685b83 | |||
749d26fafa | |||
485faf0141 | |||
af9d896510 | |||
1fc114fec7 | |||
e6938cef6f | |||
ffafd291ee | |||
f532759543 | |||
db3ba6db3c | |||
0a333f8476 | |||
738aaeed12 | |||
ce6c9c91fc | |||
7035b71ccd | |||
923a567822 | |||
9b24e9378f | |||
779f21a1ca | |||
73d70aa5e5 | |||
fc78eacf8f | |||
006af636e6 | |||
4575fda10a | |||
6c960628c2 | |||
00aa7deaae | |||
f722956864 | |||
8f520bff12 | |||
8398534fa0 | |||
e1fed90b71 | |||
5ba6e53379 | |||
d33bdfd50c | |||
4f5392eb74 | |||
064087a7c0 | |||
e13821ba49 | |||
c2b85779c3 | |||
cdfdad3e3d | |||
1f7992e5da | |||
4bad7d7c52 | |||
1fcf39d4ab | |||
a64e304d16 | |||
30c7cbba96 | |||
a7d324901d | |||
15c87dc0b6 | |||
0d2de4c421 | |||
da95bd6127 | |||
e31b5529b0 | |||
0836df6974 | |||
de4cd55adf | |||
6b156f2144 | |||
2b1efd9347 | |||
97dd10edc0 | |||
cc4e46d212 | |||
dc0671942d | |||
f79c8ab641 | |||
314fda7877 | |||
aaf77515fc | |||
b5f7b1aad4 | |||
d36974a47e | |||
5bd16f990c | |||
28d7924077 | |||
89ecba961c | |||
3481a5fd19 | |||
70a21c5136 | |||
2e2c9764f3 | |||
bd447b6c79 | |||
4f6ec3aa32 | |||
e37b3179ba | |||
808214f973 | |||
7e714f1ef8 | |||
e65e46f664 | |||
5e7eb6635f | |||
49ae62b02e | |||
c9cfe5cc6e | |||
e8df010449 | |||
949136b161 | |||
1e00c63146 | |||
6d9b93a407 | |||
37c39ad587 | |||
e3e65878aa | |||
6843b0eaab | |||
e25f76753a | |||
75c2fabd7f | |||
35aeb19fcd | |||
5a00f6a4fc | |||
3a9fc52b8c | |||
64a8de938b | |||
605cf407a8 | |||
9ed5297e91 | |||
07da404a23 | |||
21467ef65d | |||
4d5b2c4033 | |||
5e7836b293 | |||
a6fe61d508 | |||
c0aa320f0a | |||
4bcc18fb41 | |||
32370545cb | |||
2fd8c831c0 | |||
5b4877c402 | |||
71c11b34f4 | |||
3123718166 | |||
dfbec71906 | |||
757c087afd | |||
b30aa968b0 | |||
1e902c8dee | |||
db5f64432e | |||
6c9c463da9 | |||
c73878ccca | |||
41e453306d | |||
626c6007fd | |||
deb88032cb | |||
eca317b3c4 | |||
9300326483 | |||
ebc46eb7d2 | |||
cb83669802 | |||
f6f616a21d | |||
62d50c0189 | |||
dd5b143c13 | |||
2e864c32fa | |||
f4fa7c927c | |||
3736cbc107 | |||
776825cc66 | |||
5cb647e57f | |||
9c5f826bb4 | |||
6b1803629d | |||
5cea0571e3 | |||
95c8afd5ba | |||
ecc9a34359 | |||
1fed7fb5af | |||
93d1ded4c2 | |||
f199775437 | |||
40271f420d | |||
9e71c02eb9 | |||
c9cbfe630d | |||
bf9331b147 | |||
f223d2e00c | |||
5246e7f035 | |||
42de0803c9 | |||
242f9c6197 | |||
5288198474 | |||
b21353c4f9 | |||
65a0c6a4b3 | |||
af5bd89f34 | |||
73aeffd13c | |||
03d2f6c017 | |||
7e1481c43f | |||
8a1069bf70 | |||
6097ab5d12 | |||
d951575f80 | |||
d887546e58 | |||
ec3b80cec9 | |||
2ef442cf83 | |||
6e5a4a7546 | |||
e0d46002cb | |||
739f13b7a3 | |||
34af74b288 | |||
4ee0cc8145 | |||
4984674b1d | |||
f5ee67aafb | |||
98a1b0da71 | |||
074ff76d49 | |||
b75409a6bf | |||
94abda6e3e | |||
68419a9510 | |||
db0854f203 | |||
994301ea4c | |||
5e344b9be7 | |||
66d3da8ac9 | |||
71bb876c9e | |||
1e029f3290 | |||
7926b689fd | |||
4638f781f9 | |||
8bea1505dd | |||
e567f7a80c | |||
3774e8dc51 | |||
dc27ffa6ba | |||
ca25eedfbc | |||
1627c05224 | |||
f65ca04507 | |||
a662b6ef6a | |||
bd6d38b3b0 | |||
a890d5300b | |||
eb8411611a | |||
9360ddf294 | |||
e3c138fa98 | |||
7147dadb2a | |||
8d03738a50 | |||
e5540ee79f | |||
2ccbb6d6a7 | |||
3dce7e7e9f | |||
79e8ce9226 | |||
89857ca77c | |||
5ce60be78a | |||
600cc20423 | |||
987d09041d | |||
df52d01a1d | |||
07de4af581 | |||
95c50dcc0d | |||
71a192d0ba | |||
9acb8c2ba2 | |||
307f7b6bd7 | |||
83dd80ae86 | |||
ccfa85b5e0 | |||
e59821caa1 | |||
2215e5e069 | |||
48b2e682bf | |||
5750da574a | |||
b40095f603 | |||
ec11585223 | |||
eedf189d44 | |||
f027d36db8 | |||
0c79474e0c | |||
610f9e2b22 | |||
4db4b28369 | |||
18464f5cd5 | |||
cf24c1307a | |||
35e870a8e7 | |||
01be74b219 | |||
b8da6847b9 | |||
e2e37a0db4 | |||
56daf347b9 | |||
5098f63175 | |||
d9b12a6927 | |||
fe4ffcfc62 | |||
64a68b95b0 | |||
58d01738ab | |||
a18dae6d04 | |||
b2959e583a | |||
a38a4d6f69 | |||
0a6ea59254 | |||
04984a51e6 | |||
8947f13dbe | |||
c0549d872c | |||
adcd5f0737 | |||
0929857b12 | |||
7d21b39534 | |||
aaf85216eb | |||
2c87100ffb | |||
6c22546577 | |||
24177ffc46 | |||
8ae4315d43 | |||
a588c72e6c | |||
a656f86003 | |||
c9dc60be7b | |||
91cb9129ab | |||
ae32fdeea7 | |||
5803512820 | |||
553b1f139b | |||
623347bc48 | |||
f64f86fbb6 | |||
39b5462809 | |||
a6ee64ea63 | |||
0dcd834535 | |||
f0fc0441bd | |||
69eaaef963 | |||
9dbfe22171 | |||
5ca4e71c34 | |||
26b04e70b1 | |||
ad2430496d | |||
d4ecfa79d6 | |||
8f4cd929cd | |||
fb213b0e0f | |||
e48d18279c | |||
5f46b48d45 | |||
0cc24c8076 | |||
2738c749dc | |||
a7b178b844 | |||
69c44b19d4 | |||
e6abce8022 | |||
ab64bbc3b0 | |||
5da83e9945 | |||
0e6a8cc33e | |||
2e2ea657ef | |||
e5fb9e2d31 | |||
1386f205fd | |||
a294ad41cb | |||
ed497cab99 | |||
282d0abb62 | |||
034b732e7c | |||
b1e9c005b7 | |||
0d144d088e | |||
b2855e74ef | |||
0652e30c30 | |||
1c58fabc30 | |||
262ba6ee1e | |||
e0534577d1 | |||
c12423f28b | |||
3dd6577b32 | |||
a638b4fb28 | |||
798cf66e3f | |||
6cf29123f3 | |||
e65d42bd61 | |||
febf8ac5b3 | |||
c8a9b66694 | |||
9c185f1081 | |||
0a444508f8 | |||
1d00ee41c4 | |||
266434fe7b | |||
7c88333060 | |||
e0b561b12a | |||
16e5e2d757 | |||
8a07c62603 | |||
4df847bc10 | |||
b5df44ce8e | |||
716952cd58 | |||
7b9b418e93 | |||
dfd7c6d4a6 | |||
920caaa524 | |||
13f10657b8 | |||
dd5fd2e5bb | |||
97b00053c4 | |||
76e46d2fa7 | |||
4c62c5dc22 | |||
c7209df7e2 | |||
c17b8e4d9e | |||
0ab33b704c | |||
ba027de3f7 | |||
3ac257bfda | |||
ec495ea4d1 | |||
3b035158a2 | |||
36582a2741 | |||
450d3cb7d2 | |||
8d157ac5ca | |||
89dc379761 | |||
3e800e7e53 | |||
b12c6289d0 | |||
7e50267cb0 | |||
6714eb9f7f | |||
f1d6f0b2a6 | |||
445606e2b1 | |||
ad05f479a8 | |||
a78c1c8278 | |||
06d6d15441 | |||
87676ece18 | |||
acfd3f1002 | |||
d5cbe66b0e | |||
88aa34747b | |||
cc8dcade49 | |||
a64dd9af16 | |||
8405ce6369 | |||
18e68d04f9 | |||
f3010f622c | |||
ff87319a74 | |||
fa517417ed | |||
f9b86a6b2e | |||
8a21dfa93f | |||
c88ae2d7fe | |||
25e979687f | |||
af866939f4 | |||
e72becdfcb | |||
4bd97eecc9 | |||
8ffe6dcfa0 | |||
23002ac70d | |||
1262ad3cd4 | |||
d8f145c4dc | |||
9c5fd1b478 | |||
24f3285003 | |||
179520a211 | |||
ec31a4fe17 | |||
ab780485b2 | |||
07c5c2972d | |||
af593117e4 | |||
931505d135 | |||
6c7433b2f1 | |||
38ca0accde | |||
df79c2cf48 | |||
94bcbeb604 | |||
35e45333b1 | |||
f17a6f13a4 | |||
1bff7bdc47 | |||
13cb2c695f | |||
c581b80132 | |||
4dd0ae8bdc | |||
4db67e5bc5 | |||
6aa9122160 | |||
f84f2dca64 | |||
3c6992e910 | |||
7f79d16f02 | |||
790c386ba8 | |||
ee72badf21 | |||
c9c4453660 | |||
f3611ac693 | |||
cc6fe24e82 | |||
5a7730951a | |||
eef729b5f9 | |||
0bb0a38649 | |||
39029adcd8 | |||
c967f91abb | |||
1ba0685596 | |||
f2daa6a150 | |||
e021d42551 | |||
13509e31ca | |||
b9af805ac1 | |||
378d2bc8ba | |||
b73aa55a75 | |||
a729dd1380 | |||
09335e2cf1 | |||
31738c465d | |||
38fb64130d | |||
493b10393b | |||
b406f52670 | |||
ef3f314754 | |||
d2910686cd | |||
793b1b56d9 | |||
d8f9075e2a | |||
1199d4ead9 | |||
4520e1bb3e | |||
afece8193e | |||
3b14585d1a | |||
9cd32a908f | |||
b9ca02088d | |||
440ce0221a | |||
caff7eda9f | |||
aef1cefc18 | |||
1385c7cc9b | |||
8d0260b644 | |||
5d9827fb60 | |||
256d711fde | |||
1d82c3779b | |||
abc9d07977 | |||
40d95acfb9 | |||
9a92bc05db | |||
8962bf00f6 | |||
2083954aa5 | |||
66af258876 | |||
4ba04031ef | |||
a30456a92d | |||
c8dd13577e | |||
fac35b46bb | |||
748cb778e0 | |||
bbcca24bcc | |||
b8c52b1120 | |||
b1b3ce48ee | |||
da864f4c6c | |||
758f627e12 | |||
20322c6ab8 | |||
7a711f0690 | |||
067b977ec8 | |||
58f0ca3d8a | |||
4176f3659b | |||
5979fe5eef | |||
362ba21567 | |||
71894ba245 | |||
2b19e0fbc6 | |||
4d0b402e8b | |||
933e0c30bf | |||
b430afe3e1 | |||
2f25f1790e | |||
d90fcf15bd | |||
be9cc41957 | |||
ef99eeb300 | |||
1646241dfb | |||
543e628a8b | |||
36269cbed6 | |||
75dcdc72d2 | |||
f5c90bebdc | |||
15af66de55 | |||
17c8ac8248 | |||
e5c6b9a979 | |||
753849cedd | |||
b81e4c01ec | |||
2a32b05df1 | |||
e3a0fe88c1 | |||
ee3aa49eee | |||
dd27ad79bd | |||
cfd0f556a5 | |||
347e70f4ea | |||
828aae35ce | |||
2f56783b7e | |||
dc4ecdaa38 | |||
1440e8c55d | |||
51a072808f | |||
0a8c2926ea | |||
5e79f567a7 | |||
e2eb26eb93 | |||
740a50a26d | |||
be3f248a5a | |||
f2870caed2 | |||
ad22d3fd91 | |||
9dcd8b6edf | |||
9607e0e55d | |||
ad221eaaa2 | |||
74a1a5262d | |||
32ae82d4da | |||
9c6c8d4f8f | |||
45fbe6972b | |||
c262132a2f | |||
911a7ef6b5 | |||
8cb3757f5c | |||
10bf914d78 | |||
684177ee44 | |||
b2052ca308 | |||
4174fa648d | |||
182d67881d | |||
9284ac7461 | |||
55eec06e77 | |||
069acf0297 | |||
d9d2c7d213 | |||
83b28e0b00 | |||
c2d52fd48f | |||
32e6643303 | |||
5faf6be02d | |||
9ff93ac2d5 | |||
5131d8d328 | |||
2147f8ec8b | |||
cfa568a230 | |||
ace904cf16 | |||
cb337f4a65 | |||
9df78946c5 | |||
e47359129e | |||
4187e0f94c | |||
b2899529c3 | |||
3d2b4cbfa8 | |||
9daa424afd | |||
aa04951081 | |||
d8da8023c2 | |||
60cadb8b6d | |||
dcf8783c2e | |||
eb9dc95c58 | |||
f94fb4f65e | |||
e0aff2cf9d | |||
d2369f45ce | |||
7b718ada63 | |||
652604a36f | |||
8a4834dd2b | |||
6d49093620 | |||
489ce0bebc | |||
58922c23a6 | |||
be3183fc45 | |||
38b4812eb3 | |||
69fdc2d821 | |||
9104b0f974 | |||
6ec7373a1a | |||
39be605459 | |||
4d4459fa4e | |||
2a3dbaa7b4 | |||
6069e8f083 | |||
30ea223d09 | |||
0a957d7097 | |||
f28a898053 | |||
8921d4fac8 | |||
a66578c46d | |||
e45dcf61c4 | |||
40bfc9b368 | |||
73684d11c8 | |||
0d4ca4520b | |||
f1c1846c66 | |||
d59295688e | |||
c1808164f2 | |||
8f8562705a | |||
6da6723c72 | |||
0a726d598c | |||
4ffd2265ea | |||
3ce6269212 | |||
dc0cf26f51 | |||
713a1f03e9 | |||
c07952629c | |||
d958b1808c | |||
4a596c7373 | |||
bf7c8d5a5c | |||
84f9ee3765 | |||
c22536ce67 | |||
c14fd69a0e | |||
0812596929 | |||
d33a449332 | |||
02b99d2b06 | |||
b4f0cf510d | |||
eb6b1b431c | |||
e955ddb9f1 | |||
48acd101a5 | |||
694cedb89a | |||
47e9f820e4 | |||
a7d7b5abc3 | |||
03d6c86899 | |||
e9bd1bad67 | |||
c9f0295516 | |||
42df6d58b1 | |||
078a2d7e39 | |||
f352399428 | |||
0b2f115b73 | |||
9aed4b0e87 | |||
3054f91fe7 | |||
91da129abc | |||
f77c27ca71 | |||
19cc93daae | |||
4516bbdadd | |||
0cf9b20328 | |||
1c510d45f0 | |||
5b958d7ff6 | |||
d9872bc94d | |||
f177a39b96 | |||
0e53ead14e | |||
9b0fb9ecdc | |||
fa08c52f74 | |||
ce15eed343 | |||
b993da9751 | |||
a93e3be197 | |||
858d56d20c | |||
0818abe233 | |||
c39138e3ba | |||
98c530cada | |||
e4f3c1ae94 | |||
05b45f8cf5 | |||
d530059e7e | |||
7a04be0f30 | |||
c3d8c8d4b0 | |||
0af4be3d99 | |||
8a68e1b49d | |||
cf99f0fca0 | |||
31e335792f | |||
d1efddd312 | |||
dbe1579fc4 | |||
2de20937ac | |||
10f5967e41 | |||
0f743cec41 | |||
f371c47be5 | |||
d334eed9bb | |||
0819df3d26 | |||
e276443d2d | |||
0fc862bac3 | |||
c640289f4f | |||
8891111b2c | |||
abd0ba49ca | |||
62f00fa970 | |||
f6252b73f1 | |||
0dbed93454 | |||
1cf60acb29 | |||
44889a3826 | |||
8a3c751c10 | |||
f14ad8be58 | |||
4463d2408c | |||
7e60328cff | |||
45ba4675fc | |||
79c685c99b | |||
1c5567225c | |||
8ba852084e | |||
9365706777 | |||
8e8415515d | |||
eb9fe7c401 | |||
371b33a2e1 | |||
2711f2cb2f | |||
25dd38af5c | |||
0545f6b74d | |||
e7b8220bac | |||
9a0adcf9ed | |||
0a8fb1b835 | |||
92a8d864d3 | |||
fa46252c65 | |||
e051581c39 | |||
50a9772388 | |||
75fdb8f2e4 | |||
de755ac0bb | |||
7ca0a8c56c | |||
1cb3e5f98c | |||
f507452a37 | |||
083a213e74 | |||
8f17d373a3 | |||
5e6cc4f55a | |||
d8550f6cca | |||
e70753df5e | |||
0744e23ca6 | |||
fcd4f223f8 | |||
39beacf884 | |||
69c2400ec7 | |||
81561c6f3d | |||
85d393fec3 | |||
0d8e2f0d4a | |||
13b9a7bf6e | |||
f6aeee2b70 | |||
86e7b7bdb3 | |||
735995954f | |||
98c4b658c4 | |||
3c3e2f80da | |||
eba0778045 | |||
4055498921 | |||
811fd98a39 | |||
47930035a7 | |||
6a8dbf49da | |||
0e07fcc706 | |||
dbe7f464bd | |||
7ca74aeea7 | |||
cf7c5102fc | |||
b71eb12e23 | |||
709b06baa3 | |||
f900d520da | |||
f2e94e6819 | |||
be21e7d253 | |||
8f0cc9de03 | |||
67b04473b5 | |||
b2ff041ec0 | |||
8dea7df82a | |||
5f6f54db36 | |||
41bebfedc4 | |||
4917f32574 | |||
8f4f87cd8f | |||
7ca2df9fcc | |||
d96bd15b3b | |||
cb5601c68b | |||
34e76494e3 | |||
81bba8c829 | |||
9ac5011bed | |||
6c055ff9ef | |||
db89754a26 | |||
8239fd7e0e | |||
e7ea8ac40f | |||
a249a164f7 | |||
44896559c6 | |||
112495323e | |||
2767fca5d6 | |||
b5b32cacfc | |||
98a74a15f7 | |||
68686cd249 | |||
565dbd88ff | |||
c4d2ece9c7 | |||
59f00ea3df | |||
00f4691f38 | |||
a578857806 | |||
80e46db48a | |||
f4ad04ec2e | |||
66d01aecc3 | |||
b176b972b6 | |||
90ccf88d4b | |||
12b5c88acf | |||
3024ace641 | |||
d907010e1d | |||
bc5068ac7b | |||
68482732f7 | |||
d05f914841 | |||
f323d06f5c | |||
0aad14dcfe | |||
b812c7493a | |||
f244170f7b | |||
5c9d0fd40a | |||
10d6e44a38 | |||
a7a793088d | |||
18ce6c83c4 | |||
768f335a3c | |||
56ed583bff | |||
901f3c4f7a | |||
d12e6a0465 | |||
ef5a05d051 | |||
111cdbd4dc | |||
4e70f5b8f1 | |||
26aac6c45d | |||
0de8cbfd45 | |||
c6d72f0487 | |||
c79e79a5b6 | |||
f73c912945 | |||
37cb49d785 | |||
ea9836a701 | |||
3dbb8a0cc1 | |||
0e1818f535 | |||
e1947c0077 | |||
7c349b12b2 | |||
d758bedaed | |||
a80146e894 | |||
68d13b8724 | |||
f974e1b6cd | |||
50d3a53e4f | |||
53be80a26d | |||
2d608621d9 | |||
ede5aceeeb | |||
b6959bdfd4 | |||
eb0dee07d8 | |||
067a42d400 | |||
f363ebd41d | |||
698ae56d82 | |||
5a9793a952 | |||
57fffc8ef0 | |||
78d4bc07d2 | |||
b381e629f1 | |||
0c7314f771 | |||
4dca905a91 | |||
4ace7e07c9 | |||
74c80fa536 | |||
f2a005eeac | |||
7f29769352 | |||
ffcc967aef | |||
23aefccbe9 | |||
a0d70ea8a4 | |||
db29a31de6 | |||
e399815427 | |||
16eedf4153 | |||
ce87d2e45c | |||
c18167889d | |||
adefaf2fa8 | |||
c9d830f9ae | |||
9e70bb448a | |||
6c7d3ae0bf | |||
51211dccb0 | |||
53f9c22fb7 | |||
1b3e40fd70 | |||
dc3c130162 | |||
ea7231ff26 | |||
b47b942e97 | |||
b90ce01e05 | |||
85d61c4c93 | |||
ad307e859e | |||
f6801187cb | |||
5b929e85cf | |||
8e2728902a | |||
6894a224b6 | |||
77f5d0be35 | |||
bce1345ccc | |||
2c26d55813 | |||
87f411e5f1 | |||
4af3fa4eb2 | |||
7974633bba | |||
1fb75c908b | |||
26112a1ed6 | |||
17bcfe154c | |||
3ce16dc9a3 | |||
f9342b1c92 | |||
39cc420415 | |||
9b7323f9fa | |||
77fff553d1 | |||
cfdd1af3a3 | |||
22da4182b1 | |||
002f6d3e87 | |||
02998fff49 | |||
8156fce81a | |||
2d3b0717f8 | |||
e33200058d | |||
7230a91b4f | |||
c06c5d4104 | |||
92ae1109d0 | |||
19ffd031ec | |||
466a0c6049 | |||
97e5f2e656 | |||
bce386bc7a | |||
f47ffd7ed0 | |||
0b115c3228 | |||
a22c12adc9 | |||
8f293db29b | |||
7bcc559ec7 | |||
e3a8e1a187 | |||
9d9d0461ad | |||
6bacddc159 | |||
b7d66efb20 | |||
26480dc602 | |||
ba316d02ca | |||
82582d24ea | |||
aeaaa2f7d5 | |||
89c39d15de | |||
2cabc63752 | |||
e03311e5ec | |||
810e12f474 | |||
60157eb70c | |||
1f3f456123 | |||
97b7d920cb | |||
3ffd79c279 | |||
09c7b2a5e4 | |||
df1447b917 | |||
22f22c0fa0 | |||
272de60f9f | |||
b40dd46871 | |||
e67d2ee498 | |||
310f6a385c | |||
6245684801 | |||
79f0e5768b | |||
967f28542f | |||
df413d1af0 | |||
a3b4ceba50 | |||
2496ec73bf | |||
f84fe82f9b | |||
c5a073cee8 | |||
ed81a17039 | |||
22f8c4b88b | |||
27d7d03d4c | |||
ca8d83099f | |||
3b250dbbd0 | |||
bc0215b647 | |||
25527ec1dd | |||
9e1ac8cd28 | |||
8688334f0d | |||
8d6a70ed7b | |||
36e3eeecaa | |||
25d08c1a71 | |||
7c1d0f2e8f | |||
0e8cd20533 | |||
6bc5c05cf3 | |||
dbf6676115 | |||
188774f30a | |||
cfef1f3432 | |||
892ea0e9af | |||
f6549cda33 | |||
9fb83f268b | |||
31d927c93d | |||
16977009ea | |||
08db3b1613 | |||
32c6228dfa | |||
f3700c39e3 | |||
7d0aa8d91f | |||
bdfe77dbb5 | |||
2e225a1435 | |||
c2a4bc2603 | |||
561caf966a | |||
33eb5f8117 | |||
efa62e72af | |||
94e8bf4a72 | |||
391d7b01d1 | |||
9d1cd085ea | |||
311972c39f | |||
72d4fa6cd0 | |||
016bf1d671 | |||
406b06a0be | |||
24439f1dc2 | |||
15df2dfb0c | |||
d393cee732 | |||
4c175ca340 | |||
5ed21fd740 | |||
88af6c441f | |||
5da9bd1784 | |||
a122c38666 | |||
e9870a4455 | |||
dbb8dae5e2 | |||
6f9043b2bc | |||
0235624c64 | |||
ea8f121cb0 | |||
9b9cb83a06 | |||
17421497a1 | |||
761f6152d0 | |||
eb14635a53 | |||
37b065ce6a | |||
dd0f8faf79 | |||
006ebf3f15 | |||
572c7ebbd8 | |||
b728cd61ae | |||
04f71155b0 | |||
e45c5ae71e | |||
632911d28c | |||
5fb72513a0 | |||
4b392ad70a | |||
42f6fbb4e5 | |||
afce1682a6 | |||
9f7af1c7d3 | |||
ca1355f80c | |||
0d2f35c22f | |||
6c71949888 | |||
91e06d0858 | |||
fe776edc9e | |||
1c7185a574 | |||
8a7825f3bd | |||
3f23531f20 | |||
29d95a53a3 | |||
718835255f | |||
ca1f910d55 | |||
0e410af63f | |||
0bbe095f6f | |||
8b1a457312 | |||
7a46b2fd1b | |||
bfd25b8a14 | |||
dae8163846 | |||
4db6c16068 | |||
906ecc021b | |||
8fc593a73e | |||
f8e3b62edf | |||
3051724ad8 | |||
b82abb066d | |||
ccfb97612e | |||
6bf3dd96fb | |||
f1e8b4b6e6 | |||
82af723f1f | |||
aeb90a3674 | |||
64ab8e3fbe | |||
f7474340cd | |||
04acbf6509 | |||
f88c02cccd | |||
be5e0ea3fd | |||
b6c7af32de | |||
29294318d0 | |||
d3325f17c5 | |||
51514252b6 | |||
18abc4913b | |||
d2958e1a7d | |||
be44c3f9c2 | |||
72e407b69d | |||
66b9d0739b | |||
3e717ecdbc | |||
91720a0f34 | |||
9d531a385d | |||
26137200b9 | |||
376b5fc160 | |||
dbb2924ccc | |||
d0188f42b7 | |||
6208706d46 | |||
3288264ca0 | |||
16f2ddddf0 | |||
783185d99c | |||
4ca83de131 | |||
f2b986a357 | |||
a0065bc2ba | |||
dc43b54892 | |||
603a3dd273 | |||
16b5f70e4b | |||
9a989b46cc | |||
6c64e7c220 | |||
d66325a241 | |||
bf8190d122 | |||
23aec25686 | |||
405c0c609f | |||
95e0f3378d | |||
c9850a5e24 | |||
3cf7d01f37 | |||
ae9fae1f7d | |||
69b423edc8 | |||
5e8b379c50 | |||
d03124dfba | |||
fdc11bba8d | |||
dc5d8a6cb7 | |||
2042f59283 | |||
8230a408ac | |||
7805e5cea4 | |||
36868644dc | |||
321b67efd4 | |||
9ea42dd981 | |||
631d97c6b3 | |||
13569fe4a2 | |||
12e2b93ac9 | |||
0dd1b668cd | |||
e751be21ea | |||
15b8a159f5 | |||
24a88fcfb5 | |||
9f842be53a | |||
c6632fe083 | |||
0b720768b8 | |||
9f12fe7e0a | |||
cff5b82b06 | |||
677cc3bee9 | |||
aef5cc50d5 | |||
6729827645 | |||
d7eeadac41 | |||
7cdfa7d4c5 | |||
9070b475ea | |||
43a99bfef2 | |||
18ffd678b7 | |||
7566d3dac8 | |||
741b93dc04 | |||
b19298f633 | |||
1954dfd4d7 | |||
31cc966b38 | |||
261931c8ef | |||
2c44c25b25 | |||
f072ec3a8c | |||
113869bd08 | |||
0dab96f0a6 | |||
342f63a625 | |||
f52c6b65ce | |||
07efa87fe5 | |||
ffa04b625a | |||
b9807aac56 | |||
b973c0ab82 | |||
0d876b9322 | |||
09a72f2cfb | |||
455ac8786a | |||
213e68859e | |||
2f4967a23a | |||
0c170fc399 | |||
d1383d78c5 | |||
8876f1f992 | |||
b53cb50a91 | |||
1f35534dfb | |||
294dad01c3 | |||
0ec566e6df | |||
536a85eadc | |||
8cdc73c31f | |||
afaabd06d9 | |||
bb6f6e7d27 | |||
73588ea22b | |||
b6e3ad9325 | |||
7e9bf9598d | |||
3680e03cdb | |||
0b89598f39 | |||
bad4c9dc60 | |||
95a751c505 | |||
359e761922 | |||
654bb0c8ca | |||
3eb503b13b | |||
31e0bb43e8 | |||
4bc0fd98ca | |||
9206f0cd2e | |||
e834cd7595 | |||
50e1e2d982 | |||
6ddb20d022 | |||
0cacfa140b | |||
1ab016d21e | |||
6ad7d18c42 | |||
a46774c2ee | |||
58f9b9b0c1 | |||
0000257dcc | |||
8c3907df82 | |||
f7c1dff576 | |||
16982dc76a | |||
9532db7bae | |||
a93062e0f0 | |||
6c828a29ec | |||
b7c65b2ba6 | |||
f40a8853f6 | |||
1889c33d80 | |||
308ca479df | |||
0b7d5c839a | |||
9e0d6618b1 | |||
02a2bd92af | |||
03d90f79ea | |||
b066cfd904 | |||
475d7f01b7 | |||
b30597b8f1 | |||
1824f03d35 | |||
4cd3d167b1 | |||
4640c63094 | |||
2460012caa | |||
db7768ef57 | |||
74b6aa7353 | |||
0e0297d650 | |||
8dd6ecc0b8 | |||
e84d4d3cb5 | |||
da54154ae7 | |||
a9dbbe1955 | |||
3fbe86c286 | |||
0022e71dd4 | |||
c74121fefc | |||
67c3581989 | |||
1d1c1141a3 | |||
cf00784096 | |||
db209af787 | |||
30bd94ee43 | |||
f313a5f221 | |||
b9ef5af5d7 | |||
59677b6521 | |||
56283df05a | |||
ef271a088a | |||
6043b7c75d | |||
c338779f0e | |||
34239dc383 | |||
67758609a7 | |||
6af3b4a51d | |||
16afca8058 | |||
f2bb24f6ab | |||
44ee7c66ce | |||
117622200b | |||
340ba5c714 | |||
9e16b506e5 | |||
e865d85c2c | |||
284e66c730 | |||
587f244f1d | |||
379e5741e7 | |||
ec4c346e0a | |||
5099f98d2a | |||
ebc99adc58 | |||
048dff7e9e | |||
a70934938a | |||
d9a93f996f | |||
3456d87bb5 | |||
4947fa4d45 | |||
37f4b34b5e | |||
66206399e1 | |||
1e3f62718d | |||
114ab98059 | |||
47baa219fd | |||
96509717cb | |||
89bbcb6092 | |||
95dbb65612 | |||
7db8d52624 | |||
77073fa78c | |||
9e315f99d0 | |||
16ad3ee7fe | |||
559015c70d | |||
15d02dab4f | |||
332a1da167 | |||
e12aa9e657 | |||
9503e07dc8 | |||
9b44370832 | |||
568015c58f | |||
58f56eac90 | |||
03532e4063 | |||
de6081c2dc | |||
197b46880c | |||
b7ec22ee89 | |||
fad53a9fa2 | |||
5b4fec11ed | |||
0ef4602a65 | |||
c8f182f13f | |||
36630d9586 | |||
32f2acee53 | |||
3be2ef5c91 | |||
7e5d269c39 | |||
6e0c090622 | |||
cccf3ca617 | |||
9e9b5945fe | |||
77f6019d82 | |||
35432d919c | |||
25e6f82aa3 | |||
d22993871f | |||
80563de587 | |||
b5102c4269 | |||
9d215ea27d | |||
cdf6886c39 | |||
79b034b505 | |||
bfba105aec | |||
1bbdaa1251 | |||
ca462bec84 | |||
eb5dcab32d | |||
ca3acdacdc | |||
33f63508e8 | |||
5033cb3186 | |||
3d1122be7c | |||
1d092a15fb | |||
501a21b89e | |||
b9006e4417 | |||
5b3b96b372 | |||
338a0f9251 | |||
29ba761d7c | |||
b96e668dfd | |||
de3753d04e | |||
2a030fe7fb | |||
f595d823b6 | |||
78d191f7d8 | |||
3b6dbe76c5 | |||
e3b348b55c | |||
cf012a7946 | |||
8d1ff01ee8 | |||
e9bda50054 | |||
8ca2824b00 | |||
f7d70daff3 | |||
42d27d69dc | |||
5a9d1e3257 | |||
9cc9a16bb9 | |||
a3efe9a9dc | |||
94b0b9498d | |||
bb322d6bf3 | |||
b0f820e95a | |||
da588380ed | |||
8fa65408ed | |||
2d68d0da63 | |||
2bc7fa0316 | |||
55f416c48c | |||
aff91f49ef | |||
ba02372d13 | |||
e5a3ef3e22 | |||
137c3ef2ce | |||
87352f0b62 | |||
2226884946 | |||
9d2cd46464 | |||
f3b2b350ce | |||
96c04481da | |||
dad2642fa7 | |||
59bdb943dd | |||
67da6ee379 | |||
9c9c102e74 | |||
26241be6fa | |||
2bb4dd5d01 | |||
5312bb1dee | |||
bf6f5aa335 | |||
4a58763f98 | |||
b8202da7aa | |||
edfc82ac75 | |||
b28fc85974 | |||
ab1b36bcdc | |||
5443ac4688 | |||
d92d8ba0e4 | |||
0f19d303eb | |||
1332f597e5 | |||
de004074b7 | |||
29741f39ac | |||
33ea8984fc | |||
85517b0344 | |||
74c574255e | |||
70d4e98dff | |||
f1900d30f2 | |||
463567cb07 | |||
53b0e675c3 | |||
d323bb35cc | |||
3e13e478ad | |||
5f421b0679 | |||
c99fe54db1 | |||
05a2985c5b | |||
47408498b9 | |||
e75b4ec6bf | |||
ff99ab1239 | |||
2841cd8498 | |||
519f4af867 | |||
68cc3aba21 | |||
3a2970a495 | |||
b31fb1a269 | |||
3801eeec43 | |||
94cdd399d5 | |||
c784144a07 | |||
b600e5777e | |||
e49074d797 | |||
02d26467f9 | |||
e68b45c76a | |||
f410f7d4d1 | |||
d4dbe6fe17 | |||
c7305ba5e1 | |||
e11963aca0 | |||
2d77426e04 | |||
7e0f9e1d28 | |||
18e181bb9f | |||
c3c9585a95 | |||
4b5b941761 | |||
79c70b31a3 | |||
072139f707 | |||
9d80db98c5 | |||
a5df029d43 | |||
47f16aadd5 | |||
f8b2b18c6e | |||
4be6c06af5 | |||
92c58eea7f | |||
5e6049bf3f | |||
7adaa146dc | |||
e3b51f593e | |||
e64094dfcc | |||
cb6fcadb86 | |||
297b84a18b | |||
b7c0e049b5 | |||
aeef160d0b | |||
34c1a304a9 | |||
4f1ae4733c | |||
e009c1a25a | |||
79f12a7058 | |||
deb197cfa5 | |||
2710130667 | |||
48163961ed | |||
8658cb5f29 | |||
a6a56e4791 | |||
22e39998e2 | |||
70d1056d48 | |||
3bd5c3e1b5 | |||
0a1a4fd3b5 | |||
e508b22d34 | |||
a7815f107e | |||
ded5670108 | |||
c1ffeb331b | |||
ad1148d3e2 | |||
a7b926d907 | |||
1f7a821c09 | |||
bf45edb5d8 | |||
686f5bf151 | |||
426fe793e6 | |||
aee55103a3 | |||
778bf97079 | |||
2dcb3111f8 | |||
03d1f98402 | |||
34755b32dc | |||
6679ee1ca2 | |||
8420c74b31 | |||
0077105a2d | |||
51db617584 | |||
514b695907 | |||
b470ce2dad | |||
161850150a | |||
b02cfa9d41 | |||
dfe655393d | |||
8c81dae167 | |||
de75d30f06 | |||
8ba99d4e7c | |||
c3bc25a7d4 | |||
42be03b560 | |||
e73aece9c3 | |||
69c57867b3 | |||
7434163848 | |||
00d1c4ebcc | |||
26067fbfe2 | |||
03458efea4 | |||
bd21bf9c0f | |||
5b7a20c33e | |||
c73c34dfaa | |||
a3a9361ba5 | |||
2f0e9569a1 | |||
511a0efa89 | |||
4ae91ba307 | |||
3a70f467eb | |||
4e09bb0b01 | |||
5ae18cf21f | |||
6bfb6a795e | |||
1d2540543b | |||
9efe6267d3 | |||
cb10551d2c | |||
b0073af5aa | |||
7ca7f53446 | |||
ad284a4b61 | |||
95e7d5ded9 | |||
55722b3191 | |||
5e34efc9f4 | |||
6f85ffd9df | |||
9783a76c38 | |||
05952f95f1 | |||
b9c97cc5d7 | |||
d5b088b924 | |||
fbd5673cfd | |||
dbb7ad083a | |||
ce7e4234cc | |||
d2b38fdfce | |||
fcdcc5e69b | |||
8d73606809 | |||
15a7c4d092 | |||
c205e41072 | |||
48c220b751 | |||
06ff268644 | |||
9ee920a816 | |||
a403363015 | |||
6274958409 | |||
d47e225dce | |||
841cf61c92 | |||
2d2c5b46af | |||
cc80e4636f | |||
bb24c95e71 | |||
c7a4158a39 | |||
ed0e423aa7 | |||
1c0d713b00 | |||
70c80f4d44 | |||
e3f6de8472 | |||
95644f8884 | |||
f57db12c09 | |||
0d821ff4db | |||
6927d81175 | |||
e183714475 | |||
6602823067 | |||
111feeb673 | |||
3bf1b78b33 | |||
751ccc333f | |||
624e6e4744 | |||
73b13c750d | |||
148b04e9ba | |||
32938479ac | |||
aae0086e68 | |||
1f4556bd9d | |||
d7bb15cac3 | |||
9a54445785 | |||
523edfef58 | |||
5a841216b8 | |||
d6d58a98db | |||
6a0cda69c9 | |||
24691e5290 | |||
b203d369fb | |||
b1cc30d25d | |||
72e64885be | |||
f4a47f5197 | |||
fe45152529 | |||
9a9773853e | |||
9d2ab8b154 | |||
ba2184e21a | |||
829b0dd5e2 | |||
9fc451c9ca | |||
452568e740 | |||
5503132ffc | |||
17a6b7d34f | |||
69ad9edc9a | |||
80bb959ac3 | |||
1e0587af26 | |||
16e35e8b55 | |||
8278926e42 | |||
1debbc3cdb | |||
65c99ead1d | |||
2693dacae6 | |||
7ce614f1c4 | |||
79a0f97abb | |||
670e0ee7df | |||
3f231a8894 | |||
f5dfee7642 | |||
ab120c5dcb | |||
f085a5618b | |||
d939baac84 | |||
41d70e8462 | |||
9af7edf8b8 | |||
01a8c20ee8 | |||
4c966e2a09 | |||
42aead3c89 | |||
a348960041 | |||
c737a25234 | |||
a01b2e4a83 | |||
5f838db281 | |||
08beffb005 | |||
76b919d887 | |||
c106ac2c42 | |||
4a1fb71e09 | |||
98e2baae19 | |||
963c69a0e0 | |||
fd026a9733 | |||
e76785a64e | |||
1a8f222e46 | |||
24d26d7a44 | |||
c86370c25a | |||
20cba1d3a1 | |||
3e2efc7f27 | |||
d2c29aaec6 | |||
bb1c5dead5 | |||
41cc79600a | |||
238d4fceea | |||
c6d75de3d7 | |||
9e1ae29600 | |||
d60b00e8cd | |||
49786f4195 | |||
7b6eae6053 | |||
a408541eb3 | |||
1ba25448cc | |||
4d2e59e1a1 | |||
7b4f686add | |||
ee0ef2881a | |||
22f79e9fe4 | |||
fdad5a47d5 | |||
e32f3cbf80 | |||
b56d026fdb | |||
64717328f6 | |||
065be9be64 | |||
10fcfab233 | |||
ff9865c516 | |||
59bae2c337 | |||
89d9793692 | |||
23b2f55b47 | |||
886510c2e1 | |||
2b11b43d6d | |||
d90ffb2254 | |||
fc88a867fa | |||
e4cb1a875b | |||
1a62ee9260 | |||
56d5e6f99f | |||
f1821636db | |||
2e3a0706ee | |||
89da4184ff | |||
1895e154d9 | |||
6d7b57ea3b | |||
39a8c3fe47 | |||
927c09ff7b | |||
08abda1522 | |||
d219ba5d32 | |||
afdee9d8a2 | |||
ac14f199e4 | |||
76818fa385 | |||
49be370e51 | |||
fbe89f1784 | |||
b7afcb90a2 | |||
a6ac67963e | |||
bde8ed7aa2 | |||
ca234838a3 | |||
d54d340bef | |||
a926a5eedf | |||
0df5e7d7a3 | |||
034fb4ec80 | |||
69482eb4fb | |||
10e52f08be | |||
5565d8dae5 | |||
c633402fe2 | |||
0688feea3c | |||
c906fd42df | |||
6468b39121 | |||
d0a95f5a69 | |||
e36338d903 | |||
e596513fc1 | |||
77588182b9 | |||
ca00caa4a4 | |||
36bd76248b | |||
f0f05acdfd | |||
6df7ffd7e2 | |||
91924512e6 | |||
7899c2d5c5 | |||
56ba834ca2 | |||
d57fdd4785 | |||
805e1f53b3 | |||
40953ef2c6 | |||
ff055c08fb | |||
f3d5cf3622 | |||
e48e8c34d9 | |||
98a48cd0a5 | |||
f8f358ebdb | |||
9d99c32305 | |||
478b1463ff | |||
7e7f0053e2 | |||
9a940a044e | |||
d2864ccd7c | |||
ad4dbdad6d | |||
094307d688 | |||
53e7c84e73 | |||
2a865284da | |||
4666238e38 | |||
b54a7b80e3 | |||
432d6bb261 | |||
fb36ed2cae | |||
55516a3253 | |||
a0e638d500 | |||
2def9e7bd3 | |||
0bfc12ae3d | |||
318d826694 | |||
44b3bb34a4 | |||
46edc281b6 | |||
d72139c2c1 | |||
29a807696b | |||
517c65f1fc | |||
8f18be727b | |||
d6c66d0c03 | |||
eac33d494a | |||
2105b44610 | |||
ab74013a05 | |||
967b02e373 | |||
8432cd5477 | |||
ccfca65c41 | |||
0a8abaf7d5 | |||
47c1164003 | |||
65d26ad8a1 | |||
0a0d8d53a4 | |||
e50e3f662d | |||
540a31207e | |||
132c36df7b | |||
e351e0c9ea | |||
8d7b9fcef2 | |||
6e1f3989e8 | |||
e99767c7e2 | |||
c85fb3e89f | |||
348934488d | |||
6c8918a308 | |||
ff2ea5815c | |||
cc0202ecb3 | |||
0c065df4bd | |||
b5664dac81 | |||
8173296c96 | |||
71a00c0e67 | |||
70b172addc | |||
2002c6750b | |||
786be9d1f5 | |||
233fa8a4a1 | |||
c74f52a61c | |||
245507f821 | |||
5495c4b5d3 | |||
afd2c8e3d7 | |||
c8e1db2102 | |||
95f859b6db | |||
6bf7ef0798 | |||
42152050a3 | |||
67befcc629 | |||
3cdf881438 | |||
153992a458 | |||
691a8d6fd8 | |||
a9bf843be0 | |||
60e5afe690 | |||
980bedf301 | |||
6f6e8ba1a1 | |||
d3af82e38b | |||
65afc9f7b2 | |||
2e630ac5d8 | |||
e6acc19bcc | |||
c598a1827f | |||
1edd19f403 | |||
1052e9a035 | |||
5e15dd97b3 | |||
7763ad5b2c | |||
4e826553f8 | |||
21c7bcca5a | |||
1df0fe9deb | |||
7038c28429 | |||
d9bdb46033 | |||
e0aad34105 | |||
a88f46e1ab | |||
ba480e40e6 | |||
ef52d6b4c7 | |||
99f47e2848 | |||
8046872315 | |||
b282a70534 | |||
991daefd85 | |||
2a0353b6ff | |||
304caaaf1d | |||
4f5f52b937 | |||
0b4760bc29 | |||
7f6d27cc5b | |||
f8520201ce | |||
efda8ff5bd | |||
27f964e2a1 | |||
56380a5fb3 | |||
a303e793b4 | |||
2934c27ee5 | |||
44d4673981 | |||
fca6b39681 | |||
c3bfce7656 | |||
c607696230 | |||
9eac33793a | |||
18aaa1a0c4 | |||
e7eea1036b | |||
48c21baee5 | |||
95b9884af7 | |||
d9ea9fbffd | |||
0c7f35b000 | |||
78f73132ed | |||
5a93857b4a | |||
b71fd1653e | |||
ec80787120 | |||
501c3241b5 | |||
0a8b303c11 | |||
fec5637040 | |||
5cbe61e2e0 | |||
023e64704d | |||
276a9a95f9 | |||
d16a4334cb | |||
fa51180dfa | |||
a3e7729c52 | |||
2a7f6e4aa3 | |||
1d61db4758 | |||
ee524e36c5 | |||
f097ecdc80 | |||
a354f7d9dd | |||
29d51ad2a2 | |||
1be6408246 | |||
34702d2633 | |||
b79b310bd5 | |||
dc4f8a1fbe | |||
6d0896084f | |||
d31bff7070 | |||
f2aab4cf03 | |||
c03dc48fe9 | |||
143c909812 | |||
821b904163 | |||
6015eb337a | |||
5d817a0483 | |||
ee9905e85a | |||
ff4c7c364e | |||
a2d657f5cb | |||
db6a4687d2 | |||
07f0d95f56 | |||
1a409a441d | |||
445e184154 | |||
9a10f55a85 | |||
ae33b1d0a8 | |||
4ed2db83a5 | |||
500aa85142 | |||
3b6cc84a93 | |||
5ce29d2bb8 | |||
3184d2b2df | |||
f5e65ec2a6 | |||
66488d813b | |||
4853cfe41a | |||
dc7733abcd | |||
771c8e2758 | |||
24664b60af | |||
82393eb8bb | |||
b432d8903f | |||
ea9169f607 | |||
496a6f0f55 | |||
fb2a0fb7fb | |||
ef503fa907 | |||
fe2eca4fda | |||
88835b5b55 | |||
876c940032 | |||
a08d5be35c | |||
0074790684 | |||
23aaf794ef | |||
bb12d37416 | |||
e058903450 | |||
06f1c17a5f | |||
e00136de93 | |||
56d8c033d7 | |||
666682677c | |||
652b958d4f | |||
c7c0db612a | |||
a83edce4dc | |||
f99058a9fa | |||
a907143d81 | |||
4ae173bb69 | |||
1436420a93 | |||
086cbaa231 | |||
5dd3112e0d | |||
b42e4f240a | |||
7076692069 | |||
dcb3601791 | |||
54c7c0d696 | |||
f324185d82 | |||
a63502873c | |||
f5cbf6672a | |||
a78dff5931 | |||
f8139a9156 | |||
27a61b7afd | |||
71671b9e16 | |||
c68bf5220e | |||
80ee03d897 | |||
d0bfa67495 | |||
bdb2edba12 | |||
78d8f4e011 | |||
1bfe9dda97 | |||
8e6f43cd3a | |||
6848482999 | |||
43967ee86e | |||
61b99f6630 | |||
7e073fb7e1 | |||
1ceb5cb576 | |||
53a60d1660 | |||
25b733ca7f | |||
1bf680fdb9 | |||
76008c9f5c | |||
1bf04ac4ac | |||
4b088defd3 | |||
a2be7ee471 | |||
025da0261d | |||
4ac79a7ea3 | |||
ef20a03b95 | |||
d9681398e5 | |||
25f19e5d9f | |||
aab6fcd508 | |||
a8ac01cd8b | |||
605a0fd3c9 | |||
90ec416125 | |||
827b6085af | |||
ff11e6e032 | |||
9b55648e41 | |||
6dffbbd93d | |||
7a0991d6b1 | |||
9b165de5e6 | |||
1b9a4e7775 | |||
48799562f8 | |||
7d545ca682 | |||
9739f3fb25 | |||
bb12de8945 | |||
feabeafed9 | |||
6b427e99ca | |||
31db34ec8d | |||
bf614cd322 | |||
9410933e1c | |||
c269dee980 | |||
5aefb585e9 | |||
780cf67a1b | |||
12e7c5e5e1 | |||
92e5f2852a | |||
0fbda9441a | |||
32a82bbb7c | |||
628d0bb690 | |||
05223c1a5f | |||
9aa0603d87 | |||
36f980135f | |||
63953e42a8 | |||
4ba836f1ff | |||
b7132ab66a | |||
67810d50cb | |||
b7503c994c | |||
389695751f | |||
dad3039c06 | |||
9ccb472c7a | |||
c35afd5e9a | |||
74adaf1d1f | |||
0fce8d0739 | |||
dbb6408acb | |||
5dbdb4b399 | |||
58d9a48787 | |||
4baeb7bc71 | |||
1a3da096a7 | |||
ba0e501e38 | |||
bff95e4655 | |||
4f03f3c9cb | |||
d48334b97f | |||
90da81f68e | |||
9ba1403f5c | |||
846fd815ff | |||
60e0f775ed | |||
529c2df1cc | |||
430a9eb261 | |||
d3408b91be | |||
d5febb30e7 | |||
63c4ec1809 | |||
6ac8cd19d3 | |||
c95bceef4d | |||
3449bba4b3 | |||
d94b016e63 | |||
629dfcf152 | |||
9876208b7d | |||
df617d5186 | |||
21f715bfc6 | |||
18a2c1a00f | |||
6c2fdecebe | |||
c3b7779ea3 | |||
83ea95ed6d | |||
a816e37621 | |||
33c65a6548 | |||
bf57701cf0 | |||
bfcd90d8d1 | |||
0387306918 | |||
c99d26a55d | |||
7efeeb7c28 | |||
3164783b31 | |||
28c441924a | |||
3b3ec7fc21 | |||
dfa0201726 | |||
2b889d9e29 | |||
08688f69c0 | |||
4a0d29c700 | |||
fa916d4862 | |||
1973647b51 | |||
12133cd7d3 | |||
9b66ba226b | |||
96731fabc7 | |||
87f1ab7caa | |||
4cf6f8e753 | |||
dc59c4ca47 | |||
4f046ed1d3 | |||
d689222e04 | |||
57985e78e5 | |||
731341b749 | |||
f12186e09f | |||
4d7480db15 | |||
0485a9178d | |||
17d2b20cd5 | |||
aa459d0ff3 | |||
656ff7029e | |||
8e00e6d8e3 | |||
8bcb2381a0 | |||
a73d2db02a | |||
47eb087d1b | |||
ed6a01469a | |||
7cfe5f0421 | |||
1aef7f7ea6 | |||
9142c48a0b | |||
45e139c5b7 | |||
6706658377 | |||
a75b6201b7 | |||
f724d6c0cf | |||
0dccbeac3d | |||
7d2dc45dfb | |||
f284ef9052 | |||
80790bd9b0 | |||
2da9434571 | |||
579e0d2e09 | |||
33703b83a3 | |||
23b9dfed2c | |||
b8f6ef8844 | |||
6f6b4c8ead | |||
5d87dd5861 | |||
02c8bf4469 | |||
540cb912f3 | |||
93f490f570 | |||
de2e222ae5 | |||
12055a000b | |||
6addb3e481 | |||
d9cd916440 | |||
452a705b75 | |||
1c8206c749 | |||
062c42e524 | |||
2d932ebb21 | |||
0e0fa53517 | |||
4e20730379 | |||
1d70d935b8 | |||
9b8f42cdf6 | |||
eb85b1a7b4 | |||
df7e2073df | |||
84d943d6cc | |||
a1d82b0e8b | |||
ab7c124302 | |||
544597348b | |||
1559c510be | |||
3e08581e9b | |||
49c70d9b04 | |||
50e7d8389c | |||
ea5bd6d435 | |||
cbb37674e3 | |||
e70d5ceb08 | |||
5d7b253edd | |||
df38b84bbb | |||
a3fc75ea3b | |||
71a8166027 | |||
564dd95d81 | |||
eb16b435df | |||
f94daed06d | |||
e841bfa148 | |||
03b76380e7 | |||
c6671f7122 | |||
db56c2b106 | |||
f7b2c836b7 | |||
6ec379b538 | |||
d6e1d34ebf | |||
bc2a039ea2 | |||
e31e600144 | |||
91f83d751f | |||
b8288f1efa | |||
fa61c2bcdd | |||
2d168e1d9b | |||
3e7ad4a4f6 | |||
d2357ee8b9 | |||
9f04c7d0bc | |||
9baa7eed80 | |||
287fbc523f | |||
ea6df35c87 | |||
2e0db1a430 | |||
7ccf0c3612 | |||
1b58058796 | |||
98276bcb3d | |||
1aa4dbb90d | |||
eef623fb4b | |||
84bbbcbe10 | |||
a324e2aeaf | |||
d6b3530384 | |||
dfe8a10e1a | |||
5afa847e6e | |||
1bcbc9bab0 | |||
b915544798 | |||
2b9f390c64 | |||
ee42d5c7b4 | |||
f809dd51a6 | |||
1a8d6e5c05 | |||
869ba745b2 | |||
180dfb6edf | |||
45b08ac8d2 | |||
9a4b385432 | |||
08289b89c5 | |||
a31d1d81c8 | |||
e4c7bb0378 | |||
374aaf2e2b | |||
52fd686993 | |||
03c36ef0d2 | |||
71a6ffac2e | |||
92777ba181 | |||
81843fb609 | |||
3af3ffd038 | |||
2ce5cd0b6f | |||
d791fd59e9 | |||
6064e3ce55 | |||
0fcfe0e977 | |||
997df5c64d | |||
27af96662f | |||
0be6f3ca70 | |||
7af80611b6 | |||
4c349803b6 | |||
35a4278ae8 | |||
06365b7b73 | |||
f31e013986 | |||
fe1df743ce | |||
22ffd48cd4 | |||
c83bcd259d | |||
8ebac28ccf | |||
4e5001d7ef | |||
84fe14a1ed | |||
6828730313 | |||
e540079220 | |||
e99f806b66 | |||
b452f1d125 | |||
f0a9d209a5 | |||
984aa2912a | |||
c8937f6d46 | |||
cb849ab23e | |||
3bca3427eb | |||
a127b13db1 | |||
a2f608266b | |||
05f8b8d8af | |||
f1cef81d76 | |||
e1bf376f10 | |||
9298eab30d | |||
584528f903 | |||
3501920956 | |||
65a867e82d | |||
2bfea50014 | |||
89539fca01 | |||
240f6fa45a | |||
c004065eea | |||
1cfba82d77 | |||
3bdcbd8907 | |||
fd53811fdd | |||
5eeda40098 | |||
7bce316e78 | |||
68f172b9ef | |||
9b3e7338ba | |||
c6ef6fc17d | |||
e4c797eaa7 | |||
bdca51a178 | |||
e147ce8606 | |||
830286ecc1 | |||
bc56cab488 | |||
dd683db6d5 | |||
5436999b13 | |||
29946763ba | |||
7160f7dc22 | |||
e44db30ddb | |||
458b2fd72e | |||
66ffa5f987 | |||
dd8caa46c4 | |||
55de85d829 | |||
10f782aa11 | |||
5bb6918465 | |||
205fd3c9ce | |||
50bf55cbdf | |||
3a9ecd8b33 | |||
5942a840b2 | |||
6dd3c79c23 | |||
a25e0ef592 | |||
29465cbadc | |||
fdc1aa25e4 | |||
04fbe42bda | |||
57a6949565 | |||
bcb85e2084 | |||
6900964c03 | |||
3d2b8d2969 | |||
c7da4e3eff | |||
9e31154808 | |||
89353b8e7c | |||
b8eea53e01 | |||
9bafce8069 | |||
a9de1c2c64 | |||
e6505040e0 | |||
92bdb20e1c | |||
c6bba9188b | |||
c3a84f6577 | |||
ba54b5aacf | |||
e92a15e072 | |||
ad853c6985 | |||
e7ff5c0a4b | |||
fef1bde9b6 | |||
eb87d7cadc | |||
5394e0a4a0 | |||
0f0b846e04 | |||
ae869489b5 | |||
cdc973cbea | |||
bae9ca2a7a | |||
0df7506ad5 | |||
974101624b | |||
621a7d998d | |||
539c7d6e17 | |||
2743641122 | |||
1d08a811e7 | |||
c5ca02e48e | |||
bce201038f | |||
c24bb443d3 | |||
9c165d84ef | |||
58b834fe9d | |||
2b1aac9aa9 | |||
dfdb99165b | |||
b75eaee6dd | |||
888b06376d | |||
7f6b1e7e6e | |||
8dd1efc126 | |||
9cd64bf81a | |||
2c14cece6b | |||
11c269693e | |||
ae9b93ca8f | |||
563e95df7c | |||
5b37a9df0b | |||
28396206de | |||
9d3026f676 | |||
0f7458254e | |||
2305a0a5c8 | |||
7ce2ddb400 | |||
13c8372329 | |||
8fd7ee0763 | |||
aab7c08500 | |||
ff8de47e69 | |||
3ff9cc85ef | |||
0a2440e14c | |||
d37abb53f0 | |||
656a3956b1 | |||
c31e7593b6 | |||
7be9083220 | |||
b85667a191 | |||
892d906ac7 | |||
0277708b2a | |||
d757aa2978 | |||
cf7bba9600 | |||
a0d498812d | |||
29e8783beb | |||
57b87a55bc | |||
9ff9377bc7 | |||
163ef031b9 | |||
1cfdd1489b | |||
0a9290a980 | |||
f0c2fb62df | |||
24d6532dac | |||
fee1fe22a7 | |||
d8103f7293 | |||
3d3446e46a | |||
22af4d2836 | |||
06b2a3383d | |||
06c3f01e41 | |||
d392880102 | |||
55dd8da284 | |||
e76f5b19b1 | |||
5650b8560d | |||
2d80dbfa8f | |||
c62aeb670a | |||
1a407a2da3 | |||
72d7e2dc5b | |||
a126ec1718 | |||
bf59114a00 | |||
6b587bfc31 | |||
28a2017b65 | |||
c3a6e9a799 | |||
45c66a167b | |||
380629a961 | |||
74fdd1358c | |||
e9d63650b9 | |||
9ecb27a9bd | |||
b0ae878ef6 | |||
28cc4facd4 | |||
749146ad3c | |||
a4ba93d249 | |||
7eae1f3b3c | |||
d66e8f2d13 | |||
058b768b0a | |||
3425f84507 | |||
aad586232c | |||
b514533814 | |||
3b1f851f8a | |||
99095f25d9 | |||
d79a28ac6f | |||
120fe1ba85 | |||
ad8d8c31ab | |||
3e5ab70583 | |||
cd5b334a00 | |||
9a99b3fdc2 | |||
2249ee195a | |||
93cdbf7a1a | |||
22fa43f8d6 | |||
39a6bd15d1 | |||
1d8fe9fb93 | |||
565cac34b0 | |||
1cb02b2913 | |||
1174178771 | |||
f1a2cc2b65 | |||
36d97d1e74 | |||
12264d8e74 | |||
4d68b12080 | |||
3c7137830e | |||
4f1b4131cb | |||
ccb45e3a99 | |||
f3461bfbe6 | |||
22b05500f1 | |||
66a2383ad1 | |||
7d6fb21a8c | |||
5054e76d64 | |||
9adb825c30 | |||
9a28dc5121 | |||
c82c67359c | |||
59afc05661 | |||
c05820224e | |||
fee106abef | |||
48fa11759f | |||
eac4c91820 | |||
037fcf93f5 | |||
dabe805602 | |||
dacf5c1e16 | |||
da2e8665a1 | |||
8643c04a39 | |||
c5ba063edf | |||
9648836e2d | |||
3c9b58916b | |||
d56a5ad86e | |||
cd5cc6435c | |||
c908301b84 | |||
e68d76b56d | |||
8339ec59b7 | |||
c5cfd7921a | |||
e584004b23 | |||
281a2461ad | |||
bd94b5f84e | |||
2b040b3465 | |||
0e452c7cdf | |||
2acdc77289 | |||
fda6a1a77b | |||
7e5c593e09 | |||
40b191ef49 | |||
a92f0fe289 | |||
ca17efbc29 | |||
5025e0dd4d | |||
1325c5d441 | |||
30585d2cc1 | |||
98468f4eb0 | |||
39876dea07 | |||
03917ec806 | |||
1c9a91140b | |||
3417556f5c | |||
0cc2fa962d | |||
8ba1303968 | |||
ae2b055fb5 | |||
a919d3ddec | |||
102b38b5a8 | |||
56a363adf9 | |||
5c8dcb0292 | |||
0fd5c722f6 | |||
b86befbdaf | |||
53310dee8a | |||
78b86ce0ea | |||
3bdc7c102a | |||
f9714f0be0 | |||
536f98b566 | |||
f4977e7f9f | |||
68807bae37 | |||
ccc2d0e13c | |||
c2032ee15b | |||
724a5b5460 | |||
c9ec0f9d3c | |||
411fe90b8c | |||
a56004fbef | |||
e75edac3c1 | |||
aaa05eb5ec | |||
8d0d80e086 | |||
4d84343a80 | |||
275fbc81e7 | |||
d23adfbd78 | |||
f7b85babfe | |||
56e85b68d9 | |||
755a6bf8e6 | |||
7282199c31 | |||
639f5d2fc4 | |||
8c8ef9d3ca | |||
2c5c6d28e3 | |||
fd78d02576 | |||
3a0328d0be | |||
d66b111121 | |||
8cbc58ea2f | |||
3366c86b16 | |||
c7e3241a85 | |||
1c2c3ede80 | |||
0f46da2e6b | |||
514386ecdd | |||
2257b95732 | |||
7a5cfcf50f | |||
e8d5190569 | |||
d6d13ec001 | |||
f3aa67e0f1 | |||
59839a3332 | |||
fa18bd9a69 | |||
bf9dd57177 | |||
a230e21737 | |||
e763e9e41a | |||
2e0abdbd06 | |||
f3890cd029 | |||
2f918b1195 | |||
5b73f22eb4 | |||
edfdae744f | |||
438fc34ad2 | |||
9e107b1eb1 | |||
a8e2a99faa | |||
0823a3e0dc | |||
7ac72c6c2a | |||
6d703d590b | |||
3dada3c464 | |||
a2cb6178b8 | |||
42dda56eea | |||
6407e15187 | |||
af97e296ba | |||
200c9709fe | |||
18b8bec8d0 | |||
41d714e2ce | |||
60a8b23c03 | |||
0096250384 | |||
2ce0749bb6 | |||
7ab97311be | |||
e6cfb6e851 | |||
b3298589c3 | |||
127ad3e573 | |||
2a262c4e1e | |||
ee804c9922 | |||
3a8e136f39 | |||
8eec6db825 | |||
1c90b6227c | |||
8b7ea6c71f | |||
3fc9d0c010 | |||
345ce6ba5a | |||
d9cd00f49a | |||
2266c0dc96 | |||
882430cf58 | |||
11730cbae6 | |||
dc3abc76c3 | |||
0013703cef | |||
91b1a5e3e5 | |||
911faeb510 | |||
8fa9834bf6 | |||
cf930fc46a | |||
9ca9b5a5d2 | |||
3a87dc2223 | |||
67d3875c98 | |||
77d0f3d85c | |||
0798b95c6b | |||
c247e275f6 | |||
f17a359893 | |||
8e15707dc7 | |||
d890753ee2 | |||
00b82ad07a | |||
a21948cf16 | |||
eb583ba628 | |||
a4b61f8aab | |||
7208e63155 | |||
8f464b0838 | |||
233b799a46 | |||
d99beb9811 | |||
fefc45854e | |||
0047a5388d | |||
66064bd2eb | |||
6bd601137a | |||
eae913f809 | |||
bc8e7ce888 | |||
1ec342da1e | |||
a169179061 | |||
57b436417c | |||
0229b560e7 | |||
3c51bd3b23 | |||
b7ba97d86f | |||
0eb58e9a91 | |||
f257f9f91d | |||
8971dbc2f9 | |||
5b4e78f8d1 | |||
27f20386df | |||
9154e4264d | |||
7457e99451 | |||
c5227d9996 | |||
1447b5e8be | |||
efdb131c33 | |||
d9a0db3efc | |||
cb8c077c1e | |||
9688798a4a | |||
9a9e31c759 | |||
55c0c0ea6f | |||
43ee22f965 | |||
989a7b863e | |||
709ee54ac2 | |||
664b920a39 | |||
7ea3312534 | |||
929b5c7951 | |||
3e9bee2d44 | |||
a571f77a40 | |||
13f2be7811 | |||
3d00611ddf | |||
576734b5cb | |||
6cd60732b5 | |||
1635e1e3fb | |||
b29b46bbc7 | |||
e45f1afd51 | |||
288dc9b626 | |||
81c6a76ea2 | |||
182f9b3cf6 | |||
e71fd4950f | |||
72d519bb45 | |||
e743b2e457 | |||
f932a34581 | |||
3543d9bd60 | |||
d387834c6c | |||
6ea15411b6 | |||
63df6ac5eb | |||
039bee5b65 | |||
be5597085b | |||
6b355cbe1b | |||
dec5d19a2f | |||
ff533994d8 | |||
221e2c7898 | |||
fb77fddcc3 | |||
c37086e000 | |||
3d6783b743 | |||
c479e6aae5 | |||
59a770e0d7 | |||
140259e737 | |||
59a391dcc9 | |||
3a1cdefa09 | |||
7be104f486 | |||
d90a65975c | |||
4e53f59a9c | |||
8e58fc128d | |||
756b6e9692 | |||
23d546c559 | |||
6d4ea6a951 | |||
f9b5dcd4a6 | |||
eab679cb2b | |||
ddf8b20091 | |||
f1457582fe | |||
7841f79f31 | |||
56e5acfb65 | |||
6b777878e3 | |||
428c7c5444 | |||
f8427eb801 | |||
2a53c056ca | |||
21d555ee6b | |||
d79fda166f | |||
c8025ebaac | |||
42d7ad02b0 | |||
21556d4c07 | |||
89a7166c1b | |||
5d6c28c997 | |||
717cadc64b | |||
3dac7ef3f3 | |||
056cb60d5d | |||
bb4e92ec50 | |||
9218fb6463 | |||
d9baea4c38 | |||
6df6537cf9 | |||
72d199f390 | |||
233bce578b | |||
63472d54d7 | |||
db57b5ae80 | |||
8896d89908 | |||
8e07bf3ffb | |||
6194d0ad44 | |||
138532d3d4 | |||
4716b704d4 | |||
109e576811 | |||
631c878722 | |||
4cbcdb8af5 | |||
d24628a386 | |||
7e714bdfa2 | |||
e3283fb29b | |||
be0285155f | |||
1c055a7282 | |||
8d3cdd39ca | |||
010ba4d5b6 | |||
d176a16caa | |||
fd4a27c1a3 | |||
ae73858e23 | |||
1427e5458b | |||
8853cf9f83 | |||
de7f22bcbc | |||
b8b2fa29d7 | |||
476a241936 | |||
dc97982fad | |||
e488f93b17 | |||
e6e9668bbb | |||
56976898bd | |||
221ff05c49 | |||
8f719d3e33 | |||
67c2abca2d | |||
36046f08f7 | |||
3c4455c23c | |||
e3db2e2b76 | |||
5567a26b33 | |||
5387c3dd97 | |||
d14eef979c | |||
c7069f4fd9 | |||
b40239f93b | |||
2958175add | |||
719ad8f4d4 | |||
4055eda757 | |||
442df56629 | |||
477ab67fe9 | |||
64c60741a0 | |||
9e354d7703 | |||
1932c1cd7c | |||
11670d0c0f | |||
6cab02cd99 | |||
fc1d781272 | |||
a58ecfd35a | |||
645516ee1b | |||
f570de5086 | |||
81ccfa1e6c | |||
b808aa4971 | |||
d1f1bc93b3 | |||
faf433f644 | |||
ba4660a03a | |||
03aa3693d0 | |||
ecae976993 | |||
307c8980e0 | |||
e53d0eda47 | |||
369b15b20b | |||
ff8bbcd88a | |||
c52d22dc30 | |||
4fa6c9dc3d | |||
a958d10dd9 | |||
ff86ce64b4 | |||
f31d8aa9d7 | |||
3cf7406123 | |||
5d8bf196a8 | |||
019bd26c51 | |||
0e1f924fc3 | |||
15c3893aab | |||
deeab7c238 | |||
e5ba7b9e69 | |||
ca5be7e38d | |||
fb530f2b34 | |||
29cbf63346 | |||
13c03cc0c2 | |||
281280d3ec | |||
410be51951 | |||
eefe8289b3 | |||
a53a5944f8 | |||
cd009466b6 | |||
f0c106de75 | |||
fcf1b679e6 | |||
03ba57cd46 | |||
bea08e5cfd | |||
01787e2662 | |||
ac76220349 | |||
796954c6e3 | |||
292c188182 | |||
1f7097ef89 | |||
b97e083017 | |||
8ffd182b98 | |||
1e77546251 | |||
8711960e74 | |||
8e2bcef824 | |||
d418cf7b07 | |||
864bcbb675 | |||
0b257b98f5 | |||
daab68d0b8 | |||
ab0511aa1d | |||
12494c3ac6 | |||
621533e050 | |||
dc334d230a | |||
b848595378 | |||
ae4b2ab1fd | |||
2ca8cc6ca3 | |||
3b57e2684e | |||
898c672193 | |||
18a7bc9278 | |||
bb29ee10c5 | |||
5441ae537a | |||
0a0ddafd67 | |||
a3b914d8b4 | |||
39f75d3742 | |||
3dd77a4f2c | |||
6782e82972 | |||
120fce0288 | |||
aa57531ed7 | |||
8f76bc0bcb | |||
189280e602 | |||
78ca26cf78 | |||
0c5c6233c7 | |||
4fe480ee55 | |||
be6560e08c | |||
0f58f6da36 | |||
dcaf0463a7 | |||
5c6643270b | |||
7b337bde49 | |||
7056aae301 | |||
1b6eb9cab0 | |||
80e23beda9 | |||
d70e120acc | |||
c877937fdf | |||
8379b07de0 | |||
c8c33245b8 | |||
0faf2fe83e | |||
19bc511f39 | |||
916323bb3b | |||
0e568e2af5 | |||
dde841383a | |||
81dae7d350 | |||
d3e3c31b0c | |||
90852fe951 | |||
a2251d245f | |||
112f9c4241 | |||
b300404bc7 | |||
19161b52f5 | |||
429170520e | |||
5571413a78 | |||
512ee16620 | |||
15dc0d60db | |||
d86cc9192e | |||
25b08b21fa | |||
ef9c2e8af1 | |||
9bee48c601 | |||
961942ff6a | |||
de1c2b0150 | |||
5a73358bca | |||
1812ea90b5 | |||
d98a416ed9 | |||
b947749382 | |||
c4d0b061c9 | |||
3bada5d443 | |||
06a35787aa | |||
88c931ec13 | |||
3d436c3b0e | |||
b4bb44d3e6 | |||
39157e6883 | |||
9b6b9e6113 | |||
87df34e064 | |||
55a48ff84a | |||
aed98f16bb | |||
2926865c1b | |||
20fb7fc188 | |||
461462eafc | |||
7aa6d1a8d7 | |||
d914fe2f48 | |||
e100edce24 | |||
a68915d6cf | |||
210d680b21 | |||
8dc4acdc34 | |||
eb54a18fcd | |||
cf436e11ae | |||
e22b7f74c7 | |||
f8fca7434c | |||
66d303c4ba | |||
186ed8beb2 | |||
fac546cc0b | |||
9d2d2d0d64 | |||
f58043b07f | |||
289c6fa10e | |||
00e24ab249 | |||
7b69e334d7 | |||
12507b6743 | |||
3750842833 | |||
1dcec3e1fb | |||
d8e1edd6d3 | |||
a1f1e90626 | |||
522d745883 | |||
8ffb81cdf3 | |||
ae5254c65e | |||
9d53888524 | |||
cd6dd78759 | |||
27fd49e61c | |||
a3a259556f | |||
803da75636 | |||
d1556eb6cd | |||
a7edbfe5e9 | |||
663b5beac1 | |||
7e164d2ec3 | |||
f9fb0bb477 | |||
702c7f2c30 | |||
8b348ade75 | |||
bf37f44795 | |||
698033b0cf | |||
10496363f5 | |||
14647d5778 | |||
560dde3396 | |||
7f9c2439c4 | |||
6de5d0bce8 | |||
c705a11aa7 | |||
45a196b407 | |||
07cb6adb69 | |||
5358f81ce0 | |||
5b7988be79 | |||
e6c794d68f | |||
de73fedd1b | |||
2719849a54 | |||
3011fecf0f | |||
6da0a9a201 | |||
572fe3eacb | |||
ff82f15246 | |||
b214e3f6df | |||
cb9130fdf9 | |||
925dc869a2 | |||
5f1aa619cd | |||
541c748ecb | |||
e853bddbc8 | |||
79d26b5d95 | |||
840f52a75b | |||
f955302c74 | |||
95e7d3dfc4 | |||
75f2749b19 | |||
01e5b319d1 | |||
e504163bc7 | |||
aba3f7d6bd | |||
8d74023d30 | |||
602625fc17 | |||
bbeb2d5009 | |||
51faa39636 | |||
f37bfbf9f9 | |||
ba9928831e | |||
2b6bd3d751 | |||
e96ca21c89 | |||
6ee10fe98b | |||
a567c19759 | |||
bb3a087d39 | |||
5a92fe736f | |||
88390402a4 | |||
538eb66672 | |||
0b6dfe0fd3 | |||
d5579ef2b5 | |||
836c3a5b3a | |||
f2da64adad | |||
e5704abfb3 | |||
3bf4eea1fe | |||
aa23222339 | |||
68c1670c70 | |||
914eaaaa51 | |||
5831ba2143 | |||
c167a24f09 | |||
a539d27c62 | |||
d7fc079376 | |||
3a05f7e294 | |||
03713f9bd8 | |||
2a145f4350 | |||
d049da696c | |||
5a46d0e80d | |||
926250a967 | |||
139b588795 | |||
909f18f9c7 | |||
f598495198 | |||
95d746504d | |||
9a2e1d43ea | |||
be844978c1 | |||
60a361f963 | |||
93f50451e6 | |||
0936812df0 | |||
50351f56f8 | |||
232ceed8b0 | |||
b6c37a73b1 | |||
5967666df6 | |||
bf035333cf | |||
f93d1173e2 | |||
08bf4faeee | |||
e2b2cf0175 | |||
d32a24004e | |||
1f04e4e6be | |||
778dcf97b1 | |||
957fbdb907 | |||
e169b851ee | |||
7fadb4c5ad | |||
a20db7f341 | |||
b5f4739ae5 | |||
4bc03fbf06 | |||
1d3ff143d2 | |||
6918b8a291 | |||
3cd37682d3 | |||
19a990b095 | |||
87a4f02f18 | |||
8a99fc0505 | |||
bac99deb6c | |||
e65850b1eb | |||
77338c6054 | |||
a6e52ed3df | |||
4a9eadf71a | |||
b8f6cf4f23 | |||
e8abc1137b | |||
8507688c50 | |||
5718096224 | |||
d76e61e6f4 | |||
232817c00d | |||
86af585df3 | |||
9e770ea484 | |||
9670f11554 | |||
dc369d52cb | |||
33c755fc54 | |||
c5adc0eb71 | |||
fcb1de8a86 | |||
6df83ad148 | |||
857a436677 | |||
c6091750b0 | |||
64e7324285 | |||
d5bd0ee781 | |||
3b91b38014 | |||
165d4e2732 | |||
098dfacce8 | |||
44d1419af9 | |||
d0d077642d | |||
dc04839fab | |||
4ce0cb4b35 | |||
5100c36c06 | |||
b184360eb7 | |||
02d79de17c | |||
cf27c66132 | |||
53d9ed5adb | |||
3fe5051098 | |||
f7c8a989b6 | |||
65dcfd3549 | |||
6976fc54ca | |||
0e077ff5c4 | |||
c2f171a729 | |||
fea38758e4 | |||
444733565b | |||
96d28f00cc | |||
70cc79a77f | |||
8d10186fdf | |||
6f7e0205f8 | |||
7ef11817c1 | |||
c387c84861 | |||
ae7ad9f667 | |||
c55f1185e6 | |||
1619666bef | |||
bf784f6fd7 | |||
13e330fa65 | |||
827b133534 | |||
4067d4b00f | |||
359d8c5c6a | |||
265b7364e8 | |||
dc2b8c9e4c | |||
37869fd049 | |||
d7ada4d493 | |||
f093f85dbf | |||
1cf17872ab | |||
c79751829b | |||
7a21c03896 | |||
54f07139db | |||
d78990fbd5 | |||
9ed7dbc838 | |||
9b12c7bc57 | |||
8973c75bbc | |||
f425df7b6d | |||
a44b600c5e | |||
7f0a42c2d5 | |||
60cd864226 | |||
71cf02915e | |||
327d2298fb | |||
2ca11ed692 | |||
0224815a60 | |||
df824c36d2 | |||
66e7777b1a | |||
7ff85a86bf | |||
7b3700c2c6 | |||
04679aefd6 | |||
5190639b77 | |||
0bf73abb39 | |||
7e0211924d | |||
a8a857a7ce | |||
1d18965a26 | |||
e020b86a3f | |||
1b80b90609 | |||
efc3512994 | |||
acb8ca982f | |||
adc42cbba4 | |||
7edcb7ef5f | |||
656017c6df | |||
35db6d4a8b | |||
2741187546 | |||
c3a7ab647c | |||
92da0ec2d2 | |||
c767a49f2d | |||
ea8196b532 | |||
58f138e854 | |||
b4b6939498 | |||
bc97c07670 | |||
cf27fe5a53 | |||
449066449b | |||
eb5e32a07f | |||
708cdbe23f | |||
333de52c33 | |||
6b9932fa14 | |||
6c45689e6a | |||
1e3307c84c | |||
d0eed9857d | |||
4221763f48 | |||
184c797b0e | |||
4853e15d8a | |||
6b4b903669 | |||
05da63f2a5 | |||
5b4b073fc8 | |||
4723a83dbb | |||
78350db62d | |||
e8b71f36b2 | |||
6db9061dd1 | |||
320826a4b9 | |||
ad0edb5f4c | |||
2856c10bc3 | |||
24aa18e9ed | |||
767eca97cb | |||
73d5415ea9 | |||
e5a26cfca8 | |||
e40cd1fc0c | |||
978b7d930e | |||
0f2e3ef957 | |||
275b590e80 | |||
5d9da82d8e | |||
1a122726b7 | |||
0bd02a9272 | |||
3cce7b8b35 | |||
e3ab1f5228 | |||
4c875d9c7c | |||
e79334a6f6 | |||
a09c6d51e6 | |||
312c7b7193 | |||
ee733fee28 | |||
4d7e9d3f8a | |||
873c0a183a | |||
ea53ae8f20 | |||
686bc3380d | |||
67da20bcea | |||
561644f75b | |||
1abc89858f | |||
91c63a8ee6 | |||
563882d30b | |||
9a5eeee794 | |||
0578a692db | |||
f74f06338a | |||
1281f348bf | |||
5e76d4bfc1 | |||
2a302ea346 | |||
be90172840 | |||
b85ee895f5 | |||
93de408e07 | |||
d3662ae734 | |||
132d7795ea | |||
bf5a624209 | |||
abbdbda03a | |||
8a8593437a | |||
e203cada54 | |||
00c11c7ee9 | |||
82126b85d2 | |||
4f428c8ed1 | |||
9868af4db8 | |||
0a5d7c5efa | |||
c2754b324d | |||
5c618233cb | |||
9e91259b9e | |||
014d08f38a | |||
7998ea142b | |||
a4051dac72 | |||
e3a8892d24 | |||
ea02d77e69 | |||
4f582a6712 | |||
4769b1d452 | |||
17b18d820f | |||
26f34e75c2 | |||
6f50ac50ec | |||
5261cfcdd3 | |||
675920697f | |||
24699bf2ba | |||
5ab92ed794 | |||
8e83f0faa1 | |||
30d5add2ea | |||
6e47babf45 | |||
9b95fa1f20 | |||
c67aa14a87 | |||
23f296ef34 | |||
c6ce676ad3 | |||
fafb02b0dc | |||
53cecc8c8a | |||
db0e9ee8f8 | |||
2fac794d96 | |||
ffcd716906 | |||
85f50724db | |||
808a995741 | |||
4deb853914 | |||
470ec3354e | |||
053c2da9f1 | |||
c0e28ce66e | |||
08dd94e267 | |||
7497865d1f | |||
1888e4fe2b | |||
6746a5cbd5 | |||
baecb7bb0c | |||
28bf4b42bb | |||
c73dc425ad | |||
2138b7dcb8 | |||
8b6c4a9383 | |||
344755cbd0 | |||
63a975267c | |||
3c7d93e88d | |||
75974037bc | |||
e8a346182b | |||
e96d34f741 | |||
7dad814f19 | |||
7e67ca1413 | |||
603263549b | |||
a82b971ce7 | |||
b58c8ef2f0 | |||
274533bfdf | |||
cd6ce401e1 | |||
0c0809101d | |||
4b342376a8 | |||
fd963b9ad0 | |||
06406c0695 | |||
2b567de5c1 | |||
ef46d03760 | |||
b174f299fa | |||
09837966b9 | |||
465dce1d02 | |||
067dbad546 | |||
522970fdb9 | |||
e67aa499a6 | |||
3b68d81507 | |||
051248f2fc | |||
9a239f99f4 | |||
86c431d66e | |||
b35fe0e8e3 | |||
54905f5ceb | |||
1c9b05d992 | |||
a89c71df38 | |||
3db1f2af12 | |||
5399ff2751 | |||
bcea6027e9 | |||
a9722df7e4 | |||
474be6f7be | |||
ada9a7264b | |||
e991b302d0 | |||
eef301c6ec | |||
3fdfd0adfd | |||
358f1ffc43 | |||
349c3409df | |||
0263a2950c | |||
0364a57cae | |||
e232dd7d7e | |||
fee936b569 | |||
420115c54d | |||
312e961098 | |||
223213857f | |||
c0da81557b | |||
81945c0737 | |||
9664e3d6a1 | |||
0a8bd38e76 | |||
013054fb82 | |||
d898f716d1 | |||
1d3f144d21 | |||
de29d87487 | |||
ebef085a9c | |||
2c1f159d72 | |||
1ef59e05a5 | |||
5e09992637 | |||
30448233b1 | |||
a1601a17aa | |||
7522f7d0f7 | |||
d04b9c4c09 | |||
1a24ff9a49 | |||
13d72de82d | |||
3728fdab3f | |||
2317e3d50c | |||
5f15976c02 | |||
7f592639c5 | |||
a98402af12 | |||
316ffa91d1 | |||
c24953b57e | |||
7a1b1b7e5e | |||
70f71f64c4 | |||
5bccd07d7d | |||
d818baa6d1 | |||
249b8abf03 | |||
c134277514 | |||
f5d366cf7f | |||
ad25a2ed08 | |||
1e7a2ffe97 | |||
dd52075ff1 | |||
0253e42bd5 | |||
d99774f8d9 | |||
d563a2ec89 | |||
b4b4523193 | |||
fbcb69f447 | |||
8ae5a9c1f7 | |||
3ef5bfb6eb | |||
4016ded584 | |||
5b0b4adb1c | |||
f1ec3b0c75 | |||
b5d55a2066 | |||
0d2c9fe377 | |||
2c7cc9a796 | |||
2e1d623755 | |||
52fee8f842 | |||
6ba17e8e30 | |||
ac3432920a | |||
63c88be533 | |||
3cb577e6ba | |||
1e0d64c548 | |||
bc1b9ff59c | |||
7d73bed3be | |||
126fbdfd60 | |||
15094436fd | |||
010c653995 | |||
119f82fd4e | |||
3bbf4de5d2 | |||
0807f3b87b | |||
4e9b3b40aa | |||
cc444811db | |||
50c8525012 | |||
aedad497e8 | |||
b1b231e645 | |||
dc46fd225a | |||
6226de7cff | |||
37327ec674 | |||
c071c81403 | |||
85d75a013a | |||
3816b36131 | |||
dc7965267b | |||
ce9a6bced7 | |||
85325dc710 | |||
ac4050df70 | |||
a16a53167b | |||
afab3cf847 | |||
8fdaeb7bac | |||
7e0f9f6e0d | |||
5b1bf6cd88 | |||
b1584c352b | |||
b06b83503c | |||
b03d89c190 | |||
f53548d10f | |||
5ec2f54d7f | |||
db588ff961 | |||
2b7006a14c | |||
8f5f07882f | |||
0eee8e7464 | |||
3725a5b644 | |||
c84c0ac64d | |||
098e07988c | |||
66bb702aca | |||
03ff2fedf0 | |||
c707f47b11 | |||
585efa3ff5 | |||
07d0b98a23 | |||
c7c0f01010 | |||
cf6b17250a | |||
90503a490c | |||
ebdd53b99b | |||
51a5d2e812 | |||
2ad509d56a | |||
1a98bfba36 | |||
d05bb6c60e | |||
ed81b6a6aa | |||
264914588f | |||
05df43b426 | |||
0334a4e176 | |||
38dca425da | |||
82d4a79dd4 | |||
6725be8145 | |||
f5b693f01b | |||
f09f23e570 | |||
4f4d05b8cd | |||
0c5b5ff49c | |||
a815fad3f1 | |||
d8b1c7c10a | |||
02e1aea80c | |||
1892f7e0f4 | |||
b7b50349a7 | |||
02d227ee02 | |||
47f8938b89 | |||
4945a640a7 | |||
0136977359 | |||
0acd3e20b0 | |||
30bdfeee37 | |||
7ea665d884 | |||
073edcfb12 | |||
a645366a25 | |||
12aa0b7abd | |||
3f98a50410 | |||
24c8c076d5 | |||
37e6931d33 | |||
86493568e9 | |||
bb51436ae3 | |||
854a55ac1a | |||
cfb4b080d3 | |||
00aa2e4e17 | |||
69c67d99f6 | |||
65596ec8c1 | |||
49643cb00e | |||
35b0faee57 | |||
88ef4d69b2 | |||
575b6ca222 | |||
b5a0e844d2 | |||
2642e11ce2 | |||
b4fe655efe | |||
ffb761909a | |||
b443e1ac6e | |||
a4792f54a7 | |||
686ae029e0 | |||
f3fd2e7d0f | |||
7efd9ba0a5 | |||
1c2a6bb8a1 | |||
7bcf1cbdd5 | |||
2aaa2544bd | |||
d85f03ba20 | |||
cfb51a6be4 | |||
c9d778c94b | |||
fd62f882de | |||
adc050f190 | |||
2d551b9fc5 | |||
884acdde32 | |||
8f896de794 | |||
5e4e26d2fd | |||
ae688e6615 | |||
c4c812bdf6 | |||
e620fc0283 | |||
c333902468 | |||
4c83ecd06a | |||
b28a547dc4 | |||
6bc17e05bd | |||
0903350d30 | |||
6c0f19b457 | |||
e119dc823f | |||
43295c9c57 | |||
ded8b54042 | |||
50a3178d51 | |||
393c226032 | |||
f2630df387 | |||
abcd2c1750 | |||
cc95f3b5b5 | |||
a08ee93b43 | |||
4b90f873d5 | |||
419ab8e0b1 | |||
c95ef27998 | |||
63dfd93834 | |||
57610881de | |||
7469faf296 | |||
55a884a559 | |||
ee2b3c3d10 | |||
e5819a260b | |||
a3ecf48702 | |||
1c0b904cd2 | |||
072d8a1728 | |||
964e541c32 | |||
78fec4ed22 | |||
ef111d36c9 | |||
4f64193e85 | |||
89bb6d1268 | |||
9f4226bf0f | |||
a87c2a3374 | |||
d7294ba5a0 | |||
82d286dc6f | |||
1fa18ab997 | |||
afc90f32c9 | |||
e9cfb7c21e | |||
1af8ea3769 | |||
9f7af190f1 | |||
9c703fe94d | |||
a7a11a4f13 | |||
c32c3bb62b | |||
e29d1480a6 | |||
8f299d7791 | |||
65fb2e992e | |||
41f5d677d5 | |||
a2b78b8cd9 | |||
c93f217033 | |||
82c47b6e9a | |||
94fb738c67 | |||
89071e40fc | |||
95a90c410e | |||
59fc371cd5 | |||
9b404e330d | |||
1667f9b2ef | |||
caadfc8641 | |||
bffc2e70c1 | |||
8b686f0b12 | |||
def8d1e0cb | |||
ca28c34be0 | |||
196bc3ea00 | |||
b15267be4d | |||
5c074f6f5f | |||
04cba61888 | |||
a41e2e1ceb | |||
d1d03c98ba | |||
679942159e | |||
3e48a54ab5 | |||
f6e389ff62 | |||
63c309bd12 | |||
561ec57cc8 | |||
3cefd7bd1e | |||
c63feb488c | |||
12c418d84d | |||
4b982f815c | |||
d4d3346b6d | |||
6010a103e0 | |||
5dc1da2af0 | |||
f2ccc4d963 | |||
a92d48efdd | |||
b633206b45 | |||
b6f3d2af5e | |||
5fd77d9fcc | |||
5ca4494eed | |||
de7e419ef4 | |||
20a6b3fc33 | |||
540414d8f5 | |||
abcdb8ced0 | |||
5076d73695 | |||
d88735f84e | |||
2244f0ab76 | |||
40c85d6104 | |||
42892e24f4 | |||
e6357d2ac8 | |||
1eecd85ceb | |||
c27557826b | |||
88150b6535 | |||
d63176da19 | |||
887da5aa9a | |||
6e7f1151bc | |||
b2aebcc5d3 | |||
ae9ad0fa65 | |||
fb6d852827 | |||
ba17612461 | |||
a15c7a0213 | |||
7e321d4016 | |||
a05cd5678b | |||
2ccf007b9a | |||
895b8c2c80 | |||
0f175174f6 | |||
493466683c | |||
761c342c51 | |||
5341da28d9 | |||
7768f41849 | |||
fa8993191e | |||
239ce28575 | |||
c52a49f747 | |||
e4b9895ba7 | |||
92a2bb4d32 | |||
bfec722312 | |||
5a3f7b5b70 | |||
2aa097be46 | |||
8a646d85c6 | |||
890b3eaa00 | |||
cda28ebf15 | |||
2245027ca3 | |||
3dc250f801 | |||
66e786a1b0 | |||
1e26926350 | |||
8bd7ea5bbc | |||
6eb36abe2e | |||
6fced3fab2 | |||
774e456e54 | |||
519859e1c5 | |||
26f0c488e5 | |||
1b0b53fbd0 | |||
35f4ea29f9 | |||
fff39d9879 | |||
444e761d41 | |||
68a3def35a | |||
d9426d301d | |||
8bcf7109a3 | |||
3effdf0f4d | |||
3c122bcf53 | |||
037ff52f4f | |||
b11f8acba1 | |||
ef9a633aa4 | |||
c7e2f979dd | |||
e97bb9c933 | |||
fa506b5bf8 | |||
e3193a92d0 | |||
d76dabdca6 | |||
d219f50912 | |||
e08710a19c | |||
4e167b35be | |||
16873384a8 | |||
f87339f9fa | |||
5f5e5e3211 | |||
f724db8226 | |||
c7e90cd7df | |||
8c5b00b1a3 | |||
a3b79fbcd8 | |||
9db77e6351 | |||
5bc1eaec9f | |||
81c9ce7284 | |||
caa6978d80 | |||
af22d6a4e3 | |||
0eabb3c37c | |||
2b84791391 | |||
6f896cb096 | |||
9a488c60f2 | |||
9cb50446f4 | |||
8c00a2359e | |||
d1ff34d16d | |||
8e8615dab8 | |||
a63ed4d3b4 | |||
968c820702 | |||
3061b4dfd2 | |||
ed4de612dd | |||
d4bdd5fd9c | |||
8b71556425 | |||
ae6e1bfd85 | |||
6d1f3b73ef | |||
0dcaf80c7f | |||
fc9cd5bdf0 | |||
a434c45196 | |||
87b316ec23 | |||
9c99ffae57 | |||
30a3a84ec9 | |||
d0f585df9d | |||
bac2db5cda | |||
c35bf2f483 | |||
2e04c5e39c | |||
9dcf16e819 | |||
361d494cde | |||
4d7015294e | |||
5f16fb4668 | |||
4bf2228675 | |||
2ba823f192 | |||
27fa2d5b69 | |||
47ef7661d8 | |||
3f6ff25322 | |||
f56c23009a | |||
e80593fb7b | |||
57324345ac | |||
73e280157d | |||
cfaa5766ed | |||
8b08db308b | |||
3e2ff55954 | |||
70d1d0d230 | |||
94e0048a3b | |||
a34d1641b3 | |||
40c645e433 | |||
b2e5415a35 | |||
365ee4cf0b | |||
2b4603a234 | |||
ec23eae21d | |||
7a9229628a | |||
9db5c0f375 | |||
27bde55f54 | |||
2bb24282d2 | |||
998472e463 | |||
63ff46a768 | |||
660f43e3b7 | |||
0ba96aa4b8 | |||
d85247d2ad | |||
9ca85ed365 | |||
93113fd871 | |||
b5d360594a | |||
d5ae79c38c | |||
7cf07b27e3 | |||
bb0f986b0c | |||
2c2a85327f | |||
7bf03e497b | |||
7a4dee3d38 | |||
7b27d6f0bb | |||
83dc95a0a7 | |||
d60889f952 | |||
8c9952973d | |||
00673bdb7f | |||
d039890a9b | |||
41e88c07fe | |||
67c5027b16 | |||
a341d4f800 | |||
e3833914b3 | |||
49cdec6961 | |||
3ad1834439 | |||
4b492eae85 | |||
f0ff47af8d | |||
991826b686 | |||
22d59a1ed7 | |||
475ea68696 | |||
864e84706a | |||
9c93e76eeb | |||
7fa1b65af0 | |||
c00c95efcf | |||
94be2b46d5 | |||
4b4d0d2d19 | |||
0d06cf63b7 | |||
7b24c02d51 | |||
becf488714 | |||
e89e8226e4 | |||
a533a96598 | |||
27321c0919 | |||
058472d325 | |||
b5c9a03052 | |||
07dad3affa | |||
8afc103ae7 | |||
591d7b4b80 | |||
2162afc78e | |||
25e226d219 | |||
8472bfe90d | |||
93645b2fbe | |||
d53c987f2e | |||
682693a9f0 | |||
e836faf792 | |||
6e27233be8 | |||
9209984a2f | |||
1477630c78 | |||
ab670080c7 | |||
8198f98376 | |||
65b4697229 | |||
e75a1a8b70 | |||
580494fea7 | |||
5a958da84d | |||
cad602ad14 | |||
1f14bd6188 | |||
156f52b76f | |||
d674b8ac71 | |||
861150971f | |||
a653421514 | |||
8f234a02cb | |||
92ecf99427 | |||
705dbf12d7 | |||
fe11b11c13 | |||
f2a43ad1f3 | |||
cbbe5cfb25 | |||
0eccc6085b | |||
a89da1f705 | |||
5b297e539a | |||
1d932c3753 | |||
5a77fc74ba | |||
7b47b96252 | |||
a4bec83ecc | |||
8509a0de18 | |||
8e30b7430d | |||
9235d32a45 | |||
dd503570ac | |||
613281a1e7 | |||
bab7bf6633 | |||
1831692761 | |||
e144d2479b | |||
c25831316e | |||
60b72aabe8 | |||
c8fcb0ab18 | |||
9911d18390 | |||
e24630ac1e | |||
4c1fd3edae | |||
f65492dd66 | |||
5d978c7670 | |||
11788cece9 | |||
1aaa55dc62 | |||
ce57a2b8fb | |||
0604cc5bd0 | |||
3d2c0bcc6c | |||
0f222979a6 | |||
a1eb6a14f5 | |||
186ce01022 | |||
0096ec1d12 | |||
2929d7bf51 | |||
d90fb5764d | |||
4dccd0c733 | |||
300d912331 | |||
9d21c89151 | |||
24a8c4015c | |||
5eb40d6b7f | |||
36f486e91b | |||
5b684ac26e | |||
85062725bd | |||
401d9c8565 | |||
6f276ac1bc | |||
4350785cef | |||
9a2a85ac3d | |||
d030a61322 | |||
dacb6dca41 | |||
c40fc69087 | |||
eff983135c | |||
479303dd9e | |||
e9b2088f7d | |||
4af5b94013 | |||
441398402d | |||
258d4fda3f | |||
8e667f6c3f | |||
a996cc2e6d | |||
9b8a8690e7 | |||
f2387fd6b5 | |||
888036a99d | |||
539c0ed7f0 | |||
95e065a462 | |||
087f20cb6c | |||
7adf321956 | |||
dc749462ec | |||
16b57f24a2 | |||
b16b1c3e8b | |||
fee56873b5 | |||
e1b2b72cd2 | |||
daf4e5ce6c | |||
2ec2c7263f | |||
abfcab552f | |||
cfdf8b1670 | |||
f23e2a3ec4 | |||
aa1ac3da50 | |||
c9c7316b7d | |||
d152d5cd90 | |||
6fd37710e1 | |||
0419a3c19a | |||
0c382da561 | |||
9fc7f287d2 | |||
dd7c4850f0 | |||
93992ec3ed | |||
15d9adfbf1 | |||
676a914c40 | |||
b423b4eec1 | |||
9784a89112 | |||
7b596e6d9c | |||
76febcf238 | |||
a57a72de88 | |||
235b307b06 | |||
05b0f6d0f7 | |||
1d7081d8b8 | |||
c0174c0c2c | |||
fa8324c1f9 | |||
4b0951caec | |||
0d51c99717 | |||
24623c59d7 | |||
88044f6b76 | |||
38edbf8362 | |||
bc0acf5701 | |||
a82f181126 | |||
be0139a46f | |||
4db5b4f2b1 | |||
93cefced80 | |||
85f586f623 | |||
2be1f97419 | |||
63014231ab | |||
3ac37497ab | |||
d0cafb020f | |||
d3b3198b68 | |||
c1f17ff63b | |||
dafd958f69 | |||
f51af6c61c | |||
254db22063 | |||
8be4256278 | |||
8e8669d63f | |||
4625ff92f1 | |||
6aa84326af | |||
9a384d81fe | |||
0cbe36c048 | |||
7f16aa8c7e | |||
872f8a6229 | |||
9b261daa6d | |||
c46c15c258 | |||
a8ba1ed1ed | |||
ff4056d4f3 | |||
ae152c3ffa | |||
e2ff33d7db | |||
ce94c05fd3 | |||
9cde4dc7e2 | |||
ca571cd756 | |||
e5eb0c79c0 | |||
43bd6587d3 | |||
3bb059ab74 | |||
4c963d6edf | |||
396bc7f7b4 | |||
2896a9b26f | |||
9267a45449 | |||
c430d470c4 | |||
3921a3ca22 | |||
1ff0a98d30 | |||
f0efd52cb7 | |||
bb8fa88688 | |||
4b976c13c1 | |||
f68d4efcdd | |||
fea247b218 | |||
f419c56a3c | |||
a5fca7a1c4 | |||
e18d0b5d51 | |||
9952cdca7f | |||
6278145374 | |||
84018a5caa | |||
d7785fe2d2 | |||
e1751c4d91 | |||
913da79ff4 | |||
a4fbb2de7e | |||
b5601ed5e6 | |||
42c4f15f22 | |||
6fbd9b2628 | |||
d04bfb58a2 | |||
cded2548f5 | |||
dcc859a86a | |||
9bec38559f | |||
2856454d41 | |||
b3c4fc4003 | |||
c2bbc04c4c | |||
db40c7bc32 | |||
60707fdbd1 | |||
f05614f4da | |||
a10c382bd4 | |||
da2fb876cb | |||
3c58bff803 | |||
a28814bc0e | |||
3cff8261ae | |||
b16e8f7b76 | |||
57ab001c0c | |||
3d85dace38 | |||
7a04c2974f | |||
d459839bf7 | |||
657cfe1b23 | |||
f4eaa0f01f | |||
1e2ffcadf0 | |||
dcc05af02e | |||
4b7f78f38b | |||
f94ff4cc74 | |||
b750663a1f | |||
4c4b76e995 | |||
da19d2c1a7 | |||
fb15c5b354 | |||
6ffe1cfcab | |||
87678c58ac | |||
feab4cc48a | |||
712946f512 | |||
a7bfceae05 | |||
8a26cd549a | |||
1cf3ce0617 | |||
73c65fada2 | |||
92ea923c03 | |||
e7db453717 | |||
10ee09f052 | |||
be7d91a138 | |||
3278c80d3f | |||
65e1edb0b8 | |||
e05c88370f | |||
15c29f8419 | |||
fc722731d3 | |||
1c9c564e90 | |||
872b60f8ea | |||
0d3364b3da | |||
fed53661b3 | |||
e86b4d89ca | |||
c5cb32f6dd | |||
deb56e16ec | |||
b5626ef01c | |||
e39d9067f2 | |||
43d34d5d35 | |||
7341be76bb | |||
0abd62dfe8 | |||
735012e3d7 | |||
b5efb8d2e6 | |||
1dbeabb716 | |||
671f9e56e2 | |||
dc6c189948 | |||
4501824f3f | |||
4568d2a98e | |||
f5d81334f8 | |||
f3ed90399b | |||
fada01cec9 | |||
1b4b9fb4cc | |||
6eeef8a866 | |||
24979a0af2 | |||
be1a44f018 | |||
9fcc2903fc | |||
06df63b283 | |||
0f1efc16f5 | |||
da8a06952c | |||
38d810cef7 | |||
393a3a2b8f | |||
aaddc580d1 | |||
957d478865 | |||
023913a852 | |||
6c51d83f61 | |||
0edaedb6ab | |||
13f21aa0d6 | |||
929a0c37bd | |||
058ccf56d0 | |||
162ac572da | |||
c7f3fdb46d | |||
29af07b3f9 | |||
758436a428 | |||
e0cadb4f62 | |||
013dfa1b61 | |||
e0f1c50534 | |||
d50dc2e68e | |||
8b5b18c97e | |||
f7383b4cc8 | |||
1bc32285ba | |||
f12114f9aa | |||
2b6faa8d20 | |||
45b7df6ac9 | |||
5a43ce2719 | |||
fe31dc8606 | |||
f0615482d9 | |||
03c47e6f7d | |||
4111b8a5a3 | |||
5b5a2e8c25 | |||
9ec0c23c52 | |||
9a5034c13c | |||
b1fcf4524a | |||
87d384dba5 | |||
4f5a8f7953 | |||
8728356698 | |||
9c30476fc8 | |||
09beb57eaf | |||
76a36d1829 | |||
0d4036efa2 | |||
cb4562aad5 | |||
0084d4766b | |||
74ddcfa01e | |||
ed36fba0d7 | |||
af015d435b | |||
ec59980e6f | |||
f0f4247c5d | |||
b562094956 | |||
4afd55c441 | |||
d7404f418d | |||
893410911c | |||
556b581b6a | |||
1685ccaca8 | |||
522abcfdfd | |||
ed1827ff28 | |||
214b2d1c1c | |||
322518e9dc | |||
ea2dd536b4 | |||
6a1eca760a | |||
29513d4ded | |||
57daf27fdd | |||
e698d90e3c | |||
86ca081030 | |||
14841ad7c9 | |||
2c6aa12aab | |||
ef4d39db3c | |||
7a566c477d | |||
85c40aef23 | |||
d00fa42553 | |||
e9e94f5e99 | |||
5e2d4407ca | |||
846bd08e20 | |||
a1a4eed860 | |||
1e582625f3 | |||
39b018fdf3 | |||
83304de1c6 | |||
5c8e03dcbf | |||
4dddc539f6 | |||
9950b781b4 | |||
7a32f692d1 | |||
d480be925b | |||
3775317047 | |||
500bdd9bf1 | |||
57bda24664 | |||
6401af00fe | |||
3b3a18bbbc | |||
b4e9dfeeaf | |||
16f5def245 | |||
26e7de534b | |||
a3ae694048 | |||
b04d70f141 | |||
101d6131c7 | |||
faabd68f6f | |||
aa72b814da | |||
0dcda0f289 | |||
a2b039f983 | |||
1a54f2d01a | |||
4276994265 | |||
2c6133b4f7 | |||
64181d1a93 | |||
25e9a27a78 | |||
f3edaf5160 | |||
7bfdf2d11d | |||
d2808cf662 | |||
b68fcec692 | |||
86644d38d7 | |||
8cafa8a483 | |||
724af44e41 | |||
bac9ef4f93 | |||
ada6f3b844 | |||
c8a26ce952 | |||
6cf80b7533 | |||
79df523bb2 | |||
e921f9757a | |||
bed9737d64 | |||
2583eb15ec | |||
1879ea55e8 |
6
.circleci/can-build.sh
Executable file
6
.circleci/can-build.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
echo "Checking if it is possible to build Bitcoin only..."
|
||||
cd ../BTCPayServer.Tests
|
||||
docker-compose -f "docker-compose.yml" build
|
75
.circleci/config.yml
Normal file
75
.circleci/config.yml
Normal file
@ -0,0 +1,75 @@
|
||||
version: 2
|
||||
jobs:
|
||||
fast_tests:
|
||||
machine:
|
||||
image: ubuntu-2004:2024.11.1
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
command: |
|
||||
cd .circleci && ./run-tests.sh "Fast=Fast|ThirdParty=ThirdParty" && ./can-build.sh
|
||||
selenium_tests:
|
||||
machine:
|
||||
image: ubuntu-2004:2024.11.1
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
command: |
|
||||
cd .circleci && ./run-tests.sh "Selenium=Selenium"
|
||||
integration_tests:
|
||||
machine:
|
||||
image: ubuntu-2004:2024.11.1
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
command: |
|
||||
cd .circleci && ./run-tests.sh "Integration=Integration"
|
||||
trigger_docs_build:
|
||||
machine:
|
||||
image: ubuntu-2004:2024.11.1
|
||||
steps:
|
||||
- run:
|
||||
command: |
|
||||
curl -X POST -H "Authorization: token $GH_PAT" -H "Accept: application/vnd.github.everest-preview+json" -H "Content-Type: application/json" https://api.github.com/repos/btcpayserver/btcpayserver-doc/dispatches --data '{"event_type": "build_docs"}'
|
||||
# publish jobs require $DOCKERHUB_REPO, $DOCKERHUB_USER, $DOCKERHUB_PASS defined
|
||||
docker:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- setup_remote_docker
|
||||
- checkout
|
||||
- run:
|
||||
command: |
|
||||
LATEST_TAG=${CIRCLE_TAG:1} #trim v from tag
|
||||
GIT_COMMIT=$(git rev-parse HEAD)
|
||||
#
|
||||
docker login --username=$DOCKERHUB_USER --password=$DOCKERHUB_PASS
|
||||
docker buildx create --use
|
||||
DOCKER_BUILDX_OPTS="--platform linux/amd64,linux/arm64,linux/arm/v7 --build-arg GIT_COMMIT=${GIT_COMMIT} --push"
|
||||
docker buildx build $DOCKER_BUILDX_OPTS -t $DOCKERHUB_REPO:$LATEST_TAG .
|
||||
workflows:
|
||||
version: 2
|
||||
build_and_test:
|
||||
jobs:
|
||||
- fast_tests
|
||||
- selenium_tests
|
||||
- integration_tests
|
||||
publish:
|
||||
jobs:
|
||||
- trigger_docs_build:
|
||||
filters:
|
||||
branches:
|
||||
ignore: /.*/
|
||||
# only act on version tags
|
||||
tags:
|
||||
only: /(v[1-9]+(\.[0-9]+)*(-[a-z0-9-]+)?)|(v[a-z0-9-]+)/
|
||||
- docker:
|
||||
filters:
|
||||
# ignore any commit on any branch by default
|
||||
branches:
|
||||
ignore: /.*/
|
||||
# only act on version tags v1.0.0.88 or v1.0.2-1
|
||||
# OR feature tags like vlndseedbackup
|
||||
# OR features on specific versions like v1.0.0.88-lndseedbackup-1
|
||||
tags:
|
||||
only: /(v[1-9]+(\.[0-9]+)*(-[a-z0-9-]+)?)|(v[a-z0-9-]+)/
|
18
.circleci/run-tests.sh
Executable file
18
.circleci/run-tests.sh
Executable file
@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
cd ../BTCPayServer.Tests
|
||||
docker-compose --version
|
||||
docker-compose -f "docker-compose.altcoins.yml" down -v
|
||||
|
||||
# For some reason, docker-compose pull fails time to time, so we try several times
|
||||
n=0
|
||||
until [ "$n" -ge 10 ]
|
||||
do
|
||||
docker-compose -f "docker-compose.altcoins.yml" pull && break
|
||||
n=$((n+1))
|
||||
sleep 5
|
||||
done
|
||||
|
||||
docker-compose -f "docker-compose.altcoins.yml" build
|
||||
docker-compose -f "docker-compose.altcoins.yml" run -e "TEST_FILTERS=$1" tests
|
@ -10,10 +10,15 @@ root = true
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
charset = utf-8
|
||||
space_before_self_closing = true
|
||||
|
||||
[project.json]
|
||||
[*.json]
|
||||
indent_size = 2
|
||||
|
||||
[swagger*.json]
|
||||
indent_size = 4
|
||||
|
||||
# C# files
|
||||
[*.cs]
|
||||
# New line preferences
|
||||
@ -66,7 +71,7 @@ dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
|
||||
dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
|
||||
|
||||
dotnet_naming_style.camel_case_underscore_style.required_prefix = _
|
||||
dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
|
||||
dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
|
||||
|
||||
# Code style defaults
|
||||
dotnet_sort_system_directives_first = true
|
||||
@ -120,8 +125,11 @@ csharp_space_between_method_declaration_name_and_open_parenthesis = false
|
||||
csharp_space_between_method_declaration_parameter_list_parentheses = false
|
||||
csharp_space_between_parentheses = false
|
||||
csharp_space_between_square_brackets = false
|
||||
csharp_style_prefer_null_check_over_type_check = true:warning
|
||||
csharp_prefer_simple_using_statement = true:warning
|
||||
|
||||
# C++ Files
|
||||
|
||||
[*.{cpp,h,in}]
|
||||
curly_bracket_next_line = true
|
||||
indent_brace_style = Allman
|
||||
@ -146,4 +154,4 @@ indent_size = 2
|
||||
[*.sh]
|
||||
end_of_line = lf
|
||||
[*.{cmd, bat}]
|
||||
end_of_line = crlf
|
||||
end_of_line = crlf
|
||||
|
2
.github/FUNDING.yml
vendored
Normal file
2
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# These are supported funding model platforms
|
||||
custom: https://foundation.btcpayserver.org
|
68
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
68
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
name: 🐛 Bug Report
|
||||
description: File a bug report
|
||||
title: "[Bug]: "
|
||||
labels: ["bug"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report! Please provide as much information as you can. It helps us better understand the problem and fix it faster.
|
||||
- type: textarea
|
||||
id: version
|
||||
attributes:
|
||||
label: What is your BTCPay version?
|
||||
description: You can see the version in the footer's bottom right corner
|
||||
placeholder: I'm running BTCPay v1.X.X.X
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: deployment
|
||||
attributes:
|
||||
label: How did you deploy BTCPay Server?
|
||||
description: Docker, manual, third-party host? Read more on deployment methods [here](https://docs.btcpayserver.org/Deployment/)
|
||||
placeholder: I'm running BTCPay Server on a...
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: What happened?
|
||||
description: A clear and concise description of what the bug is.
|
||||
placeholder: Tell us what you see!
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduce
|
||||
attributes:
|
||||
label: How did you encounter this bug?
|
||||
description: Step by step describe how did you encounter the bug?
|
||||
placeholder: 1. I clicked X 2. Then I clicked Y 3. See error
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logoutput
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. Logs can be found in Server Settings > Logs. Here's how you can [troubleshoot an issue](https://docs.btcpayserver.org/Troubleshooting/)
|
||||
render: shell
|
||||
- type: textarea
|
||||
id: browser
|
||||
attributes:
|
||||
label: What browser do you use?
|
||||
description: Provide your browser and it's version. If you replicated issues on multiple browsers, let us know which ones.
|
||||
placeholder: For example Safari 15.00, Chrome 10.0, Tor, Edge, etc
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: additonal
|
||||
attributes:
|
||||
label: Additional information
|
||||
description: Feel free to provide additional information. Screenshots are always helpful.
|
||||
- type: checkboxes
|
||||
id: terms
|
||||
attributes:
|
||||
label: Are you sure this is a bug report?
|
||||
description: By submitting this report, you agree that this is not a support or a feature request. For general questions please read our [documentation](https://docs.btcpayserver.org). You can ask questions in [discussions](https://github.com/btcpayserver/btcpayserver/discussions) and [on our community chat](https://chat.btcpayserver.org)
|
||||
options:
|
||||
- label: I confirm this is a bug report
|
||||
required: true
|
17
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
17
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: 💡 Request a feature
|
||||
url: https://github.com/btcpayserver/btcpayserver/discussions/categories/ideas-feature-requests
|
||||
about: Submit a feature request or vote on ideas posted by others. Features with most upvotes become roadmap candidates
|
||||
- name: 🧑💻 Ask a technical question
|
||||
url: https://github.com/btcpayserver/btcpayserver/discussions/new?category=technical-support
|
||||
about: If you're experiencing a technical problem post it to our community support forum
|
||||
- name: 🔌 Report a problem with a plugin
|
||||
url: https://github.com/btcpayserver/btcpayserver/discussions/new?category=plugins-integrations
|
||||
about: Experiencing a problem with a third-party plugin? Post it here and we will tag their developers to assist
|
||||
- name: 📝 Official Documentation
|
||||
url: https://docs.btcpayserver.org
|
||||
about: Check our documentation for answers to common questions
|
||||
- name: 💬 Community Support Chat
|
||||
url: https://chat.btcpayserver.org/
|
||||
about: Ask general questions and get community support in real-time
|
2
.github/codeql/codeql-config.yml
vendored
Normal file
2
.github/codeql/codeql-config.yml
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
paths-ignore:
|
||||
- 'BTCPayServer/wwwroot/vendor/**/*.js'
|
80
.github/workflows/codeql.yml
vendored
Normal file
80
.github/workflows/codeql.yml
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
# Allow running tests manually. Usefull if scan failure, or need to rescan before next scheduled date.
|
||||
workflow_dispatch:
|
||||
# We scan only on a schedule for now, can uncomment the following to scan on commit or PR merge later on if deemed appropriate.
|
||||
# push:
|
||||
# branches: [ "master" ]
|
||||
# pull_request:
|
||||
# branches: [ "master" ]
|
||||
schedule:
|
||||
# Scan every Monday 06:00 UTC.
|
||||
- cron: '0 6 * * 1'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'javascript', 'csharp' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Use only 'java' to analyze code written in Java, Kotlin or both
|
||||
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
|
||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
|
||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||
|
||||
# - run: |
|
||||
# echo "Run, Build Application using script"
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
17
.gitignore
vendored
17
.gitignore
vendored
@ -266,6 +266,7 @@ paket-files/
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
.run
|
||||
|
||||
# CodeRush
|
||||
.cr/
|
||||
@ -288,8 +289,16 @@ __pycache__/
|
||||
*.xsd.cs
|
||||
/BTCPayServer/Build/dockerfiles
|
||||
|
||||
# Bundling JS/CSS
|
||||
BTCPayServer/wwwroot/bundles/*
|
||||
!BTCPayServer/wwwroot/bundles/.gitignore
|
||||
.vscode/*
|
||||
!.vscode/launch.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/extensions.json
|
||||
BTCPayServer/testpwd
|
||||
.DS_Store
|
||||
Packed Plugins
|
||||
Plugins/packed
|
||||
|
||||
.vscode
|
||||
BTCPayServer/wwwroot/swagger/v1/openapi.json
|
||||
BTCPayServer/appsettings.dev.json
|
||||
BTCPayServer.Tests/monero_wallet
|
||||
/BTCPayServer.Tests/NewBlocks.bat
|
||||
|
3
.vscode/extensions.json
vendored
Normal file
3
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"recommendations": ["ms-dotnettools.csharp"]
|
||||
}
|
33
.vscode/launch.json
vendored
Normal file
33
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
{
|
||||
// Use IntelliSense to find out which attributes exist for C# debugging
|
||||
// Use hover for the description of the existing attributes
|
||||
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": ".NET Core Launch (web)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
// If you have changed target frameworks, make sure to update the program path.
|
||||
"program": "${workspaceFolder}/BTCPayServer/bin/Debug/net8.0/BTCPayServer.dll",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}/BTCPayServer",
|
||||
"stopAtEntry": false,
|
||||
// Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
|
||||
"serverReadyAction": {
|
||||
"action": "openExternally",
|
||||
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
|
||||
},
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/Views": "${workspaceFolder}/Views"
|
||||
},
|
||||
"logging": {
|
||||
"moduleLoad": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
42
.vscode/tasks.json
vendored
Normal file
42
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "build",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"build",
|
||||
"${workspaceFolder}/BTCPayServer/BTCPayServer.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "publish",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"publish",
|
||||
"${workspaceFolder}/BTCPayServer/BTCPayServer.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "watch",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"watch",
|
||||
"run",
|
||||
"${workspaceFolder}/BTCPayServer/BTCPayServer.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
}
|
||||
]
|
||||
}
|
41
BTCPayServer.Abstractions/BTCPayServer.Abstractions.csproj
Normal file
41
BTCPayServer.Abstractions/BTCPayServer.Abstractions.csproj
Normal file
@ -0,0 +1,41 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="../Build/Version.csproj" Condition="Exists('../Build/Version.csproj')" />
|
||||
<Import Project="../Build/Common.csproj" />
|
||||
|
||||
<PropertyGroup>
|
||||
<Company>BTCPay Server</Company>
|
||||
<Copyright>Copyright © BTCPay Server 2020</Copyright>
|
||||
<Description>A library for BTCPay Server plugin development</Description>
|
||||
<PackageIcon>icon.png</PackageIcon>
|
||||
<PackageTags>btcpay,btcpayserver</PackageTags>
|
||||
<PackageProjectUrl>https://github.com/btcpayserver/btcpayserver/tree/master/BTCPayServer.Abstractions</PackageProjectUrl>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<RepositoryUrl>https://github.com/btcpayserver/btcpayserver</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
<DebugType>portable</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>1591;1573;1572;1584;1570;3021</NoWarn>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="icon.png" Pack="true" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="HtmlSanitizer" Version="8.0.838" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.11" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.11" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BTCPayServer.Client\BTCPayServer.Client.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
18
BTCPayServer.Abstractions/CamelCaseSerializerSettings.cs
Normal file
18
BTCPayServer.Abstractions/CamelCaseSerializerSettings.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BTCPayServer.Abstractions
|
||||
{
|
||||
public class CamelCaseSerializerSettings
|
||||
{
|
||||
static CamelCaseSerializerSettings()
|
||||
{
|
||||
Settings = new JsonSerializerSettings()
|
||||
{
|
||||
ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver()
|
||||
};
|
||||
Serializer = JsonSerializer.Create(Settings);
|
||||
}
|
||||
public static readonly JsonSerializerSettings Settings;
|
||||
public static readonly JsonSerializer Serializer;
|
||||
}
|
||||
}
|
21
BTCPayServer.Abstractions/Configuration/DataDirectories.cs
Normal file
21
BTCPayServer.Abstractions/Configuration/DataDirectories.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System.IO;
|
||||
|
||||
namespace BTCPayServer.Configuration
|
||||
{
|
||||
public class DataDirectories
|
||||
{
|
||||
public string DataDir { get; set; }
|
||||
public string PluginDir { get; set; }
|
||||
public string TempStorageDir { get; set; }
|
||||
public string StorageDir { get; set; }
|
||||
public string TempDir { get; set; }
|
||||
public string LangsDir { get; set; }
|
||||
|
||||
public string ToDatadirFullPath(string path)
|
||||
{
|
||||
if (Path.IsPathRooted(path))
|
||||
return path;
|
||||
return Path.Combine(DataDir, path);
|
||||
}
|
||||
}
|
||||
}
|
12
BTCPayServer.Abstractions/Constants/AuthenticationSchemes.cs
Normal file
12
BTCPayServer.Abstractions/Constants/AuthenticationSchemes.cs
Normal file
@ -0,0 +1,12 @@
|
||||
namespace BTCPayServer.Abstractions.Constants
|
||||
{
|
||||
public class AuthenticationSchemes
|
||||
{
|
||||
public const string Cookie = "Identity.Application";
|
||||
public const string Bitpay = "Bitpay";
|
||||
public const string Greenfield = "Greenfield.APIKeys,Greenfield.Basic,Greenfield.Bearer";
|
||||
public const string GreenfieldAPIKeys = "Greenfield.APIKeys";
|
||||
public const string GreenfieldBasic = "Greenfield.Basic";
|
||||
public const string GreenfieldBearer = "Greenfield.Bearer";
|
||||
}
|
||||
}
|
7
BTCPayServer.Abstractions/Constants/WellKnownTempData.cs
Normal file
7
BTCPayServer.Abstractions/Constants/WellKnownTempData.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace BTCPayServer.Abstractions.Constants;
|
||||
|
||||
public class WellKnownTempData
|
||||
{
|
||||
public const string SuccessMessage = nameof(SuccessMessage);
|
||||
public const string ErrorMessage = nameof(ErrorMessage);
|
||||
}
|
94
BTCPayServer.Abstractions/Contracts/BaseDbContextFactory.cs
Normal file
94
BTCPayServer.Abstractions/Contracts/BaseDbContextFactory.cs
Normal file
@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using BTCPayServer.Abstractions.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Npgsql;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Migrations.Operations;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Contracts
|
||||
{
|
||||
public abstract class BaseDbContextFactory<T> where T : DbContext
|
||||
{
|
||||
private readonly IOptions<DatabaseOptions> _options;
|
||||
private readonly string _migrationTableName;
|
||||
|
||||
public BaseDbContextFactory(IOptions<DatabaseOptions> options, string migrationTableName)
|
||||
{
|
||||
_options = options;
|
||||
_migrationTableName = migrationTableName;
|
||||
}
|
||||
|
||||
public T CreateContext() => CreateContext(null);
|
||||
public abstract T CreateContext(Action<NpgsqlDbContextOptionsBuilder> npgsqlOptionsAction = null);
|
||||
class CustomNpgsqlMigrationsSqlGenerator : NpgsqlMigrationsSqlGenerator
|
||||
{
|
||||
#pragma warning disable EF1001 // Internal EF Core API usage.
|
||||
public CustomNpgsqlMigrationsSqlGenerator(MigrationsSqlGeneratorDependencies dependencies, Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal.INpgsqlSingletonOptions opts) : base(dependencies, opts)
|
||||
#pragma warning restore EF1001 // Internal EF Core API usage.
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Generate(NpgsqlCreateDatabaseOperation operation, IModel model, MigrationCommandListBuilder builder)
|
||||
{
|
||||
builder
|
||||
.Append("CREATE DATABASE ")
|
||||
.Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Name));
|
||||
|
||||
// POSTGRES gotcha: Indexed Text column (even if PK) are not used if we are not using C locale
|
||||
builder
|
||||
.Append(" TEMPLATE ")
|
||||
.Append(Dependencies.SqlGenerationHelper.DelimitIdentifier("template0"));
|
||||
|
||||
builder
|
||||
.Append(" LC_CTYPE ")
|
||||
.Append(Dependencies.SqlGenerationHelper.DelimitIdentifier("C"));
|
||||
|
||||
builder
|
||||
.Append(" LC_COLLATE ")
|
||||
.Append(Dependencies.SqlGenerationHelper.DelimitIdentifier("C"));
|
||||
|
||||
builder
|
||||
.Append(" ENCODING ")
|
||||
.Append(Dependencies.SqlGenerationHelper.DelimitIdentifier("UTF8"));
|
||||
|
||||
if (operation.Tablespace != null)
|
||||
{
|
||||
builder
|
||||
.Append(" TABLESPACE ")
|
||||
.Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Tablespace));
|
||||
}
|
||||
|
||||
builder.AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator);
|
||||
|
||||
EndStatement(builder, suppressTransaction: true);
|
||||
}
|
||||
}
|
||||
|
||||
public void ConfigureBuilder(DbContextOptionsBuilder builder) => ConfigureBuilder(builder, null);
|
||||
public void ConfigureBuilder(DbContextOptionsBuilder builder, Action<NpgsqlDbContextOptionsBuilder> npgsqlOptionsAction = null)
|
||||
{
|
||||
builder
|
||||
.UseNpgsql(_options.Value.ConnectionString, o =>
|
||||
{
|
||||
o.EnableRetryOnFailure(10);
|
||||
o.SetPostgresVersion(12, 0);
|
||||
npgsqlOptionsAction?.Invoke(o);
|
||||
var mainSearchPath = GetSearchPath(_options.Value.ConnectionString);
|
||||
var schemaPrefix = string.IsNullOrEmpty(_migrationTableName) ? "__EFMigrationsHistory" : _migrationTableName;
|
||||
o.MigrationsHistoryTable(schemaPrefix, mainSearchPath);
|
||||
})
|
||||
.ReplaceService<IMigrationsSqlGenerator, CustomNpgsqlMigrationsSqlGenerator>();
|
||||
}
|
||||
|
||||
private string GetSearchPath(string connectionString)
|
||||
{
|
||||
var connectionStringBuilder = new NpgsqlConnectionStringBuilder(connectionString);
|
||||
var searchPaths = connectionStringBuilder.SearchPath?.Split(',');
|
||||
return searchPaths is not { Length: > 0 } ? null : searchPaths[0];
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Contracts
|
||||
{
|
||||
public interface IBTCPayServerClientFactory
|
||||
{
|
||||
Task<BTCPayServerClient> Create(string userId, params string[] storeIds);
|
||||
Task<BTCPayServerClient> Create(string userId, string[] storeIds, HttpContext httpRequest);
|
||||
}
|
||||
}
|
32
BTCPayServer.Abstractions/Contracts/IBTCPayServerPlugin.cs
Normal file
32
BTCPayServer.Abstractions/Contracts/IBTCPayServerPlugin.cs
Normal file
@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
using BTCPayServer.Abstractions.Converters;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Contracts
|
||||
{
|
||||
public interface IBTCPayServerPlugin
|
||||
{
|
||||
public string Identifier { get; }
|
||||
string Name { get; }
|
||||
[JsonConverter(typeof(VersionConverter))]
|
||||
Version Version { get; }
|
||||
string Description { get; }
|
||||
bool SystemPlugin { get; set; }
|
||||
PluginDependency[] Dependencies { get; }
|
||||
void Execute(IApplicationBuilder applicationBuilder, IServiceProvider applicationBuilderApplicationServices);
|
||||
void Execute(IServiceCollection applicationBuilder);
|
||||
|
||||
public class PluginDependency
|
||||
{
|
||||
public string Identifier { get; set; }
|
||||
public string Condition { get; set; }
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Identifier}: {Condition}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
19
BTCPayServer.Abstractions/Contracts/IFileService.cs
Normal file
19
BTCPayServer.Abstractions/Contracts/IFileService.cs
Normal file
@ -0,0 +1,19 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using BTCPayServer.Abstractions.Models;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Contracts;
|
||||
|
||||
public interface IFileService
|
||||
{
|
||||
Task<bool> IsAvailable();
|
||||
Task<IStoredFile> AddFile(IFormFile file, string userId);
|
||||
Task<IStoredFile> AddFile(Uri file, string userId);
|
||||
Task<string?> GetFileUrl(Uri baseUri, string fileId);
|
||||
Task<string?> GetTemporaryFileUrl(Uri baseUri, string fileId, DateTimeOffset expiry,
|
||||
bool isDownload);
|
||||
Task RemoveFile(string fileId, string userId);
|
||||
Task<UploadImageResultModel> UploadImage(IFormFile file, string userId, long maxFileSizeInBytes = 1_000_000);
|
||||
}
|
30
BTCPayServer.Abstractions/Contracts/INotificationHandler.cs
Normal file
30
BTCPayServer.Abstractions/Contracts/INotificationHandler.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using System;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Contracts
|
||||
{
|
||||
public abstract class BaseNotification
|
||||
{
|
||||
public abstract string Identifier { get; }
|
||||
public abstract string NotificationType { get; }
|
||||
}
|
||||
|
||||
public interface INotificationHandler
|
||||
{
|
||||
string NotificationType { get; }
|
||||
Type NotificationBlobType { get; }
|
||||
public (string identifier, string name)[] Meta { get; }
|
||||
void FillViewModel(object notification, NotificationViewModel vm);
|
||||
}
|
||||
|
||||
public class NotificationViewModel
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Identifier { get; set; }
|
||||
public string Type { get; set; }
|
||||
public DateTimeOffset Created { get; set; }
|
||||
public string Body { get; set; }
|
||||
public string ActionLink { get; set; }
|
||||
public bool Seen { get; set; }
|
||||
public string StoreId { get; set; }
|
||||
}
|
||||
}
|
10
BTCPayServer.Abstractions/Contracts/IPluginHookAction.cs
Normal file
10
BTCPayServer.Abstractions/Contracts/IPluginHookAction.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Contracts
|
||||
{
|
||||
public interface IPluginHookAction
|
||||
{
|
||||
public string Hook { get; }
|
||||
Task Execute(object args);
|
||||
}
|
||||
}
|
11
BTCPayServer.Abstractions/Contracts/IPluginHookFilter.cs
Normal file
11
BTCPayServer.Abstractions/Contracts/IPluginHookFilter.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Contracts
|
||||
{
|
||||
public interface IPluginHookFilter
|
||||
{
|
||||
public string Hook { get; }
|
||||
|
||||
Task<object> Execute(object args);
|
||||
}
|
||||
}
|
14
BTCPayServer.Abstractions/Contracts/IPluginHookService.cs
Normal file
14
BTCPayServer.Abstractions/Contracts/IPluginHookService.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Contracts
|
||||
{
|
||||
public interface IPluginHookService
|
||||
{
|
||||
Task ApplyAction(string hook, object args);
|
||||
Task<object> ApplyFilter(string hook, object args);
|
||||
|
||||
event EventHandler<(string hook, object args)> ActionInvoked;
|
||||
event EventHandler<(string hook, object args)> FilterInvoked;
|
||||
}
|
||||
}
|
7
BTCPayServer.Abstractions/Contracts/IScopeProvider.cs
Normal file
7
BTCPayServer.Abstractions/Contracts/IScopeProvider.cs
Normal file
@ -0,0 +1,7 @@
|
||||
#nullable enable
|
||||
namespace BTCPayServer.Abstractions.Contracts;
|
||||
|
||||
public interface IScopeProvider
|
||||
{
|
||||
string? GetCurrentStoreId();
|
||||
}
|
13
BTCPayServer.Abstractions/Contracts/ISettingsRepository.cs
Normal file
13
BTCPayServer.Abstractions/Contracts/ISettingsRepository.cs
Normal file
@ -0,0 +1,13 @@
|
||||
#nullable enable
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Contracts
|
||||
{
|
||||
public interface ISettingsRepository
|
||||
{
|
||||
Task<T?> GetSettingAsync<T>(string? name = null) where T : class;
|
||||
Task UpdateSetting<T>(T obj, string? name = null) where T : class;
|
||||
Task<T> WaitSettingsChanged<T>(CancellationToken cancellationToken = default) where T : class;
|
||||
}
|
||||
}
|
10
BTCPayServer.Abstractions/Contracts/IStartupTask.cs
Normal file
10
BTCPayServer.Abstractions/Contracts/IStartupTask.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Contracts
|
||||
{
|
||||
public interface IStartupTask
|
||||
{
|
||||
Task ExecuteAsync(CancellationToken cancellationToken = default);
|
||||
}
|
||||
}
|
12
BTCPayServer.Abstractions/Contracts/IStoreRepository.cs
Normal file
12
BTCPayServer.Abstractions/Contracts/IStoreRepository.cs
Normal file
@ -0,0 +1,12 @@
|
||||
#nullable enable
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Contracts;
|
||||
|
||||
public interface IStoreRepository
|
||||
{
|
||||
Task<T?> GetSettingAsync<T>(string storeId, string name) where T : class;
|
||||
Task<Dictionary<string, T?>> GetSettingsAsync<T>(string name) where T : class;
|
||||
Task UpdateSetting<T>(string storeId, string name, T obj) where T : class;
|
||||
}
|
12
BTCPayServer.Abstractions/Contracts/IStoredFile.cs
Normal file
12
BTCPayServer.Abstractions/Contracts/IStoredFile.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Contracts;
|
||||
|
||||
public interface IStoredFile
|
||||
{
|
||||
string Id { get; set; }
|
||||
string FileName { get; set; }
|
||||
string StorageFileName { get; set; }
|
||||
DateTime Timestamp { get; set; }
|
||||
string ApplicationUserId { get; set; }
|
||||
}
|
9
BTCPayServer.Abstractions/Contracts/ISwaggerProvider.cs
Normal file
9
BTCPayServer.Abstractions/Contracts/ISwaggerProvider.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Contracts;
|
||||
|
||||
public interface ISwaggerProvider
|
||||
{
|
||||
Task<JObject> Fetch();
|
||||
}
|
18
BTCPayServer.Abstractions/Contracts/ISyncSummaryProvider.cs
Normal file
18
BTCPayServer.Abstractions/Contracts/ISyncSummaryProvider.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Contracts
|
||||
{
|
||||
public interface ISyncSummaryProvider
|
||||
{
|
||||
bool AllAvailable();
|
||||
|
||||
string Partial { get; }
|
||||
IEnumerable<ISyncStatus> GetStatuses();
|
||||
}
|
||||
|
||||
public interface ISyncStatus
|
||||
{
|
||||
public string PaymentMethodId { get; set; }
|
||||
public bool Available { get; }
|
||||
}
|
||||
}
|
9
BTCPayServer.Abstractions/Contracts/IUIExtension.cs
Normal file
9
BTCPayServer.Abstractions/Contracts/IUIExtension.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace BTCPayServer.Abstractions.Contracts
|
||||
{
|
||||
public interface IUIExtension
|
||||
{
|
||||
string Partial { get; }
|
||||
|
||||
string Location { get; }
|
||||
}
|
||||
}
|
13
BTCPayServer.Abstractions/Contracts/IUTXOLocker.cs
Normal file
13
BTCPayServer.Abstractions/Contracts/IUTXOLocker.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using NBitcoin;
|
||||
|
||||
namespace BTCPayServer.Payments.PayJoin;
|
||||
|
||||
public interface IUTXOLocker
|
||||
{
|
||||
Task<bool> TryLock(OutPoint outpoint);
|
||||
Task<bool> TryUnlock(params OutPoint[] outPoints);
|
||||
Task<bool> TryLockInputs(OutPoint[] outPoints);
|
||||
Task<HashSet<OutPoint>> FindLocks(OutPoint[] outpoints);
|
||||
}
|
19
BTCPayServer.Abstractions/Converters/VersionConverter.cs
Normal file
19
BTCPayServer.Abstractions/Converters/VersionConverter.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Converters
|
||||
{
|
||||
public class VersionConverter : JsonConverter<Version>
|
||||
{
|
||||
public override Version Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
return Version.Parse(reader.GetString());
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, Version value, JsonSerializerOptions options)
|
||||
{
|
||||
writer.WriteStringValue(value.ToString());
|
||||
}
|
||||
}
|
||||
}
|
47
BTCPayServer.Abstractions/Extensions/GreenfieldExtensions.cs
Normal file
47
BTCPayServer.Abstractions/Extensions/GreenfieldExtensions.cs
Normal file
@ -0,0 +1,47 @@
|
||||
using System.Collections.Generic;
|
||||
using BTCPayServer.Client.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Extensions;
|
||||
|
||||
public static class GreenfieldExtensions
|
||||
{
|
||||
public static IActionResult UserNotFound(this ControllerBase ctrl)
|
||||
{
|
||||
return ctrl.CreateAPIError(404, "user-not-found", "The user was not found");
|
||||
}
|
||||
public static IActionResult CreateValidationError(this ControllerBase controller, ModelStateDictionary modelState)
|
||||
{
|
||||
return controller.UnprocessableEntity(modelState.ToGreenfieldValidationError());
|
||||
}
|
||||
|
||||
public static List<GreenfieldValidationError> ToGreenfieldValidationError(this ModelStateDictionary modelState)
|
||||
{
|
||||
List<GreenfieldValidationError> errors = new List<GreenfieldValidationError>();
|
||||
foreach (var error in modelState)
|
||||
{
|
||||
foreach (var errorMessage in error.Value.Errors)
|
||||
{
|
||||
errors.Add(new GreenfieldValidationError(error.Key, errorMessage.ErrorMessage));
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
public static IActionResult CreateAPIError(this ControllerBase controller, string errorCode, string errorMessage)
|
||||
{
|
||||
return controller.BadRequest(new GreenfieldAPIError(errorCode, errorMessage));
|
||||
}
|
||||
|
||||
public static IActionResult CreateAPIError(this ControllerBase controller, int httpCode, string errorCode, string errorMessage)
|
||||
{
|
||||
return controller.StatusCode(httpCode, new GreenfieldAPIError(errorCode, errorMessage));
|
||||
}
|
||||
|
||||
public static IActionResult CreateAPIPermissionError(this ControllerBase controller, string missingPermission, string message = null)
|
||||
{
|
||||
return controller.StatusCode(403, new GreenfieldPermissionAPIError(missingPermission, message));
|
||||
}
|
||||
}
|
131
BTCPayServer.Abstractions/Extensions/HttpRequestExtensions.cs
Normal file
131
BTCPayServer.Abstractions/Extensions/HttpRequestExtensions.cs
Normal file
@ -0,0 +1,131 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Extensions;
|
||||
|
||||
public static class HttpRequestExtensions
|
||||
{
|
||||
public static bool IsOnion(this HttpRequest request)
|
||||
{
|
||||
if (request?.Host.Host == null)
|
||||
return false;
|
||||
return request.Host.Host.EndsWith(".onion", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public static string GetAbsoluteRoot(this HttpRequest request)
|
||||
{
|
||||
return string.Concat(
|
||||
request.Scheme,
|
||||
"://",
|
||||
request.Host.ToUriComponent(),
|
||||
request.PathBase.ToUriComponent());
|
||||
}
|
||||
|
||||
public static Uri GetAbsoluteRootUri(this HttpRequest request)
|
||||
{
|
||||
return new Uri(request.GetAbsoluteRoot());
|
||||
}
|
||||
|
||||
public static string GetCurrentUrl(this HttpRequest request)
|
||||
{
|
||||
return string.Concat(
|
||||
request.Scheme,
|
||||
"://",
|
||||
request.Host.ToUriComponent(),
|
||||
request.PathBase.ToUriComponent(),
|
||||
request.Path.ToUriComponent());
|
||||
}
|
||||
|
||||
public static string GetCurrentUrlWithQueryString(this HttpRequest request)
|
||||
{
|
||||
return string.Concat(
|
||||
request.Scheme,
|
||||
"://",
|
||||
request.Host.ToUriComponent(),
|
||||
request.PathBase.ToUriComponent(),
|
||||
request.Path.ToUriComponent(),
|
||||
request.QueryString.ToUriComponent());
|
||||
}
|
||||
|
||||
public static string GetCurrentPath(this HttpRequest request)
|
||||
{
|
||||
return string.Concat(
|
||||
request.PathBase.ToUriComponent(),
|
||||
request.Path.ToUriComponent());
|
||||
}
|
||||
|
||||
public static string GetCurrentPathWithQueryString(this HttpRequest request)
|
||||
{
|
||||
return request.PathBase + request.Path + request.QueryString;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If 'toto' and RootPath is 'rootpath' returns '/rootpath/toto'
|
||||
/// If 'toto' and RootPath is empty returns '/toto'
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetRelativePath(this HttpRequest request, string path)
|
||||
{
|
||||
if (path.Length > 0 && path[0] != '/')
|
||||
path = $"/{path}";
|
||||
return string.Concat(
|
||||
request.PathBase.ToUriComponent(),
|
||||
path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If 'https://example.com/toto' returns 'https://example.com/toto'
|
||||
/// If 'toto' and RootPath is 'rootpath' returns '/rootpath/toto'
|
||||
/// If 'toto' and RootPath is empty returns '/toto'
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetRelativePathOrAbsolute(this HttpRequest request, string path)
|
||||
{
|
||||
if (!Uri.TryCreate(path, UriKind.RelativeOrAbsolute, out var uri) ||
|
||||
uri.IsAbsoluteUri)
|
||||
return path;
|
||||
|
||||
if (path.Length > 0 && path[0] != '/')
|
||||
path = $"/{path}";
|
||||
return string.Concat(
|
||||
request.PathBase.ToUriComponent(),
|
||||
path);
|
||||
}
|
||||
|
||||
public static string GetAbsoluteUri(this HttpRequest request, string redirectUrl)
|
||||
{
|
||||
bool isRelative =
|
||||
(redirectUrl.Length > 0 && redirectUrl[0] == '/')
|
||||
|| !new Uri(redirectUrl, UriKind.RelativeOrAbsolute).IsAbsoluteUri;
|
||||
return isRelative ? request.GetAbsoluteRoot() + redirectUrl : redirectUrl;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will return an absolute URL.
|
||||
/// If `relativeOrAsbolute` is absolute, returns it.
|
||||
/// If `relativeOrAsbolute` is relative, send absolute url based on the HOST of this request (without PathBase)
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="relativeOrAbsolte"></param>
|
||||
/// <returns></returns>
|
||||
public static Uri GetAbsoluteUriNoPathBase(this HttpRequest request, Uri relativeOrAbsolute = null)
|
||||
{
|
||||
if (relativeOrAbsolute == null)
|
||||
{
|
||||
return new Uri(string.Concat(
|
||||
request.Scheme,
|
||||
"://",
|
||||
request.Host.ToUriComponent()), UriKind.Absolute);
|
||||
}
|
||||
if (relativeOrAbsolute.IsAbsoluteUri)
|
||||
return relativeOrAbsolute;
|
||||
return new Uri(string.Concat(
|
||||
request.Scheme,
|
||||
"://",
|
||||
request.Host.ToUriComponent()) + relativeOrAbsolute.ToString().WithStartingSlash(), UriKind.Absolute);
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
using System.Text.Json;
|
||||
using BTCPayServer.Abstractions.Constants;
|
||||
using BTCPayServer.Abstractions.Models;
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Extensions;
|
||||
|
||||
public static class SetStatusMessageModelExtensions
|
||||
{
|
||||
public static void SetStatusSuccess(this ITempDataDictionary tempData, string statusMessage)
|
||||
{
|
||||
tempData.SetStatusMessageModel(new StatusMessageModel
|
||||
{
|
||||
Severity = StatusMessageModel.StatusSeverity.Success,
|
||||
Message = statusMessage
|
||||
});
|
||||
}
|
||||
public static void SetStatusMessageModel(this ITempDataDictionary tempData, StatusMessageModel statusMessage)
|
||||
{
|
||||
if (statusMessage == null)
|
||||
{
|
||||
tempData.Remove("StatusMessageModel");
|
||||
return;
|
||||
}
|
||||
|
||||
tempData["StatusMessageModel"] = JsonSerializer.Serialize(statusMessage, new JsonSerializerOptions());
|
||||
}
|
||||
|
||||
public static StatusMessageModel GetStatusMessageModel(this ITempDataDictionary tempData)
|
||||
{
|
||||
tempData.TryGetValue(WellKnownTempData.SuccessMessage, out var successMessage);
|
||||
tempData.TryGetValue(WellKnownTempData.ErrorMessage, out var errorMessage);
|
||||
tempData.TryGetValue("StatusMessageModel", out var model);
|
||||
if (successMessage != null || errorMessage != null)
|
||||
{
|
||||
var parsedModel = new StatusMessageModel
|
||||
{
|
||||
Message = (string)successMessage ?? (string)errorMessage,
|
||||
Severity = successMessage != null ? StatusMessageModel.StatusSeverity.Success : StatusMessageModel.StatusSeverity.Error
|
||||
};
|
||||
return parsedModel;
|
||||
}
|
||||
if (model is string str)
|
||||
{
|
||||
return JObject.Parse(str).ToObject<StatusMessageModel>();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static bool HasStatusMessage(this ITempDataDictionary tempData)
|
||||
{
|
||||
return (tempData.Peek(WellKnownTempData.SuccessMessage) ??
|
||||
tempData.Peek(WellKnownTempData.ErrorMessage) ??
|
||||
tempData.Peek("StatusMessageModel")) != null;
|
||||
}
|
||||
|
||||
public static bool HasErrorMessage(this ITempDataDictionary tempData)
|
||||
{
|
||||
return GetStatusMessageModel(tempData)?.Severity == StatusMessageModel.StatusSeverity.Error;
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
using BTCPayServer.Abstractions.Contracts;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Extensions
|
||||
{
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddStartupTask<T>(this IServiceCollection services)
|
||||
where T : class, IStartupTask
|
||||
=> services.AddTransient<IStartupTask, T>();
|
||||
}
|
||||
}
|
43
BTCPayServer.Abstractions/Extensions/StringExtensions.cs
Normal file
43
BTCPayServer.Abstractions/Extensions/StringExtensions.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Extensions;
|
||||
|
||||
public static class StringExtensions
|
||||
{
|
||||
public static bool IsValidFileName(this string fileName)
|
||||
{
|
||||
return !fileName.ToCharArray().Any(c => Path.GetInvalidFileNameChars().Contains(c)
|
||||
|| c == Path.AltDirectorySeparatorChar
|
||||
|| c == Path.DirectorySeparatorChar
|
||||
|| c == Path.PathSeparator
|
||||
|| c == '\\');
|
||||
}
|
||||
|
||||
public static string Truncate(this string value, int maxLength)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
return value;
|
||||
return value.Length <= maxLength ? value : value.Substring(0, maxLength);
|
||||
}
|
||||
|
||||
public static string WithTrailingSlash(this string str)
|
||||
{
|
||||
if (str.EndsWith("/", StringComparison.InvariantCulture))
|
||||
return str;
|
||||
return str + "/";
|
||||
}
|
||||
public static string WithStartingSlash(this string str)
|
||||
{
|
||||
if (str.StartsWith("/", StringComparison.InvariantCulture))
|
||||
return str;
|
||||
return $"/{str}";
|
||||
}
|
||||
public static string WithoutEndingSlash(this string str)
|
||||
{
|
||||
if (str.EndsWith("/", StringComparison.InvariantCulture))
|
||||
return str.Substring(0, str.Length - 1);
|
||||
return str;
|
||||
}
|
||||
}
|
199
BTCPayServer.Abstractions/Extensions/ViewsRazor.cs
Normal file
199
BTCPayServer.Abstractions/Extensions/ViewsRazor.cs
Normal file
@ -0,0 +1,199 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Html;
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Extensions
|
||||
{
|
||||
public static class ViewsRazor
|
||||
{
|
||||
private const string ACTIVE_CATEGORY_KEY = "ActiveCategory";
|
||||
private const string ACTIVE_PAGE_KEY = "ActivePage";
|
||||
private const string ACTIVE_ID_KEY = "ActiveId";
|
||||
private const string ACTIVE_CLASS = "active";
|
||||
|
||||
public enum DateDisplayFormat
|
||||
{
|
||||
Localized,
|
||||
Relative
|
||||
}
|
||||
|
||||
public static void SetBlazorAllowed(this ViewDataDictionary viewData, bool allowed)
|
||||
{
|
||||
viewData["BlazorAllowed"] = allowed;
|
||||
}
|
||||
public static bool IsBlazorAllowed(this ViewDataDictionary viewData)
|
||||
{
|
||||
return viewData["BlazorAllowed"] is not false;
|
||||
}
|
||||
|
||||
public static void SetActivePage<T>(this ViewDataDictionary viewData, T activePage, string title = null, string activeId = null)
|
||||
where T : IConvertible
|
||||
{
|
||||
SetActivePage(viewData, activePage.ToString(), activePage.GetType().ToString(), title, activeId);
|
||||
}
|
||||
|
||||
public static void SetActivePage(this ViewDataDictionary viewData, string activePage, string category, string title = null, string activeId = null)
|
||||
{
|
||||
// Page Title
|
||||
viewData["Title"] = title ?? activePage;
|
||||
// Navigation
|
||||
viewData[ACTIVE_PAGE_KEY] = activePage;
|
||||
viewData[ACTIVE_ID_KEY] = activeId;
|
||||
SetActiveCategory(viewData, category);
|
||||
}
|
||||
|
||||
public static void SetActiveCategory<T>(this ViewDataDictionary viewData, T activeCategory)
|
||||
{
|
||||
SetActiveCategory(viewData, activeCategory.ToString());
|
||||
}
|
||||
|
||||
public static void SetActiveCategory(this ViewDataDictionary viewData, string activeCategory)
|
||||
{
|
||||
viewData[ACTIVE_CATEGORY_KEY] = activeCategory;
|
||||
}
|
||||
|
||||
public static bool IsCategoryActive(this ViewDataDictionary viewData, string category, object id = null)
|
||||
{
|
||||
if (!viewData.ContainsKey(ACTIVE_CATEGORY_KEY)) return false;
|
||||
var activeId = viewData[ACTIVE_ID_KEY];
|
||||
var activeCategory = viewData[ACTIVE_CATEGORY_KEY]?.ToString();
|
||||
var categoryMatch = category.Equals(activeCategory, StringComparison.InvariantCultureIgnoreCase);
|
||||
var idMatch = id == null || activeId == null || id.Equals(activeId);
|
||||
return categoryMatch && idMatch;
|
||||
}
|
||||
|
||||
public static bool IsCategoryActive<T>(this ViewDataDictionary viewData, T category, object id = null)
|
||||
{
|
||||
return IsCategoryActive(viewData, category.ToString(), id);
|
||||
}
|
||||
|
||||
public static bool IsPageActive(this ViewDataDictionary viewData, string page, string category, object id = null)
|
||||
{
|
||||
if (!viewData.ContainsKey(ACTIVE_PAGE_KEY)) return false;
|
||||
var activeId = viewData[ACTIVE_ID_KEY];
|
||||
var activePage = viewData[ACTIVE_PAGE_KEY]?.ToString();
|
||||
var activeCategory = viewData[ACTIVE_CATEGORY_KEY]?.ToString();
|
||||
var categoryAndPageMatch = page.Equals(activePage, StringComparison.InvariantCultureIgnoreCase) &&
|
||||
(category == null || activeCategory != null && activeCategory.Equals(category, StringComparison.InvariantCultureIgnoreCase));
|
||||
var idMatch = id == null || activeId == null || id.Equals(activeId);
|
||||
return categoryAndPageMatch && idMatch;
|
||||
}
|
||||
|
||||
public static bool IsPageActive<T>(this ViewDataDictionary viewData, IEnumerable<T> pages, object id = null)
|
||||
where T : IConvertible
|
||||
{
|
||||
return pages.Any(page => ActivePageClass(viewData, page.ToString(), page.GetType().ToString(), id) == ACTIVE_CLASS);
|
||||
}
|
||||
|
||||
public static string ActiveCategoryClass<T>(this ViewDataDictionary viewData, T category, object id = null)
|
||||
{
|
||||
return ActiveCategoryClass(viewData, category.ToString(), id);
|
||||
}
|
||||
|
||||
public static string ActiveCategoryClass(this ViewDataDictionary viewData, string category, object id = null)
|
||||
{
|
||||
return IsCategoryActive(viewData, category, id) ? ACTIVE_CLASS : null;
|
||||
}
|
||||
|
||||
public static string ActivePageClass<T>(this ViewDataDictionary viewData, T page, object id = null)
|
||||
where T : IConvertible
|
||||
{
|
||||
return ActivePageClass(viewData, page.ToString(), page.GetType().ToString(), id);
|
||||
}
|
||||
|
||||
public static string ActivePageClass(this ViewDataDictionary viewData, string page, string category, object id = null)
|
||||
{
|
||||
return IsPageActive(viewData, page, category, id) ? ACTIVE_CLASS : null;
|
||||
}
|
||||
|
||||
public static string ActivePageClass<T>(this ViewDataDictionary viewData, IEnumerable<T> pages, object id = null) where T : IConvertible
|
||||
{
|
||||
return IsPageActive(viewData, pages, id) ? ACTIVE_CLASS : null;
|
||||
}
|
||||
|
||||
[Obsolete("Use ActiveCategoryClass instead")]
|
||||
public static string IsActiveCategory<T>(this ViewDataDictionary viewData, T category, object id = null)
|
||||
{
|
||||
return ActiveCategoryClass(viewData, category, id);
|
||||
}
|
||||
|
||||
[Obsolete("Use ActiveCategoryClass instead")]
|
||||
public static string IsActiveCategory(this ViewDataDictionary viewData, string category, object id = null)
|
||||
{
|
||||
return ActiveCategoryClass(viewData, category, id);
|
||||
}
|
||||
|
||||
[Obsolete("Use ActivePageClass instead")]
|
||||
public static string IsActivePage<T>(this ViewDataDictionary viewData, T page, object id = null) where T : IConvertible
|
||||
{
|
||||
return ActivePageClass(viewData, page, id);
|
||||
}
|
||||
|
||||
[Obsolete("Use ActivePageClass instead")]
|
||||
public static string IsActivePage<T>(this ViewDataDictionary viewData, IEnumerable<T> pages, object id = null) where T : IConvertible
|
||||
{
|
||||
return ActivePageClass(viewData, pages, id);
|
||||
}
|
||||
|
||||
[Obsolete("Use ActivePageClass instead")]
|
||||
public static string IsActivePage(this ViewDataDictionary viewData, string page, string category, object id = null)
|
||||
{
|
||||
return ActivePageClass(viewData, page, category, id);
|
||||
}
|
||||
|
||||
public static HtmlString ToBrowserDate(this DateTimeOffset date, string netFormat, string jsDateFormat = "short", string jsTimeFormat = "short")
|
||||
{
|
||||
var dateTime = date.ToString("o", CultureInfo.InvariantCulture);
|
||||
var displayDate = date.ToString(netFormat, CultureInfo.InvariantCulture);
|
||||
var tooltip = dateTime.Replace("T", " ");
|
||||
return new HtmlString($"<time datetime=\"{dateTime}\" data-date-style=\"{jsDateFormat}\" data-time-style=\"{jsTimeFormat}\" data-initial=\"localized\" data-bs-toggle=\"tooltip\" data-bs-title=\"{tooltip}\">{displayDate}</time>");
|
||||
}
|
||||
|
||||
public static HtmlString ToBrowserDate(this DateTimeOffset date, DateDisplayFormat format = DateDisplayFormat.Localized)
|
||||
{
|
||||
var relative = date.ToTimeAgo();
|
||||
var initial = format.ToString().ToLower();
|
||||
var dateTime = date.ToString("o", CultureInfo.InvariantCulture);
|
||||
var displayDate = format == DateDisplayFormat.Relative ? relative : date.ToString("g", CultureInfo.InvariantCulture);
|
||||
return new HtmlString($"<time datetime=\"{dateTime}\" data-relative=\"{relative}\" data-initial=\"{initial}\">{displayDate}</time>");
|
||||
}
|
||||
|
||||
public static HtmlString ToBrowserDate(this DateTime date, DateDisplayFormat format = DateDisplayFormat.Localized)
|
||||
{
|
||||
var relative = date.ToTimeAgo();
|
||||
var initial = format.ToString().ToLower();
|
||||
var dateTime = date.ToString("o", CultureInfo.InvariantCulture);
|
||||
var displayDate = format == DateDisplayFormat.Relative ? relative : date.ToString("g", CultureInfo.InvariantCulture);
|
||||
return new HtmlString($"<time datetime=\"{dateTime}\" data-relative=\"{relative}\" data-initial=\"{initial}\">{displayDate}</time>");
|
||||
}
|
||||
|
||||
public static string ToTimeAgo(this DateTimeOffset date) => (DateTimeOffset.UtcNow - date).ToTimeAgo();
|
||||
|
||||
public static string ToTimeAgo(this DateTime date) => (DateTimeOffset.UtcNow - date).ToTimeAgo();
|
||||
|
||||
public static string ToTimeAgo(this TimeSpan diff) => diff.TotalSeconds > 0 ? $"{diff.TimeString()} ago" : $"in {diff.Negate().TimeString()}";
|
||||
|
||||
public static string TimeString(this TimeSpan timeSpan)
|
||||
{
|
||||
if (timeSpan.TotalMinutes < 1)
|
||||
{
|
||||
return $"{(int)timeSpan.TotalSeconds} second{Plural((int)timeSpan.TotalSeconds)}";
|
||||
}
|
||||
if (timeSpan.TotalHours < 1)
|
||||
{
|
||||
return $"{(int)timeSpan.TotalMinutes} minute{Plural((int)timeSpan.TotalMinutes)}";
|
||||
}
|
||||
return timeSpan.Days < 1
|
||||
? $"{(int)timeSpan.TotalHours} hour{Plural((int)timeSpan.TotalHours)}"
|
||||
: $"{(int)timeSpan.TotalDays} day{Plural((int)timeSpan.TotalDays)}";
|
||||
}
|
||||
|
||||
private static string Plural(int value)
|
||||
{
|
||||
return value == 1 ? string.Empty : "s";
|
||||
}
|
||||
}
|
||||
}
|
37
BTCPayServer.Abstractions/Form/AlertMessage.cs
Normal file
37
BTCPayServer.Abstractions/Form/AlertMessage.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Form;
|
||||
|
||||
public class AlertMessage
|
||||
{
|
||||
// Corresponds to the Bootstrap CSS "alert alert-xxx" messages:
|
||||
// Success = green
|
||||
// Warning = orange
|
||||
// Danger = red
|
||||
// Info = blue
|
||||
public enum AlertMessageType
|
||||
{
|
||||
Success,
|
||||
Warning,
|
||||
Danger,
|
||||
Info
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public AlertMessageType Type;
|
||||
|
||||
// The translated message to be shown to the user
|
||||
public string Message;
|
||||
|
||||
public AlertMessage()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public AlertMessage(AlertMessageType type, string message)
|
||||
{
|
||||
this.Type = type;
|
||||
this.Message = message;
|
||||
}
|
||||
}
|
64
BTCPayServer.Abstractions/Form/Field.cs
Normal file
64
BTCPayServer.Abstractions/Form/Field.cs
Normal file
@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Form;
|
||||
|
||||
public class Field
|
||||
{
|
||||
public static Field Create(string label, string name, string value, bool required, string helpText, string type = "text")
|
||||
{
|
||||
return new Field
|
||||
{
|
||||
Label = label,
|
||||
Name = name,
|
||||
Value = value,
|
||||
OriginalValue = value,
|
||||
Required = required,
|
||||
HelpText = helpText,
|
||||
Type = type
|
||||
};
|
||||
}
|
||||
// The name of the HTML5 node. Should be used as the key for the posted data.
|
||||
public string Name;
|
||||
|
||||
public bool Constant;
|
||||
|
||||
// HTML5 compatible type string like "text", "textarea", "email", "password", etc.
|
||||
public string Type;
|
||||
|
||||
public static Field CreateFieldset()
|
||||
{
|
||||
return new Field { Type = "fieldset" };
|
||||
}
|
||||
|
||||
// The value field is what is currently in the DB or what the user entered, but possibly not saved yet due to validation errors.
|
||||
// If this is the first the user sees the form, then value and original value are the same. Value changes as the user starts interacting with the form.
|
||||
public string Value;
|
||||
|
||||
public bool Required;
|
||||
|
||||
// The translated label of the field.
|
||||
public string Label;
|
||||
|
||||
// The original value is the value that is currently saved in the backend. A "reset" button can be used to revert back to this. Should only be set from the constructor.
|
||||
public string OriginalValue;
|
||||
|
||||
// A useful note shown below the field or via a tooltip / info icon. Should be translated for the user.
|
||||
public string HelpText;
|
||||
|
||||
[JsonExtensionData] public IDictionary<string, JToken> AdditionalData { get; set; }
|
||||
public List<Field> Fields { get; set; } = new();
|
||||
|
||||
// The field is considered "valid" if there are no validation errors
|
||||
public List<string> ValidationErrors = new();
|
||||
|
||||
public virtual bool IsValid()
|
||||
{
|
||||
return ValidationErrors.Count == 0 && Fields.All(field => field.IsValid());
|
||||
}
|
||||
}
|
110
BTCPayServer.Abstractions/Form/Form.cs
Normal file
110
BTCPayServer.Abstractions/Form/Form.cs
Normal file
@ -0,0 +1,110 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Form;
|
||||
|
||||
public class Form
|
||||
{
|
||||
#nullable enable
|
||||
public static Form Parse(string str)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(str);
|
||||
return JObject.Parse(str).ToObject<Form>(CamelCaseSerializerSettings.Serializer) ?? throw new InvalidOperationException("Impossible to deserialize Form");
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return JObject.FromObject(this, CamelCaseSerializerSettings.Serializer).ToString(Newtonsoft.Json.Formatting.Indented);
|
||||
}
|
||||
#nullable restore
|
||||
|
||||
// Messages to be shown at the top of the form indicating user feedback like "Saved successfully" or "Please change X because of Y." or a warning, etc...
|
||||
public List<AlertMessage> TopMessages { get; set; } = new();
|
||||
|
||||
// Groups of fields in the form
|
||||
public List<Field> Fields { get; set; } = new();
|
||||
|
||||
// Are all the fields valid in the form?
|
||||
public bool IsValid()
|
||||
{
|
||||
if (TopMessages?.Any(t => t.Type == AlertMessage.AlertMessageType.Danger) is true)
|
||||
return false;
|
||||
return Fields.Select(f => f.IsValid()).All(o => o);
|
||||
}
|
||||
|
||||
public Field GetFieldByFullName(string fullName)
|
||||
{
|
||||
foreach (var f in GetAllFields())
|
||||
{
|
||||
if (f.FullName == fullName)
|
||||
return f.Field;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public IEnumerable<(string FullName, List<string> Path, Field Field)> GetAllFields()
|
||||
{
|
||||
HashSet<string> nameReturned = new();
|
||||
foreach (var f in GetAllFieldsCore(new List<string>(), Fields))
|
||||
{
|
||||
var fullName = string.Join('_', f.Path.Where(s => !string.IsNullOrEmpty(s)));
|
||||
if (!nameReturned.Add(fullName))
|
||||
continue;
|
||||
yield return (fullName, f.Path, f.Field);
|
||||
}
|
||||
}
|
||||
|
||||
public bool ValidateFieldNames(out List<string> errors)
|
||||
{
|
||||
errors = new List<string>();
|
||||
HashSet<string> nameReturned = new();
|
||||
foreach (var f in GetAllFieldsCore(new List<string>(), Fields))
|
||||
{
|
||||
var fullName = string.Join('_', f.Path.Where(s => !string.IsNullOrEmpty(s)));
|
||||
if (!nameReturned.Add(fullName))
|
||||
{
|
||||
errors.Add($"Form contains duplicate field names '{fullName}'");
|
||||
}
|
||||
}
|
||||
return errors.Count == 0;
|
||||
}
|
||||
|
||||
IEnumerable<(List<string> Path, Field Field)> GetAllFieldsCore(List<string> path, List<Field> fields)
|
||||
{
|
||||
foreach (var field in fields)
|
||||
{
|
||||
List<string> thisPath = new(path.Count + 1);
|
||||
thisPath.AddRange(path);
|
||||
if (!string.IsNullOrEmpty(field.Name))
|
||||
{
|
||||
thisPath.Add(field.Name);
|
||||
yield return (thisPath, field);
|
||||
}
|
||||
foreach (var descendant in GetAllFieldsCore(thisPath, field.Fields))
|
||||
{
|
||||
descendant.Field.Constant = field.Constant || descendant.Field.Constant;
|
||||
yield return descendant;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyValuesFromForm(IEnumerable<KeyValuePair<string, StringValues>> form)
|
||||
{
|
||||
var values = form.GroupBy(f => f.Key, f => f.Value).ToDictionary(g => g.Key, g => g.First());
|
||||
foreach (var f in GetAllFields())
|
||||
{
|
||||
if (f.Field.Constant || !values.TryGetValue(f.FullName, out var val))
|
||||
continue;
|
||||
|
||||
f.Field.Value = val;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
69
BTCPayServer.Abstractions/Models/BaseBTCPayServerPlugin.cs
Normal file
69
BTCPayServer.Abstractions/Models/BaseBTCPayServerPlugin.cs
Normal file
@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using BTCPayServer.Abstractions.Contracts;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Models
|
||||
{
|
||||
public abstract class BaseBTCPayServerPlugin : IBTCPayServerPlugin
|
||||
{
|
||||
public virtual string Identifier
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetType().GetTypeInfo().Assembly.GetName().Name;
|
||||
}
|
||||
}
|
||||
public virtual string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetType().GetTypeInfo().Assembly
|
||||
.GetCustomAttribute<AssemblyProductAttribute>()?
|
||||
.Product ?? "???";
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Version Version
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetVersion(GetType().GetTypeInfo().Assembly
|
||||
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?
|
||||
.InformationalVersion) ??
|
||||
Assembly.GetAssembly(GetType())?.GetName()?.Version ??
|
||||
new Version(1, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private static Version GetVersion(string informationalVersion)
|
||||
{
|
||||
if (informationalVersion is null)
|
||||
return null;
|
||||
Version.TryParse(informationalVersion, out var r);
|
||||
return r;
|
||||
}
|
||||
|
||||
public virtual string Description
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetType().GetTypeInfo().Assembly
|
||||
.GetCustomAttribute<AssemblyDescriptionAttribute>()?
|
||||
.Description ?? string.Empty;
|
||||
}
|
||||
}
|
||||
public bool SystemPlugin { get; set; }
|
||||
public virtual IBTCPayServerPlugin.PluginDependency[] Dependencies { get; } = Array.Empty<IBTCPayServerPlugin.PluginDependency>();
|
||||
|
||||
public virtual void Execute(IApplicationBuilder applicationBuilder,
|
||||
IServiceProvider applicationBuilderApplicationServices)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void Execute(IServiceCollection applicationBuilder)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
34
BTCPayServer.Abstractions/Models/ConfirmModel.cs
Normal file
34
BTCPayServer.Abstractions/Models/ConfirmModel.cs
Normal file
@ -0,0 +1,34 @@
|
||||
using System;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Models
|
||||
{
|
||||
public class ConfirmModel
|
||||
{
|
||||
private const string ButtonClassDefault = "btn-danger";
|
||||
|
||||
public ConfirmModel() { }
|
||||
|
||||
public ConfirmModel(string title, string desc, string action = null, string buttonClass = ButtonClassDefault, string actionName = null, string controllerName = null)
|
||||
{
|
||||
Title = title;
|
||||
Description = desc;
|
||||
Action = action;
|
||||
ActionName = actionName;
|
||||
ControllerName = controllerName;
|
||||
ButtonClass = buttonClass;
|
||||
|
||||
if (Description.Contains("<strong>", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
DescriptionHtml = true;
|
||||
}
|
||||
}
|
||||
|
||||
public string Title { get; set; }
|
||||
public string Description { get; set; }
|
||||
public bool DescriptionHtml { get; set; }
|
||||
public string Action { get; set; }
|
||||
public string ActionName { get; set; }
|
||||
public string ControllerName { get; set; }
|
||||
public string ButtonClass { get; set; } = ButtonClassDefault;
|
||||
}
|
||||
}
|
7
BTCPayServer.Abstractions/Models/DatabaseOptions.cs
Normal file
7
BTCPayServer.Abstractions/Models/DatabaseOptions.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace BTCPayServer.Abstractions.Models
|
||||
{
|
||||
public class DatabaseOptions
|
||||
{
|
||||
public string ConnectionString { get; set; }
|
||||
}
|
||||
}
|
42
BTCPayServer.Abstractions/Models/StatusMessageModel.cs
Normal file
42
BTCPayServer.Abstractions/Models/StatusMessageModel.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using System;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Models
|
||||
{
|
||||
public class StatusMessageModel
|
||||
{
|
||||
public StatusMessageModel()
|
||||
{
|
||||
}
|
||||
public string Message { get; set; }
|
||||
public string Html { get; set; }
|
||||
public StatusSeverity Severity { get; set; }
|
||||
public bool AllowDismiss { get; set; } = true;
|
||||
|
||||
public string SeverityCSS => ToString(Severity);
|
||||
|
||||
public static string ToString(StatusSeverity severity)
|
||||
{
|
||||
switch (severity)
|
||||
{
|
||||
case StatusSeverity.Info:
|
||||
return "info";
|
||||
case StatusSeverity.Error:
|
||||
return "danger";
|
||||
case StatusSeverity.Success:
|
||||
return "success";
|
||||
case StatusSeverity.Warning:
|
||||
return "warning";
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public enum StatusSeverity
|
||||
{
|
||||
Info,
|
||||
Error,
|
||||
Success,
|
||||
Warning
|
||||
}
|
||||
}
|
||||
}
|
16
BTCPayServer.Abstractions/Models/UploadImageResultModel.cs
Normal file
16
BTCPayServer.Abstractions/Models/UploadImageResultModel.cs
Normal file
@ -0,0 +1,16 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Abstractions.Contracts;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Models;
|
||||
|
||||
public class UploadImageResultModel
|
||||
{
|
||||
public bool Success { get; set; }
|
||||
public string Response { get; set; } = string.Empty;
|
||||
public IStoredFile? StoredFile { get; set; }
|
||||
}
|
7
BTCPayServer.Abstractions/PushNuget.ps1
Normal file
7
BTCPayServer.Abstractions/PushNuget.ps1
Normal file
@ -0,0 +1,7 @@
|
||||
rm "bin\release\" -Recurse -Force
|
||||
dotnet pack --configuration Release --include-symbols -p:SymbolPackageFormat=snupkg
|
||||
$package=(ls .\bin\Release\*.nupkg).FullName
|
||||
dotnet nuget push $package --source "https://api.nuget.org/v3/index.json"
|
||||
$ver = ((ls .\bin\release\*.nupkg)[0].Name -replace '.*(\d+\.\d+\.\d+)\.nupkg','$1')
|
||||
git tag -a "BTCPayServer.Abstractions/v$ver" -m "BTCPayServer.Abstractions/$ver"
|
||||
git push origin "BTCPayServer.Abstractions/v$ver"
|
@ -0,0 +1,27 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace BTCPayServer.Security;
|
||||
|
||||
public class AuthorizationFilterHandle
|
||||
{
|
||||
public AuthorizationHandlerContext Context { get; }
|
||||
public PolicyRequirement Requirement { get; }
|
||||
public HttpContext HttpContext { get; }
|
||||
public bool Success { get; private set; }
|
||||
|
||||
public AuthorizationFilterHandle(
|
||||
AuthorizationHandlerContext context,
|
||||
PolicyRequirement requirement,
|
||||
HttpContext httpContext)
|
||||
{
|
||||
Context = context;
|
||||
Requirement = requirement;
|
||||
HttpContext = httpContext;
|
||||
}
|
||||
|
||||
public void MarkSuccessful()
|
||||
{
|
||||
Success = true;
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NBitcoin.Crypto;
|
||||
|
||||
namespace BTCPayServer.Security
|
||||
{
|
||||
@ -10,6 +10,8 @@ namespace BTCPayServer.Security
|
||||
{
|
||||
public ConsentSecurityPolicy(string name, string value)
|
||||
{
|
||||
if (value.Contains(';', StringComparison.OrdinalIgnoreCase))
|
||||
throw new FormatException();
|
||||
_Value = value;
|
||||
_Name = name;
|
||||
}
|
||||
@ -66,14 +68,57 @@ namespace BTCPayServer.Security
|
||||
{
|
||||
|
||||
}
|
||||
HashSet<ConsentSecurityPolicy> _Policies = new HashSet<ConsentSecurityPolicy>();
|
||||
|
||||
readonly HashSet<ConsentSecurityPolicy> _Policies = new HashSet<ConsentSecurityPolicy>();
|
||||
|
||||
/// <summary>
|
||||
/// Allow a specific script as event handler
|
||||
/// </summary>
|
||||
/// <param name="script"></param>
|
||||
public void AllowUnsafeHashes(string script = null)
|
||||
{
|
||||
if (!allowUnsafeHashes)
|
||||
{
|
||||
Add("script-src", $"'unsafe-hashes'");
|
||||
allowUnsafeHashes = true;
|
||||
}
|
||||
if (script != null)
|
||||
{
|
||||
var sha = GetSha256(script);
|
||||
Add("script-src", $"'sha256-{sha}'");
|
||||
}
|
||||
}
|
||||
|
||||
bool allowUnsafeHashes = false;
|
||||
/// <summary>
|
||||
/// Allow the injection of script tag with the following script
|
||||
/// </summary>
|
||||
/// <param name="script"></param>
|
||||
public void AllowInline(string script)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(script);
|
||||
var sha = GetSha256(script);
|
||||
Add("script-src", $"'sha256-{sha}'");
|
||||
}
|
||||
static string GetSha256(string script)
|
||||
{
|
||||
return Convert.ToBase64String(Hashes.SHA256(Encoding.UTF8.GetBytes(script.Replace("\r\n", "\n", StringComparison.Ordinal))));
|
||||
}
|
||||
|
||||
public void Add(string name, string value)
|
||||
{
|
||||
Add(new ConsentSecurityPolicy(name, value));
|
||||
}
|
||||
public void Add(ConsentSecurityPolicy policy)
|
||||
{
|
||||
if (_Policies.Any(p => p.Name == policy.Name && p.Value == policy.Name))
|
||||
return;
|
||||
_Policies.Add(policy);
|
||||
}
|
||||
|
||||
public void UnsafeEval()
|
||||
{
|
||||
Add("script-src", "'unsafe-eval'");
|
||||
}
|
||||
|
||||
public IEnumerable<ConsentSecurityPolicy> Rules => _Policies;
|
||||
public bool HasRules => _Policies.Count != 0;
|
||||
|
||||
@ -81,40 +126,25 @@ namespace BTCPayServer.Security
|
||||
{
|
||||
StringBuilder value = new StringBuilder();
|
||||
bool firstGroup = true;
|
||||
foreach(var group in Rules.GroupBy(r => r.Name))
|
||||
foreach (var group in Rules.GroupBy(r => r.Name))
|
||||
{
|
||||
if (!firstGroup)
|
||||
{
|
||||
value.Append(';');
|
||||
}
|
||||
List<string> values = new List<string>();
|
||||
HashSet<string> values = new HashSet<string>();
|
||||
List<string> valuesList = new List<string>();
|
||||
values.Add(group.Key);
|
||||
valuesList.Add(group.Key);
|
||||
foreach (var v in group)
|
||||
{
|
||||
values.Add(v.Value);
|
||||
if (values.Add(v.Value))
|
||||
valuesList.Add(v.Value);
|
||||
}
|
||||
foreach(var i in authorized)
|
||||
{
|
||||
values.Add(i);
|
||||
}
|
||||
value.Append(String.Join(" ", values.OfType<object>().ToArray()));
|
||||
value.Append(String.Join(" ", valuesList.OfType<object>().ToArray()));
|
||||
firstGroup = false;
|
||||
}
|
||||
return value.ToString();
|
||||
}
|
||||
|
||||
internal void Clear()
|
||||
{
|
||||
authorized.Clear();
|
||||
_Policies.Clear();
|
||||
}
|
||||
|
||||
HashSet<string> authorized = new HashSet<string>();
|
||||
internal void AddAllAuthorized(string v)
|
||||
{
|
||||
authorized.Add(v);
|
||||
}
|
||||
|
||||
public IEnumerable<string> Authorized => authorized;
|
||||
}
|
||||
}
|
15
BTCPayServer.Abstractions/Security/PolicyRequirement.cs
Normal file
15
BTCPayServer.Abstractions/Security/PolicyRequirement.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
namespace BTCPayServer.Security
|
||||
{
|
||||
public class PolicyRequirement : IAuthorizationRequirement
|
||||
{
|
||||
public PolicyRequirement(string policy)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(policy);
|
||||
Policy = policy;
|
||||
}
|
||||
public string Policy { get; }
|
||||
}
|
||||
}
|
16
BTCPayServer.Abstractions/Services/PluginAction.cs
Normal file
16
BTCPayServer.Abstractions/Services/PluginAction.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Abstractions.Contracts;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Services
|
||||
{
|
||||
public abstract class PluginAction<T> : IPluginHookAction
|
||||
{
|
||||
public abstract string Hook { get; }
|
||||
public Task Execute(object args)
|
||||
{
|
||||
return Execute(args is T args1 ? args1 : default);
|
||||
}
|
||||
|
||||
public abstract Task Execute(T arg);
|
||||
}
|
||||
}
|
17
BTCPayServer.Abstractions/Services/PluginHookFilter.cs
Normal file
17
BTCPayServer.Abstractions/Services/PluginHookFilter.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Abstractions.Contracts;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Services
|
||||
{
|
||||
public abstract class PluginHookFilter<T> : IPluginHookFilter
|
||||
{
|
||||
public abstract string Hook { get; }
|
||||
|
||||
public Task<object> Execute(object args)
|
||||
{
|
||||
return Execute(args is T args1 ? args1 : default).ContinueWith(task => task.Result as object);
|
||||
}
|
||||
|
||||
public abstract Task<T> Execute(T arg);
|
||||
}
|
||||
}
|
36
BTCPayServer.Abstractions/Services/Safe.cs
Normal file
36
BTCPayServer.Abstractions/Services/Safe.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Web;
|
||||
using Ganss.Xss;
|
||||
using Microsoft.AspNetCore.Html;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Services
|
||||
{
|
||||
public class Safe
|
||||
{
|
||||
private readonly IHtmlHelper _htmlHelper;
|
||||
private readonly IJsonHelper _jsonHelper;
|
||||
private readonly HtmlSanitizer _htmlSanitizer;
|
||||
|
||||
public Safe(IHtmlHelper htmlHelper, IJsonHelper jsonHelper, HtmlSanitizer htmlSanitizer)
|
||||
{
|
||||
_htmlHelper = htmlHelper;
|
||||
_jsonHelper = jsonHelper;
|
||||
_htmlSanitizer = htmlSanitizer;
|
||||
}
|
||||
|
||||
public IHtmlContent Raw(string value)
|
||||
{
|
||||
return _htmlHelper.Raw(_htmlSanitizer.Sanitize(value));
|
||||
}
|
||||
|
||||
public IHtmlContent RawEncode(string value)
|
||||
{
|
||||
return _htmlHelper.Raw(HttpUtility.HtmlEncode(_htmlSanitizer.Sanitize(value)));
|
||||
}
|
||||
|
||||
public IHtmlContent Json(object model)
|
||||
{
|
||||
return _htmlHelper.Raw(_jsonHelper.Serialize(model));
|
||||
}
|
||||
}
|
||||
}
|
18
BTCPayServer.Abstractions/Services/UIExtension.cs
Normal file
18
BTCPayServer.Abstractions/Services/UIExtension.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using BTCPayServer.Abstractions.Contracts;
|
||||
|
||||
namespace BTCPayServer.Abstractions.Services
|
||||
{
|
||||
public class UIExtension : IUIExtension
|
||||
{
|
||||
[Obsolete("Use extension method BTCPayServer.Extensions.AddUIExtension(this IServiceCollection services, string location, string partialViewName) instead")]
|
||||
public UIExtension(string partial, string location)
|
||||
{
|
||||
Partial = partial;
|
||||
Location = location;
|
||||
}
|
||||
|
||||
public string Partial { get; }
|
||||
public string Location { get; }
|
||||
}
|
||||
}
|
30
BTCPayServer.Abstractions/TagHelpers/CSPA.cs
Normal file
30
BTCPayServer.Abstractions/TagHelpers/CSPA.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using BTCPayServer.Security;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
|
||||
namespace BTCPayServer.Abstractions.TagHelpers;
|
||||
|
||||
/// <summary>
|
||||
/// Add sha256- to allow inline event handlers in a:href=javascript:
|
||||
/// </summary>
|
||||
[HtmlTargetElement("a", Attributes = "csp-allow")]
|
||||
public class CSPA : TagHelper
|
||||
{
|
||||
private readonly ContentSecurityPolicies _csp;
|
||||
public CSPA(ContentSecurityPolicies csp)
|
||||
{
|
||||
_csp = csp;
|
||||
}
|
||||
public override void Process(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
output.Attributes.RemoveAll("csp-allow");
|
||||
if (output.Attributes.TryGetAttribute("href", out var attr))
|
||||
{
|
||||
var v = attr.Value.ToString();
|
||||
if (v.StartsWith("javascript:", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
_csp.AllowUnsafeHashes(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
37
BTCPayServer.Abstractions/TagHelpers/CSPEventTagHelper.cs
Normal file
37
BTCPayServer.Abstractions/TagHelpers/CSPEventTagHelper.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BTCPayServer.Security;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
|
||||
namespace BTCPayServer.Abstractions.TagHelpers;
|
||||
|
||||
/// <summary>
|
||||
/// Add 'unsafe-hashes' and sha256- to allow inline event handlers in CSP
|
||||
/// </summary>
|
||||
[HtmlTargetElement(Attributes = "onclick")]
|
||||
[HtmlTargetElement(Attributes = "onkeypress")]
|
||||
[HtmlTargetElement(Attributes = "onchange")]
|
||||
[HtmlTargetElement(Attributes = "onsubmit")]
|
||||
public class CSPEventTagHelper : TagHelper
|
||||
{
|
||||
public const string EventNames = "onclick,onkeypress,onchange,onsubmit";
|
||||
private readonly ContentSecurityPolicies _csp;
|
||||
|
||||
readonly static HashSet<string> EventSet = EventNames.Split(',')
|
||||
.ToHashSet();
|
||||
public CSPEventTagHelper(ContentSecurityPolicies csp)
|
||||
{
|
||||
_csp = csp;
|
||||
}
|
||||
public override void Process(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
foreach (var attr in output.Attributes)
|
||||
{
|
||||
var n = attr.Name.ToLowerInvariant();
|
||||
if (EventSet.Contains(n))
|
||||
{
|
||||
_csp.AllowUnsafeHashes(attr.Value.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
using BTCPayServer.Security;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
using NBitcoin;
|
||||
|
||||
namespace BTCPayServer.Abstractions.TagHelpers;
|
||||
|
||||
/// <summary>
|
||||
/// Add a nonce-* so the inline-script can pass CSP rule when they are rendered server-side
|
||||
/// </summary>
|
||||
[HtmlTargetElement("script")]
|
||||
public class CSPInlineScriptTagHelper : TagHelper
|
||||
{
|
||||
private readonly ContentSecurityPolicies _csp;
|
||||
|
||||
public CSPInlineScriptTagHelper(ContentSecurityPolicies csp)
|
||||
{
|
||||
_csp = csp;
|
||||
}
|
||||
|
||||
public override void Process(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
if (output.Attributes.ContainsName("src"))
|
||||
return;
|
||||
if (output.Attributes.TryGetAttribute("type", out var attr))
|
||||
{
|
||||
if (attr.Value?.ToString() != "text/javascript")
|
||||
return;
|
||||
}
|
||||
var nonce = RandomUtils.GetUInt256().ToString().Substring(0, 32);
|
||||
output.Attributes.Add(new TagHelperAttribute("nonce", nonce));
|
||||
_csp.Add("script-src", $"'nonce-{nonce}'");
|
||||
}
|
||||
}
|
25
BTCPayServer.Abstractions/TagHelpers/CSPTemplate.cs
Normal file
25
BTCPayServer.Abstractions/TagHelpers/CSPTemplate.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Security;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
|
||||
namespace BTCPayServer.Abstractions.TagHelpers;
|
||||
|
||||
/// <summary>
|
||||
/// Add sha256- to allow inline event handlers in CSP
|
||||
/// </summary>
|
||||
[HtmlTargetElement("template", Attributes = "csp-allow")]
|
||||
public class CSPTemplate : TagHelper
|
||||
{
|
||||
private readonly ContentSecurityPolicies _csp;
|
||||
public CSPTemplate(ContentSecurityPolicies csp)
|
||||
{
|
||||
_csp = csp;
|
||||
}
|
||||
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
output.Attributes.RemoveAll("csp-allow");
|
||||
var childContent = await output.GetChildContentAsync();
|
||||
var content = childContent.GetContent();
|
||||
_csp.AllowInline(content);
|
||||
}
|
||||
}
|
94
BTCPayServer.Abstractions/TagHelpers/PermissionTagHelper.cs
Normal file
94
BTCPayServer.Abstractions/TagHelpers/PermissionTagHelper.cs
Normal file
@ -0,0 +1,94 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace BTCPayServer.Abstractions.TagHelpers;
|
||||
|
||||
[HtmlTargetElement(Attributes = "[permission]")]
|
||||
[HtmlTargetElement(Attributes = "[not-permission]")]
|
||||
public class PermissionTagHelper : TagHelper
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
|
||||
public PermissionTagHelper(IAuthorizationService authorizationService, IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
_authorizationService = authorizationService;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
}
|
||||
|
||||
public string Permission { get; set; }
|
||||
public string NotPermission { get; set; }
|
||||
public string PermissionResource { get; set; }
|
||||
public bool AndMode { get; set; } = false;
|
||||
|
||||
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
var permissions = Permission?.Split(',', StringSplitOptions.RemoveEmptyEntries) ?? Array.Empty<string>();
|
||||
var notPermissions = NotPermission?.Split(',', StringSplitOptions.RemoveEmptyEntries) ?? Array.Empty<string>();
|
||||
|
||||
if (!permissions.Any() && !notPermissions.Any())
|
||||
return;
|
||||
if (_httpContextAccessor.HttpContext is null)
|
||||
return;
|
||||
|
||||
bool shouldRender = true; // Assume tag should be rendered unless a check fails
|
||||
|
||||
// Process 'Permission' - User must have these permissions
|
||||
if (permissions.Any())
|
||||
{
|
||||
bool finalResult = AndMode;
|
||||
foreach (var perm in permissions)
|
||||
{
|
||||
var key = $"{perm}_{PermissionResource}";
|
||||
AuthorizationResult res = await GetOrAddAuthorizationResult(key, perm);
|
||||
|
||||
if (AndMode)
|
||||
finalResult &= res.Succeeded;
|
||||
else
|
||||
finalResult |= res.Succeeded;
|
||||
|
||||
if (!AndMode && finalResult) break;
|
||||
}
|
||||
|
||||
shouldRender = finalResult;
|
||||
}
|
||||
|
||||
// Process 'NotPermission' - User must not have these permissions
|
||||
if (shouldRender && notPermissions.Any())
|
||||
{
|
||||
foreach (var notPerm in notPermissions)
|
||||
{
|
||||
var key = $"{notPerm}_{PermissionResource}";
|
||||
AuthorizationResult res = await GetOrAddAuthorizationResult(key, notPerm);
|
||||
|
||||
if (res.Succeeded) // If the user has a 'NotPermission', they should not see the tag
|
||||
{
|
||||
shouldRender = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!shouldRender)
|
||||
{
|
||||
output.SuppressOutput();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<AuthorizationResult> GetOrAddAuthorizationResult(string key, string permission)
|
||||
{
|
||||
if (!_httpContextAccessor.HttpContext.Items.TryGetValue(key, out var cachedResult))
|
||||
{
|
||||
var res = await _authorizationService.AuthorizeAsync(_httpContextAccessor.HttpContext.User,
|
||||
PermissionResource, permission);
|
||||
_httpContextAccessor.HttpContext.Items[key] = res;
|
||||
return res;
|
||||
}
|
||||
|
||||
return cachedResult as AuthorizationResult;
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
|
||||
namespace BTCPayServer.Abstractions.TagHelpers;
|
||||
|
||||
[HtmlTargetElement("form", Attributes = "[permissioned]")]
|
||||
public partial class PermissionedFormTagHelper(
|
||||
IAuthorizationService authorizationService,
|
||||
IHttpContextAccessor httpContextAccessor)
|
||||
: TagHelper
|
||||
{
|
||||
public string Permissioned { get; set; }
|
||||
public string PermissionResource { get; set; }
|
||||
|
||||
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
if (httpContextAccessor.HttpContext is null || string.IsNullOrEmpty(Permissioned))
|
||||
return;
|
||||
|
||||
var res = await authorizationService.AuthorizeAsync(httpContextAccessor.HttpContext.User,
|
||||
PermissionResource, Permissioned);
|
||||
if (!res.Succeeded)
|
||||
{
|
||||
var content = await output.GetChildContentAsync();
|
||||
var html = SubmitButtonRegex().Replace(content.GetContent(), "");
|
||||
output.Content.SetHtmlContent($"<fieldset disabled>{html}</fieldset>");
|
||||
}
|
||||
}
|
||||
|
||||
[GeneratedRegex("<(button|input).*?type=\"submit\".*?>.*?</\\1>")]
|
||||
private static partial Regex SubmitButtonRegex();
|
||||
}
|
42
BTCPayServer.Abstractions/TagHelpers/SVGUse.cs
Normal file
42
BTCPayServer.Abstractions/TagHelpers/SVGUse.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Text.Encodings.Web;
|
||||
using Microsoft.AspNetCore.Html;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.AspNetCore.Mvc.Routing;
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
|
||||
namespace BTCPayServer.Abstractions.TagHelpers;
|
||||
|
||||
// Make sure that <svg><use href=/ are correctly working if rootpath is present
|
||||
[HtmlTargetElement("use", Attributes = "href")]
|
||||
public class SVGUse : UrlResolutionTagHelper2
|
||||
{
|
||||
private readonly IFileVersionProvider _fileVersionProvider;
|
||||
|
||||
public SVGUse(IUrlHelperFactory urlHelperFactory, HtmlEncoder htmlEncoder, IFileVersionProvider fileVersionProvider) : base(urlHelperFactory, htmlEncoder)
|
||||
{
|
||||
_fileVersionProvider = fileVersionProvider;
|
||||
}
|
||||
|
||||
public override void Process(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
var attr = output.Attributes["href"].Value.ToString();
|
||||
var symbolIndex = attr!.IndexOf("#", StringComparison.InvariantCulture);
|
||||
var start = attr.IndexOf("~", StringComparison.InvariantCulture) + 1;
|
||||
var length = (symbolIndex != -1 ? symbolIndex : attr.Length) - start;
|
||||
var filePath = attr.Substring(start, length);
|
||||
if (!string.IsNullOrEmpty(filePath))
|
||||
{
|
||||
var versioned = _fileVersionProvider.AddFileVersionToPath(ViewContext.HttpContext.Request.PathBase, filePath);
|
||||
attr = attr.Replace(filePath, versioned);
|
||||
}
|
||||
output.Attributes.SetAttribute("href", attr);
|
||||
base.Process(context, output);
|
||||
}
|
||||
}
|
31
BTCPayServer.Abstractions/TagHelpers/SrvModel.cs
Normal file
31
BTCPayServer.Abstractions/TagHelpers/SrvModel.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using BTCPayServer.Abstractions.Services;
|
||||
using BTCPayServer.Security;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
using NBitcoin;
|
||||
|
||||
namespace BTCPayServer.Abstractions.TagHelpers;
|
||||
|
||||
[HtmlTargetElement("srv-model")]
|
||||
public class SrvModel : TagHelper
|
||||
{
|
||||
private readonly Safe _safe;
|
||||
private readonly ContentSecurityPolicies _csp;
|
||||
|
||||
public SrvModel(Safe safe, ContentSecurityPolicies csp)
|
||||
{
|
||||
_safe = safe;
|
||||
_csp = csp;
|
||||
}
|
||||
public string VarName { get; set; } = "srvModel";
|
||||
public object Model { get; set; }
|
||||
public override void Process(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
output.TagName = "script";
|
||||
output.TagMode = TagMode.StartTagAndEndTag;
|
||||
output.Attributes.Add(new TagHelperAttribute("type", "text/javascript"));
|
||||
var nonce = RandomUtils.GetUInt256().ToString().Substring(0, 32);
|
||||
output.Attributes.Add(new TagHelperAttribute("nonce", nonce));
|
||||
_csp.Add("script-src", $"'nonce-{nonce}'");
|
||||
output.Content.SetHtmlContent($"var {VarName} = {_safe.Json(Model)};");
|
||||
}
|
||||
}
|
314
BTCPayServer.Abstractions/TagHelpers/UrlResolutionTagHelper2.cs
Normal file
314
BTCPayServer.Abstractions/TagHelpers/UrlResolutionTagHelper2.cs
Normal file
@ -0,0 +1,314 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Text.Encodings.Web;
|
||||
using Microsoft.AspNetCore.Html;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.AspNetCore.Mvc.Routing;
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
|
||||
|
||||
namespace BTCPayServer.Abstractions.TagHelpers
|
||||
{
|
||||
// A copy of https://github.com/dotnet/aspnetcore/blob/39f0e0b8f40b4754418f81aef0de58a9204a1fe5/src/Mvc/Mvc.Razor/src/TagHelpers/UrlResolutionTagHelper.cs
|
||||
// slightly modified to also work on use tag.
|
||||
public class UrlResolutionTagHelper2 : TagHelper
|
||||
{
|
||||
// Valid whitespace characters defined by the HTML5 spec.
|
||||
private static readonly char[] ValidAttributeWhitespaceChars =
|
||||
new[] { '\t', '\n', '\u000C', '\r', ' ' };
|
||||
private static readonly Dictionary<string, string[]> ElementAttributeLookups =
|
||||
new(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "use", new[] { "href" } },
|
||||
{ "a", new[] { "href" } },
|
||||
{ "applet", new[] { "archive" } },
|
||||
{ "area", new[] { "href" } },
|
||||
{ "audio", new[] { "src" } },
|
||||
{ "base", new[] { "href" } },
|
||||
{ "blockquote", new[] { "cite" } },
|
||||
{ "button", new[] { "formaction" } },
|
||||
{ "del", new[] { "cite" } },
|
||||
{ "embed", new[] { "src" } },
|
||||
{ "form", new[] { "action" } },
|
||||
{ "html", new[] { "manifest" } },
|
||||
{ "iframe", new[] { "src" } },
|
||||
{ "img", new[] { "src", "srcset" } },
|
||||
{ "input", new[] { "src", "formaction" } },
|
||||
{ "ins", new[] { "cite" } },
|
||||
{ "link", new[] { "href" } },
|
||||
{ "menuitem", new[] { "icon" } },
|
||||
{ "object", new[] { "archive", "data" } },
|
||||
{ "q", new[] { "cite" } },
|
||||
{ "script", new[] { "src" } },
|
||||
{ "source", new[] { "src", "srcset" } },
|
||||
{ "track", new[] { "src" } },
|
||||
{ "video", new[] { "poster", "src" } },
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="UrlResolutionTagHelper"/>.
|
||||
/// </summary>
|
||||
/// <param name="urlHelperFactory">The <see cref="IUrlHelperFactory"/>.</param>
|
||||
/// <param name="htmlEncoder">The <see cref="HtmlEncoder"/>.</param>
|
||||
public UrlResolutionTagHelper2(IUrlHelperFactory urlHelperFactory, HtmlEncoder htmlEncoder)
|
||||
{
|
||||
UrlHelperFactory = urlHelperFactory;
|
||||
HtmlEncoder = htmlEncoder;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int Order => -1000 - 999;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IUrlHelperFactory"/>.
|
||||
/// </summary>
|
||||
protected IUrlHelperFactory UrlHelperFactory { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="HtmlEncoder"/>.
|
||||
/// </summary>
|
||||
protected HtmlEncoder HtmlEncoder { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ViewContext"/>.
|
||||
/// </summary>
|
||||
[HtmlAttributeNotBound]
|
||||
[ViewContext]
|
||||
public ViewContext ViewContext { get; set; } = default!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Process(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(context);
|
||||
ArgumentNullException.ThrowIfNull(output);
|
||||
|
||||
if (output.TagName == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ElementAttributeLookups.TryGetValue(output.TagName, out var attributeNames))
|
||||
{
|
||||
for (var i = 0; i < attributeNames.Length; i++)
|
||||
{
|
||||
ProcessUrlAttribute(attributeNames[i], output);
|
||||
}
|
||||
}
|
||||
|
||||
// itemid can be present on any HTML element.
|
||||
ProcessUrlAttribute("itemid", output);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves and updates URL values starting with '~/' (relative to the application's 'webroot' setting) for
|
||||
/// <paramref name="output"/>'s <see cref="TagHelperOutput.Attributes"/> whose
|
||||
/// <see cref="TagHelperAttribute.Name"/> is <paramref name="attributeName"/>.
|
||||
/// </summary>
|
||||
/// <param name="attributeName">The attribute name used to lookup values to resolve.</param>
|
||||
/// <param name="output">The <see cref="TagHelperOutput"/>.</param>
|
||||
protected void ProcessUrlAttribute(string attributeName, TagHelperOutput output)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(attributeName);
|
||||
ArgumentNullException.ThrowIfNull(output);
|
||||
|
||||
var attributes = output.Attributes;
|
||||
// Read interface .Count once rather than per iteration
|
||||
var attributesCount = attributes.Count;
|
||||
for (var i = 0; i < attributesCount; i++)
|
||||
{
|
||||
var attribute = attributes[i];
|
||||
if (!string.Equals(attribute.Name, attributeName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (attribute.Value is string stringValue)
|
||||
{
|
||||
if (TryResolveUrl(stringValue, resolvedUrl: out string? resolvedUrl))
|
||||
{
|
||||
attributes[i] = new TagHelperAttribute(
|
||||
attribute.Name,
|
||||
resolvedUrl,
|
||||
attribute.ValueStyle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (attribute.Value is IHtmlContent htmlContent)
|
||||
{
|
||||
var htmlString = htmlContent as HtmlString;
|
||||
if (htmlString != null)
|
||||
{
|
||||
// No need for a StringWriter in this case.
|
||||
stringValue = htmlString.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
using var writer = new StringWriter();
|
||||
htmlContent.WriteTo(writer, HtmlEncoder);
|
||||
stringValue = writer.ToString();
|
||||
}
|
||||
|
||||
if (TryResolveUrl(stringValue, resolvedUrl: out IHtmlContent? resolvedUrl))
|
||||
{
|
||||
attributes[i] = new TagHelperAttribute(
|
||||
attribute.Name,
|
||||
resolvedUrl,
|
||||
attribute.ValueStyle);
|
||||
}
|
||||
else if (htmlString == null)
|
||||
{
|
||||
// Not a ~/ URL. Just avoid re-encoding the attribute value later.
|
||||
attributes[i] = new TagHelperAttribute(
|
||||
attribute.Name,
|
||||
new HtmlString(stringValue),
|
||||
attribute.ValueStyle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to resolve the given <paramref name="url"/> value relative to the application's 'webroot' setting.
|
||||
/// </summary>
|
||||
/// <param name="url">The URL to resolve.</param>
|
||||
/// <param name="resolvedUrl">Absolute URL beginning with the application's virtual root. <c>null</c> if
|
||||
/// <paramref name="url"/> could not be resolved.</param>
|
||||
/// <returns><c>true</c> if the <paramref name="url"/> could be resolved; <c>false</c> otherwise.</returns>
|
||||
protected bool TryResolveUrl(string url, out string? resolvedUrl)
|
||||
{
|
||||
resolvedUrl = null;
|
||||
var start = FindRelativeStart(url);
|
||||
if (start == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var trimmedUrl = CreateTrimmedString(url, start);
|
||||
|
||||
var urlHelper = UrlHelperFactory.GetUrlHelper(ViewContext);
|
||||
resolvedUrl = urlHelper.Content(trimmedUrl);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to resolve the given <paramref name="url"/> value relative to the application's 'webroot' setting.
|
||||
/// </summary>
|
||||
/// <param name="url">The URL to resolve.</param>
|
||||
/// <param name="resolvedUrl">
|
||||
/// Absolute URL beginning with the application's virtual root. <c>null</c> if <paramref name="url"/> could
|
||||
/// not be resolved.
|
||||
/// </param>
|
||||
/// <returns><c>true</c> if the <paramref name="url"/> could be resolved; <c>false</c> otherwise.</returns>
|
||||
protected bool TryResolveUrl(string url, [NotNullWhen(true)] out IHtmlContent? resolvedUrl)
|
||||
{
|
||||
resolvedUrl = null;
|
||||
var start = FindRelativeStart(url);
|
||||
if (start == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var trimmedUrl = CreateTrimmedString(url, start);
|
||||
|
||||
var urlHelper = UrlHelperFactory.GetUrlHelper(ViewContext);
|
||||
var appRelativeUrl = urlHelper.Content(trimmedUrl);
|
||||
var postTildeSlashUrlValue = trimmedUrl.Substring(2);
|
||||
|
||||
if (!appRelativeUrl.EndsWith(postTildeSlashUrlValue, StringComparison.Ordinal))
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
resolvedUrl = new EncodeFirstSegmentContent(
|
||||
appRelativeUrl,
|
||||
appRelativeUrl.Length - postTildeSlashUrlValue.Length,
|
||||
postTildeSlashUrlValue);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static int FindRelativeStart(string url)
|
||||
{
|
||||
if (url == null || url.Length < 2)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
var maxTestLength = url.Length - 2;
|
||||
|
||||
var start = 0;
|
||||
for (; start < url.Length; start++)
|
||||
{
|
||||
if (start > maxTestLength)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!IsCharWhitespace(url[start]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Before doing more work, ensure that the URL we're looking at is app-relative.
|
||||
if (url[start] != '~' || url[start + 1] != '/')
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
private static string CreateTrimmedString(string input, int start)
|
||||
{
|
||||
var end = input.Length - 1;
|
||||
for (; end >= start; end--)
|
||||
{
|
||||
if (!IsCharWhitespace(input[end]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var len = end - start + 1;
|
||||
|
||||
// Substring returns same string if start == 0 && len == Length
|
||||
return input.Substring(start, len);
|
||||
}
|
||||
|
||||
private static bool IsCharWhitespace(char ch)
|
||||
{
|
||||
return ValidAttributeWhitespaceChars.AsSpan().IndexOf(ch) != -1;
|
||||
}
|
||||
|
||||
private sealed class EncodeFirstSegmentContent : IHtmlContent
|
||||
{
|
||||
private readonly string _firstSegment;
|
||||
private readonly int _firstSegmentLength;
|
||||
private readonly string _secondSegment;
|
||||
|
||||
public EncodeFirstSegmentContent(string firstSegment, int firstSegmentLength, string secondSegment)
|
||||
{
|
||||
_firstSegment = firstSegment;
|
||||
_firstSegmentLength = firstSegmentLength;
|
||||
_secondSegment = secondSegment;
|
||||
}
|
||||
|
||||
public void WriteTo(TextWriter writer, HtmlEncoder encoder)
|
||||
{
|
||||
encoder.Encode(writer, _firstSegment, 0, _firstSegmentLength);
|
||||
writer.Write(_secondSegment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
BIN
BTCPayServer.Abstractions/icon.png
Normal file
BIN
BTCPayServer.Abstractions/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
154
BTCPayServer.Client/App/IBTCPayAppHubClient.cs
Normal file
154
BTCPayServer.Client/App/IBTCPayAppHubClient.cs
Normal file
@ -0,0 +1,154 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
using BTCPayServer.Lightning;
|
||||
using NBitcoin;
|
||||
|
||||
namespace BTCPayServer.Client.App;
|
||||
|
||||
//methods available on the hub in the client
|
||||
public interface IBTCPayAppHubClient
|
||||
{
|
||||
Task NotifyServerEvent(ServerEvent ev);
|
||||
Task NotifyNetwork(string network);
|
||||
Task NotifyServerNode(string nodeInfo);
|
||||
Task TransactionDetected(TransactionDetectedRequest request);
|
||||
Task NewBlock(string block);
|
||||
Task StartListen(string key);
|
||||
|
||||
Task<LightningInvoice> CreateInvoice(string key, CreateLightningInvoiceRequest createLightningInvoiceRequest);
|
||||
Task<LightningInvoice?> GetLightningInvoice(string key, uint256 paymentHash);
|
||||
Task<LightningPayment?> GetLightningPayment(string key, uint256 paymentHash);
|
||||
Task CancelInvoice(string key, uint256 paymentHash);
|
||||
Task<List<LightningPayment>> GetLightningPayments(string key, ListPaymentsParams request);
|
||||
Task<List<LightningInvoice>> GetLightningInvoices(string key, ListInvoicesParams request);
|
||||
Task<PayResponse> PayInvoice(string key, string bolt11, long? amountMilliSatoshi);
|
||||
Task MasterUpdated(long? deviceIdentifier);
|
||||
Task<LightningNodeInformation> GetLightningNodeInfo(string key);
|
||||
Task<LightningNodeBalance> GetLightningBalance(string key);
|
||||
}
|
||||
|
||||
//methods available on the hub in the server
|
||||
public interface IBTCPayAppHubServer
|
||||
{
|
||||
Task<bool> DeviceMasterSignal(long deviceIdentifier, bool active);
|
||||
|
||||
Task<Dictionary<string,string>> Pair(PairRequest request);
|
||||
Task<AppHandshakeResponse> Handshake(AppHandshake request);
|
||||
Task<bool> BroadcastTransaction(string tx);
|
||||
Task<decimal> GetFeeRate(int blockTarget);
|
||||
Task<BestBlockResponse> GetBestBlock();
|
||||
Task<TxInfoResponse> FetchTxsAndTheirBlockHeads(string identifier, string[] txIds, string[] outpoints);
|
||||
Task<ScriptResponse> DeriveScript(string identifier);
|
||||
Task TrackScripts(string identifier, string[] scripts);
|
||||
Task<string> UpdatePsbt(string[] identifiers, string psbt);
|
||||
Task<Dictionary<string, CoinResponse[]>> GetUTXOs(string[] identifiers);
|
||||
Task<Dictionary<string, TxResp[]>> GetTransactions(string[] identifiers);
|
||||
Task SendInvoiceUpdate(LightningInvoice lightningInvoice);
|
||||
Task<long?> GetCurrentMaster();
|
||||
}
|
||||
|
||||
public class ServerEvent
|
||||
{
|
||||
public string? Type { get; set; }
|
||||
public string? StoreId { get; set; }
|
||||
public string? UserId { get; set; }
|
||||
public string? AppId { get; set; }
|
||||
public string? InvoiceId { get; set; }
|
||||
public string? Detail { get; set; }
|
||||
}
|
||||
|
||||
public record TxResp
|
||||
{
|
||||
public TxResp(long confirmations, long? height, decimal balanceChange, DateTimeOffset timestamp, string transactionId)
|
||||
{
|
||||
Confirmations = confirmations;
|
||||
Height = height;
|
||||
BalanceChange = balanceChange;
|
||||
Timestamp = timestamp;
|
||||
TransactionId = transactionId;
|
||||
}
|
||||
|
||||
public long Confirmations { get; set; }
|
||||
public long? Height { get; set; }
|
||||
public decimal BalanceChange { get; set; }
|
||||
public DateTimeOffset Timestamp { get; set; }
|
||||
public string TransactionId { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{{ Confirmations = {Confirmations}, Height = {Height}, BalanceChange = {BalanceChange}, Timestamp = {Timestamp}, TransactionId = {TransactionId} }}";
|
||||
}
|
||||
}
|
||||
|
||||
public class TransactionDetectedRequest
|
||||
{
|
||||
public string? Identifier { get; set; }
|
||||
public string? TxId { get; set; }
|
||||
public string[]? SpentScripts { get; set; }
|
||||
public string[]? ReceivedScripts { get; set; }
|
||||
public bool Confirmed { get; set; }
|
||||
}
|
||||
|
||||
public class CoinResponse
|
||||
{
|
||||
public bool Confirmed { get; set; }
|
||||
public string? Script { get; set; }
|
||||
public string? Outpoint { get; set; }
|
||||
public decimal Value { get; set; }
|
||||
public string? Path { get; set; }
|
||||
}
|
||||
|
||||
public class TxInfoResponse
|
||||
{
|
||||
public Dictionary<string,TransactionResponse>? Txs { get; set; }
|
||||
public Dictionary<string,string>? BlockHeaders { get; set; }
|
||||
public Dictionary<string,int>? BlockHeghts { get; set; }
|
||||
}
|
||||
|
||||
public class TransactionResponse
|
||||
{
|
||||
public string? BlockHash { get; set; }
|
||||
public string? Transaction { get; set; }
|
||||
}
|
||||
|
||||
public class BestBlockResponse
|
||||
{
|
||||
public string? BlockHash { get; set; }
|
||||
public int BlockHeight { get; set; }
|
||||
public string? BlockHeader { get; set; }
|
||||
}
|
||||
|
||||
public class ScriptResponse
|
||||
{
|
||||
public string Script { get; set; }
|
||||
public string KeyPath { get; set; }
|
||||
}
|
||||
|
||||
public class AppHandshake
|
||||
{
|
||||
public string[]? Identifiers { get; set; }
|
||||
}
|
||||
|
||||
public class AppHandshakeResponse
|
||||
{
|
||||
//response about identifiers being tracked successfully
|
||||
public string[]? IdentifiersAcknowledged { get; set; }
|
||||
}
|
||||
|
||||
public class PairRequest
|
||||
{
|
||||
public Dictionary<string, DerivationItem?> Derivations { get; set; } = new();
|
||||
}
|
||||
|
||||
public class DerivationItem
|
||||
{
|
||||
public string Descriptor { get; set; }
|
||||
public int Index { get; set; }
|
||||
|
||||
public OutPoint[] KnownCoins { get; set; } = Array.Empty<OutPoint>();
|
||||
|
||||
|
||||
}
|
8
BTCPayServer.Client/App/Models/AcceptInviteRequest.cs
Normal file
8
BTCPayServer.Client/App/Models/AcceptInviteRequest.cs
Normal file
@ -0,0 +1,8 @@
|
||||
#nullable enable
|
||||
namespace BTCPayServer.Client.App.Models;
|
||||
|
||||
public class AcceptInviteRequest
|
||||
{
|
||||
public string? UserId { get; set; }
|
||||
public string? Code { get; set; }
|
||||
}
|
10
BTCPayServer.Client/App/Models/AcceptInviteResult.cs
Normal file
10
BTCPayServer.Client/App/Models/AcceptInviteResult.cs
Normal file
@ -0,0 +1,10 @@
|
||||
#nullable enable
|
||||
namespace BTCPayServer.Client.App.Models;
|
||||
|
||||
public class AcceptInviteResult
|
||||
{
|
||||
public string? Email { get; set; }
|
||||
public bool? RequiresUserApproval { get; set; }
|
||||
public bool? EmailHasBeenConfirmed { get; set; }
|
||||
public string? PasswordSetCode { get; set; }
|
||||
}
|
10
BTCPayServer.Client/App/Models/AccessTokenResult.cs
Normal file
10
BTCPayServer.Client/App/Models/AccessTokenResult.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using System;
|
||||
|
||||
namespace BTCPayServer.Client.App.Models;
|
||||
|
||||
public class AccessTokenResult
|
||||
{
|
||||
public string AccessToken { get; set; }
|
||||
public string RefreshToken { get; set; }
|
||||
public DateTimeOffset Expiry { get; set; }
|
||||
}
|
13
BTCPayServer.Client/App/Models/AppInstanceInfo.cs
Normal file
13
BTCPayServer.Client/App/Models/AppInstanceInfo.cs
Normal file
@ -0,0 +1,13 @@
|
||||
#nullable enable
|
||||
namespace BTCPayServer.Client.App.Models;
|
||||
|
||||
public class AppInstanceInfo
|
||||
{
|
||||
public string BaseUrl { get; set; } = null!;
|
||||
public string ServerName { get; set; } = null!;
|
||||
public string? ContactUrl { get; set; }
|
||||
public string? LogoUrl { get; set; }
|
||||
public string? CustomThemeCssUrl { get; set; }
|
||||
public string? CustomThemeExtension { get; set; }
|
||||
public bool RegistrationEnabled { get; set; }
|
||||
}
|
44
BTCPayServer.Client/App/Models/AppUserInfo.cs
Normal file
44
BTCPayServer.Client/App/Models/AppUserInfo.cs
Normal file
@ -0,0 +1,44 @@
|
||||
#nullable enable
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BTCPayServer.Client.App.Models;
|
||||
|
||||
public class AppUserInfo
|
||||
{
|
||||
public string? UserId { get; set; }
|
||||
public string? Email { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? ImageUrl { get; set; }
|
||||
public IEnumerable<string>? Roles { get; set; }
|
||||
public IEnumerable<AppUserStoreInfo>? Stores { get; set; }
|
||||
|
||||
public void SetInfo(string email, string? name, string? imageUrl)
|
||||
{
|
||||
Email = email;
|
||||
Name = name;
|
||||
ImageUrl = imageUrl;
|
||||
}
|
||||
|
||||
public static bool Equals(AppUserInfo? x, AppUserInfo? y)
|
||||
{
|
||||
if (ReferenceEquals(x, y)) return true;
|
||||
if (ReferenceEquals(x, null)) return false;
|
||||
if (ReferenceEquals(y, null)) return false;
|
||||
if (x.GetType() != y.GetType()) return false;
|
||||
return x.UserId == y.UserId && x.Email == y.Email &&
|
||||
x.Name == y.Name && x.ImageUrl == y.ImageUrl &&
|
||||
Equals(x.Roles, y.Roles) && Equals(x.Stores, y.Stores);
|
||||
}
|
||||
}
|
||||
|
||||
public class AppUserStoreInfo
|
||||
{
|
||||
public string Id { get; set; } = null!;
|
||||
public string? Name { get; set; }
|
||||
public string? LogoUrl { get; set; }
|
||||
public string? RoleId { get; set; }
|
||||
public string? PosAppId { get; set; }
|
||||
public string? DefaultCurrency { get; set; }
|
||||
public bool Archived { get; set; }
|
||||
public IEnumerable<string>? Permissions { get; set; }
|
||||
}
|
11
BTCPayServer.Client/App/Models/CreateStoreData.cs
Normal file
11
BTCPayServer.Client/App/Models/CreateStoreData.cs
Normal file
@ -0,0 +1,11 @@
|
||||
#nullable enable
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BTCPayServer.Client.App.Models;
|
||||
|
||||
public class CreateStoreData
|
||||
{
|
||||
public string? DefaultCurrency { get; set; }
|
||||
public string? RecommendedExchangeId { get; set; }
|
||||
public Dictionary<string, string>? Exchanges { get; set; }
|
||||
}
|
40
BTCPayServer.Client/BTCPayServer.Client.csproj
Normal file
40
BTCPayServer.Client/BTCPayServer.Client.csproj
Normal file
@ -0,0 +1,40 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<Company>BTCPay Server</Company>
|
||||
<Copyright>Copyright © BTCPay Server 2020</Copyright>
|
||||
<Description>A client library for BTCPay Server Greenfield API</Description>
|
||||
<PackageIcon>icon.png</PackageIcon>
|
||||
<PackageTags>btcpay,btcpayserver</PackageTags>
|
||||
<PackageProjectUrl>https://github.com/btcpayserver/btcpayserver/tree/master/BTCPayServer.Client</PackageProjectUrl>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<RepositoryUrl>https://github.com/btcpayserver/btcpayserver</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Platforms>AnyCPU</Platforms>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<Version Condition=" '$(Version)' == '' ">2.0.1</Version>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
<DebugType>portable</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>1591;1573;1572;1584;1570;3021</NoWarn>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BTCPayServer.Lightning.Common" Version="1.5.2" />
|
||||
<PackageReference Include="NBitcoin" Version="7.0.46" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="icon.png" Pack="true" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
44
BTCPayServer.Client/BTCPayServerClient.APIKeys.cs
Normal file
44
BTCPayServer.Client/BTCPayServerClient.APIKeys.cs
Normal file
@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<ApiKeyData> GetCurrentAPIKeyInfo(CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<ApiKeyData>("api/v1/api-keys/current", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<ApiKeyData> CreateAPIKey(CreateApiKeyRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<ApiKeyData>("api/v1/api-keys", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<ApiKeyData> CreateAPIKey(string userId, CreateApiKeyRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<ApiKeyData>($"api/v1/users/{userId}/api-keys", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task RevokeCurrentAPIKeyInfo(CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest("api/v1/api-keys/current", null, HttpMethod.Delete, token);
|
||||
}
|
||||
|
||||
public virtual async Task RevokeAPIKey(string apikey, CancellationToken token = default)
|
||||
{
|
||||
if (apikey == null) throw new ArgumentNullException(nameof(apikey));
|
||||
await SendHttpRequest($"api/v1/api-keys/{apikey}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
public virtual async Task RevokeAPIKey(string userId, string apikey, CancellationToken token = default)
|
||||
{
|
||||
if (apikey == null) throw new ArgumentNullException(nameof(apikey));
|
||||
if (userId is null) throw new ArgumentNullException(nameof(userId));
|
||||
await SendHttpRequest($"api/v1/users/{userId}/api-keys/{apikey}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
}
|
91
BTCPayServer.Client/BTCPayServerClient.Apps.cs
Normal file
91
BTCPayServer.Client/BTCPayServerClient.Apps.cs
Normal file
@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<PointOfSaleAppData> CreatePointOfSaleApp(string storeId,
|
||||
PointOfSaleAppRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<PointOfSaleAppData>($"api/v1/stores/{storeId}/apps/pos", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<CrowdfundAppData> CreateCrowdfundApp(string storeId,
|
||||
CrowdfundAppRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<CrowdfundAppData>($"api/v1/stores/{storeId}/apps/crowdfund", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<PointOfSaleAppData> UpdatePointOfSaleApp(string appId,
|
||||
PointOfSaleAppRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<PointOfSaleAppData>($"api/v1/apps/pos/{appId}", request, HttpMethod.Put, token);
|
||||
}
|
||||
|
||||
public virtual async Task<AppBaseData> GetApp(string appId, CancellationToken token = default)
|
||||
{
|
||||
if (appId == null) throw new ArgumentNullException(nameof(appId));
|
||||
return await SendHttpRequest<AppBaseData>($"api/v1/apps/{appId}", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<AppBaseData[]> GetAllApps(string storeId, CancellationToken token = default)
|
||||
{
|
||||
if (storeId == null) throw new ArgumentNullException(nameof(storeId));
|
||||
return await SendHttpRequest<AppBaseData[]>($"api/v1/stores/{storeId}/apps", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<AppBaseData[]> GetAllApps(CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<AppBaseData[]>("api/v1/apps", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<PointOfSaleAppData> GetPosApp(string appId, CancellationToken token = default)
|
||||
{
|
||||
if (appId == null) throw new ArgumentNullException(nameof(appId));
|
||||
return await SendHttpRequest<PointOfSaleAppData>($"api/v1/apps/pos/{appId}", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<CrowdfundAppData> GetCrowdfundApp(string appId, CancellationToken token = default)
|
||||
{
|
||||
if (appId == null) throw new ArgumentNullException(nameof(appId));
|
||||
return await SendHttpRequest<CrowdfundAppData>($"api/v1/apps/crowdfund/{appId}", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<AppSalesStats> GetAppSales(string appId, int numberOfDays = 7, CancellationToken token = default)
|
||||
{
|
||||
if (appId == null) throw new ArgumentNullException(nameof(appId));
|
||||
var queryPayload = new Dictionary<string, object> { { nameof(numberOfDays), numberOfDays } };
|
||||
return await SendHttpRequest<AppSalesStats>($"api/v1/apps/{appId}/sales", queryPayload, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<List<AppItemStats>> GetAppTopItems(string appId, int offset = 0, int count = 10, CancellationToken token = default)
|
||||
{
|
||||
if (appId == null) throw new ArgumentNullException(nameof(appId));
|
||||
var queryPayload = new Dictionary<string, object> { { nameof(offset), offset }, { nameof(count), count } };
|
||||
return await SendHttpRequest<List<AppItemStats>>($"api/v1/apps/{appId}/top-items", queryPayload, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task DeleteApp(string appId, CancellationToken token = default)
|
||||
{
|
||||
if (appId == null) throw new ArgumentNullException(nameof(appId));
|
||||
await SendHttpRequest($"api/v1/apps/{appId}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
|
||||
public virtual async Task<FileData> UploadAppItemImage(string appId, string filePath, string mimeType, CancellationToken token = default)
|
||||
{
|
||||
return await UploadFileRequest<FileData>($"api/v1/apps/{appId}/image", filePath, mimeType, "file", HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task DeleteAppItemImage(string appId, string fileId, CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/apps/{appId}/image/{fileId}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
}
|
29
BTCPayServer.Client/BTCPayServerClient.Authorization.cs
Normal file
29
BTCPayServer.Client/BTCPayServerClient.Authorization.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public static Uri GenerateAuthorizeUri(Uri btcpayHost, string[] permissions, bool strict = true,
|
||||
bool selectiveStores = false, (string ApplicationIdentifier, Uri Redirect) applicationDetails = default)
|
||||
{
|
||||
var result = new UriBuilder(btcpayHost) { Path = "api-keys/authorize" };
|
||||
AppendPayloadToQuery(result,
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{"strict", strict}, {"selectiveStores", selectiveStores}, {"permissions", permissions}
|
||||
});
|
||||
|
||||
if (applicationDetails.Redirect != null)
|
||||
{
|
||||
AppendPayloadToQuery(result, new KeyValuePair<string, object>("redirect", applicationDetails.Redirect));
|
||||
if (!string.IsNullOrEmpty(applicationDetails.ApplicationIdentifier))
|
||||
{
|
||||
AppendPayloadToQuery(result, new KeyValuePair<string, object>("applicationIdentifier", applicationDetails.ApplicationIdentifier));
|
||||
}
|
||||
}
|
||||
|
||||
return result.Uri;
|
||||
}
|
||||
}
|
29
BTCPayServer.Client/BTCPayServerClient.Files.cs
Normal file
29
BTCPayServer.Client/BTCPayServerClient.Files.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<FileData[]> GetFiles(CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<FileData[]>("api/v1/files", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<FileData> GetFile(string fileId, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<FileData>($"api/v1/files/{fileId}", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<FileData> UploadFile(string filePath, string mimeType, CancellationToken token = default)
|
||||
{
|
||||
return await UploadFileRequest<FileData>("api/v1/files", filePath, mimeType, "file", HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task DeleteFile(string fileId, CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/files/{fileId}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
}
|
14
BTCPayServer.Client/BTCPayServerClient.Health.cs
Normal file
14
BTCPayServer.Client/BTCPayServerClient.Health.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<ApiHealthData> GetHealth(CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<ApiHealthData>("api/v1/health", null, HttpMethod.Get, token);
|
||||
}
|
||||
}
|
107
BTCPayServer.Client/BTCPayServerClient.Invoices.cs
Normal file
107
BTCPayServer.Client/BTCPayServerClient.Invoices.cs
Normal file
@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
using NBitcoin;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<IEnumerable<InvoiceData>> GetInvoices(string storeId, string[] orderId = null,
|
||||
InvoiceStatus[] status = null,
|
||||
DateTimeOffset? startDate = null,
|
||||
DateTimeOffset? endDate = null,
|
||||
string textSearch = null,
|
||||
bool includeArchived = false,
|
||||
int? skip = null,
|
||||
int? take = null,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = new Dictionary<string, object> { { nameof(includeArchived), includeArchived } };
|
||||
if (startDate is { } s)
|
||||
queryPayload.Add(nameof(startDate), Utils.DateTimeToUnixTime(s));
|
||||
if (endDate is { } e)
|
||||
queryPayload.Add(nameof(endDate), Utils.DateTimeToUnixTime(e));
|
||||
if (orderId != null)
|
||||
queryPayload.Add(nameof(orderId), orderId);
|
||||
if (textSearch != null)
|
||||
queryPayload.Add(nameof(textSearch), textSearch);
|
||||
if (status != null)
|
||||
queryPayload.Add(nameof(status), status.Select(s => s.ToString().ToLower()).ToArray());
|
||||
if (skip != null)
|
||||
queryPayload.Add(nameof(skip), skip);
|
||||
if (take != null)
|
||||
queryPayload.Add(nameof(take), take);
|
||||
|
||||
return await SendHttpRequest<IEnumerable<InvoiceData>>($"api/v1/stores/{storeId}/invoices", queryPayload, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<InvoiceData> GetInvoice(string storeId, string invoiceId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<InvoiceData>($"api/v1/stores/{storeId}/invoices/{invoiceId}", null, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task<InvoicePaymentMethodDataModel[]> GetInvoicePaymentMethods(string storeId, string invoiceId,
|
||||
bool onlyAccountedPayments = true, bool includeSensitive = false,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = new Dictionary<string, object>
|
||||
{
|
||||
{ nameof(onlyAccountedPayments), onlyAccountedPayments },
|
||||
{ nameof(includeSensitive), includeSensitive }
|
||||
};
|
||||
return await SendHttpRequest<InvoicePaymentMethodDataModel[]>($"api/v1/stores/{storeId}/invoices/{invoiceId}/payment-methods", queryPayload, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task ArchiveInvoice(string storeId, string invoiceId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
|
||||
public virtual async Task<InvoiceData> CreateInvoice(string storeId,
|
||||
CreateInvoiceRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<InvoiceData>($"api/v1/stores/{storeId}/invoices", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<InvoiceData> UpdateInvoice(string storeId, string invoiceId,
|
||||
UpdateInvoiceRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<InvoiceData>($"api/v1/stores/{storeId}/invoices/{invoiceId}", request, HttpMethod.Put, token);
|
||||
}
|
||||
|
||||
public virtual async Task<InvoiceData> MarkInvoiceStatus(string storeId, string invoiceId,
|
||||
MarkInvoiceStatusRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
if (request.Status != InvoiceStatus.Settled && request.Status != InvoiceStatus.Invalid) throw new ArgumentOutOfRangeException(nameof(request.Status), "Status can only be Invalid or Complete");
|
||||
return await SendHttpRequest<InvoiceData>($"api/v1/stores/{storeId}/invoices/{invoiceId}/status", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<InvoiceData> UnarchiveInvoice(string storeId, string invoiceId, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<InvoiceData>($"api/v1/stores/{storeId}/invoices/{invoiceId}/unarchive", null, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task ActivateInvoicePaymentMethod(string storeId, string invoiceId, string paymentMethod, CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/invoices/{invoiceId}/payment-methods/{paymentMethod}/activate", null, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<PullPaymentData> RefundInvoice(
|
||||
string storeId,
|
||||
string invoiceId,
|
||||
RefundInvoiceRequest request,
|
||||
CancellationToken token = default
|
||||
)
|
||||
{
|
||||
return await SendHttpRequest<PullPaymentData>($"api/v1/stores/{storeId}/invoices/{invoiceId}/refund", request, HttpMethod.Post, token);
|
||||
}
|
||||
}
|
112
BTCPayServer.Client/BTCPayServerClient.Lightning.Internal.cs
Normal file
112
BTCPayServer.Client/BTCPayServerClient.Lightning.Internal.cs
Normal file
@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<LightningNodeInformationData> GetLightningNodeInfo(string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<LightningNodeInformationData>($"api/v1/server/lightning/{cryptoCode}/info", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<LightningNodeBalanceData>($"api/v1/server/lightning/{cryptoCode}/balance", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<HistogramData> GetLightningNodeHistogram(string cryptoCode, HistogramType? type = null,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = type == null ? null : new Dictionary<string, object> { { "type", type.ToString() } };
|
||||
return await SendHttpRequest<HistogramData>($"api/v1/server/lightning/{cryptoCode}/histogram", queryPayload, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task ConnectToLightningNode(string cryptoCode, ConnectToNodeRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
await SendHttpRequest($"api/v1/server/lightning/{cryptoCode}/connect", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<LightningChannelData>> GetLightningNodeChannels(string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<IEnumerable<LightningChannelData>>($"api/v1/server/lightning/{cryptoCode}/channels", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task OpenLightningChannel(string cryptoCode, OpenLightningChannelRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/server/lightning/{cryptoCode}/channels", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<string> GetLightningDepositAddress(string cryptoCode, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<string>($"api/v1/server/lightning/{cryptoCode}/address", null, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningPaymentData> PayLightningInvoice(string cryptoCode, PayLightningInvoiceRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<LightningPaymentData>($"api/v1/server/lightning/{cryptoCode}/invoices/pay", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningPaymentData> GetLightningPayment(string cryptoCode,
|
||||
string paymentHash, CancellationToken token = default)
|
||||
{
|
||||
if (paymentHash == null) throw new ArgumentNullException(nameof(paymentHash));
|
||||
return await SendHttpRequest<LightningPaymentData>($"api/v1/server/lightning/{cryptoCode}/payments/{paymentHash}", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningInvoiceData> GetLightningInvoice(string cryptoCode,
|
||||
string invoiceId, CancellationToken token = default)
|
||||
{
|
||||
if (invoiceId == null) throw new ArgumentNullException(nameof(invoiceId));
|
||||
return await SendHttpRequest<LightningInvoiceData>($"api/v1/server/lightning/{cryptoCode}/invoices/{invoiceId}", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningInvoiceData[]> GetLightningInvoices(string cryptoCode,
|
||||
bool? pendingOnly = null, long? offsetIndex = null, CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = new Dictionary<string, object>();
|
||||
if (pendingOnly is bool v)
|
||||
{
|
||||
queryPayload.Add("pendingOnly", v.ToString());
|
||||
}
|
||||
if (offsetIndex is > 0)
|
||||
{
|
||||
queryPayload.Add("offsetIndex", offsetIndex);
|
||||
}
|
||||
return await SendHttpRequest<LightningInvoiceData[]>($"api/v1/server/lightning/{cryptoCode}/invoices", queryPayload, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningPaymentData[]> GetLightningPayments(string cryptoCode,
|
||||
bool? includePending = null, long? offsetIndex = null, CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = new Dictionary<string, object>();
|
||||
if (includePending is bool v)
|
||||
{
|
||||
queryPayload.Add("includePending", v.ToString());
|
||||
}
|
||||
if (offsetIndex is > 0)
|
||||
{
|
||||
queryPayload.Add("offsetIndex", offsetIndex);
|
||||
}
|
||||
return await SendHttpRequest<LightningPaymentData[]>($"api/v1/server/lightning/{cryptoCode}/payments", queryPayload, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningInvoiceData> CreateLightningInvoice(string cryptoCode, CreateLightningInvoiceRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<LightningInvoiceData>($"api/v1/server/lightning/{cryptoCode}/invoices", request, HttpMethod.Post, token);
|
||||
}
|
||||
}
|
113
BTCPayServer.Client/BTCPayServerClient.Lightning.Store.cs
Normal file
113
BTCPayServer.Client/BTCPayServerClient.Lightning.Store.cs
Normal file
@ -0,0 +1,113 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<LightningNodeInformationData> GetLightningNodeInfo(string storeId, string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<LightningNodeInformationData>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/info", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningNodeBalanceData> GetLightningNodeBalance(string storeId, string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<LightningNodeBalanceData>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/balance", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<HistogramData> GetLightningNodeHistogram(string storeId, string cryptoCode, HistogramType? type = null,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = type == null ? null : new Dictionary<string, object> { { "type", type.ToString() } };
|
||||
return await SendHttpRequest<HistogramData>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/histogram", queryPayload, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task ConnectToLightningNode(string storeId, string cryptoCode, ConnectToNodeRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/connect", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<LightningChannelData>> GetLightningNodeChannels(string storeId, string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<IEnumerable<LightningChannelData>>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/channels", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task OpenLightningChannel(string storeId, string cryptoCode, OpenLightningChannelRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/lightning/{cryptoCode}/channels", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<string> GetLightningDepositAddress(string storeId, string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<string>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/address", null, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningPaymentData> PayLightningInvoice(string storeId, string cryptoCode, PayLightningInvoiceRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<LightningPaymentData>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices/pay", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningPaymentData> GetLightningPayment(string storeId, string cryptoCode,
|
||||
string paymentHash, CancellationToken token = default)
|
||||
{
|
||||
if (paymentHash == null) throw new ArgumentNullException(nameof(paymentHash));
|
||||
return await SendHttpRequest<LightningPaymentData>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/payments/{paymentHash}", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningInvoiceData> GetLightningInvoice(string storeId, string cryptoCode,
|
||||
string invoiceId, CancellationToken token = default)
|
||||
{
|
||||
if (invoiceId == null) throw new ArgumentNullException(nameof(invoiceId));
|
||||
return await SendHttpRequest<LightningInvoiceData>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices/{invoiceId}", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningInvoiceData[]> GetLightningInvoices(string storeId, string cryptoCode,
|
||||
bool? pendingOnly = null, long? offsetIndex = null, CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = new Dictionary<string, object>();
|
||||
if (pendingOnly is bool v)
|
||||
{
|
||||
queryPayload.Add("pendingOnly", v.ToString());
|
||||
}
|
||||
if (offsetIndex is > 0)
|
||||
{
|
||||
queryPayload.Add("offsetIndex", offsetIndex);
|
||||
}
|
||||
return await SendHttpRequest<LightningInvoiceData[]>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices", queryPayload, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningPaymentData[]> GetLightningPayments(string storeId, string cryptoCode,
|
||||
bool? includePending = null, long? offsetIndex = null, CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = new Dictionary<string, object>();
|
||||
if (includePending is bool v)
|
||||
{
|
||||
queryPayload.Add("includePending", v.ToString());
|
||||
}
|
||||
if (offsetIndex is > 0)
|
||||
{
|
||||
queryPayload.Add("offsetIndex", offsetIndex);
|
||||
}
|
||||
return await SendHttpRequest<LightningPaymentData[]>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/payments", queryPayload, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningInvoiceData> CreateLightningInvoice(string storeId, string cryptoCode,
|
||||
CreateLightningInvoiceRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<LightningInvoiceData>($"api/v1/stores/{storeId}/lightning/{cryptoCode}/invoices", request, HttpMethod.Post, token);
|
||||
}
|
||||
}
|
34
BTCPayServer.Client/BTCPayServerClient.LightningAddresses.cs
Normal file
34
BTCPayServer.Client/BTCPayServerClient.LightningAddresses.cs
Normal file
@ -0,0 +1,34 @@
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<LightningAddressData[]> GetStoreLightningAddresses(string storeId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<LightningAddressData[]>($"api/v1/stores/{storeId}/lightning-addresses", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningAddressData> GetStoreLightningAddress(string storeId, string username,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<LightningAddressData>($"api/v1/stores/{storeId}/lightning-addresses/{username}", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task RemoveStoreLightningAddress(string storeId, string username,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/lightning-addresses/{username}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningAddressData> AddOrUpdateStoreLightningAddress(string storeId,
|
||||
string username, LightningAddressData data,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<LightningAddressData>($"api/v1/stores/{storeId}/lightning-addresses/{username}", data, HttpMethod.Post, token);
|
||||
}
|
||||
}
|
19
BTCPayServer.Client/BTCPayServerClient.Misc.cs
Normal file
19
BTCPayServer.Client/BTCPayServerClient.Misc.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<PermissionMetadata[]> GetPermissionMetadata(CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<PermissionMetadata[]>("misc/permissions", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<Language[]> GetAvailableLanguages(CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<Language[]>("misc/lang", null, HttpMethod.Get, token);
|
||||
}
|
||||
}
|
52
BTCPayServer.Client/BTCPayServerClient.Notifications.cs
Normal file
52
BTCPayServer.Client/BTCPayServerClient.Notifications.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<IEnumerable<NotificationData>> GetNotifications(bool? seen = null, int? skip = null,
|
||||
int? take = null, string[] storeId = null, CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = new Dictionary<string, object>();
|
||||
if (seen != null)
|
||||
queryPayload.Add(nameof(seen), seen);
|
||||
if (skip != null)
|
||||
queryPayload.Add(nameof(skip), skip);
|
||||
if (take != null)
|
||||
queryPayload.Add(nameof(take), take);
|
||||
if (storeId != null)
|
||||
queryPayload.Add(nameof(storeId), storeId);
|
||||
return await SendHttpRequest<IEnumerable<NotificationData>>("api/v1/users/me/notifications", queryPayload, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<NotificationData> GetNotification(string notificationId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<NotificationData>($"api/v1/users/me/notifications/{notificationId}", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<NotificationData> UpdateNotification(string notificationId, bool? seen,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<NotificationData>($"api/v1/users/me/notifications/{notificationId}", new UpdateNotification { Seen = seen }, HttpMethod.Put, token);
|
||||
}
|
||||
|
||||
public virtual async Task<NotificationSettingsData> GetNotificationSettings(CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<NotificationSettingsData>("api/v1/users/me/notification-settings", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<NotificationSettingsData> UpdateNotificationSettings(UpdateNotificationSettingsRequest request, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<NotificationSettingsData>("api/v1/users/me/notification-settings", request, HttpMethod.Put, token);
|
||||
}
|
||||
|
||||
public virtual async Task RemoveNotification(string notificationId, CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/users/me/notifications/{notificationId}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<OnChainPaymentMethodPreviewResultData>
|
||||
PreviewProposedStoreOnChainPaymentMethodAddresses(
|
||||
string storeId, string paymentMethodId, string derivationScheme, int offset = 0,
|
||||
int amount = 10,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<UpdatePaymentMethodRequest, OnChainPaymentMethodPreviewResultData>($"api/v1/stores/{storeId}/payment-methods/{paymentMethodId}/wallet/preview",
|
||||
new Dictionary<string, object> { { "offset", offset }, { "amount", amount } },
|
||||
new UpdatePaymentMethodRequest { Config = JValue.CreateString(derivationScheme) },
|
||||
HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<OnChainPaymentMethodPreviewResultData> PreviewStoreOnChainPaymentMethodAddresses(
|
||||
string storeId, string paymentMethodId, int offset = 0, int amount = 10,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<OnChainPaymentMethodPreviewResultData>($"api/v1/stores/{storeId}/payment-methods/{paymentMethodId}/wallet/preview",
|
||||
new Dictionary<string, object> { { "offset", offset }, { "amount", amount } }, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<GenerateOnChainWalletResponse> GenerateOnChainWallet(string storeId,
|
||||
string paymentMethodId, GenerateOnChainWalletRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<GenerateOnChainWalletResponse>($"api/v1/stores/{storeId}/payment-methods/{paymentMethodId}/wallet/generate", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<OnChainWalletObjectData> GetOnChainWalletObject(string storeId, string cryptoCode, OnChainWalletObjectId objectId, bool? includeNeighbourData = null, CancellationToken token = default)
|
||||
{
|
||||
var parameters = new Dictionary<string, object>();
|
||||
if (includeNeighbourData is bool v)
|
||||
parameters.Add("includeNeighbourData", v);
|
||||
try
|
||||
{
|
||||
return await SendHttpRequest<OnChainWalletObjectData>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/objects/{objectId.Type}/{objectId.Id}", parameters, HttpMethod.Get, token);
|
||||
}
|
||||
catch (GreenfieldAPIException err) when (err.APIError.Code == "wallet-object-not-found")
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public virtual async Task<OnChainWalletObjectData[]> GetOnChainWalletObjects(string storeId, string cryptoCode, GetWalletObjectsRequest query = null, CancellationToken token = default)
|
||||
{
|
||||
Dictionary<string, object> parameters = new Dictionary<string, object>();
|
||||
if (query?.Type is string s)
|
||||
parameters.Add("type", s);
|
||||
if (query?.Ids is string[] ids)
|
||||
parameters.Add("ids", ids);
|
||||
if (query?.IncludeNeighbourData is bool v)
|
||||
parameters.Add("includeNeighbourData", v);
|
||||
return await SendHttpRequest<OnChainWalletObjectData[]>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/objects", parameters, HttpMethod.Get, token);
|
||||
}
|
||||
public virtual async Task RemoveOnChainWalletObject(string storeId, string cryptoCode, OnChainWalletObjectId objectId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/objects/{objectId.Type}/{objectId.Id}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
public virtual async Task<OnChainWalletObjectData> AddOrUpdateOnChainWalletObject(string storeId, string cryptoCode, AddOnChainWalletObjectRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<OnChainWalletObjectData>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/objects", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task AddOrUpdateOnChainWalletLink(string storeId, string cryptoCode,
|
||||
OnChainWalletObjectId objectId,
|
||||
AddOnChainWalletObjectLinkRequest request = null,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/objects/{objectId.Type}/{objectId.Id}/links", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task RemoveOnChainWalletLinks(string storeId, string cryptoCode,
|
||||
OnChainWalletObjectId objectId,
|
||||
OnChainWalletObjectId link,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/objects/{objectId.Type}/{objectId.Id}/links/{link.Type}/{link.Id}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
}
|
119
BTCPayServer.Client/BTCPayServerClient.OnChainWallet.cs
Normal file
119
BTCPayServer.Client/BTCPayServerClient.OnChainWallet.cs
Normal file
@ -0,0 +1,119 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
using NBitcoin;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<OnChainWalletOverviewData> ShowOnChainWalletOverview(string storeId, string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<OnChainWalletOverviewData>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<HistogramData> GetOnChainWalletHistogram(string storeId, string cryptoCode, HistogramType? type = null,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = type == null ? null : new Dictionary<string, object> { { "type", type.ToString() } };
|
||||
return await SendHttpRequest<HistogramData>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/histogram", queryPayload, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<OnChainWalletFeeRateData> GetOnChainFeeRate(string storeId, string cryptoCode, int? blockTarget = null,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var queryParams = new Dictionary<string, object>();
|
||||
if (blockTarget != null)
|
||||
{
|
||||
queryParams.Add("blockTarget", blockTarget);
|
||||
}
|
||||
return await SendHttpRequest<OnChainWalletFeeRateData>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/feerate", queryParams, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<OnChainWalletAddressData> GetOnChainWalletReceiveAddress(string storeId, string cryptoCode, bool forceGenerate = false,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<OnChainWalletAddressData>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/address", new Dictionary<string, object>
|
||||
{
|
||||
{"forceGenerate", forceGenerate}
|
||||
}, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task UnReserveOnChainWalletReceiveAddress(string storeId, string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/address", null, HttpMethod.Delete, token);
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<OnChainWalletTransactionData>> ShowOnChainWalletTransactions(
|
||||
string storeId, string cryptoCode, TransactionStatus[] statusFilter = null, string labelFilter = null, int skip = 0,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var query = new Dictionary<string, object>();
|
||||
if (statusFilter?.Any() is true)
|
||||
{
|
||||
query.Add(nameof(statusFilter), statusFilter);
|
||||
}
|
||||
if (labelFilter != null)
|
||||
{
|
||||
query.Add(nameof(labelFilter), labelFilter);
|
||||
}
|
||||
if (skip != 0)
|
||||
{
|
||||
query.Add(nameof(skip), skip);
|
||||
}
|
||||
return await SendHttpRequest<IEnumerable<OnChainWalletTransactionData>>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/transactions", query, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<OnChainWalletTransactionData> GetOnChainWalletTransaction(
|
||||
string storeId, string cryptoCode, string transactionId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<OnChainWalletTransactionData>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/transactions/{transactionId}", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<OnChainWalletTransactionData> PatchOnChainWalletTransaction(
|
||||
string storeId, string cryptoCode, string transactionId,
|
||||
PatchOnChainTransactionRequest request,
|
||||
bool force = false, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<PatchOnChainTransactionRequest, OnChainWalletTransactionData>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/transactions/{transactionId}",
|
||||
new Dictionary<string, object> { {"force", force} }, request, HttpMethod.Patch, token);
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<OnChainWalletUTXOData>> GetOnChainWalletUTXOs(string storeId,
|
||||
string cryptoCode,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<IEnumerable<OnChainWalletUTXOData>>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/utxos", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<OnChainWalletTransactionData> CreateOnChainTransaction(string storeId,
|
||||
string cryptoCode, CreateOnChainTransactionRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (!request.ProceedWithBroadcast)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(request.ProceedWithBroadcast),
|
||||
"Please use CreateOnChainTransactionButDoNotBroadcast when wanting to only create the transaction");
|
||||
}
|
||||
return await SendHttpRequest<OnChainWalletTransactionData>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/transactions", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<Transaction> CreateOnChainTransactionButDoNotBroadcast(string storeId,
|
||||
string cryptoCode, CreateOnChainTransactionRequest request, Network network,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (request.ProceedWithBroadcast)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(request.ProceedWithBroadcast),
|
||||
"Please use CreateOnChainTransaction when wanting to also broadcast the transaction");
|
||||
}
|
||||
return Transaction.Parse(await SendHttpRequest<string>($"api/v1/stores/{storeId}/payment-methods/{cryptoCode}-CHAIN/wallet/transactions", request, HttpMethod.Post, token), network);
|
||||
}
|
||||
}
|
53
BTCPayServer.Client/BTCPayServerClient.PaymentRequests.cs
Normal file
53
BTCPayServer.Client/BTCPayServerClient.PaymentRequests.cs
Normal file
@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<IEnumerable<PaymentRequestData>> GetPaymentRequests(string storeId,
|
||||
bool includeArchived = false,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<IEnumerable<PaymentRequestData>>($"api/v1/stores/{storeId}/payment-requests",
|
||||
new Dictionary<string, object> { { nameof(includeArchived), includeArchived } }, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<PaymentRequestData> GetPaymentRequest(string storeId, string paymentRequestId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<PaymentRequestData>($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task ArchivePaymentRequest(string storeId, string paymentRequestId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
|
||||
public virtual async Task<Client.Models.InvoiceData> PayPaymentRequest(string storeId, string paymentRequestId, PayPaymentRequestRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
if (storeId is null) throw new ArgumentNullException(nameof(storeId));
|
||||
if (paymentRequestId is null) throw new ArgumentNullException(nameof(paymentRequestId));
|
||||
return await SendHttpRequest<InvoiceData>($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}/pay", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<PaymentRequestData> CreatePaymentRequest(string storeId,
|
||||
CreatePaymentRequestRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<PaymentRequestData>($"api/v1/stores/{storeId}/payment-requests", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<PaymentRequestData> UpdatePaymentRequest(string storeId, string paymentRequestId,
|
||||
UpdatePaymentRequestRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<PaymentRequestData>($"api/v1/stores/{storeId}/payment-requests/{paymentRequestId}", request, HttpMethod.Put, token);
|
||||
}
|
||||
}
|
16
BTCPayServer.Client/BTCPayServerClient.PayoutProcessors.cs
Normal file
16
BTCPayServer.Client/BTCPayServerClient.PayoutProcessors.cs
Normal file
@ -0,0 +1,16 @@
|
||||
#nullable enable
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<IEnumerable<PayoutProcessorData>> GetPayoutProcessors(CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<IEnumerable<PayoutProcessorData>>("api/v1/payout-processors", null, HttpMethod.Get, token);
|
||||
}
|
||||
}
|
94
BTCPayServer.Client/BTCPayServerClient.PullPayments.cs
Normal file
94
BTCPayServer.Client/BTCPayServerClient.PullPayments.cs
Normal file
@ -0,0 +1,94 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<PullPaymentData> CreatePullPayment(string storeId, CreatePullPaymentRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await SendHttpRequest<PullPaymentData>($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/pull-payments", request, HttpMethod.Post, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task<PullPaymentData> GetPullPayment(string pullPaymentId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await SendHttpRequest<PullPaymentData>($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}", null, HttpMethod.Get, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task<RegisterBoltcardResponse> RegisterBoltcard(string pullPaymentId, RegisterBoltcardRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await SendHttpRequest<RegisterBoltcardResponse>($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/boltcards", request, HttpMethod.Post, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task<PullPaymentData[]> GetPullPayments(string storeId, bool includeArchived = false, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var query = new Dictionary<string, object> { { "includeArchived", includeArchived } };
|
||||
return await SendHttpRequest<PullPaymentData[]>($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/pull-payments", query, HttpMethod.Get, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task ArchivePullPayment(string storeId, string pullPaymentId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}", null, HttpMethod.Delete, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task<PayoutData[]> GetPayouts(string pullPaymentId, bool includeCancelled = false, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var query = new Dictionary<string, object> { { "includeCancelled", includeCancelled } };
|
||||
return await SendHttpRequest<PayoutData[]>($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts", query, HttpMethod.Get, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task<PayoutData[]> GetStorePayouts(string storeId, bool includeCancelled = false, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var query = new Dictionary<string, object> { { "includeCancelled", includeCancelled } };
|
||||
return await SendHttpRequest<PayoutData[]>($"api/v1/stores/{storeId}/payouts", queryPayload: query, method: HttpMethod.Get, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task<PayoutData> CreatePayout(string pullPaymentId, CreatePayoutRequest payoutRequest, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await SendHttpRequest<PayoutData>($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts", bodyPayload: payoutRequest, HttpMethod.Post, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task<PayoutData> GetPullPaymentPayout(string pullPaymentId, string payoutId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await SendHttpRequest<PayoutData>($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/payouts/{payoutId}", null, HttpMethod.Get, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task<PayoutData> GetStorePayout(string storeId, string payoutId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await SendHttpRequest<PayoutData>($"api/v1/stores/{storeId}/payouts/{payoutId}", null, HttpMethod.Get, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task<PayoutData> CreatePayout(string storeId, CreatePayoutThroughStoreRequest payoutRequest, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await SendHttpRequest<PayoutData>($"api/v1/stores/{storeId}/payouts", bodyPayload: payoutRequest, method: HttpMethod.Post, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task CancelPayout(string storeId, string payoutId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}", null, HttpMethod.Delete, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task<PayoutData> ApprovePayout(string storeId, string payoutId, ApprovePayoutRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await SendHttpRequest<PayoutData>($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}", request, HttpMethod.Post, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task MarkPayoutPaid(string storeId, string payoutId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}/mark-paid", null, HttpMethod.Post, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task MarkPayout(string storeId, string payoutId, MarkPayoutRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{HttpUtility.UrlEncode(storeId)}/payouts/{HttpUtility.UrlEncode(payoutId)}/mark", request, HttpMethod.Post, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task<PullPaymentLNURL> GetPullPaymentLNURL(string pullPaymentId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await SendHttpRequest<PullPaymentLNURL>($"api/v1/pull-payments/{HttpUtility.UrlEncode(pullPaymentId)}/lnurl", null, HttpMethod.Get, cancellationToken);
|
||||
}
|
||||
}
|
20
BTCPayServer.Client/BTCPayServerClient.ServerInfo.cs
Normal file
20
BTCPayServer.Client/BTCPayServerClient.ServerInfo.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<ServerInfoData> GetServerInfo(CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<ServerInfoData>("api/v1/server/info", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<List<RoleData>> GetServerRoles(CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<List<RoleData>>("api/v1/server/roles", null, HttpMethod.Get, token);
|
||||
}
|
||||
}
|
24
BTCPayServer.Client/BTCPayServerClient.StoreEmail.cs
Normal file
24
BTCPayServer.Client/BTCPayServerClient.StoreEmail.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<EmailSettingsData> GetStoreEmailSettings(string storeId, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<EmailSettingsData>($"api/v1/stores/{storeId}/email", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<EmailSettingsData> UpdateStoreEmailSettings(string storeId, EmailSettingsData request, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<EmailSettingsData>($"api/v1/stores/{storeId}/email", request, method: HttpMethod.Put, token);
|
||||
}
|
||||
|
||||
public virtual async Task SendEmail(string storeId, SendEmailRequest request, CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/email/send", request, HttpMethod.Post, token);
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<GenericPaymentMethodData> UpdateStorePaymentMethod(string storeId, string paymentMethodId, UpdatePaymentMethodRequest request, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<GenericPaymentMethodData>($"api/v1/stores/{storeId}/payment-methods/{paymentMethodId}", request, HttpMethod.Put, token);
|
||||
}
|
||||
|
||||
public virtual async Task RemoveStorePaymentMethod(string storeId, string paymentMethodId)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/payment-methods/{paymentMethodId}", null, HttpMethod.Delete, CancellationToken.None);
|
||||
}
|
||||
|
||||
public virtual async Task<GenericPaymentMethodData> GetStorePaymentMethod(string storeId, string paymentMethodId, bool? includeConfig = null, CancellationToken token = default)
|
||||
{
|
||||
var query = new Dictionary<string, object>();
|
||||
if (includeConfig != null)
|
||||
{
|
||||
query.Add(nameof(includeConfig), includeConfig);
|
||||
}
|
||||
return await SendHttpRequest<GenericPaymentMethodData>($"api/v1/stores/{storeId}/payment-methods/{paymentMethodId}", query, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<GenericPaymentMethodData[]> GetStorePaymentMethods(string storeId, bool? onlyEnabled = null, bool? includeConfig = null, CancellationToken token = default)
|
||||
{
|
||||
var query = new Dictionary<string, object>();
|
||||
if (onlyEnabled != null)
|
||||
{
|
||||
query.Add(nameof(onlyEnabled), onlyEnabled);
|
||||
}
|
||||
if (includeConfig != null)
|
||||
{
|
||||
query.Add(nameof(includeConfig), includeConfig);
|
||||
}
|
||||
|
||||
return await SendHttpRequest<GenericPaymentMethodData[]>($"api/v1/stores/{storeId}/payment-methods", query, HttpMethod.Get, token);
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
#nullable enable
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<IEnumerable<PayoutProcessorData>> GetPayoutProcessors(string storeId, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<IEnumerable<PayoutProcessorData>>($"api/v1/stores/{storeId}/payout-processors", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task RemovePayoutProcessor(string storeId, string processor, string paymentMethod, CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/payout-processors/{processor}/{paymentMethod}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<LightningAutomatedPayoutSettings>> GetStoreLightningAutomatedPayoutProcessors(string storeId, string? payoutMethodId = null, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<IEnumerable<LightningAutomatedPayoutSettings>>($"api/v1/stores/{storeId}/payout-processors/LightningAutomatedPayoutSenderFactory{(payoutMethodId is null ? string.Empty : $"/{payoutMethodId}")}", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningAutomatedPayoutSettings> UpdateStoreLightningAutomatedPayoutProcessors(string storeId, string payoutMethodId, LightningAutomatedPayoutSettings request, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<LightningAutomatedPayoutSettings>($"api/v1/stores/{storeId}/payout-processors/LightningAutomatedPayoutSenderFactory/{payoutMethodId}", request, HttpMethod.Put, token);
|
||||
}
|
||||
|
||||
public virtual async Task<OnChainAutomatedPayoutSettings> UpdateStoreOnChainAutomatedPayoutProcessors(string storeId, string paymentMethod, OnChainAutomatedPayoutSettings request, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<OnChainAutomatedPayoutSettings>($"api/v1/stores/{storeId}/payout-processors/OnChainAutomatedPayoutSenderFactory/{paymentMethod}", request, HttpMethod.Put, token);
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<OnChainAutomatedPayoutSettings>> GetStoreOnChainAutomatedPayoutProcessors(string storeId, string? paymentMethod = null, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<IEnumerable<OnChainAutomatedPayoutSettings>>($"api/v1/stores/{storeId}/payout-processors/OnChainAutomatedPayoutSenderFactory{(paymentMethod is null ? string.Empty : $"/{paymentMethod}")}", null, HttpMethod.Get, token);
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<StoreRateConfiguration> GetStoreRateConfiguration(string storeId, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<StoreRateConfiguration>($"api/v1/stores/{storeId}/rates/configuration", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<List<RateSource>> GetRateSources(CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<List<RateSource>>("misc/rate-sources", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<StoreRateConfiguration> UpdateStoreRateConfiguration(string storeId, StoreRateConfiguration request, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<StoreRateConfiguration>($"api/v1/stores/{storeId}/rates/configuration", request, HttpMethod.Put, token);
|
||||
}
|
||||
|
||||
public virtual async Task<List<StoreRateResult>> PreviewUpdateStoreRateConfiguration(string storeId, StoreRateConfiguration request, string[] currencyPair = null, CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = currencyPair == null ? null : new Dictionary<string, object> { { "currencyPair", currencyPair } };
|
||||
return await SendHttpRequest<StoreRateConfiguration, List<StoreRateResult>>($"api/v1/stores/{storeId}/rates/configuration/preview", queryPayload, request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<List<StoreRateResult>> GetStoreRates(string storeId, string[] currencyPair = null, CancellationToken token = default)
|
||||
{
|
||||
var queryPayload = currencyPair == null ? null : new Dictionary<string, object> { { "currencyPair", currencyPair } };
|
||||
return await SendHttpRequest<List<StoreRateResult>>($"api/v1/stores/{storeId}/rates", queryPayload, HttpMethod.Get, token);
|
||||
}
|
||||
}
|
38
BTCPayServer.Client/BTCPayServerClient.StoreUsers.cs
Normal file
38
BTCPayServer.Client/BTCPayServerClient.StoreUsers.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<List<RoleData>> GetStoreRoles(string storeId, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<List<RoleData>>($"api/v1/stores/{storeId}/roles", null, HttpMethod.Get,token);
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<StoreUserData>> GetStoreUsers(string storeId, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<IEnumerable<StoreUserData>>($"api/v1/stores/{storeId}/users", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task RemoveStoreUser(string storeId, string userId, CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/users/{userId}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
|
||||
public virtual async Task AddStoreUser(string storeId, StoreUserData request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
await SendHttpRequest<StoreUserData>($"api/v1/stores/{storeId}/users", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task UpdateStoreUser(string storeId, string userId, StoreUserData request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
await SendHttpRequest<StoreUserData>($"api/v1/stores/{storeId}/users/{userId}", request, HttpMethod.Put, token);
|
||||
}
|
||||
}
|
49
BTCPayServer.Client/BTCPayServerClient.Stores.cs
Normal file
49
BTCPayServer.Client/BTCPayServerClient.Stores.cs
Normal file
@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
|
||||
namespace BTCPayServer.Client;
|
||||
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<IEnumerable<StoreData>> GetStores(CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<IEnumerable<StoreData>>("api/v1/stores", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task<StoreData> GetStore(string storeId, CancellationToken token = default)
|
||||
{
|
||||
return await SendHttpRequest<StoreData>($"api/v1/stores/{storeId}", null, HttpMethod.Get, token);
|
||||
}
|
||||
|
||||
public virtual async Task RemoveStore(string storeId, CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}", null, HttpMethod.Delete, token);
|
||||
}
|
||||
|
||||
public virtual async Task<StoreData> CreateStore(CreateStoreRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return await SendHttpRequest<StoreData>("api/v1/stores", request, HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task<StoreData> UpdateStore(string storeId, UpdateStoreRequest request, CancellationToken token = default)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
if (storeId == null) throw new ArgumentNullException(nameof(storeId));
|
||||
return await SendHttpRequest<StoreData>($"api/v1/stores/{storeId}", request, HttpMethod.Put, token);
|
||||
}
|
||||
|
||||
public virtual async Task<StoreData> UploadStoreLogo(string storeId, string filePath, string mimeType, CancellationToken token = default)
|
||||
{
|
||||
return await UploadFileRequest<StoreData>($"api/v1/stores/{storeId}/logo", filePath, mimeType, "file", HttpMethod.Post, token);
|
||||
}
|
||||
|
||||
public virtual async Task DeleteStoreLogo(string storeId, CancellationToken token = default)
|
||||
{
|
||||
await SendHttpRequest($"api/v1/stores/{storeId}/logo", null, HttpMethod.Delete, token);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user