Compare commits
996 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4f6290c73 | ||
|
|
b707531fd1 | ||
|
|
cccfffe06e | ||
|
|
bb67263e58 | ||
|
|
1282a28c2f | ||
|
|
20b506f515 | ||
|
|
d24cf9de29 | ||
|
|
48e670d7aa | ||
|
|
a43ff641ba | ||
|
|
68b02e9963 | ||
|
|
e5220012de | ||
|
|
8c92c5446e | ||
|
|
b88dd6cdf2 | ||
|
|
84a333231d | ||
|
|
c1a2e984ba | ||
|
|
53cc575c23 | ||
|
|
7e2cea7425 | ||
|
|
f5d049f026 | ||
|
|
4a01640228 | ||
|
|
54eb6a62ec | ||
|
|
42f7ec4f93 | ||
|
|
c153febb2e | ||
|
|
c18f130bc7 | ||
|
|
829710dc34 | ||
|
|
4a1c7c7a58 | ||
|
|
90f0305f9c | ||
|
|
c726310f3e | ||
|
|
2632522c13 | ||
|
|
d4d91d37ee | ||
|
|
18f4498a58 | ||
|
|
5045cd6333 | ||
|
|
2d3f14f534 | ||
|
|
af4d043e4e | ||
|
|
fa820a998d | ||
|
|
31c7cdda01 | ||
|
|
ddfe67fc45 | ||
|
|
1b9c6d0dd6 | ||
|
|
7bddeffd4e | ||
|
|
b9c13053f1 | ||
|
|
0e4273d242 | ||
|
|
eb8cddb534 | ||
|
|
63506698e9 | ||
|
|
68db337316 | ||
|
|
b7d6c77218 | ||
|
|
b0805abc84 | ||
|
|
89561771a0 | ||
|
|
bd371b4b11 | ||
|
|
91dd98abb0 | ||
|
|
c622ccfc85 | ||
|
|
d07eba683d | ||
|
|
77e172e623 | ||
|
|
e0da6e2ddf | ||
|
|
834d53c069 | ||
|
|
07bcaf21a1 | ||
|
|
5ef2be56c4 | ||
|
|
f06c358718 | ||
|
|
ac590abda9 | ||
|
|
e0b8b44fb3 | ||
|
|
a114608a0d | ||
|
|
63e3ba32db | ||
|
|
5c2c14ca23 | ||
|
|
14f1b30a3b | ||
|
|
10d872f85e | ||
|
|
55c06dfd85 | ||
|
|
7a94494638 | ||
|
|
f618b32321 | ||
|
|
44d94e6a39 | ||
|
|
e82c11521d | ||
|
|
b9c2ee109b | ||
|
|
4bb213c9e4 | ||
|
|
cb20739494 | ||
|
|
214be6d9a5 | ||
|
|
f58978a442 | ||
|
|
7359763b0c | ||
|
|
ec32d4a859 | ||
|
|
609fa2874f | ||
|
|
43bfcb4f59 | ||
|
|
d3509ac5f9 | ||
|
|
612f58e5a6 | ||
|
|
aa8ed7662f | ||
|
|
06df8848bd | ||
|
|
02b365eb96 | ||
|
|
db71d0e234 | ||
|
|
21121b294d | ||
|
|
4bca49113a | ||
|
|
54e6701c51 | ||
|
|
8f73c6af0b | ||
|
|
962ac189ea | ||
|
|
1e1d11b216 | ||
|
|
c3dd18d661 | ||
|
|
e5c66ec77d | ||
|
|
52ab8de1cc | ||
|
|
31351100aa | ||
|
|
6f59e4c9d6 | ||
|
|
79a78ceb7b | ||
|
|
ef3776e235 | ||
|
|
422ce4b3f7 | ||
|
|
00a3ec01f2 | ||
|
|
da37f29d9d | ||
|
|
a69146a36e | ||
|
|
e7b12be958 | ||
|
|
c8994aebb4 | ||
|
|
47fc673d73 | ||
|
|
8a4cdb3287 | ||
|
|
253d3563d5 | ||
|
|
96e6c5bc71 | ||
|
|
8c5a0716e7 | ||
|
|
ff7ffa0c22 | ||
|
|
ced31329ef | ||
|
|
3b2433127d | ||
|
|
29c2ebc086 | ||
|
|
fb14d158ad | ||
|
|
0e4b2a6e50 | ||
|
|
3c6482e204 | ||
|
|
72945cb094 | ||
|
|
b8271dd49c | ||
|
|
4cf8e19923 | ||
|
|
436ec5e638 | ||
|
|
d311c0584d | ||
|
|
f98c31aba2 | ||
|
|
3ca36f6edf | ||
|
|
7cdb627b1b | ||
|
|
8d8421ae35 | ||
|
|
08c38106ab | ||
|
|
2a19a91714 | ||
|
|
d9b29c89d9 | ||
|
|
c04eb6fd31 | ||
|
|
d1f58c2835 | ||
|
|
29c360a501 | ||
|
|
700e2b5e0f | ||
|
|
ce1790d5e8 | ||
|
|
1f9ae88946 | ||
|
|
5abbdbab6c | ||
|
|
80208e4c5e | ||
|
|
c65f9eaace | ||
|
|
9ebd744d2c | ||
|
|
74fe0cce59 | ||
|
|
8aec577706 | ||
|
|
4c7cd17051 | ||
|
|
af2ce1bdc9 | ||
|
|
de85a30065 | ||
|
|
ae5ead3c75 | ||
|
|
e20d2f4076 | ||
|
|
30a6ee9528 | ||
|
|
6332e96b4e | ||
|
|
4cf63fbd33 | ||
|
|
d32ec1004f | ||
|
|
74940a3e31 | ||
|
|
3de413cf71 | ||
|
|
37443c9fdc | ||
|
|
65666d619d | ||
|
|
3d85acaf68 | ||
|
|
b4287801a2 | ||
|
|
a51553fa1f | ||
|
|
e76f1a003d | ||
|
|
b31d88507e | ||
|
|
d8ae4a3ad4 | ||
|
|
cb0f79cd2f | ||
|
|
1b64cfbad6 | ||
|
|
0d7d299b7d | ||
|
|
9051b5d836 | ||
|
|
3d95d83d9a | ||
|
|
f7e8497879 | ||
|
|
d61dea4b92 | ||
|
|
9cf4a7a9fa | ||
|
|
488be6185e | ||
|
|
0649c0c58f | ||
|
|
24f30ca5e5 | ||
|
|
eeb639d2b7 | ||
|
|
abb8294bb0 | ||
|
|
237e562a4f | ||
|
|
e89185c654 | ||
|
|
a34272256a | ||
|
|
e853df7781 | ||
|
|
3517cfb869 | ||
|
|
4886c3ef4c | ||
|
|
51f8ea0ca4 | ||
|
|
7daa941ffe | ||
|
|
5ed097ee0b | ||
|
|
4e069c1e75 | ||
|
|
17ba10e2f2 | ||
|
|
dacf6a38ab | ||
|
|
a4aa8bcc6d | ||
|
|
5c8700257b | ||
|
|
862b45a512 | ||
|
|
db20dd0ec7 | ||
|
|
8932314853 | ||
|
|
8e0e5bba19 | ||
|
|
3da2c1c79a | ||
|
|
39e8874b87 | ||
|
|
d320702470 | ||
|
|
110bba7c32 | ||
|
|
c653207daf | ||
|
|
f1b4d779cb | ||
|
|
0ead8d41e1 | ||
|
|
088e42a88a | ||
|
|
12d2f42e41 | ||
|
|
9c65f61db4 | ||
|
|
225062cefe | ||
|
|
a6196c182d | ||
|
|
1342182d7c | ||
|
|
163af20d29 | ||
|
|
d376bc0553 | ||
|
|
802d04e1eb | ||
|
|
99b03ae5be | ||
|
|
9a3c13da77 | ||
|
|
d012c4fe7a | ||
|
|
75d20b1234 | ||
|
|
96fb8a21e6 | ||
|
|
39787af90b | ||
|
|
07a8ed0dc2 | ||
|
|
ee3941f16c | ||
|
|
ffe89f8265 | ||
|
|
2a0562188a | ||
|
|
7978c9e6fa | ||
|
|
4237192802 | ||
|
|
3caa6796b6 | ||
|
|
fcf9b6b909 | ||
|
|
572d8dc55f | ||
|
|
6f473816a1 | ||
|
|
6701c17332 | ||
|
|
89cee43d38 | ||
|
|
c17dde8f8f | ||
|
|
6e1aa44f2d | ||
|
|
660d26bbce | ||
|
|
7e7cb1c085 | ||
|
|
2aef7fbfba | ||
|
|
76347bf4cc | ||
|
|
280a0003ed | ||
|
|
74a1e1cbee | ||
|
|
2099c75fa8 | ||
|
|
cbb19271bf | ||
|
|
6fc2f952ce | ||
|
|
62c22d3539 | ||
|
|
83ea7b8f54 | ||
|
|
52fbe86e0f | ||
|
|
d000f81356 | ||
|
|
e815c14070 | ||
|
|
8b4b7221b5 | ||
|
|
6c025d84ad | ||
|
|
ed08f41065 | ||
|
|
71e8d74160 | ||
|
|
6261ff9da5 | ||
|
|
f507923cb1 | ||
|
|
8017904261 | ||
|
|
9a4d467d9f | ||
|
|
640781f381 | ||
|
|
b255de4627 | ||
|
|
bb9ece650f | ||
|
|
ea860e20a6 | ||
|
|
87686c1d36 | ||
|
|
e7ee8d2317 | ||
|
|
b21c6bce9f | ||
|
|
415689d725 | ||
|
|
1b66508df7 | ||
|
|
12c431f87c | ||
|
|
00a506cfdf | ||
|
|
e13ca40a75 | ||
|
|
679e0bbd00 | ||
|
|
58a73b3b53 | ||
|
|
3a2ea23822 | ||
|
|
fd4afdfc84 | ||
|
|
ec757e3418 | ||
|
|
efd9d82131 | ||
|
|
affd349ee9 | ||
|
|
2ae1c1dfaa | ||
|
|
bc6f066804 | ||
|
|
1f5f814f42 | ||
|
|
fc9b33b698 | ||
|
|
1ed4221d9f | ||
|
|
fe7f29b76f | ||
|
|
a165a4817c | ||
|
|
e35a7fe108 | ||
|
|
f91b7742c3 | ||
|
|
5065ca8c3b | ||
|
|
3a2b8bd1f4 | ||
|
|
837c7af7ee | ||
|
|
6c9103835f | ||
|
|
d16a27c891 | ||
|
|
834e21aaf0 | ||
|
|
7260433a91 | ||
|
|
c4bfff69f4 | ||
|
|
e71515ee3e | ||
|
|
2372824122 | ||
|
|
521baaa652 | ||
|
|
8df037d1ad | ||
|
|
afdbe7ba7a | ||
|
|
852308c78d | ||
|
|
020f3b6259 | ||
|
|
4fdcb32044 | ||
|
|
d55e7ed404 | ||
|
|
4e38266101 | ||
|
|
330e3f92b4 | ||
|
|
72ea0daeec | ||
|
|
b938b28076 | ||
|
|
5bb818332a | ||
|
|
85a7db1b56 | ||
|
|
972abc6277 | ||
|
|
5fdf22afc3 | ||
|
|
80669d7e2f | ||
|
|
74157b4901 | ||
|
|
a42f631bf4 | ||
|
|
47648cd57f | ||
|
|
eec5b9c9b2 | ||
|
|
61544c2099 | ||
|
|
afa3523cb2 | ||
|
|
8c6af93fd1 | ||
|
|
3dd5747b3c | ||
|
|
2901234d9c | ||
|
|
595e67a928 | ||
|
|
fa817d9f80 | ||
|
|
72b20f8c94 | ||
|
|
6dc0bd5cc5 | ||
|
|
da9eb7d0ba | ||
|
|
18f973ce00 | ||
|
|
469542416d | ||
|
|
fb6b96fa5b | ||
|
|
98f0b57eb6 | ||
|
|
4f8956829f | ||
|
|
9c6991e9d7 | ||
|
|
59b2c3895c | ||
|
|
ccef57f311 | ||
|
|
c25a752b20 | ||
|
|
9ecf10ea43 | ||
|
|
1238107b13 | ||
|
|
55fc7493c9 | ||
|
|
5959f7cbcc | ||
|
|
25ab5933a2 | ||
|
|
2e019c136f | ||
|
|
1d91f2800d | ||
|
|
66b879ebb7 | ||
|
|
e47824b1ff | ||
|
|
0e791c7bf7 | ||
|
|
4a02d27e35 | ||
|
|
224d09be9f | ||
|
|
f236db3392 | ||
|
|
ee88d7d6bf | ||
|
|
273310f915 | ||
|
|
405b956b06 | ||
|
|
ef88fcbfd3 | ||
|
|
c98913000c | ||
|
|
85d765e5e7 | ||
|
|
1406229b11 | ||
|
|
9c3a8627b5 | ||
|
|
a548fcafa8 | ||
|
|
b029054946 | ||
|
|
bcab7a9b15 | ||
|
|
5cf7e86d33 | ||
|
|
c0cd53c733 | ||
|
|
45743ca6ac | ||
|
|
54048922fa | ||
|
|
2b1fd00ca0 | ||
|
|
ccc5a12320 | ||
|
|
c828effd23 | ||
|
|
d7e6629567 | ||
|
|
b6a06c62d1 | ||
|
|
cea91bd082 | ||
|
|
a9e5270acd | ||
|
|
3f5b856310 | ||
|
|
7595971f96 | ||
|
|
1ecc2774d7 | ||
|
|
7e47914abe | ||
|
|
ef204e0a54 | ||
|
|
8e1015f64e | ||
|
|
ec9d7ab22f | ||
|
|
8cc9a916c4 | ||
|
|
0d1c1bfec2 | ||
|
|
90debd91ba | ||
|
|
bccecbbc88 | ||
|
|
850afc6688 | ||
|
|
3bffcba4de | ||
|
|
0fc319c2af | ||
|
|
3434f6963e | ||
|
|
482d47a48c | ||
|
|
0ce4714f8e | ||
|
|
1d27febf6a | ||
|
|
290301115b | ||
|
|
81ef67787a | ||
|
|
815bebf6f2 | ||
|
|
1f29d4c0ec | ||
|
|
4eaf8c87c5 | ||
|
|
234b377ceb | ||
|
|
23ba569e48 | ||
|
|
6e364009e3 | ||
|
|
b1f79c1903 | ||
|
|
0cb23e600c | ||
|
|
04b22af49d | ||
|
|
1e0589b3ed | ||
|
|
214224101c | ||
|
|
d574adbc3f | ||
|
|
1c77d030d9 | ||
|
|
0410246918 | ||
|
|
a86e662c1e | ||
|
|
c68fb8883c | ||
|
|
7dd0779f69 | ||
|
|
98ad1cdba8 | ||
|
|
386c88a8f4 | ||
|
|
5accc55e93 | ||
|
|
756e50d3ac | ||
|
|
d8c4b452c5 | ||
|
|
1430968566 | ||
|
|
13fcc3c20a | ||
|
|
8b7c20b40c | ||
|
|
f7b58c9e6d | ||
|
|
2adb329ece | ||
|
|
a5cdb9dc00 | ||
|
|
c971b1b00c | ||
|
|
85bbd15bd0 | ||
|
|
dc597c9299 | ||
|
|
b85b8a978a | ||
|
|
b27ad9d395 | ||
|
|
671de1a799 | ||
|
|
2565997fb6 | ||
|
|
8baba02f98 | ||
|
|
fbbfdd54e8 | ||
|
|
a09bc7156a | ||
|
|
5922619605 | ||
|
|
2bd9e119f8 | ||
|
|
a52faadbef | ||
|
|
5751184c46 | ||
|
|
d7418e80c2 | ||
|
|
d9578d3c32 | ||
|
|
66b09ee99a | ||
|
|
8b213d6103 | ||
|
|
2f584fd2d7 | ||
|
|
9cf8357c4f | ||
|
|
3f53de0832 | ||
|
|
59e6f33e9f | ||
|
|
24edace814 | ||
|
|
5da1125ecd | ||
|
|
8566c2ccbd | ||
|
|
d3acb298e8 | ||
|
|
3827bb4210 | ||
|
|
e71519d358 | ||
|
|
4c2a881407 | ||
|
|
a67179105c | ||
|
|
e092cec215 | ||
|
|
4f8e9019af | ||
|
|
4d68f77368 | ||
|
|
a05ae6cafe | ||
|
|
1283219c51 | ||
|
|
de30d0d09f | ||
|
|
ab5df9f725 | ||
|
|
613fe1639c | ||
|
|
4de6468393 | ||
|
|
c4f4c9a81a | ||
|
|
5a22dce8d4 | ||
|
|
bea4f3044c | ||
|
|
f8018aab68 | ||
|
|
a9d9adc25f | ||
|
|
e04cb7cb6a | ||
|
|
8539ff8430 | ||
|
|
8b60d2c61d | ||
|
|
5590e64e0a | ||
|
|
8379f8ac6a | ||
|
|
fcd6d41586 | ||
|
|
c72b04a413 | ||
|
|
342bf0caed | ||
|
|
850b18ab35 | ||
|
|
f2437b4722 | ||
|
|
595d84fb7c | ||
|
|
26246e3ef7 | ||
|
|
70196d69ad | ||
|
|
5f6ba57b33 | ||
|
|
749d465556 | ||
|
|
f143a94426 | ||
|
|
916ad43f4e | ||
|
|
4850d03825 | ||
|
|
8c72eb65ff | ||
|
|
be2ffe7580 | ||
|
|
a0a54716b8 | ||
|
|
386c85c01b | ||
|
|
908a7bfcc0 | ||
|
|
a2e0e483b5 | ||
|
|
f84e6d4598 | ||
|
|
5e5247aee1 | ||
|
|
2e27485e3b | ||
|
|
67cb2f1c8f | ||
|
|
f2ff6eaa4a | ||
|
|
2367709b2e | ||
|
|
3fc266a061 | ||
|
|
a008f6b57c | ||
|
|
27ef8da039 | ||
|
|
e45665502f | ||
|
|
c6297469d7 | ||
|
|
b419b400ba | ||
|
|
e7a7a87e48 | ||
|
|
61cb198893 | ||
|
|
dc02747f87 | ||
|
|
676c3d6b79 | ||
|
|
e32ed43c29 | ||
|
|
b4fabf70c2 | ||
|
|
e0af232f76 | ||
|
|
bdd9997bb5 | ||
|
|
950503d231 | ||
|
|
20a6275ae8 | ||
|
|
ef187ed37e | ||
|
|
11f6818663 | ||
|
|
41ef3b1d22 | ||
|
|
1ddec5f97b | ||
|
|
9ddd4a63bb | ||
|
|
3f1d9e3be0 | ||
|
|
fa7c5ee40d | ||
|
|
10ee12bfcd | ||
|
|
a43e5861d7 | ||
|
|
1724dcc8ff | ||
|
|
aca11bdb40 | ||
|
|
862ee9a2d0 | ||
|
|
a1f29738ab | ||
|
|
b03919ed86 | ||
|
|
d5c6c67f11 | ||
|
|
07d33798a0 | ||
|
|
27a748c6a6 | ||
|
|
9c839854fa | ||
|
|
fb2ea36c4b | ||
|
|
6ae4d63c30 | ||
|
|
ae3ef67825 | ||
|
|
751412e639 | ||
|
|
c73921af4f | ||
|
|
ab9106f902 | ||
|
|
aad6940ca7 | ||
|
|
470e4264b2 | ||
|
|
72e76638ff | ||
|
|
af1388a067 | ||
|
|
769c999c98 | ||
|
|
e0e53aa517 | ||
|
|
3a59e60373 | ||
|
|
78b4b9c938 | ||
|
|
ea166af67b | ||
|
|
5baddc9946 | ||
|
|
7357694211 | ||
|
|
8205a7c33f | ||
|
|
f532372535 | ||
|
|
1dd2d0c1e4 | ||
|
|
5e5d46ee4e | ||
|
|
91782898fc | ||
|
|
58d41eda8b | ||
|
|
c017102cc9 | ||
|
|
2f757f9bfd | ||
|
|
e9c759df15 | ||
|
|
111eab727e | ||
|
|
1f39d5e938 | ||
|
|
9bf908bdfb | ||
|
|
cba5100d17 | ||
|
|
d9b3a029c3 | ||
|
|
a2a34a4e2f | ||
|
|
6f96c9e3ff | ||
|
|
9aca12e0a5 | ||
|
|
ead55fe0e3 | ||
|
|
f2820471bc | ||
|
|
fb7885ada2 | ||
|
|
f9f4dc5a92 | ||
|
|
ffe4f562cc | ||
|
|
a906428734 | ||
|
|
abc7e6fec1 | ||
|
|
3b01cf3782 | ||
|
|
53d616fb16 | ||
|
|
8168c1f201 | ||
|
|
a0e1e032d6 | ||
|
|
77eca7578f | ||
|
|
d13badca50 | ||
|
|
acf4f84cae | ||
|
|
c24d135815 | ||
|
|
0d64476b04 | ||
|
|
091e110afd | ||
|
|
de8ba52643 | ||
|
|
8a2bb6eb32 | ||
|
|
ed649fd1b1 | ||
|
|
4cd4b99ae0 | ||
|
|
c903afa09d | ||
|
|
8aeb11f771 | ||
|
|
ed51b826a0 | ||
|
|
bb84eeb35e | ||
|
|
8a9fd2a97c | ||
|
|
3b49f9a67f | ||
|
|
2a4faedf67 | ||
|
|
82f7f82f54 | ||
|
|
276922104c | ||
|
|
3bd4a6673f | ||
|
|
1909feceba | ||
|
|
e585341933 | ||
|
|
e87054f0d3 | ||
|
|
6b0bd77d49 | ||
|
|
77f4cbcdd3 | ||
|
|
928c5938e9 | ||
|
|
03500d70af | ||
|
|
2c30a5361f | ||
|
|
c59d31fc21 | ||
|
|
5115ba6d8a | ||
|
|
4daab3d286 | ||
|
|
34512e5e49 | ||
|
|
0fddd90e1f | ||
|
|
29b6a58769 | ||
|
|
549b2e3815 | ||
|
|
88ef7d7eca | ||
|
|
d70c3f92ad | ||
|
|
4a25fed9d5 | ||
|
|
6fb4d43500 | ||
|
|
76dca88b62 | ||
|
|
bc7fb94d63 | ||
|
|
2bedc6cd31 | ||
|
|
c0f748756b | ||
|
|
181a8aeb1b | ||
|
|
c45f7b8148 | ||
|
|
1d21665c16 | ||
|
|
b87d3c612b | ||
|
|
d6757d67f8 | ||
|
|
376e44ec6c | ||
|
|
94402d96ad | ||
|
|
d3a1bf7eb6 | ||
|
|
beb9370fc5 | ||
|
|
58ede7e85e | ||
|
|
8dc4e6e0b9 | ||
|
|
360ce5c77b | ||
|
|
4b6d630f5c | ||
|
|
47d4b3d8a8 | ||
|
|
162d9d05cc | ||
|
|
4f114184bf | ||
|
|
432e60f9cc | ||
|
|
b2bc692cc2 | ||
|
|
810e44563c | ||
|
|
704aaf163c | ||
|
|
55988650a6 | ||
|
|
eb499512ee | ||
|
|
794310550c | ||
|
|
280db083b4 | ||
|
|
d5353a5bef | ||
|
|
fc428d45b9 | ||
|
|
19181facdb | ||
|
|
8813fce63f | ||
|
|
ac8090ae8b | ||
|
|
53e644a5f7 | ||
|
|
a325156e71 | ||
|
|
05e1875eec | ||
|
|
98d1ad8494 | ||
|
|
ef6b8727b9 | ||
|
|
d7ced0f9c4 | ||
|
|
d76ef207fe | ||
|
|
fdf6eadfcd | ||
|
|
4e4f02404f | ||
|
|
42c942514f | ||
|
|
a6b0ac43e9 | ||
|
|
0893eb85bc | ||
|
|
e817e3c7a5 | ||
|
|
32f98fa70e | ||
|
|
66bdffc747 | ||
|
|
5d353125d2 | ||
|
|
7f2d4344e3 | ||
|
|
4736871524 | ||
|
|
bcd88d6d4d | ||
|
|
8ffe74b772 | ||
|
|
57ae4c304f | ||
|
|
8be77ab7d9 | ||
|
|
8c193b913f | ||
|
|
4fac517a1e | ||
|
|
4f7061351f | ||
|
|
decc5ecae6 | ||
|
|
f06fae6885 | ||
|
|
8d46f51c66 | ||
|
|
601ef0848d | ||
|
|
3b0dd46ca6 | ||
|
|
16b2e1903a | ||
|
|
36d7a95d34 | ||
|
|
1d82e195ec | ||
|
|
78cae0c69a | ||
|
|
2b46ee27f2 | ||
|
|
de44400749 | ||
|
|
55e40bd6c3 | ||
|
|
124950d7e4 | ||
|
|
199104ca83 | ||
|
|
e5552e0a4b | ||
|
|
bfb0aa7961 | ||
|
|
44d83bdcf8 | ||
|
|
d960e57cf9 | ||
|
|
30ec03ef4d | ||
|
|
c2c27b1577 | ||
|
|
c0449ccf59 | ||
|
|
ea933ce3d1 | ||
|
|
327666385b | ||
|
|
8ea511b293 | ||
|
|
c510fe5cf0 | ||
|
|
dab70937f5 | ||
|
|
fec4859cfe | ||
|
|
63ecc3b713 | ||
|
|
d3a08c60d7 | ||
|
|
322eb1e255 | ||
|
|
22d4f3c3e7 | ||
|
|
008750b1d9 | ||
|
|
506767f32f | ||
|
|
aaa673de92 | ||
|
|
43237d8ff4 | ||
|
|
9681fc9a87 | ||
|
|
76c3e96f76 | ||
|
|
1e66afa6a4 | ||
|
|
41c59e8e49 | ||
|
|
225e3d7936 | ||
|
|
204dd97b00 | ||
|
|
27bfecc737 | ||
|
|
8cdb131a19 | ||
|
|
c9042588f0 | ||
|
|
342eaec49a | ||
|
|
77b3d28e3b | ||
|
|
357b38b5e7 | ||
|
|
a99a1c7540 | ||
|
|
6742ba332a | ||
|
|
c5916fea7c | ||
|
|
7a4958f8e9 | ||
|
|
b71a96faee | ||
|
|
24e79f0169 | ||
|
|
76e887407a | ||
|
|
0d0c8e54f4 | ||
|
|
06a01f7e32 | ||
|
|
f564d20c5b | ||
|
|
85afded6b4 | ||
|
|
7e84853c37 | ||
|
|
c3c324158f | ||
|
|
1e2fd40c05 | ||
|
|
6a7f78a218 | ||
|
|
0b637e56d7 | ||
|
|
63f44a5a3f | ||
|
|
83ce14e31b | ||
|
|
8162357ce6 | ||
|
|
ba0e9cf9c5 | ||
|
|
8d1072d97d | ||
|
|
ffd4fdf2dc | ||
|
|
d279f04a1f | ||
|
|
77e8c858a0 | ||
|
|
f6edf15011 | ||
|
|
b50c34b19c | ||
|
|
874f206e2a | ||
|
|
fd262fdb6a | ||
|
|
2cb17985d4 | ||
|
|
2daa6f108a | ||
|
|
2e0d92c0d5 | ||
|
|
1a0d61af7c | ||
|
|
eb9fc6140b | ||
|
|
b0d72030fa | ||
|
|
db27d422ae | ||
|
|
d6ec597fe2 | ||
|
|
0fe319f430 | ||
|
|
2616b49e82 | ||
|
|
c2fd26db56 | ||
|
|
71bd59fe3d | ||
|
|
5b84fe63dd | ||
|
|
40782063c4 | ||
|
|
580eb2400c | ||
|
|
4666e443cb | ||
|
|
d52c1701e4 | ||
|
|
4a543c75f7 | ||
|
|
0b15f4ffd5 | ||
|
|
0f6e24d07f | ||
|
|
7110ef1420 | ||
|
|
a56cef65d5 | ||
|
|
f58be1ff6f | ||
|
|
b1a788864c | ||
|
|
fe468d911b | ||
|
|
ef8e1c0478 | ||
|
|
710c4fb33e | ||
|
|
3ef8656bcd | ||
|
|
251e15f503 | ||
|
|
eb2f9d9c2b | ||
|
|
dfcd3ea693 | ||
|
|
7260128dfd | ||
|
|
d4e783c96f | ||
|
|
c57a342053 | ||
|
|
9ed9af2d04 | ||
|
|
295b9c98d1 | ||
|
|
8f4de0e08f | ||
|
|
8f53301b79 | ||
|
|
6372ef8c22 | ||
|
|
a91f9e5a6b | ||
|
|
6b74f75616 | ||
|
|
9cd9babb83 | ||
|
|
380c14da56 | ||
|
|
32c1c18af2 | ||
|
|
b7077339a1 | ||
|
|
52fd505ffc | ||
|
|
b911b7a3dd | ||
|
|
9b38d5135e | ||
|
|
0346c48546 | ||
|
|
212c6ca5ac | ||
|
|
361c89d016 | ||
|
|
b0cbc67799 | ||
|
|
18cfb08054 | ||
|
|
66121e6d5d | ||
|
|
a4841de17e | ||
|
|
84aef97e37 | ||
|
|
f14e1976e7 | ||
|
|
8c9acc98fb | ||
|
|
bd36428bd4 | ||
|
|
7f7276e34a | ||
|
|
460761ef68 | ||
|
|
9fefc6428e | ||
|
|
ffe4423c10 | ||
|
|
3f02919cd9 | ||
|
|
3075badf33 | ||
|
|
29d66ee264 | ||
|
|
846ec3a430 | ||
|
|
a65a50ffd3 | ||
|
|
c945bb9d03 | ||
|
|
3dc9575c9e | ||
|
|
f901167009 | ||
|
|
8519a6c6a4 | ||
|
|
d8fc2c088f | ||
|
|
679cd37ec6 | ||
|
|
40be77f9c3 | ||
|
|
1a0d762c4e | ||
|
|
a7e0032225 | ||
|
|
0b9df02faa | ||
|
|
0dcf7d1520 | ||
|
|
b146057ca7 | ||
|
|
2628d912cd | ||
|
|
2e75d531a6 | ||
|
|
be7607bc17 | ||
|
|
5bd724141e | ||
|
|
7b5538c104 | ||
|
|
462e7d6ffe | ||
|
|
68a32e036e | ||
|
|
dba5b63230 | ||
|
|
26efccb110 | ||
|
|
e0516663aa | ||
|
|
d737d91bc2 | ||
|
|
1b10d59188 | ||
|
|
a9ca13c55d | ||
|
|
57fbe9cc09 | ||
|
|
061b225690 | ||
|
|
27189d559a | ||
|
|
d9e0c94797 | ||
|
|
e2e719a12e | ||
|
|
52ec97f11f | ||
|
|
d094386c4d | ||
|
|
515777bd96 | ||
|
|
d56d0dfaaf | ||
|
|
60b22d0df8 | ||
|
|
0072bf8330 | ||
|
|
f36b4546a9 | ||
|
|
c0a97fd263 | ||
|
|
46932e4adf | ||
|
|
0c2675ec28 | ||
|
|
f4e5d7978a | ||
|
|
cc7ba566c5 | ||
|
|
d47e3f6bbf | ||
|
|
2335c74b55 | ||
|
|
ca4bab7bf8 | ||
|
|
d4d84ea422 | ||
|
|
f985e07be4 | ||
|
|
bab62cf374 | ||
|
|
4eb988c34d | ||
|
|
3006d7e32e | ||
|
|
3e9b7426bf | ||
|
|
e8f93782e0 | ||
|
|
839a8b4102 | ||
|
|
89a1b81ea2 | ||
|
|
6306af3c4a | ||
|
|
910b24c460 | ||
|
|
5dc580c76b | ||
|
|
c0705222f5 | ||
|
|
b51e8add55 | ||
|
|
873785bb53 | ||
|
|
86211df4b3 | ||
|
|
5ef5c6b641 | ||
|
|
5b96253146 | ||
|
|
54111504ac | ||
|
|
bc2a2895e0 | ||
|
|
80833486cd | ||
|
|
e92c59bf25 | ||
|
|
d511b2f65c | ||
|
|
921785c29d | ||
|
|
1db42fd268 | ||
|
|
6313cc8135 | ||
|
|
7abf7de71b | ||
|
|
c5628cecc0 | ||
|
|
5212d3bfe5 | ||
|
|
bed317a05b | ||
|
|
7644e29f71 | ||
|
|
3245d5fcf5 | ||
|
|
9dbce4d08b | ||
|
|
84a046ce82 | ||
|
|
d5c5a8723a | ||
|
|
67051b21a0 | ||
|
|
f646f003c1 | ||
|
|
ad1a3925ff | ||
|
|
5ae686ac5f | ||
|
|
6a1429c2eb | ||
|
|
4645c0bc13 | ||
|
|
51e5fa3b03 | ||
|
|
c3ff38a310 | ||
|
|
a547aacfa9 | ||
|
|
06fc6ceeb6 | ||
|
|
e8c3153ff5 | ||
|
|
84ac98cfe1 | ||
|
|
9579342e95 | ||
|
|
04ed4996e7 | ||
|
|
f22b4cd39a | ||
|
|
4d2ea5478d | ||
|
|
8ca722165a | ||
|
|
88a14a753e | ||
|
|
01bc387134 | ||
|
|
c692f4d393 | ||
|
|
fe9df2c34f | ||
|
|
a1968467de | ||
|
|
875698c926 | ||
|
|
f035d37243 | ||
|
|
3f7dec4d79 | ||
|
|
3d59c78ad8 | ||
|
|
d6b664e2f6 | ||
|
|
a387783287 | ||
|
|
a2d610133a | ||
|
|
62fb15e58f | ||
|
|
05c22bb839 | ||
|
|
08eae11f25 | ||
|
|
fb90bc8c1f | ||
|
|
0c275dce98 | ||
|
|
97b8eb435a | ||
|
|
7ebc57b659 | ||
|
|
2036e7e3ec | ||
|
|
bf054ef9f5 | ||
|
|
26e67edafe | ||
|
|
5ab31f5133 | ||
|
|
2ec6930099 | ||
|
|
4aa8f3f5dc | ||
|
|
2506c8420f | ||
|
|
90a04c04d2 | ||
|
|
48c800fd5a | ||
|
|
dafce44c0a | ||
|
|
a70885ad18 | ||
|
|
b5110d9df3 | ||
|
|
1391ffa2a5 | ||
|
|
ce8b52f684 | ||
|
|
0256deef66 | ||
|
|
f05a47d636 | ||
|
|
db4d84e1c0 | ||
|
|
adfde391ab | ||
|
|
512b4c2e09 | ||
|
|
e56143c508 | ||
|
|
f9aa441ce8 | ||
|
|
37e0185d25 | ||
|
|
29070efc06 | ||
|
|
3ddd37b843 | ||
|
|
409b603530 | ||
|
|
0458de2fb0 | ||
|
|
7c74ce3212 | ||
|
|
624162a3ec | ||
|
|
612b222887 | ||
|
|
d4efa58388 | ||
|
|
04ba342542 | ||
|
|
3105ce109c | ||
|
|
757b829a17 | ||
|
|
ea16ef847e | ||
|
|
294ccfe3f9 | ||
|
|
6ef5298b8b | ||
|
|
d31b41ed9e | ||
|
|
2100ca222c | ||
|
|
2dcb929089 | ||
|
|
7a95cbdf62 | ||
|
|
1ab251af6a | ||
|
|
d1c5e847da | ||
|
|
dc501bb2e6 | ||
|
|
e3e722a972 | ||
|
|
f7b47afae7 | ||
|
|
74d1eeca24 | ||
|
|
fa8f5ba41e | ||
|
|
1ee279bc5a | ||
|
|
d724f93e36 | ||
|
|
96783c1ee2 | ||
|
|
db5c6d0865 | ||
|
|
5f6df5569e | ||
|
|
661a121d6f | ||
|
|
25856e4675 | ||
|
|
cedf3f8364 | ||
|
|
0a66d3f3e3 | ||
|
|
10251c3c43 | ||
|
|
3cd9973fc1 | ||
|
|
2c68dd1a31 | ||
|
|
34cfb3548a | ||
|
|
fc3e98bdc6 | ||
|
|
bb6226f420 | ||
|
|
79c4d0d128 | ||
|
|
571c12061e | ||
|
|
786dd72b82 | ||
|
|
e53d318e22 | ||
|
|
2d0e06f22c | ||
|
|
f544c32d6d | ||
|
|
c56b1040d4 | ||
|
|
51e4cbef32 | ||
|
|
8a60e4e467 | ||
|
|
bb792206cc | ||
|
|
6448e6b928 | ||
|
|
7b7d53c97a | ||
|
|
431b97a011 | ||
|
|
5ccf4fac48 | ||
|
|
ba21ed7cf9 | ||
|
|
1db6453fd2 | ||
|
|
713b2fef0d | ||
|
|
05aa5cc8c1 | ||
|
|
9e5eec4e3b |
13
.editorconfig
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
charset = utf-8
|
||||||
|
|
||||||
|
[*.{py,swift,launch}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
[*.{js,html}]
|
||||||
|
indent_style = tab
|
||||||
3
.gitattributes
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
apps/ios/cleverrc/roslib.js linguist-vendored
|
||||||
|
apps/ios/cleverrc/BinUtils.swift linguist-vendored
|
||||||
|
apps/android/app/src/main/assets/roslib.js linguist-vendored
|
||||||
6
.gitignore
vendored
@@ -1,2 +1,6 @@
|
|||||||
/deploy/ros_lib/
|
|
||||||
*.pyc
|
*.pyc
|
||||||
|
*.DS_Store
|
||||||
|
/images
|
||||||
|
node_modules/
|
||||||
|
_book/
|
||||||
|
package-lock.json
|
||||||
|
|||||||
4
.gitmodules
vendored
@@ -1,4 +0,0 @@
|
|||||||
[submodule "clever/static"]
|
|
||||||
path = clever/static
|
|
||||||
url = https://github.com/CopterExpress/clever-rc.git
|
|
||||||
branch = build
|
|
||||||
31
.markdownlint.json
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"MD003": false,
|
||||||
|
"MD010": {
|
||||||
|
"code_blocks": false
|
||||||
|
},
|
||||||
|
"MD013": false,
|
||||||
|
"MD024": false,
|
||||||
|
"MD026" :{
|
||||||
|
"punctuation": ".,;:!"
|
||||||
|
},
|
||||||
|
"MD033": false,
|
||||||
|
"MD034": false,
|
||||||
|
"MD040": false,
|
||||||
|
"MD044": {
|
||||||
|
"names": [
|
||||||
|
"MAVLink",
|
||||||
|
"ROS",
|
||||||
|
"Python",
|
||||||
|
"C++",
|
||||||
|
"PX4",
|
||||||
|
"WireShark",
|
||||||
|
"Wi-Fi",
|
||||||
|
"Raspberry Pi",
|
||||||
|
"Pixhawk",
|
||||||
|
"Pixracer",
|
||||||
|
"ArUco"
|
||||||
|
],
|
||||||
|
"code_blocks": false
|
||||||
|
},
|
||||||
|
"MD045": false
|
||||||
|
}
|
||||||
36
.travis.yml
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
sudo: required
|
||||||
|
language: generic
|
||||||
|
services:
|
||||||
|
- docker
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- DOCKER="sfalexrog/img-tool:builder-mod"
|
||||||
|
- TARGET_REPO="https://github.com/${TRAVIS_REPO_SLUG}.git"
|
||||||
|
- if [[ -z ${TRAVIS_TAG} ]]; then IMAGE_VERSION="${TRAVIS_COMMIT}}"; else IMAGE_VERSION="${TRAVIS_TAG}"; fi
|
||||||
|
- IMAGE_NAME="$(basename -s '.git' ${TARGET_REPO})_${IMAGE_VERSION}.img"
|
||||||
|
git:
|
||||||
|
depth: 1
|
||||||
|
before_script:
|
||||||
|
- docker pull ${DOCKER}
|
||||||
|
script:
|
||||||
|
- docker run --privileged --rm -v /dev:/dev -v $(pwd):/builder/repo -e TRAVIS_TAG="${TRAVIS_TAG}" ${DOCKER}
|
||||||
|
before_deploy:
|
||||||
|
# Set up git user name and tag this commit
|
||||||
|
- git config --local user.name "goldarte"
|
||||||
|
- git config --local user.email "goldartt@gmail.com"
|
||||||
|
- sudo chmod -R 777 *
|
||||||
|
- cd images && zip ${IMAGE_NAME}.zip ${IMAGE_NAME}
|
||||||
|
deploy:
|
||||||
|
provider: releases
|
||||||
|
api_key: ${GITHUB_OAUTH_TOKEN}
|
||||||
|
file: ${IMAGE_NAME}.zip
|
||||||
|
skip_cleanup: true
|
||||||
|
on:
|
||||||
|
tags: true
|
||||||
|
draft: true
|
||||||
|
|
||||||
|
# More info there
|
||||||
|
# https://github.com/travis-ci/travis-ci/issues/6893
|
||||||
|
# https://docs.travis-ci.com/user/customizing-the-build/
|
||||||
|
# https://docs.travis-ci.com/user/deployment/releases
|
||||||
|
# https://docs.travis-ci.com/user/environment-variables/
|
||||||
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Copter Express Technologies
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
56
README.md
@@ -1,62 +1,70 @@
|
|||||||
Клевер
|
# CLEVER
|
||||||
======
|
|
||||||
|
|
||||||
<img src="assets/clever.jpg" align="right" width="300px" alt="Клевер">
|
<img src="docs/assets/clever3.png" align="right" width="300px" alt="CLEVER drone">
|
||||||
|
|
||||||
«Клевер» — это учебный конструктор программируемого квадрокоптера, состоящего из популярных открытых компонентов, а также набор необходимой документации и библиотек для работы с ним.
|
CLEVER (Russian: *"Клевер"*, meaning *"Clover"*) is an educational programmable drone kit consisting of an unassembled quadcopter, open source software and documentation. The kit includes Pixhawk/Pixracer autopilot running PX4 firmware, Raspberry Pi 3 as companion computer, a camera for computer vision navigation as well as additional sensors and peripheral devices.
|
||||||
|
|
||||||
Набор включает в себя полетный контроллер PixHawk/PixRacer с полетным стеком PX4, Raspberry Pi 3 в качестве управлящего бортового компьютера, модуль камеры для реализации полетов с использованием компьютерного зрения, а также набор различных датчиков и другой периферии.
|
Copter Express has implemented a large number of different autonomous drone projects using exactly the same platform: [automated pizza delivery](https://www.youtube.com/watch?v=hmkAoZOtF58) in Samara and Kazan, coffee delivery in Skolkovo Innovation Center, [autonomous quadcopter with charging station](https://www.youtube.com/watch?v=RjX6nUqw1mI) for site monitoring and security, winning drones on [Robocross-2016](https://www.youtube.com/watch?v=dGbDaz_VmYU) and [Robocross-2017](https://youtu.be/AQnd2CRczbQ) competitions and many others.
|
||||||
|
|
||||||
На базе точно такой же платформы были созданы многие «большие» проекты компании Copter Express, например, дроны для [пиар-акций по автономной доставке пиццы](https://www.youtube.com/watch?v=hmkAoZOtF58) (Самара, Казань); дрон-доставщик кофе в Сколково, мониторинговый дрон с зарядной станцией, дроны-победители на полевых испытаниях «[Робокросс-2016](https://www.youtube.com/watch?v=dGbDaz_VmYU)», «[Робокросс-2017](https://youtu.be/AQnd2CRczbQ)» и многие другие.
|
**The main documentation in Russian is available [on our Gitbook](https://clever.copterexpress.com/).**
|
||||||
|
|
||||||
Для того, чтобы научиться собирать, настраивать, пилотировать и программировать автономный дрон «Клевер», воспользуйтесь этим учебником.
|
Use it to learn how to assemble, configure, pilot and program autonomous CLEVER drone.
|
||||||
|
|
||||||
Основная документация
|
## Preconfigured RPi 3 image
|
||||||
---------------------
|
|
||||||
|
|
||||||
https://copterexpress.gitbooks.io/clever/content/
|
**Preconfigured image for Raspberry Pi 3 with installed and configured software, ready to fly, is available [in the Releases section](https://github.com/CopterExpress/clever/releases).**
|
||||||
|
|
||||||
**Готовый образ ОС** для RPi 3 с предустановленным и преднастроенным ПО можно скачать [здесь](https://copterexpress.gitbooks.io/clever/content/docs/microsd_images.html).
|
[](https://travis-ci.org/CopterExpress/clever)
|
||||||
|
|
||||||
[Описание API](https://copterexpress.gitbooks.io/clever/content/docs/simple_offboard.html) для автономных полетов.
|
Image includes:
|
||||||
|
|
||||||
Ручная установка
|
* Raspbian Stretch
|
||||||
---------
|
* ROS Kinetic
|
||||||
|
* Configured networking
|
||||||
|
* OpenCV
|
||||||
|
* mavros
|
||||||
|
* Periphery drivers (`pigpiod`, `rpi_ws281x`, etc)
|
||||||
|
* CLEVER software bundle for autonomous drone control
|
||||||
|
|
||||||
Склонировать репозиторий в папку `/home/pi/catkin_ws/src/clever` (**важно**):
|
API description (in Russian) for autonomous flights is available [on GitBook](https://clever.copterexpress.com/simple_offboard.html).
|
||||||
|
|
||||||
|
## Manual installation
|
||||||
|
|
||||||
|
Install ROS Kinetic according to the [documentation](http://wiki.ros.org/kinetic/Installation).
|
||||||
|
|
||||||
|
Clone repo to directory `/home/pi/catkin_ws/src/clever`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/catkin_ws/src
|
cd ~/catkin_ws/src
|
||||||
git clone https://github.com/CopterExpress/clever_bundle.git clever
|
git clone https://github.com/CopterExpress/clever.git clever
|
||||||
```
|
```
|
||||||
|
|
||||||
Пересобрать ROS-пакеты:
|
Build ROS packages:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/catkin_ws
|
cd ~/catkin_ws
|
||||||
catkin_make -j1
|
catkin_make -j1
|
||||||
```
|
```
|
||||||
|
|
||||||
Включить сервис roscore (если он не включен):
|
Enable systemd service `roscore` (if not enabled):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo systemctl enable /home/pi/catkin_ws/src/clever/deploy/roscore.service
|
sudo systemctl enable /home/pi/catkin_ws/src/clever/deploy/roscore.service
|
||||||
sudo systemctl start roscore
|
sudo systemctl start roscore
|
||||||
```
|
```
|
||||||
|
|
||||||
Включить сервис clever:
|
Enable systemd service `clever`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo systemctl enable /home/pi/catkin_ws/src/clever/deploy/clever.service
|
sudo systemctl enable /home/pi/catkin_ws/src/clever/deploy/clever.service
|
||||||
sudo systemctl start clever
|
sudo systemctl start clever
|
||||||
```
|
```
|
||||||
|
|
||||||
Зависимости
|
### Dependencies
|
||||||
-----------
|
|
||||||
|
|
||||||
[ROS Kinetic](http://wiki.ros.org/kinetic).
|
[ROS Kinetic](http://wiki.ros.org/kinetic).
|
||||||
|
|
||||||
Необходимые для работы ROS-пакеты:
|
Necessary ROS packages:
|
||||||
|
|
||||||
* `opencv3`
|
* `opencv3`
|
||||||
* `mavros`
|
* `mavros`
|
||||||
@@ -65,8 +73,6 @@ sudo systemctl start clever
|
|||||||
* `cv_camera`
|
* `cv_camera`
|
||||||
* `nodelet`
|
* `nodelet`
|
||||||
* `dynamic_reconfigure`
|
* `dynamic_reconfigure`
|
||||||
* `bondcpp`, ветка `master`
|
* `bondcpp`, branch `master`
|
||||||
* `roslint`
|
* `roslint`
|
||||||
* `rosserial`
|
* `rosserial`
|
||||||
|
|
||||||
TODO: внести в package.xml
|
|
||||||
|
|||||||
44
SUMMARY.md
@@ -1,44 +0,0 @@
|
|||||||
# Summary
|
|
||||||
|
|
||||||
* [Введение](README.md)
|
|
||||||
* [Сборка](docs/assemble.md)
|
|
||||||
* [Первоначальная настройка](docs/setup.md)
|
|
||||||
* [Полетные режимы](docs/modes.md)
|
|
||||||
* [Raspberry Pi](docs/raspberry.md)
|
|
||||||
* [Образ операционной системы на RPi](docs/microsd_images.md)
|
|
||||||
* [Подключение Raspberry Pi к PixHawk](docs/connection.md)
|
|
||||||
* [Подключение по Wi-Fi](docs/wifi.md)
|
|
||||||
* [Работа с QGroundControl через Wi-Fi](docs/gcs_bridge.md)
|
|
||||||
* [SSH-доступ](docs/ssh.md)
|
|
||||||
* [Неисправности радиоаппаратуры](docs/radioerrors.md)
|
|
||||||
* [Безопасность](docs/safety.md)
|
|
||||||
* [Техника безопасности по пайке](docs/tb.md)
|
|
||||||
* [Просмотр видеострима с камер](docs/web_video_server.md)
|
|
||||||
* [Работа с ROS](docs/ros.md)
|
|
||||||
* [MAVROS](docs/mavros.md)
|
|
||||||
* [Автономный полет в OFFBOARD](docs/simple_offboard.md)
|
|
||||||
* [Навигация по ArUco-маркерам](docs/aruco.md)
|
|
||||||
* [Взаимодействие с Arduino](docs/arduino.md)
|
|
||||||
* [Системы координат](docs/frames.md)
|
|
||||||
* [Работа с камерой \(компьютерное зрение\)](docs/camera.md)
|
|
||||||
* [Ориентация камеры](docs/camera_frame.md)
|
|
||||||
* [Визуализация с помощью rviz](docs/rviz.md)
|
|
||||||
* [Работа с SITL](docs/sitl.md)
|
|
||||||
* [Подключение GPS](docs/gps.md)
|
|
||||||
* [Использование 3G-модема](docs/3g.md)
|
|
||||||
* [Примеры программ](primeri-programm.md)
|
|
||||||
* Учебник
|
|
||||||
* [Урок 1](docs/les1.md)
|
|
||||||
* [Урок 2](docs/les2.md)
|
|
||||||
* [Урок 7](docs/les7.md)
|
|
||||||
* [Урок 8](docs/les8.md)
|
|
||||||
* [Урок 9](docs/les9.md)
|
|
||||||
* [Урок 11](docs/les11.md)
|
|
||||||
* [Урок 13](docs/les13.md)
|
|
||||||
* [Урок 15](docs/les15.md)
|
|
||||||
* [Урок 16](docs/les16.md)
|
|
||||||
* Другое
|
|
||||||
* [CopterHack-2017](docs/copterhack2017.md)
|
|
||||||
* [Прошивка ESC контроллеров с помощью Arduino](docs/esc_firmware.md)
|
|
||||||
* [Полезные ссылки](docs/links.md)
|
|
||||||
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
theme: jekyll-theme-cayman
|
|
||||||
tagline: Конструктор программируемого квадрокоптера
|
|
||||||
11
apps/android/.gitignore
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
*.iml
|
||||||
|
.gradle
|
||||||
|
/local.properties
|
||||||
|
/.idea/caches/build_file_checksums.ser
|
||||||
|
/.idea/libraries
|
||||||
|
/.idea/modules.xml
|
||||||
|
/.idea/workspace.xml
|
||||||
|
.DS_Store
|
||||||
|
/build
|
||||||
|
/captures
|
||||||
|
.externalNativeBuild
|
||||||
57
apps/android/.idea/assetWizardSettings.xml
generated
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="WizardSettings">
|
||||||
|
<option name="children">
|
||||||
|
<map>
|
||||||
|
<entry key="imageWizard">
|
||||||
|
<value>
|
||||||
|
<PersistentState>
|
||||||
|
<option name="children">
|
||||||
|
<map>
|
||||||
|
<entry key="imageAssetPanel">
|
||||||
|
<value>
|
||||||
|
<PersistentState>
|
||||||
|
<option name="children">
|
||||||
|
<map>
|
||||||
|
<entry key="launcher">
|
||||||
|
<value>
|
||||||
|
<PersistentState>
|
||||||
|
<option name="children">
|
||||||
|
<map>
|
||||||
|
<entry key="foregroundImage">
|
||||||
|
<value>
|
||||||
|
<PersistentState>
|
||||||
|
<option name="values">
|
||||||
|
<map>
|
||||||
|
<entry key="scalingPercent" value="54" />
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</PersistentState>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
<option name="values">
|
||||||
|
<map>
|
||||||
|
<entry key="backgroundAssetType" value="COLOR" />
|
||||||
|
<entry key="backgroundColor" value="ffffff" />
|
||||||
|
<entry key="foregroundImage" value="C:\Users\Motoy\Desktop\COEX\logo.png" />
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</PersistentState>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</PersistentState>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</PersistentState>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
35
apps/android/.idea/codeStyles/Project.xml
generated
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<code_scheme name="Project" version="173">
|
||||||
|
<JetCodeStyleSettings>
|
||||||
|
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||||
|
</JetCodeStyleSettings>
|
||||||
|
<Objective-C-extensions>
|
||||||
|
<file>
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
|
||||||
|
</file>
|
||||||
|
<class>
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
|
||||||
|
</class>
|
||||||
|
<extensions>
|
||||||
|
<pair source="cpp" header="h" fileNamingConvention="NONE" />
|
||||||
|
<pair source="c" header="h" fileNamingConvention="NONE" />
|
||||||
|
</extensions>
|
||||||
|
</Objective-C-extensions>
|
||||||
|
<codeStyleSettings language="kotlin">
|
||||||
|
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||||
|
</codeStyleSettings>
|
||||||
|
</code_scheme>
|
||||||
|
</component>
|
||||||
5
apps/android/.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||||
|
</state>
|
||||||
|
</component>
|
||||||
18
apps/android/.idea/gradle.xml
generated
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="GradleSettings">
|
||||||
|
<option name="linkedExternalProjectsSettings">
|
||||||
|
<GradleProjectSettings>
|
||||||
|
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="modules">
|
||||||
|
<set>
|
||||||
|
<option value="$PROJECT_DIR$" />
|
||||||
|
<option value="$PROJECT_DIR$/app" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
<option name="resolveModulePerSourceSet" value="false" />
|
||||||
|
</GradleProjectSettings>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
38
apps/android/.idea/misc.xml
generated
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="NullableNotNullManager">
|
||||||
|
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
|
||||||
|
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
|
||||||
|
<option name="myNullables">
|
||||||
|
<value>
|
||||||
|
<list size="7">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
|
||||||
|
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
|
||||||
|
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
|
||||||
|
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
|
||||||
|
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
|
||||||
|
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
|
||||||
|
<item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="myNotNulls">
|
||||||
|
<value>
|
||||||
|
<list size="6">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
|
||||||
|
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
|
||||||
|
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
|
||||||
|
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
|
||||||
|
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
|
||||||
|
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectType">
|
||||||
|
<option name="id" value="Android" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
12
apps/android/.idea/runConfigurations.xml
generated
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="RunConfigurationProducerService">
|
||||||
|
<option name="ignoredProducers">
|
||||||
|
<set>
|
||||||
|
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
apps/android/.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
1
apps/android/app/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/build
|
||||||
33
apps/android/app/build.gradle
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
apply plugin: 'kotlin-android'
|
||||||
|
|
||||||
|
apply plugin: 'kotlin-android-extensions'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 28
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "express.copter.cleverrc"
|
||||||
|
minSdkVersion 19
|
||||||
|
targetSdkVersion 28
|
||||||
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
|
implementation 'com.android.support:appcompat-v7:28.0.0'
|
||||||
|
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
|
||||||
|
testImplementation 'junit:junit:4.12'
|
||||||
|
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
||||||
|
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
||||||
|
}
|
||||||
21
apps/android/app/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# You can control the set of applied configuration files using the
|
||||||
|
# proguardFiles setting in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for
|
||||||
|
# debugging stack traces.
|
||||||
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to
|
||||||
|
# hide the original source file name.
|
||||||
|
#-renamesourcefileattribute SourceFile
|
||||||
BIN
apps/android/app/release/release/app1.aab
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package express.copter.cleverrc
|
||||||
|
|
||||||
|
import android.support.test.InstrumentationRegistry
|
||||||
|
import android.support.test.runner.AndroidJUnit4
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
import org.junit.Assert.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instrumented test, which will execute on an Android device.
|
||||||
|
*
|
||||||
|
* See [testing documentation](http://d.android.com/tools/testing).
|
||||||
|
*/
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class ExampleInstrumentedTest {
|
||||||
|
@Test
|
||||||
|
fun useAppContext() {
|
||||||
|
// Context of the app under test.
|
||||||
|
val appContext = InstrumentationRegistry.getTargetContext()
|
||||||
|
assertEquals("express.copter.cleverrc", appContext.packageName)
|
||||||
|
}
|
||||||
|
}
|
||||||
25
apps/android/app/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="express.copter.cleverrc">
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
android:theme="@style/AppTheme">
|
||||||
|
<activity android:name=".MainActivity"
|
||||||
|
android:screenOrientation="landscape"
|
||||||
|
android:theme="@style/NoUiAppTheme">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
57
apps/android/app/src/main/assets/clever.svg
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<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"
|
||||||
|
viewBox="0 0 69.988266 69.987198"
|
||||||
|
height="69.987198"
|
||||||
|
width="69.988266"
|
||||||
|
xml:space="preserve"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"><metadata
|
||||||
|
id="metadata8"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs6"><clipPath
|
||||||
|
id="clipPath18"
|
||||||
|
clipPathUnits="userSpaceOnUse"><path
|
||||||
|
id="path16"
|
||||||
|
d="M 0,52.49 H 52.491 V 0 H 0 Z" /></clipPath></defs><g
|
||||||
|
transform="matrix(1.3333333,0,0,-1.3333333,0,69.9872)"
|
||||||
|
id="g10"><g
|
||||||
|
id="g12"><g
|
||||||
|
clip-path="url(#clipPath18)"
|
||||||
|
id="g14"><g
|
||||||
|
transform="translate(35.6531,35.3361)"
|
||||||
|
id="g20"><path
|
||||||
|
id="path22"
|
||||||
|
style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
|
||||||
|
d="M 0,0 C 0.279,0.322 0.5,0.686 0.657,1.081 0.827,1.513 0.914,1.968 0.917,2.434 0.92,2.924 0.829,3.403 0.647,3.857 0.458,4.329 0.165,4.77 -0.2,5.13 -0.587,5.512 -1.061,5.812 -1.571,5.995 -2.138,6.198 -2.756,6.262 -3.358,6.18 -3.821,6.115 -4.263,5.967 -4.671,5.739 -4.886,5.618 -5.094,5.472 -5.291,5.305 L -5.467,5.151 C -5.527,5.099 -5.587,5.049 -5.649,5.003 -5.775,4.909 -5.906,4.827 -6.04,4.759 -6.173,4.691 -6.314,4.633 -6.458,4.586 -6.575,4.549 -6.696,4.519 -6.819,4.496 -6.917,4.478 -7.017,4.465 -7.115,4.457 c -0.623,-0.052 -1.281,0.082 -1.9,0.385 -0.224,0.111 -0.439,0.241 -0.64,0.387 -0.042,0.03 -0.084,0.063 -0.127,0.095 -0.039,0.031 -0.069,0.054 -0.102,0.09 -0.023,0.025 -0.043,0.05 -0.061,0.077 -0.056,0.082 -0.093,0.176 -0.107,0.271 -0.004,0.022 -0.005,0.044 -0.006,0.066 l -0.002,6.486 c -0.534,0.589 -1.115,1.136 -1.728,1.626 -0.913,0.73 -1.913,1.352 -2.971,1.845 -0.867,0.405 -1.779,0.725 -2.711,0.952 -0.851,0.208 -1.731,0.34 -2.617,0.391 -0.912,0.053 -1.834,0.023 -2.741,-0.092 -0.741,-0.094 -1.479,-0.246 -2.194,-0.453 -1.274,-0.365 -2.494,-0.905 -3.628,-1.604 -0.824,-0.507 -1.603,-1.101 -2.316,-1.764 -0.687,-0.64 -1.317,-1.35 -1.871,-2.109 -0.505,-0.692 -0.951,-1.432 -1.327,-2.2 -0.375,-0.764 -0.684,-1.566 -0.919,-2.383 -0.201,-0.7 -0.351,-1.423 -0.446,-2.147 -0.12,-0.919 -0.153,-1.858 -0.099,-2.79 0.05,-0.838 0.171,-1.673 0.359,-2.482 0.201,-0.856 0.481,-1.7 0.833,-2.507 0.546,-1.253 1.265,-2.423 2.136,-3.479 0.317,-0.384 0.654,-0.753 1.002,-1.098 0.158,-0.157 0.32,-0.31 0.485,-0.459 h 6.121 c 0.051,0.08 0.099,0.161 0.143,0.245 0.037,0.071 0.072,0.144 0.104,0.218 0.026,0.062 0.05,0.128 0.073,0.193 0.132,0.394 0.159,0.784 0.077,1.127 -0.013,0.052 -0.028,0.105 -0.046,0.157 -0.024,0.068 -0.053,0.136 -0.087,0.201 -0.048,0.09 -0.105,0.174 -0.169,0.249 -0.035,0.041 -0.07,0.079 -0.107,0.116 l -0.024,0.026 c -0.025,0.029 -0.046,0.053 -0.066,0.079 -0.014,0.02 -0.02,0.029 -0.027,0.038 l -0.079,0.096 c -0.109,0.134 -0.212,0.277 -0.304,0.42 -0.207,0.318 -0.378,0.659 -0.506,1.013 -0.118,0.32 -0.202,0.651 -0.252,0.985 -0.085,0.571 -0.073,1.146 0.035,1.71 0.098,0.509 0.273,0.999 0.521,1.454 0.258,0.475 0.588,0.903 0.98,1.272 0.419,0.394 0.895,0.711 1.415,0.942 0.557,0.249 1.15,0.393 1.762,0.428 0.659,0.035 1.298,-0.05 1.914,-0.258 0.653,-0.221 1.268,-0.585 1.78,-1.05 0.541,-0.492 0.977,-1.106 1.261,-1.776 0.151,-0.357 0.26,-0.729 0.324,-1.106 0.072,-0.415 0.092,-0.843 0.058,-1.272 -0.031,-0.388 -0.108,-0.773 -0.227,-1.144 -0.11,-0.341 -0.257,-0.673 -0.441,-0.988 -0.103,-0.177 -0.216,-0.347 -0.335,-0.503 -0.037,-0.051 -0.077,-0.1 -0.117,-0.151 l -0.033,-0.04 -0.005,0.002 -0.049,-0.07 c -0.022,-0.028 -0.043,-0.054 -0.066,-0.08 l -0.076,-0.08 c -0.028,-0.03 -0.055,-0.062 -0.081,-0.094 -0.05,-0.063 -0.095,-0.131 -0.134,-0.202 -0.035,-0.064 -0.066,-0.131 -0.09,-0.199 -0.019,-0.053 -0.035,-0.105 -0.049,-0.158 -0.085,-0.34 -0.062,-0.729 0.066,-1.123 0.021,-0.066 0.045,-0.13 0.071,-0.193 0.03,-0.073 0.063,-0.145 0.1,-0.215 0.045,-0.088 0.096,-0.176 0.156,-0.269 h 7.162 l 0.002,7.527 c 10e-4,0.022 0.002,0.043 0.006,0.065 0.008,0.061 0.027,0.124 0.057,0.187 0.03,0.06 0.067,0.114 0.111,0.161 0.034,0.037 0.065,0.062 0.102,0.09 l 0.062,0.048 c 0.087,0.065 0.173,0.126 0.262,0.183 0.487,0.316 1.027,0.526 1.563,0.608 0.154,0.024 0.312,0.037 0.482,0.04 0.037,0.001 0.076,0 0.113,-0.001 0.062,-0.002 0.124,-0.005 0.186,-0.01 0.123,-0.011 0.247,-0.029 0.367,-0.053 0.338,-0.071 0.654,-0.2 0.939,-0.383 0.11,-0.07 0.214,-0.149 0.31,-0.231 0.031,-0.026 0.061,-0.053 0.09,-0.081 l 0.029,-0.028 -0.07,-0.106 c 0.003,-0.003 0.007,-0.007 0.01,-0.01 l 0.071,0.101 0.215,-0.169 c 0.13,-0.101 0.243,-0.179 0.358,-0.25 0.24,-0.146 0.497,-0.266 0.763,-0.355 0.656,-0.219 1.363,-0.253 2.04,-0.097 0.374,0.086 0.731,0.229 1.059,0.424 C -0.581,-0.571 -0.268,-0.309 0,0" /></g><g
|
||||||
|
transform="translate(41.5882,22.8337)"
|
||||||
|
id="g24"><path
|
||||||
|
id="path26"
|
||||||
|
style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
|
||||||
|
d="M 0,0 V 0 L 0.053,0.044 0.013,0.018 Z" /></g><g
|
||||||
|
transform="translate(28.5515,3.2736)"
|
||||||
|
id="g28"><path
|
||||||
|
id="path30"
|
||||||
|
style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
|
||||||
|
d="m 0,0 c 0.934,-0.757 1.959,-1.398 3.045,-1.906 0.84,-0.39 1.72,-0.702 2.615,-0.927 0.883,-0.222 1.796,-0.362 2.714,-0.416 0.944,-0.054 1.897,-0.019 2.832,0.106 0.707,0.094 1.414,0.242 2.102,0.439 1.276,0.368 2.496,0.908 3.628,1.605 0.798,0.492 1.556,1.065 2.251,1.704 0.724,0.666 1.384,1.408 1.962,2.205 0.468,0.646 0.886,1.334 1.242,2.044 0.409,0.815 0.742,1.672 0.99,2.547 0.179,0.628 0.316,1.274 0.409,1.921 0.14,0.979 0.182,1.98 0.123,2.973 -0.048,0.819 -0.165,1.638 -0.348,2.433 -0.2,0.872 -0.484,1.732 -0.843,2.556 -0.538,1.234 -1.247,2.392 -2.106,3.442 -0.313,0.381 -0.648,0.752 -0.998,1.1 l -0.52,0.493 H 12.982 L 12.831,22.068 C 12.797,22.003 12.763,21.931 12.732,21.857 12.705,21.794 12.681,21.73 12.659,21.665 12.527,21.268 12.5,20.878 12.582,20.536 c 0.012,-0.053 0.027,-0.105 0.045,-0.156 0.024,-0.069 0.054,-0.137 0.088,-0.202 0.046,-0.086 0.103,-0.171 0.169,-0.251 0.027,-0.032 0.056,-0.062 0.086,-0.093 l 0.045,-0.048 c 0.023,-0.025 0.044,-0.051 0.065,-0.078 l -0.046,-0.082 0.061,0.057 0.003,-0.002 0.022,-0.028 -10e-4,-10e-4 0.01,-0.015 0.004,0.003 0.05,-0.062 c 0.171,-0.212 0.322,-0.433 0.451,-0.659 0.275,-0.478 0.469,-0.996 0.575,-1.538 0.141,-0.718 0.124,-1.472 -0.05,-2.181 -0.152,-0.623 -0.431,-1.228 -0.807,-1.751 -0.303,-0.42 -0.667,-0.79 -1.082,-1.1 C 11.868,12.048 11.425,11.81 10.954,11.64 10.456,11.461 9.935,11.362 9.406,11.345 8.955,11.331 8.505,11.376 8.07,11.48 c -0.494,0.118 -0.965,0.308 -1.399,0.565 -0.509,0.301 -0.958,0.685 -1.333,1.14 -0.393,0.477 -0.692,1.014 -0.89,1.596 -0.218,0.645 -0.305,1.348 -0.25,2.031 0.029,0.355 0.095,0.704 0.194,1.037 0.114,0.383 0.273,0.751 0.474,1.095 0.095,0.164 0.207,0.334 0.334,0.503 0.038,0.051 0.078,0.102 0.118,0.151 L 5.45,19.56 v 0 l -0.101,0.074 0.055,0.073 c 0.023,0.028 0.045,0.054 0.066,0.078 l 0.076,0.08 c 0.03,0.031 0.057,0.062 0.082,0.095 0.05,0.063 0.095,0.131 0.135,0.203 0.034,0.063 0.065,0.13 0.09,0.199 0.019,0.052 0.034,0.103 0.047,0.156 0.086,0.341 0.063,0.73 -0.065,1.124 -0.021,0.065 -0.044,0.129 -0.071,0.193 -0.033,0.082 -0.071,0.162 -0.113,0.24 -0.044,0.084 -0.092,0.165 -0.143,0.244 h -7.162 l -0.002,-7.532 c -0.001,-0.02 -0.003,-0.041 -0.006,-0.06 -0.015,-0.099 -0.052,-0.192 -0.107,-0.272 -0.018,-0.027 -0.039,-0.052 -0.061,-0.076 -0.035,-0.037 -0.064,-0.061 -0.102,-0.09 -0.02,-0.016 -0.042,-0.033 -0.065,-0.05 -0.122,-0.091 -0.254,-0.181 -0.393,-0.264 -0.619,-0.37 -1.29,-0.565 -1.942,-0.565 -0.093,-0.003 -0.179,0.003 -0.268,0.011 -0.11,0.01 -0.221,0.025 -0.33,0.046 -0.36,0.071 -0.709,0.213 -1.008,0.411 -0.109,0.072 -0.213,0.152 -0.309,0.237 -0.029,0.026 -0.058,0.052 -0.085,0.079 h -0.026 l -0.022,0.042 -0.036,0.027 c -0.035,0.03 -0.061,0.051 -0.087,0.072 l -0.073,0.059 c -0.212,0.162 -0.427,0.296 -0.648,0.404 -0.416,0.204 -0.861,0.328 -1.324,0.367 -0.345,0.028 -0.695,0.012 -1.037,-0.053 -0.259,-0.05 -0.511,-0.126 -0.75,-0.228 -0.498,-0.211 -0.954,-0.534 -1.32,-0.936 -0.345,-0.381 -0.614,-0.838 -0.779,-1.322 -0.154,-0.455 -0.218,-0.933 -0.191,-1.421 0.026,-0.462 0.136,-0.909 0.326,-1.327 0.175,-0.386 0.412,-0.738 0.706,-1.047 0.283,-0.296 0.609,-0.543 0.97,-0.734 0.319,-0.168 0.661,-0.289 1.015,-0.36 0.449,-0.089 0.906,-0.095 1.357,-0.021 0.246,0.041 0.49,0.108 0.725,0.198 0.254,0.098 0.499,0.225 0.727,0.377 0.113,0.075 0.229,0.161 0.343,0.257 l 0.068,0.054 0.016,0.046 0.041,0.002 c 0.012,0.013 0.02,0.02 0.029,0.028 l 0.055,0.052 c 0.051,0.043 0.1,0.084 0.151,0.124 0.104,0.08 0.212,0.151 0.322,0.213 0.28,0.159 0.589,0.268 0.917,0.324 0.152,0.026 0.31,0.04 0.48,0.043 h 0.109 C -4.1,9.429 -3.938,9.414 -3.782,9.389 -3.261,9.303 -2.734,9.095 -2.256,8.787 -2.167,8.73 -2.08,8.668 -1.996,8.604 l 0.053,-0.04 c 0.048,-0.037 0.077,-0.061 0.111,-0.097 0.047,-0.05 0.084,-0.104 0.113,-0.162 0.029,-0.062 0.048,-0.125 0.057,-0.187 0.003,-0.02 0.005,-0.04 0.006,-0.06 L -1.654,8.021 V 1.566 C -1.142,1.001 -0.585,0.474 0,0" /></g><g
|
||||||
|
transform="translate(22.2707,17.571)"
|
||||||
|
id="g32"><path
|
||||||
|
id="path34"
|
||||||
|
style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
|
||||||
|
d="m 0,0 v -0.008 l 0.011,0.019 v 0 z" /></g><g
|
||||||
|
transform="translate(40.657,22.3049)"
|
||||||
|
id="g36"><path
|
||||||
|
id="path38"
|
||||||
|
style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
|
||||||
|
d="M 0,0 Z" /></g><g
|
||||||
|
transform="translate(49.1867,28.5134)"
|
||||||
|
id="g40"><path
|
||||||
|
id="path42"
|
||||||
|
style="fill:white;fill-opacity:0.5;fill-rule:nonzero;stroke:none"
|
||||||
|
d="m 0,0 c 0.721,0.884 1.337,1.848 1.832,2.865 0.359,0.739 0.659,1.516 0.89,2.311 0.244,0.839 0.413,1.706 0.503,2.579 0.173,1.678 0.063,3.352 -0.329,4.976 -0.323,1.339 -0.834,2.625 -1.518,3.823 -0.416,0.728 -0.898,1.425 -1.432,2.072 -0.597,0.724 -1.268,1.394 -1.993,1.994 -0.636,0.525 -1.32,0.999 -2.034,1.409 -0.75,0.431 -1.539,0.796 -2.345,1.086 -1,0.359 -2.041,0.609 -3.095,0.743 -0.401,0.051 -0.808,0.086 -1.209,0.104 -0.205,0.009 -0.41,0.014 -0.615,0.015 h -0.098 c -0.479,-0.003 -0.943,-0.026 -1.379,-0.069 -0.825,-0.08 -1.65,-0.231 -2.451,-0.45 -0.861,-0.235 -1.705,-0.551 -2.509,-0.941 -0.765,-0.371 -1.502,-0.811 -2.191,-1.308 -0.571,-0.411 -1.115,-0.866 -1.618,-1.352 -0.236,-0.227 -0.471,-0.469 -0.698,-0.72 v -6.121 c 0.079,-0.052 0.161,-0.1 0.245,-0.144 0.07,-0.037 0.143,-0.071 0.216,-0.102 0.064,-0.027 0.13,-0.051 0.195,-0.074 0.394,-0.132 0.784,-0.158 1.127,-0.077 0.053,0.012 0.105,0.027 0.156,0.045 0.069,0.024 0.136,0.054 0.201,0.088 0.088,0.047 0.173,0.104 0.251,0.169 0.04,0.034 0.078,0.071 0.116,0.107 l 0.029,0.028 c 0.035,0.029 0.055,0.046 0.077,0.063 l 0.107,0.085 c 0.164,0.132 0.314,0.24 0.466,0.338 0.319,0.205 0.662,0.373 1.018,0.502 0.317,0.115 0.649,0.198 0.987,0.245 0.56,0.082 1.126,0.068 1.681,-0.038 0.51,-0.098 1,-0.273 1.455,-0.521 0.473,-0.257 0.901,-0.587 1.272,-0.981 0.394,-0.418 0.711,-0.894 0.942,-1.414 0.248,-0.558 0.392,-1.151 0.427,-1.762 0.037,-0.645 -0.052,-1.307 -0.258,-1.914 -0.22,-0.652 -0.583,-1.267 -1.049,-1.781 -0.491,-0.54 -1.105,-0.976 -1.776,-1.26 -0.352,-0.149 -0.724,-0.259 -1.106,-0.325 -0.421,-0.072 -0.849,-0.091 -1.272,-0.057 -0.371,0.03 -0.739,0.1 -1.09,0.21 -0.365,0.113 -0.716,0.267 -1.042,0.458 -0.167,0.096 -0.336,0.209 -0.503,0.334 -0.051,0.039 -0.102,0.078 -0.151,0.118 l -0.108,0.086 c -0.028,0.022 -0.053,0.043 -0.079,0.065 -0.03,0.028 -0.056,0.054 -0.082,0.079 -0.029,0.026 -0.061,0.054 -0.094,0.081 -0.064,0.05 -0.132,0.095 -0.201,0.133 -0.064,0.035 -0.132,0.065 -0.201,0.091 -0.051,0.018 -0.101,0.034 -0.154,0.046 C -20.829,6.024 -21.219,6 -21.613,5.873 -21.677,5.852 -21.742,5.828 -21.806,5.802 -21.887,5.768 -21.967,5.73 -22.045,5.689 -22.129,5.645 -22.21,5.598 -22.289,5.546 v -7.162 l 7.532,-0.003 c 0.02,-0.001 0.04,-0.002 0.06,-0.005 0.098,-0.015 0.192,-0.052 0.272,-0.107 0.026,-0.018 0.053,-0.039 0.076,-0.062 0.035,-0.033 0.058,-0.061 0.085,-0.096 l 0.053,-0.068 c 0.094,-0.125 0.184,-0.257 0.267,-0.395 0.362,-0.608 0.557,-1.269 0.563,-1.912 0.002,-0.099 -0.002,-0.198 -0.01,-0.298 -0.009,-0.11 -0.025,-0.221 -0.046,-0.33 -0.072,-0.362 -0.213,-0.711 -0.41,-1.008 -0.074,-0.11 -0.153,-0.214 -0.238,-0.309 -0.026,-0.029 -0.053,-0.057 -0.08,-0.086 l -0.025,-0.026 v 10e-4 l -0.18,-0.227 c -0.083,-0.106 -0.161,-0.219 -0.23,-0.334 -0.143,-0.233 -0.26,-0.483 -0.349,-0.744 -0.223,-0.654 -0.261,-1.359 -0.109,-2.037 0.084,-0.378 0.229,-0.742 0.429,-1.083 0.208,-0.351 0.47,-0.665 0.779,-0.932 0.323,-0.28 0.687,-0.5 1.081,-0.656 0.429,-0.17 0.884,-0.257 1.352,-0.26 h 0.026 c 0.482,0 0.951,0.09 1.397,0.269 0.473,0.19 0.913,0.483 1.274,0.848 0.383,0.388 0.682,0.862 0.865,1.371 0.203,0.566 0.267,1.184 0.184,1.786 -0.066,0.477 -0.221,0.931 -0.461,1.349 -0.117,0.204 -0.256,0.4 -0.413,0.584 l -0.073,0.089 0.005,0.01 -0.002,0.006 0.007,0.002 0.017,0.033 0.035,0.065 -0.091,-0.085 -0.053,0.057 c -0.051,0.06 -0.101,0.12 -0.148,0.182 -0.091,0.121 -0.173,0.253 -0.243,0.391 -0.067,0.13 -0.125,0.27 -0.172,0.417 -0.038,0.116 -0.068,0.239 -0.091,0.363 -0.018,0.097 -0.031,0.196 -0.039,0.294 -0.052,0.624 0.082,1.281 0.385,1.901 0.109,0.221 0.239,0.436 0.386,0.639 0.031,0.043 0.064,0.085 0.096,0.127 0.032,0.041 0.055,0.069 0.09,0.102 0.025,0.023 0.051,0.045 0.078,0.063 0.079,0.054 0.172,0.091 0.27,0.106 0.02,0.003 0.04,0.004 0.06,0.005 l 0.038,0.003 h 6.454 C -0.981,-1.113 -0.465,-0.57 0,0" /></g>
|
||||||
|
</g></g></g></svg>
|
||||||
|
After Width: | Height: | Size: 13 KiB |
24
apps/android/app/src/main/assets/index.html
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, minimal-ui">
|
||||||
|
<link rel="stylesheet" href="main.css">
|
||||||
|
<script src="roslib.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="telemetry"><span class="mode">DISCONNECTED</span></div>
|
||||||
|
<div class="battery"></div>
|
||||||
|
<div class="logo"></div>
|
||||||
|
<div class="container">
|
||||||
|
<div class="stick stick-left">
|
||||||
|
<div class="stick-pointer"></div>
|
||||||
|
</div>
|
||||||
|
<div class="stick stick-right">
|
||||||
|
<div class="stick-pointer"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="notifications"></div>
|
||||||
|
<script src="main.js" type="text/javascript"></script>
|
||||||
|
<script src="telemetry.js" type="text/javascript"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
125
apps/android/app/src/main/assets/main.css
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
user-select: none;
|
||||||
|
font-family: sans-serif;
|
||||||
|
background: #212121;
|
||||||
|
color: rgba(255, 255, 255, 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stick {
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 5cm;
|
||||||
|
height: 5cm;
|
||||||
|
position: relative;
|
||||||
|
transform: translateZ(0);
|
||||||
|
border: 4px solid rgba(255,255,255,.4);
|
||||||
|
box-shadow: 0 0 0 1px rgba(0,0,0,.2), inset 0 0 0 1px rgba(0,0,0,.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stick-pointer {
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: rgba(255,255,255,.25);
|
||||||
|
box-shadow: 0 0 10px rgba(0,0,0,.3);
|
||||||
|
width: 3cm;
|
||||||
|
height: 3cm;
|
||||||
|
margin-left: -1.5cm;
|
||||||
|
margin-top: -1.5cm;
|
||||||
|
top: 2.5cm;
|
||||||
|
left: 2.5cm;
|
||||||
|
pointer-events: none;
|
||||||
|
transform: translateZ(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.telemetry {
|
||||||
|
position: absolute;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
top: 30px;
|
||||||
|
font-size: 20px;
|
||||||
|
user-select: none;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.armed .telemetry .mode {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes scale {
|
||||||
|
0% { transform: scale(1.0); }
|
||||||
|
50% { transform: scale(1.2); }
|
||||||
|
100% { transform: scale(1.0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.battery {
|
||||||
|
position: absolute;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
bottom: 30px;
|
||||||
|
font-size: 20px;
|
||||||
|
user-select: none;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.low-battery .battery {
|
||||||
|
color: #ff554b;
|
||||||
|
animation: scale 0.3s 1 ease-in-out
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
position: absolute;
|
||||||
|
background: url(clever.svg);
|
||||||
|
-webkit-background-size: 50px;
|
||||||
|
background-size: 50px;
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
margin-top: -25px;
|
||||||
|
margin-left: -25px;
|
||||||
|
font-size: 20px;
|
||||||
|
user-select: none;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notifications {
|
||||||
|
pointer-events: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notifications.hidden {
|
||||||
|
transform: translateY(-100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.notifications.anim {
|
||||||
|
transition: transform 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notifications .item {
|
||||||
|
font-size: 4mm;
|
||||||
|
-webkit-text-size-adjust: none;
|
||||||
|
background: #fca83a;
|
||||||
|
padding: 3mm;
|
||||||
|
padding-bottom: 1.5mm;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notifications .item:last-child {
|
||||||
|
padding-bottom: 3mm;
|
||||||
|
}
|
||||||
139
apps/android/app/src/main/assets/main.js
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
function throttle(func, ms) {
|
||||||
|
var isThrottled = false,
|
||||||
|
savedArgs,
|
||||||
|
savedThis;
|
||||||
|
|
||||||
|
function wrapper() {
|
||||||
|
if (isThrottled) {
|
||||||
|
savedArgs = arguments;
|
||||||
|
savedThis = this;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
func.apply(this, arguments);
|
||||||
|
isThrottled = true;
|
||||||
|
setTimeout(function() {
|
||||||
|
isThrottled = false;
|
||||||
|
if (savedArgs) {
|
||||||
|
wrapper.apply(savedThis, savedArgs);
|
||||||
|
savedArgs = savedThis = null;
|
||||||
|
}
|
||||||
|
}, ms);
|
||||||
|
}
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
function postAppMessage(msg) {
|
||||||
|
if (window.webkit != undefined) {
|
||||||
|
if (window.webkit.messageHandlers.appInterface != undefined) {
|
||||||
|
window.webkit.messageHandlers.appInterface.postMessage(JSON.stringify(msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (window.appInterface != undefined) {
|
||||||
|
window.appInterface.postMessage(JSON.stringify(msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function callNativeApp(name, msg) {
|
||||||
|
try {
|
||||||
|
postAppMessage(msg);
|
||||||
|
return true;
|
||||||
|
} catch(err) {
|
||||||
|
console.warn('The native context does not exist yet');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var rcLastPublish = null;
|
||||||
|
|
||||||
|
function rcPublish() {
|
||||||
|
callNativeApp('control', controlMessage);
|
||||||
|
rcLastPublish = new Date();
|
||||||
|
}
|
||||||
|
|
||||||
|
rcPublishThrottled = throttle(rcPublish, 30);
|
||||||
|
|
||||||
|
setInterval(function() {
|
||||||
|
if (rcLastPublish !== null && new Date() - rcLastPublish > 800) {
|
||||||
|
rcPublishThrottled();
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
|
||||||
|
var body = document.querySelector('body');
|
||||||
|
var stickLeft = document.querySelector('.stick-left');
|
||||||
|
var stickRight = document.querySelector('.stick-right');
|
||||||
|
|
||||||
|
var controlMessage = { x: 0, y: 0, z: 0, r: 0 };
|
||||||
|
|
||||||
|
function onStickTouchMove(touch) {
|
||||||
|
var target = touch.target;
|
||||||
|
var targetRect = target.getBoundingClientRect();
|
||||||
|
var stickPointer = target.querySelector('.stick-pointer');
|
||||||
|
|
||||||
|
var offsetX = touch.clientX - targetRect.left;
|
||||||
|
var offsetY = touch.clientY - targetRect.top;
|
||||||
|
|
||||||
|
var x = 2 * offsetX / targetRect.width;
|
||||||
|
var y = 2 * offsetY / targetRect.height;
|
||||||
|
|
||||||
|
x = Math.max(0, x);
|
||||||
|
x = Math.min(2, x);
|
||||||
|
y = Math.max(0, y);
|
||||||
|
y = Math.min(2, y);
|
||||||
|
|
||||||
|
stickPointer.style.left = (x * 50) + '%';
|
||||||
|
stickPointer.style.top = (y * 50) + '%';
|
||||||
|
|
||||||
|
x -= 1;
|
||||||
|
y = 1 - y;
|
||||||
|
|
||||||
|
if (target.matches('.stick-left')) {
|
||||||
|
controlMessage.z = Math.round((y + 1) * 500);
|
||||||
|
controlMessage.r = Math.round(x * 1000);
|
||||||
|
} else if (target.matches('.stick-right')) {
|
||||||
|
controlMessage.x = Math.round(y * 1000);
|
||||||
|
controlMessage.y = Math.round(x * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body.addEventListener('touchmove', function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
function stickTouchStart(e) {
|
||||||
|
setControlMode();
|
||||||
|
callNativeApp('controlStart');
|
||||||
|
onStickTouchMove(e.changedTouches[0]);
|
||||||
|
rcPublishThrottled();
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
function stickTouchMove(e) {
|
||||||
|
for (touch of e.changedTouches) {
|
||||||
|
onStickTouchMove(touch);
|
||||||
|
}
|
||||||
|
//onStickTouchMove(e.changedTouches[0]);
|
||||||
|
rcPublishThrottled();
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
function stickTouchEnd(e) {
|
||||||
|
var pointer = e.target.querySelector('.stick-pointer');
|
||||||
|
if (e.target.matches('.stick-left')) {
|
||||||
|
controlMessage.r = 0;
|
||||||
|
pointer.style.left = '50%';
|
||||||
|
} else if (e.target.matches('.stick-right')) {
|
||||||
|
controlMessage.x = 0;
|
||||||
|
controlMessage.y = 0;
|
||||||
|
pointer.style.left = '50%';
|
||||||
|
pointer.style.top = '50%';
|
||||||
|
}
|
||||||
|
rcPublishThrottled();
|
||||||
|
}
|
||||||
|
|
||||||
|
stickLeft.addEventListener('touchmove', stickTouchMove);
|
||||||
|
stickRight.addEventListener('touchmove', stickTouchMove);
|
||||||
|
stickLeft.addEventListener('touchstart', stickTouchStart);
|
||||||
|
stickRight.addEventListener('touchstart', stickTouchStart);
|
||||||
|
stickLeft.addEventListener('touchend', stickTouchEnd);
|
||||||
|
stickRight.addEventListener('touchend', stickTouchEnd);
|
||||||
142
apps/android/app/src/main/assets/old.js
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
function throttle(func, ms) {
|
||||||
|
var isThrottled = false,
|
||||||
|
savedArgs,
|
||||||
|
savedThis;
|
||||||
|
|
||||||
|
function wrapper() {
|
||||||
|
if (isThrottled) {
|
||||||
|
savedArgs = arguments;
|
||||||
|
savedThis = this;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
func.apply(this, arguments);
|
||||||
|
isThrottled = true;
|
||||||
|
setTimeout(function() {
|
||||||
|
isThrottled = false;
|
||||||
|
if (savedArgs) {
|
||||||
|
wrapper.apply(savedThis, savedArgs);
|
||||||
|
savedArgs = savedThis = null;
|
||||||
|
}
|
||||||
|
}, ms);
|
||||||
|
}
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
function postAppMessage(msg) {
|
||||||
|
if (window.webkit != undefined) {
|
||||||
|
if (window.webkit.messageHandlers.appInterface != undefined) {
|
||||||
|
window.webkit.messageHandlers.appInterface.postMessage(JSON.stringify(msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (window.appInterface != undefined) {
|
||||||
|
window.appInterface.postMessage(JSON.stringify(msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function callNativeApp(name, msg) {
|
||||||
|
try {
|
||||||
|
postAppMessage(msg);
|
||||||
|
return true;
|
||||||
|
} catch(err) {
|
||||||
|
console.warn('The native context does not exist yet');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var rcLastPublish = null;
|
||||||
|
|
||||||
|
function rcPublish() {
|
||||||
|
callNativeApp('control', controlMessage);
|
||||||
|
rcLastPublish = new Date();
|
||||||
|
}
|
||||||
|
|
||||||
|
rcPublishThrottled = throttle(rcPublish, 30);
|
||||||
|
|
||||||
|
setInterval(function() {
|
||||||
|
if (rcLastPublish !== null && new Date() - rcLastPublish > 800) {
|
||||||
|
rcPublishThrottled();
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
|
||||||
|
var body = document.querySelector('body');
|
||||||
|
var stickLeft = document.querySelector('.stick-left');
|
||||||
|
var stickRight = document.querySelector('.stick-right');
|
||||||
|
|
||||||
|
var controlMessage = { x: 0, y: 0, z: 0, r: 0 };
|
||||||
|
|
||||||
|
function onStickTouchMove(touch) {
|
||||||
|
var target = touch.target;
|
||||||
|
var targetRect = target.getBoundingClientRect();
|
||||||
|
var stickPointer = target.querySelector('.stick-pointer');
|
||||||
|
|
||||||
|
var offsetX = touch.clientX - targetRect.left;
|
||||||
|
var offsetY = touch.clientY - targetRect.top;
|
||||||
|
|
||||||
|
var x = 2 * offsetX / targetRect.width;
|
||||||
|
var y = 2 * offsetY / targetRect.height;
|
||||||
|
|
||||||
|
x = Math.max(0, x);
|
||||||
|
x = Math.min(2, x);
|
||||||
|
y = Math.max(0, y);
|
||||||
|
y = Math.min(2, y);
|
||||||
|
|
||||||
|
stickPointer.style.left = (x * 50) + '%';
|
||||||
|
stickPointer.style.top = (y * 50) + '%';
|
||||||
|
|
||||||
|
x -= 1;
|
||||||
|
y = 1 - y;
|
||||||
|
|
||||||
|
if (target.matches('.stick-left')) {
|
||||||
|
controlMessage.z = Math.round((y + 1) * 500);
|
||||||
|
controlMessage.r = Math.round(x * 1000);
|
||||||
|
} else if (target.matches('.stick-right')) {
|
||||||
|
controlMessage.x = Math.round(y * 1000);
|
||||||
|
controlMessage.y = Math.round(x * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body.addEventListener('touchmove', function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
function stickTouchStart(e) {
|
||||||
|
setControlMode();
|
||||||
|
callNativeApp('controlStart');
|
||||||
|
onStickTouchMove(e.changedTouches[0]);
|
||||||
|
rcPublishThrottled();
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
function stickTouchMove(e) {
|
||||||
|
for (touch of e.changedTouches) {
|
||||||
|
onStickTouchMove(touch);
|
||||||
|
}
|
||||||
|
//onStickTouchMove(e.changedTouches[0]);
|
||||||
|
rcPublishThrottled();
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
function stickTouchEnd(e) {
|
||||||
|
var pointer = e.target.querySelector('.stick-pointer');
|
||||||
|
if (e.target.matches('.stick-left')) {
|
||||||
|
controlMessage.r = 0;
|
||||||
|
pointer.style.left = '50%';
|
||||||
|
} else if (e.target.matches('.stick-right')) {
|
||||||
|
controlMessage.x = 0;
|
||||||
|
controlMessage.y = 0;
|
||||||
|
pointer.style.left = '50%';
|
||||||
|
pointer.style.top = '50%';
|
||||||
|
}
|
||||||
|
rcPublishThrottled();
|
||||||
|
}
|
||||||
|
|
||||||
|
stickLeft.addEventListener('touchmove', stickTouchMove);
|
||||||
|
stickRight.addEventListener('touchmove', stickTouchMove);
|
||||||
|
stickLeft.addEventListener('touchstart', stickTouchStart);
|
||||||
|
stickRight.addEventListener('touchstart', stickTouchStart);
|
||||||
|
stickLeft.addEventListener('touchend', stickTouchEnd);
|
||||||
|
stickRight.addEventListener('touchend', stickTouchEnd);
|
||||||
3693
apps/android/app/src/main/assets/roslib.js
vendored
Normal file
115
apps/android/app/src/main/assets/telemetry.js
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
var url = 'ws://192.168.11.1:9090';
|
||||||
|
var modeEl = document.querySelector('.telemetry .mode');
|
||||||
|
var batteryEl = document.querySelector('.battery');
|
||||||
|
var notificationsEl = document.querySelector('.notifications');
|
||||||
|
|
||||||
|
var ros = new ROSLIB.Ros({ url: url });
|
||||||
|
|
||||||
|
ros.on('connection', function () {
|
||||||
|
body.classList.add('connected');
|
||||||
|
});
|
||||||
|
|
||||||
|
ros.on('close', function () {
|
||||||
|
body.classList.remove('connected');
|
||||||
|
modeEl.classList.remove('armed');
|
||||||
|
modeEl.innerHTML = 'DISCONNECTED';
|
||||||
|
batteryEl.innerHTML = '';
|
||||||
|
setTimeout(function() {
|
||||||
|
modeEl.innerHTML = 'RECONNECTING';
|
||||||
|
ros.connect(url);
|
||||||
|
}, 2000);
|
||||||
|
});
|
||||||
|
|
||||||
|
var fcuState;
|
||||||
|
|
||||||
|
new ROSLIB.Topic({
|
||||||
|
ros: ros,
|
||||||
|
name: '/state_latched',
|
||||||
|
messageType: 'mavros_msgs/State'
|
||||||
|
}).subscribe(function(message) {
|
||||||
|
body.classList.toggle('fcu-disconnected', !message.connected);
|
||||||
|
body.classList.toggle('armed', message.armed);
|
||||||
|
fcuState = message;
|
||||||
|
modeEl.classList.toggle('armed', fcuState.armed);
|
||||||
|
modeEl.innerHTML = message.connected ? fcuState.mode : 'DISCONNECTED FROM FCU';
|
||||||
|
console.log('state', message);
|
||||||
|
});
|
||||||
|
|
||||||
|
function notifyLowBattery() {
|
||||||
|
console.log('low battery');
|
||||||
|
callNativeApp('lowBattery');
|
||||||
|
body.classList.remove('low-battery');
|
||||||
|
void body.offsetWidth; // trick for repeating animation
|
||||||
|
body.classList.add('low-battery');
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyLowBatteryThrottled = throttle(notifyLowBattery, 15000);
|
||||||
|
|
||||||
|
new ROSLIB.Topic({
|
||||||
|
ros: ros,
|
||||||
|
name: '/mavros/battery',
|
||||||
|
messageType: 'sensor_msgs/BatteryState',
|
||||||
|
throttle_rate: 5000
|
||||||
|
}).subscribe(function(message) {
|
||||||
|
var LOW_BATTERY = 3.8;
|
||||||
|
batteryEl.innerHTML = (message.cell_voltage[0].toFixed(2) + ' V') || '';
|
||||||
|
|
||||||
|
if (message.cell_voltage[0] < LOW_BATTERY) {
|
||||||
|
notifyLowBatteryThrottled();
|
||||||
|
} else {
|
||||||
|
body.classList.remove('low-battery');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var notificationHideTimer;
|
||||||
|
|
||||||
|
function notify(text, severity) {
|
||||||
|
var item = document.createElement('div');
|
||||||
|
item.innerHTML = text;
|
||||||
|
item.classList.add('item');
|
||||||
|
notificationsEl.prepend(item);
|
||||||
|
var itemHeight = item.offsetHeight;
|
||||||
|
notificationsEl.classList.remove('anim');
|
||||||
|
notificationsEl.style.transform = 'translateY(' + -itemHeight + 'px)';
|
||||||
|
setTimeout(function() {
|
||||||
|
notificationsEl.classList.add('anim');
|
||||||
|
notificationsEl.style.transform = 'translateY(0)';
|
||||||
|
}, 0);
|
||||||
|
clearTimeout(notificationHideTimer);
|
||||||
|
notificationHideTimer = setTimeout(function() {
|
||||||
|
notificationsEl.style.transform = '';
|
||||||
|
notificationsEl.classList.add('hidden');
|
||||||
|
setTimeout(function() {
|
||||||
|
notificationsEl.innerHTML = '';
|
||||||
|
}, 210);
|
||||||
|
}, 4000);
|
||||||
|
}
|
||||||
|
|
||||||
|
new ROSLIB.Topic({
|
||||||
|
ros: ros,
|
||||||
|
name: '/mavros/statustext/recv',
|
||||||
|
messageType: 'mavros_msgs/StatusText'
|
||||||
|
}).subscribe(function(message) {
|
||||||
|
var BLACKLIST = ['CMD: ', 'PR: ', 'DROPPED', 'Clock skew detected', 'MANUAL CONTROL LOST'];
|
||||||
|
if (message.severity <= 4) {
|
||||||
|
if (BLACKLIST.some(function(e) {
|
||||||
|
return message.text.indexOf(e) != -1;
|
||||||
|
})) {
|
||||||
|
console.log('Filtered out message ' + message.text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
notify(message.text, message.severity);
|
||||||
|
callNativeApp('notification', message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var setMode = new ROSLIB.Service({
|
||||||
|
ros: ros,
|
||||||
|
name : '/mavros/set_mode',
|
||||||
|
serviceType : 'mavros_msgs/SetMode'
|
||||||
|
});
|
||||||
|
|
||||||
|
function setControlMode() {
|
||||||
|
var CONTROL_MODE = 'STABILIZED';
|
||||||
|
setMode.callService(new ROSLIB.ServiceRequest({ custom_mode: CONTROL_MODE }));
|
||||||
|
}
|
||||||
BIN
apps/android/app/src/main/ic_launcher-web.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
@@ -0,0 +1,86 @@
|
|||||||
|
package express.copter.cleverrc
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.Build
|
||||||
|
import android.support.v7.app.AppCompatActivity
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import android.view.WindowManager
|
||||||
|
import android.webkit.JavascriptInterface
|
||||||
|
import kotlinx.android.synthetic.main.activity_main.*
|
||||||
|
import org.json.JSONObject
|
||||||
|
import java.net.DatagramPacket
|
||||||
|
import java.net.DatagramSocket
|
||||||
|
import java.net.InetAddress
|
||||||
|
import java.nio.ByteBuffer
|
||||||
|
|
||||||
|
fun pack(x: Short, y: Short, z: Short, r: Short): ByteArray {
|
||||||
|
val pump_on_buf: ByteBuffer = ByteBuffer.allocate(8)
|
||||||
|
pump_on_buf.putShort(r)
|
||||||
|
pump_on_buf.putShort(z)
|
||||||
|
pump_on_buf.putShort(y)
|
||||||
|
pump_on_buf.putShort(x)
|
||||||
|
|
||||||
|
return pump_on_buf.array().reversedArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun send(host: String, port: Int, data: ByteArray, senderPort: Int = 0): Boolean {
|
||||||
|
var ret = false
|
||||||
|
var socket: DatagramSocket? = null
|
||||||
|
try {
|
||||||
|
socket = DatagramSocket(senderPort)
|
||||||
|
val address = InetAddress.getByName(host)
|
||||||
|
val packet = DatagramPacket(data, data.size, address, port)
|
||||||
|
socket.send(packet)
|
||||||
|
ret = true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
} finally {
|
||||||
|
socket?.close()
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_main)
|
||||||
|
fullScreenCall()
|
||||||
|
main_web.loadUrl("file:///android_asset/index.html")
|
||||||
|
|
||||||
|
main_web.settings.apply {
|
||||||
|
domStorageEnabled = true
|
||||||
|
javaScriptEnabled = true
|
||||||
|
loadWithOverviewMode = true
|
||||||
|
useWideViewPort = true
|
||||||
|
setSupportZoom(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
main_web.addJavascriptInterface(WebAppInterface(this), "appInterface")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fullScreenCall() {
|
||||||
|
window.setFlags(
|
||||||
|
WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||||
|
WindowManager.LayoutParams.FLAG_FULLSCREEN
|
||||||
|
)
|
||||||
|
if (Build.VERSION.SDK_INT < 19) {
|
||||||
|
val v = this.window.decorView
|
||||||
|
v.systemUiVisibility = View.GONE
|
||||||
|
} else {
|
||||||
|
//for higher api versions.
|
||||||
|
val decorView = window.decorView
|
||||||
|
val uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||||
|
decorView.systemUiVisibility = uiOptions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class WebAppInterface(c: Context) {
|
||||||
|
@JavascriptInterface
|
||||||
|
public fun postMessage(message: String) {
|
||||||
|
val data = JSONObject(message)
|
||||||
|
send("255.255.255.255", 35602, pack(data.getInt("x").toShort(), data.getInt("y").toShort(), data.getInt("z").toShort(), data.getInt("r").toShort()))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:aapt="http://schemas.android.com/aapt"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportHeight="108"
|
||||||
|
android:viewportWidth="108">
|
||||||
|
<path
|
||||||
|
android:fillType="evenOdd"
|
||||||
|
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
|
||||||
|
android:strokeColor="#00000000"
|
||||||
|
android:strokeWidth="1">
|
||||||
|
<aapt:attr name="android:fillColor">
|
||||||
|
<gradient
|
||||||
|
android:endX="78.5885"
|
||||||
|
android:endY="90.9159"
|
||||||
|
android:startX="48.7653"
|
||||||
|
android:startY="61.0927"
|
||||||
|
android:type="linear">
|
||||||
|
<item
|
||||||
|
android:color="#44000000"
|
||||||
|
android:offset="0.0"/>
|
||||||
|
<item
|
||||||
|
android:color="#00000000"
|
||||||
|
android:offset="1.0"/>
|
||||||
|
</gradient>
|
||||||
|
</aapt:attr>
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:fillType="nonZero"
|
||||||
|
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
|
||||||
|
android:strokeColor="#00000000"
|
||||||
|
android:strokeWidth="1"/>
|
||||||
|
</vector>
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:height="108dp"
|
||||||
|
android:width="108dp"
|
||||||
|
android:viewportHeight="108"
|
||||||
|
android:viewportWidth="108">
|
||||||
|
<path android:fillColor="#008577"
|
||||||
|
android:pathData="M0,0h108v108h-108z"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
</vector>
|
||||||
14
apps/android/app/src/main/res/layout/activity_main.xml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".MainActivity">
|
||||||
|
|
||||||
|
<WebView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:id="@+id/main_web"/>
|
||||||
|
</FrameLayout>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/ic_launcher_background"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/ic_launcher_background"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
||||||
BIN
apps/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
BIN
apps/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
apps/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
BIN
apps/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
apps/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
BIN
apps/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
BIN
apps/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 8.8 KiB |
|
After Width: | Height: | Size: 8.8 KiB |
BIN
apps/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 13 KiB |
6
apps/android/app/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="colorPrimary">#fafafa</color>
|
||||||
|
<color name="colorPrimaryDark">#d1d1d1</color>
|
||||||
|
<color name="colorAccent">#757575</color>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="ic_launcher_background">#FFFFFF</color>
|
||||||
|
</resources>
|
||||||
3
apps/android/app/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name">CLEVER RC</string>
|
||||||
|
</resources>
|
||||||
18
apps/android/app/src/main/res/values/styles.xml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<resources>
|
||||||
|
|
||||||
|
<!-- Base application theme. -->
|
||||||
|
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||||
|
<!-- Customize your theme here. -->
|
||||||
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
|
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||||
|
<item name="colorAccent">@color/colorAccent</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="NoUiAppTheme"
|
||||||
|
parent="Theme.AppCompat.NoActionBar">
|
||||||
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
|
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||||
|
<item name="colorAccent">@color/colorAccent</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package express.copter.cleverrc
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import org.junit.Assert.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example local unit test, which will execute on the development machine (host).
|
||||||
|
*
|
||||||
|
* See [testing documentation](http://d.android.com/tools/testing).
|
||||||
|
*/
|
||||||
|
class ExampleUnitTest {
|
||||||
|
@Test
|
||||||
|
fun addition_isCorrect() {
|
||||||
|
assertEquals(4, 2 + 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
27
apps/android/build.gradle
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
ext.kotlin_version = '1.2.71'
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||||
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
|
||||||
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
|
// in the individual module build.gradle files
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task clean(type: Delete) {
|
||||||
|
delete rootProject.buildDir
|
||||||
|
}
|
||||||
15
apps/android/gradle.properties
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# Project-wide Gradle settings.
|
||||||
|
# IDE (e.g. Android Studio) users:
|
||||||
|
# Gradle settings configured through the IDE *will override*
|
||||||
|
# any settings specified in this file.
|
||||||
|
# For more details on how to configure your build environment visit
|
||||||
|
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||||
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
|
org.gradle.jvmargs=-Xmx1536m
|
||||||
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
|
# This option should only be used with decoupled projects. More details, visit
|
||||||
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||||
|
# org.gradle.parallel=true
|
||||||
|
# Kotlin code style for this project: "official" or "obsolete":
|
||||||
|
kotlin.code.style=official
|
||||||
BIN
apps/android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
5
apps/android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
172
apps/android/gradlew
vendored
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
NONSTOP* )
|
||||||
|
nonstop=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Escape application args
|
||||||
|
save () {
|
||||||
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
|
echo " "
|
||||||
|
}
|
||||||
|
APP_ARGS=$(save "$@")
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
|
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||||
|
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
||||||
84
apps/android/gradlew.bat
vendored
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS=
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windows variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
||||||
1
apps/android/settings.gradle
Normal file
@@ -0,0 +1 @@
|
|||||||
|
include ':app'
|
||||||
17
apps/ios/.gitignore
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Xcode
|
||||||
|
.DS_Store
|
||||||
|
build/
|
||||||
|
*.pbxuser
|
||||||
|
!default.pbxuser
|
||||||
|
*.mode1v3
|
||||||
|
!default.mode1v3
|
||||||
|
*.mode2v3
|
||||||
|
!default.mode2v3
|
||||||
|
*.perspectivev3
|
||||||
|
!default.perspectivev3
|
||||||
|
!default.xcworkspace
|
||||||
|
xcuserdata
|
||||||
|
profile
|
||||||
|
*.moved-aside
|
||||||
|
DerivedData
|
||||||
|
Pods/
|
||||||
13
apps/ios/Podfile
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
project 'cleverrc.xcodeproj/'
|
||||||
|
|
||||||
|
# Uncomment the next line to define a global platform for your project
|
||||||
|
# platform :ios, '9.0'
|
||||||
|
|
||||||
|
target 'cleverrc' do
|
||||||
|
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
|
||||||
|
use_frameworks!
|
||||||
|
|
||||||
|
# Pods for cleverrc
|
||||||
|
pod 'SwiftSocket', '~> 2.0'
|
||||||
|
|
||||||
|
end
|
||||||
12
apps/ios/Podfile.lock
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
PODS:
|
||||||
|
- SwiftSocket (2.0.2)
|
||||||
|
|
||||||
|
DEPENDENCIES:
|
||||||
|
- SwiftSocket (~> 2.0)
|
||||||
|
|
||||||
|
SPEC CHECKSUMS:
|
||||||
|
SwiftSocket: 6f4c9c63fbc5c1d61188936bb3c599fd546f40ae
|
||||||
|
|
||||||
|
PODFILE CHECKSUM: 2044f57d00f536792fbc38c63ded4fa78dcc135c
|
||||||
|
|
||||||
|
COCOAPODS: 1.4.0
|
||||||
10
apps/ios/README.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
iOS-приложение для управления Клевером
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
Для установки зависимостей необходим [CocoaPods](https://cocoapods.org):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pod install
|
||||||
|
```
|
||||||
|
|
||||||
|
Для разработки и сборки откройте в XCode файл `cleverrc.xcworkspace`.
|
||||||
444
apps/ios/cleverrc.xcodeproj/project.pbxproj
Normal file
@@ -0,0 +1,444 @@
|
|||||||
|
// !$*UTF8*$!
|
||||||
|
{
|
||||||
|
archiveVersion = 1;
|
||||||
|
classes = {
|
||||||
|
};
|
||||||
|
objectVersion = 48;
|
||||||
|
objects = {
|
||||||
|
|
||||||
|
/* Begin PBXBuildFile section */
|
||||||
|
7C0AB7AB202A744400BAED27 /* BinUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C0AB7AA202A744400BAED27 /* BinUtils.swift */; };
|
||||||
|
7C51654120139237004D1F4D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C51654020139237004D1F4D /* AppDelegate.swift */; };
|
||||||
|
7C51654320139237004D1F4D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C51654220139237004D1F4D /* ViewController.swift */; };
|
||||||
|
7C51654620139237004D1F4D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7C51654420139237004D1F4D /* Main.storyboard */; };
|
||||||
|
7C51654820139237004D1F4D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7C51654720139237004D1F4D /* Assets.xcassets */; };
|
||||||
|
7C51654B20139237004D1F4D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7C51654920139237004D1F4D /* LaunchScreen.storyboard */; };
|
||||||
|
7C516553201526BA004D1F4D /* index.html in Resources */ = {isa = PBXBuildFile; fileRef = 7C516552201526BA004D1F4D /* index.html */; };
|
||||||
|
7C51655520153180004D1F4D /* main.js in Resources */ = {isa = PBXBuildFile; fileRef = 7C51655420153180004D1F4D /* main.js */; };
|
||||||
|
7C7DECC2203CBCC4000C1C51 /* roslib.js in Resources */ = {isa = PBXBuildFile; fileRef = 7C45DCE9203A75A2009C73F5 /* roslib.js */; };
|
||||||
|
7CA401E22033CE17009FAA3B /* main.css in Resources */ = {isa = PBXBuildFile; fileRef = 7CA401E12033CE17009FAA3B /* main.css */; };
|
||||||
|
7CA401E42033FA34009FAA3B /* telemetry.js in Resources */ = {isa = PBXBuildFile; fileRef = 7CA401E32033FA34009FAA3B /* telemetry.js */; };
|
||||||
|
7CA401E6203471D9009FAA3B /* clever.svg in Resources */ = {isa = PBXBuildFile; fileRef = 7CA401E5203471D8009FAA3B /* clever.svg */; };
|
||||||
|
C25141CAF1A7125F3CE29DDC /* Pods_cleverrc.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C38C04523251039FF13DDCD /* Pods_cleverrc.framework */; };
|
||||||
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXFileReference section */
|
||||||
|
5C38C04523251039FF13DDCD /* Pods_cleverrc.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_cleverrc.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
7C0AB7AA202A744400BAED27 /* BinUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BinUtils.swift; sourceTree = "<group>"; };
|
||||||
|
7C45DCE9203A75A2009C73F5 /* roslib.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = roslib.js; sourceTree = "<group>"; };
|
||||||
|
7C51653D20139237004D1F4D /* cleverrc.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = cleverrc.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
7C51654020139237004D1F4D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
|
7C51654220139237004D1F4D /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
|
||||||
|
7C51654520139237004D1F4D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||||
|
7C51654720139237004D1F4D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
|
7C51654A20139237004D1F4D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||||
|
7C51654C20139237004D1F4D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
|
7C516552201526BA004D1F4D /* index.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = index.html; sourceTree = "<group>"; };
|
||||||
|
7C51655420153180004D1F4D /* main.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = main.js; sourceTree = "<group>"; };
|
||||||
|
7CA401E12033CE17009FAA3B /* main.css */ = {isa = PBXFileReference; lastKnownFileType = text.css; path = main.css; sourceTree = "<group>"; };
|
||||||
|
7CA401E32033FA34009FAA3B /* telemetry.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = telemetry.js; sourceTree = "<group>"; };
|
||||||
|
7CA401E5203471D8009FAA3B /* clever.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = clever.svg; sourceTree = "<group>"; };
|
||||||
|
AAC9195BF3A9BF6942EF4D0B /* Pods-cleverrc.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-cleverrc.release.xcconfig"; path = "Pods/Target Support Files/Pods-cleverrc/Pods-cleverrc.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
CB200F4B933204EA97E0E2E4 /* Pods-cleverrc.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-cleverrc.debug.xcconfig"; path = "Pods/Target Support Files/Pods-cleverrc/Pods-cleverrc.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
7C51653A20139237004D1F4D /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
C25141CAF1A7125F3CE29DDC /* Pods_cleverrc.framework in Frameworks */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXGroup section */
|
||||||
|
4FA3968F2242239E15A656D2 /* Pods */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
CB200F4B933204EA97E0E2E4 /* Pods-cleverrc.debug.xcconfig */,
|
||||||
|
AAC9195BF3A9BF6942EF4D0B /* Pods-cleverrc.release.xcconfig */,
|
||||||
|
);
|
||||||
|
name = Pods;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
66C638F0021EBE07741B26F3 /* Frameworks */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
5C38C04523251039FF13DDCD /* Pods_cleverrc.framework */,
|
||||||
|
);
|
||||||
|
name = Frameworks;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
7C51653420139237004D1F4D = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
66C638F0021EBE07741B26F3 /* Frameworks */,
|
||||||
|
4FA3968F2242239E15A656D2 /* Pods */,
|
||||||
|
7C51653E20139237004D1F4D /* Products */,
|
||||||
|
7C51653F20139237004D1F4D /* cleverrc */,
|
||||||
|
);
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
7C51653E20139237004D1F4D /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
7C51653D20139237004D1F4D /* cleverrc.app */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
7C51653F20139237004D1F4D /* cleverrc */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
7C45DCE9203A75A2009C73F5 /* roslib.js */,
|
||||||
|
7C51654020139237004D1F4D /* AppDelegate.swift */,
|
||||||
|
7C51654720139237004D1F4D /* Assets.xcassets */,
|
||||||
|
7C0AB7AA202A744400BAED27 /* BinUtils.swift */,
|
||||||
|
7C51654C20139237004D1F4D /* Info.plist */,
|
||||||
|
7C51654920139237004D1F4D /* LaunchScreen.storyboard */,
|
||||||
|
7C51654420139237004D1F4D /* Main.storyboard */,
|
||||||
|
7C51654220139237004D1F4D /* ViewController.swift */,
|
||||||
|
7CA401E5203471D8009FAA3B /* clever.svg */,
|
||||||
|
7C516552201526BA004D1F4D /* index.html */,
|
||||||
|
7CA401E12033CE17009FAA3B /* main.css */,
|
||||||
|
7C51655420153180004D1F4D /* main.js */,
|
||||||
|
7CA401E32033FA34009FAA3B /* telemetry.js */,
|
||||||
|
);
|
||||||
|
path = cleverrc;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXGroup section */
|
||||||
|
|
||||||
|
/* Begin PBXNativeTarget section */
|
||||||
|
7C51653C20139237004D1F4D /* cleverrc */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 7C51654F20139237004D1F4D /* Build configuration list for PBXNativeTarget "cleverrc" */;
|
||||||
|
buildPhases = (
|
||||||
|
9F096121C4A02BCE9D4FD1B9 /* [CP] Check Pods Manifest.lock */,
|
||||||
|
7C51653920139237004D1F4D /* Sources */,
|
||||||
|
7C51653A20139237004D1F4D /* Frameworks */,
|
||||||
|
7C51653B20139237004D1F4D /* Resources */,
|
||||||
|
A37DBBAD5E44E632F8A8A204 /* [CP] Embed Pods Frameworks */,
|
||||||
|
9BAB41D26FC0095C7C86B9DE /* [CP] Copy Pods Resources */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = cleverrc;
|
||||||
|
productName = cleverrc;
|
||||||
|
productReference = 7C51653D20139237004D1F4D /* cleverrc.app */;
|
||||||
|
productType = "com.apple.product-type.application";
|
||||||
|
};
|
||||||
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
|
/* Begin PBXProject section */
|
||||||
|
7C51653520139237004D1F4D /* Project object */ = {
|
||||||
|
isa = PBXProject;
|
||||||
|
attributes = {
|
||||||
|
LastSwiftUpdateCheck = 0920;
|
||||||
|
LastUpgradeCheck = 0930;
|
||||||
|
ORGANIZATIONNAME = "Copter Express";
|
||||||
|
TargetAttributes = {
|
||||||
|
7C51653C20139237004D1F4D = {
|
||||||
|
CreatedOnToolsVersion = 9.2;
|
||||||
|
ProvisioningStyle = Automatic;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
buildConfigurationList = 7C51653820139237004D1F4D /* Build configuration list for PBXProject "cleverrc" */;
|
||||||
|
compatibilityVersion = "Xcode 8.0";
|
||||||
|
developmentRegion = en;
|
||||||
|
hasScannedForEncodings = 0;
|
||||||
|
knownRegions = (
|
||||||
|
en,
|
||||||
|
Base,
|
||||||
|
);
|
||||||
|
mainGroup = 7C51653420139237004D1F4D;
|
||||||
|
productRefGroup = 7C51653E20139237004D1F4D /* Products */;
|
||||||
|
projectDirPath = "";
|
||||||
|
projectRoot = "";
|
||||||
|
targets = (
|
||||||
|
7C51653C20139237004D1F4D /* cleverrc */,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
/* End PBXProject section */
|
||||||
|
|
||||||
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
|
7C51653B20139237004D1F4D /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
7C51654B20139237004D1F4D /* LaunchScreen.storyboard in Resources */,
|
||||||
|
7CA401E6203471D9009FAA3B /* clever.svg in Resources */,
|
||||||
|
7CA401E42033FA34009FAA3B /* telemetry.js in Resources */,
|
||||||
|
7C7DECC2203CBCC4000C1C51 /* roslib.js in Resources */,
|
||||||
|
7C516553201526BA004D1F4D /* index.html in Resources */,
|
||||||
|
7C51654820139237004D1F4D /* Assets.xcassets in Resources */,
|
||||||
|
7CA401E22033CE17009FAA3B /* main.css in Resources */,
|
||||||
|
7C51654620139237004D1F4D /* Main.storyboard in Resources */,
|
||||||
|
7C51655520153180004D1F4D /* main.js in Resources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
|
9BAB41D26FC0095C7C86B9DE /* [CP] Copy Pods Resources */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
name = "[CP] Copy Pods Resources";
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-cleverrc/Pods-cleverrc-resources.sh\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
9F096121C4A02BCE9D4FD1B9 /* [CP] Check Pods Manifest.lock */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||||
|
"${PODS_ROOT}/Manifest.lock",
|
||||||
|
);
|
||||||
|
name = "[CP] Check Pods Manifest.lock";
|
||||||
|
outputPaths = (
|
||||||
|
"$(DERIVED_FILE_DIR)/Pods-cleverrc-checkManifestLockResult.txt",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
A37DBBAD5E44E632F8A8A204 /* [CP] Embed Pods Frameworks */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
"${SRCROOT}/Pods/Target Support Files/Pods-cleverrc/Pods-cleverrc-frameworks.sh",
|
||||||
|
"${BUILT_PRODUCTS_DIR}/SwiftSocket/SwiftSocket.framework",
|
||||||
|
);
|
||||||
|
name = "[CP] Embed Pods Frameworks";
|
||||||
|
outputPaths = (
|
||||||
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftSocket.framework",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-cleverrc/Pods-cleverrc-frameworks.sh\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
7C51653920139237004D1F4D /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
7C51654320139237004D1F4D /* ViewController.swift in Sources */,
|
||||||
|
7C51654120139237004D1F4D /* AppDelegate.swift in Sources */,
|
||||||
|
7C0AB7AB202A744400BAED27 /* BinUtils.swift in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXVariantGroup section */
|
||||||
|
7C51654420139237004D1F4D /* Main.storyboard */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
7C51654520139237004D1F4D /* Base */,
|
||||||
|
);
|
||||||
|
name = Main.storyboard;
|
||||||
|
path = .;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
7C51654920139237004D1F4D /* LaunchScreen.storyboard */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
7C51654A20139237004D1F4D /* Base */,
|
||||||
|
);
|
||||||
|
name = LaunchScreen.storyboard;
|
||||||
|
path = .;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXVariantGroup section */
|
||||||
|
|
||||||
|
/* Begin XCBuildConfiguration section */
|
||||||
|
7C51654D20139237004D1F4D /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_TESTABILITY = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"DEBUG=1",
|
||||||
|
"$(inherited)",
|
||||||
|
);
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 11.2;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
7C51654E20139237004D1F4D /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 11.2;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||||
|
VALIDATE_PRODUCT = YES;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
7C51655020139237004D1F4D /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = CB200F4B933204EA97E0E2E4 /* Pods-cleverrc.debug.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
DEVELOPMENT_TEAM = M8TDN3PAH2;
|
||||||
|
INFOPLIST_FILE = cleverrc/Info.plist;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = coex.cleverrc;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_VERSION = 4.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
7C51655120139237004D1F4D /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = AAC9195BF3A9BF6942EF4D0B /* Pods-cleverrc.release.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
DEVELOPMENT_TEAM = M8TDN3PAH2;
|
||||||
|
INFOPLIST_FILE = cleverrc/Info.plist;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = coex.cleverrc;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_VERSION = 4.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
|
/* Begin XCConfigurationList section */
|
||||||
|
7C51653820139237004D1F4D /* Build configuration list for PBXProject "cleverrc" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
7C51654D20139237004D1F4D /* Debug */,
|
||||||
|
7C51654E20139237004D1F4D /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
7C51654F20139237004D1F4D /* Build configuration list for PBXNativeTarget "cleverrc" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
7C51655020139237004D1F4D /* Debug */,
|
||||||
|
7C51655120139237004D1F4D /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
/* End XCConfigurationList section */
|
||||||
|
};
|
||||||
|
rootObject = 7C51653520139237004D1F4D /* Project object */;
|
||||||
|
}
|
||||||
7
apps/ios/cleverrc.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
<FileRef
|
||||||
|
location = "self:cleverrc.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
|
</Workspace>
|
||||||
10
apps/ios/cleverrc.xcworkspace/contents.xcworkspacedata
generated
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
<FileRef
|
||||||
|
location = "group:cleverrc.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
|
<FileRef
|
||||||
|
location = "group:Pods/Pods.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
|
</Workspace>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>IDEDidComputeMac32BitWarning</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
46
apps/ios/cleverrc/AppDelegate.swift
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
//
|
||||||
|
// AppDelegate.swift
|
||||||
|
// cleverrc
|
||||||
|
//
|
||||||
|
// Created by Oleg Kalachev on 20.01.2018.
|
||||||
|
// Copyright © 2018 Copter Express Technologies. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
@UIApplicationMain
|
||||||
|
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
|
|
||||||
|
var window: UIWindow?
|
||||||
|
|
||||||
|
|
||||||
|
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
|
||||||
|
// Override point for customization after application launch.
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func applicationWillResignActive(_ application: UIApplication) {
|
||||||
|
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
||||||
|
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
|
||||||
|
}
|
||||||
|
|
||||||
|
func applicationDidEnterBackground(_ application: UIApplication) {
|
||||||
|
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
||||||
|
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
||||||
|
}
|
||||||
|
|
||||||
|
func applicationWillEnterForeground(_ application: UIApplication) {
|
||||||
|
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
|
||||||
|
}
|
||||||
|
|
||||||
|
func applicationDidBecomeActive(_ application: UIApplication) {
|
||||||
|
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
||||||
|
}
|
||||||
|
|
||||||
|
func applicationWillTerminate(_ application: UIApplication) {
|
||||||
|
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"size" : "20x20",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "Icon-App-20x20@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "20x20",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "Icon-App-20x20@3x.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "29x29",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "Icon-App-29x29@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "29x29",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "Icon-App-29x29@3x.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "40x40",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "Icon-App-40x40@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "40x40",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "Icon-App-40x40@3x.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "60x60",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "Icon-App-60x60@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "60x60",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "Icon-App-60x60@3x.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "20x20",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "Icon-App-20x20@1x.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "20x20",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "Icon-App-20x20@2x-1.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "29x29",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "Icon-App-29x29@1x.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "29x29",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "Icon-App-29x29@2x-1.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "40x40",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "Icon-App-40x40@1x.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "40x40",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "Icon-App-40x40@2x-1.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "76x76",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "Icon-App-76x76@1x.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "76x76",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "Icon-App-76x76@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "83.5x83.5",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "Icon-App-83.5x83.5@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "1024x1024",
|
||||||
|
"idiom" : "ios-marketing",
|
||||||
|
"filename" : "ItunesArtwork@2x.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "24x24",
|
||||||
|
"idiom" : "watch",
|
||||||
|
"scale" : "2x",
|
||||||
|
"role" : "notificationCenter",
|
||||||
|
"subtype" : "38mm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "27.5x27.5",
|
||||||
|
"idiom" : "watch",
|
||||||
|
"scale" : "2x",
|
||||||
|
"role" : "notificationCenter",
|
||||||
|
"subtype" : "42mm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "29x29",
|
||||||
|
"idiom" : "watch",
|
||||||
|
"role" : "companionSettings",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "29x29",
|
||||||
|
"idiom" : "watch",
|
||||||
|
"role" : "companionSettings",
|
||||||
|
"scale" : "3x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "40x40",
|
||||||
|
"idiom" : "watch",
|
||||||
|
"scale" : "2x",
|
||||||
|
"role" : "appLauncher",
|
||||||
|
"subtype" : "38mm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "44x44",
|
||||||
|
"idiom" : "watch",
|
||||||
|
"scale" : "2x",
|
||||||
|
"role" : "longLook",
|
||||||
|
"subtype" : "42mm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "86x86",
|
||||||
|
"idiom" : "watch",
|
||||||
|
"scale" : "2x",
|
||||||
|
"role" : "quickLook",
|
||||||
|
"subtype" : "38mm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "98x98",
|
||||||
|
"idiom" : "watch",
|
||||||
|
"scale" : "2x",
|
||||||
|
"role" : "quickLook",
|
||||||
|
"subtype" : "42mm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "watch-marketing",
|
||||||
|
"size" : "1024x1024",
|
||||||
|
"scale" : "1x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
},
|
||||||
|
"properties" : {
|
||||||
|
"pre-rendered" : true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 638 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 9.6 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 26 KiB |
6
apps/ios/cleverrc/Assets.xcassets/Contents.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
||||||
29
apps/ios/cleverrc/Base.lproj/LaunchScreen.storyboard
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||||
|
<device id="retina4_7" orientation="portrait">
|
||||||
|
<adaptation id="fullscreen"/>
|
||||||
|
</device>
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="iOS"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
|
||||||
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<scenes>
|
||||||
|
<!--View Controller-->
|
||||||
|
<scene sceneID="EHf-IW-A2E">
|
||||||
|
<objects>
|
||||||
|
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||||
|
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<color key="backgroundColor" red="0.10586584359407425" green="0.10589186102151871" blue="0.10586420446634293" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
||||||
|
</view>
|
||||||
|
</viewController>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
<point key="canvasLocation" x="53" y="375"/>
|
||||||
|
</scene>
|
||||||
|
</scenes>
|
||||||
|
</document>
|
||||||
46
apps/ios/cleverrc/Base.lproj/Main.storyboard
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
|
||||||
|
<device id="retina4_7" orientation="landscape">
|
||||||
|
<adaptation id="fullscreen"/>
|
||||||
|
</device>
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="iOS"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
|
||||||
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<scenes>
|
||||||
|
<!--View Controller-->
|
||||||
|
<scene sceneID="tne-QT-ifu">
|
||||||
|
<objects>
|
||||||
|
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="cleverrc" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
|
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="667" height="375"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<wkWebView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dtJ-LN-BYT">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="667" height="375"/>
|
||||||
|
<color key="backgroundColor" red="0.12939286231994629" green="0.12942266464233398" blue="0.12939092516899109" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<wkWebViewConfiguration key="configuration">
|
||||||
|
<audiovisualMediaTypes key="mediaTypesRequiringUserActionForPlayback" none="YES"/>
|
||||||
|
<wkPreferences key="preferences"/>
|
||||||
|
</wkWebViewConfiguration>
|
||||||
|
</wkWebView>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" red="0.1097869947552681" green="0.10981365293264389" blue="0.10978532582521439" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="dtJ-LN-BYT" firstAttribute="height" secondItem="8bC-Xf-vdC" secondAttribute="height" id="KRn-ag-67x"/>
|
||||||
|
<constraint firstItem="dtJ-LN-BYT" firstAttribute="width" secondItem="8bC-Xf-vdC" secondAttribute="width" id="qOr-gg-e4M"/>
|
||||||
|
</constraints>
|
||||||
|
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
||||||
|
</view>
|
||||||
|
<connections>
|
||||||
|
<outlet property="webView" destination="dtJ-LN-BYT" id="bQ3-jy-o6E"/>
|
||||||
|
</connections>
|
||||||
|
</viewController>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
<point key="canvasLocation" x="138.0809595202399" y="124"/>
|
||||||
|
</scene>
|
||||||
|
</scenes>
|
||||||
|
</document>
|
||||||
453
apps/ios/cleverrc/BinUtils.swift
vendored
Normal file
@@ -0,0 +1,453 @@
|
|||||||
|
//
|
||||||
|
// BinUtils.swift
|
||||||
|
// BinUtils
|
||||||
|
//
|
||||||
|
// Created by Nicolas Seriot on 12/03/16.
|
||||||
|
// Copyright © 2016 Nicolas Seriot. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import CoreFoundation
|
||||||
|
|
||||||
|
// MARK: protocol UnpackedType
|
||||||
|
|
||||||
|
public protocol Unpackable {}
|
||||||
|
|
||||||
|
extension NSString: Unpackable {}
|
||||||
|
extension Bool: Unpackable {}
|
||||||
|
extension Int: Unpackable {}
|
||||||
|
extension Double: Unpackable {}
|
||||||
|
|
||||||
|
// MARK: protocol DataConvertible
|
||||||
|
|
||||||
|
protocol DataConvertible {}
|
||||||
|
|
||||||
|
extension DataConvertible {
|
||||||
|
|
||||||
|
init?(data: Data) {
|
||||||
|
guard data.count == MemoryLayout<Self>.size else { return nil }
|
||||||
|
self = data.withUnsafeBytes { $0.pointee }
|
||||||
|
}
|
||||||
|
|
||||||
|
init?(bytes: [UInt8]) {
|
||||||
|
let data = Data(bytes:bytes)
|
||||||
|
self.init(data:data)
|
||||||
|
}
|
||||||
|
|
||||||
|
var data: Data {
|
||||||
|
var value = self
|
||||||
|
return Data(buffer: UnsafeBufferPointer(start: &value, count: 1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Bool : DataConvertible { }
|
||||||
|
|
||||||
|
extension Int8 : DataConvertible { }
|
||||||
|
extension Int16 : DataConvertible { }
|
||||||
|
extension Int32 : DataConvertible { }
|
||||||
|
extension Int64 : DataConvertible { }
|
||||||
|
|
||||||
|
extension UInt8 : DataConvertible { }
|
||||||
|
extension UInt16 : DataConvertible { }
|
||||||
|
extension UInt32 : DataConvertible { }
|
||||||
|
extension UInt64 : DataConvertible { }
|
||||||
|
|
||||||
|
extension Float32 : DataConvertible { }
|
||||||
|
extension Float64 : DataConvertible { }
|
||||||
|
|
||||||
|
// MARK: String extension
|
||||||
|
|
||||||
|
extension String {
|
||||||
|
subscript (from:Int, to:Int) -> String {
|
||||||
|
return NSString(string: self).substring(with: NSMakeRange(from, to-from))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Data extension
|
||||||
|
|
||||||
|
extension Data {
|
||||||
|
var bytes : [UInt8] {
|
||||||
|
return self.withUnsafeBytes {
|
||||||
|
[UInt8](UnsafeBufferPointer(start: $0, count: self.count))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: functions
|
||||||
|
|
||||||
|
public func hexlify(_ data:Data) -> String {
|
||||||
|
|
||||||
|
// similar to hexlify() in Python's binascii module
|
||||||
|
// https://docs.python.org/2/library/binascii.html
|
||||||
|
|
||||||
|
var s = String()
|
||||||
|
var byte: UInt8 = 0
|
||||||
|
|
||||||
|
for i in 0 ..< data.count {
|
||||||
|
NSData(data: data).getBytes(&byte, range: NSMakeRange(i, 1))
|
||||||
|
s = s.appendingFormat("%02x", byte)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s as String
|
||||||
|
}
|
||||||
|
|
||||||
|
public func unhexlify(_ string:String) -> Data? {
|
||||||
|
|
||||||
|
// similar to unhexlify() in Python's binascii module
|
||||||
|
// https://docs.python.org/2/library/binascii.html
|
||||||
|
|
||||||
|
let s = string.uppercased().replacingOccurrences(of: " ", with: "")
|
||||||
|
|
||||||
|
let nonHexCharacterSet = CharacterSet(charactersIn: "0123456789ABCDEF").inverted
|
||||||
|
if let range = s.rangeOfCharacter(from: nonHexCharacterSet) {
|
||||||
|
print("-- found non hex character at range \(range)")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = Data(capacity: s.count / 2)
|
||||||
|
|
||||||
|
for i in stride(from: 0, to:s.count, by:2) {
|
||||||
|
let byteString = s[i, i+2]
|
||||||
|
let byte = UInt8(byteString.withCString { strtoul($0, nil, 16) })
|
||||||
|
data.append([byte] as [UInt8], count: 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
func readIntegerType<T:DataConvertible>(_ type:T.Type, bytes:[UInt8], loc:inout Int) -> T {
|
||||||
|
let size = MemoryLayout<T>.size
|
||||||
|
let sub = Array(bytes[loc..<(loc+size)])
|
||||||
|
loc += size
|
||||||
|
return T(bytes: sub)!
|
||||||
|
}
|
||||||
|
|
||||||
|
func readFloatingPointType<T:DataConvertible>(_ type:T.Type, bytes:[UInt8], loc:inout Int, isBigEndian:Bool) -> T {
|
||||||
|
let size = MemoryLayout<T>.size
|
||||||
|
let sub = Array(bytes[loc..<(loc+size)])
|
||||||
|
loc += size
|
||||||
|
let sub_ = isBigEndian ? sub.reversed() : sub
|
||||||
|
return T(bytes: sub_)!
|
||||||
|
}
|
||||||
|
|
||||||
|
func isBigEndianFromMandatoryByteOrderFirstCharacter(_ format:String) -> Bool {
|
||||||
|
|
||||||
|
guard let firstChar = format.first else { assertionFailure("empty format"); return false }
|
||||||
|
|
||||||
|
let s = NSString(string: String(firstChar))
|
||||||
|
let c = s.substring(to: 1)
|
||||||
|
|
||||||
|
if c == "@" { assertionFailure("native size and alignment is unsupported") }
|
||||||
|
|
||||||
|
if c == "=" || c == "<" { return false }
|
||||||
|
if c == ">" || c == "!" { return true }
|
||||||
|
|
||||||
|
assertionFailure("format '\(format)' first character must be among '=<>!'")
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// akin to struct.calcsize(fmt)
|
||||||
|
func numberOfBytesInFormat(_ format:String) -> Int {
|
||||||
|
|
||||||
|
var numberOfBytes = 0
|
||||||
|
|
||||||
|
var n = 0 // repeat counter
|
||||||
|
|
||||||
|
var mutableFormat = format
|
||||||
|
|
||||||
|
while !mutableFormat.isEmpty {
|
||||||
|
|
||||||
|
let c = mutableFormat.remove(at: mutableFormat.startIndex)
|
||||||
|
|
||||||
|
if let i = Int(String(c)) , 0...9 ~= i {
|
||||||
|
if n > 0 { n *= 10 }
|
||||||
|
n += i
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if c == "s" {
|
||||||
|
numberOfBytes += max(n,1)
|
||||||
|
n = 0
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _ in 0..<max(n,1) {
|
||||||
|
|
||||||
|
switch(c) {
|
||||||
|
|
||||||
|
case "@", "<", "=", ">", "!", " ":
|
||||||
|
()
|
||||||
|
case "c", "b", "B", "x", "?":
|
||||||
|
numberOfBytes += 1
|
||||||
|
case "h", "H":
|
||||||
|
numberOfBytes += 2
|
||||||
|
case "i", "l", "I", "L", "f":
|
||||||
|
numberOfBytes += 4
|
||||||
|
case "q", "Q", "d":
|
||||||
|
numberOfBytes += 8
|
||||||
|
case "P":
|
||||||
|
numberOfBytes += MemoryLayout<Int>.size
|
||||||
|
default:
|
||||||
|
assertionFailure("-- unsupported format \(c)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
n = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return numberOfBytes
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatDoesMatchDataLength(_ format:String, data:Data) -> Bool {
|
||||||
|
let sizeAccordingToFormat = numberOfBytesInFormat(format)
|
||||||
|
let dataLength = data.count
|
||||||
|
if sizeAccordingToFormat != dataLength {
|
||||||
|
print("format \"\(format)\" expects \(sizeAccordingToFormat) bytes but data is \(dataLength) bytes")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
pack() and unpack() should behave as Python's struct module https://docs.python.org/2/library/struct.html BUT:
|
||||||
|
- native size and alignment '@' is not supported
|
||||||
|
- as a consequence, the byte order specifier character is mandatory and must be among "=<>!"
|
||||||
|
- native byte order '=' assumes a little-endian system (eg. Intel x86)
|
||||||
|
- Pascal strings 'p' and native pointers 'P' are not supported
|
||||||
|
*/
|
||||||
|
|
||||||
|
public enum BinUtilsError: Error {
|
||||||
|
case formatDoesMatchDataLength(format:String, dataSize:Int)
|
||||||
|
case unsupportedFormat(character:Character)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func pack(_ format:String, _ objects:[Any], _ stringEncoding:String.Encoding=String.Encoding.windowsCP1252) -> Data {
|
||||||
|
|
||||||
|
var objectsQueue = objects
|
||||||
|
|
||||||
|
var mutableFormat = format
|
||||||
|
|
||||||
|
var mutableData = Data()
|
||||||
|
|
||||||
|
var isBigEndian = false
|
||||||
|
|
||||||
|
let firstCharacter = mutableFormat.remove(at: mutableFormat.startIndex)
|
||||||
|
|
||||||
|
switch(firstCharacter) {
|
||||||
|
case "<", "=":
|
||||||
|
isBigEndian = false
|
||||||
|
case ">", "!":
|
||||||
|
isBigEndian = true
|
||||||
|
case "@":
|
||||||
|
assertionFailure("native size and alignment '@' is unsupported'")
|
||||||
|
default:
|
||||||
|
assertionFailure("unsupported format chacracter'")
|
||||||
|
}
|
||||||
|
|
||||||
|
var n = 0 // repeat counter
|
||||||
|
|
||||||
|
while !mutableFormat.isEmpty {
|
||||||
|
|
||||||
|
let c = mutableFormat.remove(at: mutableFormat.startIndex)
|
||||||
|
|
||||||
|
if let i = Int(String(c)) , 0...9 ~= i {
|
||||||
|
if n > 0 { n *= 10 }
|
||||||
|
n += i
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var o : Any = 0
|
||||||
|
|
||||||
|
if c == "s" {
|
||||||
|
o = objectsQueue.remove(at: 0)
|
||||||
|
|
||||||
|
guard let stringData = (o as! String).data(using: .utf8) else { assertionFailure(); return Data() }
|
||||||
|
var bytes = stringData.bytes
|
||||||
|
|
||||||
|
let expectedSize = max(1, n)
|
||||||
|
|
||||||
|
// pad ...
|
||||||
|
while bytes.count < expectedSize { bytes.append(0x00) }
|
||||||
|
|
||||||
|
// ... or trunk
|
||||||
|
if bytes.count > expectedSize { bytes = Array(bytes[0..<expectedSize]) }
|
||||||
|
|
||||||
|
assert(bytes.count == expectedSize)
|
||||||
|
|
||||||
|
if isBigEndian { bytes = bytes.reversed() }
|
||||||
|
|
||||||
|
mutableData.append(bytes, count: bytes.count)
|
||||||
|
|
||||||
|
n = 0
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _ in 0..<max(n,1) {
|
||||||
|
|
||||||
|
var bytes : [UInt8] = []
|
||||||
|
|
||||||
|
if c != "x" {
|
||||||
|
o = objectsQueue.removeFirst()
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(c) {
|
||||||
|
case "?":
|
||||||
|
bytes = (o as! Bool) ? [0x01] : [0x00]
|
||||||
|
case "c":
|
||||||
|
let charAsString = (o as! NSString).substring(to: 1)
|
||||||
|
guard let data = charAsString.data(using: stringEncoding) else {
|
||||||
|
assertionFailure("cannot decode character \(charAsString) using encoding \(stringEncoding)")
|
||||||
|
return Data()
|
||||||
|
}
|
||||||
|
bytes = data.bytes
|
||||||
|
case "b":
|
||||||
|
bytes = Int8(truncatingIfNeeded:o as! Int).data.bytes
|
||||||
|
case "h":
|
||||||
|
bytes = Int16(truncatingIfNeeded:o as! Int).data.bytes
|
||||||
|
case "i", "l":
|
||||||
|
bytes = Int32(truncatingIfNeeded:o as! Int).data.bytes
|
||||||
|
case "q", "Q":
|
||||||
|
bytes = Int64(o as! Int).data.bytes
|
||||||
|
case "B":
|
||||||
|
bytes = UInt8(truncatingIfNeeded:o as! Int).data.bytes
|
||||||
|
case "H":
|
||||||
|
bytes = UInt16(truncatingIfNeeded:o as! Int).data.bytes
|
||||||
|
case "I", "L":
|
||||||
|
bytes = UInt32(truncatingIfNeeded:o as! Int).data.bytes
|
||||||
|
case "f":
|
||||||
|
bytes = Float32(o as! Double).data.bytes
|
||||||
|
case "d":
|
||||||
|
bytes = Float64(o as! Double).data.bytes
|
||||||
|
case "x":
|
||||||
|
bytes = [0x00]
|
||||||
|
default:
|
||||||
|
assertionFailure("Unsupported packing format: \(c)")
|
||||||
|
}
|
||||||
|
|
||||||
|
if isBigEndian { bytes = bytes.reversed() }
|
||||||
|
let data = Data(bytes)
|
||||||
|
mutableData.append(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
n = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return mutableData
|
||||||
|
}
|
||||||
|
|
||||||
|
public func unpack(_ format:String, _ data:Data, _ stringEncoding:String.Encoding=String.Encoding.windowsCP1252) throws -> [Unpackable] {
|
||||||
|
|
||||||
|
assert(CFByteOrderGetCurrent() == 1 /* CFByteOrderLittleEndian */, "\(#file) assumes little endian, but host is big endian")
|
||||||
|
|
||||||
|
let isBigEndian = isBigEndianFromMandatoryByteOrderFirstCharacter(format)
|
||||||
|
|
||||||
|
if formatDoesMatchDataLength(format, data: data) == false {
|
||||||
|
throw BinUtilsError.formatDoesMatchDataLength(format:format, dataSize:data.count)
|
||||||
|
}
|
||||||
|
|
||||||
|
var a : [Unpackable] = []
|
||||||
|
|
||||||
|
var loc = 0
|
||||||
|
|
||||||
|
let bytes = data.bytes
|
||||||
|
|
||||||
|
var n = 0 // repeat counter
|
||||||
|
|
||||||
|
var mutableFormat = format
|
||||||
|
|
||||||
|
mutableFormat.remove(at: mutableFormat.startIndex) // consume byte-order specifier
|
||||||
|
|
||||||
|
while !mutableFormat.isEmpty {
|
||||||
|
|
||||||
|
let c = mutableFormat.remove(at: mutableFormat.startIndex)
|
||||||
|
|
||||||
|
if let i = Int(String(c)) , 0...9 ~= i {
|
||||||
|
if n > 0 { n *= 10 }
|
||||||
|
n += i
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if c == "s" {
|
||||||
|
let length = max(n,1)
|
||||||
|
let sub = Array(bytes[loc..<loc+length])
|
||||||
|
|
||||||
|
guard let s = NSString(bytes: sub, length: length, encoding: stringEncoding.rawValue) else {
|
||||||
|
assertionFailure("-- not a string: \(sub)")
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
a.append(s)
|
||||||
|
|
||||||
|
loc += length
|
||||||
|
|
||||||
|
n = 0
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _ in 0..<max(n,1) {
|
||||||
|
|
||||||
|
var o : Unpackable?
|
||||||
|
|
||||||
|
switch(c) {
|
||||||
|
|
||||||
|
case "c":
|
||||||
|
let optionalString = NSString(bytes: [bytes[loc]], length: 1, encoding: String.Encoding.utf8.rawValue)
|
||||||
|
loc += 1
|
||||||
|
guard let s = optionalString else { assertionFailure(); return [] }
|
||||||
|
o = s
|
||||||
|
case "b":
|
||||||
|
let r = readIntegerType(Int8.self, bytes:bytes, loc:&loc)
|
||||||
|
o = Int(r)
|
||||||
|
case "B":
|
||||||
|
let r = readIntegerType(UInt8.self, bytes:bytes, loc:&loc)
|
||||||
|
o = Int(r)
|
||||||
|
case "?":
|
||||||
|
let r = readIntegerType(Bool.self, bytes:bytes, loc:&loc)
|
||||||
|
o = r ? true : false
|
||||||
|
case "h":
|
||||||
|
let r = readIntegerType(Int16.self, bytes:bytes, loc:&loc)
|
||||||
|
o = Int(isBigEndian ? Int16(bigEndian: r) : r)
|
||||||
|
case "H":
|
||||||
|
let r = readIntegerType(UInt16.self, bytes:bytes, loc:&loc)
|
||||||
|
o = Int(isBigEndian ? UInt16(bigEndian: r) : r)
|
||||||
|
case "i":
|
||||||
|
fallthrough
|
||||||
|
case "l":
|
||||||
|
let r = readIntegerType(Int32.self, bytes:bytes, loc:&loc)
|
||||||
|
o = Int(isBigEndian ? Int32(bigEndian: r) : r)
|
||||||
|
case "I":
|
||||||
|
fallthrough
|
||||||
|
case "L":
|
||||||
|
let r = readIntegerType(UInt32.self, bytes:bytes, loc:&loc)
|
||||||
|
o = Int(isBigEndian ? UInt32(bigEndian: r) : r)
|
||||||
|
case "q":
|
||||||
|
let r = readIntegerType(Int64.self, bytes:bytes, loc:&loc)
|
||||||
|
o = Int(isBigEndian ? Int64(bigEndian: r) : r)
|
||||||
|
case "Q":
|
||||||
|
let r = readIntegerType(UInt64.self, bytes:bytes, loc:&loc)
|
||||||
|
o = Int(isBigEndian ? UInt64(bigEndian: r) : r)
|
||||||
|
case "f":
|
||||||
|
let r = readFloatingPointType(Float32.self, bytes:bytes, loc:&loc, isBigEndian:isBigEndian)
|
||||||
|
o = Double(r)
|
||||||
|
case "d":
|
||||||
|
let r = readFloatingPointType(Float64.self, bytes:bytes, loc:&loc, isBigEndian:isBigEndian)
|
||||||
|
o = Double(r)
|
||||||
|
case "x":
|
||||||
|
loc += 1
|
||||||
|
case " ":
|
||||||
|
()
|
||||||
|
default:
|
||||||
|
throw BinUtilsError.unsupportedFormat(character:c)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let o = o { a.append(o) }
|
||||||
|
}
|
||||||
|
|
||||||
|
n = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return a
|
||||||
|
}
|
||||||
46
apps/ios/cleverrc/Info.plist
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
|
<key>CFBundleDisplayName</key>
|
||||||
|
<string>CLEVER RC</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>$(PRODUCT_NAME)</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.1</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>6</string>
|
||||||
|
<key>LSRequiresIPhoneOS</key>
|
||||||
|
<true/>
|
||||||
|
<key>UILaunchStoryboardName</key>
|
||||||
|
<string>LaunchScreen</string>
|
||||||
|
<key>UIMainStoryboardFile</key>
|
||||||
|
<string>Main</string>
|
||||||
|
<key>UIRequiredDeviceCapabilities</key>
|
||||||
|
<array>
|
||||||
|
<string>armv7</string>
|
||||||
|
</array>
|
||||||
|
<key>UISupportedInterfaceOrientations</key>
|
||||||
|
<array>
|
||||||
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
|
</array>
|
||||||
|
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||||
|
<array>
|
||||||
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
|
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
10
apps/ios/cleverrc/README.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
iOS-приложение для управления Клевером
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
Для установки зависимостей необходим [CocoaPods](https://cocoapods.org):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pod install
|
||||||
|
```
|
||||||
|
|
||||||
|
Для разработки и сборки откройте в XCode файл `cleverrc.xcworkspace`.
|
||||||
85
apps/ios/cleverrc/ViewController.swift
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
//
|
||||||
|
// ViewController.swift
|
||||||
|
// cleverrc
|
||||||
|
//
|
||||||
|
// Created by Oleg Kalachev on 20.01.2018.
|
||||||
|
// Copyright © 2018 Copter Express Technologies. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import WebKit
|
||||||
|
import SwiftSocket
|
||||||
|
import AudioToolbox.AudioServices
|
||||||
|
|
||||||
|
class ViewController: UIViewController, WKScriptMessageHandler {
|
||||||
|
@IBOutlet weak var webView: WKWebView!
|
||||||
|
let impactGenerator = UIImpactFeedbackGenerator(style: .medium)
|
||||||
|
let notificationGenerator = UINotificationFeedbackGenerator()
|
||||||
|
let udpSocket = UDPClient(address: "255.255.255.255", port: 35602)
|
||||||
|
|
||||||
|
override func viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
// Don't lock screen
|
||||||
|
UIApplication.shared.isIdleTimerDisabled = true
|
||||||
|
|
||||||
|
// Setup webview event handlers
|
||||||
|
webView.scrollView.bounces = false;
|
||||||
|
webView.configuration.userContentController.add(self, name: "control")
|
||||||
|
webView.configuration.userContentController.add(self, name: "controlStart")
|
||||||
|
webView.configuration.userContentController.add(self, name: "lowBattery")
|
||||||
|
webView.configuration.userContentController.add(self, name: "notification")
|
||||||
|
|
||||||
|
// Load the main page
|
||||||
|
let url = Bundle.main.url(forResource: "index", withExtension: "html")
|
||||||
|
let requestObj = URLRequest(url: url!)
|
||||||
|
webView.load(requestObj)
|
||||||
|
|
||||||
|
// Setup UDP broadcasting
|
||||||
|
udpSocket.enableBroadcast()
|
||||||
|
|
||||||
|
// Set UDP broadcasting interface
|
||||||
|
var wifiInterface = if_nametoindex("en0");
|
||||||
|
setsockopt(udpSocket.fd!, IPPROTO_IP, IP_BOUND_IF, &wifiInterface, socklen_t(MemoryLayout<UInt32>.size));
|
||||||
|
}
|
||||||
|
|
||||||
|
override func didReceiveMemoryWarning() {
|
||||||
|
super.didReceiveMemoryWarning()
|
||||||
|
// Dispose of any resources that can be recreated.
|
||||||
|
}
|
||||||
|
|
||||||
|
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
||||||
|
if (message.name == "control") {
|
||||||
|
// Send UDP control message
|
||||||
|
let m = message.body as! NSDictionary;
|
||||||
|
let d = pack("<hhhh", [m["x"]!, m["y"]!, m["z"]!, m["r"]!])
|
||||||
|
_ = udpSocket.send(data: d)
|
||||||
|
} else if (message.name == "lowBattery") {
|
||||||
|
// Got low battery notification
|
||||||
|
print("Low battery notification")
|
||||||
|
tapticNotify()
|
||||||
|
} else if (message.name == "notification") {
|
||||||
|
// Got notification message
|
||||||
|
print(message)
|
||||||
|
tapticNotify()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func tapticNotify() {
|
||||||
|
if let feedbackSupportLevel = UIDevice.current.value(forKey: "_feedbackSupportLevel") as? Int {
|
||||||
|
switch feedbackSupportLevel {
|
||||||
|
case 2:
|
||||||
|
// 2nd Generation Taptic Engine w/ Haptic Feedback (iPhone 7/7+)
|
||||||
|
notificationGenerator.notificationOccurred(.warning)
|
||||||
|
case 1:
|
||||||
|
// 1st Generation Taptic Engine (iPhone 6S/6S+)
|
||||||
|
let peek = SystemSoundID(1519)
|
||||||
|
AudioServicesPlaySystemSound(peek)
|
||||||
|
case 0:
|
||||||
|
// No Taptic Engine
|
||||||
|
break
|
||||||
|
default: break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||