Compare commits
4019 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
57b95d72e5 | ||
![]() |
ef4e4e4c46 | ||
![]() |
761e7557db | ||
![]() |
fc19854d0f | ||
![]() |
cdc64bad98 | ||
![]() |
45eb284108 | ||
![]() |
8c30a70232 | ||
![]() |
ccdd6e624e | ||
![]() |
a27f0473eb | ||
![]() |
8714c472ec | ||
![]() |
670a032207 | ||
![]() |
0ba0c79d4b | ||
![]() |
4983ccc039 | ||
![]() |
18ccdaa133 | ||
![]() |
4e1c24849f | ||
![]() |
b346ee054f | ||
![]() |
e9f29fb8af | ||
![]() |
83736b0315 | ||
![]() |
688961c500 | ||
![]() |
3a92cd82f4 | ||
![]() |
be3ad2515e | ||
![]() |
dbeaff56f6 | ||
![]() |
e6bbab6262 | ||
![]() |
1f76bff469 | ||
![]() |
f2fd8d4475 | ||
![]() |
2bdb2ea31f | ||
![]() |
34c6043102 | ||
![]() |
538b0b97d4 | ||
![]() |
31e804a3f5 | ||
![]() |
bb2b6a8919 | ||
![]() |
a57c2a18c7 | ||
![]() |
4df1501875 | ||
![]() |
de18e6ad57 | ||
![]() |
19e797749e | ||
![]() |
0325af37dd | ||
![]() |
86b9372a5d | ||
![]() |
9878be5cf1 | ||
![]() |
b453cc2955 | ||
![]() |
6b878406f2 | ||
![]() |
79b18db7f6 | ||
![]() |
474bbe18e3 | ||
![]() |
bbfc1c3b9c | ||
![]() |
e66baea3ac | ||
![]() |
37425fa896 | ||
![]() |
2b14d3ba29 | ||
![]() |
2b1a9560cc | ||
![]() |
484d24b4b3 | ||
![]() |
a39f5154cf | ||
![]() |
02b3d610bc | ||
![]() |
8fc5106f41 | ||
![]() |
4b77781155 | ||
![]() |
101919e912 | ||
![]() |
01ae52dd77 | ||
![]() |
54e177bba1 | ||
![]() |
600aa3ad27 | ||
![]() |
28b71732a6 | ||
![]() |
223cf1c3ba | ||
![]() |
f04fc256f0 | ||
![]() |
15c10afd82 | ||
![]() |
ee2ae58509 | ||
![]() |
4a6d3ccec4 | ||
![]() |
373d019b55 | ||
![]() |
df86a19ea3 | ||
![]() |
029ef0888e | ||
![]() |
73b927af77 | ||
![]() |
0a10445263 | ||
![]() |
dbf0d22a38 | ||
![]() |
b6c700244a | ||
![]() |
a9fd83544e | ||
![]() |
b583ca7ea9 | ||
![]() |
c6dc1bf434 | ||
![]() |
c0764b0d25 | ||
![]() |
661da42800 | ||
![]() |
911d240ffc | ||
![]() |
d116b4bc47 | ||
![]() |
fcc65306a2 | ||
![]() |
17118d0966 | ||
![]() |
ea1f2157aa | ||
![]() |
53406f3fa4 | ||
![]() |
daf6e4b564 | ||
![]() |
9ba47dd2e0 | ||
![]() |
43b416012c | ||
![]() |
1b08029cd0 | ||
![]() |
01c730c9a5 | ||
![]() |
1c3022f8e5 | ||
![]() |
221056146e | ||
![]() |
22e9c15281 | ||
![]() |
85ab3972d1 | ||
![]() |
d3e1454e71 | ||
![]() |
3b932ccea4 | ||
![]() |
08eb86dd56 | ||
![]() |
e7f371cb42 | ||
![]() |
2a3ca51840 | ||
![]() |
6fa0b08e86 | ||
![]() |
0966278f10 | ||
![]() |
632f49acbd | ||
![]() |
3e4bc66519 | ||
![]() |
aa1fc84abd | ||
![]() |
c16fcdb237 | ||
![]() |
232f655ba3 | ||
![]() |
bc970d29c0 | ||
![]() |
e0259faf25 | ||
![]() |
c9bbf05fd4 | ||
![]() |
353a949fa6 | ||
![]() |
61726b38a8 | ||
![]() |
6eb8870d6e | ||
![]() |
45d671977e | ||
![]() |
364413c729 | ||
![]() |
f53a543626 | ||
![]() |
87376db23b | ||
![]() |
7f6b744e72 | ||
![]() |
8bbf698004 | ||
![]() |
8b5c80ebba | ||
![]() |
edd99f0bff | ||
![]() |
efe535f21f | ||
![]() |
3d11e6b3a4 | ||
![]() |
08f93902f7 | ||
![]() |
5bde545685 | ||
![]() |
8b886ac2ff | ||
![]() |
3a214e1001 | ||
![]() |
e8d3aca742 | ||
![]() |
26276da421 | ||
![]() |
600f9a03ef | ||
![]() |
9d153e20e5 | ||
![]() |
1db54e62fd | ||
![]() |
5d9eff2b93 | ||
![]() |
feefcffc1e | ||
![]() |
a882b4aa41 | ||
![]() |
17d90f923a | ||
![]() |
f3ac4cc403 | ||
![]() |
04ff4f4962 | ||
![]() |
40f5e7a085 | ||
![]() |
ec4e68bcff | ||
![]() |
277610fa39 | ||
![]() |
839e343ebe | ||
![]() |
7d78d81573 | ||
![]() |
9bdc9fbe9a | ||
![]() |
5a4e946b0f | ||
![]() |
e2d22fcb96 | ||
![]() |
9cbdbebc77 | ||
![]() |
52ff6401b6 | ||
![]() |
ce2a63ceea | ||
![]() |
c26c26b444 | ||
![]() |
fe3b930978 | ||
![]() |
2db9c55a4f | ||
![]() |
b53f1fd220 | ||
![]() |
34924d0a24 | ||
![]() |
335ba5f745 | ||
![]() |
58b962fd87 | ||
![]() |
6f35f049e4 | ||
![]() |
c302222645 | ||
![]() |
80ce0c5d38 | ||
![]() |
c3c35397a3 | ||
![]() |
c7b2f5e1e2 | ||
![]() |
53636ed792 | ||
![]() |
f2137bf432 | ||
![]() |
8091af9aa0 | ||
![]() |
722ce3a206 | ||
![]() |
cef6900a9d | ||
![]() |
4ff6e0228c | ||
![]() |
0cb5df1615 | ||
![]() |
b2f276d33e | ||
![]() |
b9c31140c9 | ||
![]() |
c77833a50b | ||
![]() |
136dfa04d6 | ||
![]() |
82cd6fb86b | ||
![]() |
1f4c2043ac | ||
![]() |
b9550bf548 | ||
![]() |
2d9566e997 | ||
![]() |
5ab9cd5485 | ||
![]() |
79ccc8727d | ||
![]() |
83f34998f4 | ||
![]() |
9c4b298862 | ||
![]() |
6288867d41 | ||
![]() |
fd03010c0a | ||
![]() |
95803060e6 | ||
![]() |
10f7fb8b72 | ||
![]() |
7fe02b7235 | ||
![]() |
41d86ae546 | ||
![]() |
ff0c762374 | ||
![]() |
091583e4ee | ||
![]() |
62422c935b | ||
![]() |
374ed32365 | ||
![]() |
d59ade7aa2 | ||
![]() |
1d2d4eaa12 | ||
![]() |
2d337f3328 | ||
![]() |
ee8c620c7d | ||
![]() |
2b35adec96 | ||
![]() |
0fd8b4e606 | ||
![]() |
12723117a2 | ||
![]() |
539e8b1ef8 | ||
![]() |
2bdb3d9dba | ||
![]() |
958026eb2a | ||
![]() |
046ebb4d00 | ||
![]() |
22869a383d | ||
![]() |
68867a916e | ||
![]() |
02ff5446b4 | ||
![]() |
f06702749e | ||
![]() |
67fd1bc7d9 | ||
![]() |
2dce5229ea | ||
![]() |
84e7ae8344 | ||
![]() |
6d2ed9dfc7 | ||
![]() |
13fe1536fd | ||
![]() |
531fc7afcb | ||
![]() |
8104f718c2 | ||
![]() |
bff0eac866 | ||
![]() |
59132a3ffb | ||
![]() |
c83dd50cd2 | ||
![]() |
4850f064fa | ||
![]() |
2edba78f69 | ||
![]() |
2e8e96eb8a | ||
![]() |
efe6353526 | ||
![]() |
25587eacc7 | ||
![]() |
1e2658d4d3 | ||
![]() |
a28122b0da | ||
![]() |
5510243b26 | ||
![]() |
71468c7345 | ||
![]() |
455c3b30ef | ||
![]() |
4a5ecbbf28 | ||
![]() |
69ee99f897 | ||
![]() |
392e446c28 | ||
![]() |
ee7e6c7cbc | ||
![]() |
c457e8d7a7 | ||
![]() |
80ff93fb34 | ||
![]() |
a842e1b8b8 | ||
![]() |
c20afa19ba | ||
![]() |
36f3f6f6d3 | ||
![]() |
fe5b0c4871 | ||
![]() |
faa9f47f94 | ||
![]() |
c07fbdffca | ||
![]() |
ba285321dd | ||
![]() |
407f43a104 | ||
![]() |
972329ae68 | ||
![]() |
ca25bf0e73 | ||
![]() |
be23fe4f0c | ||
![]() |
954f7ba1ae | ||
![]() |
f0d0f9305d | ||
![]() |
0eba50ad4f | ||
![]() |
fa6901f91f | ||
![]() |
48d16e1b50 | ||
![]() |
72b334f016 | ||
![]() |
4514b87359 | ||
![]() |
4d1102c01e | ||
![]() |
a9bef3647c | ||
![]() |
d5c985c2a3 | ||
![]() |
4373ba5820 | ||
![]() |
aa0197e373 | ||
![]() |
61c73f6917 | ||
![]() |
0b5f67be30 | ||
![]() |
26252c6ad5 | ||
![]() |
ac9d203068 | ||
![]() |
ecdbf7f8ab | ||
![]() |
cc12dbbbb5 | ||
![]() |
1b391e1dd1 | ||
![]() |
b87af2e548 | ||
![]() |
bd2e41a184 | ||
![]() |
8ddff714db | ||
![]() |
cf4b4adf2c | ||
![]() |
8b60ebfbcc | ||
![]() |
71d1735664 | ||
![]() |
96525021c9 | ||
![]() |
09e8de8e33 | ||
![]() |
dbaea5f94f | ||
![]() |
3565801ea7 | ||
![]() |
802ed0da75 | ||
![]() |
e0f5db72ed | ||
![]() |
fdfb5353df | ||
![]() |
dbc3c66f90 | ||
![]() |
3c91d310cf | ||
![]() |
80298eefc6 | ||
![]() |
dd8a4bc41b | ||
![]() |
6fe56f273a | ||
![]() |
1b6d7c0868 | ||
![]() |
6990b6edc7 | ||
![]() |
a1e55eb8d7 | ||
![]() |
04f1a9576c | ||
![]() |
3bb289cd1d | ||
![]() |
ddb0600db4 | ||
![]() |
3490a15658 | ||
![]() |
3e07ecf3a0 | ||
![]() |
e07f30435b | ||
![]() |
03cae79912 | ||
![]() |
72c6966953 | ||
![]() |
10232b033d | ||
![]() |
e84dab69b0 | ||
![]() |
9b0905ed01 | ||
![]() |
8e4621a65c | ||
![]() |
b47b95f18a | ||
![]() |
0b63b7bfdc | ||
![]() |
3c634424ef | ||
![]() |
d3dbe2dcef | ||
![]() |
7e71374cef | ||
![]() |
fc24e6521e | ||
![]() |
b52b43d32a | ||
![]() |
f0c61d8d50 | ||
![]() |
c7cad391b3 | ||
![]() |
928a7fd545 | ||
![]() |
43a5b1720a | ||
![]() |
5e4f9f35c1 | ||
![]() |
4fdca88365 | ||
![]() |
4b2e711fb2 | ||
![]() |
388f89a658 | ||
![]() |
8c52d9626b | ||
![]() |
5283d65c0a | ||
![]() |
ddd8a765fa | ||
![]() |
ae4abf7f77 | ||
![]() |
531122db31 | ||
![]() |
fb7fac9b50 | ||
![]() |
b0ad561f19 | ||
![]() |
a4dacba699 | ||
![]() |
6a6e6b77ec | ||
![]() |
aa3c8a0629 | ||
![]() |
32e6650042 | ||
![]() |
2e2418f2a3 | ||
![]() |
6d42648c01 | ||
![]() |
1d9c850383 | ||
![]() |
3c3f48664e | ||
![]() |
5994760167 | ||
![]() |
c9bcda945c | ||
![]() |
2b38f1ed09 | ||
![]() |
071c7316e7 | ||
![]() |
373771d176 | ||
![]() |
a6597997f6 | ||
![]() |
af4ac5895e | ||
![]() |
3d7bb6b490 | ||
![]() |
caa2354e8e | ||
![]() |
3af114a046 | ||
![]() |
6542cb27d3 | ||
![]() |
e5365898eb | ||
![]() |
070eefbdcf | ||
![]() |
ebae639003 | ||
![]() |
b15f0294f0 | ||
![]() |
957ffb6d7d | ||
![]() |
cbf7e9984c | ||
![]() |
9d0a4c5d86 | ||
![]() |
96a80c51e6 | ||
![]() |
2ab0beaa67 | ||
![]() |
6f1b7843dc | ||
![]() |
d1443712e3 | ||
![]() |
f0e0e50af0 | ||
![]() |
6b00d11178 | ||
![]() |
3af2fd5f41 | ||
![]() |
360a23e4d0 | ||
![]() |
6dd97ac434 | ||
![]() |
9974142322 | ||
![]() |
d846d59db9 | ||
![]() |
4e5f36201f | ||
![]() |
5e7edbebae | ||
![]() |
ad4db2ad22 | ||
![]() |
e20bea70e0 | ||
![]() |
032e5ee581 | ||
![]() |
44fad5e828 | ||
![]() |
9d893d4fba | ||
![]() |
5072edf2d1 | ||
![]() |
6baf5a19b6 | ||
![]() |
4b599dcce4 | ||
![]() |
576909ac1a | ||
![]() |
3844e66ecb | ||
![]() |
9a6f99c378 | ||
![]() |
e4a5d143b2 | ||
![]() |
fdbb7e97cb | ||
![]() |
99755e9aff | ||
![]() |
23a7abd323 | ||
![]() |
c322d70a2e | ||
![]() |
a47711ff14 | ||
![]() |
e1bba3b68e | ||
![]() |
7c81fa1260 | ||
![]() |
c69806f19e | ||
![]() |
ceb2f745f6 | ||
![]() |
d32e257589 | ||
![]() |
a5035388a0 | ||
![]() |
d66159938d | ||
![]() |
7921e74e24 | ||
![]() |
c4bbce425d | ||
![]() |
af534ac8e0 | ||
![]() |
fc9c944891 | ||
![]() |
7dbd6c6378 | ||
![]() |
795eaf463d | ||
![]() |
d645eb412c | ||
![]() |
318335e97d | ||
![]() |
ad92394785 | ||
![]() |
1cdfc51a90 | ||
![]() |
653cb522d9 | ||
![]() |
91d0cebed9 | ||
![]() |
d69e9a6468 | ||
![]() |
b721aab0f1 | ||
![]() |
647ce92c07 | ||
![]() |
8962e79b7a | ||
![]() |
6e3748c44d | ||
![]() |
4d1b603bf6 | ||
![]() |
893be4998e | ||
![]() |
b6d9312bc8 | ||
![]() |
b3f3813c4b | ||
![]() |
0981e401a4 | ||
![]() |
32cda3b20f | ||
![]() |
f1324a75cc | ||
![]() |
f73673a006 | ||
![]() |
ab61084959 | ||
![]() |
788645589c | ||
![]() |
4c607b496a | ||
![]() |
386ccd9ada | ||
![]() |
a31d5ee1be | ||
![]() |
3c4f4a9584 | ||
![]() |
a7711b29f3 | ||
![]() |
e86728b5f6 | ||
![]() |
a38fe40fe4 | ||
![]() |
678be9fd14 | ||
![]() |
8b7b7d8252 | ||
![]() |
bcaf67a9b3 | ||
![]() |
bcfb5ed443 | ||
![]() |
81d7c393f0 | ||
![]() |
761e720a05 | ||
![]() |
313989de53 | ||
![]() |
ca17f60b50 | ||
![]() |
9fc93123d0 | ||
![]() |
f8303cdde7 | ||
![]() |
3bd0287466 | ||
![]() |
5afff41c69 | ||
![]() |
d72e5dc726 | ||
![]() |
35b6e18762 | ||
![]() |
52485f32f4 | ||
![]() |
d3899fc398 | ||
![]() |
fdc42b5dd8 | ||
![]() |
74b483cf0b | ||
![]() |
8019f411f8 | ||
![]() |
59c9fa82f3 | ||
![]() |
07d9f13a75 | ||
![]() |
b52899bf2a | ||
![]() |
a67979ac44 | ||
![]() |
c8126b225e | ||
![]() |
bee206814a | ||
![]() |
f41c7a4251 | ||
![]() |
ca93d6ca4d | ||
![]() |
c3d53e0267 | ||
![]() |
669ebbaefb | ||
![]() |
1fff87a739 | ||
![]() |
20bf357f33 | ||
![]() |
692636ca9d | ||
![]() |
f5d358de14 | ||
![]() |
5d77525722 | ||
![]() |
8a498b0bfa | ||
![]() |
14d0b524f4 | ||
![]() |
49bb31bcc6 | ||
![]() |
75cb1d932d | ||
![]() |
228e3ecf9b | ||
![]() |
08d67ffd00 | ||
![]() |
d7f2e35ebe | ||
![]() |
dba6c02fde | ||
![]() |
8ebaf12323 | ||
![]() |
eaa19e7d49 | ||
![]() |
876e266e32 | ||
![]() |
b4c49278bb | ||
![]() |
4693f48f04 | ||
![]() |
07b8915fa9 | ||
![]() |
03e2537c9f | ||
![]() |
32b9e55f75 | ||
![]() |
e8a3143012 | ||
![]() |
4388347bf6 | ||
![]() |
97e8965800 | ||
![]() |
4778222134 | ||
![]() |
8b92bf0af8 | ||
![]() |
e8a2d74bc4 | ||
![]() |
94832d8633 | ||
![]() |
b243522d25 | ||
![]() |
344dafe9ef | ||
![]() |
29011fe0f0 | ||
![]() |
025075dac2 | ||
![]() |
4858090db1 | ||
![]() |
50019e5145 | ||
![]() |
acf9a64883 | ||
![]() |
45e23e0330 | ||
![]() |
165b87f8a5 | ||
![]() |
b62bc142de | ||
![]() |
81e1433635 | ||
![]() |
b722bcc762 | ||
![]() |
8050985d81 | ||
![]() |
9b77207f77 | ||
![]() |
ffb9cc0c61 | ||
![]() |
9a31ae11bb | ||
![]() |
8716eeeef1 | ||
![]() |
40e98347ca | ||
![]() |
5c75c9dd58 | ||
![]() |
89c41de572 | ||
![]() |
1594b88e91 | ||
![]() |
9ec88ad9dc | ||
![]() |
b50c0e9cc8 | ||
![]() |
ea9303aa80 | ||
![]() |
bbc7751538 | ||
![]() |
b659b4a413 | ||
![]() |
b6dc2f442f | ||
![]() |
11cbf733df | ||
![]() |
325d627537 | ||
![]() |
5cab045d1b | ||
![]() |
f08e102f40 | ||
![]() |
6bb15793e9 | ||
![]() |
d24b241d63 | ||
![]() |
ad6f63e334 | ||
![]() |
1913633216 | ||
![]() |
1c930c43ad | ||
![]() |
3e5868d8e0 | ||
![]() |
be6bbbe318 | ||
![]() |
e16299dca8 | ||
![]() |
875e759794 | ||
![]() |
f3e42393ea | ||
![]() |
3339d6d280 | ||
![]() |
5221619566 | ||
![]() |
b64bc0e0fa | ||
![]() |
7065ecaf24 | ||
![]() |
62625f0b97 | ||
![]() |
cf559ee23e | ||
![]() |
dc25f6ff1c | ||
![]() |
ea9812eb9e | ||
![]() |
7d7812b8b0 | ||
![]() |
72a517d017 | ||
![]() |
7eb8485364 | ||
![]() |
d9811e00a4 | ||
![]() |
359707764a | ||
![]() |
a2bdbfaff3 | ||
![]() |
3f0c08e941 | ||
![]() |
ba5385040c | ||
![]() |
611be24011 | ||
![]() |
edeeb71a43 | ||
![]() |
085d31663c | ||
![]() |
fb8f3fee01 | ||
![]() |
df38c71a8e | ||
![]() |
31d6cc2680 | ||
![]() |
5e71089f21 | ||
![]() |
38e1688297 | ||
![]() |
7bd834e82a | ||
![]() |
5c24c11f48 | ||
![]() |
d7c791e1c2 | ||
![]() |
1a89620a4e | ||
![]() |
c6e9724c4b | ||
![]() |
529030f646 | ||
![]() |
1d5d827dd0 | ||
![]() |
d23728d194 | ||
![]() |
12eaffab8e | ||
![]() |
d8add4cbb6 | ||
![]() |
4d1a9aa5bc | ||
![]() |
36bade76ca | ||
![]() |
aef7126a2a | ||
![]() |
ee646fde9c | ||
![]() |
3cb3689c01 | ||
![]() |
ff909a0ed2 | ||
![]() |
afe2a390dc | ||
![]() |
78d59d4553 | ||
![]() |
5640f30e34 | ||
![]() |
07617a5201 | ||
![]() |
2f47112d49 | ||
![]() |
affed3d942 | ||
![]() |
973eabaad9 | ||
![]() |
a42f9fe136 | ||
![]() |
d91de6e9af | ||
![]() |
6391ac146b | ||
![]() |
243c037887 | ||
![]() |
2811351786 | ||
![]() |
34dd3de0ff | ||
![]() |
016bd3fc44 | ||
![]() |
0beeb3dfe7 | ||
![]() |
0f19f40e61 | ||
![]() |
1f37b0e9fb | ||
![]() |
008943b8a6 | ||
![]() |
856306f086 | ||
![]() |
c11da88745 | ||
![]() |
7b2acd1825 | ||
![]() |
83f1ba1060 | ||
![]() |
2f75b14749 | ||
![]() |
7f213ac275 | ||
![]() |
37b50b23c1 | ||
![]() |
6938d9301b | ||
![]() |
940c10c0f5 | ||
![]() |
d7913b8431 | ||
![]() |
e4d7e2937a | ||
![]() |
69d67ca434 | ||
![]() |
3f13d39b8c | ||
![]() |
e575e2e9da | ||
![]() |
d3479674d6 | ||
![]() |
e548da7829 | ||
![]() |
12e25494b9 | ||
![]() |
82eb53f7e6 | ||
![]() |
943d9e60f8 | ||
![]() |
a4e6a5f19f | ||
![]() |
e1807595a8 | ||
![]() |
70802aabbd | ||
![]() |
8151263a4e | ||
![]() |
e8b5516a85 | ||
![]() |
f0a6ffb718 | ||
![]() |
26ef30a3d0 | ||
![]() |
0f8374c2d5 | ||
![]() |
6810d85db4 | ||
![]() |
0c49b98bbb | ||
![]() |
cf0ef879e6 | ||
![]() |
a53e028aab | ||
![]() |
eda81e0371 | ||
![]() |
7dc43f92ed | ||
![]() |
84c6e99cac | ||
![]() |
3755f24127 | ||
![]() |
c557224dbb | ||
![]() |
7b3ce1d368 | ||
![]() |
5ef13890ed | ||
![]() |
e41f20a4cc | ||
![]() |
7f3ec4e450 | ||
![]() |
e4dc6fd787 | ||
![]() |
2872807686 | ||
![]() |
45218144de | ||
![]() |
e72f0906be | ||
![]() |
08003c5d27 | ||
![]() |
ae1609ae9d | ||
![]() |
00665d2bad | ||
![]() |
17076431ac | ||
![]() |
a26dcd93a0 | ||
![]() |
b8e568ecbd | ||
![]() |
032996db67 | ||
![]() |
bfc9c05cd5 | ||
![]() |
f3a7de1ed3 | ||
![]() |
7fe8b42f3b | ||
![]() |
105bb4fc8a | ||
![]() |
b395648185 | ||
![]() |
44b252928f | ||
![]() |
c02129717d | ||
![]() |
4f6b6de2c1 | ||
![]() |
8d9700e145 | ||
![]() |
40ae31ad0d | ||
![]() |
ddd2221e7c | ||
![]() |
5d96268b19 | ||
![]() |
2874ef39fc | ||
![]() |
44df23a021 | ||
![]() |
8562a6f08f | ||
![]() |
e9ca4908bc | ||
![]() |
78a00caed8 | ||
![]() |
cbfef5b70b | ||
![]() |
fbaa87208b | ||
![]() |
2b696d736b | ||
![]() |
8b28542ebf | ||
![]() |
79b61e97e3 | ||
![]() |
f3975a9652 | ||
![]() |
87a0ffa3ed | ||
![]() |
994963ae2e | ||
![]() |
4cc5521755 | ||
![]() |
ed4ae74e52 | ||
![]() |
677ade0acd | ||
![]() |
9e16a0cf3c | ||
![]() |
e97b97deb3 | ||
![]() |
2f0f409f74 | ||
![]() |
0456a4a4a0 | ||
![]() |
418c1a8b97 | ||
![]() |
4c8a5cc1b8 | ||
![]() |
40efdba888 | ||
![]() |
db0d3a09ea | ||
![]() |
1feb841142 | ||
![]() |
fa4b132ed5 | ||
![]() |
0af4be06e7 | ||
![]() |
2d9fa8ed68 | ||
![]() |
acf478c000 | ||
![]() |
9f5281a104 | ||
![]() |
36c3ae547c | ||
![]() |
5282fa2573 | ||
![]() |
9d62ba9cd1 | ||
![]() |
b48468620f | ||
![]() |
61f59d2156 | ||
![]() |
daa27be52f | ||
![]() |
3d954ffc14 | ||
![]() |
810e1922ba | ||
![]() |
8c840f8323 | ||
![]() |
e7868d9740 | ||
![]() |
d959d11c2f | ||
![]() |
435981a7f5 | ||
![]() |
da4adce6f5 | ||
![]() |
f89d6943ac | ||
![]() |
5a80958fd3 | ||
![]() |
860ecc16da | ||
![]() |
f209356573 | ||
![]() |
dd566690a9 | ||
![]() |
2a6f7d5aa4 | ||
![]() |
6f4ad95567 | ||
![]() |
85bf56b162 | ||
![]() |
9a7657e70c | ||
![]() |
e47539a53f | ||
![]() |
2606934691 | ||
![]() |
d003a3184b | ||
![]() |
91c4ee63ad | ||
![]() |
2f02b36596 | ||
![]() |
e06b9cae4b | ||
![]() |
1511f2379a | ||
![]() |
03b99628e2 | ||
![]() |
69e32a2585 | ||
![]() |
b4c15e5b18 | ||
![]() |
c6b96c036e | ||
![]() |
89e398f487 | ||
![]() |
2ee29ba5aa | ||
![]() |
accc5b98df | ||
![]() |
ded5e522d7 | ||
![]() |
ae26295b3c | ||
![]() |
5938d4d612 | ||
![]() |
40f075b1d2 | ||
![]() |
4acea9e0af | ||
![]() |
f370609dd3 | ||
![]() |
0259015240 | ||
![]() |
1577e69b92 | ||
![]() |
78668d4884 | ||
![]() |
760fe66f8c | ||
![]() |
ca94a1fa98 | ||
![]() |
59bedd726b | ||
![]() |
73777fd6f3 | ||
![]() |
0e6acc54af | ||
![]() |
67fbe4ba0e | ||
![]() |
4294d6e27b | ||
![]() |
2ed7fc04fc | ||
![]() |
a014c2f9d1 | ||
![]() |
0262961787 | ||
![]() |
94556d590b | ||
![]() |
fc128613df | ||
![]() |
d175b9ed15 | ||
![]() |
14a4147e18 | ||
![]() |
31148a77de | ||
![]() |
29ca7964c1 | ||
![]() |
28bd9c8356 | ||
![]() |
adb1e02780 | ||
![]() |
4844a21ca5 | ||
![]() |
78336b6df0 | ||
![]() |
78e5efcdc0 | ||
![]() |
118052403f | ||
![]() |
e580971d11 | ||
![]() |
d15cde2ff5 | ||
![]() |
d4fe52c77c | ||
![]() |
674d67acd3 | ||
![]() |
2bb7b624a8 | ||
![]() |
2964fcc19f | ||
![]() |
be88c2ce62 | ||
![]() |
c920d3a636 | ||
![]() |
803e2acfb9 | ||
![]() |
38a93fbc68 | ||
![]() |
cd377faee9 | ||
![]() |
3b9e245c0a | ||
![]() |
e76cce3576 | ||
![]() |
96d783ce88 | ||
![]() |
c9b8ed2aae | ||
![]() |
fbf4cee10e | ||
![]() |
53b6d761e2 | ||
![]() |
2b9e5d840e | ||
![]() |
2c3674b7f3 | ||
![]() |
e1bd31a8b9 | ||
![]() |
54ba1821cd | ||
![]() |
0b03442c53 | ||
![]() |
37e10c62ee | ||
![]() |
2cd28c5ad5 | ||
![]() |
ca2fa35bb3 | ||
![]() |
dbd8313dcc | ||
![]() |
8081a0cdde | ||
![]() |
fc749c4392 | ||
![]() |
1ed6b72630 | ||
![]() |
82a9a02bc2 | ||
![]() |
16de764540 | ||
![]() |
5de7439e17 | ||
![]() |
ad4bd72dce | ||
![]() |
ccdf05bed2 | ||
![]() |
27c350b27c | ||
![]() |
341fd5c55a | ||
![]() |
1a54098ad6 | ||
![]() |
06b00e27cc | ||
![]() |
f62fd3c432 | ||
![]() |
da46401eb3 | ||
![]() |
0ef672191a | ||
![]() |
516e40722f | ||
![]() |
2ef2ad98b8 | ||
![]() |
5307de68be | ||
![]() |
6c9581109b | ||
![]() |
45c6b2cf5d | ||
![]() |
e9acb84d65 | ||
![]() |
6f07d78a03 | ||
![]() |
46853e4c81 | ||
![]() |
c78ce4a33f | ||
![]() |
bcb7c4d9da | ||
![]() |
c8514a68c9 | ||
![]() |
e12d3999b4 | ||
![]() |
176837b3af | ||
![]() |
b2002a002a | ||
![]() |
99dc3c9802 | ||
![]() |
ebb82beb27 | ||
![]() |
1fefa78b9a | ||
![]() |
38174e7970 | ||
![]() |
3fe6e78659 | ||
![]() |
9d61c57329 | ||
![]() |
4dfad37bbe | ||
![]() |
1d4e265655 | ||
![]() |
cda7c2cc37 | ||
![]() |
44f041a362 | ||
![]() |
32e9070eda | ||
![]() |
d482c18e0d | ||
![]() |
cec45a9281 | ||
![]() |
900c8b0df5 | ||
![]() |
693beec49d | ||
![]() |
7e74578223 | ||
![]() |
40d88a43fb | ||
![]() |
178e5a11d8 | ||
![]() |
d6b53e64ba | ||
![]() |
8670f25e93 | ||
![]() |
6c0a167725 | ||
![]() |
f1f299649c | ||
![]() |
280de1c346 | ||
![]() |
1d87a9c194 | ||
![]() |
7891775969 | ||
![]() |
34d9be5a9c | ||
![]() |
3d78470eca | ||
![]() |
c48988c03e | ||
![]() |
67f28b06b5 | ||
![]() |
63e4999389 | ||
![]() |
a2b666f315 | ||
![]() |
f358afa118 | ||
![]() |
69a96b97a3 | ||
![]() |
d8fd0cf7de | ||
![]() |
23f6a262e9 | ||
![]() |
5cffe5a957 | ||
![]() |
3954c05401 | ||
![]() |
2f0a7c22b5 | ||
![]() |
6e3def93b1 | ||
![]() |
167e158a97 | ||
![]() |
d6012a39eb | ||
![]() |
460b122d02 | ||
![]() |
6126057060 | ||
![]() |
91bac970b3 | ||
![]() |
0485fa442e | ||
![]() |
9d0252b170 | ||
![]() |
9dbe6d437b | ||
![]() |
6015b80b6b | ||
![]() |
ff27d0de60 | ||
![]() |
2f58d46843 | ||
![]() |
aa0c24bb83 | ||
![]() |
0503a776ce | ||
![]() |
03a09788b9 | ||
![]() |
304866f03c | ||
![]() |
6c4cf5193c | ||
![]() |
7f1c1e5f18 | ||
![]() |
fb56aafead | ||
![]() |
f93419d9d5 | ||
![]() |
0bb480d192 | ||
![]() |
be71ee684f | ||
![]() |
b8306cf127 | ||
![]() |
491baffeb7 | ||
![]() |
bf94ffd7c7 | ||
![]() |
463d573171 | ||
![]() |
e7d4a31592 | ||
![]() |
5ef1df4001 | ||
![]() |
0d7666b548 | ||
![]() |
52eb063bbf | ||
![]() |
cb9bb2b875 | ||
![]() |
e0cc02e0a4 | ||
![]() |
3cf5a8b780 | ||
![]() |
b6c0cdd7c2 | ||
![]() |
e1d89faaf8 | ||
![]() |
325a8bb0a2 | ||
![]() |
ffaf7ae95a | ||
![]() |
7782a68d6e | ||
![]() |
6adc97247c | ||
![]() |
bb456f5518 | ||
![]() |
a8cc37d8f3 | ||
![]() |
82a28d2c89 | ||
![]() |
b116af8adf | ||
![]() |
1bc1e8ebef | ||
![]() |
c31b0df061 | ||
![]() |
a46fb334a5 | ||
![]() |
47cba37c67 | ||
![]() |
c207460146 | ||
![]() |
76de076265 | ||
![]() |
f9557f09f7 | ||
![]() |
63fd781bf0 | ||
![]() |
4436c714d8 | ||
![]() |
f23ed1d3e1 | ||
![]() |
42e59fd740 | ||
![]() |
3cb5050bcc | ||
![]() |
a22dc86d27 | ||
![]() |
8a77f42a78 | ||
![]() |
84afe628d0 | ||
![]() |
19d4df5ce7 | ||
![]() |
1fdce7f235 | ||
![]() |
cffc05560d | ||
![]() |
97fd575472 | ||
![]() |
ad4320765c | ||
![]() |
65cdae7696 | ||
![]() |
2b6fb268f1 | ||
![]() |
1599c3a72b | ||
![]() |
1817e74ad1 | ||
![]() |
50ff1f1213 | ||
![]() |
b5f7f27b0f | ||
![]() |
18daf03930 | ||
![]() |
34346f36a3 | ||
![]() |
0cf88c0674 | ||
![]() |
bf4d626dec | ||
![]() |
b66eccd85f | ||
![]() |
63adc17b96 | ||
![]() |
b18b8e05a6 | ||
![]() |
988abbfc6a | ||
![]() |
51b3f435c6 | ||
![]() |
5e9e535cb0 | ||
![]() |
790876d9fe | ||
![]() |
213458f56a | ||
![]() |
f5ac7c76bb | ||
![]() |
f57737eb52 | ||
![]() |
557248b142 | ||
![]() |
153c853b71 | ||
![]() |
1203225109 | ||
![]() |
0aaf42b507 | ||
![]() |
d615034315 | ||
![]() |
c29d96054f | ||
![]() |
7bfc553f99 | ||
![]() |
1d1cf89aa6 | ||
![]() |
66818f8b38 | ||
![]() |
c47af75e1e | ||
![]() |
24cc2a8b6d | ||
![]() |
ca27139ee1 | ||
![]() |
80fc1ef2c0 | ||
![]() |
fdf075de01 | ||
![]() |
21b5e64552 | ||
![]() |
5a217fc045 | ||
![]() |
968ba03790 | ||
![]() |
6ddff3bb33 | ||
![]() |
ee4eaa18be | ||
![]() |
1baf5e1953 | ||
![]() |
8801ab4781 | ||
![]() |
17869660f5 | ||
![]() |
aad6d6e145 | ||
![]() |
ce512f47f3 | ||
![]() |
ffc987e922 | ||
![]() |
7bc5b1e541 | ||
![]() |
cc36f40868 | ||
![]() |
89c94fba7d | ||
![]() |
cb658d8040 | ||
![]() |
8b9010e8d1 | ||
![]() |
e7ec9442ed | ||
![]() |
e1a0413004 | ||
![]() |
a385b92c62 | ||
![]() |
5b633aaa4c | ||
![]() |
f42bd0e064 | ||
![]() |
40d6f60943 | ||
![]() |
13469121e7 | ||
![]() |
890d0532eb | ||
![]() |
239499ffd0 | ||
![]() |
4a7031c928 | ||
![]() |
590dacc151 | ||
![]() |
1dcf21e235 | ||
![]() |
1fc4f6c18e | ||
![]() |
595f5adacd | ||
![]() |
95bc3e9a20 | ||
![]() |
216f49f885 | ||
![]() |
dd938aa668 | ||
![]() |
083775a2b2 | ||
![]() |
7527d78d29 | ||
![]() |
9e9565c4e4 | ||
![]() |
b44e5fdae0 | ||
![]() |
cd2dbfce0b | ||
![]() |
da8e5e9b1e | ||
![]() |
8a035e4fdf | ||
![]() |
94c211e395 | ||
![]() |
f66c6bc2aa | ||
![]() |
4d375d4da3 | ||
![]() |
b2f6182407 | ||
![]() |
5950e8fbca | ||
![]() |
f86c34eecd | ||
![]() |
ca3384c7e2 | ||
![]() |
e6c095d038 | ||
![]() |
418995bf2f | ||
![]() |
ebf7c19861 | ||
![]() |
e677117073 | ||
![]() |
037606c857 | ||
![]() |
86aa4a6f91 | ||
![]() |
a41a860c10 | ||
![]() |
8bb0a2723b | ||
![]() |
8135cda1e6 | ||
![]() |
f638e5dd34 | ||
![]() |
5e0f9f89c0 | ||
![]() |
8b58283533 | ||
![]() |
4c0c88958b | ||
![]() |
84e536fb59 | ||
![]() |
7c285c6978 | ||
![]() |
34cb19d0d8 | ||
![]() |
7b78db23f5 | ||
![]() |
599eb3cd96 | ||
![]() |
8b128ea15f | ||
![]() |
a47e79bb24 | ||
![]() |
a31d51e19c | ||
![]() |
896d39c174 | ||
![]() |
ef9df35580 | ||
![]() |
4c663e18d7 | ||
![]() |
762b52e06b | ||
![]() |
65ad82a597 | ||
![]() |
15bf7624bc | ||
![]() |
7b753bfbda | ||
![]() |
76abd48147 | ||
![]() |
c6307c08e2 | ||
![]() |
577210ee9a | ||
![]() |
0d1906355b | ||
![]() |
6b6c38bcb3 | ||
![]() |
fb8f624386 | ||
![]() |
63a3b5c625 | ||
![]() |
2cb49ab2c9 | ||
![]() |
3d678d5aa2 | ||
![]() |
6c1fa43167 | ||
![]() |
df7a30653f | ||
![]() |
7066f3a4a8 | ||
![]() |
2e7fea0c9b | ||
![]() |
ea020847b7 | ||
![]() |
a498f1ec3f | ||
![]() |
23511bba70 | ||
![]() |
a4f11d4cd9 | ||
![]() |
fa9642bdd1 | ||
![]() |
28ce0e8901 | ||
![]() |
93794b581e | ||
![]() |
cb6b2cd980 | ||
![]() |
4c5aeffec5 | ||
![]() |
db4abf9e15 | ||
![]() |
11fb22154d | ||
![]() |
4c6b1c44b0 | ||
![]() |
ed54f23fd7 | ||
![]() |
118aa95abe | ||
![]() |
b86481f52c | ||
![]() |
201ffa83fe | ||
![]() |
91078a79f0 | ||
![]() |
470da93d6e | ||
![]() |
9eb7f5acfa | ||
![]() |
8ae306c040 | ||
![]() |
eff3fe95bf | ||
![]() |
1996883890 | ||
![]() |
7f6999f1fc | ||
![]() |
dd0500492f | ||
![]() |
a9a2783130 | ||
![]() |
31a0a9d090 | ||
![]() |
ef35f8a67d | ||
![]() |
19c934bfda | ||
![]() |
834047342d | ||
![]() |
4652850c59 | ||
![]() |
ae64e39a01 | ||
![]() |
059ca66b16 | ||
![]() |
01cc55652c | ||
![]() |
3d588de755 | ||
![]() |
517417988a | ||
![]() |
e283f7dfd2 | ||
![]() |
ba02cc5375 | ||
![]() |
307d83d38f | ||
![]() |
06561d1a65 | ||
![]() |
8ac923060e | ||
![]() |
7423b39875 | ||
![]() |
bbb110f1be | ||
![]() |
1120579beb | ||
![]() |
6776f1336e | ||
![]() |
473a0be7fd | ||
![]() |
9037659e9a | ||
![]() |
4ded2351f5 | ||
![]() |
7c1b2cf743 | ||
![]() |
12338da577 | ||
![]() |
b68b0dba2c | ||
![]() |
fb06808bc3 | ||
![]() |
fb9eb68a19 | ||
![]() |
e1966b9cbc | ||
![]() |
71e5b81dcc | ||
![]() |
218be391cc | ||
![]() |
62fed89895 | ||
![]() |
be0c99822c | ||
![]() |
a0a7fedad8 | ||
![]() |
ce30592080 | ||
![]() |
70bc49dfd0 | ||
![]() |
61f57b0689 | ||
![]() |
73641fd63c | ||
![]() |
01c4b99f16 | ||
![]() |
40cdd585b3 | ||
![]() |
93e43173ba | ||
![]() |
5dcde3091c | ||
![]() |
2e334a7662 | ||
![]() |
ecd1491298 | ||
![]() |
8ca367a808 | ||
![]() |
23f9851808 | ||
![]() |
fc46a419f8 | ||
![]() |
722e40d4fd | ||
![]() |
e28838d90e | ||
![]() |
3e7f578d93 | ||
![]() |
da0fb7a110 | ||
![]() |
f4593107ac | ||
![]() |
25148e7fa2 | ||
![]() |
3571650164 | ||
![]() |
d181acafdc | ||
![]() |
14f7cd12c1 | ||
![]() |
7748f5c983 | ||
![]() |
c5eea9a154 | ||
![]() |
c16ecc44e0 | ||
![]() |
0783c69559 | ||
![]() |
35d0492d38 | ||
![]() |
b0e5a55b36 | ||
![]() |
e7e0e8a796 | ||
![]() |
dc4b9ff7a5 | ||
![]() |
b42d35bf09 | ||
![]() |
024b527b36 | ||
![]() |
9f2ccaaae7 | ||
![]() |
0b1267acf7 | ||
![]() |
5a8dbdc271 | ||
![]() |
52f2e22326 | ||
![]() |
b1ef8bd8ff | ||
![]() |
dd32e6e613 | ||
![]() |
db9f4c9460 | ||
![]() |
6ed7ad2cb2 | ||
![]() |
52be7f78e2 | ||
![]() |
b443be717c | ||
![]() |
b323620060 | ||
![]() |
be3d9fbec2 | ||
![]() |
47b3e6bd75 | ||
![]() |
d8d59bd29f | ||
![]() |
2b2392fcd8 | ||
![]() |
be7a32bfe0 | ||
![]() |
d3e0f5a371 | ||
![]() |
de38d036c5 | ||
![]() |
6007f6d4d4 | ||
![]() |
003cbb049a | ||
![]() |
b08ce42d9c | ||
![]() |
faa146da4a | ||
![]() |
0f8a5e4c66 | ||
![]() |
20dbc36b10 | ||
![]() |
4666f260f0 | ||
![]() |
3b028be1da | ||
![]() |
2f1136c97c | ||
![]() |
e6179e50de | ||
![]() |
7a6c735e23 | ||
![]() |
e0281979fd | ||
![]() |
f266c46feb | ||
![]() |
65895eda85 | ||
![]() |
187ab8079f | ||
![]() |
152839df90 | ||
![]() |
513132f08c | ||
![]() |
e29efd013d | ||
![]() |
e0dee1c0bf | ||
![]() |
ddf1549905 | ||
![]() |
5abee851f4 | ||
![]() |
5a39e36252 | ||
![]() |
a1e210c3d7 | ||
![]() |
6f9e0b7b04 | ||
![]() |
9ce9264f3e | ||
![]() |
6a206df61f | ||
![]() |
26cdaa9c31 | ||
![]() |
3864b2ba36 | ||
![]() |
d91e7a20e6 | ||
![]() |
ae5f47606c | ||
![]() |
15cf61610c | ||
![]() |
bda6c885e9 | ||
![]() |
5a179e1e44 | ||
![]() |
a7cec39f86 | ||
![]() |
31b60d1a88 | ||
![]() |
278e873c21 | ||
![]() |
e23dd35096 | ||
![]() |
5f181018d6 | ||
![]() |
06c3ac500b | ||
![]() |
394ea90536 | ||
![]() |
d999c33882 | ||
![]() |
3751fce400 | ||
![]() |
d1dc277af1 | ||
![]() |
c970b77038 | ||
![]() |
a007b89ce9 | ||
![]() |
485115d19d | ||
![]() |
8d219bd66d | ||
![]() |
96705a7be3 | ||
![]() |
c17380fd43 | ||
![]() |
71859fc385 | ||
![]() |
2c98f6de04 | ||
![]() |
577c69f7b2 | ||
![]() |
6781623bdc | ||
![]() |
85d3323ff0 | ||
![]() |
d375d66e1a | ||
![]() |
8f3b83565a | ||
![]() |
6d644d26d8 | ||
![]() |
3ef894b41a | ||
![]() |
019c45e425 | ||
![]() |
72d5d075c3 | ||
![]() |
ed7b299c77 | ||
![]() |
0939946cb5 | ||
![]() |
a61da5199e | ||
![]() |
8d7d1af2af | ||
![]() |
9971d29f40 | ||
![]() |
2929fb3444 | ||
![]() |
e294c9bd5a | ||
![]() |
e3460fef91 | ||
![]() |
11d3b71e44 | ||
![]() |
f023ca7498 | ||
![]() |
c631490c65 | ||
![]() |
baab6c007d | ||
![]() |
96c4984f4d | ||
![]() |
6a3772bb05 | ||
![]() |
10afb45469 | ||
![]() |
175b6969d0 | ||
![]() |
6af8a2e92d | ||
![]() |
48e4e5ed76 | ||
![]() |
e808dfc70e | ||
![]() |
ced8bd9bdb | ||
![]() |
3b09cc8e7b | ||
![]() |
f2b1d3f7e0 | ||
![]() |
f4c9ab6e0b | ||
![]() |
53966db5eb | ||
![]() |
9cad663f14 | ||
![]() |
c075aad226 | ||
![]() |
e85144bb49 | ||
![]() |
4a834d265c | ||
![]() |
6a817bc6f6 | ||
![]() |
0e1819ec17 | ||
![]() |
0e3fefbeb2 | ||
![]() |
199229d148 | ||
![]() |
21afc4af4e | ||
![]() |
a335044d5a | ||
![]() |
6e575b8b8c | ||
![]() |
cba42dc20f | ||
![]() |
5db8cfbd8b | ||
![]() |
85d3add083 | ||
![]() |
d5eb6a96d3 | ||
![]() |
8cf6a484ca | ||
![]() |
7559e507d3 | ||
![]() |
7464747b98 | ||
![]() |
6d2eada2c9 | ||
![]() |
f432caf2b6 | ||
![]() |
9a0f8af4a1 | ||
![]() |
7ade5f4218 | ||
![]() |
a5529afe8b | ||
![]() |
4f69f5dd7b | ||
![]() |
c7190ea0b9 | ||
![]() |
054341eb37 | ||
![]() |
a81a30e313 | ||
![]() |
f3f0d8f15f | ||
![]() |
0e1a829af2 | ||
![]() |
4e1a731802 | ||
![]() |
b30f45c251 | ||
![]() |
cf06470fb5 | ||
![]() |
2ec9dc3db9 | ||
![]() |
9aefb5a0b4 | ||
![]() |
2c215a07d2 | ||
![]() |
665734656b | ||
![]() |
2e98ee98d2 | ||
![]() |
fa25a5628f | ||
![]() |
7942992137 | ||
![]() |
b07b0cafbf | ||
![]() |
03970cdc32 | ||
![]() |
68dcec78f3 | ||
![]() |
8d31b4291d | ||
![]() |
f15031dbc2 | ||
![]() |
fac9a47d0d | ||
![]() |
24b9c36296 | ||
![]() |
64ca5bb117 | ||
![]() |
722e8d7065 | ||
![]() |
84eb7b04dd | ||
![]() |
45683c69c1 | ||
![]() |
9cf3670c46 | ||
![]() |
3ec49a7fed | ||
![]() |
f2b2d83020 | ||
![]() |
27c1d88938 | ||
![]() |
a516afeb9b | ||
![]() |
9e268b8c42 | ||
![]() |
93b2200ca4 | ||
![]() |
544fea623a | ||
![]() |
8dc84e2ee0 | ||
![]() |
98387a3e71 | ||
![]() |
99502a3d0e | ||
![]() |
cbe0225043 | ||
![]() |
47e833be28 | ||
![]() |
c0fb4a4285 | ||
![]() |
d4dc10a0c5 | ||
![]() |
2aa0181207 | ||
![]() |
b720af1855 | ||
![]() |
037362a41c | ||
![]() |
e45370331d | ||
![]() |
f143f0749f | ||
![]() |
f1dded980c | ||
![]() |
0b557b3924 | ||
![]() |
df9981a48a | ||
![]() |
9eebfb2cca | ||
![]() |
a10557b2c0 | ||
![]() |
2dc7b5493b | ||
![]() |
89179b28cb | ||
![]() |
52dfce6cc4 | ||
![]() |
09b1490399 | ||
![]() |
5c40476391 | ||
![]() |
e8f48f262f | ||
![]() |
11621338c1 | ||
![]() |
712aae02e8 | ||
![]() |
90bf227c57 | ||
![]() |
6f0ab28d69 | ||
![]() |
b6b68ca718 | ||
![]() |
959563cd9d | ||
![]() |
f76ac5b1b1 | ||
![]() |
b42c6bec48 | ||
![]() |
ee6cbc45cf | ||
![]() |
e5e38cd8a4 | ||
![]() |
c1b5abb0a5 | ||
![]() |
b52dacf3d6 | ||
![]() |
e3c4d00360 | ||
![]() |
a32a8f681a | ||
![]() |
86795e740c | ||
![]() |
185c7faeef | ||
![]() |
90131f8c43 | ||
![]() |
6f234acec5 | ||
![]() |
c83a1494b7 | ||
![]() |
8d62602067 | ||
![]() |
e872b18582 | ||
![]() |
ddc04fed59 | ||
![]() |
0737eba1fc | ||
![]() |
1f962ad44f | ||
![]() |
d8130098fa | ||
![]() |
9c3107cbe0 | ||
![]() |
bb6187cf43 | ||
![]() |
2d2b9603da | ||
![]() |
1a11960e9a | ||
![]() |
508b6c5341 | ||
![]() |
e602954500 | ||
![]() |
54c1123c61 | ||
![]() |
1dd55f15a8 | ||
![]() |
da245914f5 | ||
![]() |
4e9354558a | ||
![]() |
ed665d02c7 | ||
![]() |
3603283960 | ||
![]() |
3d580b06ee | ||
![]() |
f64fbd9485 | ||
![]() |
17cbbcbfea | ||
![]() |
c2a244b9fb | ||
![]() |
148e87e585 | ||
![]() |
d60dc6dfef | ||
![]() |
20746b9fb7 | ||
![]() |
9bf0d9ff18 | ||
![]() |
611383f817 | ||
![]() |
47e6a01a29 | ||
![]() |
d2ace954f9 | ||
![]() |
550592d6bc | ||
![]() |
ad0db22fe7 | ||
![]() |
7a6a9718a8 | ||
![]() |
99d4b58235 | ||
![]() |
4c048b8f2b | ||
![]() |
2afa8559b0 | ||
![]() |
7de755f480 | ||
![]() |
aeef7e8b48 | ||
![]() |
456e4565fc | ||
![]() |
4dd4e09a0e | ||
![]() |
1badfa1b9f | ||
![]() |
ca05ecaf24 | ||
![]() |
c55bd3aac5 | ||
![]() |
2dc37eafb3 | ||
![]() |
1ff204ec49 | ||
![]() |
eac28ef743 | ||
![]() |
e29abde749 | ||
![]() |
84863445f6 | ||
![]() |
78b1998547 | ||
![]() |
2b70361fcc | ||
![]() |
6c7fb0e3d9 | ||
![]() |
0e34e4b6f2 | ||
![]() |
59fe8e804b | ||
![]() |
49ad5f0df8 | ||
![]() |
7255234ffb | ||
![]() |
d8008fee97 | ||
![]() |
4c6e5e44c9 | ||
![]() |
8b094823a8 | ||
![]() |
6f6485fca3 | ||
![]() |
49e6760983 | ||
![]() |
60c2bc1acf | ||
![]() |
0c5836665b | ||
![]() |
7788088383 | ||
![]() |
1500c26734 | ||
![]() |
1c9dfd8cc0 | ||
![]() |
4ad7f04d12 | ||
![]() |
5f04667813 | ||
![]() |
312fa01efa | ||
![]() |
06923c4a44 | ||
![]() |
2ff7ba520e | ||
![]() |
bcc1574497 | ||
![]() |
9080f85aaf | ||
![]() |
afcd7194cf | ||
![]() |
71d102f239 | ||
![]() |
e8c570acbb | ||
![]() |
4866a2f48c | ||
![]() |
b8a45e5b9b | ||
![]() |
16b8db1fb6 | ||
![]() |
8def82ca1e | ||
![]() |
dcd813c1d6 | ||
![]() |
16429ee65b | ||
![]() |
ed13338a86 | ||
![]() |
e894bff782 | ||
![]() |
7a88f2ee7a | ||
![]() |
6b993d2cb4 | ||
![]() |
cdeeb74ae9 | ||
![]() |
1abcbc7ef2 | ||
![]() |
396f14c7cb | ||
![]() |
4ce2261c41 | ||
![]() |
a878e92b54 | ||
![]() |
a7c276969c | ||
![]() |
89d6e1f3c2 | ||
![]() |
0797b57d5a | ||
![]() |
620ece9519 | ||
![]() |
531a05eb11 | ||
![]() |
df9b05e5f2 | ||
![]() |
dd778de0e7 | ||
![]() |
71ca496ab6 | ||
![]() |
b8b1b45338 | ||
![]() |
1940381088 | ||
![]() |
fd8e4692b6 | ||
![]() |
d46ae41f9d | ||
![]() |
c5e41ce739 | ||
![]() |
b7bec5810b | ||
![]() |
9ecf3d2b9e | ||
![]() |
c3bc93227b | ||
![]() |
787c8e2de1 | ||
![]() |
be461b3863 | ||
![]() |
f32f3be444 | ||
![]() |
804aeb41c6 | ||
![]() |
f83b8bd63c | ||
![]() |
aebe671b5c | ||
![]() |
226c60dfea | ||
![]() |
e2663d4009 | ||
![]() |
602cfe99df | ||
![]() |
d0707e8d9d | ||
![]() |
564962a2ea | ||
![]() |
a56424d6fe | ||
![]() |
d3a5c24394 | ||
![]() |
6429c63787 | ||
![]() |
b4e056ca58 | ||
![]() |
a37d237459 | ||
![]() |
358685fd79 | ||
![]() |
ba31b9e449 | ||
![]() |
5db7e0dfb6 | ||
![]() |
95f803dad3 | ||
![]() |
8a6364a28f | ||
![]() |
e3692dc820 | ||
![]() |
a5de2967b0 | ||
![]() |
258fbcf5ff | ||
![]() |
963484577e | ||
![]() |
684d5e910d | ||
![]() |
1dd2ea7a13 | ||
![]() |
054eb236fc | ||
![]() |
3dffb397b9 | ||
![]() |
6b4ee06062 | ||
![]() |
7ab64dff9b | ||
![]() |
eacb384752 | ||
![]() |
855268b260 | ||
![]() |
ca4d4dd0c9 | ||
![]() |
b760a6cf94 | ||
![]() |
a93bd7a007 | ||
![]() |
9af4a7395d | ||
![]() |
9f92330dcd | ||
![]() |
da673bd605 | ||
![]() |
6264bce874 | ||
![]() |
4817efed3a | ||
![]() |
2204fcb12c | ||
![]() |
c480f3bfd7 | ||
![]() |
5f8b003ed2 | ||
![]() |
e909bc7ef5 | ||
![]() |
7735902a92 | ||
![]() |
d78f57a407 | ||
![]() |
7654364864 | ||
![]() |
dd4d2dda10 | ||
![]() |
5e294f79db | ||
![]() |
40d858e013 | ||
![]() |
3f50f52fad | ||
![]() |
c41838d3b1 | ||
![]() |
ebcf819b65 | ||
![]() |
b09d9d06cf | ||
![]() |
e7d94c6b4d | ||
![]() |
bf7ad7d8c3 | ||
![]() |
8951afee02 | ||
![]() |
cea2b94066 | ||
![]() |
542a404105 | ||
![]() |
7add0e6317 | ||
![]() |
9e10e0d903 | ||
![]() |
1b0b3e4862 | ||
![]() |
0db22cba41 | ||
![]() |
1d39c23f69 | ||
![]() |
46fba9fd55 | ||
![]() |
547b103c9a | ||
![]() |
314e57720e | ||
![]() |
49d2e7fb2e | ||
![]() |
5dd6f831d6 | ||
![]() |
e96fdbff2f | ||
![]() |
f2e91e4847 | ||
![]() |
cd7af5cdde | ||
![]() |
ac697df722 | ||
![]() |
1598d5c444 | ||
![]() |
bd152633d9 | ||
![]() |
14f68ed9bb | ||
![]() |
dc4602d565 | ||
![]() |
74d35ad44a | ||
![]() |
9e046d325e | ||
![]() |
8b0663d472 | ||
![]() |
71017044f6 | ||
![]() |
bd866df6a9 | ||
![]() |
e92ff68b25 | ||
![]() |
3190342092 | ||
![]() |
0932b80a5f | ||
![]() |
a3b08e9fb1 | ||
![]() |
d822cc7862 | ||
![]() |
a0cd8e304e | ||
![]() |
9631723115 | ||
![]() |
4ae72a029f | ||
![]() |
749eec186b | ||
![]() |
d56224032f | ||
![]() |
3af5ce3298 | ||
![]() |
b72fa572d1 | ||
![]() |
23194ce849 | ||
![]() |
0a2d96bcff | ||
![]() |
5301bad2d6 | ||
![]() |
1c68e9a9d7 | ||
![]() |
77eee2e92c | ||
![]() |
f666c6378f | ||
![]() |
336ff2ed4e | ||
![]() |
3e86926b5d | ||
![]() |
b29e5ae08b | ||
![]() |
7e97154a01 | ||
![]() |
7cbdc43e4f | ||
![]() |
17aae9b8d1 | ||
![]() |
93cd542724 | ||
![]() |
c05849844e | ||
![]() |
960a796dbb | ||
![]() |
408812eafd | ||
![]() |
93f4b25f36 | ||
![]() |
18ec6eb1fa | ||
![]() |
783242a8fc | ||
![]() |
c4b1380ac6 | ||
![]() |
f245508e18 | ||
![]() |
d777a52fbc | ||
![]() |
41fe96088a | ||
![]() |
eefa99eb38 | ||
![]() |
40d1c65b60 | ||
![]() |
96352b0c30 | ||
![]() |
c1ba6432b1 | ||
![]() |
9c670cc0d0 | ||
![]() |
775accf2ff | ||
![]() |
d31e43f33a | ||
![]() |
fda8474864 | ||
![]() |
e6cf5cbc49 | ||
![]() |
ca52e4b507 | ||
![]() |
13f83f91de | ||
![]() |
be74ee8d64 | ||
![]() |
f99dc91019 | ||
![]() |
6cebc0eb92 | ||
![]() |
dde92cd855 | ||
![]() |
f70becf59a | ||
![]() |
9c6404bbd2 | ||
![]() |
029b31a628 | ||
![]() |
a89e649a43 | ||
![]() |
e3b694fa7b | ||
![]() |
7ab9b6b380 | ||
![]() |
d65c45a488 | ||
![]() |
c02abe6fba | ||
![]() |
dbfe2a9ab8 | ||
![]() |
182b7e619d | ||
![]() |
bf772bb0ca | ||
![]() |
76fde52adc | ||
![]() |
82680d5909 | ||
![]() |
f28077e5b4 | ||
![]() |
852e9bcf2f | ||
![]() |
3d82b04e3f | ||
![]() |
6ed6ffca85 | ||
![]() |
abae27e6a5 | ||
![]() |
d024b5dfb0 | ||
![]() |
e9cccca06a | ||
![]() |
a41a461e98 | ||
![]() |
bdd0f825c2 | ||
![]() |
19f6399f31 | ||
![]() |
efba6111f1 | ||
![]() |
4e956463be | ||
![]() |
d7d0afd555 | ||
![]() |
33ba72143f | ||
![]() |
62b783fca5 | ||
![]() |
346f885345 | ||
![]() |
137bcdd938 | ||
![]() |
e017fa75fa | ||
![]() |
e101a9a1d7 | ||
![]() |
f76ae15881 | ||
![]() |
e705734d54 | ||
![]() |
5f7f5fe284 | ||
![]() |
c7a569dd28 | ||
![]() |
496cd6912a | ||
![]() |
3641e56ea7 | ||
![]() |
b6d7e2f521 | ||
![]() |
4928d5fe07 | ||
![]() |
4106cc6489 | ||
![]() |
411839c22a | ||
![]() |
a98b4f5257 | ||
![]() |
fc26c9d5c0 | ||
![]() |
8d381966cf | ||
![]() |
a2e4601a2c | ||
![]() |
d70cc81d17 | ||
![]() |
687c06bf11 | ||
![]() |
c23a5acda0 | ||
![]() |
5c7c0df016 | ||
![]() |
b64d102839 | ||
![]() |
af597e108a | ||
![]() |
e46890b21b | ||
![]() |
4fc1a060e5 | ||
![]() |
41fa645578 | ||
![]() |
406571ef4b | ||
![]() |
f42a8a3819 | ||
![]() |
b67243deb2 | ||
![]() |
17657eb0e5 | ||
![]() |
42090d6568 | ||
![]() |
1f303e905f | ||
![]() |
0672f61220 | ||
![]() |
b2c480307a | ||
![]() |
64dd22bcb2 | ||
![]() |
d938bb6d37 | ||
![]() |
911886bdba | ||
![]() |
a6181dd337 | ||
![]() |
a3c9997036 | ||
![]() |
f643fc197d | ||
![]() |
f43c3c460a | ||
![]() |
a717a8fd42 | ||
![]() |
61b04fdc13 | ||
![]() |
5ac9092180 | ||
![]() |
6bd8a215d6 | ||
![]() |
50c07edddc | ||
![]() |
dd741b7caa | ||
![]() |
298d51e4ce | ||
![]() |
94dc01b4d0 | ||
![]() |
f0c0c02a97 | ||
![]() |
2de2b4d15c | ||
![]() |
5152edd4cc | ||
![]() |
390fd0ba4d | ||
![]() |
9c7bf27914 | ||
![]() |
485a3e4a29 | ||
![]() |
79c506e0ef | ||
![]() |
916a28c1cb | ||
![]() |
cdaf853674 | ||
![]() |
98fb042665 | ||
![]() |
65eda95bd8 | ||
![]() |
b0036e2c78 | ||
![]() |
afb591a68c | ||
![]() |
5130867929 | ||
![]() |
ee61f2b604 | ||
![]() |
5efb8b4918 | ||
![]() |
425ae7beaa | ||
![]() |
fd47adec27 | ||
![]() |
3cb0aa1e00 | ||
![]() |
39e07443bc | ||
![]() |
1eb794f78e | ||
![]() |
ff82b8150c | ||
![]() |
56c9f36768 | ||
![]() |
4363daa31d | ||
![]() |
481d6e9d23 | ||
![]() |
201e69126e | ||
![]() |
58a7683aa2 | ||
![]() |
a36d39b74f | ||
![]() |
5ef0091bd9 | ||
![]() |
55ef08a958 | ||
![]() |
5f83dc9a1c | ||
![]() |
2a5badd762 | ||
![]() |
628366225e | ||
![]() |
bd207b2baa | ||
![]() |
e8b32abee8 | ||
![]() |
a0b1da37b1 | ||
![]() |
b5700329cb | ||
![]() |
c4d6c7215f | ||
![]() |
884e54c7ec | ||
![]() |
12c20296a6 | ||
![]() |
c0fadd2770 | ||
![]() |
b62f2ac2a1 | ||
![]() |
dea0e18187 | ||
![]() |
ee7282f85c | ||
![]() |
bc3fdab284 | ||
![]() |
15415bf0bf | ||
![]() |
8a425ba452 | ||
![]() |
d448b906aa | ||
![]() |
21fb35a6ca | ||
![]() |
907cd6a750 | ||
![]() |
1b81dac2c6 | ||
![]() |
4a66d40d58 | ||
![]() |
738241059e | ||
![]() |
f217c6f32b | ||
![]() |
2fee13264e | ||
![]() |
c4c6cc65e4 | ||
![]() |
0e5860a92b | ||
![]() |
81736cd1b9 | ||
![]() |
3dd7390b63 | ||
![]() |
ff242e37ff | ||
![]() |
1c5f7a6b37 | ||
![]() |
a3b7a58d42 | ||
![]() |
be06ac9c6b | ||
![]() |
48a60241a1 | ||
![]() |
33c8a8690c | ||
![]() |
244496f37a | ||
![]() |
dbb0e25645 | ||
![]() |
4e76c0d06b | ||
![]() |
f2c6170f1e | ||
![]() |
dbcdfe9025 | ||
![]() |
ebc986f59c | ||
![]() |
dbed2f054f | ||
![]() |
f0238f6131 | ||
![]() |
76ba1e3297 | ||
![]() |
c02efd59b6 | ||
![]() |
dff71e2a86 | ||
![]() |
e1fad45f36 | ||
![]() |
b4d0991b11 | ||
![]() |
cd106d9025 | ||
![]() |
437f0cc5ca | ||
![]() |
64f699a9f2 | ||
![]() |
a14557bd88 | ||
![]() |
9fa4974641 | ||
![]() |
b5b08af71d | ||
![]() |
5bf10feb3c | ||
![]() |
f1452b1966 | ||
![]() |
2182ab205d | ||
![]() |
a3dba1258a | ||
![]() |
2c8efcc8d1 | ||
![]() |
e9c10bb0a0 | ||
![]() |
760a696c67 | ||
![]() |
4400f53a64 | ||
![]() |
f1e7d7d289 | ||
![]() |
0c066f5a3d | ||
![]() |
1c9d242968 | ||
![]() |
46f73ce302 | ||
![]() |
b77b8aeb22 | ||
![]() |
63b741cba7 | ||
![]() |
81a9f7179c | ||
![]() |
52f1852c55 | ||
![]() |
16e9a879f5 | ||
![]() |
d8265a14ed | ||
![]() |
febe0852a2 | ||
![]() |
ceb7d65471 | ||
![]() |
c5341374e5 | ||
![]() |
80796697ff | ||
![]() |
fb87f30828 | ||
![]() |
349840877c | ||
![]() |
1d4d713718 | ||
![]() |
965552fd4e | ||
![]() |
47d673fd55 | ||
![]() |
030fbe2da2 | ||
![]() |
32f5371311 | ||
![]() |
5d32bee351 | ||
![]() |
dfed8091ae | ||
![]() |
784f869e90 | ||
![]() |
0d8f3ba324 | ||
![]() |
a145b37f92 | ||
![]() |
1da1c619d9 | ||
![]() |
6d78e9e341 | ||
![]() |
b6aa18a064 | ||
![]() |
20b7c57d83 | ||
![]() |
8c8485359c | ||
![]() |
799347d9a6 | ||
![]() |
ef3d7b34e8 | ||
![]() |
a2e22fcc5c | ||
![]() |
4f169fa791 | ||
![]() |
db5053721b | ||
![]() |
e5c50c08db | ||
![]() |
d1edd8401c | ||
![]() |
a0c1de6f19 | ||
![]() |
6c2dc85637 | ||
![]() |
023a5d6172 | ||
![]() |
9e77c31ca6 | ||
![]() |
0bede459ec | ||
![]() |
e2713d09aa | ||
![]() |
98255953c7 | ||
![]() |
8ed539cbc0 | ||
![]() |
a164702f6e | ||
![]() |
600bd43478 | ||
![]() |
1590c96256 | ||
![]() |
455b071244 | ||
![]() |
e1f74d9671 | ||
![]() |
6a8483cdb7 | ||
![]() |
ae8298b824 | ||
![]() |
e8010bca4d | ||
![]() |
6a06256861 | ||
![]() |
7b4256377c | ||
![]() |
7e7ee6fc43 | ||
![]() |
7afe5ae09d | ||
![]() |
bc1eddfb64 | ||
![]() |
e8463db8ec | ||
![]() |
fda4498d63 | ||
![]() |
0030d64c13 | ||
![]() |
87a3053a92 | ||
![]() |
f859130b8c | ||
![]() |
7c2aa8a218 | ||
![]() |
56510c723e | ||
![]() |
146869417e | ||
![]() |
9fa987cb2d | ||
![]() |
e4f8b19f04 | ||
![]() |
aee0d5b9f8 | ||
![]() |
112f48d0c8 | ||
![]() |
ed843ee3b6 | ||
![]() |
a73ab97ddc | ||
![]() |
8ef3c3b3dc | ||
![]() |
ae270312ff | ||
![]() |
a01d7fae59 | ||
![]() |
64a93cce95 | ||
![]() |
1a7a312dda | ||
![]() |
8c94d74a16 | ||
![]() |
ff7206d03b | ||
![]() |
48668e34ed | ||
![]() |
2196456b43 | ||
![]() |
4f380948b2 | ||
![]() |
96628cbed3 | ||
![]() |
71b2b06980 | ||
![]() |
3a60521da6 | ||
![]() |
cf631a6528 | ||
![]() |
158511e204 | ||
![]() |
0c01eb0afd | ||
![]() |
d89d2d7d43 | ||
![]() |
9a83452c97 | ||
![]() |
6a064566df | ||
![]() |
4bc0d34c7d | ||
![]() |
9f070f8c84 | ||
![]() |
0463e6749d | ||
![]() |
76c9c2a7f0 | ||
![]() |
d4c5cfe8c7 | ||
![]() |
a7ef32c425 | ||
![]() |
a945d831d1 | ||
![]() |
cf2815191a | ||
![]() |
9323805bc2 | ||
![]() |
7e43dd14ed | ||
![]() |
6969beb07b | ||
![]() |
500caf0fb1 | ||
![]() |
7ae652a61d | ||
![]() |
a4b5a2e7ca | ||
![]() |
e8551d5ba1 | ||
![]() |
47e8625e6b | ||
![]() |
7780b9126b | ||
![]() |
37f169dd7b | ||
![]() |
6dc2d322e1 | ||
![]() |
3209dcd71b | ||
![]() |
d7609dd9ff | ||
![]() |
c8ee9a97e8 | ||
![]() |
7c9c409fdb | ||
![]() |
3c99252247 | ||
![]() |
46bec62530 | ||
![]() |
fa2a8ceee7 | ||
![]() |
147a67053f | ||
![]() |
7fe3e76a58 | ||
![]() |
f73c588caf | ||
![]() |
b9962e3bf2 | ||
![]() |
1dd1083244 | ||
![]() |
7b145a1f58 | ||
![]() |
02e96e04b4 | ||
![]() |
d944a17ba0 | ||
![]() |
6cc2614e71 | ||
![]() |
e11975f944 | ||
![]() |
80af02570c | ||
![]() |
bedd151dfc | ||
![]() |
a2829792ef | ||
![]() |
378fa50b47 | ||
![]() |
2dd8142ae2 | ||
![]() |
4bee54883a | ||
![]() |
60ce77a53e | ||
![]() |
62b2f96c51 | ||
![]() |
af101c3ced | ||
![]() |
05824807b2 | ||
![]() |
785f57ca2b | ||
![]() |
83c41e762a | ||
![]() |
dca257002b | ||
![]() |
e58c7dc8c1 | ||
![]() |
2616ed7a3e | ||
![]() |
dbe94c467a | ||
![]() |
192e88b212 | ||
![]() |
f294920410 | ||
![]() |
706bd9567d | ||
![]() |
747dee1b36 | ||
![]() |
3966365b5f | ||
![]() |
2301a029e2 | ||
![]() |
667d445a24 | ||
![]() |
b18fe7b4d2 | ||
![]() |
d7f44812d5 | ||
![]() |
a088e17e0e | ||
![]() |
d7ab7c28f4 | ||
![]() |
b8af32d874 | ||
![]() |
8bf588da8a | ||
![]() |
70a4413feb | ||
![]() |
83bd252b96 | ||
![]() |
7837b28d86 | ||
![]() |
6293b9a67e | ||
![]() |
fefc3c2fbc | ||
![]() |
55c0fd861b | ||
![]() |
59f24166ae | ||
![]() |
56f506babb | ||
![]() |
6459e9f22e | ||
![]() |
78418d607a | ||
![]() |
a6661833a7 | ||
![]() |
d2bc2e6915 | ||
![]() |
2f165df59c | ||
![]() |
3daef4a79d | ||
![]() |
ee6f5457bb | ||
![]() |
bec57bd955 | ||
![]() |
076507ee95 | ||
![]() |
8fc2877529 | ||
![]() |
9dcd9be5ba | ||
![]() |
0b500867e6 | ||
![]() |
e2d77d007c | ||
![]() |
5fdfffb790 | ||
![]() |
645afd6e28 | ||
![]() |
056a1141fd | ||
![]() |
e7ac7c90b6 | ||
![]() |
e4a775eda7 | ||
![]() |
1bd706fd1e | ||
![]() |
46fc35bf54 | ||
![]() |
958893b6e5 | ||
![]() |
0c580b88de | ||
![]() |
8d512f8a46 | ||
![]() |
a9e34948eb | ||
![]() |
96e313dcdb | ||
![]() |
17bfa5b657 | ||
![]() |
8c07c84356 | ||
![]() |
f000d0451c | ||
![]() |
60712ebe70 | ||
![]() |
d143d5cac6 | ||
![]() |
c02fcefc72 | ||
![]() |
62f91aba92 | ||
![]() |
8a396bc7b4 | ||
![]() |
0ce22f3d74 | ||
![]() |
2e0c561d55 | ||
![]() |
cdbe9e4dc4 | ||
![]() |
af54a58fab | ||
![]() |
0994e8a5b5 | ||
![]() |
98650e083e | ||
![]() |
8617fbb65a | ||
![]() |
6b04ba405a | ||
![]() |
8aef58b76f | ||
![]() |
96c811834f | ||
![]() |
2dcc5c9daf | ||
![]() |
71b35ce93e | ||
![]() |
9e2cfe105a | ||
![]() |
d0efe9c37e | ||
![]() |
1c83e0a252 | ||
![]() |
8ddff16569 | ||
![]() |
2db42953af | ||
![]() |
38f1b782f2 | ||
![]() |
70f0d32cea | ||
![]() |
904d7e21f1 | ||
![]() |
667f3fe6c9 | ||
![]() |
06d4ceafb2 | ||
![]() |
312c94813a | ||
![]() |
a9ef30e005 | ||
![]() |
f7c88f931b | ||
![]() |
0f2db4f02c | ||
![]() |
1fcc3da5fb | ||
![]() |
fff08b45a7 | ||
![]() |
6a8b34c10f | ||
![]() |
1e90bbd346 | ||
![]() |
6333bbf140 | ||
![]() |
dd0a4bf441 | ||
![]() |
0d70d6f611 | ||
![]() |
cbe8ed8ae0 | ||
![]() |
9cf2897af6 | ||
![]() |
8e1e31d879 | ||
![]() |
82efb9deda | ||
![]() |
a6cd1d68f2 | ||
![]() |
7c562f42e1 | ||
![]() |
8d365ecfd8 | ||
![]() |
574a8a1db6 | ||
![]() |
4500b5f810 | ||
![]() |
d170a76e44 | ||
![]() |
6d78349b91 | ||
![]() |
25ff16fc5b | ||
![]() |
1dde3f5810 | ||
![]() |
1136d383bb | ||
![]() |
e4c8145af5 | ||
![]() |
23455a16cd | ||
![]() |
2c61bb60a7 | ||
![]() |
7651235cb1 | ||
![]() |
244b1caf74 | ||
![]() |
8f229a6514 | ||
![]() |
49c6722ac1 | ||
![]() |
6315d59ff2 | ||
![]() |
ab72860f13 | ||
![]() |
6d6f657549 | ||
![]() |
1ebea8a7a2 | ||
![]() |
47bb633085 | ||
![]() |
b00a33f6aa | ||
![]() |
d4aef615e4 | ||
![]() |
641c1746be | ||
![]() |
ae522207b9 | ||
![]() |
fa530fdd5e | ||
![]() |
a44347f675 | ||
![]() |
837006f230 | ||
![]() |
374acaf6d3 | ||
![]() |
042af95c2c | ||
![]() |
d115792633 | ||
![]() |
916e8e7957 | ||
![]() |
12ad7ca119 | ||
![]() |
46ea1645b5 | ||
![]() |
2e30fa5a40 | ||
![]() |
a8a13451d2 | ||
![]() |
f8176d2f56 | ||
![]() |
97e09f9d78 | ||
![]() |
2a95f65915 | ||
![]() |
69d9538492 | ||
![]() |
198400035d | ||
![]() |
3c5ea6a70b | ||
![]() |
f09c564995 | ||
![]() |
6c62f5cdf6 | ||
![]() |
840e119945 | ||
![]() |
32d5da825f | ||
![]() |
8a3f83eee2 | ||
![]() |
d13c28487c | ||
![]() |
2e94967d65 | ||
![]() |
5bfabbf076 | ||
![]() |
20e31270fe | ||
![]() |
69298bb51e | ||
![]() |
f982fc95aa | ||
![]() |
ad08902e14 | ||
![]() |
778c59167a | ||
![]() |
778f7d74f3 | ||
![]() |
a874a50bcb | ||
![]() |
3f775fc524 | ||
![]() |
71fd6fc70b | ||
![]() |
f175ce3d68 | ||
![]() |
78d5c10d05 | ||
![]() |
1cdfefb93f | ||
![]() |
a21cdc1d5e | ||
![]() |
9a6989797b | ||
![]() |
69f6893091 | ||
![]() |
506ba0ef28 | ||
![]() |
f0d8738852 | ||
![]() |
f68d651a28 | ||
![]() |
fe96df1856 | ||
![]() |
7f588ea6f2 | ||
![]() |
c10554d6b5 | ||
![]() |
071eff1a8b | ||
![]() |
75878011c7 | ||
![]() |
295b2786d6 | ||
![]() |
510d7e204a | ||
![]() |
753b982499 | ||
![]() |
7c72526781 | ||
![]() |
fcf79023bd | ||
![]() |
c016b727a7 | ||
![]() |
a4b9dbca80 | ||
![]() |
d8e666e45f | ||
![]() |
c3d7e2d17a | ||
![]() |
f7f5ae3d30 | ||
![]() |
38e34eb34b | ||
![]() |
cd6c4210f3 | ||
![]() |
54969ef32b | ||
![]() |
24b8206a44 | ||
![]() |
89fc197809 | ||
![]() |
3048e8528c | ||
![]() |
1e74ea19d9 | ||
![]() |
625a3125c6 | ||
![]() |
67d807d059 | ||
![]() |
a1002a1b1b | ||
![]() |
bc6bca802c | ||
![]() |
744a00dc5a | ||
![]() |
f759c11a9e | ||
![]() |
37d9e63982 | ||
![]() |
fe8e10d6ef | ||
![]() |
22595a4464 | ||
![]() |
5c2919e937 | ||
![]() |
67fc48d204 | ||
![]() |
ff0971c1f7 | ||
![]() |
213a0e1fff | ||
![]() |
4b79612b8c | ||
![]() |
fd742d162b | ||
![]() |
a0641b0657 | ||
![]() |
53d25b88e6 | ||
![]() |
8414e8261a | ||
![]() |
5146b9dbc6 | ||
![]() |
f02f3b64d1 | ||
![]() |
f08b752109 | ||
![]() |
792520015f | ||
![]() |
de569caf47 | ||
![]() |
ecff1b7739 | ||
![]() |
09b1de5a98 | ||
![]() |
e39ab51a85 | ||
![]() |
0f8c622185 | ||
![]() |
351136f31d | ||
![]() |
b64631cf14 | ||
![]() |
d8df075beb | ||
![]() |
6f7437d56a | ||
![]() |
24d34453f4 | ||
![]() |
0f2bfe532d | ||
![]() |
ebc3540a8a | ||
![]() |
c3b208bd45 | ||
![]() |
f0025d6256 | ||
![]() |
5f2cdf2502 | ||
![]() |
8e30c9af30 | ||
![]() |
6806cb99d3 | ||
![]() |
fc5d779e2c | ||
![]() |
de52e31500 | ||
![]() |
95a94a79b4 | ||
![]() |
38507abde6 | ||
![]() |
94dfddaa4d | ||
![]() |
4b375651b7 | ||
![]() |
1b7936ed9b | ||
![]() |
0d7c28c3c9 | ||
![]() |
13c2521ca6 | ||
![]() |
85b282daec | ||
![]() |
37e7b40a34 | ||
![]() |
93343903da | ||
![]() |
3f4cae61b7 | ||
![]() |
8b39ab974a | ||
![]() |
e42ab04328 | ||
![]() |
de41fed559 | ||
![]() |
99ce247eef | ||
![]() |
b1e7c37db4 | ||
![]() |
00fbe4799e | ||
![]() |
6c2a8338b0 | ||
![]() |
40b426305a | ||
![]() |
463acc70d3 | ||
![]() |
6358bfc509 | ||
![]() |
ac3cbbd08c | ||
![]() |
0b493a7306 | ||
![]() |
51b112c350 | ||
![]() |
7bd3bb1f5f | ||
![]() |
bc86eb0ec7 | ||
![]() |
cd8607311d | ||
![]() |
1d34ad2f7d | ||
![]() |
53949672a7 | ||
![]() |
82371dfd2c | ||
![]() |
63eb47a51e | ||
![]() |
e2a72ab548 | ||
![]() |
7ab78802f3 | ||
![]() |
b769572d6b | ||
![]() |
2222807eb7 | ||
![]() |
4c0c29c5c6 | ||
![]() |
c1e2dd914f | ||
![]() |
95c2b3bc86 | ||
![]() |
7e45b0fb06 | ||
![]() |
8efa9dd527 | ||
![]() |
d5f6200e64 | ||
![]() |
7b43939f64 | ||
![]() |
9b821e17fc | ||
![]() |
353843cd74 | ||
![]() |
50b3088248 | ||
![]() |
48852e2b2a | ||
![]() |
1430ab34cd | ||
![]() |
85cf839c5a | ||
![]() |
e7e60b7972 | ||
![]() |
a2595b15f7 | ||
![]() |
17faaf13bb | ||
![]() |
5b1adf9fd6 | ||
![]() |
acdd1d7fd9 | ||
![]() |
be81b7a533 | ||
![]() |
81758ddfe1 | ||
![]() |
abcdb64600 | ||
![]() |
4b8fa139b0 | ||
![]() |
bf35095fec | ||
![]() |
d869c79866 | ||
![]() |
7b96e22296 | ||
![]() |
33e84cdc01 | ||
![]() |
a6f4c318ec | ||
![]() |
e340969718 | ||
![]() |
79d810cf4a | ||
![]() |
0783b86407 | ||
![]() |
445339e1a3 | ||
![]() |
1565eda515 | ||
![]() |
de4c50efdc | ||
![]() |
bf0008701b | ||
![]() |
e83ba18e9a | ||
![]() |
1f14252fcc | ||
![]() |
38685df63a | ||
![]() |
15e8200a69 | ||
![]() |
666a8d556e | ||
![]() |
79c43130b2 | ||
![]() |
a3fc321961 | ||
![]() |
50feb42b13 | ||
![]() |
ca8d8f91b6 | ||
![]() |
bd5181a8af | ||
![]() |
625c83ee20 | ||
![]() |
1769544149 | ||
![]() |
293b0bad55 | ||
![]() |
84f7afe846 | ||
![]() |
3bc109d00e | ||
![]() |
5e99830add | ||
![]() |
fbb778b6c4 | ||
![]() |
d3b301f647 | ||
![]() |
4ff119e500 | ||
![]() |
545f95d3cd | ||
![]() |
6db579d1be | ||
![]() |
41ba1399e7 | ||
![]() |
0c06c3f8eb | ||
![]() |
b06265cacc | ||
![]() |
8decbfe95a | ||
![]() |
745857acf4 | ||
![]() |
ea10733366 | ||
![]() |
77806182ea | ||
![]() |
c5d52a3779 | ||
![]() |
fdb8c91435 | ||
![]() |
7c3e5c0d21 | ||
![]() |
bd9d32ea22 | ||
![]() |
acdfef4bb2 | ||
![]() |
f43c9e6b8d | ||
![]() |
6d72081a63 | ||
![]() |
e95174ddf9 | ||
![]() |
416f9e0645 | ||
![]() |
adcd4d94d9 | ||
![]() |
2c6c3b72ce | ||
![]() |
86216ba908 | ||
![]() |
fe1591e0da | ||
![]() |
8592e5caea | ||
![]() |
6845c317b7 | ||
![]() |
526f6ae62f | ||
![]() |
91fa684344 | ||
![]() |
9cec224f78 | ||
![]() |
15b22a5495 | ||
![]() |
624061cd4c | ||
![]() |
7f73ceab50 | ||
![]() |
bfaff65351 | ||
![]() |
9a428885ee | ||
![]() |
251596a822 | ||
![]() |
dc967e06e8 | ||
![]() |
6587739196 | ||
![]() |
f43ebd5537 | ||
![]() |
91c61fc239 | ||
![]() |
29355786a9 | ||
![]() |
d3f5a1400d | ||
![]() |
565ef44373 | ||
![]() |
ba0963d98b | ||
![]() |
e0ecb68386 | ||
![]() |
ecfbaa5a08 | ||
![]() |
11fbafff30 | ||
![]() |
6b53e7e557 | ||
![]() |
054edeae3c | ||
![]() |
5f1be433da | ||
![]() |
a490db819d | ||
![]() |
4314560401 | ||
![]() |
7fc0fa60c8 | ||
![]() |
8b0dc42e84 | ||
![]() |
e452cb0285 | ||
![]() |
8493a0353e | ||
![]() |
de53877231 | ||
![]() |
ab8610d064 | ||
![]() |
771dd91a5b | ||
![]() |
18309bdd06 | ||
![]() |
d2a7ca1d55 | ||
![]() |
44afb8e82a | ||
![]() |
958ccd8d71 | ||
![]() |
b7d6cbde0a | ||
![]() |
196bb2cded | ||
![]() |
3accb89b56 | ||
![]() |
1266007000 | ||
![]() |
612e052821 | ||
![]() |
8cacc0be9a | ||
![]() |
d17ecdce35 | ||
![]() |
74ec67f40c | ||
![]() |
f6e8a7839a | ||
![]() |
f96ea6da92 | ||
![]() |
59742e4b93 | ||
![]() |
d4e7c21769 | ||
![]() |
768fe00b8b | ||
![]() |
ac8b900d88 | ||
![]() |
dd19b5ba5c | ||
![]() |
dca945f478 | ||
![]() |
86d8352a5e | ||
![]() |
c402d70961 | ||
![]() |
fdfd4a89b6 | ||
![]() |
22284231d0 | ||
![]() |
823f5d516e | ||
![]() |
940f32a42c | ||
![]() |
22b7ca3f5c | ||
![]() |
d647bbfa0f | ||
![]() |
d16322bc46 | ||
![]() |
3039318fdb | ||
![]() |
d433eeca98 | ||
![]() |
3301759925 | ||
![]() |
f727b166ad | ||
![]() |
642dad295c | ||
![]() |
ee2af5946d | ||
![]() |
c7f056e0d5 | ||
![]() |
3187f5bea3 | ||
![]() |
d6afc7a49c | ||
![]() |
cf813d9fb1 | ||
![]() |
853f964049 | ||
![]() |
ca1623b9ac | ||
![]() |
2e5dc82836 | ||
![]() |
d64fc9f9fa | ||
![]() |
d4a1abc526 | ||
![]() |
16c90c8467 | ||
![]() |
567e819b97 | ||
![]() |
1d2e443a08 | ||
![]() |
0d0d77be3a | ||
![]() |
2f88540080 | ||
![]() |
6bf8088807 | ||
![]() |
0f0c783891 | ||
![]() |
3963519bf2 | ||
![]() |
67da033cf1 | ||
![]() |
3e256e856b | ||
![]() |
629cbec3f3 | ||
![]() |
abf06a3f28 | ||
![]() |
dffa21b34f | ||
![]() |
03deb76ab9 | ||
![]() |
61ea96cecb | ||
![]() |
3a615909d5 | ||
![]() |
d21253c5d4 | ||
![]() |
e7ea1041df | ||
![]() |
0cd5c1e158 | ||
![]() |
becfb1a231 | ||
![]() |
4c4e550ace | ||
![]() |
5a57313816 | ||
![]() |
6ca4f9040f | ||
![]() |
2d6e57ef88 | ||
![]() |
788431c1ed | ||
![]() |
9419ec4912 | ||
![]() |
322a929b56 | ||
![]() |
6d0b49c507 | ||
![]() |
40356f0fc2 | ||
![]() |
987a8a2721 | ||
![]() |
68549482ec | ||
![]() |
c6e093a5ca | ||
![]() |
824f4f7a73 | ||
![]() |
ec34b3a4f8 | ||
![]() |
b682a90f1f | ||
![]() |
717a16c8c7 | ||
![]() |
dabf46f7ff | ||
![]() |
cf4f03e540 | ||
![]() |
f1f505495d | ||
![]() |
dadb6fd838 | ||
![]() |
8b41a0a09e | ||
![]() |
c70b8a78bd | ||
![]() |
77c19cc65b | ||
![]() |
6b1b62d35e | ||
![]() |
c36f4f00ea | ||
![]() |
c4f029ce86 | ||
![]() |
cadf1c1683 | ||
![]() |
262cb665c4 | ||
![]() |
d2092cfed5 | ||
![]() |
1b473dae29 | ||
![]() |
f6f17973b7 | ||
![]() |
956afbff93 | ||
![]() |
05d8734667 | ||
![]() |
5d0407caa7 | ||
![]() |
5ec1a193b6 | ||
![]() |
263ae33f12 | ||
![]() |
089d3f6ab6 | ||
![]() |
b27d5851a1 | ||
![]() |
c65cdad265 | ||
![]() |
2182c91790 | ||
![]() |
0cd3cbb9e3 | ||
![]() |
0ba92f9001 | ||
![]() |
d180022809 | ||
![]() |
a5138e9a4c | ||
![]() |
f9a6de8942 | ||
![]() |
21bd2a1e27 | ||
![]() |
5553446139 | ||
![]() |
1a7e5834f5 | ||
![]() |
a0d1c0772d | ||
![]() |
ac0d103fe1 | ||
![]() |
19b9524784 | ||
![]() |
2553c2d620 | ||
![]() |
1c234a394a | ||
![]() |
bd5b9d0a50 | ||
![]() |
ace4c209ed | ||
![]() |
cf315ff81f | ||
![]() |
5760c592ed | ||
![]() |
d9d1f3f7de | ||
![]() |
3647848786 | ||
![]() |
f957d263a4 | ||
![]() |
9ac9d746cc | ||
![]() |
b222f1b020 | ||
![]() |
4efeece278 | ||
![]() |
4de3f44d16 | ||
![]() |
3693896060 | ||
![]() |
37fee6d168 | ||
![]() |
ad960eb423 | ||
![]() |
545fb469b1 | ||
![]() |
7bc0456cc7 | ||
![]() |
4cf59e2947 | ||
![]() |
8e20d0e14c | ||
![]() |
ca8f93fcc8 | ||
![]() |
7a91835f58 | ||
![]() |
5caa19baec | ||
![]() |
b160be7f7f | ||
![]() |
da0455a8d5 | ||
![]() |
6c03db8f8d | ||
![]() |
eff8e0d07f | ||
![]() |
70b4018cd6 | ||
![]() |
5bbeb20dc0 | ||
![]() |
c8534bba21 | ||
![]() |
747f5ef905 | ||
![]() |
a9523d8152 | ||
![]() |
7d8bbb2110 | ||
![]() |
8c813619f4 | ||
![]() |
98835e8dcb | ||
![]() |
8d927cf66b | ||
![]() |
f281217040 | ||
![]() |
6e44132a54 | ||
![]() |
041f2fe8d4 | ||
![]() |
3a779b0e13 | ||
![]() |
465c6e6b23 | ||
![]() |
3752ea9176 | ||
![]() |
5983837425 | ||
![]() |
4e9a860b90 | ||
![]() |
096849d830 | ||
![]() |
dcc90efc0f | ||
![]() |
e3e594c934 | ||
![]() |
dac6a96f5b | ||
![]() |
75a8fff644 | ||
![]() |
faa962ce75 | ||
![]() |
3b0454c72b | ||
![]() |
7374a96fb2 | ||
![]() |
4fd0cda00c | ||
![]() |
509b2d32b0 | ||
![]() |
e7d09818cc | ||
![]() |
a479489d1f | ||
![]() |
7d4a561b03 | ||
![]() |
b90e6d3920 | ||
![]() |
45de4070ec | ||
![]() |
70964cd4a8 | ||
![]() |
059e8c016a | ||
![]() |
2a7d05d632 | ||
![]() |
5275beb10e | ||
![]() |
3093ac5b4e | ||
![]() |
b8398fcfc5 | ||
![]() |
73033b301e | ||
![]() |
2083e45ddd | ||
![]() |
3ef9696a24 | ||
![]() |
4e1a5d2f3a | ||
![]() |
05139bd31a | ||
![]() |
1e66acb854 | ||
![]() |
216f2b12bd | ||
![]() |
b6dd463b46 | ||
![]() |
e874b68a57 | ||
![]() |
ddd59c794f | ||
![]() |
7bd03acd92 | ||
![]() |
23c474289e | ||
![]() |
06bf5ff33e | ||
![]() |
e2dacb08f5 | ||
![]() |
659e1aafc7 | ||
![]() |
17e8acbb02 | ||
![]() |
b82ce5b75b | ||
![]() |
67888f84b0 | ||
![]() |
51d0d54039 | ||
![]() |
9c69cac678 | ||
![]() |
59a4ca8ff2 | ||
![]() |
5874e791ee | ||
![]() |
20e8e541fb | ||
![]() |
b323b591f7 | ||
![]() |
c79f2a6ac9 | ||
![]() |
f30584ef66 | ||
![]() |
ad3bfa209d | ||
![]() |
02432cb8f5 | ||
![]() |
c25f6bc608 | ||
![]() |
2de9cc178a | ||
![]() |
f8248df955 | ||
![]() |
3ee0eeba64 | ||
![]() |
4eb71e6a94 | ||
![]() |
781d2679a9 | ||
![]() |
e73252e9b7 | ||
![]() |
e425f1326c | ||
![]() |
35af89562f | ||
![]() |
75c0771c2d | ||
![]() |
a7ea6cf5d5 | ||
![]() |
e6199ca47f | ||
![]() |
443a9a2bf8 | ||
![]() |
4483d83aef | ||
![]() |
1c437b7748 | ||
![]() |
5b216e5eec | ||
![]() |
8d0a785cae | ||
![]() |
cee1221a03 | ||
![]() |
1dc2f95ed7 | ||
![]() |
2f9d6623e0 | ||
![]() |
ac3f36d3f1 | ||
![]() |
4947a6be67 | ||
![]() |
fb5b9397d2 | ||
![]() |
8d388841b5 | ||
![]() |
5890136b1a | ||
![]() |
657a03b623 | ||
![]() |
1370cb65b5 | ||
![]() |
23c3894980 | ||
![]() |
5ffd98e4f1 | ||
![]() |
f1ee779476 | ||
![]() |
c62d5337f3 | ||
![]() |
879b9b9cbe | ||
![]() |
eb5fd185a5 | ||
![]() |
07dc0c1f16 | ||
![]() |
5edd080e92 | ||
![]() |
bbb8438336 | ||
![]() |
b471d71f76 | ||
![]() |
9a8a24d768 | ||
![]() |
a3b0fab8ea | ||
![]() |
a598df15b5 | ||
![]() |
314269c95b | ||
![]() |
713bd1500c | ||
![]() |
4444576387 | ||
![]() |
dedcc19e95 | ||
![]() |
81348a4b6a | ||
![]() |
dac4ab6296 | ||
![]() |
9c98f12388 | ||
![]() |
c7f1da06ed | ||
![]() |
0caaabba9f | ||
![]() |
7392c7a0dd | ||
![]() |
cb3445e051 | ||
![]() |
22d469ffa9 | ||
![]() |
70b66ee60b | ||
![]() |
3eed5f66f1 | ||
![]() |
8bb65158b6 | ||
![]() |
e02b0f2c03 | ||
![]() |
979b62a06b | ||
![]() |
d27d4900f3 | ||
![]() |
8c0c443709 | ||
![]() |
42e2bfbe1e | ||
![]() |
2df18ca784 | ||
![]() |
2c003f37b2 | ||
![]() |
c3755a5d75 | ||
![]() |
85f79b5194 | ||
![]() |
a8224e988b | ||
![]() |
bdf96c6eb7 | ||
![]() |
f1421fa497 | ||
![]() |
5b8c0dea8a | ||
![]() |
43d1fb4b37 | ||
![]() |
84194e7a95 | ||
![]() |
4cee6d0574 | ||
![]() |
b4d03da9f5 | ||
![]() |
e32a405c8a | ||
![]() |
9f58a242c4 | ||
![]() |
4be8a48601 | ||
![]() |
b8178b0f48 | ||
![]() |
1e8f6dd1bf | ||
![]() |
c272e2a002 | ||
![]() |
0f8ad5ff6b | ||
![]() |
81c905fd77 | ||
![]() |
d340ab3fa8 | ||
![]() |
e50513bda7 | ||
![]() |
5703f198d1 | ||
![]() |
054594aef2 | ||
![]() |
851a40106c | ||
![]() |
704b4da124 | ||
![]() |
fe64c71c25 | ||
![]() |
dcebe39dd6 | ||
![]() |
4f4e2d73a2 | ||
![]() |
448c2c0811 | ||
![]() |
ad710193fd | ||
![]() |
0c85fd507b | ||
![]() |
cbceb9245a | ||
![]() |
e9bc958499 | ||
![]() |
2c3934565b | ||
![]() |
7a33337639 | ||
![]() |
6feb0090bb | ||
![]() |
74c0e3c342 | ||
![]() |
f8d222535f | ||
![]() |
e460bcfb90 | ||
![]() |
beaf6851e0 | ||
![]() |
833b6d666e | ||
![]() |
f71c36406a | ||
![]() |
f3ad9625ea | ||
![]() |
07cb212b0e | ||
![]() |
4f2b2dae9d | ||
![]() |
9ff97a65de | ||
![]() |
d3171ea585 | ||
![]() |
fe290342a9 | ||
![]() |
d282bc24d8 | ||
![]() |
86037b8bdc | ||
![]() |
d0942bc35d | ||
![]() |
495ad8d054 | ||
![]() |
35e7ed0493 | ||
![]() |
7057c85c17 | ||
![]() |
8c4a6b578c | ||
![]() |
2f9a90fddc | ||
![]() |
9b34d44fa2 | ||
![]() |
09a7c20ab1 | ||
![]() |
42345f1031 | ||
![]() |
42122adcd1 | ||
![]() |
021a243597 | ||
![]() |
3bbc1ea758 | ||
![]() |
734122f675 | ||
![]() |
2074f43f67 | ||
![]() |
1686feb4c6 | ||
![]() |
9febc8943c | ||
![]() |
494d43ba33 | ||
![]() |
54478374bf | ||
![]() |
8b9842cd55 | ||
![]() |
5b3eccd47d | ||
![]() |
29ff93c9ca | ||
![]() |
b1ef2a509e | ||
![]() |
018f99e331 | ||
![]() |
ac0273130a | ||
![]() |
ca9f4cda7d | ||
![]() |
206cb66c4f | ||
![]() |
870a8a2aa5 | ||
![]() |
2b8db25e37 | ||
![]() |
e34ccc8059 | ||
![]() |
bfcfd0e556 | ||
![]() |
18bfff308b | ||
![]() |
796eebb096 | ||
![]() |
b957fe12d6 | ||
![]() |
e80b267e6e | ||
![]() |
98db12d6d2 | ||
![]() |
9d6ca6875d | ||
![]() |
84c4e41607 | ||
![]() |
ef0abeec2a | ||
![]() |
3e3d88bc96 | ||
![]() |
f9ace9bd8e | ||
![]() |
75bbfc2506 | ||
![]() |
a683156eb0 | ||
![]() |
3490bcfdff | ||
![]() |
cdb291299c | ||
![]() |
b460f58ee2 | ||
![]() |
f3d3244afc | ||
![]() |
33d35816e0 | ||
![]() |
5d4864927a | ||
![]() |
0501c57958 | ||
![]() |
7df81716b3 | ||
![]() |
5da06b0f65 | ||
![]() |
f014c75e90 | ||
![]() |
db655f3979 | ||
![]() |
ccbd64293f | ||
![]() |
27637d9f13 | ||
![]() |
bdacf68e41 | ||
![]() |
e350ac9b21 | ||
![]() |
a9a09668f2 | ||
![]() |
9ce501020d | ||
![]() |
6d8bb31620 | ||
![]() |
031c1976fd | ||
![]() |
66608456b6 | ||
![]() |
e85492c137 | ||
![]() |
0644d54ede | ||
![]() |
2994407c22 | ||
![]() |
431361b991 | ||
![]() |
430123ace2 | ||
![]() |
24a8dda6a6 | ||
![]() |
1f42d83384 | ||
![]() |
7a3e6c9d4e | ||
![]() |
03d8e00c14 | ||
![]() |
3552410044 | ||
![]() |
bd30dbb4a7 | ||
![]() |
0d1912de54 | ||
![]() |
fc39f1ed2a | ||
![]() |
218788fbd4 | ||
![]() |
f8af5ba8ba | ||
![]() |
49334bc08f | ||
![]() |
dbb7821475 | ||
![]() |
29ce39e573 | ||
![]() |
940a2d1f24 | ||
![]() |
e1b69e8417 | ||
![]() |
327dc523c0 | ||
![]() |
4c5f46f2e2 | ||
![]() |
a80483cde2 | ||
![]() |
4db9e44493 | ||
![]() |
5619d9ff4d | ||
![]() |
6e2ad52a4f | ||
![]() |
e2c54a1468 | ||
![]() |
f8ccb79fc8 | ||
![]() |
6aab8636d4 | ||
![]() |
5d980f6444 | ||
![]() |
26e728a170 | ||
![]() |
0031c3c37c | ||
![]() |
1d75f52b49 | ||
![]() |
bbf1796ec4 | ||
![]() |
bd9df6b027 | ||
![]() |
a5eb48e991 | ||
![]() |
8fe4772608 | ||
![]() |
d9289a33c5 | ||
![]() |
b98b60d92d | ||
![]() |
60d7c3addc | ||
![]() |
1f4d70f934 | ||
![]() |
0848e5967f | ||
![]() |
cee213b8e3 | ||
![]() |
14e205a9a9 | ||
![]() |
706f6188a0 | ||
![]() |
34b787bd4f | ||
![]() |
66c5a2ff27 | ||
![]() |
c66e27e371 | ||
![]() |
0341d2cf72 | ||
![]() |
545e8856ba | ||
![]() |
9f709aeef4 | ||
![]() |
f9c5139b06 | ||
![]() |
e50405768a | ||
![]() |
7c9df522ef | ||
![]() |
ff903c5f35 | ||
![]() |
208d330887 | ||
![]() |
ba7db76a39 | ||
![]() |
82a1548736 | ||
![]() |
feed907fc3 | ||
![]() |
3e71941209 | ||
![]() |
43ff49a2e3 | ||
![]() |
3d02716e45 | ||
![]() |
1bd7de5f93 | ||
![]() |
b5bdec9bf2 | ||
![]() |
dc4a5b49ff | ||
![]() |
8409170ebb | ||
![]() |
8f3d980401 | ||
![]() |
31ea6e68bd | ||
![]() |
2be52570b2 | ||
![]() |
cdab8896e7 | ||
![]() |
313a01cfed | ||
![]() |
9c5521ae45 | ||
![]() |
1a95587a3a | ||
![]() |
2e4757d500 | ||
![]() |
d85b1f2386 | ||
![]() |
75019cbc12 | ||
![]() |
fce2ae2138 | ||
![]() |
818b1a6e51 | ||
![]() |
b1107631a8 | ||
![]() |
427aac8a3b | ||
![]() |
a0109b0172 | ||
![]() |
41c5fe1a9c | ||
![]() |
082c049089 | ||
![]() |
f71c62c60b | ||
![]() |
59edda94a6 | ||
![]() |
355c108554 | ||
![]() |
30d736c43e | ||
![]() |
0dfbe04f92 | ||
![]() |
1bb8767254 | ||
![]() |
f006c5ce37 | ||
![]() |
5d342c34f0 | ||
![]() |
0ede25ef25 | ||
![]() |
bac579c9a0 | ||
![]() |
8e7b68c6bf | ||
![]() |
100bd52179 | ||
![]() |
e81f901967 | ||
![]() |
e8a8c9fdcd | ||
![]() |
a0fe3d626f | ||
![]() |
f60ffba94b | ||
![]() |
8501b5cf00 | ||
![]() |
6fd6a1e8d9 | ||
![]() |
2e41ff0b7b | ||
![]() |
5b267e3889 | ||
![]() |
f751759755 | ||
![]() |
b849fdb173 | ||
![]() |
80eb74cd84 | ||
![]() |
acb24efa88 | ||
![]() |
88150eeacf | ||
![]() |
7f50e61591 | ||
![]() |
9b1adaf085 | ||
![]() |
d7915ab6ce | ||
![]() |
7a4c80ab0d | ||
![]() |
130688478e | ||
![]() |
bd2d3ccde9 | ||
![]() |
ea33fd6472 | ||
![]() |
859bba8fe2 | ||
![]() |
31e5e6ce1a | ||
![]() |
1b08941c00 | ||
![]() |
4ce320d56a | ||
![]() |
50cacea9ef | ||
![]() |
fa22d27743 | ||
![]() |
e5e088372d | ||
![]() |
f78b3a61fe | ||
![]() |
f344914e86 | ||
![]() |
99a6e8145e | ||
![]() |
f3c1eccf60 | ||
![]() |
dee12ced09 | ||
![]() |
ba100b7394 | ||
![]() |
0371ce7631 | ||
![]() |
d56d0867b1 | ||
![]() |
2c1577e4b7 | ||
![]() |
f76dd18375 | ||
![]() |
2c7280e04c | ||
![]() |
774fa72004 | ||
![]() |
658629ed3a | ||
![]() |
d49419a438 | ||
![]() |
9b8f9467b3 | ||
![]() |
b0accb0fd4 | ||
![]() |
e9fd2c039d | ||
![]() |
e1d04b4e28 | ||
![]() |
71ee0d772f | ||
![]() |
8dabb618d0 | ||
![]() |
1eb872bdf5 | ||
![]() |
59561f78a2 | ||
![]() |
315cbf4130 | ||
![]() |
783ece712c | ||
![]() |
d27742257b | ||
![]() |
d1a9081d5e | ||
![]() |
67c7d89304 | ||
![]() |
b879d8d9bc | ||
![]() |
e19506646a | ||
![]() |
9ee9cf8e3f | ||
![]() |
a206c1ffbe | ||
![]() |
69c608c1f8 | ||
![]() |
ddaa63e73f | ||
![]() |
3baa781c78 | ||
![]() |
ef4f320823 | ||
![]() |
1600ab772e | ||
![]() |
01e871b029 | ||
![]() |
546724f8fe | ||
![]() |
2b1ff48664 | ||
![]() |
2b84214be3 | ||
![]() |
215a48f43a | ||
![]() |
17f166c235 | ||
![]() |
3cbad4b269 | ||
![]() |
329595eaca | ||
![]() |
fc3a4ff18d | ||
![]() |
6354403a57 | ||
![]() |
58ab4b21aa | ||
![]() |
bb9132d80a | ||
![]() |
72738328f4 | ||
![]() |
a5589db366 | ||
![]() |
faa14e08c3 | ||
![]() |
af37e1e127 | ||
![]() |
29cb86f051 | ||
![]() |
b94c8a778e | ||
![]() |
16a6a43e3d | ||
![]() |
7923eb1f98 | ||
![]() |
a60b34c180 | ||
![]() |
d9f9d33874 | ||
![]() |
82355a0c44 | ||
![]() |
4a2b409b0a | ||
![]() |
87bbbca5d0 | ||
![]() |
54aebf1eb7 | ||
![]() |
fb2a5c4e15 | ||
![]() |
e400b8bc6f | ||
![]() |
fe76136cb1 | ||
![]() |
815c542bd3 | ||
![]() |
d2508837d9 | ||
![]() |
5783033bf8 | ||
![]() |
6f4c76cf16 | ||
![]() |
a1066e2cec | ||
![]() |
6af5ad6954 | ||
![]() |
b2392719ec | ||
![]() |
ecf4927dcb | ||
![]() |
10c7b535d4 | ||
![]() |
277a37856e | ||
![]() |
1b196a181e | ||
![]() |
3943eb8180 | ||
![]() |
210b96ebf6 | ||
![]() |
36da7eeef1 | ||
![]() |
e7425d16cc | ||
![]() |
8f4f88842a | ||
![]() |
862db060ce | ||
![]() |
77f8f42392 | ||
![]() |
36b9195cee | ||
![]() |
085e808fdc | ||
![]() |
b9180699c7 | ||
![]() |
b957bf4c7f | ||
![]() |
ea26a8932b | ||
![]() |
a93a11273b | ||
![]() |
b27fe480fd | ||
![]() |
5de25f9eb8 | ||
![]() |
276a9cbd4c | ||
![]() |
0eefa267db | ||
![]() |
cb8982c6c1 | ||
![]() |
2b379eae9d | ||
![]() |
4344fc5e63 | ||
![]() |
7eb992cb30 | ||
![]() |
98b79dd3a1 | ||
![]() |
3c7ef960c8 | ||
![]() |
05000d400f | ||
![]() |
b0c534a0c2 | ||
![]() |
28a97c4837 | ||
![]() |
1c774bbbb6 | ||
![]() |
ee3f90c5db | ||
![]() |
fa5d9cadfb | ||
![]() |
05defa2cd9 | ||
![]() |
a1e1bf5179 | ||
![]() |
7d8b0e50e3 | ||
![]() |
cbe49c2797 | ||
![]() |
cd55ef7393 | ||
![]() |
08c6caf832 | ||
![]() |
a0bb5af60c | ||
![]() |
c6310238ef | ||
![]() |
dc10a49e14 | ||
![]() |
05412bd091 | ||
![]() |
20261e2740 | ||
![]() |
a0e278a5b4 | ||
![]() |
20a927a07c | ||
![]() |
da23a87fc6 | ||
![]() |
82a1d43978 | ||
![]() |
84506d894f | ||
![]() |
c3da7e8c68 | ||
![]() |
d25710fb9f | ||
![]() |
2e2433ef99 | ||
![]() |
af5065f3a2 | ||
![]() |
43a878d8d9 | ||
![]() |
8947b724f3 | ||
![]() |
917269daa3 | ||
![]() |
de61ea989f | ||
![]() |
e838296c88 | ||
![]() |
28379144e6 | ||
![]() |
19d8315845 | ||
![]() |
8ed8bf384c | ||
![]() |
1432630327 | ||
![]() |
0c7eb5b8fb | ||
![]() |
0b8d842150 | ||
![]() |
00d144edbf | ||
![]() |
d3982ff08c | ||
![]() |
893b680a42 | ||
![]() |
825696e201 | ||
![]() |
d7aeef5d31 | ||
![]() |
8a46daa61a | ||
![]() |
ae81bd95f0 | ||
![]() |
852b5c689e | ||
![]() |
80c9f76afb | ||
![]() |
835e2221a9 | ||
![]() |
8a581f5392 | ||
![]() |
3cb4d85094 | ||
![]() |
8d555cda2b | ||
![]() |
4adc65c9f9 | ||
![]() |
e4089d8cf8 | ||
![]() |
f2aff0fc87 | ||
![]() |
c1d050248e | ||
![]() |
9a8fd06e27 | ||
![]() |
b6c350a6e8 | ||
![]() |
929b7bdc61 | ||
![]() |
640718f5a6 | ||
![]() |
6d26f2ca17 | ||
![]() |
61f7869faf | ||
![]() |
e0d9d76bb9 | ||
![]() |
5636b6cc77 | ||
![]() |
1874a4b7ee | ||
![]() |
dc7d5e8b39 | ||
![]() |
70dbb9005d | ||
![]() |
c2000a39dc | ||
![]() |
b4d1fa75ec | ||
![]() |
36b1f37ff7 | ||
![]() |
299d03f1e7 | ||
![]() |
2ad053ca46 | ||
![]() |
0c9901d36d | ||
![]() |
a49ffb26fd | ||
![]() |
3599f5b47f | ||
![]() |
9bf4bafb63 | ||
![]() |
d4aee96f96 | ||
![]() |
035562af7d | ||
![]() |
a3397cc767 | ||
![]() |
6247941272 | ||
![]() |
fb64086f8e | ||
![]() |
cb5b6954c6 | ||
![]() |
0f37ca78d9 | ||
![]() |
27e592e7e4 | ||
![]() |
aac0e43882 | ||
![]() |
ef9e80e37f | ||
![]() |
a97759ef4c | ||
![]() |
23f031aa8d | ||
![]() |
9ea3a6d9f0 | ||
![]() |
f6882001a0 | ||
![]() |
ab76e1e8bf | ||
![]() |
25fab7f98e | ||
![]() |
b54da41435 | ||
![]() |
000e0e02c9 | ||
![]() |
d74a047eff | ||
![]() |
51d41dba08 | ||
![]() |
36dc647ddd | ||
![]() |
1b8024a191 | ||
![]() |
df82fc595a | ||
![]() |
5d71adf373 | ||
![]() |
b72a278dc9 | ||
![]() |
4822558a9a | ||
![]() |
e78c14b202 | ||
![]() |
092980a276 | ||
![]() |
6b926c46bb | ||
![]() |
1e17bd4c82 | ||
![]() |
91ce9d6c55 | ||
![]() |
57a6641da1 | ||
![]() |
021a322ef9 | ||
![]() |
517d48a91d | ||
![]() |
4abef5d6fc | ||
![]() |
0d304ae292 | ||
![]() |
156726025c | ||
![]() |
f017159221 | ||
![]() |
f44d4e2bef | ||
![]() |
9c5b0a8e76 | ||
![]() |
3dcb44eebe | ||
![]() |
2eec0edbe0 | ||
![]() |
9dd4668137 | ||
![]() |
dc9263ee8f | ||
![]() |
986025cf35 | ||
![]() |
f16d07017b | ||
![]() |
d9ad72d06b | ||
![]() |
eed4d5fd5e | ||
![]() |
134a7b26d9 | ||
![]() |
57c321cef7 | ||
![]() |
6a6f2816cb | ||
![]() |
06eaef83e5 | ||
![]() |
e44c5bd925 | ||
![]() |
c1ff47f7f9 | ||
![]() |
91f378d9cc | ||
![]() |
2008633a60 | ||
![]() |
63adad289f | ||
![]() |
fbf443a268 | ||
![]() |
2b1e4f7a4f | ||
![]() |
63307c1abb | ||
![]() |
7725e76358 | ||
![]() |
0a1f705263 | ||
![]() |
8d8e98309f | ||
![]() |
20c1adf1ec | ||
![]() |
0a98a92e4c | ||
![]() |
78c66c9b78 | ||
![]() |
3315274d41 | ||
![]() |
163cd5a74c | ||
![]() |
b864d36faa | ||
![]() |
408cf26290 | ||
![]() |
705f609296 | ||
![]() |
d3c0931825 | ||
![]() |
1a1dc92ac2 | ||
![]() |
2fae891423 | ||
![]() |
f1a8d953b3 | ||
![]() |
03d0ccff28 | ||
![]() |
ac13bcb8ae | ||
![]() |
fd54825707 | ||
![]() |
5eb5b5da2d | ||
![]() |
c1bff52b93 | ||
![]() |
35ce47a18e | ||
![]() |
f4d0422781 | ||
![]() |
f7d776c02c | ||
![]() |
ecdaaea58b | ||
![]() |
ec1505c5c4 | ||
![]() |
3c067548a7 | ||
![]() |
29e9f266a8 | ||
![]() |
96c99819b8 | ||
![]() |
7179072456 | ||
![]() |
04c35880d1 | ||
![]() |
f026a2b2c8 | ||
![]() |
4648fc4ba7 | ||
![]() |
9880bc124d | ||
![]() |
ef8716edc0 | ||
![]() |
45f2170731 | ||
![]() |
f57f9ea353 | ||
![]() |
a5a4f839fe | ||
![]() |
4cea17e529 | ||
![]() |
39bd65dbd8 | ||
![]() |
707d5e5e38 | ||
![]() |
ad34d95353 | ||
![]() |
88ebb2587d | ||
![]() |
a00744d069 | ||
![]() |
4696855406 | ||
![]() |
06ea20e93c | ||
![]() |
9b393c6f83 | ||
![]() |
7874e9f98c | ||
![]() |
4438a00128 | ||
![]() |
00e00a80bc | ||
![]() |
c19cfd740b | ||
![]() |
fa11d5e0cc | ||
![]() |
94e477994b | ||
![]() |
1c2d733fc9 | ||
![]() |
cf0b3b03b3 | ||
![]() |
08eb3105b5 | ||
![]() |
52f6312a70 | ||
![]() |
760c8b4eb4 | ||
![]() |
899857c67a | ||
![]() |
23970bc8c4 | ||
![]() |
6e10e9493b | ||
![]() |
46e3d66de1 | ||
![]() |
15dbffdae4 | ||
![]() |
da8d58b17f | ||
![]() |
9b001c81fa | ||
![]() |
e0163fb795 | ||
![]() |
df8f169e13 | ||
![]() |
72aa9798fd | ||
![]() |
3699e1b38e | ||
![]() |
604b2de556 | ||
![]() |
52496a94b3 | ||
![]() |
7a29a88e52 | ||
![]() |
8913f6b377 | ||
![]() |
56bdc5389a | ||
![]() |
30d8c6be66 | ||
![]() |
af40cafd4e | ||
![]() |
d57644c12d | ||
![]() |
4bb7c04532 | ||
![]() |
52a3f83564 | ||
![]() |
b4294bdf52 | ||
![]() |
66caa31754 | ||
![]() |
56e460c426 | ||
![]() |
174a5b1ba8 | ||
![]() |
cbc5c2428c | ||
![]() |
68473665ea | ||
![]() |
b5dec9b414 | ||
![]() |
f1ebdeb36e | ||
![]() |
6590a8c617 | ||
![]() |
716e6fb9aa | ||
![]() |
eb73d3fedb | ||
![]() |
56a73c47b6 | ||
![]() |
ffe7b11101 | ||
![]() |
08feda4d91 | ||
![]() |
225b03223b | ||
![]() |
b51f145a6c | ||
![]() |
f14ec2fb65 | ||
![]() |
bc21447d17 | ||
![]() |
679d523dba | ||
![]() |
dafe917306 | ||
![]() |
e249f24361 | ||
![]() |
26421d8ee4 | ||
![]() |
4cdc7e1eeb | ||
![]() |
fb2add462b | ||
![]() |
0105769a90 | ||
![]() |
f868f507e0 | ||
![]() |
b52eea7062 | ||
![]() |
f9883ed862 | ||
![]() |
9e71d2e51d | ||
![]() |
f8697938f6 | ||
![]() |
118567a226 | ||
![]() |
bc2e85f4a1 | ||
![]() |
3e2ad5650a | ||
![]() |
09fcb9e1fd | ||
![]() |
fc4a514a4f | ||
![]() |
db27daca08 | ||
![]() |
8f9a71c92a | ||
![]() |
068117e2a1 | ||
![]() |
00ab40d6af | ||
![]() |
19f6901690 | ||
![]() |
1a5dc9b0c7 | ||
![]() |
fbb996095b | ||
![]() |
2bb1d84f0c | ||
![]() |
a5886a7cec | ||
![]() |
b0dfe2f55f | ||
![]() |
0cd666e1f1 | ||
![]() |
f38613dce6 | ||
![]() |
0cf2429258 | ||
![]() |
db523261b9 | ||
![]() |
8d9d0914dd | ||
![]() |
56ae864256 | ||
![]() |
4f05ac3998 | ||
![]() |
8d436914ae | ||
![]() |
de9bbfeef0 | ||
![]() |
3c574880e6 | ||
![]() |
2057fa188d | ||
![]() |
4172172498 | ||
![]() |
8821395471 | ||
![]() |
3fb41b5d00 | ||
![]() |
316363bb8a | ||
![]() |
b08b8601b5 | ||
![]() |
0c64448d4b | ||
![]() |
7cd695ac41 | ||
![]() |
39d431f85e | ||
![]() |
d5de90c42c | ||
![]() |
fd89efb778 | ||
![]() |
844a4bf34d | ||
![]() |
788a64ea8b | ||
![]() |
0a7dc40f27 | ||
![]() |
c94934136f | ||
![]() |
98ecc159a7 | ||
![]() |
3b1c3a9428 | ||
![]() |
e926b4ae95 | ||
![]() |
9431c63c8d | ||
![]() |
7e930b5399 | ||
![]() |
ae39944a93 | ||
![]() |
4bdffa72b4 | ||
![]() |
1984b6a291 | ||
![]() |
414f114ffb | ||
![]() |
62cf41f770 | ||
![]() |
53b545a374 | ||
![]() |
901984ce5b | ||
![]() |
595e5b94d3 | ||
![]() |
f1da5526a5 | ||
![]() |
910b09fb0f | ||
![]() |
67f2f5b5b0 | ||
![]() |
a071f8cd22 | ||
![]() |
228ef50a7c | ||
![]() |
ad457576da | ||
![]() |
37e84f036c | ||
![]() |
05c0dfcc44 | ||
![]() |
74b1c07d3d | ||
![]() |
0e52e069d0 | ||
![]() |
019b353b1f | ||
![]() |
3c1ed8ac6d | ||
![]() |
68c7f3b018 | ||
![]() |
1c26798eca | ||
![]() |
c12084e11b | ||
![]() |
fe66967566 | ||
![]() |
14c5662e40 | ||
![]() |
a50a209b03 | ||
![]() |
b8832b020a | ||
![]() |
e32e9d381c | ||
![]() |
7824297ab8 | ||
![]() |
6cba754208 | ||
![]() |
9bed91187f | ||
![]() |
0b95f3455b | ||
![]() |
4cba1e6071 | ||
![]() |
c53f53a031 | ||
![]() |
a25811314e | ||
![]() |
d4a01227b7 | ||
![]() |
a1a9503beb | ||
![]() |
62fe7d64f0 | ||
![]() |
e2a2779d9e | ||
![]() |
2e1e9039b5 | ||
![]() |
903a1c8454 | ||
![]() |
ad98808cce | ||
![]() |
82ad7e4d87 | ||
![]() |
1976462ed8 | ||
![]() |
767570223a | ||
![]() |
4b8cdc4767 | ||
![]() |
d52934257d | ||
![]() |
307b89721c | ||
![]() |
08ad212b3c | ||
![]() |
56bf7f8879 | ||
![]() |
57580a3b65 | ||
![]() |
1fc52b2173 | ||
![]() |
d6593819b1 | ||
![]() |
87f45c1574 | ||
![]() |
d016a671a2 | ||
![]() |
70d8278164 | ||
![]() |
8ec150ae65 | ||
![]() |
ae29f34c35 | ||
![]() |
f2bd8458b6 | ||
![]() |
4be258fd3b | ||
![]() |
ee0a4236b5 | ||
![]() |
086f2a89b5 | ||
![]() |
330e2d8e83 | ||
![]() |
c116ede1cb | ||
![]() |
8b8e4b84d5 | ||
![]() |
d47c62870e | ||
![]() |
0a39b036ce | ||
![]() |
17f82f4642 | ||
![]() |
be573324a8 | ||
![]() |
1a19b84ee1 | ||
![]() |
192f7a5b7d | ||
![]() |
692a38c34e | ||
![]() |
aad92f4184 | ||
![]() |
a9160c3a4b | ||
![]() |
2dbd833186 | ||
![]() |
ba114621f3 | ||
![]() |
edc7b44ae6 | ||
![]() |
270be82f68 | ||
![]() |
3f1c1270de | ||
![]() |
abf3eb7311 | ||
![]() |
4e474017fe | ||
![]() |
88fe2f0593 | ||
![]() |
0cb47ab931 | ||
![]() |
6e9ca1fe26 | ||
![]() |
6f051ceac0 | ||
![]() |
a682f2205f | ||
![]() |
461160ec27 | ||
![]() |
a6b2a956ae | ||
![]() |
bcc9f72c76 | ||
![]() |
7b3ce332a8 | ||
![]() |
7344f2cd97 | ||
![]() |
9097e7c8dc | ||
![]() |
9357af1424 | ||
![]() |
2e80df535f | ||
![]() |
2874f9df6d | ||
![]() |
606ef15ece | ||
![]() |
e9831ed1b2 | ||
![]() |
d086a28a5b | ||
![]() |
a1a50c6609 | ||
![]() |
8dab8a3318 | ||
![]() |
979ed4fe95 | ||
![]() |
c7294ade2e | ||
![]() |
897c0837d7 | ||
![]() |
83453a5c57 | ||
![]() |
450d77c0ac | ||
![]() |
3e80697e79 | ||
![]() |
942a957b5d | ||
![]() |
4b0c38d83a | ||
![]() |
10ce96fa3b | ||
![]() |
e52940eac6 | ||
![]() |
6be3dca907 | ||
![]() |
a71a780fee | ||
![]() |
5b2323d536 | ||
![]() |
3cc1e35882 | ||
![]() |
6d7d88f211 | ||
![]() |
9448862555 | ||
![]() |
47a04ebcdd | ||
![]() |
8fe60482a0 | ||
![]() |
16b8d47a58 | ||
![]() |
3d4c4e03da | ||
![]() |
6c4d141625 | ||
![]() |
f80a03d4f5 | ||
![]() |
7fb7e2ec66 | ||
![]() |
1cb5752e48 | ||
![]() |
acac4cb5fd | ||
![]() |
13322511a4 | ||
![]() |
c07c518c61 | ||
![]() |
0103f79716 | ||
![]() |
0ecdd3f245 | ||
![]() |
705879d17d | ||
![]() |
7d92acc276 | ||
![]() |
c8a129d0c8 | ||
![]() |
aa3fbe812d | ||
![]() |
2e95d7c60b | ||
![]() |
30bb80da4f | ||
![]() |
8e8309c42c | ||
![]() |
32f6f37583 | ||
![]() |
5926c63b8b | ||
![]() |
3175b2e072 | ||
![]() |
0e318f2dba | ||
![]() |
6694626e7f | ||
![]() |
360337e7cf | ||
![]() |
2a2fd5f1f9 | ||
![]() |
ea98047f86 | ||
![]() |
573a2f5544 | ||
![]() |
3cc38ed402 | ||
![]() |
a38535691b | ||
![]() |
5a63a7cd69 | ||
![]() |
309ac3d34f | ||
![]() |
9a169f5dda | ||
![]() |
071afd1514 | ||
![]() |
4b600288cb | ||
![]() |
530a5cfe4f | ||
![]() |
701d3cfe4f | ||
![]() |
c5d66b831e | ||
![]() |
25e4fa8170 | ||
![]() |
d571c02881 | ||
![]() |
70019653df | ||
![]() |
98e8c67bff | ||
![]() |
28b99bd8aa | ||
![]() |
0ecaf64f5e | ||
![]() |
7c26cf2ac9 | ||
![]() |
2342363b29 | ||
![]() |
7117057389 | ||
![]() |
cab4914b01 | ||
![]() |
14cf31415a | ||
![]() |
ae8cb9329b | ||
![]() |
9b608b200b | ||
![]() |
ee1db5e9ab | ||
![]() |
88d5a6b11d | ||
![]() |
b85f69c2b7 | ||
![]() |
ace6ccce66 | ||
![]() |
e1c6b8ccdf | ||
![]() |
b688b986b4 | ||
![]() |
df7beb821f | ||
![]() |
c7dc06016a | ||
![]() |
87e2f213f7 | ||
![]() |
5ca1316688 | ||
![]() |
332143ef47 | ||
![]() |
d34a01b87f | ||
![]() |
f58d1dc7c5 | ||
![]() |
bf86b75485 | ||
![]() |
76609f642d | ||
![]() |
257d6d686f | ||
![]() |
8706a7829f | ||
![]() |
08864825cd | ||
![]() |
d043b4e03a | ||
![]() |
da39631a80 | ||
![]() |
844862277b | ||
![]() |
47977e2250 | ||
![]() |
36bdc5b122 | ||
![]() |
3c73e22a0f | ||
![]() |
c080367a92 | ||
![]() |
f9ede53d38 | ||
![]() |
5008371219 | ||
![]() |
ea0e6977f8 | ||
![]() |
ba53e1932d | ||
![]() |
67f7d66a80 | ||
![]() |
c3fedf6bc3 | ||
![]() |
77c49ee470 | ||
![]() |
e12120f42d | ||
![]() |
e480f4c111 | ||
![]() |
40ddbe2954 | ||
![]() |
1d8c32c773 | ||
![]() |
c8d0b4b30f | ||
![]() |
a7f2aaa6fb | ||
![]() |
70cda00d4b | ||
![]() |
05ec031666 | ||
![]() |
a8a07a8fb6 | ||
![]() |
eb2b518117 | ||
![]() |
b9160b21f2 | ||
![]() |
669281faab | ||
![]() |
3644136dd3 | ||
![]() |
c4b6d37fec | ||
![]() |
c860b26870 | ||
![]() |
929fcf6cb5 | ||
![]() |
4f939c1dfe | ||
![]() |
a3569c1d89 | ||
![]() |
09757f9033 | ||
![]() |
f4c8b1c2d7 | ||
![]() |
c44efc4df4 | ||
![]() |
afcb6855ec | ||
![]() |
6902ae2687 | ||
![]() |
b648110820 | ||
![]() |
bb1cf386c1 | ||
![]() |
7d07201dce | ||
![]() |
04704410db | ||
![]() |
32ef82fc54 | ||
![]() |
f55ed4aa8e | ||
![]() |
e4f49f46cd | ||
![]() |
a378c597f4 | ||
![]() |
f51bd8c842 | ||
![]() |
0a302c9c40 | ||
![]() |
574bde91d4 | ||
![]() |
7f298e7886 | ||
![]() |
93e8f157cf | ||
![]() |
04e375a0ae | ||
![]() |
33319dba88 | ||
![]() |
3fd33fd4fa | ||
![]() |
22153b09b4 | ||
![]() |
0aca0ebfe1 | ||
![]() |
f8a7e8fcd0 | ||
![]() |
ba42f460c8 | ||
![]() |
552797d3e0 | ||
![]() |
dd10131d4a | ||
![]() |
3297b308fe | ||
![]() |
e7966bc929 | ||
![]() |
09fdeff28d | ||
![]() |
a34834ba71 | ||
![]() |
e6eb7c8382 | ||
![]() |
f4b98a4e4e | ||
![]() |
7991f9a7d4 | ||
![]() |
b580d3b9a8 | ||
![]() |
168c971ae3 | ||
![]() |
e2ed04ea18 | ||
![]() |
26829186e6 | ||
![]() |
d5f1c42e28 | ||
![]() |
04af8c1491 | ||
![]() |
65b96a56f3 | ||
![]() |
85c448d5a9 | ||
![]() |
021b54de67 | ||
![]() |
43c0458a86 | ||
![]() |
121b1e24b9 | ||
![]() |
86dbf24184 | ||
![]() |
0576a42a4f | ||
![]() |
eb037b62e3 | ||
![]() |
1cf520cc30 | ||
![]() |
10e3c3b720 | ||
![]() |
b55b7b7d84 | ||
![]() |
eaf9538576 | ||
![]() |
b02fcceb4e | ||
![]() |
7ec31704a5 | ||
![]() |
1bbaaa61f1 | ||
![]() |
89fc109aa8 | ||
![]() |
12891ec53d | ||
![]() |
7794b5eb51 | ||
![]() |
7b5f673269 | ||
![]() |
1d41766455 | ||
![]() |
cdeb5df243 | ||
![]() |
20a9dee920 | ||
![]() |
f4186c216b | ||
![]() |
02be4a1aa0 | ||
![]() |
c2243fa9b5 | ||
![]() |
b58a8abeb0 | ||
![]() |
960d2f0516 | ||
![]() |
0c56dd8971 | ||
![]() |
4735e8f59f | ||
![]() |
efb453567e | ||
![]() |
289f3d1693 | ||
![]() |
3924d4475c | ||
![]() |
3266caef87 | ||
![]() |
cbbba04026 | ||
![]() |
267d1fef6f | ||
![]() |
b658f9b80e | ||
![]() |
a420bb953f | ||
![]() |
3742ccf611 | ||
![]() |
ae071f5c66 | ||
![]() |
7f2db95c88 | ||
![]() |
b42eec9748 | ||
![]() |
3a10fdc25a | ||
![]() |
11c844ac42 | ||
![]() |
15b813b2c5 | ||
![]() |
67a6d55be9 | ||
![]() |
cf7e6608df | ||
![]() |
cc94e6c829 | ||
![]() |
9f63534537 | ||
![]() |
96fba7a700 | ||
![]() |
742714de77 | ||
![]() |
db15332f86 | ||
![]() |
c5a1279b0d | ||
![]() |
a19e3d61e2 | ||
![]() |
0add921dad | ||
![]() |
310256a9e4 | ||
![]() |
c5faa4abb8 | ||
![]() |
871d754957 | ||
![]() |
7242d48b1c | ||
![]() |
aa9f653f5b | ||
![]() |
fafb1be834 | ||
![]() |
34decdef13 | ||
![]() |
75bcc84059 | ||
![]() |
1330ca66cb | ||
![]() |
6641044d21 | ||
![]() |
9876089a10 | ||
![]() |
9e3aeda6af | ||
![]() |
9a411d62be | ||
![]() |
afc86cab01 | ||
![]() |
1d25c25417 | ||
![]() |
e2a5c36b43 | ||
![]() |
152e0f3326 | ||
![]() |
bbe157f865 | ||
![]() |
ea78d1e63b | ||
![]() |
ca5b0a1520 | ||
![]() |
cf36f03518 | ||
![]() |
9296bb1859 | ||
![]() |
0292eb9dce | ||
![]() |
03beec74b8 | ||
![]() |
79b5e5bbd1 | ||
![]() |
60847e28a2 | ||
![]() |
fc754dff54 | ||
![]() |
efa55c9ebf | ||
![]() |
bdfd017d10 | ||
![]() |
993bdb56c1 | ||
![]() |
e9321727b3 | ||
![]() |
3c5c80ba4a | ||
![]() |
3d24e90894 | ||
![]() |
ea453ba48c | ||
![]() |
9c4d817745 | ||
![]() |
4fe6dd9a79 | ||
![]() |
38a4cab789 | ||
![]() |
f046956123 | ||
![]() |
148a89ebfa | ||
![]() |
d6b77b7982 | ||
![]() |
bfe8216b17 | ||
![]() |
75bee4d1be | ||
![]() |
36b8646e2b | ||
![]() |
2ef6dfa391 | ||
![]() |
71e63d7c89 | ||
![]() |
1c1fdf6519 | ||
![]() |
0d4c8a3b1b | ||
![]() |
9fc97c38d4 | ||
![]() |
e4cb91fba1 | ||
![]() |
619874b03b | ||
![]() |
3203a854f3 | ||
![]() |
dc29c824c8 | ||
![]() |
5669fdd9cc | ||
![]() |
95aa66b09c | ||
![]() |
4e414e5a4d | ||
![]() |
456e757258 | ||
![]() |
db41f455f3 | ||
![]() |
e267428ed2 | ||
![]() |
1bbf69c282 | ||
![]() |
47a1e6dd4c | ||
![]() |
676a8c77a6 | ||
![]() |
9c77062cd6 | ||
![]() |
4dd0e9bad5 | ||
![]() |
83a0b61b30 | ||
![]() |
4b0124f3a7 | ||
![]() |
546ad50c62 | ||
![]() |
4ba47b9866 | ||
![]() |
8df9521ad0 | ||
![]() |
791da54f6d | ||
![]() |
7004e15b71 | ||
![]() |
fb23c179f2 | ||
![]() |
10b3e79e44 | ||
![]() |
b3ff49ac79 | ||
![]() |
333f04112d | ||
![]() |
6aa2e951fd | ||
![]() |
3c02e2e425 | ||
![]() |
3b8d633cbc | ||
![]() |
7bd636542b | ||
![]() |
f03bca58a5 | ||
![]() |
b89aa4a4c7 | ||
![]() |
8ff403816a | ||
![]() |
1961543b3d | ||
![]() |
9b54b3637e | ||
![]() |
18caf13fb9 | ||
![]() |
39591b2859 | ||
![]() |
8314e13414 | ||
![]() |
6b070b0f77 | ||
![]() |
4f4a6dfa0a | ||
![]() |
ffc9cc18a5 | ||
![]() |
1170d0e492 | ||
![]() |
078eb8d4de | ||
![]() |
2dc4ef061d | ||
![]() |
639a565cf3 | ||
![]() |
096186d27d | ||
![]() |
bb5932040a | ||
![]() |
0102ba7669 | ||
![]() |
9aa497eb78 | ||
![]() |
40795b316a | ||
![]() |
c909f3e40d | ||
![]() |
2a55895120 | ||
![]() |
22ba38f4d7 | ||
![]() |
3a81fff743 | ||
![]() |
1538047b7b | ||
![]() |
6024692db1 | ||
![]() |
2e6ba8fe89 | ||
![]() |
152c2b21ec | ||
![]() |
02cfede0cd | ||
![]() |
6af36798ff | ||
![]() |
c7da689fac | ||
![]() |
f3e7b88822 | ||
![]() |
ad80a66ee1 | ||
![]() |
651deffc7f | ||
![]() |
dc1fe0ac65 | ||
![]() |
10477ccd14 | ||
![]() |
cfd161253d | ||
![]() |
b51b34531b | ||
![]() |
fd54ca6bcc | ||
![]() |
0cf935be06 | ||
![]() |
d2f1c6b6c2 | ||
![]() |
a7319410ae | ||
![]() |
2fa814da29 | ||
![]() |
5ecc2b10a8 | ||
![]() |
bbfbb267c0 | ||
![]() |
4ce0fb2da3 | ||
![]() |
7f21f40753 | ||
![]() |
fd97c4ffab | ||
![]() |
6da35c8840 | ||
![]() |
39817aa356 | ||
![]() |
b026cd7e11 | ||
![]() |
342e4dabc6 | ||
![]() |
36c18a1c16 | ||
![]() |
d065bc850c | ||
![]() |
22c130fc49 | ||
![]() |
e5a475f15c | ||
![]() |
6a77c5549c | ||
![]() |
7eb7387b4b | ||
![]() |
16905f2474 | ||
![]() |
7dba6168f1 | ||
![]() |
3a48801240 | ||
![]() |
dc59b1a6b5 | ||
![]() |
952f7bb98a | ||
![]() |
3edcb3f9f8 | ||
![]() |
482a9e29f8 | ||
![]() |
fe4bb9804a | ||
![]() |
0032050b68 | ||
![]() |
3902f0a91c | ||
![]() |
4ee05adddb | ||
![]() |
495de1fe63 | ||
![]() |
d4b687fb57 | ||
![]() |
c7fe278075 | ||
![]() |
1a12bfeaba | ||
![]() |
c208d69f9a | ||
![]() |
9b21c2c0b4 | ||
![]() |
c93dfb776e | ||
![]() |
8c7ba83327 | ||
![]() |
156cc2f83d | ||
![]() |
a701e5a848 | ||
![]() |
86a95c29e0 | ||
![]() |
809bee221f | ||
![]() |
56cbc7a7a6 | ||
![]() |
1aa8b61bcb | ||
![]() |
f5e6dc5306 | ||
![]() |
33e6828c46 | ||
![]() |
ae1734112d | ||
![]() |
be04aeebb5 | ||
![]() |
260efeb20f | ||
![]() |
c9dd34416a | ||
![]() |
81c2218fcc | ||
![]() |
7f2b899a44 | ||
![]() |
ca22a6a146 | ||
![]() |
bf4de59438 | ||
![]() |
2972958897 | ||
![]() |
4d2c6bfc49 | ||
![]() |
a3a49f7a02 | ||
![]() |
c6475a69b2 | ||
![]() |
275a9fa9ca | ||
![]() |
50fdc99bcf | ||
![]() |
54d56ab9a3 | ||
![]() |
ef5765bfd3 | ||
![]() |
e601f802a2 | ||
![]() |
045942f699 | ||
![]() |
c790248206 | ||
![]() |
7b2aed2a99 | ||
![]() |
1f7635df62 | ||
![]() |
f6d385f178 | ||
![]() |
cb5a59ca72 | ||
![]() |
ed9c1559e6 | ||
![]() |
17ad6ff1fe | ||
![]() |
02680c7a99 | ||
![]() |
ecff2387bc | ||
![]() |
7da233116b | ||
![]() |
507a8bfd67 | ||
![]() |
cb2b64e2da | ||
![]() |
1aebaa8da7 | ||
![]() |
6731b9a91c | ||
![]() |
2dfd7056e5 | ||
![]() |
a6513ec49b | ||
![]() |
763526b03a | ||
![]() |
dddaddd0e4 | ||
![]() |
a6b10fabe9 | ||
![]() |
a22e027a51 | ||
![]() |
55b9c3240c | ||
![]() |
9befcc30b0 | ||
![]() |
bbf91cbca9 | ||
![]() |
702404945e | ||
![]() |
22e8dd7e04 | ||
![]() |
46c6563b2a | ||
![]() |
4cd15058e5 | ||
![]() |
226dcb542e | ||
![]() |
2711403e67 | ||
![]() |
5f37636c79 | ||
![]() |
e982da4cd3 | ||
![]() |
d0edfcb0d0 | ||
![]() |
5affc15bfe | ||
![]() |
efaae62663 | ||
![]() |
54b796e850 | ||
![]() |
96e060ac90 | ||
![]() |
97a9989a7b | ||
![]() |
ec950d1a29 | ||
![]() |
2d01b7ad59 | ||
![]() |
e93ede96a8 | ||
![]() |
6712b82f6c | ||
![]() |
e9de331fac | ||
![]() |
61ed856bdc | ||
![]() |
618afa4342 | ||
![]() |
b159d63fc5 | ||
![]() |
a601d350fc | ||
![]() |
8f347eadb2 | ||
![]() |
2498792564 | ||
![]() |
04457adc09 | ||
![]() |
5dc0687cc0 | ||
![]() |
461943555a | ||
![]() |
56525826ba | ||
![]() |
94c7f0e24c | ||
![]() |
f1b3b4dc34 | ||
![]() |
380f655df8 | ||
![]() |
f4960bc85b | ||
![]() |
77379b7cd5 | ||
![]() |
bac1252347 | ||
![]() |
df5380ab3a | ||
![]() |
2106258cca | ||
![]() |
c0bc61dd70 | ||
![]() |
e7e4cd0582 | ||
![]() |
f2b2a67616 | ||
![]() |
395280460b | ||
![]() |
94bbc8eea0 | ||
![]() |
9a9919999e | ||
![]() |
bff8cfc9d0 | ||
![]() |
78c4f75d21 | ||
![]() |
71a6d2967a | ||
![]() |
9923e9cf09 | ||
![]() |
f248a3173a | ||
![]() |
f1917151f0 | ||
![]() |
0b27e24901 | ||
![]() |
a0e5491c54 | ||
![]() |
cb8fbc5357 | ||
![]() |
2d0a19a09c | ||
![]() |
6e249c8551 | ||
![]() |
14b3bf135e | ||
![]() |
f2fc2cc04b | ||
![]() |
0eab009a99 | ||
![]() |
0c744082d2 | ||
![]() |
9609b7bf50 | ||
![]() |
41780dd046 | ||
![]() |
ec7b9c2474 | ||
![]() |
edabac14cb | ||
![]() |
e0cd5b88b3 | ||
![]() |
ba36c96049 | ||
![]() |
87511af860 | ||
![]() |
115a0837e4 | ||
![]() |
ddd70bf91c | ||
![]() |
2aaf9aef16 | ||
![]() |
42b1b0758c | ||
![]() |
2546695382 | ||
![]() |
d27f0110f8 | ||
![]() |
e9a5576036 | ||
![]() |
e892db6426 | ||
![]() |
342171e061 | ||
![]() |
ff6bb887fe | ||
![]() |
c7160d0007 | ||
![]() |
0b2e5bd51e | ||
![]() |
0d27e41998 | ||
![]() |
d4e98736f1 | ||
![]() |
2c9c17fc5d | ||
![]() |
fcc874bb13 | ||
![]() |
9778065c8c | ||
![]() |
5cdc4602a0 | ||
![]() |
70429d4b12 | ||
![]() |
6e7df92e89 | ||
![]() |
caf6d8f9a8 | ||
![]() |
10cc9e3cc5 | ||
![]() |
b227a0ef6a | ||
![]() |
4ed72211cd | ||
![]() |
6b6a7569da | ||
![]() |
3921608c08 | ||
![]() |
3e53a9d9e6 | ||
![]() |
560ae55f4c | ||
![]() |
0bc46fe739 | ||
![]() |
acecde75fe | ||
![]() |
b28ca6f2c5 | ||
![]() |
983dc788f3 | ||
![]() |
4a1371f0a0 | ||
![]() |
ec26c11cfe | ||
![]() |
be4232dbf1 | ||
![]() |
22d5defc3b | ||
![]() |
31d6f2d809 | ||
![]() |
682defa6c1 | ||
![]() |
f383e25d26 | ||
![]() |
b779fc1387 | ||
![]() |
439b90008c | ||
![]() |
b1aa6d305d | ||
![]() |
84620ef5ff | ||
![]() |
28e7dba47b | ||
![]() |
6bd35ce0e1 | ||
![]() |
ff53408718 | ||
![]() |
1a3b84e3ef | ||
![]() |
a4c3923ca9 | ||
![]() |
6b21b37222 | ||
![]() |
240cd7152c | ||
![]() |
23ea500492 | ||
![]() |
1fcd8f0364 | ||
![]() |
5a62d5f602 | ||
![]() |
2acd28c1b0 | ||
![]() |
08ce98cedd | ||
![]() |
5d48f30788 | ||
![]() |
123d1d487c | ||
![]() |
f0cd11e590 | ||
![]() |
fee701012d | ||
![]() |
ae2692d3b4 | ||
![]() |
027bd3e973 | ||
![]() |
0bfcc705d7 | ||
![]() |
ece92385d0 | ||
![]() |
226b139fcf | ||
![]() |
8642fc52e8 | ||
![]() |
7cefc2735b | ||
![]() |
c3b4a71118 | ||
![]() |
3e957a3ee4 | ||
![]() |
ee557af21e | ||
![]() |
4fe0061cda | ||
![]() |
40d8ec2eb4 | ||
![]() |
05005ea832 | ||
![]() |
145a5765d9 | ||
![]() |
402ff676b8 | ||
![]() |
2d16ecba78 | ||
![]() |
059d15e7bf | ||
![]() |
93163a6e2d | ||
![]() |
5e125ff7e7 | ||
![]() |
be5b68afb5 | ||
![]() |
3b0cd3e98a | ||
![]() |
8187f0c60d | ||
![]() |
0d9ab2b609 | ||
![]() |
7f60fd2fe9 | ||
![]() |
7770999db3 | ||
![]() |
18b3d751ca | ||
![]() |
81d3ed86c7 | ||
![]() |
b35cf03161 | ||
![]() |
c2aeb8d248 | ||
![]() |
8342a898df | ||
![]() |
6be69b3366 | ||
![]() |
6bbbe6719f | ||
![]() |
460eb8dc16 | ||
![]() |
79183ea6a1 | ||
![]() |
d5edb4da1c | ||
![]() |
b440bcf355 | ||
![]() |
f83ca7ca4a | ||
![]() |
77efdbd577 | ||
![]() |
da0978bcd4 | ||
![]() |
34109b28fc | ||
![]() |
736ffd79b5 | ||
![]() |
b41d22edd6 | ||
![]() |
47263f9a66 | ||
![]() |
0eb81597f3 | ||
![]() |
04946f56fa | ||
![]() |
f606ef66ff | ||
![]() |
87cbc67b53 | ||
![]() |
9511632cdf | ||
![]() |
94da4a6599 | ||
![]() |
da6a3819b6 | ||
![]() |
53962d9e8e | ||
![]() |
85c56ad37a | ||
![]() |
bc7b38502c | ||
![]() |
1de0652daf | ||
![]() |
036bc251b1 | ||
![]() |
0f26dc412a | ||
![]() |
2a2458dc0a | ||
![]() |
73a4be0ddc | ||
![]() |
07f1ef22a0 | ||
![]() |
43f5cbdce4 | ||
![]() |
e92da2bcf1 | ||
![]() |
d03186219b | ||
![]() |
9348c6d0f1 | ||
![]() |
5cd9d50ef9 | ||
![]() |
b3e8f6492c | ||
![]() |
f00833917c | ||
![]() |
16ac5ad6cd | ||
![]() |
887a7517b8 | ||
![]() |
5b773b6298 | ||
![]() |
3f403f6877 | ||
![]() |
0c18557bbf | ||
![]() |
8f173747a2 | ||
![]() |
5a1ef31b01 | ||
![]() |
60807b6eea | ||
![]() |
429d6d76fb | ||
![]() |
fa16fccbde | ||
![]() |
fc1df26b64 | ||
![]() |
98e0501f82 | ||
![]() |
b5f500ae8c | ||
![]() |
c72df3e206 | ||
![]() |
9d5282474a | ||
![]() |
1add5b88f6 | ||
![]() |
13cee587f0 | ||
![]() |
32daa90131 | ||
![]() |
ac32ce97f8 | ||
![]() |
13fab10da5 | ||
![]() |
843a8cc024 | ||
![]() |
6568e0337d | ||
![]() |
1786e746e7 | ||
![]() |
f568399bb2 | ||
![]() |
e7e439c279 | ||
![]() |
9c53333f88 | ||
![]() |
60f276a436 | ||
![]() |
0aba4708c1 | ||
![]() |
6c904659b3 | ||
![]() |
f0383e226f | ||
![]() |
370dde81ce | ||
![]() |
6867f279a4 | ||
![]() |
9713068e5c | ||
![]() |
72ef75df49 | ||
![]() |
dcc954babc | ||
![]() |
183cb1b369 | ||
![]() |
fe2ba27c3a | ||
![]() |
31ac24d9eb | ||
![]() |
50dac88e88 | ||
![]() |
2d0f124858 | ||
![]() |
df7a8d31ef | ||
![]() |
0aa3446e70 | ||
![]() |
bd7371c6d7 | ||
![]() |
88ca81e8a4 | ||
![]() |
da121da7b6 | ||
![]() |
b2e154b9d2 | ||
![]() |
a9e812bb41 | ||
![]() |
ee8c17713b | ||
![]() |
8fab66fb27 | ||
![]() |
3881dcc119 | ||
![]() |
2516bf7d44 | ||
![]() |
a893fc0f9d | ||
![]() |
661ae76460 | ||
![]() |
00e00020d9 | ||
![]() |
f311c28b49 | ||
![]() |
da401df16e | ||
![]() |
2d3ef4b3ef | ||
![]() |
bfd821decf | ||
![]() |
3368940220 | ||
![]() |
73bc984d53 | ||
![]() |
8ed1afbee7 | ||
![]() |
ad10d8c789 | ||
![]() |
6c242dad74 | ||
![]() |
8f2755bf37 | ||
![]() |
87330fbbdd | ||
![]() |
c09a229704 | ||
![]() |
41dd6c539a | ||
![]() |
7f69636123 | ||
![]() |
1ab3014f35 | ||
![]() |
9537ce435a | ||
![]() |
7b97ab8b47 | ||
![]() |
fcd3124f2f | ||
![]() |
79cd7f9a04 | ||
![]() |
d8c0aa0c7d | ||
![]() |
e0c700f697 | ||
![]() |
892f8a6da3 | ||
![]() |
fba42f5b12 | ||
![]() |
0eb5be5a6f | ||
![]() |
0f6bf3a1c9 | ||
![]() |
30d637baaa | ||
![]() |
0122cf854d | ||
![]() |
8119c59921 | ||
![]() |
2b8deb2367 | ||
![]() |
8ea3b826d6 | ||
![]() |
31855596b5 | ||
![]() |
ff9fee2506 | ||
![]() |
270e57af07 | ||
![]() |
174c1ad962 | ||
![]() |
346b7c89d9 | ||
![]() |
afcd143063 | ||
![]() |
3a86a11ba4 | ||
![]() |
0ac4ac97f9 | ||
![]() |
eac35e29ef | ||
![]() |
7bb96b9f6a | ||
![]() |
4d12f26877 | ||
![]() |
087d8d3853 | ||
![]() |
74b1c54523 | ||
![]() |
9ce6fe71f7 | ||
![]() |
c9a4434718 | ||
![]() |
44538606d0 | ||
![]() |
47488896c9 | ||
![]() |
3fb57fee88 | ||
![]() |
c163f1156d | ||
![]() |
9db152cdf7 | ||
![]() |
e82d67ba9b | ||
![]() |
00793030cf | ||
![]() |
296808b8a0 | ||
![]() |
0bfabe9caf | ||
![]() |
e42d18d43b | ||
![]() |
c3c6394400 | ||
![]() |
8e2197c8db | ||
![]() |
aad4808953 | ||
![]() |
ae0a891045 | ||
![]() |
0450f53d94 | ||
![]() |
7cc9dcca42 | ||
![]() |
623b8537f1 | ||
![]() |
abdf103e53 | ||
![]() |
5d509ac9df | ||
![]() |
c010c36789 | ||
![]() |
a03e5a416f | ||
![]() |
fbf9e190a5 | ||
![]() |
7dd2dbe3f2 | ||
![]() |
f60d00d272 | ||
![]() |
1ba9344512 | ||
![]() |
8887ad6ebc | ||
![]() |
21fe5ebe3c | ||
![]() |
d51f9de753 | ||
![]() |
d8ac3a68db | ||
![]() |
cdee73d858 | ||
![]() |
445a5beca5 | ||
![]() |
935326b383 | ||
![]() |
cb14407e95 | ||
![]() |
1fe69e06e0 | ||
![]() |
bb27ac8b31 | ||
![]() |
71a26a63bc | ||
![]() |
fd64e5c4af | ||
![]() |
2efec882e1 | ||
![]() |
35c2cbc0b8 | ||
![]() |
95127af8ca | ||
![]() |
50638a9a7a | ||
![]() |
91a4f2688f | ||
![]() |
42bea18cfe | ||
![]() |
473c5aa7a8 | ||
![]() |
6a3eac53e0 | ||
![]() |
01b795eaea | ||
![]() |
2442a4cb95 | ||
![]() |
60c5f5110e | ||
![]() |
7ec84f1b4c | ||
![]() |
d2bbc9c6f7 | ||
![]() |
ebfb4901d4 | ||
![]() |
c762314868 | ||
![]() |
7cef01b1ce | ||
![]() |
a739002a01 | ||
![]() |
4b8f2c9217 | ||
![]() |
353aee522e | ||
![]() |
d90a288496 | ||
![]() |
94fe2ca2e7 | ||
![]() |
ed3f0e7bb8 | ||
![]() |
5f68acabcd | ||
![]() |
10e72e3cb7 | ||
![]() |
42675ffa0d | ||
![]() |
ef4c3f9402 | ||
![]() |
05b450ce77 | ||
![]() |
5047286d1c | ||
![]() |
13b5c95aab | ||
![]() |
9aaa229216 | ||
![]() |
c89378988e | ||
![]() |
92ea48d457 | ||
![]() |
05db18d215 | ||
![]() |
a41eba9f46 | ||
![]() |
7a5fa42c67 | ||
![]() |
c8fb4dc556 | ||
![]() |
0b1db8b814 | ||
![]() |
311697616c | ||
![]() |
bf68b3b26c | ||
![]() |
cdf27e6454 | ||
![]() |
dcf048cb5a | ||
![]() |
b6129a4312 | ||
![]() |
4cb6eea9d4 | ||
![]() |
79cf9a3754 | ||
![]() |
50675f5667 | ||
![]() |
c386a4656d | ||
![]() |
70d7573742 | ||
![]() |
b1f2c91f1c | ||
![]() |
f2ebc3d4c9 | ||
![]() |
781e85a8f1 | ||
![]() |
14c47abb5f | ||
![]() |
58decda5c5 | ||
![]() |
ea43c38063 | ||
![]() |
b886b79d4d | ||
![]() |
78fa213cd9 | ||
![]() |
a747a97626 | ||
![]() |
dd2ae0b265 | ||
![]() |
8d6fe6c16d | ||
![]() |
8b100ea58d | ||
![]() |
66d1974d3f | ||
![]() |
a895173e14 | ||
![]() |
792e5a352f | ||
![]() |
ab8270cb25 | ||
![]() |
249e6a7785 | ||
![]() |
df2a1bd491 | ||
![]() |
559e3dc01a | ||
![]() |
c485fb917e | ||
![]() |
9145161c53 | ||
![]() |
575528693e | ||
![]() |
f22f17eb42 | ||
![]() |
cc210f41cb | ||
![]() |
64ab02446e | ||
![]() |
1e56692db1 | ||
![]() |
11eda8993a | ||
![]() |
aa45c15f2e | ||
![]() |
49dbf34ad4 | ||
![]() |
320e7788b7 |
46
.github/CODE_OF_CONDUCT.md
vendored
|
@ -1,46 +0,0 @@
|
|||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at hi@planetpeanut.uk. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
14
.github/CONTRIBUTING.md
vendored
|
@ -1,14 +0,0 @@
|
|||
Hey there!
|
||||
|
||||
I'm Hylke, the creator of this project. It's about time I wrote something up about how to contribute to SparkleShare, so here goes...
|
||||
|
||||
Contributions to SparkleShare are always welcome! I'm not a great coder. I like to design icons and interfaces, so there are always bugs or things that can be done better. Take a look at the [list of open issues](https://github.com/hbons/SparkleShare/issues). Smaller issues or places where refactoring is needed are marked with `FIXME` or `TODO` in the source code. If you have a fix for SparkleShare, simply open a pull request against the master branch (keeping in mind the [[coding style]]) and if you think your change is significant enough to be copyrighted, feel free to add your name and email to the `AUTHORS` file. Releases are done at least once a month, so there won't be long waits for bug fixes.
|
||||
|
||||
SparkleShare tries to keep things simple and to stay out of people's way. Features are only added if they are essential and helpful to a majority of users. If you have a feature that you'd like to be added, please open an issue first, so there can be a discussion whether the feature is actually needed (or it may be it can be done in some other way); do not waste work on a feature that isn't actually desired. By limiting the amount of features, we can spend more time on making the core features solid in order to help people get things done.
|
||||
|
||||
Often requests come in to add preferences. I'm very pleased that we've been able to solve most problems reported and features requested without adding a "preference". Currently SparkleShare has only one preference: enabling/disabling notifications. Hopefully it will stay this way and we can withhold from adding a preference panel of some kind (but I can't rule it out). Figuring out how things can be done without burdening people with a preference is much more challenging and rewarding in my opinion. [Free Software UI](http://ometer.com/free-software-ui.html) is a great article about this topic and I recommend reading it.
|
||||
|
||||
Looking forward to your contributions! :)
|
||||
|
||||
Hylke
|
||||
|
1
.github/FUNDING.yml
vendored
|
@ -1 +0,0 @@
|
|||
github: hbons
|
20
.github/ISSUE_TEMPLATE.md
vendored
|
@ -1,20 +0,0 @@
|
|||
You can find session logs by date and version information in:
|
||||
~/.config/org.sparkleshare.SparkleShare/logs/ on Linux and macOS
|
||||
C:\Users\YOUR_USERNAME\AppData\Roaming\org.sparkleshare.SparkleShare\logs\ on Windows
|
||||
|
||||
To help us help you, please include the logs from around the time the issue occurred, as well as the SparkleShare version and info about your OS (displayed at the top of the log files). Then, tell us roughly in these steps what went wrong:
|
||||
|
||||
|
||||
### What happened:
|
||||
…
|
||||
|
||||
### What I expected to happen:
|
||||
…
|
||||
|
||||
### This happens when:
|
||||
1. …
|
||||
2. …
|
||||
3. …
|
||||
|
||||
|
||||
Thanks for reporting your issue or feature request, it helps lots!
|
34
.gitignore
vendored
|
@ -12,14 +12,31 @@
|
|||
*.sln.cache
|
||||
*.user
|
||||
*.resources
|
||||
Makefile.in
|
||||
Makefile
|
||||
intltool-*
|
||||
configure
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
bin/
|
||||
build/
|
||||
obj/
|
||||
git-*
|
||||
Sparkles/InstallationInfo.Directory.cs
|
||||
install-sh
|
||||
libtool
|
||||
ltmain.sh
|
||||
missing
|
||||
build/m4/shave/shave
|
||||
build/m4/*.m4
|
||||
build/m4/shave/shave-libtool
|
||||
SparkleLib/Defines.cs
|
||||
SparkleShare/Linux/sparkleshare
|
||||
SparkleShare/Mac/git*
|
||||
SparkleShare/Mac/*.tar.gz
|
||||
gnome-doc-utils.make
|
||||
/sparkleshare-*
|
||||
desktop.ini
|
||||
_ReSharper.*
|
||||
|
@ -28,13 +45,4 @@ _ReSharper.*
|
|||
*.wixpdb
|
||||
*.wxs
|
||||
*.dotCover
|
||||
SparkleShare/Windows/build/
|
||||
.vs/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
|
||||
|
|
34
.travis.yml
|
@ -1,34 +0,0 @@
|
|||
language: csharp
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
services:
|
||||
- docker
|
||||
- os: osx
|
||||
sudo: required
|
||||
|
||||
before_install:
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker pull ubuntu:xenial ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then wget https://dl.xamarin.com/XamarinforMac/Mac/xamarin.mac-3.0.0.393.pkg ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sudo installer -pkg xamarin.mac*.pkg -target / ; fi
|
||||
|
||||
script:
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker build --file scripts/ci/Dockerfile --tag sparkleshare:nightly . ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then msbuild /p:Configuration=ReleaseMac SparkleShare.sln ; fi
|
||||
|
||||
before_deploy:
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export DEPLOY_FILE=`docker run --name container sparkleshare:nightly find / -name sparkleshare*.tar.gz` ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker cp container:${DEPLOY_FILE} ./ ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then mv sparkleshare*.tar.gz sparkleshare-linux-nightly-${TRAVIS_COMMIT}.tar.gz ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then mv SparkleShare/Mac/bin/ReleaseMac/SparkleShare.app . ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then zip --recurse-paths sparkleshare-mac-nightly-${TRAVIS_COMMIT}.zip SparkleShare.app ; fi
|
||||
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/f1a1178baa78d1162385
|
||||
on_success: change
|
||||
on_failure: always
|
||||
on_start: never
|
||||
|
23
Makefile.am
Executable file
|
@ -0,0 +1,23 @@
|
|||
basedirs = build SparkleLib SparkleLib/Git
|
||||
|
||||
SUBDIRS = $(basedirs) $(GUISUBDIRS)
|
||||
DIST_SUBDIRS = $(basedirs) SparkleShare
|
||||
|
||||
EXTRA_DIST = \
|
||||
News.txt \
|
||||
README.md \
|
||||
legal/License_for_SparkleShare.txt \
|
||||
legal/License_for_SparkleLib.txt \
|
||||
legal/Trademark.txt \
|
||||
legal/Authors.txt \
|
||||
SparkleShare/Linux/README.md \
|
||||
SparkleShare/Linux/sparkleshare.appdata.xml
|
||||
|
||||
DISTCLEANFILES = \
|
||||
intltool-extract \
|
||||
intltool-merge \
|
||||
intltool-update \
|
||||
gnome-doc-utils.make
|
||||
|
||||
clean-local:
|
||||
rm -rf $(top_builddir)/bin
|
|
@ -1,64 +1,6 @@
|
|||
3.38.0 (Sun 29 Nov, 2020):
|
||||
|
||||
- Added support for LibRAavatar
|
||||
- Updated Gravatar cert fingerprint
|
||||
- Removed planio from supported presets
|
||||
- Support default branches that are not named 'master'
|
||||
- Added support for nightly Flatpak builds
|
||||
|
||||
|
||||
3.28.0 (Sat 14 Jul, 2018):
|
||||
|
||||
Fixed a bunch of crashes and lots of under-the-hood improvements.
|
||||
SparkleShare will now follow the GNOME release schedule and version
|
||||
number scheme as much as possible.
|
||||
|
||||
Please make sure to install the AppIndicator Support GNOME Shell extension
|
||||
(https://extensions.gnome.org/extension/615/appindicator-support/) to display
|
||||
status icons in GNOME 3.26 or later. Or start with --status-icon=gtk.
|
||||
|
||||
Linux:
|
||||
- Use the Meson build system
|
||||
- Use appindicator as the default status icon
|
||||
- Fix event log parsing for newer versions of Git
|
||||
- Flatpak improvements
|
||||
|
||||
macOS:
|
||||
- Fix the system font in eventlog and related crash
|
||||
- Fix hang when quitting the app
|
||||
|
||||
Special thanks to Thiago Santos and Renpytom for supporting the project on Patreon.
|
||||
|
||||
|
||||
2.0.1 (Tue 19 Dec, 2017):
|
||||
|
||||
- Fix files created by conflict resolution being moved to the root folder
|
||||
- On conflicts, both diverging versions plus the original version are kept
|
||||
- New app icon on Mac
|
||||
|
||||
|
||||
2.0.0 for Linux, Mac and Windows (Sun Sep 10, 2017):
|
||||
|
||||
SparkleShare 2.0 is a clean break and will be incompatible with
|
||||
the 1.x series. Repositories added using 1.0 will likely not work
|
||||
and will have to be re-synced to take advantage of 2.0 features.
|
||||
|
||||
Hylke:
|
||||
- Flatpak version now available
|
||||
- Support for Git LFS managed repositories
|
||||
- Updated Linux app icon by Sam Hewitt
|
||||
- Projects are now grouped by host/organisation
|
||||
- Prefer to use the "SparkleShare" branch if it exists remotely
|
||||
- Added a GitLab preset
|
||||
- Add an entry to GNOME's System Settings to manage notifications
|
||||
- Encrypt names and emails in history of encrypted projects
|
||||
- When conflicts are resolved "SparkleShare" is now the author and
|
||||
merge commits will be hidden from the log
|
||||
- Fix conflict resolution on encrypted files
|
||||
- Use a standalone SSH configuration instead of ssh-agent
|
||||
- Use SHA256 instead of MD5 for SSH fingerprinting
|
||||
- Dropped limited HTTPS support
|
||||
- Dropped insecure DSA key support
|
||||
1.5.1 (Sun Jul 15):
|
||||
Hylke:
|
||||
- Fix an encryption compatibility issue with different versions of OpenSSL. See #1855
|
||||
|
||||
|
||||
1.5.0 for Linux, Mac and Windows (Tue Dec 22, 2015):
|
44
README.md
|
@ -1,54 +1,34 @@
|
|||
# [SparkleShare](https://www.sparkleshare.org/)
|
||||
# SparkleShare
|
||||
|
||||
[SparkleShare](https://www.sparkleshare.org/) is a file sharing and collaboration app. It works just like Dropbox, and you can run it on your own server. It's available for Linux distributions, macOS, and Windows.
|
||||
SparkleShare is an Open Source collaboration and sharing tool that is designed to keep things simple and to stay out of your way. It's available for Linux distributions, Mac, and Windows.
|
||||
|
||||

|
||||

|
||||
|
||||
You can support this project through [💕 GitHub Sponsors](https://github.com/sponsors/hbons).
|
||||
|
||||
## How does it work?
|
||||
|
||||
SparkleShare creates a special folder on your computer. You can add remotely hosted folders (or "projects") to this folder. These projects will be automatically kept in sync with both the host and all of your peers when someone adds, removes or edits a file.
|
||||
|
||||
## Install on Ubuntu or Fedora
|
||||
|
||||
You can install the package from your distribution (likely old and not updated often), but we recommend to get our Flatpak with automatic updates to always enjoy the latest and greatest:
|
||||
## Setting up a host
|
||||
|
||||
```bash
|
||||
flatpak remote-add flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak install flathub org.sparkleshare.SparkleShare
|
||||
```
|
||||
|
||||
Now you can run SparkleShare from the apps menu.
|
||||
|
||||
**Note:** by default SparkleShare uses an AppIndicator status icon on Linux. If you use GNOME on a distribution other than Ubuntu, please install the [AppIndicator extension](https://extensions.gnome.org/extension/615/appindicator-support/). If you don't use GNOME, you can start SparkleShare with `--status-icon=gtk`.
|
||||
SparkleShare uses the version control system [Git](https://git-scm.com/) under the hood, so setting up a host yourself is relatively easy. Using your own host gives you more privacy and control, as well as lots of cheap storage space and higher transfer speeds. We've made a simple [script](https://github.com/hbons/Dazzle) that does the hard work for you. If you need to manage a lot of projects and/or users it may be worth setting up a [GitLab](https://www.gitlabhq.com) instance.
|
||||
|
||||
|
||||
## Install on macOS
|
||||
|
||||
Download the app from the [releases page](https://github.com/hbons/SparkleShare/releases).
|
||||
## Free and Open Source
|
||||
`SparkleShare` is Free and Open Source software and licensed under the [GNU General Public License version 3 or later](legal/License_for_SparkleShare.txt). You are welcome to change and redistribute it under certain conditions. Its library `SparkleLib` is licensed under the [GNU Lesser General Public License version 3 or later](legal/License_for_SparkleLib.txt).
|
||||
|
||||
|
||||
## Set up a host
|
||||
## Compiling from source
|
||||
|
||||
Under the hood SparkleShare uses the version control system [Git](https://git-scm.com/) and the large files extension [Git LFS](https://git-lfs.github.com), so setting up a host yourself is relatively easy. Using your own host gives you more privacy and control, as well as lots of cheap storage space and higher transfer speeds. We've made a simple [script](https://github.com/hbons/Dazzle) that does the hard work for you. If you need to manage a lot of projects and/or users we recommend hosting a [GitLab Community Edition](https://about.gitlab.com/installation/) instance.
|
||||
Here are instructions to build SparkleShare on [Linux distributions](SparkleShare/Linux/README.md), [Mac](SparkleShare/Mac/README.md), and [Windows](SparkleShare/Windows/README.md). Make sure to have the `git` package installed when you're building on Linux.
|
||||
|
||||
|
||||
## Build from source
|
||||
`SparkleShare` is Free and Open Source software and licensed under the [GNU GPLv3 or later](LICENSE.md). You are welcome to change and redistribute it under certain conditions. Its library `Sparkles` is licensed under the [GNU LGPLv3 or later](LICENSE_Sparkles.md).
|
||||
|
||||
Here are instructions to build SparkleShare on [Linux distributions](SparkleShare/Linux/README.md), [macOS](SparkleShare/Mac/README.md), and [Windows](SparkleShare/Windows/README.md).
|
||||
|
||||
|
||||
[](https://travis-ci.org/hbons/SparkleShare)
|
||||
[](https://gitter.im/hbons/SparkleShare?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
## Useful links
|
||||
- [sparkleshare.org](https://www.sparkleshare.org/)
|
||||
- [@SparkleShare](https://www.twitter.com/SparkleShare), [@hbons](https://www.twitter.com/hbons)
|
||||
- Community chatroom on [Gitter](https://www.gitter.im/hbons/SparkleShare)
|
||||
- [Wiki](https://www.github.com/hbons/SparkleShare/wiki)
|
||||
[Website](http://www.sparkleshare.org/), [Twitter](https://www.twitter.com/SparkleShare), [Wiki](https://www.github.com/hbons/SparkleShare/wiki), and [Source Code](https://www.github.com/hbons/SparkleShare). Join the chat: #sparkleshare on irc.gnome.org.
|
||||
|
||||
|
||||
## Finally
|
||||
|
||||
Have fun, make awesome. :)
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SparkleShare, a collaboration and sharing tool.
|
||||
// Copyright (C) 2010 Hylke Bons <hi@planetpeanut.uk>
|
||||
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
|
@ -15,15 +15,17 @@
|
|||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly:AssemblyTitle ("Sparkles")]
|
||||
[assembly:AssemblyVersion ("3.38.0")]
|
||||
[assembly:AssemblyTitle ("SparkleLib")]
|
||||
[assembly:AssemblyVersion ("1.5.1")]
|
||||
[assembly:AssemblyCopyright ("Copyright (c) 2010 Hylke Bons and others")]
|
||||
[assembly:AssemblyTrademark ("SparkleShare is a trademark of SparkleShare Ltd.")]
|
||||
|
||||
namespace Sparkles {
|
||||
namespace SparkleLib {
|
||||
|
||||
public partial class InstallationInfo {
|
||||
public const string Directory = "/usr/local/share/sparkleshare";
|
||||
public class Defines {
|
||||
public const string INSTALL_DIR = "/usr/share/sparkleshare";
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
// SparkleShare, a collaboration and sharing tool.
|
||||
// Copyright (C) 2010 Hylke Bons <hi@planetpeanut.uk>
|
||||
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
|
@ -15,16 +15,17 @@
|
|||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly:AssemblyTitle ("Sparkles")]
|
||||
[assembly:AssemblyTitle ("SparkleLib")]
|
||||
[assembly:AssemblyVersion ("@VERSION@")]
|
||||
[assembly:AssemblyCopyright ("Copyright (c) 2010 Hylke Bons and others")]
|
||||
[assembly:AssemblyTrademark ("SparkleShare is a trademark of SparkleShare Ltd.")]
|
||||
|
||||
namespace Sparkles {
|
||||
namespace SparkleLib {
|
||||
|
||||
public partial class InstallationInfo {
|
||||
public const string Directory = "@ABS_INSTALL_DIR@";
|
||||
public class Defines {
|
||||
public const string INSTALL_DIR = "@expanded_datadir@/sparkleshare";
|
||||
}
|
||||
}
|
||||
|
22
SparkleLib/Git/Makefile.am
Executable file
|
@ -0,0 +1,22 @@
|
|||
ASSEMBLY = SparkleLib.Git
|
||||
TARGET = library
|
||||
|
||||
LINK = -r:$(DIR_BIN)/SparkleLib.dll
|
||||
|
||||
SOURCES = \
|
||||
SparkleGit.cs \
|
||||
SparkleFetcherGit.cs \
|
||||
SparkleRepoGit.cs
|
||||
|
||||
|
||||
install-data-hook:
|
||||
for ASM in $(EXTRA_BUNDLE); do \
|
||||
$(INSTALL) -m 0755 $$ASM $(DESTDIR)$(moduledir); \
|
||||
done;
|
||||
|
||||
uninstall-hook:
|
||||
for ASM in $(EXTRA_BUNDLE); do \
|
||||
rm -f $(DESTDIR)$(moduledir)/`basename $$ASM`; \
|
||||
done;
|
||||
|
||||
include $(top_srcdir)/build/build.mk
|
450
SparkleLib/Git/SparkleFetcherGit.cs
Executable file
|
@ -0,0 +1,450 @@
|
|||
// SparkleShare, a collaboration and sharing tool.
|
||||
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using SparkleLib;
|
||||
|
||||
namespace SparkleLib.Git {
|
||||
|
||||
public class SparkleFetcher : SparkleFetcherSSH {
|
||||
|
||||
private SparkleGit git;
|
||||
private bool use_git_bin;
|
||||
private string cached_salt;
|
||||
|
||||
private Regex progress_regex = new Regex (@"([0-9]+)%", RegexOptions.Compiled);
|
||||
private Regex speed_regex = new Regex (@"([0-9\.]+) ([KM])iB/s", RegexOptions.Compiled);
|
||||
|
||||
private bool crypto_password_is_hashed = true;
|
||||
|
||||
private string crypto_salt {
|
||||
get {
|
||||
if (!string.IsNullOrEmpty (this.cached_salt))
|
||||
return this.cached_salt;
|
||||
|
||||
// Check if the repo's salt is stored in a branch...
|
||||
SparkleGit git = new SparkleGit (TargetFolder, "ls-remote --heads");
|
||||
string branches = git.StartAndReadStandardOutput ();
|
||||
Regex salt_regex = new Regex ("refs/heads/salt-([0-9a-f]+)");
|
||||
Match salt_match = salt_regex.Match (branches);
|
||||
|
||||
if (salt_match.Success)
|
||||
this.cached_salt = salt_match.Groups [1].Value;
|
||||
|
||||
// ...if not, create a new salt for the repo
|
||||
if (string.IsNullOrEmpty (this.cached_salt)) {
|
||||
this.cached_salt = GenerateCryptoSalt ();
|
||||
string salt_file_path = new string [] { TargetFolder, ".git", "salt" }.Combine ();
|
||||
|
||||
// Temporarily store the salt in a file, so the Repo object can
|
||||
// push it to a branch on the host later
|
||||
File.WriteAllText (salt_file_path, this.cached_salt);
|
||||
}
|
||||
|
||||
return this.cached_salt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public SparkleFetcher (SparkleFetcherInfo info) : base (info)
|
||||
{
|
||||
if (RemoteUrl.ToString ().StartsWith ("ssh+"))
|
||||
RemoteUrl = new Uri ("ssh" + RemoteUrl.ToString ().Substring (RemoteUrl.ToString ().IndexOf ("://")));
|
||||
|
||||
Uri uri = RemoteUrl;
|
||||
|
||||
if (!uri.Scheme.Equals ("ssh") && !uri.Scheme.Equals ("https") &&
|
||||
!uri.Scheme.Equals ("http") && !uri.Scheme.Equals ("git")) {
|
||||
|
||||
uri = new Uri ("ssh://" + uri);
|
||||
}
|
||||
|
||||
if (uri.Host.Equals ("gitorious.org") && !uri.Scheme.StartsWith ("http")) {
|
||||
if (!uri.AbsolutePath.Equals ("/") &&
|
||||
!uri.AbsolutePath.EndsWith (".git")) {
|
||||
|
||||
uri = new Uri ("ssh://git@gitorious.org" + uri.AbsolutePath + ".git");
|
||||
|
||||
} else {
|
||||
uri = new Uri ("ssh://git@gitorious.org" + uri.AbsolutePath);
|
||||
}
|
||||
|
||||
} else if (uri.Host.Equals ("github.com") && !uri.Scheme.StartsWith ("http")) {
|
||||
uri = new Uri ("ssh://git@github.com" + uri.AbsolutePath);
|
||||
|
||||
} else if (uri.Host.Equals ("bitbucket.org") && !uri.Scheme.StartsWith ("http")) {
|
||||
// Nothing really
|
||||
|
||||
} else {
|
||||
if (string.IsNullOrEmpty (uri.UserInfo) && !uri.Scheme.StartsWith ("http")) {
|
||||
if (uri.Port == -1)
|
||||
uri = new Uri (uri.Scheme + "://storage@" + uri.Host + uri.AbsolutePath);
|
||||
else
|
||||
uri = new Uri (uri.Scheme + "://storage@" + uri.Host + ":" + uri.Port + uri.AbsolutePath);
|
||||
}
|
||||
|
||||
this.use_git_bin = false; // TODO
|
||||
}
|
||||
|
||||
RemoteUrl = uri;
|
||||
}
|
||||
|
||||
|
||||
public override bool Fetch ()
|
||||
{
|
||||
if (!base.Fetch ())
|
||||
return false;
|
||||
|
||||
if (FetchPriorHistory) {
|
||||
this.git = new SparkleGit (SparkleConfig.DefaultConfig.TmpPath,
|
||||
"clone --progress --no-checkout \"" + RemoteUrl + "\" \"" + TargetFolder + "\"");
|
||||
|
||||
} else {
|
||||
this.git = new SparkleGit (SparkleConfig.DefaultConfig.TmpPath,
|
||||
"clone --progress --no-checkout --depth=1 \"" + RemoteUrl + "\" \"" + TargetFolder + "\"");
|
||||
}
|
||||
|
||||
this.git.StartInfo.RedirectStandardError = true;
|
||||
this.git.Start ();
|
||||
|
||||
double percentage = 1.0;
|
||||
|
||||
DateTime last_change = DateTime.Now;
|
||||
TimeSpan change_interval = new TimeSpan (0, 0, 0, 1);
|
||||
|
||||
try {
|
||||
while (!this.git.StandardError.EndOfStream) {
|
||||
string line = this.git.StandardError.ReadLine ();
|
||||
Match match = this.progress_regex.Match (line);
|
||||
|
||||
double number = 0.0;
|
||||
double speed = 0.0;
|
||||
if (match.Success) {
|
||||
try {
|
||||
number = double.Parse (match.Groups [1].Value, new CultureInfo ("en-US"));
|
||||
|
||||
} catch (FormatException) {
|
||||
SparkleLogger.LogInfo ("Git", "Error parsing progress: \"" + match.Groups [1] + "\"");
|
||||
}
|
||||
|
||||
// The pushing progress consists of two stages: the "Compressing
|
||||
// objects" stage which we count as 20% of the total progress, and
|
||||
// the "Writing objects" stage which we count as the last 80%
|
||||
if (line.Contains ("Compressing")) {
|
||||
// "Compressing objects" stage
|
||||
number = (number / 100 * 20);
|
||||
|
||||
} else {
|
||||
// "Writing objects" stage
|
||||
number = (number / 100 * 80 + 20);
|
||||
Match speed_match = this.speed_regex.Match (line);
|
||||
|
||||
if (speed_match.Success) {
|
||||
try {
|
||||
speed = double.Parse (speed_match.Groups [1].Value, new CultureInfo ("en-US")) * 1024;
|
||||
|
||||
} catch (FormatException) {
|
||||
SparkleLogger.LogInfo ("Git", "Error parsing speed: \"" + speed_match.Groups [1] + "\"");
|
||||
}
|
||||
|
||||
if (speed_match.Groups [2].Value.Equals ("M"))
|
||||
speed = speed * 1024;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
SparkleLogger.LogInfo ("Fetcher", line);
|
||||
line = line.Trim (new char [] {' ', '@'});
|
||||
|
||||
if (line.StartsWith ("fatal:", StringComparison.InvariantCultureIgnoreCase) ||
|
||||
line.StartsWith ("error:", StringComparison.InvariantCultureIgnoreCase)) {
|
||||
|
||||
base.errors.Add (line);
|
||||
|
||||
} else if (line.StartsWith ("WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!")) {
|
||||
base.errors.Add ("warning: Remote host identification has changed!");
|
||||
|
||||
} else if (line.StartsWith ("WARNING: POSSIBLE DNS SPOOFING DETECTED!")) {
|
||||
base.errors.Add ("warning: Possible DNS spoofing detected!");
|
||||
}
|
||||
}
|
||||
|
||||
if (number >= percentage) {
|
||||
percentage = number;
|
||||
|
||||
if (DateTime.Compare (last_change, DateTime.Now.Subtract (change_interval)) < 0) {
|
||||
base.OnProgressChanged (percentage, speed);
|
||||
last_change = DateTime.Now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception) {
|
||||
IsActive = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
this.git.WaitForExit ();
|
||||
|
||||
if (this.git.ExitCode == 0) {
|
||||
while (percentage < 100) {
|
||||
percentage += 25;
|
||||
|
||||
if (percentage >= 100)
|
||||
break;
|
||||
|
||||
Thread.Sleep (500);
|
||||
base.OnProgressChanged (percentage, 0);
|
||||
}
|
||||
|
||||
base.OnProgressChanged (100, 0);
|
||||
|
||||
InstallConfiguration ();
|
||||
InstallExcludeRules ();
|
||||
InstallAttributeRules ();
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override bool IsFetchedRepoEmpty {
|
||||
get {
|
||||
SparkleGit git = new SparkleGit (TargetFolder, "rev-parse HEAD");
|
||||
git.StartAndWaitForExit ();
|
||||
|
||||
return (git.ExitCode != 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void EnableFetchedRepoCrypto (string password)
|
||||
{
|
||||
// Set up the encryption filter
|
||||
SparkleGit git_config_smudge = new SparkleGit (TargetFolder,
|
||||
"config filter.encryption.smudge \"openssl enc -d -aes-256-cbc -base64 -S -md md5 " + this.crypto_salt +
|
||||
" -pass file:.git/info/encryption_password\"");
|
||||
|
||||
SparkleGit git_config_clean = new SparkleGit (TargetFolder,
|
||||
"config filter.encryption.clean \"openssl enc -e -aes-256-cbc -base64 -S -md md5 " + this.crypto_salt +
|
||||
" -pass file:.git/info/encryption_password\"");
|
||||
|
||||
git_config_smudge.StartAndWaitForExit ();
|
||||
git_config_clean.StartAndWaitForExit ();
|
||||
|
||||
// Pass all files through the encryption filter
|
||||
string git_attributes_file_path = new string [] { TargetFolder, ".git", "info", "attributes" }.Combine ();
|
||||
File.WriteAllText (git_attributes_file_path, "\n* filter=encryption");
|
||||
|
||||
// Store the password
|
||||
string password_file_path = new string [] { TargetFolder, ".git", "info", "encryption_password" }.Combine ();
|
||||
|
||||
if (this.crypto_password_is_hashed)
|
||||
File.WriteAllText (password_file_path, password.SHA256 (this.crypto_salt));
|
||||
else
|
||||
File.WriteAllText (password_file_path, password);
|
||||
}
|
||||
|
||||
|
||||
public override bool IsFetchedRepoPasswordCorrect (string password)
|
||||
{
|
||||
string password_check_file_path = Path.Combine (TargetFolder, ".sparkleshare");
|
||||
|
||||
if (!File.Exists (password_check_file_path)) {
|
||||
SparkleGit git = new SparkleGit (TargetFolder, "show HEAD:.sparkleshare");
|
||||
string output = git.StartAndReadStandardOutput ();
|
||||
|
||||
if (git.ExitCode == 0)
|
||||
File.WriteAllText (password_check_file_path, output);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
Process process = new Process ();
|
||||
process.EnableRaisingEvents = true;
|
||||
process.StartInfo.FileName = "openssl";
|
||||
process.StartInfo.WorkingDirectory = TargetFolder;
|
||||
process.StartInfo.UseShellExecute = false;
|
||||
process.StartInfo.RedirectStandardOutput = true;
|
||||
process.StartInfo.CreateNoWindow = true;
|
||||
|
||||
string [] possible_passwords = new string [] {
|
||||
password.SHA256 (this.crypto_salt),
|
||||
password
|
||||
};
|
||||
|
||||
int i = 0;
|
||||
foreach (string possible_password in possible_passwords) {
|
||||
process.StartInfo.Arguments = "enc -d -aes-256-cbc -base64 -pass pass:\"" + possible_password + "\"" +
|
||||
" -in \"" + password_check_file_path + "\"";
|
||||
|
||||
SparkleLogger.LogInfo ("Cmd | " + System.IO.Path.GetFileName (process.StartInfo.WorkingDirectory),
|
||||
System.IO.Path.GetFileName (process.StartInfo.FileName) + " " + process.StartInfo.Arguments);
|
||||
|
||||
process.Start ();
|
||||
process.WaitForExit ();
|
||||
|
||||
if (process.ExitCode == 0) {
|
||||
if (i > 0)
|
||||
this.crypto_password_is_hashed = false;
|
||||
|
||||
File.Delete (password_check_file_path);
|
||||
return true;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public override void Stop ()
|
||||
{
|
||||
try {
|
||||
if (this.git != null && !this.git.HasExited) {
|
||||
this.git.Kill ();
|
||||
this.git.Dispose ();
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
SparkleLogger.LogInfo ("Fetcher", "Failed to dispose properly", e);
|
||||
}
|
||||
|
||||
if (Directory.Exists (TargetFolder)) {
|
||||
try {
|
||||
Directory.Delete (TargetFolder, true /* Recursive */ );
|
||||
SparkleLogger.LogInfo ("Fetcher", "Deleted '" + TargetFolder + "'");
|
||||
|
||||
} catch (Exception e) {
|
||||
SparkleLogger.LogInfo ("Fetcher", "Failed to delete '" + TargetFolder + "'", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void Complete ()
|
||||
{
|
||||
if (!IsFetchedRepoEmpty) {
|
||||
SparkleGit git = new SparkleGit (TargetFolder, "checkout --quiet HEAD");
|
||||
git.StartAndWaitForExit ();
|
||||
}
|
||||
|
||||
base.Complete ();
|
||||
}
|
||||
|
||||
|
||||
private void InstallConfiguration ()
|
||||
{
|
||||
string [] settings = new string [] {
|
||||
"core.autocrlf input",
|
||||
"core.quotepath false", // Don't quote "unusual" characters in path names
|
||||
"core.ignorecase false", // Be case sensitive explicitly to work on Mac
|
||||
"core.filemode false", // Ignore permission changes
|
||||
"core.precomposeunicode true", // Use the same Unicode form on all filesystems
|
||||
"core.safecrlf false",
|
||||
"core.excludesfile \"\"",
|
||||
"core.packedGitLimit 128m", // Some memory limiting options
|
||||
"core.packedGitWindowSize 128m",
|
||||
"pack.deltaCacheSize 128m",
|
||||
"pack.packSizeLimit 128m",
|
||||
"pack.windowMemory 128m",
|
||||
"push.default matching"
|
||||
};
|
||||
|
||||
if (SparkleBackend.Platform == PlatformID.Win32NT)
|
||||
settings [0] = "core.autocrlf true";
|
||||
|
||||
foreach (string setting in settings) {
|
||||
SparkleGit git_config = new SparkleGit (TargetFolder, "config " + setting);
|
||||
git_config.StartAndWaitForExit ();
|
||||
}
|
||||
|
||||
if (this.use_git_bin)
|
||||
InstallGitBinConfiguration ();
|
||||
}
|
||||
|
||||
|
||||
public void InstallGitBinConfiguration ()
|
||||
{
|
||||
string [] settings = new string [] {
|
||||
"core.bigFileThreshold 1024g",
|
||||
"filter.bin.clean \"git bin clean %f\"",
|
||||
"filter.bin.smudge \"git bin smudge\""
|
||||
};
|
||||
|
||||
foreach (string setting in settings) {
|
||||
SparkleGit git_config = new SparkleGit (TargetFolder, "config " + setting);
|
||||
git_config.StartAndWaitForExit ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Add a .gitignore file to the repo
|
||||
private void InstallExcludeRules ()
|
||||
{
|
||||
string git_info_path = new string [] { TargetFolder, ".git", "info" }.Combine ();
|
||||
|
||||
if (!Directory.Exists (git_info_path))
|
||||
Directory.CreateDirectory (git_info_path);
|
||||
|
||||
string exclude_rules = string.Join (Environment.NewLine, ExcludeRules);
|
||||
string exclude_rules_file_path = new string [] { git_info_path, "exclude" }.Combine ();
|
||||
|
||||
File.WriteAllText (exclude_rules_file_path, exclude_rules);
|
||||
}
|
||||
|
||||
|
||||
private void InstallAttributeRules ()
|
||||
{
|
||||
string attribute_rules_file_path = new string [] { TargetFolder, ".git", "info", "attributes" }.Combine ();
|
||||
TextWriter writer = new StreamWriter (attribute_rules_file_path);
|
||||
|
||||
if (this.use_git_bin) {
|
||||
writer.WriteLine ("* filter=bin binary");
|
||||
|
||||
} else {
|
||||
// Compile a list of files we don't want Git to compress.
|
||||
// Not compressing already compressed files decreases memory usage and increases speed
|
||||
string [] extensions = new string [] {
|
||||
"jpg", "jpeg", "png", "tiff", "gif", // Images
|
||||
"flac", "mp3", "ogg", "oga", // Audio
|
||||
"avi", "mov", "mpg", "mpeg", "mkv", "ogv", "ogx", "webm", // Video
|
||||
"zip", "gz", "bz", "bz2", "rpm", "deb", "tgz", "rar", "ace", "7z", "pak", "tc", "iso", ".dmg" // Archives
|
||||
};
|
||||
|
||||
foreach (string extension in extensions) {
|
||||
writer.WriteLine ("*." + extension + " -delta");
|
||||
writer.WriteLine ("*." + extension.ToUpper () + " -delta");
|
||||
}
|
||||
|
||||
writer.WriteLine ("*.txt text");
|
||||
writer.WriteLine ("*.TXT text");
|
||||
}
|
||||
|
||||
writer.Close ();
|
||||
}
|
||||
}
|
||||
}
|
166
SparkleLib/Git/SparkleGit.cs
Normal file
|
@ -0,0 +1,166 @@
|
|||
// SparkleShare, a collaboration and sharing tool.
|
||||
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using SparkleLib;
|
||||
|
||||
namespace SparkleLib.Git {
|
||||
|
||||
public abstract class SparkleProcess : Process {
|
||||
|
||||
public SparkleProcess (string path, string args) : base ()
|
||||
{
|
||||
StartInfo.FileName = path;
|
||||
StartInfo.Arguments = args;
|
||||
}
|
||||
|
||||
|
||||
new public void Start ()
|
||||
{
|
||||
SparkleLogger.LogInfo ("Cmd | " + System.IO.Path.GetFileName (StartInfo.WorkingDirectory),
|
||||
System.IO.Path.GetFileName (StartInfo.FileName) + " " + StartInfo.Arguments);
|
||||
|
||||
try {
|
||||
base.Start ();
|
||||
|
||||
} catch (Exception e) {
|
||||
SparkleLogger.LogInfo ("Cmd", "Couldn't execute command: " + e.Message);
|
||||
Environment.Exit (-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void StartAndWaitForExit ()
|
||||
{
|
||||
Start ();
|
||||
WaitForExit ();
|
||||
}
|
||||
|
||||
|
||||
public string StartAndReadStandardOutput ()
|
||||
{
|
||||
Start ();
|
||||
|
||||
// Reading the standard output HAS to go before
|
||||
// WaitForExit, or it will hang forever on output > 4096 bytes
|
||||
string output = StandardOutput.ReadToEnd ();
|
||||
WaitForExit ();
|
||||
|
||||
return output.TrimEnd ();
|
||||
}
|
||||
|
||||
|
||||
public string StartAndReadStandardError ()
|
||||
{
|
||||
StartInfo.RedirectStandardError = true;
|
||||
Start ();
|
||||
|
||||
// Reading the standard output HAS to go before
|
||||
// WaitForExit, or it will hang forever on output > 4096 bytes
|
||||
string output = StandardError.ReadToEnd ();
|
||||
WaitForExit ();
|
||||
|
||||
return output.TrimEnd ();
|
||||
}
|
||||
|
||||
|
||||
protected string LocateCommand (string name)
|
||||
{
|
||||
string [] possible_command_paths = new string [] {
|
||||
Environment.GetFolderPath (Environment.SpecialFolder.Personal) + "/bin/" + name,
|
||||
Defines.INSTALL_DIR + "/bin/" + name,
|
||||
"/usr/local/bin/" + name,
|
||||
"/usr/bin/" + name,
|
||||
"/opt/local/bin/" + name
|
||||
};
|
||||
|
||||
foreach (string path in possible_command_paths) {
|
||||
if (File.Exists (path))
|
||||
return path;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class SparkleGit : SparkleProcess {
|
||||
|
||||
public static string ExecPath;
|
||||
public static string GitPath;
|
||||
public static string SSHPath;
|
||||
|
||||
|
||||
public SparkleGit (string path, string args) : base (path, args)
|
||||
{
|
||||
if (string.IsNullOrEmpty (GitPath))
|
||||
GitPath = LocateCommand ("git");
|
||||
|
||||
EnableRaisingEvents = true;
|
||||
StartInfo.FileName = GitPath;
|
||||
StartInfo.RedirectStandardOutput = true;
|
||||
StartInfo.UseShellExecute = false;
|
||||
StartInfo.WorkingDirectory = path;
|
||||
StartInfo.CreateNoWindow = true;
|
||||
|
||||
if (StartInfo.EnvironmentVariables.ContainsKey ("LANG"))
|
||||
StartInfo.EnvironmentVariables ["LANG"] = "en_US";
|
||||
else
|
||||
StartInfo.EnvironmentVariables.Add ("LANG", "en_US");
|
||||
|
||||
if (StartInfo.EnvironmentVariables.ContainsKey ("GIT_TERMINAL_PROMPT"))
|
||||
StartInfo.EnvironmentVariables ["GIT_TERMINAL_PROMPT"] = "0";
|
||||
else
|
||||
StartInfo.EnvironmentVariables.Add ("GIT_TERMINAL_PROMPT", "0");
|
||||
|
||||
if (!string.IsNullOrEmpty (SSHPath)) {
|
||||
if (StartInfo.EnvironmentVariables.ContainsKey ("GIT_SSH"))
|
||||
StartInfo.EnvironmentVariables ["GIT_SSH"] = SSHPath;
|
||||
else
|
||||
StartInfo.EnvironmentVariables.Add ("GIT_SSH", SSHPath);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty (ExecPath))
|
||||
StartInfo.Arguments = args;
|
||||
else
|
||||
StartInfo.Arguments = "--exec-path=\"" + ExecPath + "\" " + args;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class SparkleGitBin : SparkleProcess {
|
||||
|
||||
public static string GitBinPath;
|
||||
|
||||
|
||||
public SparkleGitBin (string path, string args) : base (path, args)
|
||||
{
|
||||
if (string.IsNullOrEmpty (GitBinPath))
|
||||
GitBinPath = LocateCommand ("git-bin");
|
||||
|
||||
EnableRaisingEvents = true;
|
||||
StartInfo.FileName = GitBinPath;
|
||||
StartInfo.RedirectStandardOutput = true;
|
||||
StartInfo.UseShellExecute = false;
|
||||
StartInfo.WorkingDirectory = path;
|
||||
StartInfo.CreateNoWindow = true;
|
||||
StartInfo.Arguments = args;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
|
@ -8,12 +8,11 @@
|
|||
<ProjectGuid>{009FDCD7-1D57-4202-BB6D-8477D8C6B8EE}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Sparkles.Git</RootNamespace>
|
||||
<AssemblyName>Sparkles.Git</AssemblyName>
|
||||
<RootNamespace>SparkleLib.Git</RootNamespace>
|
||||
<AssemblyName>SparkleLib.Git</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ReleaseVersion>
|
||||
</ReleaseVersion>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<Optimize>True</Optimize>
|
||||
|
@ -28,33 +27,6 @@
|
|||
<DefineConstants>TRACE DEBUG</DefineConstants>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseMac|AnyCPU' ">
|
||||
<Optimize>True</Optimize>
|
||||
<OutputPath>..\..\bin\</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugMac|AnyCPU' ">
|
||||
<Optimize>False</Optimize>
|
||||
<OutputPath>bin\DebugMac</OutputPath>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DefineConstants>TRACE DEBUG</DefineConstants>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugWindows|AnyCPU'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>..\..\bin\</OutputPath>
|
||||
<DefineConstants>TRACE DEBUG</DefineConstants>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseWindows|AnyCPU'">
|
||||
<OutputPath>..\..\bin\</OutputPath>
|
||||
<Optimize>true</Optimize>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Service Include="{B4F97281-0DBD-4835-9ED8-7DFB966E87FF}" />
|
||||
</ItemGroup>
|
||||
|
@ -74,16 +46,14 @@
|
|||
</Target>
|
||||
-->
|
||||
<ItemGroup>
|
||||
<Compile Include="Git.Fetcher.cs" />
|
||||
<Compile Include="Git.Command.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Git.Repository.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Sparkles.csproj">
|
||||
<ProjectReference Include="..\SparkleLib.csproj">
|
||||
<Project>{2C914413-B31C-4362-93C7-1AE34F09112A}</Project>
|
||||
<Name>Sparkles</Name>
|
||||
<Name>SparkleLib</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="SparkleFetcherGit.cs" />
|
||||
<Compile Include="SparkleGit.cs" />
|
||||
<Compile Include="SparkleRepoGit.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
1225
SparkleLib/Git/SparkleRepoGit.cs
Normal file
32
SparkleLib/Makefile.am
Executable file
|
@ -0,0 +1,32 @@
|
|||
ASSEMBLY = SparkleLib
|
||||
TARGET = library
|
||||
|
||||
ASSEMBLY_INFO_SOURCE = Defines.cs
|
||||
|
||||
SOURCES = \
|
||||
SparkleBackend.cs \
|
||||
SparkleConfig.cs \
|
||||
SparkleExtensions.cs \
|
||||
SparkleFetcherBase.cs \
|
||||
SparkleFetcherSSH.cs \
|
||||
SparkleListenerBase.cs \
|
||||
SparkleListenerFactory.cs \
|
||||
SparkleListenerTcp.cs \
|
||||
SparkleLogger.cs \
|
||||
SparkleRepoBase.cs \
|
||||
SparkleUser.cs \
|
||||
SparkleWatcher.cs \
|
||||
SparkleWrappers.cs
|
||||
|
||||
|
||||
install-data-hook:
|
||||
for ASM in $(EXTRA_BUNDLE); do \
|
||||
$(INSTALL) -m 0755 $$ASM $(DESTDIR)$(moduledir); \
|
||||
done;
|
||||
|
||||
uninstall-hook:
|
||||
for ASM in $(EXTRA_BUNDLE); do \
|
||||
rm -f $(DESTDIR)$(moduledir)/`basename $$ASM`; \
|
||||
done;
|
||||
|
||||
include $(top_srcdir)/build/build.mk
|
60
SparkleLib/SparkleBackend.cs
Executable file
|
@ -0,0 +1,60 @@
|
|||
// SparkleShare, a collaboration and sharing tool.
|
||||
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SparkleLib {
|
||||
|
||||
public static class SparkleBackend {
|
||||
|
||||
public static string Version {
|
||||
get {
|
||||
string version = "" + Assembly.GetExecutingAssembly ().GetName ().Version;
|
||||
return version.Substring (0, version.Length - 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This fixes the PlatformID enumeration for MacOSX in Environment.OSVersion.Platform,
|
||||
// which is intentionally broken in Mono for historical reasons
|
||||
public static PlatformID Platform {
|
||||
get {
|
||||
IntPtr buf = IntPtr.Zero;
|
||||
|
||||
try {
|
||||
buf = Marshal.AllocHGlobal (8192);
|
||||
|
||||
if (uname (buf) == 0 && Marshal.PtrToStringAnsi (buf) == "Darwin")
|
||||
return PlatformID.MacOSX;
|
||||
|
||||
} catch {
|
||||
} finally {
|
||||
if (buf != IntPtr.Zero)
|
||||
Marshal.FreeHGlobal (buf);
|
||||
}
|
||||
|
||||
return Environment.OSVersion.Platform;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[DllImport ("libc")]
|
||||
private static extern int uname (IntPtr buf);
|
||||
}
|
||||
}
|
189
Sparkles/Configuration.cs → SparkleLib/SparkleConfig.cs
Normal file → Executable file
|
@ -1,9 +1,9 @@
|
|||
// SparkleShare, a collaboration and sharing tool.
|
||||
// Copyright (C) 2010 Hylke Bons <hi@planetpeanut.uk>
|
||||
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
|
@ -16,74 +16,51 @@
|
|||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Sparkles {
|
||||
namespace SparkleLib {
|
||||
|
||||
public class Configuration : XmlDocument {
|
||||
public class SparkleConfig : XmlDocument {
|
||||
|
||||
private static Lazy<Configuration> ConfigLazy = new Lazy<Configuration> (() => {
|
||||
string app_data_path = Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData);
|
||||
|
||||
if (InstallationInfo.OperatingSystem != OS.Windows && InstallationInfo.OperatingSystem != OS.macOS)
|
||||
app_data_path = Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.Personal), ".config");
|
||||
|
||||
string config_path = Path.Combine (app_data_path, "org.sparkleshare.SparkleShare");
|
||||
|
||||
return new Configuration (config_path, "projects.xml");
|
||||
});
|
||||
|
||||
public static Configuration DefaultConfiguration { get { return ConfigLazy.Value; } }
|
||||
public static SparkleConfig DefaultConfig;
|
||||
public static bool DebugMode = true;
|
||||
|
||||
public readonly string DirectoryPath;
|
||||
public readonly string FilePath;
|
||||
public readonly string TmpPath;
|
||||
public readonly string BinPath;
|
||||
public string AvatarProvider;
|
||||
|
||||
public readonly string LogFilePath;
|
||||
public string FullPath;
|
||||
public string TmpPath;
|
||||
public string LogFilePath;
|
||||
|
||||
|
||||
public string HomePath {
|
||||
get {
|
||||
if (InstallationInfo.OperatingSystem == OS.Windows)
|
||||
if (SparkleBackend.Platform == PlatformID.Win32NT)
|
||||
return Environment.GetFolderPath (Environment.SpecialFolder.UserProfile);
|
||||
|
||||
return Environment.GetFolderPath (Environment.SpecialFolder.Personal);
|
||||
else
|
||||
return Environment.GetFolderPath (Environment.SpecialFolder.Personal);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public string FoldersPath {
|
||||
get {
|
||||
if (GetConfigOption ("folders_path") != null)
|
||||
if (GetConfigOption ("folders_path") != null)
|
||||
return GetConfigOption ("folders_path");
|
||||
|
||||
return Path.Combine (HomePath, "SparkleShare");
|
||||
else
|
||||
return Path.Combine (HomePath, "SparkleShare");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Configuration (string config_path, string config_file_name)
|
||||
public SparkleConfig (string config_path, string config_file_name)
|
||||
{
|
||||
FilePath = Path.Combine (config_path, config_file_name);
|
||||
DirectoryPath = config_path;
|
||||
|
||||
BinPath = Path.Combine (config_path, "bin");
|
||||
|
||||
if (!Directory.Exists (BinPath))
|
||||
Directory.CreateDirectory (BinPath);
|
||||
|
||||
FullPath = Path.Combine (config_path, config_file_name);
|
||||
string logs_path = Path.Combine (config_path, "logs");
|
||||
|
||||
int i = 1;
|
||||
do {
|
||||
LogFilePath = Path.Combine (
|
||||
logs_path, "log_" + DateTime.Now.ToString ("yyyy-MM-dd") + "." + i + ".txt");
|
||||
logs_path, "debug_log_" + DateTime.Now.ToString ("yyyy-MM-dd") + "." + i + ".txt");
|
||||
|
||||
i++;
|
||||
|
||||
|
@ -93,7 +70,7 @@ namespace Sparkles {
|
|||
Directory.CreateDirectory (logs_path);
|
||||
|
||||
// Delete logs older than a week
|
||||
foreach (FileInfo file in new DirectoryInfo (logs_path).GetFiles ("log*.txt")) {
|
||||
foreach (FileInfo file in new DirectoryInfo (logs_path).GetFiles ("debug_log*.txt")) {
|
||||
if (file.LastWriteTime < DateTime.Now.AddDays (-7))
|
||||
file.Delete ();
|
||||
}
|
||||
|
@ -102,7 +79,7 @@ namespace Sparkles {
|
|||
Directory.CreateDirectory (config_path);
|
||||
|
||||
try {
|
||||
Load (FilePath);
|
||||
Load (FullPath);
|
||||
|
||||
} catch (TypeInitializationException) {
|
||||
CreateInitialConfig ();
|
||||
|
@ -111,59 +88,83 @@ namespace Sparkles {
|
|||
CreateInitialConfig ();
|
||||
|
||||
} catch (XmlException) {
|
||||
var file = new FileInfo (FilePath);
|
||||
FileInfo file = new FileInfo (FullPath);
|
||||
|
||||
if (file.Length == 0) {
|
||||
File.Delete (FilePath);
|
||||
File.Delete (FullPath);
|
||||
CreateInitialConfig ();
|
||||
|
||||
} else {
|
||||
throw;
|
||||
throw new XmlException (FullPath + " does not contain a valid config XML structure.");
|
||||
}
|
||||
|
||||
} finally {
|
||||
TmpPath = Path.Combine (DirectoryPath, "tmp");
|
||||
Load (FullPath);
|
||||
TmpPath = Path.Combine (FoldersPath, ".tmp");
|
||||
Directory.CreateDirectory (TmpPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CreateInitialConfig ()
|
||||
private void CreateInitialConfig ()
|
||||
{
|
||||
string user_name = Environment.UserName;
|
||||
string user_name = "Unknown";
|
||||
|
||||
if (InstallationInfo.OperatingSystem != OS.Windows) {
|
||||
if (SparkleBackend.Platform == PlatformID.Unix ||
|
||||
SparkleBackend.Platform == PlatformID.MacOSX) {
|
||||
|
||||
user_name = Environment.UserName;
|
||||
if (string.IsNullOrEmpty (user_name))
|
||||
user_name = "Unknown";
|
||||
else
|
||||
// On Unix systems the user name may have commas appended
|
||||
user_name = user_name.TrimEnd (',');
|
||||
user_name = user_name.TrimEnd (",".ToCharArray ());
|
||||
|
||||
} else {
|
||||
user_name = Environment.UserName;
|
||||
}
|
||||
|
||||
XElement xml =
|
||||
new XElement ("sparkleshare",
|
||||
new XElement ("user",
|
||||
new XElement ("name", user_name),
|
||||
new XElement ("email", "Unknown")
|
||||
),
|
||||
new XElement ("notifications", bool.TrueString)
|
||||
);
|
||||
|
||||
LoadXml (xml.ToString ());
|
||||
|
||||
string n = Environment.NewLine;
|
||||
File.WriteAllText (FullPath,
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + n +
|
||||
"<sparkleshare>" + n +
|
||||
" <user>" + n +
|
||||
" <name>" + user_name + "</name>" + n +
|
||||
" <email>Unknown</email>" + n +
|
||||
" </user>" + n +
|
||||
"</sparkleshare>");
|
||||
}
|
||||
|
||||
|
||||
public User User {
|
||||
public SparkleUser User {
|
||||
get {
|
||||
string name = SelectSingleNode ("/sparkleshare/user/name/text()").Value;
|
||||
string email = SelectSingleNode ("/sparkleshare/user/email/text()").Value;
|
||||
XmlNode name_node = SelectSingleNode ("/sparkleshare/user/name/text()");
|
||||
XmlNode email_node = SelectSingleNode ("/sparkleshare/user/email/text()");
|
||||
string user_name = name_node.Value;
|
||||
string user_email = email_node.Value;
|
||||
|
||||
return new User (name, email);
|
||||
SparkleUser user = new SparkleUser (user_name, user_email);
|
||||
|
||||
string [] private_key_file_paths = Directory.GetFiles (Path.GetDirectoryName (FullPath), "*.key");
|
||||
|
||||
if (private_key_file_paths.Length > 0) {
|
||||
user.PrivateKey = File.ReadAllText (private_key_file_paths [0]);
|
||||
user.PrivateKeyFilePath = private_key_file_paths [0];
|
||||
|
||||
user.PublicKey = File.ReadAllText (private_key_file_paths [0] + ".pub");
|
||||
user.PublicKeyFilePath = private_key_file_paths [0] + ".pub";
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
set {
|
||||
SelectSingleNode ("/sparkleshare/user/name/text()").InnerText = value.Name;
|
||||
SelectSingleNode ("/sparkleshare/user/email/text()").InnerText = value.Email;
|
||||
SparkleUser user = (SparkleUser) value;
|
||||
|
||||
XmlNode name_node = SelectSingleNode ("/sparkleshare/user/name/text()");
|
||||
XmlNode email_node = SelectSingleNode ("/sparkleshare/user/email/text()");
|
||||
name_node.InnerText = user.Name;
|
||||
email_node.InnerText = user.Email;
|
||||
|
||||
Save ();
|
||||
}
|
||||
|
@ -172,12 +173,13 @@ namespace Sparkles {
|
|||
|
||||
public List<string> Folders {
|
||||
get {
|
||||
var folders = new List<string> ();
|
||||
List<string> folders = new List<string> ();
|
||||
|
||||
foreach (XmlNode node_folder in SelectNodes ("/sparkleshare/folder"))
|
||||
folders.Add (node_folder ["name"].InnerText);
|
||||
|
||||
folders.Sort ();
|
||||
|
||||
return folders;
|
||||
}
|
||||
}
|
||||
|
@ -220,31 +222,31 @@ namespace Sparkles {
|
|||
}
|
||||
|
||||
|
||||
public void RenameFolder (string identifier, string new_name)
|
||||
public void RenameFolder (string identifier, string name)
|
||||
{
|
||||
XmlNode node_folder = SelectSingleNode (
|
||||
string.Format ("/sparkleshare/folder[identifier=\"{0}\"]", identifier));
|
||||
|
||||
node_folder ["name"].InnerText = new_name;
|
||||
node_folder ["name"].InnerText = name;
|
||||
Save ();
|
||||
}
|
||||
|
||||
|
||||
public string BackendByName (string name)
|
||||
public string GetBackendForFolder (string name)
|
||||
{
|
||||
return FolderValueByKey (name, "backend");
|
||||
return GetFolderValue (name, "backend");
|
||||
}
|
||||
|
||||
|
||||
public string IdentifierByName (string name)
|
||||
public string GetIdentifierForFolder (string name)
|
||||
{
|
||||
return FolderValueByKey (name, "identifier");
|
||||
return GetFolderValue (name, "identifier");
|
||||
}
|
||||
|
||||
|
||||
public string UrlByName (string name)
|
||||
public string GetUrlForFolder (string name)
|
||||
{
|
||||
return FolderValueByKey (name, "url");
|
||||
return GetFolderValue (name, "url");
|
||||
}
|
||||
|
||||
|
||||
|
@ -266,7 +268,7 @@ namespace Sparkles {
|
|||
|
||||
public bool SetFolderOptionalAttribute (string folder_name, string key, string value)
|
||||
{
|
||||
XmlNode folder = FolderByName (folder_name);
|
||||
XmlNode folder = GetFolder (folder_name);
|
||||
|
||||
if (folder == null)
|
||||
return false;
|
||||
|
@ -288,7 +290,7 @@ namespace Sparkles {
|
|||
|
||||
public string GetFolderOptionalAttribute (string folder_name, string key)
|
||||
{
|
||||
XmlNode folder = FolderByName (folder_name);
|
||||
XmlNode folder = GetFolder (folder_name);
|
||||
|
||||
if (folder != null) {
|
||||
if (folder [key] != null)
|
||||
|
@ -329,31 +331,34 @@ namespace Sparkles {
|
|||
}
|
||||
|
||||
Save ();
|
||||
Logger.LogInfo ("Config", "Updated option " + name + ":" + content);
|
||||
SparkleLogger.LogInfo ("Config", "Updated option " + name + ":" + content);
|
||||
}
|
||||
|
||||
|
||||
XmlNode FolderByName (string name)
|
||||
private XmlNode GetFolder (string name)
|
||||
{
|
||||
return SelectSingleNode (string.Format ("/sparkleshare/folder[name=\"{0}\"]", name));
|
||||
}
|
||||
|
||||
|
||||
string FolderValueByKey (string name, string key)
|
||||
|
||||
|
||||
private string GetFolderValue (string name, string key)
|
||||
{
|
||||
XmlNode folder = FolderByName(name);
|
||||
|
||||
XmlNode folder = GetFolder(name);
|
||||
|
||||
if ((folder != null) && (folder [key] != null))
|
||||
return folder [key].InnerText;
|
||||
|
||||
return null;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
void Save ()
|
||||
private void Save ()
|
||||
{
|
||||
Save (FilePath);
|
||||
Logger.LogInfo ("Config", "Wrote to '" + FilePath + "'");
|
||||
if (!File.Exists (FullPath))
|
||||
throw new FileNotFoundException (FullPath + " does not exist");
|
||||
|
||||
Save (FullPath);
|
||||
SparkleLogger.LogInfo ("Config", "Wrote to '" + FullPath + "'");
|
||||
}
|
||||
}
|
||||
}
|
93
Sparkles/Extensions.cs → SparkleLib/SparkleExtensions.cs
Normal file → Executable file
|
@ -1,5 +1,5 @@
|
|||
// SparkleShare, a collaboration and sharing tool.
|
||||
// Copyright (C) 2010 Hylke Bons <hi@planetpeanut.uk>
|
||||
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
|
@ -20,10 +20,31 @@ using System.IO;
|
|||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace Sparkles {
|
||||
namespace SparkleLib {
|
||||
|
||||
public static class Extensions {
|
||||
|
||||
public static string Combine (this string [] parts)
|
||||
{
|
||||
string new_path = "";
|
||||
|
||||
foreach (string part in parts)
|
||||
new_path = Path.Combine (new_path, part);
|
||||
|
||||
return new_path;
|
||||
}
|
||||
|
||||
|
||||
public static string SHA1 (this string s)
|
||||
{
|
||||
SHA1 sha1 = new SHA1CryptoServiceProvider ();
|
||||
byte [] bytes = ASCIIEncoding.Default.GetBytes (s);
|
||||
byte [] sha1_bytes = sha1.ComputeHash (bytes);
|
||||
|
||||
return BitConverter.ToString (sha1_bytes).ToLower ().Replace ("-", "");
|
||||
}
|
||||
|
||||
|
||||
public static string SHA256 (this string s)
|
||||
{
|
||||
SHA256 sha256 = new SHA256CryptoServiceProvider ();
|
||||
|
@ -54,75 +75,25 @@ namespace Sparkles {
|
|||
}
|
||||
|
||||
|
||||
public static string AESEncrypt (this string plain_text, string password)
|
||||
{
|
||||
Random random = new Random ();
|
||||
byte [] salt_bytes = new Byte [16];
|
||||
random.NextBytes (salt_bytes);
|
||||
|
||||
string salt = Convert.ToBase64String (salt_bytes);
|
||||
password = (password + salt).SHA256 ().Substring (0, 32);
|
||||
|
||||
RijndaelManaged aes = new RijndaelManaged () {
|
||||
KeySize = 256,
|
||||
BlockSize = 128,
|
||||
Mode = CipherMode.CBC,
|
||||
Padding = PaddingMode.PKCS7,
|
||||
Key = Encoding.UTF8.GetBytes (password),
|
||||
IV = Encoding.UTF8.GetBytes (password.ToCharArray (), 0, 16)
|
||||
};
|
||||
|
||||
byte [] buffer = Encoding.UTF8.GetBytes (plain_text);
|
||||
ICryptoTransform crypto = aes.CreateEncryptor (aes.Key, aes.IV);
|
||||
byte [] encrypted_bytes = crypto.TransformFinalBlock (buffer, 0, buffer.Length);
|
||||
|
||||
return salt + "_" + Convert.ToBase64String (encrypted_bytes);
|
||||
}
|
||||
|
||||
|
||||
public static string AESDecrypt (this string s, string password)
|
||||
{
|
||||
string salt = s.Substring (0, s.IndexOf ("_"));
|
||||
password = (password + salt).SHA256 ().Substring (0, 32);
|
||||
|
||||
RijndaelManaged aes = new RijndaelManaged () {
|
||||
KeySize = 256,
|
||||
BlockSize = 128,
|
||||
Mode = CipherMode.CBC,
|
||||
Padding = PaddingMode.PKCS7,
|
||||
Key = Encoding.UTF8.GetBytes (password),
|
||||
IV = Encoding.UTF8.GetBytes (password.ToCharArray (), 0, 16)
|
||||
};
|
||||
|
||||
string encrypted_text = s.Substring (s.IndexOf ("_") + 1);
|
||||
byte [] buffer = Convert.FromBase64String (encrypted_text);
|
||||
ICryptoTransform crypto = aes.CreateDecryptor (aes.Key, aes.IV);
|
||||
byte [] decrypted_bytes = crypto.TransformFinalBlock (buffer, 0, buffer.Length);
|
||||
|
||||
return Encoding.UTF8.GetString (decrypted_bytes);
|
||||
}
|
||||
|
||||
|
||||
// Format a file size nicely with small caps.
|
||||
// Example: 1048576 becomes "1 ᴍʙ"
|
||||
public static string ToSize (this double byte_count)
|
||||
{
|
||||
if (byte_count >= 1099511627776)
|
||||
return string.Format ("{0:##.##} ᴛʙ", Math.Round (byte_count / 1099511627776, 2));
|
||||
return String.Format ("{0:##.##} ᴛʙ", Math.Round (byte_count / 1099511627776, 2));
|
||||
else if (byte_count >= 1073741824)
|
||||
return string.Format ("{0:##.##} ɢʙ", Math.Round (byte_count / 1073741824, 1));
|
||||
return String.Format ("{0:##.##} ɢʙ", Math.Round (byte_count / 1073741824, 1));
|
||||
else if (byte_count >= 1048576)
|
||||
return string.Format ("{0:##.##} ᴍʙ", Math.Round (byte_count / 1048576, 1));
|
||||
return String.Format ("{0:##.##} ᴍʙ", Math.Round (byte_count / 1048576, 1));
|
||||
else if (byte_count >= 1024)
|
||||
return string.Format ("{0:##.##} ᴋʙ", Math.Round (byte_count / 1024, 0));
|
||||
return String.Format ("{0:##.##} ᴋʙ", Math.Round (byte_count / 1024, 0));
|
||||
else
|
||||
return byte_count + " ʙ";
|
||||
return byte_count.ToString () + " ʙ";
|
||||
}
|
||||
|
||||
|
||||
public static bool IsSymlink (this string path)
|
||||
public static bool IsSymlink (this FileSystemInfo file)
|
||||
{
|
||||
var file = new FileInfo (path);
|
||||
return ((file.Attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint);
|
||||
}
|
||||
|
||||
|
@ -130,7 +101,7 @@ namespace Sparkles {
|
|||
public static string ToPrettyDate (this DateTime timestamp)
|
||||
{
|
||||
TimeSpan time_diff = DateTime.Now.Subtract (timestamp);
|
||||
var day_diff = (int) time_diff.TotalDays;
|
||||
int day_diff = (int) time_diff.TotalDays;
|
||||
DateTime yesterday = DateTime.Today.AddDays (-1);
|
||||
|
||||
if (timestamp >= yesterday && timestamp < DateTime.Today) {
|
||||
|
@ -144,12 +115,12 @@ namespace Sparkles {
|
|||
|
||||
} else if (day_diff < 31) {
|
||||
if (day_diff < 14)
|
||||
return "a week ago";
|
||||
return "last week";
|
||||
else
|
||||
return string.Format ("{0} weeks ago", Math.Ceiling ((double) day_diff / 7));
|
||||
|
||||
} else if (day_diff < 62) {
|
||||
return "a month ago";
|
||||
return "last month";
|
||||
|
||||
} else {
|
||||
return string.Format ("{0} months ago", Math.Ceiling ((double) day_diff / 31));
|
380
Sparkles/BaseFetcher.cs → SparkleLib/SparkleFetcherBase.cs
Normal file → Executable file
|
@ -1,5 +1,5 @@
|
|||
// SparkleShare, a collaboration and sharing tool.
|
||||
// Copyright (C) 2010 Hylke Bons <hi@planetpeanut.uk>
|
||||
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
|
@ -17,244 +17,70 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading;
|
||||
|
||||
namespace Sparkles {
|
||||
namespace SparkleLib {
|
||||
|
||||
public class SparkleFetcherInfo {
|
||||
public string Address; // TODO: Uri object
|
||||
public string Address;
|
||||
public string RemotePath;
|
||||
|
||||
public string Fingerprint;
|
||||
|
||||
public string Backend;
|
||||
public string Fingerprint;
|
||||
public string TargetDirectory;
|
||||
public string AnnouncementsUrl;
|
||||
public bool FetchPriorHistory;
|
||||
|
||||
public string AnnouncementsUrl; // TODO: Uri object
|
||||
}
|
||||
|
||||
|
||||
public abstract class BaseFetcher {
|
||||
public abstract class SparkleFetcherBase {
|
||||
|
||||
public event Action Started = delegate { };
|
||||
public event Action Failed = delegate { };
|
||||
|
||||
public event FinishedEventHandler Finished = delegate { };
|
||||
public delegate void FinishedEventHandler (StorageType storage_type, string [] warnings);
|
||||
public delegate void FinishedEventHandler (bool repo_is_encrypted, bool repo_is_empty, string [] warnings);
|
||||
|
||||
public event ProgressChangedEventHandler ProgressChanged = delegate { };
|
||||
public delegate void ProgressChangedEventHandler (double percentage, double speed, string information);
|
||||
public delegate void ProgressChangedEventHandler (double percentage, double speed);
|
||||
|
||||
|
||||
public abstract bool Fetch ();
|
||||
public abstract void Stop ();
|
||||
public bool IsActive { get; protected set; }
|
||||
public double ProgressPercentage { get; private set; }
|
||||
public double ProgressSpeed { get; private set; }
|
||||
|
||||
|
||||
protected abstract bool IsFetchedRepoEmpty { get; }
|
||||
public StorageType FetchedRepoStorageType { get; protected set; }
|
||||
public abstract bool IsFetchedRepoEmpty { get; }
|
||||
public abstract bool IsFetchedRepoPasswordCorrect (string password);
|
||||
public abstract void EnableFetchedRepoCrypto (string password);
|
||||
|
||||
public readonly List<StorageTypeInfo> AvailableStorageTypes = new List<StorageTypeInfo> ();
|
||||
|
||||
public double ProgressPercentage { get; private set; }
|
||||
public double ProgressSpeed { get; private set; }
|
||||
|
||||
public Uri RemoteUrl { get; protected set; }
|
||||
public string RequiredFingerprint { get; protected set; }
|
||||
public readonly bool FetchPriorHistory;
|
||||
public readonly bool FetchPriorHistory = false;
|
||||
public string TargetFolder { get; protected set; }
|
||||
public bool IsActive { get; protected set; }
|
||||
public string Identifier;
|
||||
public SparkleFetcherInfo OriginalFetcherInfo;
|
||||
|
||||
|
||||
protected List<string> warnings = new List<string> ();
|
||||
protected List<string> errors = new List<string> ();
|
||||
|
||||
public string [] Warnings {
|
||||
get {
|
||||
return warnings.ToArray ();
|
||||
return this.warnings.ToArray ();
|
||||
}
|
||||
}
|
||||
|
||||
public string [] Errors {
|
||||
get {
|
||||
return errors.ToArray ();
|
||||
return this.errors.ToArray ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected List<string> warnings = new List<string> ();
|
||||
protected List<string> errors = new List<string> ();
|
||||
|
||||
protected BaseFetcher (SparkleFetcherInfo info)
|
||||
{
|
||||
FetchedRepoStorageType = StorageType.Unknown;
|
||||
|
||||
AvailableStorageTypes.Add (
|
||||
new StorageTypeInfo (StorageType.Plain, "Plain Storage", "Nothing fancy;\nmaximum compatibility"));
|
||||
|
||||
OriginalFetcherInfo = info;
|
||||
RequiredFingerprint = info.Fingerprint;
|
||||
FetchPriorHistory = info.FetchPriorHistory;
|
||||
string remote_path = info.RemotePath.Trim ("/".ToCharArray ());
|
||||
string address = info.Address;
|
||||
|
||||
if (address.EndsWith ("/", StringComparison.InvariantCulture))
|
||||
address = address.Substring (0, address.Length - 1);
|
||||
|
||||
if (!remote_path.StartsWith ("/", StringComparison.InvariantCulture))
|
||||
remote_path = "/" + remote_path;
|
||||
|
||||
if (!address.Contains ("://"))
|
||||
address = "ssh://" + address;
|
||||
|
||||
TargetFolder = info.TargetDirectory;
|
||||
|
||||
RemoteUrl = new Uri (address + remote_path);
|
||||
IsActive = false;
|
||||
}
|
||||
|
||||
|
||||
Thread thread;
|
||||
|
||||
public void Start ()
|
||||
{
|
||||
IsActive = true;
|
||||
Started ();
|
||||
|
||||
Logger.LogInfo ("Fetcher", TargetFolder + " | Fetching folder: " + RemoteUrl);
|
||||
|
||||
try {
|
||||
if (Directory.Exists (TargetFolder))
|
||||
Directory.Delete (TargetFolder, recursive: true);
|
||||
|
||||
} catch (IOException) {
|
||||
errors.Add ("\"" + TargetFolder + "\" is read-only.");
|
||||
Failed ();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
thread = new Thread (() => {
|
||||
if (Fetch ()) {
|
||||
Thread.Sleep (500);
|
||||
Logger.LogInfo ("Fetcher", "Finished");
|
||||
|
||||
IsActive = false;
|
||||
Finished (FetchedRepoStorageType, Warnings);
|
||||
|
||||
} else {
|
||||
Thread.Sleep (500);
|
||||
|
||||
if (IsActive) {
|
||||
Logger.LogInfo ("Fetcher", "Failed");
|
||||
Failed ();
|
||||
|
||||
} else {
|
||||
Logger.LogInfo ("Fetcher", "Failed: cancelled by user");
|
||||
}
|
||||
|
||||
IsActive = false;
|
||||
}
|
||||
});
|
||||
|
||||
thread.Start ();
|
||||
}
|
||||
|
||||
|
||||
public void Complete ()
|
||||
{
|
||||
if (FetchedRepoStorageType == StorageType.Unknown) {
|
||||
Complete (StorageType.Plain);
|
||||
return;
|
||||
}
|
||||
|
||||
this.Complete (FetchedRepoStorageType);
|
||||
}
|
||||
|
||||
|
||||
public virtual string Complete (StorageType storage_type)
|
||||
{
|
||||
FetchedRepoStorageType = storage_type;
|
||||
|
||||
if (IsFetchedRepoEmpty)
|
||||
CreateInitialChangeSet ();
|
||||
|
||||
return Path.GetRandomFileName ().SHA256 ();
|
||||
}
|
||||
|
||||
|
||||
// Create an initial change set when the
|
||||
// user has fetched an empty remote folder
|
||||
void CreateInitialChangeSet ()
|
||||
{
|
||||
string n = Environment.NewLine;
|
||||
string file_path = Path.Combine (TargetFolder, "SparkleShare.txt");
|
||||
|
||||
var uri_builder = new UriBuilder (RemoteUrl);
|
||||
|
||||
// Don't expose possible username or password
|
||||
if (RemoteUrl.Scheme.StartsWith ("http", StringComparison.InvariantCultureIgnoreCase)) {
|
||||
uri_builder.UserName = "";
|
||||
uri_builder.Password = "";
|
||||
}
|
||||
|
||||
string text = "Congratulations, you've successfully created a SparkleShare repository!" + n +
|
||||
n +
|
||||
"Any files you add or change in this folder will be automatically synced to " + n +
|
||||
uri_builder.Uri + " and everyone connected to it." + n +
|
||||
n +
|
||||
"SparkleShare is an Open Source software program that helps people collaborate and " + n +
|
||||
"share files. If you like what we do, consider buying us a beer: http://www.sparkleshare.org/" + n +
|
||||
n +
|
||||
"Have fun! :)" + n;
|
||||
|
||||
if (FetchedRepoStorageType == StorageType.Encrypted)
|
||||
text = text.Replace ("a SparkleShare repository", "an encrypted SparkleShare repository");
|
||||
|
||||
File.WriteAllText (file_path, text);
|
||||
}
|
||||
|
||||
|
||||
DateTime progress_last_change = DateTime.Now;
|
||||
|
||||
protected void OnProgressChanged (double percentage, double speed, string information) {
|
||||
// Only trigger the ProgressChanged event once per second
|
||||
if (DateTime.Compare (this.progress_last_change, DateTime.Now.Subtract (new TimeSpan (0, 0, 0, 1))) >= 0)
|
||||
return;
|
||||
|
||||
ProgressChanged (percentage, speed, information);
|
||||
}
|
||||
|
||||
|
||||
public static string GetBackend (string address)
|
||||
{
|
||||
if (address.StartsWith ("ssh+", StringComparison.InvariantCultureIgnoreCase)) {
|
||||
string backend = address.Substring (0, address.IndexOf ("://", StringComparison.InvariantCulture));
|
||||
backend = backend.Substring (4);
|
||||
|
||||
return char.ToUpper (backend [0]) + backend.Substring (1);
|
||||
}
|
||||
|
||||
return "Git";
|
||||
}
|
||||
|
||||
|
||||
public virtual string FormatName ()
|
||||
{
|
||||
return Path.GetFileName (RemoteUrl.AbsolutePath);
|
||||
}
|
||||
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
if (thread != null)
|
||||
thread.Abort ();
|
||||
}
|
||||
|
||||
|
||||
protected string [] ExcludeRules = {
|
||||
protected string [] ExcludeRules = new string [] {
|
||||
"*.autosave", // Various autosaving apps
|
||||
"*~", // gedit and emacs
|
||||
".~lock.*", // LibreOffice
|
||||
|
@ -278,5 +104,169 @@ namespace Sparkles {
|
|||
"*<*", "*>*", "*:*", "*\"*", "*|*", "*\\?*", "*\\**", "*\\\\*" // Not allowed on Windows systems,
|
||||
// see (http://msdn.microsoft.com/en-us/library/aa365247(v=vs.85).aspx)
|
||||
};
|
||||
|
||||
|
||||
private Thread thread;
|
||||
|
||||
|
||||
public SparkleFetcherBase (SparkleFetcherInfo info)
|
||||
{
|
||||
OriginalFetcherInfo = info;
|
||||
RequiredFingerprint = info.Fingerprint;
|
||||
FetchPriorHistory = info.FetchPriorHistory;
|
||||
string remote_path = info.RemotePath.Trim ("/".ToCharArray ());
|
||||
string address = info.Address;
|
||||
|
||||
if (address.EndsWith ("/"))
|
||||
address = address.Substring (0, address.Length - 1);
|
||||
|
||||
if (!remote_path.StartsWith ("/"))
|
||||
remote_path = "/" + remote_path;
|
||||
|
||||
if (!address.Contains ("://"))
|
||||
address = "ssh://" + address;
|
||||
|
||||
TargetFolder = info.TargetDirectory;
|
||||
|
||||
RemoteUrl = new Uri (address + remote_path);
|
||||
IsActive = false;
|
||||
}
|
||||
|
||||
|
||||
public void Start ()
|
||||
{
|
||||
IsActive = true;
|
||||
Started ();
|
||||
|
||||
SparkleLogger.LogInfo ("Fetcher", TargetFolder + " | Fetching folder: " + RemoteUrl);
|
||||
|
||||
try {
|
||||
if (Directory.Exists (TargetFolder))
|
||||
Directory.Delete (TargetFolder, true);
|
||||
|
||||
} catch (IOException) {
|
||||
this.errors.Add ("\"" + TargetFolder + "\" is read-only.");
|
||||
Failed ();
|
||||
return;
|
||||
}
|
||||
|
||||
this.thread = new Thread (() => {
|
||||
if (Fetch ()) {
|
||||
Thread.Sleep (500);
|
||||
SparkleLogger.LogInfo ("Fetcher", "Finished");
|
||||
|
||||
IsActive = false;
|
||||
|
||||
bool repo_is_encrypted = (RemoteUrl.AbsolutePath.Contains ("-crypto") ||
|
||||
RemoteUrl.Host.Equals ("sparkleshare.net"));
|
||||
|
||||
Finished (repo_is_encrypted, IsFetchedRepoEmpty, Warnings);
|
||||
|
||||
} else {
|
||||
Thread.Sleep (500);
|
||||
|
||||
if (IsActive) {
|
||||
SparkleLogger.LogInfo ("Fetcher", "Failed");
|
||||
Failed ();
|
||||
|
||||
} else {
|
||||
SparkleLogger.LogInfo ("Fetcher", "Failed: cancelled by user");
|
||||
}
|
||||
|
||||
IsActive = false;
|
||||
}
|
||||
});
|
||||
|
||||
this.thread.Start ();
|
||||
}
|
||||
|
||||
|
||||
public virtual void Complete ()
|
||||
{
|
||||
string identifier_path = Path.Combine (TargetFolder, ".sparkleshare");
|
||||
|
||||
if (File.Exists (identifier_path)) {
|
||||
Identifier = File.ReadAllText (identifier_path).Trim ();
|
||||
|
||||
} else {
|
||||
Identifier = CreateIdentifier ();
|
||||
File.WriteAllText (identifier_path, Identifier);
|
||||
|
||||
if (IsFetchedRepoEmpty)
|
||||
CreateInitialChangeSet ();
|
||||
}
|
||||
|
||||
File.SetAttributes (identifier_path, FileAttributes.Hidden);
|
||||
}
|
||||
|
||||
|
||||
// Create an initial change set when the
|
||||
// user has fetched an empty remote folder
|
||||
private void CreateInitialChangeSet ()
|
||||
{
|
||||
string file_path = Path.Combine (TargetFolder, "SparkleShare.txt");
|
||||
string n = Environment.NewLine;
|
||||
|
||||
UriBuilder uri_builder = new UriBuilder (RemoteUrl);
|
||||
|
||||
if (RemoteUrl.Scheme.Contains ("http")) {
|
||||
uri_builder.UserName = "";
|
||||
uri_builder.Password = "";
|
||||
}
|
||||
|
||||
string text = "Congratulations, you've successfully created a SparkleShare repository!" + n +
|
||||
n +
|
||||
"Any files you add or change in this folder will be automatically synced to " + n +
|
||||
uri_builder.ToString () + " and everyone connected to it." + n +
|
||||
n +
|
||||
"SparkleShare is an Open Source software program that helps people collaborate and " + n +
|
||||
"share files. If you like what we do, consider buying us a beer: http://www.sparkleshare.org/" + n +
|
||||
n +
|
||||
"Have fun! :)" + n;
|
||||
|
||||
if (RemoteUrl.AbsolutePath.Contains ("-crypto") || RemoteUrl.Host.Equals ("sparkleshare.net"))
|
||||
text = text.Replace ("a SparkleShare repository", "an encrypted SparkleShare repository");
|
||||
|
||||
File.WriteAllText (file_path, text);
|
||||
}
|
||||
|
||||
|
||||
public static string CreateIdentifier ()
|
||||
{
|
||||
return Path.GetRandomFileName ().SHA1 ();
|
||||
}
|
||||
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
if (this.thread != null)
|
||||
this.thread.Abort ();
|
||||
}
|
||||
|
||||
|
||||
protected void OnProgressChanged (double percentage, double speed) {
|
||||
ProgressChanged (percentage, speed);
|
||||
}
|
||||
|
||||
|
||||
protected string GenerateCryptoSalt ()
|
||||
{
|
||||
string salt = Path.GetRandomFileName ().SHA1 ();
|
||||
return salt.Substring (0, 16);
|
||||
}
|
||||
|
||||
|
||||
public static string GetBackend (string address)
|
||||
{
|
||||
if (address.StartsWith ("ssh+")) {
|
||||
string backend = address.Substring (0, address.IndexOf ("://"));
|
||||
backend = backend.Substring (4);
|
||||
|
||||
return char.ToUpper (backend [0]) + backend.Substring (1);
|
||||
|
||||
} else {
|
||||
return "Git";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
173
SparkleLib/SparkleFetcherSSH.cs
Normal file
|
@ -0,0 +1,173 @@
|
|||
// SparkleShare, a collaboration and sharing tool.
|
||||
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading;
|
||||
|
||||
namespace SparkleLib {
|
||||
|
||||
public abstract class SparkleFetcherSSH : SparkleFetcherBase {
|
||||
|
||||
public SparkleFetcherSSH (SparkleFetcherInfo info) : base (info)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public override bool Fetch ()
|
||||
{
|
||||
if (RemoteUrl.Host.EndsWith (".onion")) {
|
||||
// Tor has special domain names called ".onion addresses". They can only be
|
||||
// resolved by using a proxy via tor. While the rest of the openssh suite
|
||||
// fully supports proxying, ssh-keyscan does not, so we can't use it for .onion
|
||||
SparkleLogger.LogInfo ("Auth", "using tor .onion address skipping ssh-keyscan");
|
||||
|
||||
} else if (!RemoteUrl.Scheme.StartsWith ("http")) {
|
||||
string host_key = FetchHostKey ();
|
||||
|
||||
if (string.IsNullOrEmpty (RemoteUrl.Host) || host_key == null) {
|
||||
SparkleLogger.LogInfo ("Auth", "Could not fetch host key");
|
||||
this.errors.Add ("error: Could not fetch host key");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool warn = true;
|
||||
if (RequiredFingerprint != null) {
|
||||
string host_fingerprint;
|
||||
|
||||
try {
|
||||
host_fingerprint = DeriveFingerprint (host_key);
|
||||
|
||||
} catch (InvalidOperationException e) {
|
||||
// "Unapproved cryptographic algorithms" won't work when FIPS is enabled on Windows.
|
||||
// Software like Cisco AnyConnect can demand this feature is on, so we show an error
|
||||
SparkleLogger.LogInfo ("Auth", "Unable to derive fingerprint: ", e);
|
||||
this.errors.Add ("error: Can't check fingerprint due to FIPS being enabled");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (host_fingerprint == null || !RequiredFingerprint.Equals (host_fingerprint)) {
|
||||
SparkleLogger.LogInfo ("Auth", "Fingerprint doesn't match");
|
||||
this.errors.Add ("error: Host fingerprint doesn't match");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
warn = false;
|
||||
SparkleLogger.LogInfo ("Auth", "Fingerprint matches");
|
||||
|
||||
} else {
|
||||
SparkleLogger.LogInfo ("Auth", "Skipping fingerprint check");
|
||||
}
|
||||
|
||||
AcceptHostKey (host_key, warn);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private string FetchHostKey ()
|
||||
{
|
||||
SparkleLogger.LogInfo ("Auth", "Fetching host key for " + RemoteUrl.Host);
|
||||
|
||||
Process process = new Process ();
|
||||
process.StartInfo.FileName = "ssh-keyscan";
|
||||
process.StartInfo.WorkingDirectory = SparkleConfig.DefaultConfig.TmpPath;
|
||||
process.StartInfo.UseShellExecute = false;
|
||||
process.StartInfo.RedirectStandardOutput = true;
|
||||
process.StartInfo.CreateNoWindow = true;
|
||||
process.EnableRaisingEvents = true;
|
||||
|
||||
string [] key_types = {"rsa", "dsa", "ecdsa"};
|
||||
|
||||
foreach (string key_type in key_types) {
|
||||
if (RemoteUrl.Port < 1)
|
||||
process.StartInfo.Arguments = "-t " + key_type + " -p 22 " + RemoteUrl.Host;
|
||||
else
|
||||
process.StartInfo.Arguments = "-t " + key_type + " -p " + RemoteUrl.Port + " " + RemoteUrl.Host;
|
||||
|
||||
SparkleLogger.LogInfo ("Cmd", process.StartInfo.FileName + " " + process.StartInfo.Arguments);
|
||||
|
||||
process.Start ();
|
||||
string host_key = process.StandardOutput.ReadToEnd ().Trim ();
|
||||
process.WaitForExit ();
|
||||
|
||||
if (process.ExitCode == 0 && !string.IsNullOrWhiteSpace (host_key))
|
||||
return host_key;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private string DeriveFingerprint (string public_key)
|
||||
{
|
||||
try {
|
||||
MD5 md5 = new MD5CryptoServiceProvider ();
|
||||
string key = public_key.Split (" ".ToCharArray ()) [2];
|
||||
byte [] b64_bytes = Convert.FromBase64String (key);
|
||||
byte [] md5_bytes = md5.ComputeHash (b64_bytes);
|
||||
string fingerprint = BitConverter.ToString (md5_bytes);
|
||||
|
||||
return fingerprint.ToLower ().Replace ("-", ":");
|
||||
|
||||
} catch (Exception e) {
|
||||
SparkleLogger.LogInfo ("Fetcher", "Failed creating fingerprint: " + e.Message + " " + e.StackTrace);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void AcceptHostKey (string host_key, bool warn)
|
||||
{
|
||||
string ssh_config_path = Path.Combine (SparkleConfig.DefaultConfig.HomePath, ".ssh");
|
||||
string known_hosts_file_path = Path.Combine (ssh_config_path, "known_hosts");
|
||||
|
||||
if (!File.Exists (known_hosts_file_path)) {
|
||||
if (!Directory.Exists (ssh_config_path))
|
||||
Directory.CreateDirectory (ssh_config_path);
|
||||
|
||||
File.Create (known_hosts_file_path).Close ();
|
||||
}
|
||||
|
||||
string host = RemoteUrl.Host;
|
||||
string known_hosts = File.ReadAllText (known_hosts_file_path);
|
||||
string [] known_hosts_lines = File.ReadAllLines (known_hosts_file_path);
|
||||
|
||||
foreach (string line in known_hosts_lines) {
|
||||
if (line.StartsWith (host + " "))
|
||||
return;
|
||||
}
|
||||
|
||||
if (known_hosts.EndsWith ("\n"))
|
||||
File.AppendAllText (known_hosts_file_path, host_key + "\n");
|
||||
else
|
||||
File.AppendAllText (known_hosts_file_path, "\n" + host_key + "\n");
|
||||
|
||||
SparkleLogger.LogInfo ("Auth", "Accepted host key for " + host);
|
||||
|
||||
if (warn)
|
||||
this.warnings.Add ("The following host key has been accepted:\n" + DeriveFingerprint (host_key));
|
||||
}
|
||||
}
|
||||
}
|
51
SparkleLib/SparkleLib.csproj
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{2C914413-B31C-4362-93C7-1AE34F09112A}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>SparkleLib</RootNamespace>
|
||||
<AssemblyName>SparkleLib</AssemblyName>
|
||||
<ReleaseVersion>
|
||||
</ReleaseVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\bin</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ConsolePause>False</ConsolePause>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<Optimize>False</Optimize>
|
||||
<OutputPath>..\bin</OutputPath>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DefineConstants>DEBUG</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="SparkleRepoBase.cs" />
|
||||
<Compile Include="SparkleFetcherBase.cs" />
|
||||
<Compile Include="SparkleWrappers.cs" />
|
||||
<Compile Include="SparkleListenerBase.cs" />
|
||||
<Compile Include="SparkleListenerFactory.cs" />
|
||||
<Compile Include="SparkleListenerTcp.cs" />
|
||||
<Compile Include="SparkleBackend.cs" />
|
||||
<Compile Include="SparkleConfig.cs" />
|
||||
<Compile Include="SparkleWatcher.cs" />
|
||||
<Compile Include="SparkleExtensions.cs" />
|
||||
<Compile Include="SparkleUser.cs" />
|
||||
<Compile Include="SparkleLogger.cs" />
|
||||
<Compile Include="Defines.cs" />
|
||||
<Compile Include="SparkleFetcherSSH.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
20
SparkleLib/SparkleLib.sln
Executable file
|
@ -0,0 +1,20 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual Studio 2005
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SparkleLib", "SparkleLib.csproj", "{2C914413-B31C-4362-93C7-1AE34F09112A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{2C914413-B31C-4362-93C7-1AE34F09112A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2C914413-B31C-4362-93C7-1AE34F09112A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2C914413-B31C-4362-93C7-1AE34F09112A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2C914413-B31C-4362-93C7-1AE34F09112A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(MonoDevelopProperties) = preSolution
|
||||
StartupItem = SparkleLib.csproj
|
||||
EndGlobalSection
|
||||
EndGlobal
|
64
Sparkles/BaseListener.cs → SparkleLib/SparkleListenerBase.cs
Normal file → Executable file
|
@ -1,9 +1,9 @@
|
|||
// SparkleShare, a collaboration and sharing tool.
|
||||
// Copyright (C) 2010 Hylke Bons <hi@planetpeanut.uk>
|
||||
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
|
@ -19,7 +19,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Timers;
|
||||
|
||||
namespace Sparkles {
|
||||
namespace SparkleLib {
|
||||
|
||||
public enum DisconnectReason {
|
||||
None,
|
||||
|
@ -30,15 +30,15 @@ namespace Sparkles {
|
|||
|
||||
// A persistent connection to the server that
|
||||
// listens for change notifications
|
||||
public abstract class BaseListener {
|
||||
public abstract class SparkleListenerBase {
|
||||
|
||||
public event Action Connected = delegate { };
|
||||
|
||||
|
||||
public event DisconnectedEventHandler Disconnected = delegate { };
|
||||
public delegate void DisconnectedEventHandler (DisconnectReason reason);
|
||||
|
||||
public event AnnouncementReceivedEventHandler AnnouncementReceived = delegate { };
|
||||
public delegate void AnnouncementReceivedEventHandler (Announcement announcement);
|
||||
public delegate void AnnouncementReceivedEventHandler (SparkleAnnouncement announcement);
|
||||
|
||||
public readonly Uri Server;
|
||||
|
||||
|
@ -47,7 +47,7 @@ namespace Sparkles {
|
|||
public abstract bool IsConnecting { get; }
|
||||
|
||||
|
||||
protected abstract void AnnounceInternal (Announcement announcent);
|
||||
protected abstract void AnnounceInternal (SparkleAnnouncement announcent);
|
||||
protected abstract void AlsoListenToInternal (string folder_identifier);
|
||||
|
||||
protected List<string> channels = new List<string> ();
|
||||
|
@ -55,10 +55,10 @@ namespace Sparkles {
|
|||
|
||||
private int max_recent_announcements = 10;
|
||||
|
||||
private Dictionary<string, List<Announcement>> recent_announcements =
|
||||
new Dictionary<string, List<Announcement>> ();
|
||||
private Dictionary<string, List<SparkleAnnouncement>> recent_announcements =
|
||||
new Dictionary<string, List<SparkleAnnouncement>> ();
|
||||
|
||||
private Dictionary<string, Announcement> queue_up = new Dictionary<string, Announcement> ();
|
||||
private Dictionary<string, SparkleAnnouncement> queue_up = new Dictionary<string, SparkleAnnouncement> ();
|
||||
|
||||
private Timer reconnect_timer = new Timer {
|
||||
Interval = 60 * 1000,
|
||||
|
@ -66,7 +66,7 @@ namespace Sparkles {
|
|||
};
|
||||
|
||||
|
||||
public BaseListener (Uri server, string folder_identifier)
|
||||
public SparkleListenerBase (Uri server, string folder_identifier)
|
||||
{
|
||||
Server = server;
|
||||
this.channels.Add (folder_identifier);
|
||||
|
@ -81,23 +81,23 @@ namespace Sparkles {
|
|||
Reconnect ();
|
||||
}
|
||||
|
||||
public void Announce (Announcement announcement)
|
||||
public void Announce (SparkleAnnouncement announcement)
|
||||
{
|
||||
if (!IsRecentAnnouncement (announcement)) {
|
||||
if (IsConnected) {
|
||||
Logger.LogInfo ("Listener", "Announcing message " + announcement.Message +
|
||||
SparkleLogger.LogInfo ("Listener", "Announcing message " + announcement.Message +
|
||||
" to " + announcement.FolderIdentifier + " on " + Server);
|
||||
|
||||
AnnounceInternal (announcement);
|
||||
AddRecentAnnouncement (announcement);
|
||||
|
||||
} else {
|
||||
Logger.LogInfo ("Listener", "Can't send message to " + Server + ". Queuing message");
|
||||
SparkleLogger.LogInfo ("Listener", "Can't send message to " + Server + ". Queuing message");
|
||||
this.queue_up [announcement.FolderIdentifier] = announcement;
|
||||
}
|
||||
|
||||
} else {
|
||||
Logger.LogInfo ("Listener", "Already processed message " + announcement.Message +
|
||||
SparkleLogger.LogInfo ("Listener", "Already processed message " + announcement.Message +
|
||||
" to " + announcement.FolderIdentifier + " from " + Server);
|
||||
}
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ namespace Sparkles {
|
|||
this.channels.Add (channel);
|
||||
|
||||
if (IsConnected) {
|
||||
Logger.LogInfo ("Listener", "Subscribing to channel " + channel + " on " + Server);
|
||||
SparkleLogger.LogInfo ("Listener", "Subscribing to channel " + channel + " on " + Server);
|
||||
AlsoListenToInternal (channel);
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ namespace Sparkles {
|
|||
|
||||
public void Reconnect ()
|
||||
{
|
||||
Logger.LogInfo ("Listener", "Trying to reconnect to " + Server);
|
||||
SparkleLogger.LogInfo ("Listener", "Trying to reconnect to " + Server);
|
||||
Connect ();
|
||||
}
|
||||
|
||||
|
@ -125,18 +125,18 @@ namespace Sparkles {
|
|||
public void OnConnected ()
|
||||
{
|
||||
foreach (string channel in this.channels.GetRange (0, this.channels.Count)) {
|
||||
Logger.LogInfo ("Listener", "Subscribing to channel " + channel + " on " + Server);
|
||||
SparkleLogger.LogInfo ("Listener", "Subscribing to channel " + channel + " on " + Server);
|
||||
AlsoListenToInternal (channel);
|
||||
}
|
||||
|
||||
Logger.LogInfo ("Listener", "Listening for announcements on " + Server);
|
||||
SparkleLogger.LogInfo ("Listener", "Listening for announcements on " + Server);
|
||||
Connected ();
|
||||
|
||||
if (this.queue_up.Count > 0) {
|
||||
Logger.LogInfo ("Listener", "Delivering " + this.queue_up.Count + " queued messages...");
|
||||
SparkleLogger.LogInfo ("Listener", "Delivering " + this.queue_up.Count + " queued messages...");
|
||||
|
||||
foreach (KeyValuePair<string, Announcement> item in this.queue_up) {
|
||||
Announcement announcement = item.Value;
|
||||
foreach (KeyValuePair<string, SparkleAnnouncement> item in this.queue_up) {
|
||||
SparkleAnnouncement announcement = item.Value;
|
||||
Announce (announcement);
|
||||
}
|
||||
}
|
||||
|
@ -145,14 +145,14 @@ namespace Sparkles {
|
|||
|
||||
public void OnDisconnected (DisconnectReason reason, string message)
|
||||
{
|
||||
Logger.LogInfo ("Listener", "Disconnected from " + Server + ": " + message);
|
||||
SparkleLogger.LogInfo ("Listener", "Disconnected from " + Server + ": " + message);
|
||||
Disconnected (reason);
|
||||
}
|
||||
|
||||
|
||||
public void OnAnnouncement (Announcement announcement)
|
||||
public void OnAnnouncement (SparkleAnnouncement announcement)
|
||||
{
|
||||
Logger.LogInfo ("Listener", "Got message " + announcement.Message + " from " +
|
||||
SparkleLogger.LogInfo ("Listener", "Got message " + announcement.Message + " from " +
|
||||
announcement.FolderIdentifier + " on " + Server);
|
||||
|
||||
if (IsRecentAnnouncement (announcement))
|
||||
|
@ -176,13 +176,13 @@ namespace Sparkles {
|
|||
}
|
||||
|
||||
|
||||
private bool IsRecentAnnouncement (Announcement announcement)
|
||||
private bool IsRecentAnnouncement (SparkleAnnouncement announcement)
|
||||
{
|
||||
if (!this.recent_announcements.ContainsKey (announcement.FolderIdentifier)) {
|
||||
return false;
|
||||
|
||||
} else {
|
||||
foreach (Announcement recent_announcement in GetRecentAnnouncements (announcement.FolderIdentifier)) {
|
||||
foreach (SparkleAnnouncement recent_announcement in GetRecentAnnouncements (announcement.FolderIdentifier)) {
|
||||
if (recent_announcement.Message.Equals (announcement.Message))
|
||||
return true;
|
||||
}
|
||||
|
@ -192,18 +192,18 @@ namespace Sparkles {
|
|||
}
|
||||
|
||||
|
||||
private List<Announcement> GetRecentAnnouncements (string folder_identifier)
|
||||
private List<SparkleAnnouncement> GetRecentAnnouncements (string folder_identifier)
|
||||
{
|
||||
if (!this.recent_announcements.ContainsKey (folder_identifier))
|
||||
this.recent_announcements [folder_identifier] = new List<Announcement> ();
|
||||
this.recent_announcements [folder_identifier] = new List<SparkleAnnouncement> ();
|
||||
|
||||
return this.recent_announcements [folder_identifier];
|
||||
}
|
||||
|
||||
|
||||
private void AddRecentAnnouncement (Announcement announcement)
|
||||
private void AddRecentAnnouncement (SparkleAnnouncement announcement)
|
||||
{
|
||||
List<Announcement> recent_announcements =
|
||||
List<SparkleAnnouncement> recent_announcements =
|
||||
GetRecentAnnouncements (announcement.FolderIdentifier);
|
||||
|
||||
if (!IsRecentAnnouncement (announcement))
|
|
@ -1,5 +1,5 @@
|
|||
// SparkleShare, a collaboration and sharing tool.
|
||||
// Copyright (C) 2010 Hylke Bons <hi@planetpeanut.uk>
|
||||
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
|
@ -18,21 +18,21 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Sparkles {
|
||||
namespace SparkleLib {
|
||||
|
||||
public static class ListenerFactory {
|
||||
public static class SparkleListenerFactory {
|
||||
|
||||
static readonly List<BaseListener> listeners = new List<BaseListener> ();
|
||||
private static List<SparkleListenerBase> listeners = new List<SparkleListenerBase> ();
|
||||
|
||||
|
||||
public static BaseListener CreateListener (string folder_name, string folder_identifier)
|
||||
public static SparkleListenerBase CreateListener (string folder_name, string folder_identifier)
|
||||
{
|
||||
// Check if the user wants to use a global custom notification service
|
||||
string uri = Configuration.DefaultConfiguration.GetConfigOption ("announcements_url");
|
||||
string uri = SparkleConfig.DefaultConfig.GetConfigOption ("announcements_url");
|
||||
|
||||
// Check if the user wants a use a custom notification service for this folder
|
||||
if (string.IsNullOrEmpty (uri))
|
||||
uri = Configuration.DefaultConfiguration.GetFolderOptionalAttribute (folder_name, "announcements_url");
|
||||
uri = SparkleConfig.DefaultConfig.GetFolderOptionalAttribute (folder_name, "announcements_url");
|
||||
|
||||
// This is SparkleShare's centralized notification service.
|
||||
// It communicates "It's time to sync!" signals between clients.
|
||||
|
@ -40,27 +40,27 @@ namespace Sparkles {
|
|||
// Please see the SparkleShare wiki if you wish to run
|
||||
// your own service instead
|
||||
if (string.IsNullOrEmpty (uri))
|
||||
uri = "tcp://announcements.sparkleshare.org:443";
|
||||
uri = "tcp://notifications.sparkleshare.org:443";
|
||||
|
||||
var announce_uri = new Uri (uri);
|
||||
Uri announce_uri = new Uri (uri);
|
||||
|
||||
// Use only one listener per notification service to keep
|
||||
// the number of connections as low as possible
|
||||
foreach (BaseListener listener in listeners) {
|
||||
foreach (SparkleListenerBase listener in listeners) {
|
||||
if (listener.Server.Equals (announce_uri)) {
|
||||
Logger.LogInfo ("ListenerFactory", "Refered to existing listener for " + announce_uri);
|
||||
SparkleLogger.LogInfo ("ListenerFactory", "Refered to existing listener for " + announce_uri);
|
||||
|
||||
// We already seem to have a listener for this server,
|
||||
// refer to the existing one instead
|
||||
listener.AlsoListenTo (folder_identifier);
|
||||
return listener;
|
||||
return (SparkleListenerBase) listener;
|
||||
}
|
||||
}
|
||||
|
||||
listeners.Add (new TcpListener (announce_uri, folder_identifier));
|
||||
Logger.LogInfo ("ListenerFactory", "Issued new listener for " + announce_uri);
|
||||
listeners.Add (new SparkleListenerTcp (announce_uri, folder_identifier));
|
||||
SparkleLogger.LogInfo ("ListenerFactory", "Issued new listener for " + announce_uri);
|
||||
|
||||
return listeners [listeners.Count - 1];
|
||||
return (SparkleListenerBase) listeners [listeners.Count - 1];
|
||||
}
|
||||
}
|
||||
}
|
20
Sparkles/TcpListener.cs → SparkleLib/SparkleListenerTcp.cs
Normal file → Executable file
|
@ -1,5 +1,5 @@
|
|||
// SparkleShare, a collaboration and sharing tool.
|
||||
// Copyright (C) 2010 Hylke Bons <hi@planetpeanut.uk>
|
||||
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
|
@ -20,9 +20,9 @@ using System.Net.Sockets;
|
|||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace Sparkles {
|
||||
namespace SparkleLib {
|
||||
|
||||
public class TcpListener : BaseListener {
|
||||
public class SparkleListenerTcp : SparkleListenerBase {
|
||||
|
||||
private Socket socket;
|
||||
private Thread thread;
|
||||
|
@ -31,7 +31,7 @@ namespace Sparkles {
|
|||
private DateTime last_ping = DateTime.Now;
|
||||
|
||||
|
||||
public TcpListener (Uri server, string folder_identifier) : base (server, folder_identifier)
|
||||
public SparkleListenerTcp (Uri server, string folder_identifier) : base (server, folder_identifier)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ namespace Sparkles {
|
|||
if (this.socket != null)
|
||||
this.socket.Close ();
|
||||
|
||||
OnDisconnected (Sparkles.DisconnectReason.TimeOut, e.Message);
|
||||
OnDisconnected (SparkleLib.DisconnectReason.TimeOut, e.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ namespace Sparkles {
|
|||
// We've timed out, let's ping the server to
|
||||
// see if the connection is still up
|
||||
if (i == timeout) {
|
||||
Logger.LogInfo ("ListenerTcp", "Pinging " + Server);
|
||||
SparkleLogger.LogInfo ("ListenerTcp", "Pinging " + Server);
|
||||
|
||||
byte [] ping_bytes = Encoding.UTF8.GetBytes ("ping\n");
|
||||
byte [] pong_bytes = new byte [4096];
|
||||
|
@ -115,7 +115,7 @@ namespace Sparkles {
|
|||
// 10057 means "Socket is not connected"
|
||||
throw new SocketException (10057);
|
||||
|
||||
Logger.LogInfo ("ListenerTcp", "Received pong from " + Server);
|
||||
SparkleLogger.LogInfo ("ListenerTcp", "Received pong from " + Server);
|
||||
|
||||
i = 0;
|
||||
this.last_ping = DateTime.Now;
|
||||
|
@ -132,7 +132,7 @@ namespace Sparkles {
|
|||
);
|
||||
|
||||
if (sleepiness <= 0) {
|
||||
Logger.LogInfo ("ListenerTcp", "System woke up from sleep");
|
||||
SparkleLogger.LogInfo ("ListenerTcp", "System woke up from sleep");
|
||||
reason = DisconnectReason.SystemSleep;
|
||||
|
||||
// 10057 means "Socket is not connected"
|
||||
|
@ -171,7 +171,7 @@ namespace Sparkles {
|
|||
|
||||
// We have a message!
|
||||
if (!folder_identifier.Equals ("debug") && !string.IsNullOrEmpty (message))
|
||||
OnAnnouncement (new Announcement (folder_identifier, message));
|
||||
OnAnnouncement (new SparkleAnnouncement (folder_identifier, message));
|
||||
}
|
||||
|
||||
} catch (SocketException e) {
|
||||
|
@ -216,7 +216,7 @@ namespace Sparkles {
|
|||
}
|
||||
|
||||
|
||||
protected override void AnnounceInternal (Announcement announcement)
|
||||
protected override void AnnounceInternal (SparkleAnnouncement announcement)
|
||||
{
|
||||
string to_send = "announce " + announcement.FolderIdentifier + " " + announcement.Message + "\n";
|
||||
|
70
Sparkles/Logger.cs → SparkleLib/SparkleLogger.cs
Normal file → Executable file
|
@ -1,5 +1,5 @@
|
|||
// SparkleShare, a collaboration and sharing tool.
|
||||
// Copyright (C) 2010 Hylke Bons <hi@planetpeanut.uk>
|
||||
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
|
@ -18,13 +18,12 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Sparkles {
|
||||
namespace SparkleLib {
|
||||
|
||||
public static class Logger {
|
||||
|
||||
static StreamWriter log_writer = File.CreateText (Configuration.DefaultConfiguration.LogFilePath);
|
||||
static object log_writer_lock = new object ();
|
||||
public static class SparkleLogger {
|
||||
|
||||
private static Object debug_lock = new Object ();
|
||||
private static int log_size = 0;
|
||||
|
||||
public static void LogInfo (string type, string message)
|
||||
{
|
||||
|
@ -38,24 +37,25 @@ namespace Sparkles {
|
|||
string line;
|
||||
|
||||
if (string.IsNullOrEmpty (type))
|
||||
line = timestamp + " " + message;
|
||||
line = timestamp + " | " + message;
|
||||
else
|
||||
line = timestamp + " " + type + " | " + message;
|
||||
line = timestamp + " | " + type + " | " + message;
|
||||
|
||||
if (exception != null)
|
||||
line += ": " + exception.Message + " " + exception.StackTrace;
|
||||
|
||||
if (Configuration.DebugMode)
|
||||
if (SparkleConfig.DebugMode)
|
||||
Console.WriteLine (line);
|
||||
|
||||
lock (log_writer_lock) {
|
||||
try {
|
||||
log_writer.WriteLine (line);
|
||||
log_writer.Flush ();
|
||||
lock (debug_lock) {
|
||||
// Don't let the log get bigger than 1000 lines
|
||||
if (log_size >= 1000) {
|
||||
File.WriteAllText (SparkleConfig.DefaultConfig.LogFilePath, line + Environment.NewLine);
|
||||
log_size = 0;
|
||||
|
||||
} catch (Exception e) {
|
||||
Console.WriteLine (string.Format ("Could not write to log {0}: {1} {2}",
|
||||
(log_writer.BaseStream as FileStream).Name, e.Message, e.StackTrace));
|
||||
} else {
|
||||
File.AppendAllText (SparkleConfig.DefaultConfig.LogFilePath, line + Environment.NewLine);
|
||||
log_size++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,42 +63,39 @@ namespace Sparkles {
|
|||
|
||||
public static void WriteCrashReport (Exception e)
|
||||
{
|
||||
if (log_writer != null)
|
||||
log_writer.Close ();
|
||||
|
||||
string home_path = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
|
||||
|
||||
if (InstallationInfo.OperatingSystem == OS.Windows)
|
||||
if (SparkleBackend.Platform == PlatformID.Win32NT)
|
||||
home_path = Environment.GetFolderPath (Environment.SpecialFolder.UserProfile);
|
||||
|
||||
string crash_report_file_path = Path.Combine (home_path, "SparkleShare", "crash_report.txt");
|
||||
string crash_report_file_path = new string [] { home_path, "SparkleShare", "crash_report.txt" }.Combine ();
|
||||
|
||||
string n = Environment.NewLine;
|
||||
string crash_report =
|
||||
"Oops! SparkleShare has crashed... :(" + n +
|
||||
n +
|
||||
string crash_report = "Oops! SparkleShare has crashed... :(" + n + n +
|
||||
"If you want to help fix this crash, please report it at " + n +
|
||||
"https://github.com/hbons/SparkleShare/issues and include the lines below." + n +
|
||||
n +
|
||||
"Remove any sensitive information like file names, IP addresses, domain names, etc. if needed." + n +
|
||||
n +
|
||||
"------" + n +
|
||||
n;
|
||||
"https://github.com/hbons/SparkleShare/issues and include the lines below." + n + n +
|
||||
"Remove any sensitive information like file names, IP addresses, domain names, etc. if needed." + n + n +
|
||||
"------" + n + n +
|
||||
"SparkleShare version: " + SparkleLib.SparkleBackend.Version + n +
|
||||
"Operating system: " + SparkleLib.SparkleBackend.Platform + " (" + Environment.OSVersion + ")" + n;
|
||||
|
||||
crash_report += e.GetType () + ": " + e.Message + n + e.StackTrace + n + n;
|
||||
crash_report += e.GetType () + ": " + e.Message + n + e.StackTrace + n;
|
||||
|
||||
if (e.InnerException != null)
|
||||
crash_report += n + e.InnerException.Message + n + e.InnerException.StackTrace + n;
|
||||
|
||||
if (Configuration.DefaultConfiguration != null && File.Exists (Configuration.DefaultConfiguration.LogFilePath)) {
|
||||
string debug_log = File.ReadAllText (Configuration.DefaultConfiguration.LogFilePath);
|
||||
if (SparkleConfig.DefaultConfig != null && File.Exists (SparkleConfig.DefaultConfig.LogFilePath)) {
|
||||
string debug_log = File.ReadAllText (SparkleConfig.DefaultConfig.LogFilePath);
|
||||
string [] debug_lines = debug_log.Split (Environment.NewLine.ToCharArray ());
|
||||
int line_count = 50;
|
||||
|
||||
if (debug_lines.Length > line_count)
|
||||
crash_report += string.Join (n, debug_lines, (debug_lines.Length - line_count), line_count) + n;
|
||||
else
|
||||
if (debug_lines.Length > line_count) {
|
||||
crash_report += string.Join (Environment.NewLine, debug_lines,
|
||||
(debug_lines.Length - line_count), line_count) + n;
|
||||
|
||||
} else {
|
||||
crash_report += debug_log + n;
|
||||
}
|
||||
}
|
||||
|
||||
File.WriteAllText (crash_report_file_path, crash_report);
|
||||
|
@ -106,3 +103,4 @@ namespace Sparkles {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
199
Sparkles/BaseRepository.cs → SparkleLib/SparkleRepoBase.cs
Normal file → Executable file
|
@ -1,5 +1,5 @@
|
|||
// SparkleShare, a collaboration and sharing tool.
|
||||
// Copyright (C) 2010 Hylke Bons <hi@planetpeanut.uk>
|
||||
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
|
@ -22,32 +22,7 @@ using System.Threading;
|
|||
|
||||
using Timers = System.Timers;
|
||||
|
||||
namespace Sparkles {
|
||||
|
||||
public enum StorageType {
|
||||
Unknown,
|
||||
Plain,
|
||||
LargeFiles,
|
||||
Encrypted
|
||||
}
|
||||
|
||||
|
||||
public class StorageTypeInfo {
|
||||
|
||||
public readonly StorageType Type;
|
||||
|
||||
public readonly string Name;
|
||||
public readonly string Description;
|
||||
|
||||
|
||||
public StorageTypeInfo (StorageType storage_type, string name, string description)
|
||||
{
|
||||
Type = storage_type;
|
||||
|
||||
Name = name;
|
||||
Description = description;
|
||||
}
|
||||
}
|
||||
namespace SparkleLib {
|
||||
|
||||
public enum SyncStatus {
|
||||
Idle,
|
||||
|
@ -57,6 +32,7 @@ namespace Sparkles {
|
|||
Error
|
||||
}
|
||||
|
||||
|
||||
public enum ErrorStatus {
|
||||
None,
|
||||
HostUnreachable,
|
||||
|
@ -65,12 +41,11 @@ namespace Sparkles {
|
|||
DiskSpaceExceeded,
|
||||
UnreadableFiles,
|
||||
NotFound,
|
||||
IncompatibleClientServer,
|
||||
Unknown
|
||||
IncompatibleClientServer
|
||||
}
|
||||
|
||||
|
||||
public abstract class BaseRepository {
|
||||
public abstract class SparkleRepoBase {
|
||||
|
||||
public abstract bool SyncUp ();
|
||||
public abstract bool SyncDown ();
|
||||
|
@ -84,11 +59,9 @@ namespace Sparkles {
|
|||
public abstract double HistorySize { get; }
|
||||
|
||||
public abstract List<string> ExcludePaths { get; }
|
||||
public abstract List<Change> UnsyncedChanges { get; }
|
||||
public abstract List<ChangeSet> GetChangeSets ();
|
||||
public abstract List<ChangeSet> GetChangeSets (string path);
|
||||
|
||||
protected StorageType StorageType = StorageType.Plain;
|
||||
public abstract List<SparkleChange> UnsyncedChanges { get; }
|
||||
public abstract List<SparkleChangeSet> GetChangeSets ();
|
||||
public abstract List<SparkleChangeSet> GetChangeSets (string path);
|
||||
|
||||
public static bool UseCustomWatcher = false;
|
||||
|
||||
|
@ -100,7 +73,7 @@ namespace Sparkles {
|
|||
public delegate void ProgressChangedEventHandler ();
|
||||
|
||||
public event NewChangeSetEventHandler NewChangeSet = delegate { };
|
||||
public delegate void NewChangeSetEventHandler (ChangeSet change_set);
|
||||
public delegate void NewChangeSetEventHandler (SparkleChangeSet change_set);
|
||||
|
||||
public event Action ConflictResolved = delegate { };
|
||||
public event Action ChangesDetected = delegate { };
|
||||
|
@ -109,14 +82,12 @@ namespace Sparkles {
|
|||
public readonly string LocalPath;
|
||||
public readonly string Name;
|
||||
public readonly Uri RemoteUrl;
|
||||
public List<ChangeSet> ChangeSets { get; set; }
|
||||
public SyncStatus Status { get; set; }
|
||||
public List<SparkleChangeSet> ChangeSets { get; private set; }
|
||||
public SyncStatus Status { get; private set; }
|
||||
public ErrorStatus Error { get; protected set; }
|
||||
public bool IsBuffering { get; set; }
|
||||
|
||||
public bool IsBuffering { get; private set; }
|
||||
public double ProgressPercentage { get; private set; }
|
||||
public double ProgressSpeed { get; private set; }
|
||||
public string ProgressInformation { get; private set; }
|
||||
|
||||
public DateTime LastSync {
|
||||
get {
|
||||
|
@ -134,26 +105,24 @@ namespace Sparkles {
|
|||
|
||||
string id_path = Path.Combine (LocalPath, ".sparkleshare");
|
||||
|
||||
if (File.Exists (id_path)) {
|
||||
File.SetAttributes (id_path, FileAttributes.Hidden);
|
||||
if (File.Exists (id_path))
|
||||
this.identifier = File.ReadAllText (id_path).Trim ();
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty (this.identifier)) {
|
||||
return this.identifier;
|
||||
|
||||
} else {
|
||||
string config_identifier = this.local_config.IdentifierByName (Name);
|
||||
string config_identifier = this.local_config.GetIdentifierForFolder (Name);
|
||||
|
||||
if (!string.IsNullOrEmpty (config_identifier))
|
||||
this.identifier = config_identifier;
|
||||
else
|
||||
this.identifier = Path.GetRandomFileName ().SHA256 ();
|
||||
this.identifier = SparkleFetcherBase.CreateIdentifier ();
|
||||
|
||||
File.WriteAllText (id_path, this.identifier);
|
||||
File.SetAttributes (id_path, FileAttributes.Hidden);
|
||||
|
||||
Logger.LogInfo ("Local", Name + " | Assigned identifier: " + this.identifier);
|
||||
SparkleLogger.LogInfo ("Local", Name + " | Assigned identifier: " + this.identifier);
|
||||
|
||||
return this.identifier;
|
||||
}
|
||||
|
@ -161,43 +130,41 @@ namespace Sparkles {
|
|||
}
|
||||
|
||||
|
||||
protected Configuration local_config;
|
||||
protected SparkleConfig local_config;
|
||||
|
||||
string identifier;
|
||||
BaseListener listener = null;
|
||||
Watcher watcher;
|
||||
TimeSpan poll_interval = PollInterval.Short;
|
||||
DateTime last_poll = DateTime.Now;
|
||||
Timers.Timer remote_timer = new Timers.Timer () { Interval = 5000 };
|
||||
DisconnectReason last_disconnect_reason = DisconnectReason.None;
|
||||
|
||||
bool is_syncing {
|
||||
private string identifier;
|
||||
private SparkleListenerBase listener;
|
||||
private SparkleWatcher watcher;
|
||||
private TimeSpan poll_interval = PollInterval.Short;
|
||||
private DateTime last_poll = DateTime.Now;
|
||||
private DateTime progress_last_change = DateTime.Now;
|
||||
private Timers.Timer remote_timer = new Timers.Timer () { Interval = 5000 };
|
||||
private DisconnectReason last_disconnect_reason = DisconnectReason.None;
|
||||
|
||||
private bool is_syncing {
|
||||
get { return (Status == SyncStatus.SyncUp || Status == SyncStatus.SyncDown || IsBuffering); }
|
||||
}
|
||||
|
||||
static class PollInterval {
|
||||
private static class PollInterval {
|
||||
public static readonly TimeSpan Short = new TimeSpan (0, 0, 5, 0);
|
||||
public static readonly TimeSpan Long = new TimeSpan (0, 0, 15, 0);
|
||||
}
|
||||
|
||||
|
||||
public BaseRepository (string path, Configuration config)
|
||||
public SparkleRepoBase (string path, SparkleConfig config)
|
||||
{
|
||||
Logger.LogInfo (path, "Initializing...");
|
||||
SparkleLogger.LogInfo (path, "Initializing...");
|
||||
|
||||
Status = SyncStatus.Idle;
|
||||
Error = ErrorStatus.None;
|
||||
this.local_config = config;
|
||||
LocalPath = path;
|
||||
Name = Path.GetFileName (LocalPath);
|
||||
RemoteUrl = new Uri (this.local_config.UrlByName (Name));
|
||||
RemoteUrl = new Uri (this.local_config.GetUrlForFolder (Name));
|
||||
IsBuffering = false;
|
||||
this.identifier = Identifier;
|
||||
|
||||
string storage_type = this.local_config.GetFolderOptionalAttribute (Name, "storage_type");
|
||||
|
||||
if (!string.IsNullOrEmpty (storage_type))
|
||||
StorageType = (StorageType) Enum.Parse (typeof (StorageType), storage_type);
|
||||
ChangeSets = GetChangeSets ();
|
||||
|
||||
string is_paused = this.local_config.GetFolderOptionalAttribute (Name, "paused");
|
||||
if (is_paused != null && is_paused.Equals (bool.TrueString))
|
||||
|
@ -207,7 +174,7 @@ namespace Sparkles {
|
|||
File.SetAttributes (identifier_file_path, FileAttributes.Hidden);
|
||||
|
||||
if (!UseCustomWatcher)
|
||||
this.watcher = new Watcher (LocalPath);
|
||||
this.watcher = new SparkleWatcher (LocalPath);
|
||||
|
||||
new Thread (() => CreateListener ()).Start ();
|
||||
|
||||
|
@ -215,7 +182,7 @@ namespace Sparkles {
|
|||
}
|
||||
|
||||
|
||||
void RemoteTimerElapsedDelegate (object sender, EventArgs args)
|
||||
private void RemoteTimerElapsedDelegate (object sender, EventArgs args)
|
||||
{
|
||||
if (this.is_syncing || IsBuffering || Status == SyncStatus.Paused)
|
||||
return;
|
||||
|
@ -231,8 +198,8 @@ namespace Sparkles {
|
|||
if (HasRemoteChanges && !this.is_syncing)
|
||||
SyncDownBase ();
|
||||
|
||||
// if (this.listener.IsConnected)
|
||||
// this.poll_interval = PollInterval.Long;
|
||||
if (this.listener.IsConnected)
|
||||
this.poll_interval = PollInterval.Long;
|
||||
}
|
||||
|
||||
// In the unlikely case that we haven't synced up our
|
||||
|
@ -249,8 +216,6 @@ namespace Sparkles {
|
|||
|
||||
public void Initialize ()
|
||||
{
|
||||
ChangeSets = GetChangeSets ();
|
||||
|
||||
// Sync up everything that changed since we've been offline
|
||||
new Thread (() => {
|
||||
if (Status != SyncStatus.Paused) {
|
||||
|
@ -274,7 +239,7 @@ namespace Sparkles {
|
|||
}
|
||||
|
||||
|
||||
Object buffer_lock = new Object ();
|
||||
private Object buffer_lock = new Object ();
|
||||
|
||||
public void OnFileActivity (FileSystemEventArgs args)
|
||||
{
|
||||
|
@ -305,7 +270,7 @@ namespace Sparkles {
|
|||
if (!UseCustomWatcher)
|
||||
this.watcher.Disable ();
|
||||
|
||||
Logger.LogInfo ("Local", Name + " | Activity detected, waiting for it to settle...");
|
||||
SparkleLogger.LogInfo ("Local", Name + " | Activity detected, waiting for it to settle...");
|
||||
|
||||
List<double> size_buffer = new List<double> ();
|
||||
DirectoryInfo info = new DirectoryInfo (LocalPath);
|
||||
|
@ -321,7 +286,7 @@ namespace Sparkles {
|
|||
size_buffer [1].Equals (size_buffer [2]) &&
|
||||
size_buffer [2].Equals (size_buffer [3])) {
|
||||
|
||||
Logger.LogInfo ("Local", Name + " | Activity has settled");
|
||||
SparkleLogger.LogInfo ("Local", Name + " | Activity has settled");
|
||||
IsBuffering = false;
|
||||
|
||||
bool first_sync = true;
|
||||
|
@ -329,7 +294,7 @@ namespace Sparkles {
|
|||
if (HasLocalChanges && Status == SyncStatus.Idle) {
|
||||
do {
|
||||
if (!first_sync)
|
||||
Logger.LogInfo ("Local", Name + " | More changes found");
|
||||
SparkleLogger.LogInfo ("Local", Name + " | More changes found");
|
||||
|
||||
SyncUpBase ();
|
||||
|
||||
|
@ -370,55 +335,51 @@ namespace Sparkles {
|
|||
}
|
||||
|
||||
|
||||
DateTime progress_last_change = DateTime.Now;
|
||||
|
||||
protected void OnProgressChanged (double percentage, double speed, string information)
|
||||
protected void OnProgressChanged (double progress_percentage, double progress_speed)
|
||||
{
|
||||
if (percentage < 1)
|
||||
if (progress_percentage < 1)
|
||||
return;
|
||||
|
||||
// Only trigger the ProgressChanged event once per second
|
||||
if (DateTime.Compare (this.progress_last_change, DateTime.Now.Subtract (new TimeSpan (0, 0, 0, 1))) >= 0)
|
||||
return;
|
||||
|
||||
if (percentage == 100.0)
|
||||
percentage = 99.0;
|
||||
if (progress_percentage == 100.0)
|
||||
progress_percentage = 99.0;
|
||||
|
||||
progress_last_change = DateTime.Now;
|
||||
|
||||
ProgressPercentage = percentage;
|
||||
ProgressSpeed = speed;
|
||||
ProgressInformation = information;
|
||||
ProgressPercentage = progress_percentage;
|
||||
ProgressSpeed = progress_speed;
|
||||
this.progress_last_change = DateTime.Now;
|
||||
|
||||
ProgressChanged ();
|
||||
}
|
||||
|
||||
|
||||
void SyncUpBase ()
|
||||
private void SyncUpBase ()
|
||||
{
|
||||
if (!UseCustomWatcher)
|
||||
this.watcher.Disable ();
|
||||
|
||||
Logger.LogInfo ("SyncUp", Name + " | Initiated");
|
||||
SparkleLogger.LogInfo ("SyncUp", Name + " | Initiated");
|
||||
HasUnsyncedChanges = true;
|
||||
|
||||
Status = SyncStatus.SyncUp;
|
||||
SyncStatusChanged (Status);
|
||||
|
||||
if (SyncUp ()) {
|
||||
Logger.LogInfo ("SyncUp", Name + " | Done");
|
||||
SparkleLogger.LogInfo ("SyncUp", Name + " | Done");
|
||||
ChangeSets = GetChangeSets ();
|
||||
|
||||
HasUnsyncedChanges = false;
|
||||
this.poll_interval = PollInterval.Long;
|
||||
|
||||
// this.listener.Announce (new Announcement (Identifier, CurrentRevision));
|
||||
this.listener.Announce (new SparkleAnnouncement (Identifier, CurrentRevision));
|
||||
|
||||
Status = SyncStatus.Idle;
|
||||
SyncStatusChanged (Status);
|
||||
|
||||
} else {
|
||||
Logger.LogInfo ("SyncUp", Name + " | Error");
|
||||
SparkleLogger.LogInfo ("SyncUp", Name + " | Error");
|
||||
SyncDownBase ();
|
||||
|
||||
if (!UseCustomWatcher)
|
||||
|
@ -427,7 +388,7 @@ namespace Sparkles {
|
|||
if (Error == ErrorStatus.None && SyncUp ()) {
|
||||
HasUnsyncedChanges = false;
|
||||
|
||||
// this.listener.Announce (new Announcement (Identifier, CurrentRevision));
|
||||
this.listener.Announce (new SparkleAnnouncement (Identifier, CurrentRevision));
|
||||
|
||||
Status = SyncStatus.Idle;
|
||||
SyncStatusChanged (Status);
|
||||
|
@ -450,12 +411,12 @@ namespace Sparkles {
|
|||
}
|
||||
|
||||
|
||||
void SyncDownBase ()
|
||||
private void SyncDownBase ()
|
||||
{
|
||||
if (!UseCustomWatcher)
|
||||
this.watcher.Disable ();
|
||||
|
||||
Logger.LogInfo ("SyncDown", Name + " | Initiated");
|
||||
SparkleLogger.LogInfo ("SyncDown", Name + " | Initiated");
|
||||
|
||||
Status = SyncStatus.SyncDown;
|
||||
SyncStatusChanged (Status);
|
||||
|
@ -476,7 +437,7 @@ namespace Sparkles {
|
|||
|
||||
bool emit_change_event = true;
|
||||
|
||||
foreach (Change change in ChangeSets [0].Changes) {
|
||||
foreach (SparkleChange change in ChangeSets [0].Changes) {
|
||||
if (change.Path.EndsWith (".sparkleshare")) {
|
||||
emit_change_event = false;
|
||||
break;
|
||||
|
@ -487,7 +448,7 @@ namespace Sparkles {
|
|||
NewChangeSet (ChangeSets [0]);
|
||||
}
|
||||
|
||||
Logger.LogInfo ("SyncDown", Name + " | Done");
|
||||
SparkleLogger.LogInfo ("SyncDown", Name + " | Done");
|
||||
|
||||
// There could be changes from a resolved
|
||||
// conflict. Tries only once, then lets
|
||||
|
@ -504,7 +465,7 @@ namespace Sparkles {
|
|||
SyncStatusChanged (Status);
|
||||
|
||||
} else {
|
||||
Logger.LogInfo ("SyncDown", Name + " | Error");
|
||||
SparkleLogger.LogInfo ("SyncDown", Name + " | Error");
|
||||
|
||||
ChangeSets = GetChangeSets ();
|
||||
|
||||
|
@ -523,23 +484,23 @@ namespace Sparkles {
|
|||
}
|
||||
|
||||
|
||||
void CreateListener ()
|
||||
private void CreateListener ()
|
||||
{
|
||||
// this.listener = ListenerFactory.CreateListener (Name, Identifier);
|
||||
this.listener = SparkleListenerFactory.CreateListener (Name, Identifier);
|
||||
|
||||
// if (this.listener.IsConnected)
|
||||
// this.poll_interval = PollInterval.Long;
|
||||
if (this.listener.IsConnected)
|
||||
this.poll_interval = PollInterval.Long;
|
||||
|
||||
// this.listener.Connected += ListenerConnectedDelegate;
|
||||
// this.listener.Disconnected += ListenerDisconnectedDelegate;
|
||||
// this.listener.AnnouncementReceived += ListenerAnnouncementReceivedDelegate;
|
||||
this.listener.Connected += ListenerConnectedDelegate;
|
||||
this.listener.Disconnected += ListenerDisconnectedDelegate;
|
||||
this.listener.AnnouncementReceived += ListenerAnnouncementReceivedDelegate;
|
||||
|
||||
// if (!this.listener.IsConnected && !this.listener.IsConnecting)
|
||||
// this.listener.Connect ();
|
||||
if (!this.listener.IsConnected && !this.listener.IsConnecting)
|
||||
this.listener.Connect ();
|
||||
}
|
||||
|
||||
|
||||
void ListenerConnectedDelegate ()
|
||||
private void ListenerConnectedDelegate ()
|
||||
{
|
||||
if (this.last_disconnect_reason == DisconnectReason.SystemSleep) {
|
||||
this.last_disconnect_reason = DisconnectReason.None;
|
||||
|
@ -552,9 +513,9 @@ namespace Sparkles {
|
|||
}
|
||||
|
||||
|
||||
void ListenerDisconnectedDelegate (DisconnectReason reason)
|
||||
private void ListenerDisconnectedDelegate (DisconnectReason reason)
|
||||
{
|
||||
Logger.LogInfo (Name, "Falling back to regular polling");
|
||||
SparkleLogger.LogInfo (Name, "Falling back to regular polling");
|
||||
this.poll_interval = PollInterval.Short;
|
||||
|
||||
this.last_disconnect_reason = reason;
|
||||
|
@ -565,7 +526,7 @@ namespace Sparkles {
|
|||
int backoff_time = 2;
|
||||
|
||||
do {
|
||||
Logger.LogInfo (Name, "Next reconnect attempt in " + backoff_time + " seconds");
|
||||
SparkleLogger.LogInfo (Name, "Next reconnect attempt in " + backoff_time + " seconds");
|
||||
Thread.Sleep (backoff_time * 1000);
|
||||
this.listener.Connect ();
|
||||
backoff_time *= 2;
|
||||
|
@ -577,7 +538,7 @@ namespace Sparkles {
|
|||
}
|
||||
|
||||
|
||||
void ListenerAnnouncementReceivedDelegate (Announcement announcement)
|
||||
private void ListenerAnnouncementReceivedDelegate (SparkleAnnouncement announcement)
|
||||
{
|
||||
string identifier = Identifier;
|
||||
|
||||
|
@ -588,10 +549,10 @@ namespace Sparkles {
|
|||
while (this.is_syncing)
|
||||
Thread.Sleep (100);
|
||||
|
||||
Logger.LogInfo (Name, "Syncing due to announcement");
|
||||
SparkleLogger.LogInfo (Name, "Syncing due to announcement");
|
||||
|
||||
if (Status == SyncStatus.Paused)
|
||||
Logger.LogInfo (Name, "We're paused, skipping sync");
|
||||
SparkleLogger.LogInfo (Name, "We're paused, skipping sync");
|
||||
else
|
||||
SyncDownBase ();
|
||||
}
|
||||
|
@ -599,7 +560,7 @@ namespace Sparkles {
|
|||
|
||||
|
||||
// Recursively gets a folder's size in bytes
|
||||
long CalculateSize (DirectoryInfo parent)
|
||||
private long CalculateSize (DirectoryInfo parent)
|
||||
{
|
||||
if (ExcludePaths.Contains (parent.Name))
|
||||
return 0;
|
||||
|
@ -614,7 +575,7 @@ namespace Sparkles {
|
|||
size += file.Length;
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.LogInfo ("Local", "Error calculating directory size", e);
|
||||
SparkleLogger.LogInfo ("Local", "Error calculating directory size", e);
|
||||
}
|
||||
|
||||
return size;
|
||||
|
@ -659,12 +620,12 @@ namespace Sparkles {
|
|||
this.remote_timer = null;
|
||||
}
|
||||
|
||||
// this.listener.Disconnected -= ListenerDisconnectedDelegate;
|
||||
// this.listener.AnnouncementReceived -= ListenerAnnouncementReceivedDelegate;
|
||||
this.listener.Disconnected -= ListenerDisconnectedDelegate;
|
||||
this.listener.AnnouncementReceived -= ListenerAnnouncementReceivedDelegate;
|
||||
|
||||
// this.listener.Dispose ();
|
||||
this.listener.Dispose ();
|
||||
|
||||
if (!UseCustomWatcher && this.watcher != null)
|
||||
if (!UseCustomWatcher)
|
||||
this.watcher.Dispose ();
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
// SparkleShare, a collaboration and sharing tool.
|
||||
// Copyright (C) 2010 Hylke Bons <hi@planetpeanut.uk>
|
||||
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
|
@ -15,17 +15,25 @@
|
|||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
namespace Sparkles {
|
||||
using System;
|
||||
|
||||
public class User {
|
||||
namespace SparkleLib {
|
||||
|
||||
public class SparkleUser {
|
||||
|
||||
public readonly string Name;
|
||||
public readonly string Email;
|
||||
|
||||
public string AvatarFilePath;
|
||||
|
||||
public string PrivateKey;
|
||||
public string PrivateKeyFilePath;
|
||||
|
||||
public User (string name, string email)
|
||||
public string PublicKey;
|
||||
public string PublicKeyFilePath;
|
||||
|
||||
|
||||
public SparkleUser (string name, string email)
|
||||
{
|
||||
Name = name;
|
||||
Email = email;
|
13
Sparkles/Watcher.cs → SparkleLib/SparkleWatcher.cs
Normal file → Executable file
|
@ -1,5 +1,5 @@
|
|||
// SparkleShare, a collaboration and sharing tool.
|
||||
// Copyright (C) 2010 Hylke Bons <hi@planetpeanut.uk>
|
||||
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
|
@ -15,19 +15,20 @@
|
|||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Sparkles {
|
||||
namespace SparkleLib {
|
||||
|
||||
public class Watcher : FileSystemWatcher {
|
||||
public class SparkleWatcher : FileSystemWatcher {
|
||||
|
||||
public event ChangeEventEventHandler ChangeEvent = delegate { };
|
||||
public delegate void ChangeEventEventHandler (FileSystemEventArgs args);
|
||||
|
||||
object thread_lock = new object ();
|
||||
private Object thread_lock = new Object ();
|
||||
|
||||
|
||||
public Watcher (string path) : base (path)
|
||||
public SparkleWatcher (string path) : base (path)
|
||||
{
|
||||
IncludeSubdirectories = true;
|
||||
EnableRaisingEvents = true;
|
||||
|
@ -40,7 +41,7 @@ namespace Sparkles {
|
|||
}
|
||||
|
||||
|
||||
void OnChanged (object sender, FileSystemEventArgs args)
|
||||
private void OnChanged (object sender, FileSystemEventArgs args)
|
||||
{
|
||||
ChangeEvent (args);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
// SparkleShare, a collaboration and sharing tool.
|
||||
// Copyright (C) 2010 Hylke Bons <hi@planetpeanut.uk>
|
||||
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
|
@ -19,9 +19,9 @@ using System;
|
|||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Sparkles {
|
||||
namespace SparkleLib {
|
||||
|
||||
public enum ChangeType {
|
||||
public enum SparkleChangeType {
|
||||
Added,
|
||||
Edited,
|
||||
Deleted,
|
||||
|
@ -29,9 +29,9 @@ namespace Sparkles {
|
|||
}
|
||||
|
||||
|
||||
public class ChangeSet {
|
||||
public class SparkleChangeSet {
|
||||
|
||||
public User User = new User ("Unknown", "Unknown");
|
||||
public SparkleUser User = new SparkleUser ("Unknown", "Unknown");
|
||||
|
||||
public SparkleFolder Folder;
|
||||
public string Revision;
|
||||
|
@ -39,16 +39,16 @@ namespace Sparkles {
|
|||
public DateTime FirstTimestamp;
|
||||
public Uri RemoteUrl;
|
||||
|
||||
public List<Change> Changes = new List<Change> ();
|
||||
public List<SparkleChange> Changes = new List<SparkleChange> ();
|
||||
|
||||
public string ToMessage ()
|
||||
{
|
||||
string message = "added: {0}";
|
||||
|
||||
|
||||
switch (Changes [0].Type) {
|
||||
case ChangeType.Edited: message = "edited: {0}"; break;
|
||||
case ChangeType.Deleted: message = "deleted: {0}"; break;
|
||||
case ChangeType.Moved: message = "moved: {0}"; break;
|
||||
case SparkleChangeType.Edited: message = "edited: {0}"; break;
|
||||
case SparkleChangeType.Deleted: message = "deleted: {0}"; break;
|
||||
case SparkleChangeType.Moved: message = "moved: {0}"; break;
|
||||
}
|
||||
|
||||
if (Changes.Count > 0)
|
||||
|
@ -59,12 +59,12 @@ namespace Sparkles {
|
|||
}
|
||||
|
||||
|
||||
public class Change {
|
||||
public class SparkleChange {
|
||||
|
||||
public ChangeType Type;
|
||||
public SparkleChangeType Type;
|
||||
public DateTime Timestamp;
|
||||
public bool IsFolder;
|
||||
|
||||
public bool IsFolder = false;
|
||||
|
||||
public string Path;
|
||||
public string MovedToPath;
|
||||
}
|
||||
|
@ -77,14 +77,12 @@ namespace Sparkles {
|
|||
|
||||
public string FullPath {
|
||||
get {
|
||||
string custom_path = Configuration.DefaultConfiguration.GetFolderOptionalAttribute (Name, "path");
|
||||
string custom_path = SparkleConfig.DefaultConfig.GetFolderOptionalAttribute (Name, "path");
|
||||
|
||||
if (custom_path != null)
|
||||
return Path.Combine (custom_path, Name);
|
||||
|
||||
return Path.Combine (Configuration.DefaultConfiguration.FoldersPath,
|
||||
new Uri (Configuration.DefaultConfiguration.UrlByName (Name)).Host,
|
||||
Name);
|
||||
else
|
||||
return Path.Combine (SparkleConfig.DefaultConfig.FoldersPath, Name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,13 +94,13 @@ namespace Sparkles {
|
|||
}
|
||||
|
||||
|
||||
public class Announcement {
|
||||
public class SparkleAnnouncement {
|
||||
|
||||
public readonly string FolderIdentifier;
|
||||
public readonly string Message;
|
||||
|
||||
|
||||
public Announcement (string folder_identifier, string message)
|
||||
public SparkleAnnouncement (string folder_identifier, string message)
|
||||
{
|
||||
FolderIdentifier = folder_identifier;
|
||||
Message = message;
|
|
@ -1,89 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sparkles", "Sparkles\Sparkles.csproj", "{2C914413-B31C-4362-93C7-1AE34F09112A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sparkles.Git", "Sparkles\Git\Sparkles.Git.csproj", "{009FDCD7-1D57-4202-BB6D-8477D8C6B8EE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SparkleShare.Windows", "SparkleShare\Windows\SparkleShare.Windows.csproj", "{728483AA-E34B-4441-BF2C-C8BC2901E4E0}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SparkleShare.Linux", "SparkleShare\Linux\SparkleShare.Linux.csproj", "{5714D3CA-88A6-4330-A29D-4CA90D1D193C}"
|
||||
EndProject
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "SparkleShare", "SparkleShare\Common\SparkleShare.shproj", "{F16E3683-B622-4654-B799-99C8D68AA963}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SparkleShare.Mac", "SparkleShare\Mac\SparkleShare.Mac.csproj", "{8FCDF699-E2C3-4CB3-AF98-44198972AFC0}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
ReleaseDist|Any CPU = ReleaseDist|Any CPU
|
||||
ReleaseMac|Any CPU = ReleaseMac|Any CPU
|
||||
DebugMac|Any CPU = DebugMac|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{009FDCD7-1D57-4202-BB6D-8477D8C6B8EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{009FDCD7-1D57-4202-BB6D-8477D8C6B8EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{009FDCD7-1D57-4202-BB6D-8477D8C6B8EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{009FDCD7-1D57-4202-BB6D-8477D8C6B8EE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{009FDCD7-1D57-4202-BB6D-8477D8C6B8EE}.ReleaseDist|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{009FDCD7-1D57-4202-BB6D-8477D8C6B8EE}.ReleaseDist|Any CPU.Build.0 = Release|Any CPU
|
||||
{009FDCD7-1D57-4202-BB6D-8477D8C6B8EE}.ReleaseMac|Any CPU.ActiveCfg = ReleaseMac|Any CPU
|
||||
{009FDCD7-1D57-4202-BB6D-8477D8C6B8EE}.ReleaseMac|Any CPU.Build.0 = ReleaseMac|Any CPU
|
||||
{009FDCD7-1D57-4202-BB6D-8477D8C6B8EE}.DebugMac|Any CPU.ActiveCfg = DebugMac|Any CPU
|
||||
{009FDCD7-1D57-4202-BB6D-8477D8C6B8EE}.DebugMac|Any CPU.Build.0 = DebugMac|Any CPU
|
||||
{2C914413-B31C-4362-93C7-1AE34F09112A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2C914413-B31C-4362-93C7-1AE34F09112A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2C914413-B31C-4362-93C7-1AE34F09112A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2C914413-B31C-4362-93C7-1AE34F09112A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2C914413-B31C-4362-93C7-1AE34F09112A}.ReleaseDist|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2C914413-B31C-4362-93C7-1AE34F09112A}.ReleaseDist|Any CPU.Build.0 = Release|Any CPU
|
||||
{2C914413-B31C-4362-93C7-1AE34F09112A}.ReleaseMac|Any CPU.ActiveCfg = ReleaseMac|Any CPU
|
||||
{2C914413-B31C-4362-93C7-1AE34F09112A}.ReleaseMac|Any CPU.Build.0 = ReleaseMac|Any CPU
|
||||
{2C914413-B31C-4362-93C7-1AE34F09112A}.DebugMac|Any CPU.ActiveCfg = DebugMac|Any CPU
|
||||
{2C914413-B31C-4362-93C7-1AE34F09112A}.DebugMac|Any CPU.Build.0 = DebugMac|Any CPU
|
||||
{5714D3CA-88A6-4330-A29D-4CA90D1D193C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5714D3CA-88A6-4330-A29D-4CA90D1D193C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5714D3CA-88A6-4330-A29D-4CA90D1D193C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5714D3CA-88A6-4330-A29D-4CA90D1D193C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5714D3CA-88A6-4330-A29D-4CA90D1D193C}.ReleaseDist|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5714D3CA-88A6-4330-A29D-4CA90D1D193C}.ReleaseDist|Any CPU.Build.0 = Release|Any CPU
|
||||
{5714D3CA-88A6-4330-A29D-4CA90D1D193C}.ReleaseMac|Any CPU.ActiveCfg = ReleaseMac|Any CPU
|
||||
{5714D3CA-88A6-4330-A29D-4CA90D1D193C}.DebugMac|Any CPU.ActiveCfg = DebugMac|Any CPU
|
||||
{728483AA-E34B-4441-BF2C-C8BC2901E4E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{728483AA-E34B-4441-BF2C-C8BC2901E4E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{728483AA-E34B-4441-BF2C-C8BC2901E4E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{728483AA-E34B-4441-BF2C-C8BC2901E4E0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{728483AA-E34B-4441-BF2C-C8BC2901E4E0}.ReleaseDist|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{728483AA-E34B-4441-BF2C-C8BC2901E4E0}.ReleaseDist|Any CPU.Build.0 = Release|Any CPU
|
||||
{728483AA-E34B-4441-BF2C-C8BC2901E4E0}.ReleaseMac|Any CPU.ActiveCfg = ReleaseMac|Any CPU
|
||||
{728483AA-E34B-4441-BF2C-C8BC2901E4E0}.DebugMac|Any CPU.ActiveCfg = DebugMac|Any CPU
|
||||
{8FCDF699-E2C3-4CB3-AF98-44198972AFC0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8FCDF699-E2C3-4CB3-AF98-44198972AFC0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8FCDF699-E2C3-4CB3-AF98-44198972AFC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8FCDF699-E2C3-4CB3-AF98-44198972AFC0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8FCDF699-E2C3-4CB3-AF98-44198972AFC0}.ReleaseDist|Any CPU.ActiveCfg = ReleaseDist|Any CPU
|
||||
{8FCDF699-E2C3-4CB3-AF98-44198972AFC0}.ReleaseDist|Any CPU.Build.0 = ReleaseDist|Any CPU
|
||||
{8FCDF699-E2C3-4CB3-AF98-44198972AFC0}.ReleaseMac|Any CPU.ActiveCfg = ReleaseMac|Any CPU
|
||||
{8FCDF699-E2C3-4CB3-AF98-44198972AFC0}.ReleaseMac|Any CPU.Build.0 = ReleaseMac|Any CPU
|
||||
{8FCDF699-E2C3-4CB3-AF98-44198972AFC0}.DebugMac|Any CPU.ActiveCfg = DebugMac|Any CPU
|
||||
{8FCDF699-E2C3-4CB3-AF98-44198972AFC0}.DebugMac|Any CPU.Build.0 = DebugMac|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(MonoDevelopProperties) = preSolution
|
||||
Policies = $0
|
||||
$0.DotNetNamingPolicy = $1
|
||||
$1.DirectoryNamespaceAssociation = None
|
||||
$1.ResourceNamePolicy = FileFormatDefault
|
||||
$0.TextStylePolicy = $2
|
||||
$2.FileWidth = 120
|
||||
$2.inheritsSet = VisualStudio
|
||||
$2.inheritsScope = text/plain
|
||||
$2.scope = text/plain
|
||||
$0.CSharpFormattingPolicy = $3
|
||||
$3.inheritsSet = Mono
|
||||
$3.inheritsScope = text/x-csharp
|
||||
$3.scope = text/x-csharp
|
||||
version =
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
@ -1,763 +0,0 @@
|
|||
// SparkleShare, a collaboration and sharing tool.
|
||||
// Copyright (C) 2010 Hylke Bons <hi@planetpeanut.uk>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
||||
using Sparkles;
|
||||
|
||||
namespace SparkleShare {
|
||||
|
||||
public abstract class BaseController {
|
||||
|
||||
public BaseRepository [] Repositories {
|
||||
get {
|
||||
lock (this.repo_lock)
|
||||
return this.repositories.GetRange (0, this.repositories.Count).ToArray ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AddRepository (BaseRepository repo)
|
||||
{
|
||||
lock (this.repo_lock) {
|
||||
this.repositories.Add (repo);
|
||||
this.repositories.Sort ((x, y) => string.Compare (x.Name, y.Name));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RemoveRepository (BaseRepository repo)
|
||||
{
|
||||
lock (this.repo_lock)
|
||||
this.repositories.Remove (repo);
|
||||
}
|
||||
|
||||
|
||||
public BaseRepository GetRepoByName (string name)
|
||||
{
|
||||
lock (this.repo_lock) {
|
||||
foreach (BaseRepository repo in this.repositories)
|
||||
if (repo.Name.Equals (name))
|
||||
return repo;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public Configuration Config { get; private set; }
|
||||
public bool RepositoriesLoaded { get; private set; }
|
||||
public string FoldersPath { get; private set; }
|
||||
|
||||
public double ProgressPercentage = 0.0;
|
||||
public double ProgressSpeedUp = 0.0;
|
||||
public double ProgressSpeedDown = 0.0;
|
||||
public string ProgressInformation = "";
|
||||
|
||||
|
||||
public event ShowSetupWindowEventHandler ShowSetupWindowEvent = delegate { };
|
||||
public delegate void ShowSetupWindowEventHandler (PageType page_type);
|
||||
|
||||
public event ShowNoteWindowEventHandler ShowNoteWindowEvent = delegate { };
|
||||
public delegate void ShowNoteWindowEventHandler (string project);
|
||||
|
||||
public event Action ShowAboutWindowEvent = delegate { };
|
||||
public event Action ShowEventLogWindowEvent = delegate { };
|
||||
|
||||
public event FolderFetchedEventHandler FolderFetched = delegate { };
|
||||
public delegate void FolderFetchedEventHandler (string remote_url, string [] warnings);
|
||||
|
||||
public event FolderFetchErrorHandler FolderFetchError = delegate { };
|
||||
public delegate void FolderFetchErrorHandler (string remote_url, string [] errors);
|
||||
|
||||
public event FolderFetchingHandler FolderFetching = delegate { };
|
||||
public delegate void FolderFetchingHandler (double percentage, double speed, string information);
|
||||
|
||||
|
||||
public event Action FolderListChanged = delegate { };
|
||||
public event Action OnIdle = delegate { };
|
||||
public event Action OnSyncing = delegate { };
|
||||
public event Action OnError = delegate { };
|
||||
|
||||
|
||||
public event InviteReceivedHandler InviteReceived = delegate { };
|
||||
public delegate void InviteReceivedHandler (SparkleInvite invite);
|
||||
|
||||
public event NotificationRaisedEventHandler NotificationRaised = delegate { };
|
||||
public delegate void NotificationRaisedEventHandler (ChangeSet change_set);
|
||||
|
||||
public event AlertNotificationRaisedEventHandler AlertNotificationRaised = delegate { };
|
||||
public delegate void AlertNotificationRaisedEventHandler (string title, string message);
|
||||
|
||||
|
||||
public bool FirstRun {
|
||||
get { return Config.User.Email.Equals ("Unknown"); }
|
||||
}
|
||||
|
||||
public List<string> Folders {
|
||||
get {
|
||||
List<string> folders = Config.Folders;
|
||||
return folders;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public User CurrentUser {
|
||||
get { return Config.User; }
|
||||
set { Config.User = value; }
|
||||
}
|
||||
|
||||
public SSHAuthenticationInfo UserAuthenticationInfo;
|
||||
|
||||
|
||||
public bool NotificationsEnabled {
|
||||
get {
|
||||
string notifications_enabled = Config.GetConfigOption ("notifications");
|
||||
|
||||
if (string.IsNullOrEmpty (notifications_enabled)) {
|
||||
Config.SetConfigOption ("notifications", bool.TrueString);
|
||||
return true;
|
||||
|
||||
} else {
|
||||
return notifications_enabled.Equals (bool.TrueString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool AvatarsEnabled {
|
||||
get {
|
||||
string fetch_avatars_option = Config.GetConfigOption ("fetch_avatars");
|
||||
|
||||
if (fetch_avatars_option == null || fetch_avatars_option.Equals (bool.FalseString))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public string AvatarsProvider {
|
||||
get {
|
||||
string avatars_provider_string = Config.GetConfigOption ("avatars_provider");
|
||||
|
||||
if (avatars_provider_string == null)
|
||||
return "gravatar";
|
||||
|
||||
return avatars_provider_string;
|
||||
}
|
||||
}
|
||||
|
||||
// Path where the plugins are kept
|
||||
public abstract string PresetsPath { get; }
|
||||
|
||||
// Enables SparkleShare to start automatically at login
|
||||
public abstract void CreateStartupItem ();
|
||||
|
||||
// Installs the sparkleshare:// protocol handler
|
||||
public abstract void InstallProtocolHandler ();
|
||||
|
||||
// Installs the sparkleshare:// protocol handler
|
||||
public abstract void SetFolderIcon ();
|
||||
|
||||
// Creates the SparkleShare folder in the user's home folder
|
||||
public abstract void CreateSparkleShareFolder ();
|
||||
|
||||
// Opens the SparkleShare folder or an (optional) subfolder
|
||||
public abstract void OpenFolder (string path);
|
||||
|
||||
// Opens a file with the appropriate application
|
||||
public abstract void OpenFile (string path);
|
||||
|
||||
// Opens a file with the appropriate application
|
||||
public virtual void OpenWebsite (string url) { }
|
||||
|
||||
// Copies text to the clipboard
|
||||
public abstract void CopyToClipboard (string text);
|
||||
|
||||
// Allows for platform-specific quit and cleanup methods to be called on exit
|
||||
public abstract void PlatformQuit ();
|
||||
|
||||
public abstract string EventLogHTML { get; }
|
||||
public abstract string DayEntryHTML { get; }
|
||||
public abstract string EventEntryHTML { get; }
|
||||
|
||||
|
||||
BaseFetcher fetcher;
|
||||
FileSystemWatcher watcher;
|
||||
object repo_lock = new object ();
|
||||
object check_repos_lock = new object ();
|
||||
List<BaseRepository> repositories = new List<BaseRepository> ();
|
||||
bool lost_folders_path = false;
|
||||
|
||||
|
||||
public BaseController (Configuration config)
|
||||
{
|
||||
Config = config;
|
||||
FoldersPath = Config.FoldersPath;
|
||||
}
|
||||
|
||||
|
||||
public virtual void Initialize ()
|
||||
{
|
||||
string version = InstallationInfo.Version;
|
||||
|
||||
if (InstallationInfo.IsFlatpak)
|
||||
version += " (Flatpak)";
|
||||
|
||||
Logger.LogInfo ("Environment", "SparkleShare " + version);
|
||||
Logger.LogInfo ("Environment", "Git LFS " + Sparkles.Git.GitCommand.GitLFSVersion);
|
||||
Logger.LogInfo ("Environment", "Git " + Sparkles.Git.GitCommand.GitVersion);
|
||||
Logger.LogInfo ("Environment", InstallationInfo.OperatingSystem + " " + InstallationInfo.OperatingSystemVersion);
|
||||
|
||||
UserAuthenticationInfo = new SSHAuthenticationInfo ();
|
||||
SSHAuthenticationInfo.DefaultAuthenticationInfo = UserAuthenticationInfo;
|
||||
|
||||
Preset.PresetsPath = PresetsPath;
|
||||
InstallProtocolHandler ();
|
||||
|
||||
try {
|
||||
CreateSparkleShareFolder ();
|
||||
|
||||
} catch (DirectoryNotFoundException) {
|
||||
this.lost_folders_path = true;
|
||||
}
|
||||
|
||||
SetFolderIcon ();
|
||||
|
||||
// Watch the SparkleShare folder
|
||||
this.watcher = new FileSystemWatcher () {
|
||||
Filter = "*",
|
||||
IncludeSubdirectories = false,
|
||||
Path = FoldersPath
|
||||
};
|
||||
|
||||
watcher.Created += OnFolderActivity;
|
||||
watcher.EnableRaisingEvents = true;
|
||||
}
|
||||
|
||||
|
||||
int reopen_attempt_counts = 0;
|
||||
|
||||
public void HandleReopen ()
|
||||
{
|
||||
if (Repositories.Length > 0) {
|
||||
ShowEventLogWindow ();
|
||||
|
||||
} else if (reopen_attempt_counts > 1) {
|
||||
AlertNotificationRaised ("Hello!", "SparkleShare sits right here, as a status icon.");
|
||||
reopen_attempt_counts = 0;
|
||||
|
||||
} else {
|
||||
reopen_attempt_counts++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void UIHasLoaded ()
|
||||
{
|
||||
if (this.lost_folders_path) {
|
||||
SparkleShare.UI.Bubbles.Controller.ShowBubble ("Where's your SparkleShare folder?",
|
||||
"Did you put it on a detached drive?", null);
|
||||
|
||||
Environment.Exit (-1);
|
||||
}
|
||||
|
||||
if (FirstRun) {
|
||||
ShowSetupWindow (PageType.Setup);
|
||||
|
||||
} else {
|
||||
new Thread (() => {
|
||||
StartupInviteScan ();
|
||||
CheckRepositories ();
|
||||
RepositoriesLoaded = true;
|
||||
UpdateState ();
|
||||
|
||||
}).Start ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void ShowSetupWindow (PageType page_type)
|
||||
{
|
||||
ShowSetupWindowEvent (page_type);
|
||||
}
|
||||
|
||||
|
||||
public void ShowAboutWindow ()
|
||||
{
|
||||
ShowAboutWindowEvent ();
|
||||
}
|
||||
|
||||
|
||||
public void ShowNoteWindow (string project)
|
||||
{
|
||||
ShowNoteWindowEvent (project);
|
||||
}
|
||||
|
||||
|
||||
public void ShowEventLogWindow ()
|
||||
{
|
||||
ShowEventLogWindowEvent ();
|
||||
}
|
||||
|
||||
|
||||
public void OpenSparkleShareFolder ()
|
||||
{
|
||||
OpenFolder (Config.FoldersPath);
|
||||
}
|
||||
|
||||
|
||||
public void OpenSparkleShareFolder (string name)
|
||||
{
|
||||
OpenFolder (new SparkleFolder (name).FullPath);
|
||||
}
|
||||
|
||||
|
||||
public void ToggleNotifications ()
|
||||
{
|
||||
bool notifications_enabled = Config.GetConfigOption ("notifications").Equals (bool.TrueString);
|
||||
Config.SetConfigOption ("notifications", (!notifications_enabled).ToString ());
|
||||
}
|
||||
|
||||
|
||||
void CheckRepositories ()
|
||||
{
|
||||
lock (this.check_repos_lock) {
|
||||
DetectRepositoryRenames ();
|
||||
RemoveDeletedRepositories ();
|
||||
}
|
||||
|
||||
FolderListChanged ();
|
||||
}
|
||||
|
||||
|
||||
void DetectRepositoryRenames ()
|
||||
{
|
||||
foreach (string group_path in Directory.GetDirectories (Config.FoldersPath)) {
|
||||
foreach (string folder_path in Directory.GetDirectories (group_path)) {
|
||||
string folder_name = Path.GetFileName (folder_path);
|
||||
|
||||
if (Config.IdentifierByName (folder_name) != null)
|
||||
continue;
|
||||
|
||||
string identifier_file_path = Path.Combine (folder_path, ".sparkleshare");
|
||||
|
||||
if (!File.Exists (identifier_file_path))
|
||||
continue;
|
||||
|
||||
string identifier = File.ReadAllText (identifier_file_path).Trim ();
|
||||
|
||||
if (!Config.IdentifierExists (identifier))
|
||||
continue;
|
||||
|
||||
RemoveRepository (GetRepoByName (folder_name));
|
||||
Config.RenameFolder (identifier, folder_name);
|
||||
|
||||
string new_folder_path = Path.Combine (group_path, folder_name);
|
||||
AddRepository (new_folder_path);
|
||||
|
||||
Logger.LogInfo ("Controller",
|
||||
"Renamed folder with identifier " + identifier + " to '" + folder_name + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RemoveDeletedRepositories ()
|
||||
{
|
||||
foreach (string folder_name in Config.Folders) {
|
||||
string folder_path = new SparkleFolder (folder_name).FullPath;
|
||||
|
||||
if (!Directory.Exists (folder_path)) {
|
||||
Config.RemoveFolder (folder_name);
|
||||
RemoveRepository (GetRepoByName (folder_name));
|
||||
|
||||
Logger.LogInfo ("Controller", "Removed folder '" + folder_name + "' from config");
|
||||
|
||||
} else {
|
||||
AddRepository (folder_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AddRepository (string folder_path)
|
||||
{
|
||||
BaseRepository repo = null;
|
||||
string folder_name = Path.GetFileName (folder_path);
|
||||
string backend = Config.BackendByName (folder_name);
|
||||
|
||||
try {
|
||||
repo = (BaseRepository) Activator.CreateInstance (
|
||||
Type.GetType ("Sparkles." + backend + "." + backend + "Repository, Sparkles." + backend),
|
||||
new object [] { folder_path, Config, SSHAuthenticationInfo.DefaultAuthenticationInfo });
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.LogInfo ("Controller", "Failed to load backend '" + backend + "' for '" + folder_name + "': ", e);
|
||||
return;
|
||||
}
|
||||
|
||||
repo.ChangesDetected += delegate {
|
||||
UpdateState ();
|
||||
};
|
||||
|
||||
repo.SyncStatusChanged += delegate (SyncStatus status) {
|
||||
if (status == SyncStatus.Idle) {
|
||||
ProgressPercentage = 0.0;
|
||||
ProgressSpeedUp = 0.0;
|
||||
ProgressSpeedDown = 0.0;
|
||||
ProgressInformation = "";
|
||||
}
|
||||
|
||||
UpdateState ();
|
||||
};
|
||||
|
||||
repo.ProgressChanged += delegate {
|
||||
ProgressPercentage = 0.0;
|
||||
ProgressSpeedUp = 0.0;
|
||||
ProgressSpeedDown = 0.0;
|
||||
ProgressInformation = "";
|
||||
|
||||
double percentage = 0.0;
|
||||
int repo_count = 0;
|
||||
|
||||
foreach (BaseRepository rep in Repositories) {
|
||||
if (rep.ProgressPercentage > 0) {
|
||||
percentage += rep.ProgressPercentage;
|
||||
repo_count++;
|
||||
}
|
||||
|
||||
if (rep.Status == SyncStatus.SyncUp)
|
||||
ProgressSpeedUp += rep.ProgressSpeed;
|
||||
|
||||
if (rep.Status == SyncStatus.SyncDown)
|
||||
ProgressSpeedDown += rep.ProgressSpeed;
|
||||
}
|
||||
|
||||
if (repo_count == 1)
|
||||
ProgressInformation = repo.ProgressInformation;
|
||||
|
||||
if (repo_count > 0)
|
||||
ProgressPercentage = percentage / repo_count;
|
||||
|
||||
UpdateState ();
|
||||
};
|
||||
|
||||
repo.NewChangeSet += delegate (ChangeSet change_set) {
|
||||
if (AvatarsEnabled) {
|
||||
string provider = "gravatar";
|
||||
|
||||
if (AvatarsProvider == "libravatar")
|
||||
provider = AvatarsProvider;
|
||||
|
||||
|
||||
change_set.User.AvatarFilePath = Avatars.GetAvatar (change_set.User.Email, 48, Config.DirectoryPath, provider);
|
||||
|
||||
}
|
||||
|
||||
NotificationRaised (change_set);
|
||||
};
|
||||
|
||||
repo.ConflictResolved += delegate {
|
||||
AlertNotificationRaised ("Resolved a file collision", "Local and server versions were kept.");
|
||||
};
|
||||
|
||||
AddRepository (repo);
|
||||
repo.Initialize ();
|
||||
}
|
||||
|
||||
|
||||
void OnFolderActivity (object o, FileSystemEventArgs args)
|
||||
{
|
||||
if (args != null && args.FullPath.EndsWith (".xml") &&
|
||||
args.ChangeType == WatcherChangeTypes.Created) {
|
||||
|
||||
HandleInvite (args);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void StartupInviteScan ()
|
||||
{
|
||||
foreach (string invite in Directory.GetFiles (FoldersPath, "*.xml"))
|
||||
HandleInvite (invite);
|
||||
}
|
||||
|
||||
|
||||
void HandleInvite (FileSystemEventArgs args)
|
||||
{
|
||||
HandleInvite (args.FullPath);
|
||||
}
|
||||
|
||||
|
||||
void HandleInvite (string path)
|
||||
{
|
||||
if (this.fetcher != null &&
|
||||
this.fetcher.IsActive) {
|
||||
|
||||
AlertNotificationRaised ("SparkleShare Setup seems busy", "Please wait for it to finish");
|
||||
|
||||
} else {
|
||||
SparkleInvite invite = new SparkleInvite (path);
|
||||
|
||||
// It may be that the invite we received a path to isn't
|
||||
// fully downloaded yet, so we try to read it several times
|
||||
int tries = 0;
|
||||
while (!invite.IsValid) {
|
||||
Thread.Sleep (100);
|
||||
invite = new SparkleInvite (path);
|
||||
tries++;
|
||||
|
||||
if (tries > 10) {
|
||||
AlertNotificationRaised ("Oh noes!", "This invite seems screwed up...");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (invite.IsValid)
|
||||
InviteReceived (invite);
|
||||
|
||||
File.Delete (path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Fires events for the current syncing state
|
||||
void UpdateState ()
|
||||
{
|
||||
bool has_unsynced_repos = false;
|
||||
bool has_syncing_repos = false;
|
||||
|
||||
foreach (BaseRepository repo in Repositories) {
|
||||
if (repo.Status == SyncStatus.SyncDown || repo.Status == SyncStatus.SyncUp || repo.IsBuffering) {
|
||||
has_syncing_repos = true;
|
||||
break;
|
||||
|
||||
} else if (repo.Status == SyncStatus.Idle && repo.HasUnsyncedChanges) {
|
||||
has_unsynced_repos = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_syncing_repos)
|
||||
OnSyncing ();
|
||||
else if (has_unsynced_repos)
|
||||
OnError ();
|
||||
else
|
||||
OnIdle ();
|
||||
}
|
||||
|
||||
|
||||
public List<StorageTypeInfo> FetcherAvailableStorageTypes {
|
||||
get {
|
||||
return this.fetcher.AvailableStorageTypes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void StartFetcher (SparkleFetcherInfo info)
|
||||
{
|
||||
string canonical_name = Path.GetFileName (info.RemotePath);
|
||||
string backend = info.Backend;
|
||||
|
||||
if (string.IsNullOrEmpty (backend))
|
||||
backend = BaseFetcher.GetBackend (info.Address);
|
||||
|
||||
info.TargetDirectory = Path.Combine (Config.TmpPath, canonical_name);
|
||||
|
||||
if (Directory.Exists (info.TargetDirectory))
|
||||
Directory.Delete (info.TargetDirectory, recursive: true);
|
||||
|
||||
try {
|
||||
this.fetcher = (BaseFetcher) Activator.CreateInstance (
|
||||
Type.GetType ("Sparkles." + backend + "." + backend + "Fetcher, Sparkles." + backend),
|
||||
new object [] { info, UserAuthenticationInfo});
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.LogInfo ("Controller",
|
||||
"Failed to load '" + backend + "' backend for '" + canonical_name + "' " + e.Message);
|
||||
|
||||
FolderFetchError (Path.Combine (info.Address, info.RemotePath).Replace (@"\", "/"),
|
||||
new string [] {"Failed to load \"" + backend + "\" backend for \"" + canonical_name + "\""});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.fetcher.Finished += FetcherFinishedDelegate;
|
||||
this.fetcher.Failed += FetcherFailedDelegate;
|
||||
this.fetcher.ProgressChanged += FetcherProgressChangedDelgate;
|
||||
|
||||
this.fetcher.Start ();
|
||||
}
|
||||
|
||||
|
||||
void FetcherFinishedDelegate (StorageType storage_type, string [] warnings)
|
||||
{
|
||||
if (storage_type == StorageType.Unknown) {
|
||||
ShowSetupWindow (PageType.StorageSetup);
|
||||
return;
|
||||
}
|
||||
|
||||
if (storage_type == StorageType.Encrypted) {
|
||||
ShowSetupWindowEvent (PageType.CryptoPassword);
|
||||
return;
|
||||
}
|
||||
|
||||
FinishFetcher (storage_type);
|
||||
}
|
||||
|
||||
|
||||
void FetcherFailedDelegate ()
|
||||
{
|
||||
FolderFetchError (this.fetcher.RemoteUrl.ToString (), this.fetcher.Errors);
|
||||
StopFetcher ();
|
||||
}
|
||||
|
||||
|
||||
void FetcherProgressChangedDelgate (double percentage, double speed, string information)
|
||||
{
|
||||
FolderFetching (percentage, speed, information);
|
||||
}
|
||||
|
||||
|
||||
public void StopFetcher ()
|
||||
{
|
||||
this.fetcher.Stop ();
|
||||
this.fetcher.Dispose ();
|
||||
|
||||
this.fetcher = null;
|
||||
this.watcher.EnableRaisingEvents = true;
|
||||
}
|
||||
|
||||
|
||||
public bool CheckPassword (string password)
|
||||
{
|
||||
return this.fetcher.IsFetchedRepoPasswordCorrect (password);
|
||||
}
|
||||
|
||||
|
||||
public void FinishFetcher (StorageType selected_storage_type, string password)
|
||||
{
|
||||
this.fetcher.EnableFetchedRepoCrypto (password);
|
||||
FinishFetcher (StorageType.Encrypted);
|
||||
}
|
||||
|
||||
|
||||
public void FinishFetcher (StorageType selected_storage_type)
|
||||
{
|
||||
this.watcher.EnableRaisingEvents = false;
|
||||
string identifier = this.fetcher.Complete (selected_storage_type);
|
||||
|
||||
string target_folder_path = DetermineFolderPath ();
|
||||
string target_folder_name = Path.GetFileName (target_folder_path);
|
||||
|
||||
try {
|
||||
Directory.Move (this.fetcher.TargetFolder, target_folder_path);
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.LogInfo ("Controller", "Error moving directory, trying again...", e);
|
||||
|
||||
try {
|
||||
ClearDirectoryAttributes (this.fetcher.TargetFolder);
|
||||
Directory.Move (this.fetcher.TargetFolder, target_folder_path);
|
||||
|
||||
} catch (Exception x) {
|
||||
Logger.LogInfo ("Controller", "Error moving directory", x);
|
||||
|
||||
this.fetcher.Dispose ();
|
||||
this.fetcher = null;
|
||||
this.watcher.EnableRaisingEvents = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
string backend = BaseFetcher.GetBackend (this.fetcher.RemoteUrl.ToString ());
|
||||
|
||||
Config.AddFolder (target_folder_name, identifier, this.fetcher.RemoteUrl.ToString (), backend);
|
||||
|
||||
if (this.fetcher.FetchedRepoStorageType != StorageType.Plain) {
|
||||
Config.SetFolderOptionalAttribute (target_folder_name,
|
||||
"storage_type", this.fetcher.FetchedRepoStorageType.ToString ());
|
||||
}
|
||||
|
||||
if (this.fetcher.OriginalFetcherInfo.AnnouncementsUrl != null) {
|
||||
Config.SetFolderOptionalAttribute (target_folder_name, "announcements_url",
|
||||
this.fetcher.OriginalFetcherInfo.AnnouncementsUrl);
|
||||
}
|
||||
|
||||
AddRepository (target_folder_path);
|
||||
RepositoriesLoaded = true;
|
||||
|
||||
FolderListChanged ();
|
||||
FolderFetched (this.fetcher.RemoteUrl.ToString (), this.fetcher.Warnings.ToArray ());
|
||||
|
||||
this.fetcher.Dispose ();
|
||||
this.fetcher = null;
|
||||
|
||||
this.watcher.EnableRaisingEvents = true;
|
||||
}
|
||||
|
||||
|
||||
string DetermineFolderPath ()
|
||||
{
|
||||
string folder_name = this.fetcher.FormatName ();
|
||||
string folder_group_path = Path.Combine (Config.FoldersPath, this.fetcher.RemoteUrl.Host);
|
||||
string folder_path = Path.Combine (Config.FoldersPath, folder_group_path, folder_name);
|
||||
|
||||
if (!Directory.Exists (folder_path)) {
|
||||
if (!Directory.Exists (folder_group_path))
|
||||
Directory.CreateDirectory (folder_group_path);
|
||||
|
||||
return folder_path;
|
||||
}
|
||||
|
||||
// Add a number suffix when needed, e.g. "Folder (3)"
|
||||
int suffix = 2 + Directory.GetDirectories (folder_group_path, folder_name + " (*").Length;
|
||||
return string.Format ("{0} ({1})", folder_path, suffix);
|
||||
}
|
||||
|
||||
|
||||
public void Quit ()
|
||||
{
|
||||
foreach (BaseRepository repo in Repositories)
|
||||
repo.Dispose ();
|
||||
|
||||
PlatformQuit ();
|
||||
}
|
||||
|
||||
|
||||
void ClearDirectoryAttributes (string path)
|
||||
{
|
||||
if (!Directory.Exists (path))
|
||||
return;
|
||||
|
||||
string [] folders = Directory.GetDirectories (path);
|
||||
|
||||
foreach (string folder in folders)
|
||||
ClearDirectoryAttributes (folder);
|
||||
|
||||
string [] files = Directory.GetFiles (path);
|
||||
|
||||
foreach (string file in files)
|
||||
if (file.IsSymlink ())
|
||||
File.SetAttributes (file, FileAttributes.Normal);
|
||||
}
|
||||
}
|
||||
}
|
10
SparkleShare/Common/HTML/Makefile.am
Executable file
|
@ -0,0 +1,10 @@
|
|||
dist_html_DATA = \
|
||||
day-entry.html \
|
||||
event-entry.html \
|
||||
event-log.html \
|
||||
jquery.js
|
||||
|
||||
htmldir = $(pkgdatadir)/html/
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
Makefile.in
|
|
@ -55,7 +55,7 @@
|
|||
background-color: #fefefe;
|
||||
color: <!-- $body-color -->;
|
||||
font-size: <!-- $body-font-size -->;
|
||||
font-family: -apple-system, "<!-- $body-font-family -->";
|
||||
font-family: "<!-- $body-font-family -->";
|
||||
margin: 0;
|
||||
-webkit-user-select: none;
|
||||
overflow-x: hidden;
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
html_files = ['event-log.html',
|
||||
'day-entry.html',
|
||||
'event-entry.html',
|
||||
'jquery.js'
|
||||
]
|
||||
|
||||
install_data(
|
||||
sources: html_files,
|
||||
install_dir: join_paths(install_dir, 'html'))
|
||||
|
Before Width: | Height: | Size: 122 KiB |
|
@ -1,195 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
id="svg9662"
|
||||
height="24"
|
||||
width="24"
|
||||
version="1.1"
|
||||
inkscape:version="0.91+devel r14094"
|
||||
sodipodi:docname="gitlab.svg"
|
||||
viewBox="0 0 24 24"
|
||||
inkscape:export-filename="/Users/hbons/Personal/Projects/SparkleShare/SparkleShare/Common/Presets/gitlab@2x.png"
|
||||
inkscape:export-xdpi="192"
|
||||
inkscape:export-ydpi="192">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1280"
|
||||
inkscape:window-height="755"
|
||||
id="namedview4365"
|
||||
inkscape:document-units="px"
|
||||
showgrid="false"
|
||||
inkscape:zoom="11.313708"
|
||||
inkscape:cx="8.5858812"
|
||||
inkscape:cy="8.8928334"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="g4326"
|
||||
inkscape:snap-global="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4341" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs3">
|
||||
<linearGradient
|
||||
id="linearGradient4343"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
id="stop4345"
|
||||
offset="0"
|
||||
style="stop-color:#df2000;stop-opacity:1" />
|
||||
<stop
|
||||
id="stop4347"
|
||||
offset="1"
|
||||
style="stop-color:#881805;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4318">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4320" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop4322" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4304">
|
||||
<stop
|
||||
style="stop-color:#ce2509;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4306" />
|
||||
<stop
|
||||
style="stop-color:#a9210a;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4308" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4304"
|
||||
id="linearGradient4310"
|
||||
x1="28.415369"
|
||||
y1="9.2727699"
|
||||
x2="31.521933"
|
||||
y2="19.203804"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4343"
|
||||
id="linearGradient4339"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="26.80905"
|
||||
y1="3.7043378"
|
||||
x2="31.521933"
|
||||
y2="19.203804"
|
||||
gradientTransform="translate(0,0.98994346)" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4318"
|
||||
id="radialGradient4349"
|
||||
cx="27.992599"
|
||||
cy="13.000279"
|
||||
fx="27.992599"
|
||||
fy="13.000279"
|
||||
r="10.832553"
|
||||
gradientTransform="matrix(2.7510713,0,0,2.3899162,-49.67941,-17.015106)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata4">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="g4326"
|
||||
transform="matrix(1.01163,0,0,1.0101587,-20.452835,-1.7447338)"
|
||||
style="stroke-width:0.9892233">
|
||||
<path
|
||||
style="fill:#e24329;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9892233;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 28.012539,10.206244 8.200627,0 L 38.959248,2.1937049 43.510972,14.607498 32.075235,22.996213 20.639498,14.56988 24.965517,2.0432347 Z"
|
||||
id="path4268"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
transform="matrix(-1,0,0,1,64.092707,0.98994346)"
|
||||
id="g4278"
|
||||
style="stroke-width:0.9892233">
|
||||
<g
|
||||
id="g4284"
|
||||
style="stroke-width:0.9892233">
|
||||
<path
|
||||
style="fill:#fc6d26;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9892233px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 28.012539,9.2163007 -5.818181,0 -1.55486,4.3636363 11.435737,8.426333 z"
|
||||
id="path4280"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
style="fill:#fca326;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9892233px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 22.694403,9.207369 32.028121,21.951963 20.639498,13.579937 Z"
|
||||
id="path4282"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g4288"
|
||||
transform="translate(0.01747244,0.98994346)"
|
||||
style="stroke-width:0.9892233">
|
||||
<g
|
||||
id="g4290"
|
||||
style="stroke-width:0.9892233">
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4292"
|
||||
d="m 28.012539,9.2163007 -5.818181,0 -1.55486,4.3636363 11.435737,8.426333 z"
|
||||
style="fill:#fc6d26;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9892233px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4294"
|
||||
d="M 22.694403,9.207369 32.028121,21.951963 20.639498,13.579937 Z"
|
||||
style="fill:#fca326;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9892233px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4266"
|
||||
d="m 28.012539,10.206244 8.200627,0 L 38.959248,2.1937049 43.510972,14.607498 32.075235,22.996213 20.639498,14.56988 24.965517,2.0432347 Z"
|
||||
style="fill:none;fill-rule:evenodd;stroke:url(#linearGradient4339);stroke-width:0.9892233;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
d="M 25.001953,4.0175781 21.826172,13.210938 32.078125,20.761719 42.3125,13.253906 38.990234,4.1992188 37.160156,9.5410156 A 1.0021178,1.0021178 0 0 1 36.212891,10.21875 l -8.201172,0 A 1.0021178,1.0021178 0 0 1 27.072266,9.5664062 L 25.001953,4.0175781 Z"
|
||||
id="path4312"
|
||||
style="opacity:0.4;fill:none;fill-rule:evenodd;stroke:url(#radialGradient4349);stroke-width:0.9892233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
inkscape:original="M 24.964844 1.0527344 L 20.638672 13.580078 L 32.076172 22.005859 L 43.511719 13.617188 L 38.958984 1.203125 L 36.212891 9.2167969 L 28.011719 9.2167969 L 24.964844 1.0527344 z "
|
||||
inkscape:radius="-1.0020176"
|
||||
sodipodi:type="inkscape:offset"
|
||||
transform="translate(0,0.98994346)" />
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 7.3 KiB |
|
@ -1,11 +0,0 @@
|
|||
image_files = ['tutorial-slide-1.png',
|
||||
'tutorial-slide-2.png',
|
||||
'side-splash.png',
|
||||
'about.png',
|
||||
'text-balloon.png',
|
||||
'user-icon-default.png']
|
||||
|
||||
install_data(
|
||||
sources: image_files,
|
||||
install_dir: join_paths(install_dir, 'pixmaps'))
|
||||
|
Before Width: | Height: | Size: 134 KiB |
3
SparkleShare/Common/Makefile.am
Normal file
|
@ -0,0 +1,3 @@
|
|||
SUBDIRS = HTML \
|
||||
Plugins \
|
||||
Pixmaps
|
12
SparkleShare/Common/Pixmaps/Makefile.am
Normal file
|
@ -0,0 +1,12 @@
|
|||
dist_pixmaps_DATA = \
|
||||
side-splash.png \
|
||||
user-icon-default.png \
|
||||
text-balloon.png \
|
||||
tutorial-slide-1.png\
|
||||
tutorial-slide-2.png \
|
||||
about.png
|
||||
|
||||
pixmapsdir = $(pkgdatadir)/pixmaps/
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
Makefile.in
|
|
@ -2114,7 +2114,7 @@
|
|||
id="g101011"
|
||||
transform="translate(-65.909,-78.641)"
|
||||
clip-path="url(#clipPath4254)"
|
||||
inkscape:export-filename="/Users/hbons/Projects/SparkleShare/SparkleShare/Common/Images/about@2x.png"
|
||||
inkscape:export-filename="/Users/hbons/Projects/SparkleShare/SparkleShare/Common/Pixmaps/about@2x.png"
|
||||
inkscape:export-xdpi="180"
|
||||
inkscape:export-ydpi="180">
|
||||
<rect
|
Before Width: | Height: | Size: 955 KiB After Width: | Height: | Size: 955 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
2009
SparkleShare/Common/Pixmaps/Sources/app-icons.svg
Normal file
After Width: | Height: | Size: 763 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.6 KiB |
63
SparkleShare/Common/Pixmaps/Sources/gitorious.svg
Normal file
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg id="svg9662" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="24" width="24" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs id="defs3">
|
||||
<filter id="filter10824" height="1.2825" width="1.209" color-interpolation-filters="sRGB" y="-.14123" x="-.10449">
|
||||
<feGaussianBlur id="feGaussianBlur10826" stdDeviation="0.95917508"/>
|
||||
</filter>
|
||||
<linearGradient id="linearGradient4333" y2="34.607" gradientUnits="userSpaceOnUse" x2="-545.52" gradientTransform="translate(569,1013)" y1="28.408" x1="-557.06">
|
||||
<stop id="stop10743" stop-color="#f46e6e" offset="0"/>
|
||||
<stop id="stop10749" stop-color="#f7d478" offset=".5"/>
|
||||
<stop id="stop10745" stop-color="#f46e6e" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient4335" y2="36.362" gradientUnits="userSpaceOnUse" x2="-551" gradientTransform="translate(569,1013)" y1="27.362" x1="-551">
|
||||
<stop id="stop10755" stop-color="#e50000" offset="0"/>
|
||||
<stop id="stop10757" stop-color="#ab0000" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient4337" y2="28.079" gradientUnits="userSpaceOnUse" x2="-557.01" gradientTransform="translate(569,1013)" y1="34.767" x1="-568.52">
|
||||
<stop id="stop10729" stop-color="#73d216" offset="0"/>
|
||||
<stop id="stop10735" stop-color="#efff20" offset=".5"/>
|
||||
<stop id="stop10731" stop-color="#89d216" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient4339" y2="35.858" gradientUnits="userSpaceOnUse" x2="-563.29" gradientTransform="translate(569,1013)" y1="25.486" x1="-563.29">
|
||||
<stop id="stop10719" stop-color="#4e9a06" offset="0"/>
|
||||
<stop id="stop10721" stop-color="#346704" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient4341" y2="40.663" gradientUnits="userSpaceOnUse" x2="-549.62" gradientTransform="translate(569,1013)" y1="15.384" x1="-562.87">
|
||||
<stop id="stop10836" stop-color="#fff" offset="0"/>
|
||||
<stop id="stop10838" stop-color="#fff" stop-opacity="0" offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<metadata id="metadata4">
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g id="layer1" transform="translate(0 -1028.4)">
|
||||
<rect id="rect10657" fill-opacity="0" height="24" width="24" y="1029.4" x=".088379"/>
|
||||
<path id="path10769" d="m-555.82 22.937-11.801 3.1974v9.6581l11.801 3.4441 10.23-3.1316v-9.9706z" transform="matrix(1.0124 0 0 1 575.75 1011.2)" filter="url(#filter10824)" fill="#2e3436"/>
|
||||
<path id="path10705" stroke-linejoin="round" d="m23.514 1034.8-10.55-3.9367-1.4805 0.054 0.007 19.914 1.509 0.017 10.514-3.1427z" stroke="url(#linearGradient4335)" fill="url(#linearGradient4333)"/>
|
||||
<path id="path10691" stroke-linejoin="round" d="m0.55806 1034.8 10.471-3.9459h1.4422l0.0365 19.989-1.4631-0.031-10.487-3.1115z" stroke="url(#linearGradient4339)" fill="url(#linearGradient4337)"/>
|
||||
<path id="path10693" d="m2 1036.4 9.0165-3.0054-0.0442 15.034l-8.972-2z" fill="#fff"/>
|
||||
<path id="rect10668" d="m5 1037 2-0.3728v8.6465l-1.9844-0.3518z" fill="#539710"/>
|
||||
<path id="rect10672" d="m3 1040.1 6.5938-0.9381v3.3314l-6.5938-0.9z" fill="#539710"/>
|
||||
<path id="path10737" d="m22.016 1036.4-9.016-3l0.0442 15.034 8.9723-2.0281z" fill="#fff"/>
|
||||
<rect id="rect10798" rx="0" ry="0" height="2" width="2" y="1030.4" x="11" fill="#85680e"/>
|
||||
<rect id="rect10800" rx="0" ry="0" height="2" width="2" y="1049.4" x="11" fill="#85680e"/>
|
||||
<rect id="rect10767" rx="0" ry="0" height="19" width="2" y="1031.4" x="11" fill="#eabe35"/>
|
||||
<rect id="rect10842" rx="0" ry="0" height="1" width="2" y="1031.4" x="11" fill="#a78312"/>
|
||||
<path id="path10810" opacity=".75" d="m12.816 1031.9-1.6843 0.01-9.6106 3.6209-0.0183 11.457 9.5022 2.8463 1.9639 0.031 9.5057-2.8861 0.0335-11.455z" stroke="url(#linearGradient4341)" stroke-width="1px" fill="none"/>
|
||||
<path id="path10830" d="m21.062 1040.1-6.5938-0.9381v3.3314l6.5938-0.8463z" fill="#dc0000"/>
|
||||
<g id="layer9" stroke-linejoin="round" transform="translate(-1687.8 -118.06)" stroke="#000" stroke-linecap="round" display="none" fill="#fff">
|
||||
<path id="path11071" opacity=".5" style="enable-background:new" d="m729.88 60.625a14.688 5.9375 0 1 1 -29.375 0 14.688 5.9375 0 1 1 29.375 0z" transform="matrix(1.2596 0 0 1.0947 -22.831 -6.3684)" display="inline" stroke-width=".85160"/>
|
||||
<path id="path11073" opacity=".5" style="enable-background:new" d="m729.88 60.625a14.688 5.9375 0 1 1 -29.375 0 14.688 5.9375 0 1 1 29.375 0z" transform="matrix(1.2596 0 0 1.0947 -22.831 -3.3684)" display="inline" stroke-width=".85160"/>
|
||||
<path id="path11075" opacity=".5" style="enable-background:new" d="m729.88 60.625a14.688 5.9375 0 1 1 -29.375 0 14.688 5.9375 0 1 1 29.375 0z" transform="matrix(1.0553 0 0 .90859 173.25 35.022)" display="inline" stroke-width="1.0212"/>
|
||||
<path id="path11084" opacity=".5" style="enable-background:new" d="m729.88 60.625a14.688 5.9375 0 1 1 -29.375 0 14.688 5.9375 0 1 1 29.375 0z" transform="matrix(1.0553 0 0 .97833 123.25 30.38)" display="inline" stroke-width=".98416"/>
|
||||
<path id="path11086" opacity=".5" style="enable-background:new" d="m729.88 60.625a14.688 5.9375 0 1 1 -29.375 0 14.688 5.9375 0 1 1 29.375 0z" transform="matrix(1.0894 0 0 .97833 98.901 27.38)" display="inline" stroke-width=".96866"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.5 KiB |
|
@ -16,7 +16,7 @@
|
|||
version="1.1"
|
||||
inkscape:version="0.48.2 r9819"
|
||||
sodipodi:docname="side-splash.svg"
|
||||
inkscape:export-filename="/Users/hbons/Projects/SparkleShare/SparkleShare/Common/Images/side-splash.png"
|
||||
inkscape:export-filename="/Users/hbons/Projects/SparkleShare/SparkleShare/Common/Pixmaps/side-splash.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<sodipodi:namedview
|
Before Width: | Height: | Size: 967 KiB After Width: | Height: | Size: 967 KiB |
105
SparkleShare/Common/Pixmaps/Sources/ssnet.svg
Normal file
|
@ -0,0 +1,105 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg id="svg8763" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="24.009" width="24.013" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs id="defs8765">
|
||||
<filter id="filter3330" height="1" width="1" color-interpolation-filters="sRGB" y="0" x="0">
|
||||
<feColorMatrix id="feColorMatrix3332" values="0" type="saturate"/>
|
||||
</filter>
|
||||
<filter id="filter4375-3-0" color-interpolation-filters="sRGB" width="1.0248" y="-.35609" x="-.012418" height="1.7122">
|
||||
<feGaussianBlur id="feGaussianBlur4377-0-0" stdDeviation="1.0664062"/>
|
||||
</filter>
|
||||
<linearGradient id="linearGradient11481">
|
||||
<stop id="stop11483" stop-color="#a04600" offset="0"/>
|
||||
<stop id="stop11485" stop-color="#ce5c00" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient21508" y2="18.848" gradientUnits="userSpaceOnUse" x2="24.866" gradientTransform="matrix(.30890 0 0 .27375 301.94 218.48)" y1="30.385" x1="24.866">
|
||||
<stop id="stop4910-6" stop-color="#ce5c00" offset="0"/>
|
||||
<stop id="stop4912-9" stop-color="#f57900" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient21510" y2="221.38" xlink:href="#linearGradient11481" gradientUnits="userSpaceOnUse" x2="315.29" gradientTransform="translate(0,1)" y1="232.34" x1="315.05"/>
|
||||
<radialGradient id="radialGradient21512" gradientUnits="userSpaceOnUse" cy="179.01" cx="306.1" gradientTransform="matrix(2.5489 0 0 .51730 -476.41 129.05)" r="8.6094">
|
||||
<stop id="stop4615" stop-color="#fff" offset="0"/>
|
||||
<stop id="stop4617" stop-color="#fff" stop-opacity="0" offset="1"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="linearGradient21514" y2="-9.4962" gradientUnits="userSpaceOnUse" x2="25.188" gradientTransform="matrix(.28968 0 0 .17690 301.87 224.04)" y1="50.897" x1="25.188">
|
||||
<stop id="stop4991-0" stop-color="#f57900" offset="0"/>
|
||||
<stop id="stop4993-4" stop-color="#fcaf3e" offset=".060437"/>
|
||||
<stop id="stop4995-6" stop-color="#fcaf3e" offset=".17754"/>
|
||||
<stop id="stop4997-0" stop-color="#f57900" offset=".89422"/>
|
||||
<stop id="stop4999-3" stop-color="#ce5c00" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient21516" y2="223.68" xlink:href="#linearGradient11481" gradientUnits="userSpaceOnUse" x2="314.47" y1="233.24" x1="314.49"/>
|
||||
<linearGradient id="linearGradient21518" y2="208.75" gradientUnits="userSpaceOnUse" x2="320.56" y1="184.62" x1="312.44">
|
||||
<stop id="stop4631" stop-color="#fff" offset="0"/>
|
||||
<stop id="stop4633" stop-color="#fff" stop-opacity="0" offset="1"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="radialGradient21520" gradientUnits="userSpaceOnUse" cy="525.86" cx="147.02" gradientTransform="matrix(1.5869 1.2599e-7 -5.9773e-8 .75290 -86.287 85.9)" r="103.05">
|
||||
<stop id="stop4349-3-4" stop-color="#fff" offset="0"/>
|
||||
<stop id="stop16502" stop-color="#fff" stop-opacity=".49804" offset=".5"/>
|
||||
<stop id="stop4351-6-4" stop-color="#fff" stop-opacity="0" offset="1"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="linearGradient21532" y2="263.79" gradientUnits="userSpaceOnUse" x2="117.64" y1="220.79" x1="117.64">
|
||||
<stop id="stop21528" stop-color="#fff" offset="0"/>
|
||||
<stop id="stop21530" stop-color="#fff" stop-opacity="0.36" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient21612" y2="251.79" gradientUnits="userSpaceOnUse" x2="94.143" gradientTransform="translate(-333.93 -139.65)" y1="251.79" x1="70.143">
|
||||
<stop id="stop21608" stop-color="#5dbbc6" offset="0"/>
|
||||
<stop id="stop21610" stop-color="#96dadb" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient21638" y2="112.14" gradientUnits="userSpaceOnUse" x2="-249.54" y1="112.14" x1="-263.79">
|
||||
<stop id="stop21634" stop-color="#3e3e3e" offset="0"/>
|
||||
<stop id="stop21636" stop-opacity="0" offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<metadata id="metadata8768">
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g id="layer1" transform="translate(-474.29 -337.78)">
|
||||
<g id="g8506" transform="translate(374.14 98)">
|
||||
<rect id="rect3589" height="24" width="120" display="none" y="241.6" x="97.775" fill="#eeeeec"/>
|
||||
<rect id="rect4698" height="48" width="48" display="none" y="25.598" x="87.775" fill="#eeeeec"/>
|
||||
<rect id="rect4700" height="32" width="32" display="none" y="101.6" x="94.775" fill="#eeeeec"/>
|
||||
<rect id="rect4702" height="22" width="22" display="none" y="152.6" x="94.775" fill="#eeeeec"/>
|
||||
<rect id="rect4704" height="16" width="16" display="none" y="194.6" x="94.775" fill="#eeeeec"/>
|
||||
<rect id="rect4706" height="24" width="24" display="none" y="151.6" x="93.775" fill="#eeeeec"/>
|
||||
<rect id="rect4708" height="256" width="256" display="none" y="3.5985" x="-188.22" fill="#eeeeec"/>
|
||||
<text id="text4710" style="enable-background:new" xml:space="preserve" font-size="18.301px" display="none" y="-2.8879292" x="-187.25412" font-family="Bitstream Vera Sans" fill="#000000"><tspan id="tspan4712" x="-187.25412" y="-2.8879292">places</tspan></text>
|
||||
<text id="text4714" style="enable-background:new" line-height="125%" font-weight="bold" xml:space="preserve" font-size="18.301px" y="-2.8879292" x="-66.254158" font-family="Droid Sans" display="none" fill="#000000"><tspan id="tspan4716" x="-66.254158" y="-2.8879292">sparkleshare</tspan></text>
|
||||
<rect id="rect22378" height="22" width="22" display="none" y="152.6" x="124.78" fill="#ededed"/>
|
||||
<rect id="rect22380" height="24" width="24" display="none" y="151.6" x="123.78" fill="#ededed"/>
|
||||
<rect id="rect12657-5" style="color:#000000;enable-background:new" rx="0" ry="0" height="0" width="2" y="165.6" x="467.78" fill="#888a85"/>
|
||||
<use id="use3340" style="enable-background:new" xlink:href="#g3326" transform="translate(-203.22 225.6)" height="400" width="500" y="0" x="0"/>
|
||||
<rect id="rect20728" transform="rotate(-90)" rx="3.7196" ry="3.7196" height="22.998" width="22.998" stroke="#6196c5" stroke-linecap="round" y="100.64" x="-263.29" stroke-width="1.002" fill="url(#linearGradient21612)"/>
|
||||
<path id="path21534" opacity="0.333" d="m248.42 154.51h-6.8943s-2.6516 0.57452-3.0494-3.0494v-11.093s0.35356-1.5468 1.9446-1.9445h5.1265c1.5468 0.48614 2.0771 2.0771 2.0771 2.0771h6.8501s0.75131 0.30935 1.1049 1.1048v9.8276c-0.0442 2.1655-2.0992 3.0992-2.0992 3.0992z" transform="translate(-134.86 105.79)" stroke="#fff" stroke-width="1px" fill="none"/>
|
||||
<g id="g21596" opacity=".5">
|
||||
<path id="rect21555" opacity=".25" d="m103.14 239.79h7l2 12z"/>
|
||||
<path id="path21558" opacity=".25" d="m121.14 263.79h-7l-2-12z"/>
|
||||
<path id="path21560" opacity=".25" d="m121.14 239.79h-7l-2 12z"/>
|
||||
<path id="path21562" opacity=".25" d="m103.14 263.79h7l2-12z"/>
|
||||
<path id="path21570" opacity=".25" d="m124.14 242.79 0.00001 7-12 2z"/>
|
||||
<path id="path21572" opacity=".25" d="m100.14 260.79-0.00001-7 12-2z"/>
|
||||
<path id="path21574" opacity=".25" d="m124.14 260.79v-7l-12-2z"/>
|
||||
<path id="path21576" opacity=".25" d="m100.14 242.79 0.00001 7 12 2z"/>
|
||||
</g>
|
||||
<g id="g21498" transform="translate(9.3677 49.194)">
|
||||
<g id="g10370" style="enable-background:new" transform="translate(-208.22 -24.402)">
|
||||
<path id="path10372" style="enable-background:new" d="m304.53 220.5c-0.57203 0.064-1.0035 0.54941-1 1.125v10.344c0.00006 0.62129 0.50371 1.1249 1.125 1.125h12.719c0.62129-0.00006 1.1249-0.50371 1.125-1.125v-8.3125c-0.00006-0.62129-0.50371-1.1249-1.125-1.125h-5.8438c-0.3334 0-0.20853 0.0527-0.40625-0.21875l-0.96875-1.3438c-0.2098-0.29211-0.54661-0.46632-0.90625-0.46875h-4.5938c-0.0416-0.002-0.0834-0.002-0.125 0z" fill-rule="evenodd" stroke="url(#linearGradient21510)" fill="url(#linearGradient21508)"/>
|
||||
<path id="path10374" opacity=".4" style="enable-background:new" d="m304.62 221.44c-0.10325 0.0115-0.15688 0.0836-0.15625 0.1875v10.344c0.00001 0.11468 0.0728 0.18749 0.1875 0.1875h12.719c0.11468-0.00001 0.18749-0.0728 0.1875-0.1875v-8.3125c-0.00001-0.11468-0.0728-0.18749-0.1875-0.1875h-5.8438c-0.0587 0-0.0805-0.001-0.15625 0-0.0757 0.001-0.29559 0.0325-0.5625-0.125-0.26691-0.15754-0.34468-0.32772-0.375-0.375-0.0303-0.0473-0.0322-0.0522-0.0625-0.0937l-0.96875-1.3438c-0.0355-0.0494-0.0954-0.0933-0.15625-0.0937h-4.5938c-0.0104 0.00017-0.0208 0.00017-0.0313 0l0.00005-0.0001z" stroke="url(#radialGradient21512)" fill="none"/>
|
||||
<path id="path10377" stroke-linejoin="round" style="enable-background:new" d="m309.78 222.5c-0.2554 0-0.45965 0.13987-0.59375 0.34375-0.43264 0.54853-1.1235 1.6562-1.6562 1.6562h-2.6875c-0.83807 0-1.3437 0.5428-1.3438 1.4688v6.125c0 1.3376 0.65057 2.4062 1.4688 2.4062h12.062c0.81819 0 1.4688-1.0687 1.4688-2.4062v-8.9062c0-0.37505-0.29595-0.6875-0.65625-0.6875h-8.0625z" fill-rule="evenodd" stroke="url(#linearGradient21516)" fill="url(#linearGradient21514)"/>
|
||||
<path id="path10379" opacity=".40639" stroke-linejoin="round" style="enable-background:new" d="m310.94 183.5c-0.74659 0.74659-1.6086 2-2.4062 2h-2.6875c-0.20314 0-0.22418 0.0344-0.25 0.0625-0.0258 0.0281-0.0937 0.12531-0.0937 0.40625v7.5312h13v-10h-7.5625-0.00005z" transform="translate(-1,40)" stroke="url(#linearGradient21518)" fill="none"/>
|
||||
<path id="path10381" opacity=".71595" style="enable-background:new" d="m250.06 476.75c-0.0458 1.3355-0.49131 2.357-1.2188 3.0625-0.72744 0.70545-1.7687 1.125-3.1875 1.125h-197.25c-1.4189 0-2.4805-0.44927-3.2188-1.1562-0.73826-0.70698-1.1869-1.7049-1.2188-3.0312v3c0.03187 1.3263 0.48049 2.3243 1.2188 3.0312 0.73826 0.70698 1.7998 1.1562 3.2188 1.1562h197.25c1.4188 0 2.4601-0.41955 3.1875-1.125 0.72744-0.70545 1.1729-1.727 1.2188-3.0625v-3z" fill-rule="evenodd" transform="matrix(.065331 0 0 .29412 301.15 90.449)" filter="url(#filter4375-3-0)" fill="url(#radialGradient21520)"/>
|
||||
</g>
|
||||
<path id="path5717-2" stroke-linejoin="round" style="enable-background:new" d="m103.15 201.61c-0.1681 0.0217-0.3164 0.15386-0.3579 0.31842l-0.7155 2.1494c-0.019 0.0382-0.032 0.0777-0.039 0.11973-0.038-0.0191-0.078-0.0318-0.1196-0.0395h-2.1866c-0.1222 0-0.2415 0.0637-0.3181 0.15921-0.1612 0.18061-0.1208 0.50107 0.079 0.63685l1.7891 1.3136 0.038 0.19106-0.6757 2.1095c-0.094 0.32925 0.3466 0.66015 0.6361 0.47763l1.7889-1.3134h0.229l1.7891 1.3134c0.1556 0.1019 0.3785 0.0841 0.5167-0.0395 0.1171-0.10827 0.1659-0.28518 0.1196-0.4379l-0.6759-2.1095c-0.064-0.0127 0.025-0.12737 0.038-0.19105l1.7889-1.3136c0.2004-0.13577 0.2401-0.45623 0.079-0.63684-0.076-0.0955-0.1958-0.15526-0.318-0.15921h-2.2264c-0.042 0.0127-0.081 0.0204-0.1196 0.0395-0.013-0.042-0.02-0.0815-0.039-0.11973l-0.6759-2.1493c-0.02-0.0752-0.062-0.14546-0.1196-0.19908-0.084-0.0815-0.2016-0.1261-0.318-0.11973l0.014 0.00013-0.0006 0.00001z" stroke="#c66f11" stroke-linecap="round" fill="none"/>
|
||||
<path id="path5717" stroke-linejoin="round" style="enable-background:new" d="m103.15 200.61c-0.1681 0.0217-0.3164 0.15386-0.3579 0.31842l-0.7155 2.1494c-0.019 0.0382-0.032 0.0777-0.039 0.11973-0.038-0.0191-0.078-0.0318-0.1196-0.0395h-2.1866c-0.1222 0-0.2415 0.0637-0.3181 0.15921-0.1612 0.18061-0.1208 0.50107 0.079 0.63685l1.7891 1.3136 0.038 0.19106-0.6757 2.1095c-0.094 0.32925 0.3466 0.66015 0.6361 0.47763l1.7889-1.3134h0.229l1.7891 1.3134c0.1556 0.1019 0.3785 0.0841 0.5167-0.0395 0.1171-0.10827 0.1659-0.28518 0.1196-0.4379l-0.6759-2.1095c-0.064-0.0127 0.025-0.12737 0.038-0.19105l1.7889-1.3136c0.2004-0.13577 0.2401-0.45623 0.079-0.63684-0.076-0.0955-0.1958-0.15526-0.318-0.15921h-2.2264c-0.042 0.0127-0.081 0.0204-0.1196 0.0395-0.013-0.042-0.02-0.0815-0.039-0.11973l-0.6759-2.1493c-0.02-0.0752-0.062-0.14546-0.1196-0.19908-0.084-0.0815-0.2016-0.1261-0.318-0.11973l0.014 0.00013-0.0006 0.00001z" stroke="#fff" stroke-linecap="round" fill="none"/>
|
||||
</g>
|
||||
<rect id="rect21524" opacity=".83759" rx="2.8127" ry="2.8127" height="20.998" width="20.998" stroke="url(#linearGradient21532)" stroke-linecap="round" y="241.29" x="101.64" stroke-width="1.002" fill="none"/>
|
||||
<rect id="rect21630" opacity="0.33" ry="3.9071" rx="3.9071" transform="rotate(-90)" height="22.998" width="22.998" stroke="url(#linearGradient21638)" stroke-linecap="round" y="100.64" x="-263.29" stroke-width="1.002" fill="none"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 186 KiB After Width: | Height: | Size: 143 KiB |
|
@ -3064,7 +3064,7 @@
|
|||
style="fill:url(#radialGradient211652);fill-opacity:1;stroke:#261f1f;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
inkscape:export-xdpi="180"
|
||||
inkscape:export-ydpi="180"
|
||||
inkscape:export-filename="/Users/hbons/Projects/SparkleShare/SparkleShare/Common/Images/tutorial-slide-1@2x.png" />
|
||||
inkscape:export-filename="/Users/hbons/Projects/SparkleShare/SparkleShare/Common/Pixmaps/tutorial-slide-1@2x.png" />
|
||||
<g
|
||||
transform="matrix(0.85916724,0,0,0.85916724,-926.30984,-650.2188)"
|
||||
id="g52133-7"
|
Before Width: | Height: | Size: 1.8 MiB After Width: | Height: | Size: 1.8 MiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 192 KiB After Width: | Height: | Size: 192 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 185 KiB After Width: | Height: | Size: 185 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 558 B After Width: | Height: | Size: 558 B |
18
SparkleShare/Common/Plugins/Makefile.am
Normal file
|
@ -0,0 +1,18 @@
|
|||
dist_plugins_DATA = \
|
||||
bitbucket.xml \
|
||||
github.xml \
|
||||
gitorious.xml \
|
||||
ssnet.xml \
|
||||
own-server.xml \
|
||||
planio.xml \
|
||||
github.png \
|
||||
gitorious.png \
|
||||
bitbucket.png \
|
||||
ssnet.png \
|
||||
planio.png \
|
||||
own-server.png
|
||||
|
||||
pluginsdir = $(pkgdatadir)/plugins/
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
Makefile.in
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
@ -1,12 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<sparkleshare>
|
||||
<preset>
|
||||
<plugin>
|
||||
<info>
|
||||
<name>Bitbucket</name>
|
||||
<description>Free code hosting for Git and Mercurial</description>
|
||||
<icon>bitbucket.png</icon>
|
||||
<backend>Git</backend>
|
||||
<fingerprint>4c:eb:19:11:0d:d6:19:65:7b:6a:40:8a:fb:b7:4d:51:81:a1:7a:07:74:4a:b5:22:0c:91:86:42:74:88:9b:bc</fingerprint>
|
||||
<fingerprint>97:8c:1b:f2:6f:14:6b:5c:3b:ec:aa:46:46:74:7c:40</fingerprint>
|
||||
</info>
|
||||
<address>
|
||||
<value>ssh://git@bitbucket.org/</value>
|
||||
|
@ -17,5 +17,5 @@
|
|||
<example>/username/project</example>
|
||||
<uses_lower_case>True</uses_lower_case>
|
||||
</path>
|
||||
</preset>
|
||||
</plugin>
|
||||
</sparkleshare>
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
@ -1,13 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<sparkleshare>
|
||||
<preset>
|
||||
<plugin>
|
||||
<info>
|
||||
<name>GitHub</name>
|
||||
<description>The biggest collection of Open Source projects</description>
|
||||
<description>Collaborate on projects hosted on GitHub</description>
|
||||
<icon>github.png</icon>
|
||||
<backend>Git</backend>
|
||||
<storage_type>LargeFiles</storage_type>
|
||||
<fingerprint>92:a3:7f:bd:5e:21:a5:3a:95:c7:16:e1:14:4f:44:2f:58:2b:94:d0:fa:fc:67:3e:b6:71:7a:4e:b5:1a:88:a7</fingerprint>
|
||||
<fingerprint>16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48</fingerprint>
|
||||
</info>
|
||||
<address>
|
||||
<value>ssh://git@github.com/</value>
|
||||
|
@ -17,5 +16,5 @@
|
|||
<value/>
|
||||
<example>/username/project</example>
|
||||
</path>
|
||||
</preset>
|
||||
</plugin>
|
||||
</sparkleshare>
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
BIN
SparkleShare/Common/Plugins/gitorious.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
20
SparkleShare/Common/Plugins/gitorious.xml
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<sparkleshare>
|
||||
<plugin>
|
||||
<info>
|
||||
<name>Gitorious</name>
|
||||
<description>Open source infrastructure for hosting open source projects</description>
|
||||
<icon>gitorious.png</icon>
|
||||
<backend>Git</backend>
|
||||
<fingerprint>7e:af:8d:ec:f0:39:5e:ba:52:16:ce:19:fa:d4:b8:7d</fingerprint>
|
||||
</info>
|
||||
<address>
|
||||
<value>ssh://git@gitorious.org/</value>
|
||||
<example/>
|
||||
</address>
|
||||
<path>
|
||||
<value/>
|
||||
<example>/project/repository</example>
|
||||
</path>
|
||||
</plugin>
|
||||
</sparkleshare>
|
BIN
SparkleShare/Common/Plugins/gitorious@2x.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<sparkleshare>
|
||||
<preset>
|
||||
<plugin>
|
||||
<info>
|
||||
<name>Own server</name>
|
||||
<name>On my own server</name>
|
||||
<description>Everything under my control</description>
|
||||
<icon>own-server.png</icon>
|
||||
<backend>Git</backend>
|
||||
|
@ -15,6 +15,5 @@
|
|||
<value/>
|
||||
<example>/path/to/project</example>
|
||||
</path>
|
||||
</preset>
|
||||
</plugin>
|
||||
</sparkleshare>
|
||||
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
BIN
SparkleShare/Common/Plugins/planio.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
21
SparkleShare/Common/Plugins/planio.xml
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<sparkleshare>
|
||||
<plugin>
|
||||
<info>
|
||||
<name>Planio</name>
|
||||
<description>500MB of unlimited free hosted Git repos and project management</description>
|
||||
<icon>planio.png</icon>
|
||||
<backend>Git</backend>
|
||||
<fingerprint>77:d1:54:d7:33:7e:38:43:40:70:ca:2d:3a:24:05:22</fingerprint>
|
||||
<announcements_url>tcp://sparkleshare-notifications.plan.io:443</announcements_url>
|
||||
</info>
|
||||
<address>
|
||||
<value/>
|
||||
<example>ssh://git@[account].plan.io</example>
|
||||
</address>
|
||||
<path>
|
||||
<value/>
|
||||
<example>/[account]-[project].git</example>
|
||||
</path>
|
||||
</plugin>
|
||||
</sparkleshare>
|
BIN
SparkleShare/Common/Plugins/planio@2x.png
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
SparkleShare/Common/Plugins/ssnet.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
19
SparkleShare/Common/Plugins/ssnet.xml
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<sparkleshare>
|
||||
<plugin>
|
||||
<info>
|
||||
<name>SparkleShare.Net</name>
|
||||
<description>The easiest way to share projects with SparkleShare</description>
|
||||
<icon>ssnet.png</icon>
|
||||
<backend>Git</backend>
|
||||
</info>
|
||||
<address>
|
||||
<value>ssh://storage@sparkleshare.net/</value>
|
||||
<example/>
|
||||
</address>
|
||||
<path>
|
||||
<value/>
|
||||
<example>/username/project</example>
|
||||
</path>
|
||||
</plugin>
|
||||
</sparkleshare>
|
BIN
SparkleShare/Common/Plugins/ssnet@2x.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 1.2 KiB |
|
@ -1,21 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<sparkleshare>
|
||||
<preset>
|
||||
<info>
|
||||
<name>GitLab</name>
|
||||
<description>Open Source alternative to GitHub</description>
|
||||
<icon>gitlab.png</icon>
|
||||
<backend>Git</backend>
|
||||
<fingerprint>44:e4:05:bc:f4:e1:1a:b5:b8:46:e5:8b:a0:bf:6d:ab:d2:3d:cc:9e:36:7c:ae:17:cb:0c:91:b5:b3:b3:fc:44</fingerprint>
|
||||
</info>
|
||||
<address>
|
||||
<value>ssh://git@gitlab.com/</value>
|
||||
<example/>
|
||||
</address>
|
||||
<path>
|
||||
<value/>
|
||||
<example>/username/project</example>
|
||||
</path>
|
||||
</preset>
|
||||
</sparkleshare>
|
||||
|
Before Width: | Height: | Size: 2.9 KiB |
|
@ -1,10 +0,0 @@
|
|||
preset_files = ['github.xml', 'github.png',
|
||||
'gitlab.xml', 'gitlab.png',
|
||||
'bitbucket.xml', 'bitbucket.png',
|
||||
'own-server.xml', 'own-server.png'
|
||||
]
|
||||
|
||||
install_data(
|
||||
sources: preset_files,
|
||||
install_dir: join_paths(install_dir, 'presets'))
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
// SparkleShare, a collaboration and sharing tool.
|
||||
// Copyright (C) 2010 Hylke Bons <hi@planetpeanut.uk>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
using Sparkles;
|
||||
|
||||
namespace SparkleShare {
|
||||
|
||||
public class SparkleShare {
|
||||
|
||||
public static Controller Controller;
|
||||
public static UserInterface UI;
|
||||
|
||||
static Mutex program_mutex = new Mutex (false, "SparkleShare");
|
||||
|
||||
|
||||
#if !__MonoCS__
|
||||
[STAThread]
|
||||
#endif
|
||||
public static void Main (string [] args)
|
||||
{
|
||||
// Only allow one instance of SparkleShare (on Windows)
|
||||
if (!program_mutex.WaitOne (0, exitContext: false)) {
|
||||
Console.WriteLine ("SparkleShare is already running.");
|
||||
Environment.Exit (-1);
|
||||
}
|
||||
|
||||
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
|
||||
|
||||
Controller = new Controller (Configuration.DefaultConfiguration);
|
||||
Controller.Initialize ();
|
||||
|
||||
UI = new UserInterface ();
|
||||
UI.Run (args);
|
||||
|
||||
#if !__MonoCS__
|
||||
// Suppress assertion messages in debug mode
|
||||
GC.Collect (GC.MaxGeneration, GCCollectionMode.Forced);
|
||||
GC.WaitForPendingFinalizers ();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void OnUnhandledException (object sender, UnhandledExceptionEventArgs exception_args)
|
||||
{
|
||||
var exception = (Exception) exception_args.ExceptionObject;
|
||||
Logger.WriteCrashReport (exception);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||
<HasSharedItems>true</HasSharedItems>
|
||||
<SharedGUID>{F16E3683-B622-4654-B799-99C8D68AA963}</SharedGUID>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<Import_RootNamespace>SparkleShare</Import_RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)AboutController.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Avatars.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)BaseController.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)BubblesController.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)EventLogController.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)NoteController.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)SetupController.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)SparkleShare.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)StatusIconController.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,14 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{F16E3683-B622-4654-B799-99C8D68AA963}</ProjectGuid>
|
||||
<ReleaseVersion></ReleaseVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
|
||||
<Import Project="SparkleShare.projitems" Label="Shared" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
|
||||
</Project>
|
222
SparkleShare/Common/Translations/Makefile.in.in
Normal file
|
@ -0,0 +1,222 @@
|
|||
# Makefile for program source directory in GNU NLS utilities package.
|
||||
# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
|
||||
# Copyright (C) 2004-2008 Rodney Dawes <dobey.pwns@gmail.com>
|
||||
#
|
||||
# This file may be copied and used freely without restrictions. It may
|
||||
# be used in projects which are not available under a GNU Public License,
|
||||
# but which still want to provide support for the GNU gettext functionality.
|
||||
#
|
||||
# - Modified by Owen Taylor <otaylor@redhat.com> to use GETTEXT_PACKAGE
|
||||
# instead of PACKAGE and to look for po2tbl in ./ not in intl/
|
||||
#
|
||||
# - Modified by jacob berkman <jacob@ximian.com> to install
|
||||
# Makefile.in.in and po2tbl.sed.in for use with glib-gettextize
|
||||
#
|
||||
# - Modified by Rodney Dawes <dobey.pwns@gmail.com> for use with intltool
|
||||
#
|
||||
# We have the following line for use by intltoolize:
|
||||
# INTLTOOL_MAKEFILE
|
||||
|
||||
GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
|
||||
PACKAGE = @PACKAGE@
|
||||
VERSION = @VERSION@
|
||||
|
||||
SHELL = @SHELL@
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
top_builddir = @top_builddir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
libdir = @libdir@
|
||||
DATADIRNAME = @DATADIRNAME@
|
||||
itlocaledir = $(prefix)/$(DATADIRNAME)/locale
|
||||
subdir = po
|
||||
install_sh = @install_sh@
|
||||
# Automake >= 1.8 provides @mkdir_p@.
|
||||
# Until it can be supposed, use the safe fallback:
|
||||
mkdir_p = $(install_sh) -d
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
GMSGFMT = @GMSGFMT@
|
||||
MSGFMT = @MSGFMT@
|
||||
XGETTEXT = @XGETTEXT@
|
||||
INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
|
||||
INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
|
||||
MSGMERGE = INTLTOOL_EXTRACT="$(INTLTOOL_EXTRACT)" XGETTEXT="$(XGETTEXT)" srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --dist
|
||||
GENPOT = INTLTOOL_EXTRACT="$(INTLTOOL_EXTRACT)" XGETTEXT="$(XGETTEXT)" srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --pot
|
||||
|
||||
ALL_LINGUAS = @ALL_LINGUAS@
|
||||
|
||||
PO_LINGUAS=$(shell if test -r $(srcdir)/LINGUAS; then grep -v "^\#" $(srcdir)/LINGUAS; else echo "$(ALL_LINGUAS)"; fi)
|
||||
|
||||
USER_LINGUAS=$(shell if test -n "$(LINGUAS)"; then LLINGUAS="$(LINGUAS)"; ALINGUAS="$(ALL_LINGUAS)"; for lang in $$LLINGUAS; do if test -n "`grep \^$$lang$$ $(srcdir)/LINGUAS 2>/dev/null`" -o -n "`echo $$ALINGUAS|tr ' ' '\n'|grep \^$$lang$$`"; then printf "$$lang "; fi; done; fi)
|
||||
|
||||
USE_LINGUAS=$(shell if test -n "$(USER_LINGUAS)" -o -n "$(LINGUAS)"; then LLINGUAS="$(USER_LINGUAS)"; else if test -n "$(PO_LINGUAS)"; then LLINGUAS="$(PO_LINGUAS)"; else LLINGUAS="$(ALL_LINGUAS)"; fi; fi; for lang in $$LLINGUAS; do printf "$$lang "; done)
|
||||
|
||||
POFILES=$(shell LINGUAS="$(PO_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.po "; done)
|
||||
|
||||
DISTFILES = Makefile.in.in POTFILES.in $(POFILES)
|
||||
EXTRA_DISTFILES = ChangeLog POTFILES.skip Makevars LINGUAS
|
||||
|
||||
POTFILES = \
|
||||
# This comment gets stripped out
|
||||
|
||||
CATALOGS=$(shell LINGUAS="$(USE_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.gmo "; done)
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .po .pox .gmo .mo .msg .cat
|
||||
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
INTLTOOL_V_MSGFMT = $(INTLTOOL__v_MSGFMT_$(V))
|
||||
INTLTOOL__v_MSGFMT_= $(INTLTOOL__v_MSGFMT_$(AM_DEFAULT_VERBOSITY))
|
||||
INTLTOOL__v_MSGFMT_0 = @echo " MSGFMT" $@;
|
||||
|
||||
.po.pox:
|
||||
$(MAKE) $(GETTEXT_PACKAGE).pot
|
||||
$(MSGMERGE) $< $(GETTEXT_PACKAGE).pot -o $*.pox
|
||||
|
||||
.po.mo:
|
||||
$(INTLTOOL_V_MSGFMT)$(MSGFMT) -o $@ $<
|
||||
|
||||
.po.gmo:
|
||||
$(INTLTOOL_V_MSGFMT)file=`echo $* | sed 's,.*/,,'`.gmo \
|
||||
&& rm -f $$file && $(GMSGFMT) -o $$file $<
|
||||
|
||||
.po.cat:
|
||||
sed -f ../intl/po2msg.sed < $< > $*.msg \
|
||||
&& rm -f $@ && gencat $@ $*.msg
|
||||
|
||||
|
||||
all: all-@USE_NLS@
|
||||
|
||||
all-yes: $(CATALOGS)
|
||||
all-no:
|
||||
|
||||
$(GETTEXT_PACKAGE).pot: $(POTFILES)
|
||||
$(GENPOT)
|
||||
|
||||
install: install-data
|
||||
install-data: install-data-@USE_NLS@
|
||||
install-data-no: all
|
||||
install-data-yes: all
|
||||
linguas="$(USE_LINGUAS)"; \
|
||||
for lang in $$linguas; do \
|
||||
dir=$(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES; \
|
||||
$(mkdir_p) $$dir; \
|
||||
if test -r $$lang.gmo; then \
|
||||
$(INSTALL_DATA) $$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \
|
||||
echo "installing $$lang.gmo as $$dir/$(GETTEXT_PACKAGE).mo"; \
|
||||
else \
|
||||
$(INSTALL_DATA) $(srcdir)/$$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \
|
||||
echo "installing $(srcdir)/$$lang.gmo as" \
|
||||
"$$dir/$(GETTEXT_PACKAGE).mo"; \
|
||||
fi; \
|
||||
if test -r $$lang.gmo.m; then \
|
||||
$(INSTALL_DATA) $$lang.gmo.m $$dir/$(GETTEXT_PACKAGE).mo.m; \
|
||||
echo "installing $$lang.gmo.m as $$dir/$(GETTEXT_PACKAGE).mo.m"; \
|
||||
else \
|
||||
if test -r $(srcdir)/$$lang.gmo.m ; then \
|
||||
$(INSTALL_DATA) $(srcdir)/$$lang.gmo.m \
|
||||
$$dir/$(GETTEXT_PACKAGE).mo.m; \
|
||||
echo "installing $(srcdir)/$$lang.gmo.m as" \
|
||||
"$$dir/$(GETTEXT_PACKAGE).mo.m"; \
|
||||
else \
|
||||
true; \
|
||||
fi; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
# Empty stubs to satisfy archaic automake needs
|
||||
dvi info ctags tags CTAGS TAGS ID:
|
||||
|
||||
# Define this as empty until I found a useful application.
|
||||
install-exec installcheck:
|
||||
|
||||
uninstall:
|
||||
linguas="$(USE_LINGUAS)"; \
|
||||
for lang in $$linguas; do \
|
||||
rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo; \
|
||||
rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo.m; \
|
||||
done
|
||||
|
||||
check: all $(GETTEXT_PACKAGE).pot
|
||||
rm -f missing notexist
|
||||
srcdir=$(srcdir) $(INTLTOOL_UPDATE) -m
|
||||
if [ -r missing -o -r notexist ]; then \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
mostlyclean:
|
||||
rm -f *.pox $(GETTEXT_PACKAGE).pot *.old.po cat-id-tbl.tmp
|
||||
rm -f .intltool-merge-cache
|
||||
|
||||
clean: mostlyclean
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile Makefile.in POTFILES stamp-it
|
||||
rm -f *.mo *.msg *.cat *.cat.m *.gmo
|
||||
|
||||
maintainer-clean: distclean
|
||||
@echo "This command is intended for maintainers to use;"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
rm -f Makefile.in.in
|
||||
|
||||
distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
|
||||
dist distdir: $(DISTFILES)
|
||||
dists="$(DISTFILES)"; \
|
||||
extra_dists="$(EXTRA_DISTFILES)"; \
|
||||
for file in $$extra_dists; do \
|
||||
test -f $(srcdir)/$$file && dists="$$dists $(srcdir)/$$file"; \
|
||||
done; \
|
||||
for file in $$dists; do \
|
||||
test -f $$file || file="$(srcdir)/$$file"; \
|
||||
ln $$file $(distdir) 2> /dev/null \
|
||||
|| cp -p $$file $(distdir); \
|
||||
done
|
||||
|
||||
update-po: Makefile
|
||||
$(MAKE) $(GETTEXT_PACKAGE).pot
|
||||
tmpdir=`pwd`; \
|
||||
linguas="$(USE_LINGUAS)"; \
|
||||
for lang in $$linguas; do \
|
||||
echo "$$lang:"; \
|
||||
result="`$(MSGMERGE) -o $$tmpdir/$$lang.new.po $$lang`"; \
|
||||
if $$result; then \
|
||||
if cmp $(srcdir)/$$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
|
||||
rm -f $$tmpdir/$$lang.new.po; \
|
||||
else \
|
||||
if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
|
||||
:; \
|
||||
else \
|
||||
echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
|
||||
rm -f $$tmpdir/$$lang.new.po; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
fi; \
|
||||
else \
|
||||
echo "msgmerge for $$lang.gmo failed!"; \
|
||||
rm -f $$tmpdir/$$lang.new.po; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
Makefile POTFILES: stamp-it
|
||||
@if test ! -f $@; then \
|
||||
rm -f stamp-it; \
|
||||
$(MAKE) stamp-it; \
|
||||
fi
|
||||
|
||||
stamp-it: Makefile.in.in $(top_builddir)/config.status POTFILES.in
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES=$(subdir)/Makefile.in CONFIG_HEADERS= CONFIG_LINKS= \
|
||||
$(SHELL) ./config.status
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make not to export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
# Translators:
|
||||
# <benjamincottyn@gmail.com>, 2011.
|
||||
# <hi@planetpeanut.uk>, 2011.
|
||||
# <hylkebons@gmail.com>, 2011.
|
||||
# <inxidious@gmail.com>, 2011.
|
||||
# Łukasz Jernaś <deejay1@srem.org>, 2011.
|
||||
# <m.manshanden@gmail.com>, 2011.
|
||||
|
|
|
@ -1,166 +0,0 @@
|
|||
// SparkleShare, a collaboration and sharing tool.
|
||||
// Copyright (C) 2010 Hylke Bons (hi@planetpeanut.uk)
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see (http://www.gnu.org/licenses/).
|
||||
|
||||
|
||||
using System;
|
||||
|
||||
using Sparkles;
|
||||
using Gtk;
|
||||
|
||||
namespace SparkleShare {
|
||||
|
||||
public class About : Window {
|
||||
|
||||
public AboutController Controller = new AboutController ();
|
||||
|
||||
Label updates;
|
||||
|
||||
|
||||
public About () : base ("About SparkleShare")
|
||||
{
|
||||
IconName = "org.sparkleshare.SparkleShare";
|
||||
Resizable = false;
|
||||
WindowPosition = WindowPosition.CenterAlways;
|
||||
TypeHint = Gdk.WindowTypeHint.Dialog;
|
||||
|
||||
SetSizeRequest (640, 260);
|
||||
|
||||
|
||||
DeleteEvent += delegate (object o, DeleteEventArgs args) {
|
||||
Controller.WindowClosed ();
|
||||
args.RetVal = true;
|
||||
};
|
||||
|
||||
KeyPressEvent += delegate (object o, KeyPressEventArgs args) {
|
||||
if (args.Event.Key == Gdk.Key.Escape ||
|
||||
(args.Event.State == Gdk.ModifierType.ControlMask && args.Event.Key == Gdk.Key.w)) {
|
||||
|
||||
Controller.WindowClosed ();
|
||||
}
|
||||
};
|
||||
|
||||
Controller.HideWindowEvent += delegate {
|
||||
Application.Invoke (delegate { Hide (); });
|
||||
};
|
||||
|
||||
Controller.ShowWindowEvent += delegate {
|
||||
Application.Invoke (delegate {
|
||||
ShowAll ();
|
||||
Present ();
|
||||
});
|
||||
};
|
||||
|
||||
Controller.UpdateLabelEvent += delegate (string text) {
|
||||
Application.Invoke (delegate {
|
||||
updates.Text = text;
|
||||
updates.ShowAll();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
CreateAbout ();
|
||||
}
|
||||
|
||||
|
||||
void CreateAbout ()
|
||||
{
|
||||
CssProvider window_css_provider = new CssProvider ();
|
||||
string image_path = InstallationInfo.Directory + "/pixmaps/about.png";
|
||||
|
||||
window_css_provider.LoadFromData ("window, GtkWindow {" +
|
||||
" background-image: url('" + image_path + "');" +
|
||||
" background-repeat: no-repeat;" +
|
||||
" background-position: left bottom;" +
|
||||
"}");
|
||||
|
||||
StyleContext.AddProvider (window_css_provider, 800);
|
||||
|
||||
var layout_vertical = new VBox (false, 0);
|
||||
var links_layout = new HBox (false, 16);
|
||||
|
||||
CssProvider label_css_provider = new CssProvider ();
|
||||
label_css_provider.LoadFromData ("label { color: #fff; font-size: 14pt; background-color: rgba(0, 0, 0, 0); }");
|
||||
|
||||
CssProvider label_highlight_css_provider = new CssProvider ();
|
||||
label_highlight_css_provider.LoadFromData ("label { color: #a8bbcf; font-size: 12pt; }");
|
||||
|
||||
var version = new Label {
|
||||
Text = "version " + Controller.RunningVersion,
|
||||
Xalign = 0, Xpad = 0
|
||||
};
|
||||
|
||||
if (InstallationInfo.IsFlatpak)
|
||||
version.Text += " (Flatpak)";
|
||||
|
||||
updates = new Label ("Checking for updates…") {
|
||||
Xalign = 0, Xpad = 0
|
||||
};
|
||||
|
||||
var copyright = new Label {
|
||||
Markup = string.Format ("Copyright © 2010–{0} Hylke Bons and others", DateTime.Now.Year),
|
||||
Xalign = 0, Xpad = 0
|
||||
};
|
||||
|
||||
var license = new Label ("SparkleShare is Open Source and you’re free to\n" +
|
||||
"use, change, and share it under the GNU GPLv3") {
|
||||
|
||||
Xalign = 0, Xpad = 0
|
||||
};
|
||||
|
||||
license.StyleContext.AddProvider (label_css_provider, 800);
|
||||
updates.StyleContext.AddProvider (label_highlight_css_provider, 800);
|
||||
version.StyleContext.AddProvider (label_css_provider, 800);
|
||||
copyright.StyleContext.AddProvider (label_css_provider, 800);
|
||||
|
||||
var website_link = new Link ("Website", Controller.WebsiteLinkAddress);
|
||||
var credits_link = new Link ("Credits", Controller.CreditsLinkAddress);
|
||||
var report_problem_link = new Link ("Report a problem", Controller.ReportProblemLinkAddress);
|
||||
var debug_log_link = new Link ("Debug log", Controller.DebugLogLinkAddress);
|
||||
|
||||
layout_vertical.PackStart (new Label (""), true, true, 0);
|
||||
layout_vertical.PackStart (version, false, false, 0);
|
||||
layout_vertical.PackStart (updates, false, false, 0);
|
||||
layout_vertical.PackStart (copyright, false, false, 6);
|
||||
layout_vertical.PackStart (license, false, false, 6);
|
||||
layout_vertical.PackStart (links_layout, false, false, 6);
|
||||
|
||||
links_layout.PackStart (website_link, false, false, 0);
|
||||
links_layout.PackStart (credits_link, false, false, 0);
|
||||
links_layout.PackStart (report_problem_link, false, false, 0);
|
||||
links_layout.PackStart (debug_log_link, false, false, 0);
|
||||
|
||||
var layout_horizontal = new HBox (false, 0);
|
||||
layout_horizontal.PackStart (new Label (""), false, false, 149);
|
||||
layout_horizontal.PackStart (layout_vertical, false, false, 0);
|
||||
|
||||
Add (layout_horizontal);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Link : Label {
|
||||
|
||||
public Link (string label, string url)
|
||||
{
|
||||
Markup = string.Format ("<a href=\"{0}\">{1}</a>", url, label);
|
||||
CanFocus = false;
|
||||
|
||||
CssProvider css_provider = new CssProvider ();
|
||||
css_provider.LoadFromData ("label a { color: #729fcf; font-size: 14pt; }");
|
||||
StyleContext.AddProvider (css_provider, 800);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,151 +0,0 @@
|
|||
// SparkleShare, a collaboration and sharing tool.
|
||||
// Copyright (C) 2010 Hylke Bons <hi@planetpeanut.uk>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
using Gtk;
|
||||
using Mono.Unix.Native;
|
||||
|
||||
using Sparkles;
|
||||
using Sparkles.Git;
|
||||
|
||||
namespace SparkleShare {
|
||||
|
||||
public class Controller : BaseController {
|
||||
|
||||
public Controller (Configuration config) : base (config)
|
||||
{
|
||||
if (InstallationInfo.IsFlatpak)
|
||||
GitCommand.ExecPath = Path.Combine ("/app", "libexec", "git-core");
|
||||
}
|
||||
|
||||
|
||||
public override void CreateSparkleShareFolder ()
|
||||
{
|
||||
if (!Directory.Exists (Configuration.DefaultConfiguration.FoldersPath)) {
|
||||
Directory.CreateDirectory (Configuration.DefaultConfiguration.FoldersPath);
|
||||
Syscall.chmod (Configuration.DefaultConfiguration.FoldersPath, (FilePermissions) 448); // 448 -> 700
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void SetFolderIcon ()
|
||||
{
|
||||
var gio_set = new Command ("gio", "set \"" + Configuration.DefaultConfiguration.FoldersPath + "\" " +
|
||||
"metadata::custom-icon-name org.sparkleshare.SparkleShare");
|
||||
|
||||
string XDG_DATA_HOME = Path.Combine (Config.HomePath, ".local", "share");
|
||||
gio_set.StartInfo.EnvironmentVariables ["XDG_DATA_HOME"] = XDG_DATA_HOME;
|
||||
|
||||
gio_set.StartAndWaitForExit ();
|
||||
}
|
||||
|
||||
|
||||
public override void CreateStartupItem ()
|
||||
{
|
||||
string autostart_file_path = Path.Combine (Path.GetDirectoryName (InstallationInfo.Directory),
|
||||
"applications", "SparkleShare.Autostart.desktop");
|
||||
|
||||
string autostart_file_dest = Path.Combine (Config.HomePath, ".config", "autostart", "SparkleShare.Autostart.desktop");
|
||||
string autostart_path = Path.GetDirectoryName (autostart_file_dest);
|
||||
|
||||
if (!Directory.Exists (autostart_path))
|
||||
Directory.CreateDirectory (autostart_path);
|
||||
|
||||
if (File.Exists (autostart_file_dest))
|
||||
return;
|
||||
|
||||
try {
|
||||
File.Copy (autostart_file_path, autostart_file_dest);
|
||||
Logger.LogInfo ("Controller", "Added SparkleShare to startup items");
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.LogInfo ("Controller", "Failed to add SparkleShare to startup items", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void InstallProtocolHandler ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public override void CopyToClipboard (string text)
|
||||
{
|
||||
Clipboard.Get (Gdk.Atom.Intern ("CLIPBOARD", false)).Text = text;
|
||||
}
|
||||
|
||||
|
||||
public override void OpenFolder (string path)
|
||||
{
|
||||
OpenFile (path);
|
||||
}
|
||||
|
||||
|
||||
public override void OpenFile (string path)
|
||||
{
|
||||
if (InstallationInfo.IsFlatpak)
|
||||
Global.ShowUri (Gdk.Screen.Default, path);
|
||||
else
|
||||
new Command ("xdg-open", string.Format ("\"{0}\"", path)).Start ();
|
||||
}
|
||||
|
||||
|
||||
public override string EventLogHTML {
|
||||
get {
|
||||
string html_path = Path.Combine (InstallationInfo.Directory, "html", "event-log.html");
|
||||
string jquery_file_path = Path.Combine (InstallationInfo.Directory, "html", "jquery.js");
|
||||
|
||||
string html = File.ReadAllText (html_path);
|
||||
string jquery = File.ReadAllText (jquery_file_path);
|
||||
|
||||
return html.Replace ("<!-- $jquery -->", jquery);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override string DayEntryHTML {
|
||||
get {
|
||||
string path = Path.Combine (InstallationInfo.Directory, "html", "day-entry.html");
|
||||
return File.ReadAllText (path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override string EventEntryHTML {
|
||||
get {
|
||||
string path = Path.Combine (InstallationInfo.Directory, "html", "event-entry.html");
|
||||
return File.ReadAllText (path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override string PresetsPath {
|
||||
get {
|
||||
return Path.Combine (InstallationInfo.Directory, "presets");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void PlatformQuit ()
|
||||
{
|
||||
Environment.Exit (0);
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 232 KiB |