Compare commits
2273 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9f0e61c5b | ||
|
|
d2f5485996 | ||
|
|
e20b2844fb | ||
|
|
e9bc6a572b | ||
|
|
bb8d07274f | ||
|
|
950029884c | ||
|
|
7c78e557ed | ||
|
|
78eb5c48d7 | ||
|
|
96fd33065a | ||
|
|
abcbf5fa00 | ||
|
|
378174c277 | ||
|
|
39466f157c | ||
|
|
d1fa51c2bb | ||
|
|
a0e16fc4f9 | ||
|
|
f64da62aa8 | ||
|
|
75185cb50b | ||
|
|
bf9b34b47f | ||
|
|
6573a5cc8a | ||
|
|
7c3ca2a0fc | ||
|
|
e8214393e9 | ||
|
|
f4f9496fda | ||
|
|
c68361719d | ||
|
|
936fcb79fa | ||
|
|
65ff972d1a | ||
|
|
9ff8ae2587 | ||
|
|
c0dd64c71c | ||
|
|
f3fbbb3720 | ||
|
|
5279fbba56 | ||
|
|
bbbbfeda12 | ||
|
|
75ba99d9d1 | ||
|
|
af4603d87b | ||
|
|
1cb9e2fd29 | ||
|
|
d5b1b3fd5f | ||
|
|
f0776becff | ||
|
|
03fea45166 | ||
|
|
905b2c3c42 | ||
|
|
21619e72dc | ||
|
|
33742bca6b | ||
|
|
e0575fc179 | ||
|
|
97fe5fa496 | ||
|
|
97533cd4aa | ||
|
|
a7672168c6 | ||
|
|
5c46ca648d | ||
|
|
38c7bc0d0d | ||
|
|
cb2798cba9 | ||
|
|
f0342b852b | ||
|
|
97346617a5 | ||
|
|
ecdc018fa1 | ||
|
|
cbcbe3e8c8 | ||
|
|
b12c5ed12b | ||
|
|
96921b255f | ||
|
|
2df1077ee4 | ||
|
|
4937ddb09c | ||
|
|
4b00a06a88 | ||
|
|
be48e78a6f | ||
|
|
b7a3663078 | ||
|
|
9c364b482e | ||
|
|
355c5e584b | ||
|
|
f956fd93d5 | ||
|
|
69e285d3ca | ||
|
|
728fed2ed3 | ||
|
|
bc0d2264a3 | ||
|
|
ba8a6bf76c | ||
|
|
2cf84a796d | ||
|
|
ba62ae27af | ||
|
|
e35895d752 | ||
|
|
cc192cab44 | ||
|
|
e36792b76a | ||
|
|
61231ab99e | ||
|
|
ae2ee0e61e | ||
|
|
a339f0fd0c | ||
|
|
b9c3c3506e | ||
|
|
44d96264fb | ||
|
|
19eab0418a | ||
|
|
0695bbaa70 | ||
|
|
8d6b207833 | ||
|
|
3371a42822 | ||
|
|
fe712318b8 | ||
|
|
593d8327b2 | ||
|
|
d5c54b770f | ||
|
|
32a9a21be1 | ||
|
|
e0735f8928 | ||
|
|
c6dc962134 | ||
|
|
e068103e4d | ||
|
|
6eb5ade9ea | ||
|
|
c40168cacd | ||
|
|
a546b75986 | ||
|
|
8686ecfa54 | ||
|
|
270c48a1dd | ||
|
|
fdbec2cbac | ||
|
|
46049fd15c | ||
|
|
a81fe6ff7f | ||
|
|
fd4e8ecb01 | ||
|
|
8142e5e79e | ||
|
|
0c71772953 | ||
|
|
d54bc21441 | ||
|
|
be4bca2c15 | ||
|
|
2bd54673de | ||
|
|
4a3359f773 | ||
|
|
c35095f90e | ||
|
|
32abccd8c2 | ||
|
|
5d68ca3e18 | ||
|
|
8efa5335b0 | ||
|
|
4710bb16d8 | ||
|
|
db4f3e4e1b | ||
|
|
e18272a6d7 | ||
|
|
85aed9ce9d | ||
|
|
d03f93166f | ||
|
|
a3b1a433c6 | ||
|
|
608f63bc9c | ||
|
|
a4c118648a | ||
|
|
42866b8e4f | ||
|
|
0b7455b74f | ||
|
|
eab7bc3f5f | ||
|
|
af2623d16c | ||
|
|
e683034e77 | ||
|
|
ffa979ddc8 | ||
|
|
8a8c8a5699 | ||
|
|
2aea956fd0 | ||
|
|
1803517943 | ||
|
|
49c8081f68 | ||
|
|
3d64ca37e7 | ||
|
|
ccc88745a6 | ||
|
|
0bf6dbd402 | ||
|
|
b9abb4ce47 | ||
|
|
ad0c0f37c9 | ||
|
|
4c6257c145 | ||
|
|
6c5231dbff | ||
|
|
0454bb9b3c | ||
|
|
021f89da29 | ||
|
|
2ccca633ed | ||
|
|
fe15e025aa | ||
|
|
9e0c416db5 | ||
|
|
fa9b84a9c9 | ||
|
|
b3b1bd7bc8 | ||
|
|
91e806a619 | ||
|
|
6df6eefd3d | ||
|
|
ae35d05649 | ||
|
|
72939db2df | ||
|
|
b6f5770dc2 | ||
|
|
c1e7faa7bf | ||
|
|
37a18eae9c | ||
|
|
010bc5e328 | ||
|
|
a166051781 | ||
|
|
c2341d6697 | ||
|
|
03bba4259e | ||
|
|
80844580df | ||
|
|
a8790b9835 | ||
|
|
36262ff166 | ||
|
|
98d67be9d9 | ||
|
|
131f077c3f | ||
|
|
2c428ef099 | ||
|
|
08887cd6ed | ||
|
|
f786a29b70 | ||
|
|
d3f1d7f378 | ||
|
|
c48a31fd63 | ||
|
|
1217f06324 | ||
|
|
4cc3197be8 | ||
|
|
eb940d5968 | ||
|
|
6381389cac | ||
|
|
ab939e859a | ||
|
|
9bdc71c487 | ||
|
|
56a4abfaff | ||
|
|
769bc7f109 | ||
|
|
a587847e41 | ||
|
|
bda4650de8 | ||
|
|
4f0af93b72 | ||
|
|
4a656268b8 | ||
|
|
2ad9d5990f | ||
|
|
32585bc453 | ||
|
|
66307d4545 | ||
|
|
8b9ae2734f | ||
|
|
96f9e12d93 | ||
|
|
43c4e13c11 | ||
|
|
27f6168a29 | ||
|
|
70dbbc93f4 | ||
|
|
92c9808bfb | ||
|
|
1f8df84b87 | ||
|
|
271c1bcd51 | ||
|
|
f830b1199a | ||
|
|
b80d48aa91 | ||
|
|
691d835d16 | ||
|
|
3ac6d0ff5f | ||
|
|
68b32a20a4 | ||
|
|
88e4df4388 | ||
|
|
3e13980870 | ||
|
|
dd23af7051 | ||
|
|
7d5fc6de12 | ||
|
|
28233fbe58 | ||
|
|
32a35c6706 | ||
|
|
228ddace91 | ||
|
|
f9ffdbbce7 | ||
|
|
9b233683a2 | ||
|
|
ff78fb6b30 | ||
|
|
8efda6478c | ||
|
|
851c7871e3 | ||
|
|
a78c78f3e5 | ||
|
|
05e8442ff1 | ||
|
|
977b842df3 | ||
|
|
5bde54aac1 | ||
|
|
0f27e3ea42 | ||
|
|
d170725f0c | ||
|
|
a26fcf0cd8 | ||
|
|
18a4455511 | ||
|
|
2ab3286d0e | ||
|
|
d4a411ab4a | ||
|
|
c7facb38b1 | ||
|
|
b7434e9eaf | ||
|
|
4a174c0084 | ||
|
|
db8ad1e8eb | ||
|
|
1feaac003a | ||
|
|
c42b2fb34c | ||
|
|
5d48fa93ba | ||
|
|
527ac04c4e | ||
|
|
9644163dc5 | ||
|
|
d0090abd01 | ||
|
|
918d2ad156 | ||
|
|
b028fb955f | ||
|
|
ba33d5a39b | ||
|
|
fd0b9c55fc | ||
|
|
b28fb5c9b4 | ||
|
|
77ecd4be9b | ||
|
|
6f74003e14 | ||
|
|
63b2c2fb2f | ||
|
|
08da7a37e6 | ||
|
|
6b87a8d91b | ||
|
|
0f1364a8d7 | ||
|
|
9dbf70780d | ||
|
|
58e5592c2b | ||
|
|
02cc842cc8 | ||
|
|
e962e866b3 | ||
|
|
af3b30096d | ||
|
|
aa7ab86b62 | ||
|
|
7f864a9e35 | ||
|
|
609d345443 | ||
|
|
426815fa50 | ||
|
|
5d1b1e48d7 | ||
|
|
28d0412adc | ||
|
|
9d070b3671 | ||
|
|
cd423752d1 | ||
|
|
1f8a0eaf67 | ||
|
|
42d9fcd8b0 | ||
|
|
4e1510c840 | ||
|
|
7ebfd43f65 | ||
|
|
41d6157116 | ||
|
|
f9f8297fd6 | ||
|
|
dfbe3f665a | ||
|
|
b36df472e5 | ||
|
|
0b147f708d | ||
|
|
4e3bdbcc74 | ||
|
|
0345419ef3 | ||
|
|
9237dbbc18 | ||
|
|
68ac1b7641 | ||
|
|
2cfe4d29ba | ||
|
|
b436497555 | ||
|
|
7ac638c52c | ||
|
|
f21d2bc7c7 | ||
|
|
550917bd16 | ||
|
|
c1c0311586 | ||
|
|
489bbb6902 | ||
|
|
86af25bde3 | ||
|
|
a599e0716f | ||
|
|
30fc818771 | ||
|
|
df08f677bd | ||
|
|
7247bcad1b | ||
|
|
c0bcac25ea | ||
|
|
ae06019bdb | ||
|
|
432861780a | ||
|
|
111ee88833 | ||
|
|
487ee7015e | ||
|
|
061cc16c27 | ||
|
|
af8d9dff2d | ||
|
|
cb16bd0324 | ||
|
|
acf8171617 | ||
|
|
da7429f03e | ||
|
|
4a121db39d | ||
|
|
0e8e287fe2 | ||
|
|
cf942121dd | ||
|
|
77c2e962ec | ||
|
|
05f5cc4fe8 | ||
|
|
684f09feaf | ||
|
|
38bea3ced1 | ||
|
|
6a6f9a53bd | ||
|
|
584c12e60f | ||
|
|
bb5b667613 | ||
|
|
0628d3533f | ||
|
|
e1bd4c9a0a | ||
|
|
85c9ec38db | ||
|
|
6ff7cfde11 | ||
|
|
c52034f992 | ||
|
|
b982dd90e4 | ||
|
|
80e36688e8 | ||
|
|
c6c1071d2d | ||
|
|
481817c607 | ||
|
|
2e5739f042 | ||
|
|
0bb9f5ece5 | ||
|
|
d454f51993 | ||
|
|
7f3ab31ad5 | ||
|
|
98fe433819 | ||
|
|
4b01326420 | ||
|
|
3a4acd2693 | ||
|
|
b8e9937083 | ||
|
|
72d44ec783 | ||
|
|
680b60cb07 | ||
|
|
45527b320d | ||
|
|
0acc9a553e | ||
|
|
19f81cf379 | ||
|
|
96ddbdf0f0 | ||
|
|
9eb87911a6 | ||
|
|
b0881726fa | ||
|
|
308248d8ec | ||
|
|
de5ea4f0aa | ||
|
|
305ce6ff11 | ||
|
|
bd4dbb55e4 | ||
|
|
1fefb2bcaf | ||
|
|
e094e80ecf | ||
|
|
9715db1229 | ||
|
|
3c0daa2bf1 | ||
|
|
435fec2f1c | ||
|
|
69ba619f24 | ||
|
|
b7bb21f091 | ||
|
|
77f51a3e9f | ||
|
|
7799e511e8 | ||
|
|
416f4a4dee | ||
|
|
2fd5158839 | ||
|
|
b8287acff3 | ||
|
|
53b470ed09 | ||
|
|
8a20b773fb | ||
|
|
aa576fe7db | ||
|
|
582321c1ae | ||
|
|
541f5041fb | ||
|
|
d16babefbe | ||
|
|
4ac6768b7a | ||
|
|
97d3d3c616 | ||
|
|
2ee7572634 | ||
|
|
8e7fd1ecef | ||
|
|
6b4e6533f5 | ||
|
|
b680a89033 | ||
|
|
ee6a6f4b94 | ||
|
|
6933baafca | ||
|
|
0f3a6782b8 | ||
|
|
f99cc021f8 | ||
|
|
e4de4b8c1b | ||
|
|
793b5a679c | ||
|
|
1b75cf822d | ||
|
|
60604020c7 | ||
|
|
09780d02e3 | ||
|
|
4760f79ab5 | ||
|
|
05363a0d22 | ||
|
|
49797f891c | ||
|
|
9d38fe6764 | ||
|
|
f340b18408 | ||
|
|
358c449b17 | ||
|
|
1f6a6bbb39 | ||
|
|
10028cf500 | ||
|
|
a977458881 | ||
|
|
dc811d8b84 | ||
|
|
5bc119bd9d | ||
|
|
9016796497 | ||
|
|
32f47aaa34 | ||
|
|
c54b38a068 | ||
|
|
a9a708d0f6 | ||
|
|
ab3f118588 | ||
|
|
87852acb14 | ||
|
|
65ab26365d | ||
|
|
e7630e98d9 | ||
|
|
9779c1ebee | ||
|
|
9cef7e3370 | ||
|
|
b6bc545e7d | ||
|
|
85326be7bb | ||
|
|
75750ad38d | ||
|
|
0522114c5d | ||
|
|
6300236cdb | ||
|
|
1dbb950b3c | ||
|
|
bfd2ecd26c | ||
|
|
e60c2f5f19 | ||
|
|
274f71615f | ||
|
|
cd7d5ed665 | ||
|
|
703327ed41 | ||
|
|
a7ce24c84b | ||
|
|
c3c42e33ee | ||
|
|
530ace6b81 | ||
|
|
5345b001e8 | ||
|
|
07c9e2f675 | ||
|
|
7a08cb5ddd | ||
|
|
9c0ae12959 | ||
|
|
1e03791e82 | ||
|
|
d92e34949c | ||
|
|
c8423c0b4f | ||
|
|
2c1b4acfcc | ||
|
|
b14883c9af | ||
|
|
53245e9e4f | ||
|
|
45fc8c77b6 | ||
|
|
9d8fe4be06 | ||
|
|
03781ea692 | ||
|
|
3c28c4861b | ||
|
|
0c986ee68c | ||
|
|
17d45d7406 | ||
|
|
07ed408129 | ||
|
|
c001803d71 | ||
|
|
4ce54ea395 | ||
|
|
2039431735 | ||
|
|
15c9207542 | ||
|
|
79d8d79b9d | ||
|
|
806925333f | ||
|
|
2e196656ba | ||
|
|
55204df130 | ||
|
|
627c50910c | ||
|
|
959e11b77c | ||
|
|
6cc9da338b | ||
|
|
1cd93344dd | ||
|
|
7893814da4 | ||
|
|
da2d3237b6 | ||
|
|
431b04a011 | ||
|
|
f13c6f0153 | ||
|
|
160693f608 | ||
|
|
b127a1e98c | ||
|
|
b0a9cd70ac | ||
|
|
5955831809 | ||
|
|
b13f10d624 | ||
|
|
47635c95e1 | ||
|
|
c238d49584 | ||
|
|
2ff6455231 | ||
|
|
110db561a9 | ||
|
|
61013e9d2d | ||
|
|
2de6d1c5f1 | ||
|
|
991e453881 | ||
|
|
edcf501a22 | ||
|
|
1fc5cf0aa5 | ||
|
|
ce072ae9d3 | ||
|
|
a811b1da1a | ||
|
|
1de087eac7 | ||
|
|
2337a3e8a3 | ||
|
|
1637ae4d17 | ||
|
|
f46a08fe89 | ||
|
|
2c0d2c4497 | ||
|
|
f75eeb07be | ||
|
|
965a1d03ba | ||
|
|
12f947ed2e | ||
|
|
97d684fde1 | ||
|
|
75c1069251 | ||
|
|
050b641d79 | ||
|
|
e9539b5c5c | ||
|
|
6fc5a47970 | ||
|
|
11317154f6 | ||
|
|
98b4abfa19 | ||
|
|
f40f019d2e | ||
|
|
42109ce000 | ||
|
|
a38df1280b | ||
|
|
e19002caca | ||
|
|
b67d99e5a5 | ||
|
|
15942a7b96 | ||
|
|
cac2d0e050 | ||
|
|
7d504f9231 | ||
|
|
c0f78b023f | ||
|
|
3803ab045c | ||
|
|
bee2790af3 | ||
|
|
182a3076fc | ||
|
|
a9bcb71afe | ||
|
|
4f5baa1ac8 | ||
|
|
323743e426 | ||
|
|
3ba51fd6fe | ||
|
|
ff98e06afa | ||
|
|
6f22c73d99 | ||
|
|
87bd27f814 | ||
|
|
3e7db5617b | ||
|
|
1712e466d5 | ||
|
|
abf49529d6 | ||
|
|
3e31a78af1 | ||
|
|
41fc46c8b5 | ||
|
|
db8cfec7ad | ||
|
|
66376daad4 | ||
|
|
182f08d221 | ||
|
|
887cf39321 | ||
|
|
e2f6ec308c | ||
|
|
b1f2a27eac | ||
|
|
0c6cedf879 | ||
|
|
1ff6a00653 | ||
|
|
016821a8ce | ||
|
|
a786ae24e9 | ||
|
|
799b768367 | ||
|
|
24610f9c0a | ||
|
|
172307d53b | ||
|
|
d7816729d0 | ||
|
|
ac7daa70f7 | ||
|
|
0372f0647b | ||
|
|
60f98ac438 | ||
|
|
6d76814aed | ||
|
|
2cf5bb689f | ||
|
|
e18c295ca6 | ||
|
|
58346d6fc9 | ||
|
|
5364b7a09b | ||
|
|
52630aa735 | ||
|
|
89255a8c84 | ||
|
|
6d5cc38235 | ||
|
|
c4234ddcff | ||
|
|
7a9872d42f | ||
|
|
f5165d517c | ||
|
|
0b125e29b5 | ||
|
|
aabd6d8985 | ||
|
|
94dccae48a | ||
|
|
74ef112d57 | ||
|
|
0da63c6ef0 | ||
|
|
3c145c7dd7 | ||
|
|
63590119bb | ||
|
|
7845d65119 | ||
|
|
2454738224 | ||
|
|
3685cb8868 | ||
|
|
fcffcb5b59 | ||
|
|
19049fb890 | ||
|
|
50950cc9d2 | ||
|
|
b1f9e525ab | ||
|
|
fc03cd77fc | ||
|
|
9a3434b02e | ||
|
|
eab5e51f66 | ||
|
|
ff6b7cbec2 | ||
|
|
abe62d84ed | ||
|
|
1aa9627e4a | ||
|
|
8bbe549b0c | ||
|
|
baf69e397a | ||
|
|
3ca8f09971 | ||
|
|
3381ad0e0e | ||
|
|
150342f699 | ||
|
|
44830752f7 | ||
|
|
5e7ef691ae | ||
|
|
ed858bafdc | ||
|
|
2fff8652ca | ||
|
|
358142c1cc | ||
|
|
903ca18b75 | ||
|
|
6a91d3eec2 | ||
|
|
0d5e880fb2 | ||
|
|
03f322f92a | ||
|
|
5cf2acfff2 | ||
|
|
7d17423e4b | ||
|
|
5d877d81e3 | ||
|
|
a968410431 | ||
|
|
c6f4bfa875 | ||
|
|
71b84fb10d | ||
|
|
0d76c9ccb4 | ||
|
|
70815e276e | ||
|
|
72fe8f3af1 | ||
|
|
53bc50d05c | ||
|
|
99eb2856f7 | ||
|
|
616135ac14 | ||
|
|
5ca490d233 | ||
|
|
1c159f59bb | ||
|
|
4ad9c81381 | ||
|
|
d11eaec7d5 | ||
|
|
a02748d518 | ||
|
|
0ab2940347 | ||
|
|
fc2585eb95 | ||
|
|
c2789312ba | ||
|
|
e1646a3127 | ||
|
|
0fc1de9f29 | ||
|
|
7c5969e580 | ||
|
|
e719999d8a | ||
|
|
59ea4e4b44 | ||
|
|
df52e8ede9 | ||
|
|
028bf5919d | ||
|
|
31e16a7ed7 | ||
|
|
aa6696dfcc | ||
|
|
838355a5e9 | ||
|
|
f87962f1a0 | ||
|
|
8e4158d11d | ||
|
|
60f8f10bb5 | ||
|
|
de5e1d7274 | ||
|
|
cfe78fc387 | ||
|
|
2a8bfac2c5 | ||
|
|
3c5c684641 | ||
|
|
c757ac8517 | ||
|
|
2597ab4ea1 | ||
|
|
783799b2a4 | ||
|
|
87aec33833 | ||
|
|
06087cd853 | ||
|
|
afaef43017 | ||
|
|
e7f3f27104 | ||
|
|
6c0e11eebc | ||
|
|
809752e4ec | ||
|
|
54f6255fe4 | ||
|
|
d97a27307c | ||
|
|
6423066cb2 | ||
|
|
e8d8feb042 | ||
|
|
816caa6415 | ||
|
|
a11d123815 | ||
|
|
c24d1d1e41 | ||
|
|
1b2daef90c | ||
|
|
6284fd8024 | ||
|
|
763874ac55 | ||
|
|
4defaa103e | ||
|
|
181ac937d2 | ||
|
|
f6884524e2 | ||
|
|
23f118fb1a | ||
|
|
a3b8f31b1e | ||
|
|
c6fb2232d0 | ||
|
|
ef411ddb47 | ||
|
|
7aed2828bb | ||
|
|
560445a518 | ||
|
|
3549ed2da0 | ||
|
|
ec9f86c450 | ||
|
|
c6e829be4f | ||
|
|
5ef84916bb | ||
|
|
94403be9a8 | ||
|
|
6403b8ce38 | ||
|
|
3f34fa26bf | ||
|
|
b1a6c6b59c | ||
|
|
76981a59d4 | ||
|
|
d93fbd699d | ||
|
|
fd2dca0769 | ||
|
|
5097102ca1 | ||
|
|
fa3fd8d8a4 | ||
|
|
5582e78315 | ||
|
|
b7fd32067f | ||
|
|
2a2fdc57bd | ||
|
|
025739e35c | ||
|
|
c8f6153831 | ||
|
|
3c02e3dddc | ||
|
|
40997c34ff | ||
|
|
677c3f16e4 | ||
|
|
0adb4f5ae5 | ||
|
|
cbbcf914ad | ||
|
|
d68a29a5a2 | ||
|
|
368eeed0d0 | ||
|
|
a522b78496 | ||
|
|
dab81116e9 | ||
|
|
b7f355bd1a | ||
|
|
dbeaebaee3 | ||
|
|
fe94a1eac9 | ||
|
|
bd5107bbaf | ||
|
|
8018d9b418 | ||
|
|
0454d300ec | ||
|
|
1e5c9ebc91 | ||
|
|
5c7e9728e6 | ||
|
|
da4be33a04 | ||
|
|
47e2a5a460 | ||
|
|
04337ef4b8 | ||
|
|
df58c8eb80 | ||
|
|
b0bf1bf4be | ||
|
|
1a3d84d4c4 | ||
|
|
735f629ca1 | ||
|
|
9dc927b50b | ||
|
|
47a336eb64 | ||
|
|
33b66aaea0 | ||
|
|
7b9eefdf2d | ||
|
|
ea5e8b56dd | ||
|
|
e52fff4d0e | ||
|
|
8d108509c9 | ||
|
|
d3cc630501 | ||
|
|
e74f297f9e | ||
|
|
8be9c75734 | ||
|
|
851851a7e6 | ||
|
|
1cbe46dc3b | ||
|
|
675a943d59 | ||
|
|
908815def3 | ||
|
|
200ca1eeda | ||
|
|
b81cc139b3 | ||
|
|
f8ae906326 | ||
|
|
e6f55804f4 | ||
|
|
1432a19d7d | ||
|
|
74fbfb130c | ||
|
|
3cf45f602f | ||
|
|
7a9dcc71fd | ||
|
|
fb5249a979 | ||
|
|
3f694b75f8 | ||
|
|
0e1ee66dd6 | ||
|
|
920e002247 | ||
|
|
ab0b352d36 | ||
|
|
aa4b08a156 | ||
|
|
66514908d2 | ||
|
|
60f0801a7c | ||
|
|
7149d0d43f | ||
|
|
d970687ebe | ||
|
|
d0425fc0d6 | ||
|
|
bdd5b46708 | ||
|
|
6d949d7e4d | ||
|
|
5d72d092fc | ||
|
|
667fc8c8a6 | ||
|
|
f7a2d9fd06 | ||
|
|
85946efd0b | ||
|
|
f6a853bfe9 | ||
|
|
4bfbdeb9a5 | ||
|
|
1e53508d67 | ||
|
|
b8fca59cbb | ||
|
|
9ada6fe4a7 | ||
|
|
b1593a2053 | ||
|
|
22a5125a11 | ||
|
|
dfd9a0019b | ||
|
|
e1d81c199b | ||
|
|
e8f574ee9c | ||
|
|
472af1bca6 | ||
|
|
671346bcdd | ||
|
|
9132abb3fe | ||
|
|
1c681e9f82 | ||
|
|
19286ef99d | ||
|
|
37ad2f522a | ||
|
|
1e1aa65fc0 | ||
|
|
ec6e067938 | ||
|
|
ea515fdd85 | ||
|
|
c11c202248 | ||
|
|
1cfee31483 | ||
|
|
00a5aa01c7 | ||
|
|
fc61cf16ed | ||
|
|
0684e29098 | ||
|
|
66d29293cd | ||
|
|
e9fd657852 | ||
|
|
bd7f51358c | ||
|
|
371b8fad05 | ||
|
|
fe259747dc | ||
|
|
d4d94ddbee | ||
|
|
f62d773246 | ||
|
|
20294233e6 | ||
|
|
cb4ab411f9 | ||
|
|
7f008d1f9c | ||
|
|
fe0487c3f9 | ||
|
|
a54e810af1 | ||
|
|
5cc1f20fac | ||
|
|
da804e1f69 | ||
|
|
3399333360 | ||
|
|
e75ab3a7d7 | ||
|
|
3b70acc3ca | ||
|
|
b42092884e | ||
|
|
fea2db0e29 | ||
|
|
fe7bc924da | ||
|
|
60b357e6f9 | ||
|
|
5544a469c4 | ||
|
|
067ca91c4d | ||
|
|
afd8d692fd | ||
|
|
a9a8fa2857 | ||
|
|
4b3a624ed9 | ||
|
|
549ea19c26 | ||
|
|
c0515c9c4f | ||
|
|
e81d594d01 | ||
|
|
3d469a4986 | ||
|
|
b91bd7ede0 | ||
|
|
6048af99bc | ||
|
|
ef9427122e | ||
|
|
02402f5207 | ||
|
|
80197ee18c | ||
|
|
8989b05a69 | ||
|
|
f809782559 | ||
|
|
9522e975a0 | ||
|
|
8854fb69d8 | ||
|
|
10bd75ea7b | ||
|
|
f33ffb55a7 | ||
|
|
3bff44da0c | ||
|
|
cf960e3695 | ||
|
|
c8eac2690f | ||
|
|
8af458e61a | ||
|
|
07899327f1 | ||
|
|
dd5bffe071 | ||
|
|
83000b75ca | ||
|
|
e6c3815493 | ||
|
|
32626ef773 | ||
|
|
ab1d18debe | ||
|
|
62330571a3 | ||
|
|
a8827c361c | ||
|
|
4635481c77 | ||
|
|
c6f9e421c1 | ||
|
|
448e1cd0c3 | ||
|
|
5ee7c5a319 | ||
|
|
89625188f1 | ||
|
|
fdd19068a8 | ||
|
|
ef7033cac0 | ||
|
|
65840e45cd | ||
|
|
6075f413dc | ||
|
|
ba3b2f613a | ||
|
|
165832e703 | ||
|
|
7e27ec488b | ||
|
|
4e3356ccb2 | ||
|
|
6b69cdf12f | ||
|
|
c24b29a42c | ||
|
|
c013d19530 | ||
|
|
5a1e1864d9 | ||
|
|
7c56b2fce2 | ||
|
|
7266352ca0 | ||
|
|
c1cff1e3c2 | ||
|
|
c003efe1e9 | ||
|
|
68d847aca5 | ||
|
|
82bea640c4 | ||
|
|
4fa88dd7a0 | ||
|
|
900bdd3afe | ||
|
|
8dff457422 | ||
|
|
850a429243 | ||
|
|
d3c8f16aed | ||
|
|
a43e127dd0 | ||
|
|
84e52f5525 | ||
|
|
1dce2c1f7a | ||
|
|
1c802ad5f5 | ||
|
|
db38db9256 | ||
|
|
cb9fa62dac | ||
|
|
9cc36e2a6a | ||
|
|
bf310adc12 | ||
|
|
7273b6ad67 | ||
|
|
a02f9e1151 | ||
|
|
6ef8015179 | ||
|
|
db38b27e52 | ||
|
|
cccb5b191d | ||
|
|
3c589743b1 | ||
|
|
65270e02da | ||
|
|
27c1bf8eb6 | ||
|
|
1db54195f5 | ||
|
|
399208429d | ||
|
|
b40e57f191 | ||
|
|
be350e49f0 | ||
|
|
bae732016c | ||
|
|
e50a67f0e4 | ||
|
|
26e8e0a1b1 | ||
|
|
c8210e0516 | ||
|
|
95590dd07f | ||
|
|
7e94e96bcc | ||
|
|
5009494e89 | ||
|
|
e58c2f86aa | ||
|
|
fcea542def | ||
|
|
44407585fa | ||
|
|
3d93d88bf0 | ||
|
|
8a49e32d2a | ||
|
|
8bbc4a3c4a | ||
|
|
3a9dbbb577 | ||
|
|
5f11fa65b4 | ||
|
|
6f4129d317 | ||
|
|
e2a1d7b99d | ||
|
|
18b6f73008 | ||
|
|
c16de232ad | ||
|
|
6ff1d683a5 | ||
|
|
a7c2857808 | ||
|
|
4cea16c326 | ||
|
|
a8228159b7 | ||
|
|
4594f2fd1f | ||
|
|
9c7661d1ae | ||
|
|
dd2416b5ae | ||
|
|
54ddb7473b | ||
|
|
cc7ad7c71f | ||
|
|
bfc07b2a97 | ||
|
|
2aad2c6b8a | ||
|
|
959df65e0a | ||
|
|
76d32c1cb4 | ||
|
|
da59164664 | ||
|
|
01c3a7d687 | ||
|
|
9a57118300 | ||
|
|
8ecd6e6f54 | ||
|
|
b9ac754c07 | ||
|
|
3bd48e547d | ||
|
|
92c77332a0 | ||
|
|
5c7652afe8 | ||
|
|
c2dd35790f | ||
|
|
5dae561b70 | ||
|
|
b3600bef34 | ||
|
|
c6087f577d | ||
|
|
c695c00e76 | ||
|
|
0d10d1f95b | ||
|
|
f80d03ed15 | ||
|
|
f2b023193c | ||
|
|
e467b92bb9 | ||
|
|
ae467cd515 | ||
|
|
9e51a55d45 | ||
|
|
67a3ab164a | ||
|
|
77ea6d3748 | ||
|
|
5e9b3a16fa | ||
|
|
bdeab55d3c | ||
|
|
bb10474cbb | ||
|
|
d7a8e3dc51 | ||
|
|
2d5e336f0f | ||
|
|
2aa4ff8422 | ||
|
|
8f7523dd95 | ||
|
|
f5cdd99fe6 | ||
|
|
2459b4c64c | ||
|
|
54ea4c03d6 | ||
|
|
59061a0672 | ||
|
|
03b73e89b3 | ||
|
|
3bc6fc97a2 | ||
|
|
82176a831d | ||
|
|
9920e5ef99 | ||
|
|
f3852b20ca | ||
|
|
b20886f08a | ||
|
|
ec2b802912 | ||
|
|
3b5832eceb | ||
|
|
589e373bd8 | ||
|
|
a6fd41900f | ||
|
|
7daa626d55 | ||
|
|
72da89235a | ||
|
|
8a14fe7985 | ||
|
|
1e1c0515d1 | ||
|
|
95a398da23 | ||
|
|
ff8a8d860f | ||
|
|
928cf264b0 | ||
|
|
7139682bc7 | ||
|
|
b5ad039980 | ||
|
|
ab37817d26 | ||
|
|
e79f8b357c | ||
|
|
bdb9f9b949 | ||
|
|
07708c7a56 | ||
|
|
05e9c07aa1 | ||
|
|
3486cfaab7 | ||
|
|
313eba409c | ||
|
|
88cae5d8e9 | ||
|
|
52c4a77934 | ||
|
|
e526c244f3 | ||
|
|
54b5517222 | ||
|
|
70a691bc68 | ||
|
|
55d22e424d | ||
|
|
69ea40abc0 | ||
|
|
953fc94cb0 | ||
|
|
4b22518532 | ||
|
|
b60c438694 | ||
|
|
d1d9d65a06 | ||
|
|
b1ee4d10d7 | ||
|
|
908ef635fa | ||
|
|
6b2cf5df2f | ||
|
|
1105a9f31c | ||
|
|
689724db6c | ||
|
|
3530a95738 | ||
|
|
c9d8bbe874 | ||
|
|
8d87990793 | ||
|
|
5c4590d507 | ||
|
|
11d3754c08 | ||
|
|
209bf9e0aa | ||
|
|
9eaf072e8f | ||
|
|
065bbef781 | ||
|
|
beb5589a4a | ||
|
|
d88d5e7818 | ||
|
|
12336148d9 | ||
|
|
9bec54c454 | ||
|
|
303d712860 | ||
|
|
9e6bfaada4 | ||
|
|
3f8c47100d | ||
|
|
716120ea61 | ||
|
|
2003c5a0c9 | ||
|
|
07898cdfd6 | ||
|
|
72418194e9 | ||
|
|
358b93fb70 | ||
|
|
3e9a111643 | ||
|
|
8841951fe3 | ||
|
|
e45cee6596 | ||
|
|
66b965d9f7 | ||
|
|
f4285ae106 | ||
|
|
657e65bc6a | ||
|
|
41fc8d2e2e | ||
|
|
25ca781d76 | ||
|
|
41f4130e5d | ||
|
|
8e19f3fc0b | ||
|
|
c4b8ac8b0b | ||
|
|
0ac2df1297 | ||
|
|
251450fd50 | ||
|
|
85c5595f43 | ||
|
|
ca3188c930 | ||
|
|
2f47f82b0f | ||
|
|
0e09598b10 | ||
|
|
a705420528 | ||
|
|
4089887514 | ||
|
|
a3d02e5f39 | ||
|
|
6e09363832 | ||
|
|
1c58a64847 | ||
|
|
2a716e4d5a | ||
|
|
a2c613d380 | ||
|
|
aa4b09436c | ||
|
|
9521bba4ba | ||
|
|
55d10021f8 | ||
|
|
7fe35748d0 | ||
|
|
ff9efbd4ea | ||
|
|
23b8c325f4 | ||
|
|
ecfccb4c40 | ||
|
|
2472574cde | ||
|
|
bf81c8facc | ||
|
|
9bf0d69ab6 | ||
|
|
cf9d98d434 | ||
|
|
da8e67d4e5 | ||
|
|
d695cdef08 | ||
|
|
d7a7701c09 | ||
|
|
a31180260b | ||
|
|
f33947287c | ||
|
|
c054ceeab5 | ||
|
|
c8dce1bcb6 | ||
|
|
6195c10646 | ||
|
|
535cbbbd16 | ||
|
|
fa99f35bc0 | ||
|
|
5800f0e354 | ||
|
|
aa5e621184 | ||
|
|
283bdd6246 | ||
|
|
2884e67109 | ||
|
|
4542f9b2e3 | ||
|
|
9d08f91079 | ||
|
|
0704a4ad12 | ||
|
|
bb8509a21c | ||
|
|
f2e3d4a53d | ||
|
|
b8a221e67e | ||
|
|
f4147cce37 | ||
|
|
01f9fd502f | ||
|
|
5d20adc81e | ||
|
|
6a78f659e3 | ||
|
|
211f584bf8 | ||
|
|
fcfba8b12c | ||
|
|
85e4c7555a | ||
|
|
19dccffdde | ||
|
|
359514a83c | ||
|
|
90ea0dc857 | ||
|
|
ae18db45a4 | ||
|
|
4783c9be8d | ||
|
|
ff41fa9829 | ||
|
|
aa56dafd5f | ||
|
|
f2f2008d5d | ||
|
|
15d2589db8 | ||
|
|
47a8da49ca | ||
|
|
2250cac7f9 | ||
|
|
94e3063307 | ||
|
|
88691b3f18 | ||
|
|
3851880007 | ||
|
|
e5d2e089f4 | ||
|
|
bfe7f24a4b | ||
|
|
0d1e2c3349 | ||
|
|
bc6272a0ed | ||
|
|
56a752dc26 | ||
|
|
0fe443c92a | ||
|
|
74afdb2a46 | ||
|
|
ebd6ff36ed | ||
|
|
a5ec36bf89 | ||
|
|
c65802c1c3 | ||
|
|
784515e411 | ||
|
|
e859d39b2b | ||
|
|
62c4bfb9eb | ||
|
|
8ab1bdf30a | ||
|
|
c758066e25 | ||
|
|
06b7f69b3c | ||
|
|
c3c43a2645 | ||
|
|
343395a5de | ||
|
|
3c9bb74b61 | ||
|
|
c9cf30692f | ||
|
|
c979339c4e | ||
|
|
9393906eb9 | ||
|
|
1b4c910264 | ||
|
|
4db5d26b1e | ||
|
|
c09a4131db | ||
|
|
ce6f3f23c6 | ||
|
|
7b898c2d91 | ||
|
|
3da797a0ad | ||
|
|
517899cd03 | ||
|
|
1d6a14685e | ||
|
|
737d00f550 | ||
|
|
68798a9627 | ||
|
|
5b1dfee05c | ||
|
|
e75863e99d | ||
|
|
1c542a9b17 | ||
|
|
729ac5a0d7 | ||
|
|
ff8195df46 | ||
|
|
692ab6dacb | ||
|
|
128039d678 | ||
|
|
bb5de056d4 | ||
|
|
d927ac90e7 | ||
|
|
f61099ecad | ||
|
|
f96b663bbe | ||
|
|
f65213f8aa | ||
|
|
2e5adeb50c | ||
|
|
6de84d3b9b | ||
|
|
65ae08add6 | ||
|
|
3c970c24c1 | ||
|
|
93f3507dc8 | ||
|
|
e92e291409 | ||
|
|
4b4de8937e | ||
|
|
27a036bc00 | ||
|
|
1eb2540c67 | ||
|
|
3a5bd6029f | ||
|
|
249ff7f2d2 | ||
|
|
9afa965d5d | ||
|
|
28b7b5581d | ||
|
|
26aab15e50 | ||
|
|
92351049f1 | ||
|
|
47d3c50863 | ||
|
|
36ac3532e6 | ||
|
|
dee16f6943 | ||
|
|
3541b568c9 | ||
|
|
4dfa4d9525 | ||
|
|
5938f4e591 | ||
|
|
9ac26be65d | ||
|
|
5099ba9c96 | ||
|
|
bca5b13516 | ||
|
|
6ceb984393 | ||
|
|
17b29f376a | ||
|
|
36bef673d3 | ||
|
|
c2fa4e5220 | ||
|
|
ddf06d20c2 | ||
|
|
e51f640371 | ||
|
|
e302f53d5c | ||
|
|
b2058b9581 | ||
|
|
35501d328b | ||
|
|
cb746c64db | ||
|
|
e2f6d117bc | ||
|
|
9fd9449eca | ||
|
|
1f97af6ff1 | ||
|
|
f1a7862a9c | ||
|
|
8aeac3ed2e | ||
|
|
469832a598 | ||
|
|
e0e65e4374 | ||
|
|
66f78d6979 | ||
|
|
efc58f7dd1 | ||
|
|
bc301c27c2 | ||
|
|
82ea1935de | ||
|
|
226fb05337 | ||
|
|
be219f03d5 | ||
|
|
f10c1e923e | ||
|
|
66121e5ff3 | ||
|
|
478b71172d | ||
|
|
e7370f12ae | ||
|
|
b844a577c7 | ||
|
|
9bf33fdb25 | ||
|
|
8b988b227b | ||
|
|
8b2be019c6 | ||
|
|
4d7d92759f | ||
|
|
798b840472 | ||
|
|
48db75a995 | ||
|
|
7072541ba7 | ||
|
|
7119c915ec | ||
|
|
5e3035cc15 | ||
|
|
7cf2e4c4ed | ||
|
|
674a3a0a3f | ||
|
|
7486a99494 | ||
|
|
783d96bd7d | ||
|
|
64eea42092 | ||
|
|
8453ad0fb4 | ||
|
|
0acfeff006 | ||
|
|
a338b7ef39 | ||
|
|
e821660124 | ||
|
|
bad6045164 | ||
|
|
6779fd7ae5 | ||
|
|
04858cc42c | ||
|
|
916975b0a9 | ||
|
|
644db88e58 | ||
|
|
b025af45fa | ||
|
|
0f11731c01 | ||
|
|
ea1d21a3ef | ||
|
|
545ba6521b | ||
|
|
1fd3e6c9fa | ||
|
|
2913c0c7de | ||
|
|
a4c851899f | ||
|
|
df1c58e79b | ||
|
|
67edeab09b | ||
|
|
fe07ac025a | ||
|
|
fc72d99ab3 | ||
|
|
377f665361 | ||
|
|
4e458ec4cb | ||
|
|
6f4500f31a | ||
|
|
a363c5525b | ||
|
|
65027fceba | ||
|
|
2b0c75a649 | ||
|
|
bcc79541c1 | ||
|
|
081d6dc91e | ||
|
|
09a5111e36 | ||
|
|
253746843c | ||
|
|
5d2fac9247 | ||
|
|
3c2a1093a0 | ||
|
|
88b3d8ee4a | ||
|
|
d35a6f504f | ||
|
|
4965dad6a2 | ||
|
|
3ad4584159 | ||
|
|
5e291255bb | ||
|
|
205c99372e | ||
|
|
a05f3a969b | ||
|
|
3acc0931d8 | ||
|
|
05f6a953ea | ||
|
|
6253368f05 | ||
|
|
9483f2f178 | ||
|
|
8df6e7ef90 | ||
|
|
b09dba0a95 | ||
|
|
cfee4a0b24 | ||
|
|
34febf4949 | ||
|
|
6aed9dfb9f | ||
|
|
c7360993c9 | ||
|
|
34a072bada | ||
|
|
dda0d54f20 | ||
|
|
d710c31d48 | ||
|
|
02c74f7d96 | ||
|
|
5bdccba29e | ||
|
|
cdc819fbe8 | ||
|
|
4629d4cd3e | ||
|
|
ba3a70c524 | ||
|
|
52b985dd8e | ||
|
|
b51c8e1552 | ||
|
|
86f9c03707 | ||
|
|
e61c84ee08 | ||
|
|
2f39808275 | ||
|
|
f5aee4cbd0 | ||
|
|
9fd9bb4eef | ||
|
|
685cae8993 | ||
|
|
ec14aadec6 | ||
|
|
b934770e1e | ||
|
|
2f76433f34 | ||
|
|
535c63be2b | ||
|
|
53d4f08ee7 | ||
|
|
81b72fe72b | ||
|
|
e496794052 | ||
|
|
442b4fb30f | ||
|
|
9528b10d01 | ||
|
|
a9f9c887b5 | ||
|
|
6105a331aa | ||
|
|
0f0be95c12 | ||
|
|
d6ca9e4539 | ||
|
|
d3b5171237 | ||
|
|
cf501ac19e | ||
|
|
4fd4746ddf | ||
|
|
61c1476823 | ||
|
|
e28b8bb6e8 | ||
|
|
5eb9107adf | ||
|
|
83ddf74890 | ||
|
|
6aa7f2a0ee | ||
|
|
d801d55c3c | ||
|
|
491e644c3c | ||
|
|
5844232a00 | ||
|
|
abbf067625 | ||
|
|
806c882965 | ||
|
|
3fe5a85ffe | ||
|
|
95dae62bb3 | ||
|
|
f7edd54ea7 | ||
|
|
78ae89199e | ||
|
|
fc12a235f2 | ||
|
|
48fc96226c | ||
|
|
3534dd27dc | ||
|
|
a7e3c1a0c4 | ||
|
|
43c5051158 | ||
|
|
2f56a7090a | ||
|
|
13ffcfbbcd | ||
|
|
1aeb8e29e2 | ||
|
|
a3b844d2e3 | ||
|
|
5aa027f1a9 | ||
|
|
c12be6a1c8 | ||
|
|
c891ed81e1 | ||
|
|
c48921990d | ||
|
|
54bfd945e5 | ||
|
|
1d8c4db5eb | ||
|
|
055ab98d4c | ||
|
|
777551cb43 | ||
|
|
68827f7697 | ||
|
|
8e5b144f00 | ||
|
|
748a420b64 | ||
|
|
80fc43a075 | ||
|
|
0588f2846b | ||
|
|
8e4e7d9efa | ||
|
|
6df01edc7a | ||
|
|
996396c943 | ||
|
|
e3dddb9288 | ||
|
|
47ce71c959 | ||
|
|
8921aeb3f2 | ||
|
|
35be9739d4 | ||
|
|
f5ce46431b | ||
|
|
81ed70d291 | ||
|
|
4b0fdceb76 | ||
|
|
58e537732c | ||
|
|
02ad79b12a | ||
|
|
b179887efc | ||
|
|
0580b059fc | ||
|
|
bebd0e7258 | ||
|
|
6e96b2163e | ||
|
|
ca15ac987c | ||
|
|
6d3414caa9 | ||
|
|
85b80312e0 | ||
|
|
30d5f53c1d | ||
|
|
bad2e98757 | ||
|
|
45da396cb2 | ||
|
|
d195176a46 | ||
|
|
53078f79a6 | ||
|
|
dbb7f0c683 | ||
|
|
cb7703ecbb | ||
|
|
e63d7174bb | ||
|
|
31ab7a0493 | ||
|
|
c503f09529 | ||
|
|
f5bb9189af | ||
|
|
9ed8ba80c4 | ||
|
|
f9cce82a93 | ||
|
|
79d418d1a1 | ||
|
|
15d7f73aca | ||
|
|
4561870ece | ||
|
|
dbc8c9d07d | ||
|
|
d81a2029ec | ||
|
|
d04a5a2f92 | ||
|
|
5146f083ff | ||
|
|
57122c6eea | ||
|
|
ca748906c0 | ||
|
|
4d31bde98a | ||
|
|
3f98c332bd | ||
|
|
fb3eced1fb | ||
|
|
9641ea0b3a | ||
|
|
1df05a5529 | ||
|
|
a393bb02dd | ||
|
|
20518cbe2b | ||
|
|
9447034deb | ||
|
|
c7f0fcbe9f | ||
|
|
fce8719432 | ||
|
|
ce383769da | ||
|
|
342af62aea | ||
|
|
b3ab05cc86 | ||
|
|
36966e220c | ||
|
|
8ae3347c05 | ||
|
|
4f51a8ce31 | ||
|
|
1371bbe6fb | ||
|
|
94f4c9e334 | ||
|
|
c5c89f9d9e | ||
|
|
6a79f8ec0d | ||
|
|
aa940ef9f7 | ||
|
|
7a20f06cf4 | ||
|
|
b9596f2a6e | ||
|
|
bb2dfc269c | ||
|
|
684af4e7db | ||
|
|
1c946ac661 | ||
|
|
f8d06d38ab | ||
|
|
2a679c914b | ||
|
|
3f8d5ed570 | ||
|
|
028c2f9f03 | ||
|
|
b783c0c227 | ||
|
|
30787a372e | ||
|
|
b99169cc3b | ||
|
|
78cf146a92 | ||
|
|
b867167b78 | ||
|
|
d8dfbf6995 | ||
|
|
c2d6737796 | ||
|
|
dcfe055461 | ||
|
|
c86b1c259c | ||
|
|
400c16ba2d | ||
|
|
3ff0dbb7ef | ||
|
|
469a88f368 | ||
|
|
217ff27e72 | ||
|
|
e337f7121b | ||
|
|
665ac5ee99 | ||
|
|
f06c493458 | ||
|
|
f383e47344 | ||
|
|
e15518cd51 | ||
|
|
27ce62dd4f | ||
|
|
26202d8e56 | ||
|
|
d93b5a3374 | ||
|
|
e3acb7ce4e | ||
|
|
5b7c965c48 | ||
|
|
5f1e670dd7 | ||
|
|
ab1562ea33 | ||
|
|
2359a1444b | ||
|
|
9075b6629f | ||
|
|
583e8c43d6 | ||
|
|
26369dd14b | ||
|
|
9d40e7c004 | ||
|
|
267535844e | ||
|
|
0f5d2189e0 | ||
|
|
f76f4d9d29 | ||
|
|
2ba5e40012 | ||
|
|
1fe6ae4556 | ||
|
|
3d8a1894f6 | ||
|
|
70cfce833c | ||
|
|
96c3034a07 | ||
|
|
5aad81c696 | ||
|
|
b0e2f44f01 | ||
|
|
442e633800 | ||
|
|
5f1e788a25 | ||
|
|
3808e7e78f | ||
|
|
650edc1b1e | ||
|
|
cb5e1bd795 | ||
|
|
3282557769 | ||
|
|
dff18b6b9d | ||
|
|
2a64ead1c4 | ||
|
|
eb0a61d35b | ||
|
|
ddca70980e | ||
|
|
5aa3502ef5 | ||
|
|
3b02703805 | ||
|
|
f39d13c8f8 | ||
|
|
16a203227a | ||
|
|
b350f133b0 | ||
|
|
ec3a0e08c3 | ||
|
|
a96eea5e44 | ||
|
|
0dc7815e35 | ||
|
|
7f6e1c25e9 | ||
|
|
9291c35b00 | ||
|
|
90b67fc05c | ||
|
|
09afd2c6f8 | ||
|
|
1def571191 | ||
|
|
ef52f2465e | ||
|
|
845e5de43f | ||
|
|
b7433264eb | ||
|
|
60e606a413 | ||
|
|
9afafec9d6 | ||
|
|
c9cb84a28d | ||
|
|
8949383ade | ||
|
|
f732ea4dab | ||
|
|
162842415f | ||
|
|
07d200a752 | ||
|
|
822e1ea6c9 | ||
|
|
f79ae1541d | ||
|
|
2dfa93383f | ||
|
|
1ab5db8507 | ||
|
|
ccd951b5d3 | ||
|
|
6259690d12 | ||
|
|
8059d9cd73 | ||
|
|
c6635e554a | ||
|
|
d7ca662e70 | ||
|
|
b6f885b250 | ||
|
|
63141c4ac9 | ||
|
|
94e9f01e62 | ||
|
|
cffa74b1c2 | ||
|
|
1fb917941e | ||
|
|
08c6a4e2fb | ||
|
|
976be6d96f | ||
|
|
fe95b45820 | ||
|
|
47dffeee76 | ||
|
|
be7b06f5c8 | ||
|
|
3a371f8d75 | ||
|
|
fa97058895 | ||
|
|
df9289367b | ||
|
|
3a824b1d5e | ||
|
|
6f72da87b1 | ||
|
|
1b1c5ad6da | ||
|
|
f4777f787c | ||
|
|
6bcf45fba7 | ||
|
|
1e8a05e313 | ||
|
|
1cf0f2dd0b | ||
|
|
25a0439928 | ||
|
|
df20e97d60 | ||
|
|
fd764a28a4 | ||
|
|
81bd8fbb74 | ||
|
|
47ee572640 | ||
|
|
a0b9553158 | ||
|
|
7659a6cadf | ||
|
|
a65bae8243 | ||
|
|
421abac30a | ||
|
|
0b11e97427 | ||
|
|
fbe1ff73f1 | ||
|
|
68e831468b | ||
|
|
e382f0dba0 | ||
|
|
f0f92952d6 | ||
|
|
58f016ca00 | ||
|
|
faff0edb4a | ||
|
|
5e9a9e5b55 | ||
|
|
e182dde718 | ||
|
|
7dfc2e8736 | ||
|
|
b27a547fb8 | ||
|
|
379c752cf8 | ||
|
|
35abdc63d4 | ||
|
|
a386915b50 | ||
|
|
ab16bc849d | ||
|
|
90007127ba | ||
|
|
a1935cbdac | ||
|
|
7de91bd923 | ||
|
|
cdbcae21ac | ||
|
|
ea62033cf3 | ||
|
|
a48423944a | ||
|
|
b7fb3cd208 | ||
|
|
34825b5063 | ||
|
|
7737012103 | ||
|
|
3912a375c5 | ||
|
|
35ca6db1ee | ||
|
|
0d20869337 | ||
|
|
89d161268e | ||
|
|
5ae39ef8d3 | ||
|
|
e57696d4ff | ||
|
|
15c9a5468b | ||
|
|
30318b7c61 | ||
|
|
8b0fc9bf5f | ||
|
|
5fdba7720c | ||
|
|
ca12dc604d | ||
|
|
09f4d8ac0c | ||
|
|
254b82cc60 | ||
|
|
d4240006f1 | ||
|
|
68518e609d | ||
|
|
001eba6729 | ||
|
|
ff47a224c7 | ||
|
|
8810e25ea9 | ||
|
|
eb67d67a60 | ||
|
|
e12f95ff74 | ||
|
|
2fe213d060 | ||
|
|
b726ee42f7 | ||
|
|
6b71b4709e | ||
|
|
0701b78720 | ||
|
|
82d1ac1e83 | ||
|
|
8acf98631f | ||
|
|
0a31d19561 | ||
|
|
91279922f1 | ||
|
|
96804ae2e2 | ||
|
|
3ae8a89961 | ||
|
|
f8f13fd32c | ||
|
|
ae61d2c629 | ||
|
|
b1918e8b15 | ||
|
|
ce7bca5b36 | ||
|
|
51be62bc29 | ||
|
|
c1ff3971de | ||
|
|
57db286405 | ||
|
|
592b670e96 | ||
|
|
97fdcaac51 | ||
|
|
271d9ac13e | ||
|
|
b6cea110a7 | ||
|
|
4b5dae4779 | ||
|
|
a250317a28 | ||
|
|
431605e793 | ||
|
|
a4d3c06119 | ||
|
|
246412cb2c | ||
|
|
2fb013fb41 | ||
|
|
6f9d684b2d | ||
|
|
af6a2ec581 | ||
|
|
488b28921f | ||
|
|
4c23fc1011 | ||
|
|
db1c903f1b | ||
|
|
3fdf7411fc | ||
|
|
1da275ff3a | ||
|
|
bc5167f38d | ||
|
|
609b6f3123 | ||
|
|
fe35081e03 | ||
|
|
72df1a35a0 | ||
|
|
90ffcf5071 | ||
|
|
35f60cc536 | ||
|
|
31bb40c50b | ||
|
|
bc7b35f816 | ||
|
|
0c76612a4c | ||
|
|
ab86674aa3 | ||
|
|
8cd5a01dd5 | ||
|
|
4ef5bafcca | ||
|
|
2c783e0657 | ||
|
|
0c7ead5b21 | ||
|
|
57a8b7842e | ||
|
|
4b5a7b6a74 | ||
|
|
c09c31767d | ||
|
|
ecff04618b | ||
|
|
c377469dad | ||
|
|
ecb41382cb | ||
|
|
3150b12b99 | ||
|
|
364260b070 | ||
|
|
5ccf6f077d | ||
|
|
5b113c5c22 | ||
|
|
ff53900ea3 | ||
|
|
b0b0403d9a | ||
|
|
21c3b3ab57 | ||
|
|
e85709a341 | ||
|
|
04be42a4d6 | ||
|
|
8196e8a84d | ||
|
|
1f85492690 | ||
|
|
e15178150b | ||
|
|
d83aee2507 | ||
|
|
354a9904e9 | ||
|
|
fe3379ffbb | ||
|
|
0164936038 | ||
|
|
9106d6455f | ||
|
|
5ddea2b1da | ||
|
|
2549c5587e | ||
|
|
c9f28d8105 | ||
|
|
75b2db4749 | ||
|
|
b6f291d721 | ||
|
|
4f7e227392 | ||
|
|
7d95eb34c7 | ||
|
|
7e3ee38920 | ||
|
|
d44c2c26a8 | ||
|
|
d77a41c20f | ||
|
|
c50c747691 | ||
|
|
bcf3dde60d | ||
|
|
33ec3de1b4 | ||
|
|
26be5b5c4f | ||
|
|
56af57c682 | ||
|
|
3a5cb3f7c2 | ||
|
|
724c6be85b | ||
|
|
1c4a56f95b | ||
|
|
9c21e96538 | ||
|
|
67074bd682 | ||
|
|
b535987392 | ||
|
|
d5c0c2e3d3 | ||
|
|
7580c79c00 | ||
|
|
c0a13622b0 | ||
|
|
58d7326f77 | ||
|
|
45d7a12d0d | ||
|
|
40b4f15340 | ||
|
|
9c28ff67c1 | ||
|
|
e3f146dabf | ||
|
|
2b2a6a7f10 | ||
|
|
192574dfe8 | ||
|
|
8e95e06b2d | ||
|
|
1963b3ee71 | ||
|
|
507f66b3b6 | ||
|
|
94bf9eae8b | ||
|
|
0fa32f976c | ||
|
|
198238d4b5 | ||
|
|
66631ac105 | ||
|
|
19c5996351 | ||
|
|
cd3140a9c7 | ||
|
|
56201d6a01 | ||
|
|
654cb41e3e | ||
|
|
fa744d9204 | ||
|
|
3e1c56ff82 | ||
|
|
5d5164c4e9 | ||
|
|
0791e760a4 | ||
|
|
b53fe2dd5e | ||
|
|
1648b0c2dd | ||
|
|
1a5adfabf4 | ||
|
|
c538e9c4fc | ||
|
|
98422b296d | ||
|
|
e35068137d | ||
|
|
83dda92603 | ||
|
|
6bbcb519d7 | ||
|
|
7fa3baacfd | ||
|
|
f94c1ef852 | ||
|
|
cc4cb1a6a7 | ||
|
|
247a322366 | ||
|
|
7ec7023d1b | ||
|
|
b4edd95bab | ||
|
|
50ddc8caa3 | ||
|
|
6263dbbd0f | ||
|
|
64c45daf16 | ||
|
|
5ed41cb5ac | ||
|
|
29dea5f829 | ||
|
|
e51b21421d | ||
|
|
5cae4ae0bf | ||
|
|
5f2cbb30c2 | ||
|
|
1ddec2cb69 | ||
|
|
96b54cc77a | ||
|
|
4da6524493 | ||
|
|
1364d58065 | ||
|
|
4383966051 | ||
|
|
86451fb5d0 | ||
|
|
0878c7398d | ||
|
|
81643165c2 | ||
|
|
b37802949c | ||
|
|
a53f2388b4 | ||
|
|
e823543cad | ||
|
|
bdf7f903e9 | ||
|
|
336b40a102 | ||
|
|
354922195f | ||
|
|
9c1199fc48 | ||
|
|
ea35ed25d8 | ||
|
|
add05ef913 | ||
|
|
e3aa4110fc | ||
|
|
8a0ed1bc13 | ||
|
|
0db490d444 | ||
|
|
4fd89c8a83 | ||
|
|
4fe17e556e | ||
|
|
e95553163c | ||
|
|
8ae72074ef | ||
|
|
b6c1403f4b | ||
|
|
920d696d0b | ||
|
|
a8dcb0b973 | ||
|
|
895198b7b8 | ||
|
|
144941d991 | ||
|
|
f203517ce8 | ||
|
|
6dd6741237 | ||
|
|
066e9c2fd5 | ||
|
|
f500b9b2d5 | ||
|
|
c80e35872e | ||
|
|
05eda6e406 | ||
|
|
1686182616 | ||
|
|
fd5720451e | ||
|
|
5b9adc8daa | ||
|
|
3efd6867d8 | ||
|
|
cd1a55652f | ||
|
|
47d0a4a343 | ||
|
|
fe76d103f0 | ||
|
|
789a9bfe1a | ||
|
|
391f97d3bb | ||
|
|
d077a03e60 | ||
|
|
3317b6a9e5 | ||
|
|
0b0f0e4649 | ||
|
|
f75e416479 | ||
|
|
d83db6bdf5 | ||
|
|
92ec461a77 | ||
|
|
144fe3b8ac | ||
|
|
af2e650538 | ||
|
|
1c585dc479 | ||
|
|
c6853b197c | ||
|
|
ef591c883a | ||
|
|
4918db9cb1 | ||
|
|
b8250b67c9 | ||
|
|
d6f87894aa | ||
|
|
c808500083 | ||
|
|
3a6c2be48a | ||
|
|
a28d01704a | ||
|
|
8bed654756 | ||
|
|
8845884b24 | ||
|
|
ea5de9a289 | ||
|
|
7922920f51 | ||
|
|
dcf6ab0792 | ||
|
|
57fe510138 | ||
|
|
b4c7a6e448 | ||
|
|
1d8702e95f | ||
|
|
8171fcd346 | ||
|
|
b1ccdeb0d3 | ||
|
|
969b03b364 | ||
|
|
5ed81132fb | ||
|
|
c663cdbe0d | ||
|
|
a4d46fd501 | ||
|
|
c3e1ead90a | ||
|
|
92c10eb534 | ||
|
|
08d0758616 | ||
|
|
68d8369a8b | ||
|
|
af59a4472a | ||
|
|
269546add1 | ||
|
|
65246f8856 | ||
|
|
ab35fe793d | ||
|
|
e7b897e67c | ||
|
|
0b5dbb464d | ||
|
|
60419f4319 | ||
|
|
1ddf0db18d | ||
|
|
0732ca37b8 | ||
|
|
801ea899e6 | ||
|
|
ba5159d2ad | ||
|
|
ab2cf5a50f | ||
|
|
d533c12315 | ||
|
|
1d90719053 | ||
|
|
127d279266 | ||
|
|
a484f66e69 | ||
|
|
b34924e264 | ||
|
|
4d5494c256 | ||
|
|
46b094a57a | ||
|
|
0ef89c30e3 | ||
|
|
dc2a89ce3f | ||
|
|
47adcfec30 | ||
|
|
25e848702f | ||
|
|
756a285978 | ||
|
|
fcf79bda03 | ||
|
|
6b170f3116 | ||
|
|
ea6bc245ff | ||
|
|
61dc344d89 | ||
|
|
fa6b7eacaa | ||
|
|
23dafe539d | ||
|
|
0a654efda0 | ||
|
|
bec10ebe34 | ||
|
|
0e03ca5d48 | ||
|
|
4b1bf29ea0 | ||
|
|
b391b2c16d | ||
|
|
7b9cf93b40 | ||
|
|
dd55e5e086 | ||
|
|
ba2b1dac92 | ||
|
|
56ffeb3008 | ||
|
|
b3757fd6b5 | ||
|
|
e0de81230e | ||
|
|
2bc669c828 | ||
|
|
493f7809a4 | ||
|
|
ef52cd6991 | ||
|
|
480f15b6f6 | ||
|
|
fcfee88ef4 | ||
|
|
19f647e6ab | ||
|
|
27e5ec02f4 | ||
|
|
0808d77a2d | ||
|
|
90d9e9b911 | ||
|
|
ebfbc11c20 | ||
|
|
2764743062 | ||
|
|
c66d7d6187 | ||
|
|
f2b6c0a443 | ||
|
|
aef0ffa506 | ||
|
|
040fcfba4f | ||
|
|
9f72831e4a | ||
|
|
fa0d9ad4c3 | ||
|
|
b6107b7281 | ||
|
|
6ffe61562b | ||
|
|
b5f5e13f22 | ||
|
|
376b7545e1 | ||
|
|
ffaa3e591b | ||
|
|
24d5722ef7 | ||
|
|
9e1fe0a6c1 | ||
|
|
d128aeb6ef | ||
|
|
ef371dedb4 | ||
|
|
00d262f0e6 | ||
|
|
475b8924c3 | ||
|
|
0afb1417a3 | ||
|
|
b6b41660d6 | ||
|
|
c78811fe36 | ||
|
|
a0254eb4f2 | ||
|
|
e9c96ecde2 | ||
|
|
f9cbf9254c | ||
|
|
70d24ffdfd | ||
|
|
84530ca0a2 | ||
|
|
e848fda4e3 | ||
|
|
51964e51c6 | ||
|
|
0c63268df1 | ||
|
|
316f62c3c8 | ||
|
|
9e37800426 | ||
|
|
3e0ee374c9 | ||
|
|
bb411a365c | ||
|
|
da0878a7a7 | ||
|
|
d0328f17e1 | ||
|
|
c6f49984a7 | ||
|
|
f53fb071f0 | ||
|
|
2cc8af71d0 | ||
|
|
006da66028 | ||
|
|
2a74abdef4 | ||
|
|
269b14394d | ||
|
|
d6d6fae2ca | ||
|
|
331afc37df | ||
|
|
041bfdaf3c | ||
|
|
023cd15cd0 | ||
|
|
f2fb37df4c | ||
|
|
c4ae0dddb0 | ||
|
|
f66077f012 | ||
|
|
a31d6bc5ae | ||
|
|
fad13f517b | ||
|
|
ef36517a26 | ||
|
|
085e45a50f | ||
|
|
43b06a686b | ||
|
|
e8dba4d133 | ||
|
|
1af3cd1d77 | ||
|
|
4c44310fea | ||
|
|
3e343a80fd | ||
|
|
313fac9f18 | ||
|
|
2c242c66e5 | ||
|
|
4e2b525c99 | ||
|
|
93c76d4ba0 | ||
|
|
b69ecca252 | ||
|
|
947011103c | ||
|
|
2fd7e4503a | ||
|
|
a5fce15661 | ||
|
|
f1561ddc21 | ||
|
|
74ce094d79 | ||
|
|
f832d70701 | ||
|
|
24521bf50d | ||
|
|
cfe84fc2dd | ||
|
|
8efeb169af | ||
|
|
7b7711d410 | ||
|
|
8b0779ac17 | ||
|
|
1e904e5ebb | ||
|
|
1d3b93d4a3 | ||
|
|
7756b62f4c | ||
|
|
7990e841e0 | ||
|
|
ae348a71e6 | ||
|
|
9a1a537bfd | ||
|
|
6b7d2ea657 | ||
|
|
98ef7c2385 | ||
|
|
093bfd26a3 | ||
|
|
9953c61d62 | ||
|
|
e61072ddc9 | ||
|
|
2269cd54be | ||
|
|
76d5e64097 | ||
|
|
06073f3982 | ||
|
|
0f71a93c5e | ||
|
|
fa41c32a3e | ||
|
|
3b00efdeae | ||
|
|
0f323ce04f | ||
|
|
ad2acc2a16 | ||
|
|
162fea6e28 | ||
|
|
30e939c354 | ||
|
|
94c25b5dcb | ||
|
|
a58d65e8af | ||
|
|
06b453ebe7 | ||
|
|
f00c6b1cb6 | ||
|
|
027466dfc2 | ||
|
|
bc69a98df1 | ||
|
|
ba9fd8d1f1 | ||
|
|
0fcc3f257d | ||
|
|
382235c556 | ||
|
|
0a919d7076 | ||
|
|
0709aa56a4 | ||
|
|
684d90d0e7 | ||
|
|
227c05a696 | ||
|
|
8cf1a4a790 | ||
|
|
75e3976bfa | ||
|
|
e9791fd493 | ||
|
|
f9f445489c | ||
|
|
10e5460e39 | ||
|
|
f1049169b5 | ||
|
|
2056bdb43d | ||
|
|
785bf3ce3a | ||
|
|
c29bf61e59 | ||
|
|
a98c0516a3 | ||
|
|
a6989a2aba | ||
|
|
30e43170f8 | ||
|
|
d8feb3e794 | ||
|
|
99bdf6d173 | ||
|
|
8424a9e4de | ||
|
|
4c0cbe3253 | ||
|
|
462dc5da51 | ||
|
|
40fad5f785 | ||
|
|
c0791acbf6 | ||
|
|
3cb0a56647 | ||
|
|
95f38e8048 | ||
|
|
a3493a6c74 | ||
|
|
3535bb4e4e | ||
|
|
3be6242cb5 | ||
|
|
64a53830e4 | ||
|
|
b3e3860b23 | ||
|
|
4db560fb4b | ||
|
|
b00de4d976 | ||
|
|
0a0d6969ec | ||
|
|
ac162103a7 | ||
|
|
16876502d1 | ||
|
|
4cdd2110a6 | ||
|
|
b820adf0bf | ||
|
|
1cee2febf4 | ||
|
|
43f8d9d72b | ||
|
|
66ffe03224 | ||
|
|
5c96c83f98 | ||
|
|
6d1ddece92 | ||
|
|
897107ca23 | ||
|
|
0baaffdad8 | ||
|
|
784d2fda6d | ||
|
|
19817249db | ||
|
|
240260e598 | ||
|
|
fcf92f06ef | ||
|
|
fe1c2a1896 | ||
|
|
d55c65e275 | ||
|
|
93064bb18b | ||
|
|
dec1b24c86 | ||
|
|
8c76c3d81c | ||
|
|
8d8cabd5b3 | ||
|
|
aa948b0149 | ||
|
|
a25ef6e2a0 | ||
|
|
c404d3ac8d | ||
|
|
8eb71495a1 | ||
|
|
db824c4601 | ||
|
|
029886cc87 | ||
|
|
42604ec737 | ||
|
|
caaa62db30 | ||
|
|
0f135e0587 | ||
|
|
dae6826cc1 | ||
|
|
ddf2ac7ece | ||
|
|
5e011356f2 | ||
|
|
82e047dc66 | ||
|
|
7720b416d5 | ||
|
|
c40dc0fa50 | ||
|
|
36ed7bca66 | ||
|
|
1fa015704a | ||
|
|
7e2097ba6d | ||
|
|
3a630edaa5 | ||
|
|
1b561bbf4c | ||
|
|
37de0b59c3 | ||
|
|
2f528d2a03 | ||
|
|
686d55a672 | ||
|
|
07c58e2ce7 | ||
|
|
6fe794fdf5 | ||
|
|
d0ec90130c | ||
|
|
f7806d9781 | ||
|
|
63219b49f2 | ||
|
|
320e84627c | ||
|
|
fc9e697249 | ||
|
|
a68c626fa2 | ||
|
|
66f17cf05b | ||
|
|
5949e8fb3f | ||
|
|
3bb0fcc4cd | ||
|
|
d32d5d0eb8 | ||
|
|
5ee2c030ec | ||
|
|
58ca7df105 | ||
|
|
fc77dbc73b | ||
|
|
8aedde2422 | ||
|
|
526b5fe140 | ||
|
|
1c4e9ed474 | ||
|
|
21cbb441e2 | ||
|
|
01fedc59e2 | ||
|
|
b3d13c3a90 | ||
|
|
24ee42e0c7 | ||
|
|
3a18eccdd6 | ||
|
|
a3b763ecc9 | ||
|
|
822c74ad2f | ||
|
|
0a71e34459 | ||
|
|
25b68081ea | ||
|
|
ac0e1e7698 | ||
|
|
4be5bcc979 | ||
|
|
f3c2d7e43a | ||
|
|
9fa0700f72 | ||
|
|
868da542ab | ||
|
|
04c810e292 | ||
|
|
86478c0268 | ||
|
|
b453a8934f | ||
|
|
669c1fe490 | ||
|
|
c15895ab45 | ||
|
|
44acc7d5ac | ||
|
|
341df0dab7 | ||
|
|
8df3ff3536 | ||
|
|
85c683b714 | ||
|
|
6606edafb9 | ||
|
|
91ff7b658a | ||
|
|
27c500e950 | ||
|
|
078245cb96 | ||
|
|
e54597b944 | ||
|
|
1af9b3a018 | ||
|
|
315d041fc7 | ||
|
|
f7f1cdab34 | ||
|
|
597f0da42f | ||
|
|
497add09b3 | ||
|
|
ff05225b56 | ||
|
|
ac053e9ac9 | ||
|
|
9aeae1e460 | ||
|
|
d710f204b3 | ||
|
|
be016aa4bb | ||
|
|
04e62cba24 | ||
|
|
4d476dc641 | ||
|
|
85c3a812da | ||
|
|
e985e70303 | ||
|
|
9dbf96c259 | ||
|
|
6eba7c9a2f | ||
|
|
c1966e9301 | ||
|
|
a6fb72f1de | ||
|
|
a695a69f0f | ||
|
|
a8632297eb | ||
|
|
ca4218b309 | ||
|
|
65df71239a | ||
|
|
fdd8f3b214 | ||
|
|
1887573301 | ||
|
|
1efd56f48b | ||
|
|
bcd13b6f27 | ||
|
|
e4e880edd9 | ||
|
|
75da9c2e73 | ||
|
|
7a933dbd5e | ||
|
|
4b097b83b1 | ||
|
|
b3f9a691f5 | ||
|
|
50cd94a280 | ||
|
|
82982b3cda | ||
|
|
a5243ff58c | ||
|
|
3b25e0a112 | ||
|
|
d94d880569 | ||
|
|
8eec07b5bd | ||
|
|
9f72a51458 | ||
|
|
9fd181ee06 | ||
|
|
f18875682b | ||
|
|
897a17e303 | ||
|
|
c9d0aafbfa | ||
|
|
fbd2a57a35 | ||
|
|
ccd5c91283 | ||
|
|
c78b9f07a2 | ||
|
|
ffc3300fe4 | ||
|
|
b02d32929c | ||
|
|
e29d3e3eaa | ||
|
|
5d91643637 | ||
|
|
9eec1adf77 | ||
|
|
9cebaa0d97 | ||
|
|
48cfebd5ae | ||
|
|
0c3899840b | ||
|
|
93bab6bbdd | ||
|
|
69368b884f | ||
|
|
f59b2d26ad | ||
|
|
32ffe33e1a | ||
|
|
cc5d119ba4 | ||
|
|
637727faa0 | ||
|
|
9b82cdfe53 | ||
|
|
2424c76c50 | ||
|
|
f0dc76c7a4 | ||
|
|
798f5cd0a6 | ||
|
|
a904896269 | ||
|
|
be482bd683 | ||
|
|
e9a624c896 | ||
|
|
b3a13a25f0 | ||
|
|
30e55f5acb | ||
|
|
7a67263cf9 | ||
|
|
b811906bae | ||
|
|
2a81d41c2c | ||
|
|
51d0037a4b | ||
|
|
25fc0226aa | ||
|
|
cfef06a15b | ||
|
|
5ce6aafc07 | ||
|
|
fe833033df | ||
|
|
a47be148c8 | ||
|
|
af426d28c1 | ||
|
|
0332b81d58 | ||
|
|
88b416c949 | ||
|
|
66c4e62d9b | ||
|
|
9091c2c346 | ||
|
|
e29ca2e79c | ||
|
|
afc3f48f51 | ||
|
|
eed8b36dc1 | ||
|
|
b20942d254 | ||
|
|
e707beffd6 | ||
|
|
747c75fb18 | ||
|
|
42f0a9df4b | ||
|
|
10ee6bcc7f | ||
|
|
bcba194a31 | ||
|
|
8605f63ac6 | ||
|
|
a02827a7ac | ||
|
|
16903b0f5a | ||
|
|
26bdf25423 | ||
|
|
3c0f4be533 | ||
|
|
ecf9dce758 | ||
|
|
90e40d5245 | ||
|
|
b76424ba9b | ||
|
|
ded75563e9 | ||
|
|
1eb9920bcf | ||
|
|
7e029b5495 | ||
|
|
37f9491d5e | ||
|
|
6aec78e153 | ||
|
|
685e34bc83 | ||
|
|
fb828788df | ||
|
|
eff49af00c | ||
|
|
7f02b85eb8 | ||
|
|
1de84c66d6 | ||
|
|
e382ccff9b | ||
|
|
33e6202835 | ||
|
|
bd8b8d5b64 | ||
|
|
db9dc18118 | ||
|
|
7cc373c07f | ||
|
|
aa87640687 | ||
|
|
6724912c73 | ||
|
|
2cabe6e58e | ||
|
|
33383cd3bd | ||
|
|
78c5250f1b | ||
|
|
9797d98fac | ||
|
|
43c2dc3dec | ||
|
|
50e140e606 | ||
|
|
3f88701751 | ||
|
|
7d89d53b1b | ||
|
|
09f7989cab | ||
|
|
6255cfd401 | ||
|
|
e7e4897dcd | ||
|
|
9639143893 | ||
|
|
3be3b0ca36 | ||
|
|
afc81b6308 | ||
|
|
36d140d4bd | ||
|
|
edff998be9 | ||
|
|
5a856e468e | ||
|
|
d2845f91b5 | ||
|
|
9040c13c3f | ||
|
|
7ed95ff523 | ||
|
|
aed9889a2e | ||
|
|
0090f484d8 | ||
|
|
0c576c65a8 | ||
|
|
b94cde5fbe | ||
|
|
df2582d1de | ||
|
|
f237a9aab5 | ||
|
|
12c370d7cb | ||
|
|
015c17e2dc | ||
|
|
d8a3466914 | ||
|
|
05d2ffe8fa | ||
|
|
a62d8304e2 | ||
|
|
e51ee8c1ad | ||
|
|
6d0f668f88 | ||
|
|
ed5e590859 | ||
|
|
346fa2c004 | ||
|
|
db04b0c285 | ||
|
|
07800bdb83 | ||
|
|
ad8b338bd9 | ||
|
|
031c0c263d | ||
|
|
d54053003e | ||
|
|
adb453c216 | ||
|
|
ef04e43323 | ||
|
|
9ff5147418 | ||
|
|
cdbedf3d64 | ||
|
|
3d52fa059e | ||
|
|
ef46d1a308 | ||
|
|
d57cfa90fc | ||
|
|
7aece7dd7e | ||
|
|
ccf362db41 | ||
|
|
7bd4002f09 | ||
|
|
9460b12cf9 | ||
|
|
8cac592182 | ||
|
|
83b25b0c33 | ||
|
|
1832ec753c | ||
|
|
0c4f943d72 | ||
|
|
116ee25e28 | ||
|
|
6149c2a8a8 | ||
|
|
b2e475b857 | ||
|
|
f7e4e98b01 | ||
|
|
c4a9919652 | ||
|
|
5c1fb7d4e8 | ||
|
|
b1d0a4e7ad | ||
|
|
75db995342 | ||
|
|
c318856534 | ||
|
|
cf42e1846e | ||
|
|
56a5ebbb9d | ||
|
|
7431e1e605 | ||
|
|
4b6a460e69 | ||
|
|
f6f0c2f1dc | ||
|
|
90357ae386 | ||
|
|
bdc6b08234 | ||
|
|
1ba68d67ba | ||
|
|
d0518e6dfe | ||
|
|
3be6a78568 | ||
|
|
a6b8881e30 | ||
|
|
23c057ac08 | ||
|
|
07460ba06f | ||
|
|
bcbedbe053 | ||
|
|
ba26037c7f | ||
|
|
60243215a0 | ||
|
|
9c3ab28da9 | ||
|
|
2b1076f09e | ||
|
|
241859232b | ||
|
|
456fdc0fca | ||
|
|
be84bd27d3 | ||
|
|
2e84788d53 | ||
|
|
76b3b3b23d | ||
|
|
426c88c4ed | ||
|
|
d625b0d567 | ||
|
|
e350c5f070 | ||
|
|
1e481edc67 | ||
|
|
12f02dda98 | ||
|
|
ef50d90a18 | ||
|
|
25ae72cd26 | ||
|
|
eb8f83786c | ||
|
|
cd7b075016 | ||
|
|
19068dc6b0 | ||
|
|
93ba0bd807 | ||
|
|
15a76486ef | ||
|
|
f01e367785 | ||
|
|
9b536f8dc1 | ||
|
|
664a0e4ad8 | ||
|
|
9ed64354fc | ||
|
|
f59a160249 | ||
|
|
cdd7774a73 | ||
|
|
a10777d598 | ||
|
|
a4c5670409 | ||
|
|
343c53b41c | ||
|
|
4c97bc34ce | ||
|
|
83f0ca918a | ||
|
|
bc7c3968b6 | ||
|
|
1aba217b1a | ||
|
|
a95e87a08f | ||
|
|
b75e299b2f | ||
|
|
3e63b49c3c | ||
|
|
1eaf2372bb | ||
|
|
8b8400e5be | ||
|
|
c6551c9ea3 | ||
|
|
b04c676288 | ||
|
|
01e2a2bdb2 | ||
|
|
670533807a | ||
|
|
9d1270374e | ||
|
|
353e8bd0de | ||
|
|
9ca0ec82a8 | ||
|
|
bb5fd44750 | ||
|
|
1e435b0ff8 | ||
|
|
bb080c2d18 | ||
|
|
91063075d3 | ||
|
|
ccaf485c91 | ||
|
|
125207226b | ||
|
|
393affbd90 | ||
|
|
4f06fe45d3 | ||
|
|
ba1a981c87 | ||
|
|
6d51240a27 | ||
|
|
527143405f | ||
|
|
2808fdd3c0 | ||
|
|
a2c84392f4 | ||
|
|
3fdff4e6eb | ||
|
|
dd41e00691 | ||
|
|
29bcaa9558 | ||
|
|
3be3e8546f | ||
|
|
0bbb760e61 | ||
|
|
4f238f4f62 | ||
|
|
a244c6d5e3 | ||
|
|
aa5765971e | ||
|
|
2a66edd1c5 | ||
|
|
a6e86e8d6b | ||
|
|
f30cb9da59 | ||
|
|
e94d17a922 | ||
|
|
53f5c168ad | ||
|
|
4533f7b1d5 | ||
|
|
b9398e882a | ||
|
|
66f19d72da | ||
|
|
35e85cfdcb | ||
|
|
6d6b63cce1 | ||
|
|
a7d5e77a1c | ||
|
|
0332b22c4a | ||
|
|
09a7974818 | ||
|
|
66d2f0d550 | ||
|
|
d2556fed20 | ||
|
|
49cd8536a7 | ||
|
|
b8f15bcca9 | ||
|
|
a17ba9f62c | ||
|
|
a9aa9a2e20 | ||
|
|
43da07ca4c | ||
|
|
1b22abcd50 | ||
|
|
f85c83169d | ||
|
|
ecff344473 | ||
|
|
cde380782f | ||
|
|
d557149326 | ||
|
|
ecdcb040ee | ||
|
|
e58471fe37 | ||
|
|
30e66473db | ||
|
|
5357ed3746 | ||
|
|
337f443cbf | ||
|
|
e7ad1b8496 | ||
|
|
aea01de449 | ||
|
|
b7fb75a49e | ||
|
|
57752d09cd | ||
|
|
bd395f557a | ||
|
|
2d865d8fed | ||
|
|
5bff74e7a9 | ||
|
|
a9e3723764 | ||
|
|
b811227c41 | ||
|
|
4896c4dda5 | ||
|
|
b4ee1ade2d | ||
|
|
a6e2308282 | ||
|
|
f56c42f353 | ||
|
|
5edf51810d | ||
|
|
81985b0e31 | ||
|
|
163830f1bd | ||
|
|
867ae2991c | ||
|
|
ee3d04ba23 | ||
|
|
71dd8c14f8 | ||
|
|
88dc9c2a74 | ||
|
|
98f012de4d | ||
|
|
c85a036ac6 | ||
|
|
1f8b632d95 | ||
|
|
59dd56e542 | ||
|
|
1bfa8dcb3f | ||
|
|
1b381af7a7 | ||
|
|
2bc4912416 | ||
|
|
474f0d8291 | ||
|
|
231fe54408 |
@@ -1,21 +0,0 @@
|
||||
platform:
|
||||
- x64
|
||||
|
||||
cache:
|
||||
- node_modules
|
||||
- '%APPDATA%\npm-cache'
|
||||
- '%LOCALAPPDATA%\electron\Cache'
|
||||
- '%LOCALAPPDATA%\electron-builder\Cache'
|
||||
|
||||
install:
|
||||
- ps: Install-Product node 12 x64
|
||||
- npm install
|
||||
|
||||
build_script:
|
||||
- npm run publish:gh
|
||||
|
||||
test: off
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
22
.babelrc
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"presets": [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"corejs": "3",
|
||||
"useBuiltIns": "usage"
|
||||
}
|
||||
],
|
||||
[
|
||||
"minify",
|
||||
{
|
||||
"builtIns": false,
|
||||
"evaluate": false,
|
||||
"mangle": false
|
||||
}
|
||||
]
|
||||
],
|
||||
"plugins": [
|
||||
"@babel/plugin-syntax-dynamic-import"
|
||||
]
|
||||
}
|
||||
24
.eslintrc
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"extends": "standard",
|
||||
"plugins": [
|
||||
"html"
|
||||
],
|
||||
"parser": "babel-eslint",
|
||||
"rules": {
|
||||
"no-new": "off",
|
||||
"camelcase": "off",
|
||||
"no-return-assign": "off",
|
||||
"space-before-function-paren": ["error", "never"],
|
||||
"no-var": "error",
|
||||
"no-fallthrough": "off",
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"eqeqeq": "off",
|
||||
"no-multiple-empty-lines": [1, {"max": 2}],
|
||||
"comma-dangle": [2, "always-multiline"],
|
||||
"standard/no-callback-literal": "off",
|
||||
"prefer-const": "off"
|
||||
},
|
||||
"settings": {
|
||||
"html/html-extensions": [".html", ".vue"]
|
||||
}
|
||||
}
|
||||
97
.eslintrc.base.cjs
Normal file
@@ -0,0 +1,97 @@
|
||||
const baseRule = {
|
||||
'no-new': 'off',
|
||||
camelcase: 'off',
|
||||
'no-return-assign': 'off',
|
||||
'space-before-function-paren': ['error', 'never'],
|
||||
'no-var': 'error',
|
||||
'no-fallthrough': 'off',
|
||||
eqeqeq: 'off',
|
||||
'require-atomic-updates': ['error', { allowProperties: true }],
|
||||
'no-multiple-empty-lines': [1, { max: 2 }],
|
||||
'comma-dangle': [2, 'always-multiline'],
|
||||
'standard/no-callback-literal': 'off',
|
||||
'prefer-const': 'off',
|
||||
'no-labels': 'off',
|
||||
'node/no-callback-literal': 'off',
|
||||
'multiline-ternary': 'off',
|
||||
}
|
||||
const typescriptRule = {
|
||||
...baseRule,
|
||||
'@typescript-eslint/strict-boolean-expressions': 'off',
|
||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||
'@typescript-eslint/space-before-function-paren': 'off',
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
'@typescript-eslint/restrict-template-expressions': [1, {
|
||||
allowBoolean: true,
|
||||
allowAny: true,
|
||||
}],
|
||||
'@typescript-eslint/restrict-plus-operands': [1, {
|
||||
allowBoolean: true,
|
||||
allowAny: true,
|
||||
}],
|
||||
'@typescript-eslint/no-misused-promises': [
|
||||
'error',
|
||||
{
|
||||
checksVoidReturn: {
|
||||
arguments: false,
|
||||
attributes: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
'@typescript-eslint/naming-convention': 'off',
|
||||
'@typescript-eslint/return-await': 'off',
|
||||
'@typescript-eslint/ban-ts-comment': 'off',
|
||||
'@typescript-eslint/comma-dangle': 'off',
|
||||
'@typescript-eslint/no-unsafe-argument': 'off',
|
||||
}
|
||||
const vueRule = {
|
||||
...typescriptRule,
|
||||
'vue/multi-word-component-names': 'off',
|
||||
'vue/max-attributes-per-line': 'off',
|
||||
'vue/singleline-html-element-content-newline': 'off',
|
||||
'vue/use-v-on-exact': 'off',
|
||||
}
|
||||
|
||||
exports.base = {
|
||||
extends: ['standard'],
|
||||
rules: baseRule,
|
||||
}
|
||||
|
||||
exports.html = {
|
||||
files: ['*.html'],
|
||||
plugins: ['html'],
|
||||
}
|
||||
|
||||
exports.typescript = {
|
||||
files: ['*.ts'],
|
||||
rules: typescriptRule,
|
||||
parser: '@typescript-eslint/parser',
|
||||
extends: [
|
||||
'standard-with-typescript',
|
||||
],
|
||||
}
|
||||
|
||||
exports.vue = {
|
||||
files: ['*.vue'],
|
||||
rules: vueRule,
|
||||
parser: 'vue-eslint-parser',
|
||||
extends: [
|
||||
// 'plugin:vue/vue3-essential',
|
||||
'plugin:vue/base',
|
||||
'plugin:vue/vue3-recommended',
|
||||
'plugin:vue-pug/vue3-recommended',
|
||||
// "plugin:vue/strongly-recommended"
|
||||
'standard-with-typescript',
|
||||
],
|
||||
parserOptions: {
|
||||
sourceType: 'module',
|
||||
parser: {
|
||||
// Script parser for `<script>`
|
||||
js: '@typescript-eslint/parser',
|
||||
|
||||
// Script parser for `<script lang="ts">`
|
||||
ts: '@typescript-eslint/parser',
|
||||
},
|
||||
extraFileExtensions: ['.vue'],
|
||||
},
|
||||
}
|
||||
20
.eslintrc.cjs
Normal file
@@ -0,0 +1,20 @@
|
||||
const { base, typescript } = require('./.eslintrc.base.cjs')
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
...base,
|
||||
overrides: [
|
||||
{
|
||||
...typescript,
|
||||
parserOptions: {
|
||||
project: './tsconfig.json',
|
||||
},
|
||||
},
|
||||
],
|
||||
ignorePatterns: [
|
||||
'node_modules',
|
||||
'*.min.js',
|
||||
'dist',
|
||||
'build',
|
||||
],
|
||||
}
|
||||
17
.github/ISSUE_TEMPLATE/----.md
vendored
@@ -1,17 +0,0 @@
|
||||
---
|
||||
name: 功能请求(请先查看常见问题及搜索issue列表中有无你要提的问题)
|
||||
about: 为这个项目提出一个想法
|
||||
title: 例如:添加xxx功能、优化xxx功能
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**描述您想要的解决方案**
|
||||
简洁明了地描述您要发生的事情。
|
||||
|
||||
**描述您考虑过的替代方案**
|
||||
对您考虑过的所有替代解决方案或功能的简洁明了的描述。
|
||||
|
||||
**其他内容**
|
||||
在此处添加有关功能请求的任何其他上下文或屏幕截图。
|
||||
31
.github/ISSUE_TEMPLATE/--bug.md
vendored
@@ -1,31 +0,0 @@
|
||||
---
|
||||
name: 报告Bug(请先查看常见问题及搜索issue列表中有无你要提的问题)
|
||||
about: 创建报告以帮助我们改进
|
||||
title: 例如:音乐无法播放
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**描述错误**
|
||||
清楚简洁地说明错误是什么。
|
||||
|
||||
**重现**
|
||||
重现行为的步骤:
|
||||
1.转到“ ...”
|
||||
2.点击“ ....”
|
||||
3.向下滚动到“ ....”
|
||||
4.看到错误
|
||||
|
||||
**预期行为**
|
||||
对您期望发生的事情的简洁明了的描述。
|
||||
|
||||
**截图**
|
||||
如果适用,请添加屏幕截图以帮助解释您的问题。
|
||||
|
||||
**环境:**
|
||||
-操作系统及版本:[例如:Windows 10 64位 18362.156]
|
||||
-软件安装包及版本:[例如:Windows 64位绿色版 1.0.0]
|
||||
|
||||
**其他内容**
|
||||
在此处添加有关该问题的任何其他上下文。
|
||||
59
.github/ISSUE_TEMPLATE/bug.yml
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
name: 🐞 报告错误
|
||||
description: 报告一个错误(Bug),请先查看常见问题及搜索 Issue 列表中有无你要提的问题。
|
||||
title: "[Bug]: "
|
||||
body:
|
||||
- type: checkboxes
|
||||
id: check-answer
|
||||
attributes:
|
||||
label: 解决方案检查
|
||||
description: 请确保你已完成以下所有操作。
|
||||
options:
|
||||
- label: 我已阅读 [常见问题](https://lyswhut.github.io/lx-music-doc/desktop/faq),并没有找到解决方案。
|
||||
required: true
|
||||
- label: 我已搜索 [Issue 列表](https://github.com/lyswhut/lx-music-desktop/issues?q=is%3Aissue+),并没有发现类似的问题。
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expected-behavior
|
||||
attributes:
|
||||
label: 预期行为
|
||||
description: 对期望发生的事情的清晰简明描述。
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: actual-behavior
|
||||
attributes:
|
||||
label: 实际行为
|
||||
description: 对实际发生的事情的清晰简明描述。
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: LX Music 版本
|
||||
description: 你使用什么版本的 LX Music?
|
||||
placeholder: 例如 2.9.0
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: last-known-working-version
|
||||
attributes:
|
||||
label: 最后正常的版本
|
||||
description: 如果有,请在此处填写最后正常的版本。
|
||||
placeholder: 例如 2.8.0
|
||||
- type: input
|
||||
id: operating-system-version
|
||||
attributes:
|
||||
label: 操作系统版本
|
||||
description: |
|
||||
你使用什么版本的操作系统?
|
||||
在 macOS 上,单击「Apple 菜单 > 关于本机」;
|
||||
在 Linux 上,执行 `lsb_release` 或 `uname -a` 命令;
|
||||
在 Windows 上,单击「开始按钮 > 设置 > 系统 > 关于」。
|
||||
placeholder: "例如 Windows 11 版本 24H2、macOS Sequoia 15.1.1 或 Ubuntu 24.10"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: additional-information
|
||||
attributes:
|
||||
label: 附加信息
|
||||
description: 如果你的问题需要进一步解释,或者你所遇到的问题不容易重现,请在此处添加更多信息。(直接把图片/视频拖到编辑框即可添加图片/视频)
|
||||
38
.github/ISSUE_TEMPLATE/feature.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
name: ✨ 功能请求
|
||||
description: 为这个项目提出一个想法,请先查看常见问题及搜索 Issue 列表中有无你要提的问题。
|
||||
title: "[Feature]: "
|
||||
body:
|
||||
- type: checkboxes
|
||||
id: check-answer
|
||||
attributes:
|
||||
label: 解决方案检查
|
||||
description: 请确保你已完成以下所有操作。
|
||||
options:
|
||||
- label: 我已阅读 [常见问题](https://lyswhut.github.io/lx-music-doc/desktop/faq),但没有找到解决方案。
|
||||
required: true
|
||||
- label: 我已搜索 [Issue 列表](https://github.com/lyswhut/lx-music-desktop/issues?q=is%3Aissue+),但没有发现类似的问题。
|
||||
required: true
|
||||
- type: textarea
|
||||
id: problem-description
|
||||
attributes:
|
||||
label: 问题描述
|
||||
description: 请添加清晰简洁的描述,说明你希望通过此功能请求解决的问题。
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: proposed-solution
|
||||
attributes:
|
||||
label: 描述你想要的解决方案
|
||||
description: 简洁明了地描述你要发生的事情。
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: alternatives-considered
|
||||
attributes:
|
||||
label: 描述你考虑过的替代方案
|
||||
description: 对你考虑过的所有替代解决方案或功能的简洁明了的描述。
|
||||
- type: textarea
|
||||
id: additional-information
|
||||
attributes:
|
||||
label: 附加信息
|
||||
description: 如果你的问题需要进一步解释,或者想要表达其他内容,请在此处添加更多信息。(直接把图片/视频拖到编辑框即可添加图片/视频)
|
||||
28
.github/actions/setup/action.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
name: Setup
|
||||
description: Setup Node Env
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '22'
|
||||
|
||||
# - name: Get npm cache directory
|
||||
# run: node -p -e '`NPM_CACHE_DIR=${require("child_process").execSync("npm config get cache").toString()}`' >> $GITHUB_ENV
|
||||
# run: echo "NPM_CACHE_DIR=$(npm config get cache)" >> $GITHUB_ENV
|
||||
|
||||
# https://docs.npmjs.com/cli/v10/configuring-npm/folders#cache
|
||||
- name: Cache node modules
|
||||
id: cache-npm
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ${{ env.NPM_CACHE }}
|
||||
key: ${{ runner.os }}-npm-cache-${{ hashFiles('package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-npm-cache-
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
shell: bash
|
||||
291
.github/workflows/beta-pack.yml
vendored
Normal file
@@ -0,0 +1,291 @@
|
||||
name: Build Beta
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- beta
|
||||
|
||||
env:
|
||||
IS_CI: 'true'
|
||||
|
||||
jobs:
|
||||
# CheckCode:
|
||||
# name: Lint Code
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - name: Check out git repository
|
||||
# uses: actions/checkout@v6
|
||||
|
||||
# - name: Install Node.js
|
||||
# uses: actions/setup-node@v4
|
||||
# with:
|
||||
# node-version: 20
|
||||
|
||||
# - name: Cache file
|
||||
# uses: actions/cache@v4
|
||||
# with:
|
||||
# path: |
|
||||
# node_modules
|
||||
# $HOME/.cache/electron
|
||||
# $HOME/.cache/electron-builder
|
||||
# $HOME/.npm/_prebuilds
|
||||
# key: ${{ runner.os }}-build-caches-${{ hashFiles('**/package-lock.json') }}
|
||||
# restore-keys: |
|
||||
# ${{ runner.os }}-build-
|
||||
|
||||
# - name: Install Dependencies
|
||||
# run: |
|
||||
# npm ci
|
||||
|
||||
# - name: Lint src code
|
||||
# run: npm run lint
|
||||
|
||||
Windows:
|
||||
name: Windows
|
||||
runs-on: windows-latest
|
||||
# needs: CheckCode
|
||||
steps:
|
||||
- name: Check out git repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Get npm cache directory
|
||||
shell: pwsh
|
||||
run: echo "NPM_CACHE=$(npm config get cache)" >> $env:GITHUB_ENV
|
||||
|
||||
- name: Setup Node Env
|
||||
env:
|
||||
NPM_CACHE: ${{ env.NPM_CACHE }}
|
||||
uses: ./.github/actions/setup
|
||||
|
||||
- name: Build src code
|
||||
run: |
|
||||
git status --porcelain
|
||||
npm run build
|
||||
|
||||
- name: Build Package Setup x64
|
||||
run: npm run pack:win:setup:x64
|
||||
- name: Upload Artifact Setup x64
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: lx-music-desktop-x64-Setup
|
||||
path: build/*-x64-Setup.exe
|
||||
|
||||
- name: Build Package 7z x64
|
||||
run: npm run pack:win:7z:x64
|
||||
- name: Upload Artifact 7z x64
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: lx-music-desktop-win_x64-green
|
||||
path: build/*win_x64-green.7z
|
||||
|
||||
- name: Build Package Setup arm64
|
||||
run: npm run pack:win:setup:arm64
|
||||
- name: Upload Artifact Setup arm64
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: lx-music-desktop-arm64-Setup
|
||||
path: build/*-arm64-Setup.exe
|
||||
|
||||
- name: Build Package 7z arm64
|
||||
run: npm run pack:win:7z:arm64
|
||||
- name: Upload Artifact 7z arm64
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: lx-music-desktop-win_arm64-green
|
||||
path: build/*win_arm64-green.7z
|
||||
|
||||
- name: Generate file MD5
|
||||
run: |
|
||||
cd build
|
||||
Get-FileHash *.exe,*.7z -Algorithm MD5 | Format-List
|
||||
|
||||
Windows_7:
|
||||
name: Windows_7
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
BUILD_WIN7: true
|
||||
# needs: CheckCode
|
||||
steps:
|
||||
- name: Check out git repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Get npm cache directory
|
||||
shell: pwsh
|
||||
run: echo "NPM_CACHE=$(npm config get cache)" >> $env:GITHUB_ENV
|
||||
|
||||
- name: Setup Node Env
|
||||
env:
|
||||
NPM_CACHE: ${{ env.NPM_CACHE }}
|
||||
uses: ./.github/actions/setup
|
||||
|
||||
- name: Prepare win7 undici env
|
||||
run: |
|
||||
npm install undici@5
|
||||
Set-Content -Path .\src\common\utils\request.ts -Value "export * from './request_node16'"
|
||||
|
||||
- name: Build src code
|
||||
env:
|
||||
BUILD_WIN7: true
|
||||
run: |
|
||||
git status --porcelain
|
||||
npm run build
|
||||
|
||||
- name: Prepare win7 electron env
|
||||
run: |
|
||||
npm install electron@22 better-sqlite3@12
|
||||
pip.exe install setuptools
|
||||
|
||||
- name: Build Package win7 Setup x64
|
||||
run: npm run pack:win7:setup:x64
|
||||
- name: Upload Artifact win7 Setup x64
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: lx-music-desktop-win7_x64-Setup
|
||||
path: build/*win7_x64-Setup.exe
|
||||
|
||||
- name: Build Package win7 7z x64
|
||||
run: npm run pack:win7:7z:x64
|
||||
- name: Upload Artifact win7 7z x64
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: lx-music-desktop-win7_x64-green
|
||||
path: build/*win7_x64-green.7z
|
||||
|
||||
- name: Build Package win7 7z x86
|
||||
run: npm run pack:win7:7z:x86
|
||||
- name: Upload Artifact win7 7z x86
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: lx-music-desktop-win7_x86-green
|
||||
path: build/*win7_x86-green.7z
|
||||
|
||||
- name: Generate file MD5
|
||||
run: |
|
||||
cd build
|
||||
Get-FileHash *.exe,*.7z -Algorithm MD5 | Format-List
|
||||
|
||||
Mac:
|
||||
name: Mac
|
||||
runs-on: macos-latest
|
||||
# needs: CheckCode
|
||||
steps:
|
||||
- name: Check out git repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install python setuptools
|
||||
run: brew install python-setuptools
|
||||
|
||||
- name: Get npm cache directory
|
||||
shell: bash
|
||||
run: echo "NPM_CACHE=$(npm config get cache)" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup Node Env
|
||||
env:
|
||||
NPM_CACHE: ${{ env.NPM_CACHE }}
|
||||
uses: ./.github/actions/setup
|
||||
|
||||
- name: Build src code
|
||||
run: |
|
||||
git status --porcelain
|
||||
npm run build
|
||||
|
||||
- name: Build Package dmg
|
||||
run: |
|
||||
npm run pack:mac:dmg
|
||||
npm run pack:mac:dmg:arm64
|
||||
|
||||
- name: Upload Artifact dmg
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: lx-music-desktop-mac-dmg
|
||||
path: |
|
||||
build/*.dmg
|
||||
!build/*-arm64.dmg
|
||||
- name: Upload Artifact dmg
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: lx-music-desktop-mac-dmg-arm64
|
||||
path: build/*-arm64.dmg
|
||||
|
||||
- name: Generate file MD5
|
||||
run: |
|
||||
cd build
|
||||
md5 *.dmg
|
||||
|
||||
Linux:
|
||||
name: Linux
|
||||
runs-on: ubuntu-latest
|
||||
# needs: CheckCode
|
||||
steps:
|
||||
- name: Install package
|
||||
run: sudo apt-get update && sudo apt-get install -y rpm libarchive-tools
|
||||
|
||||
- name: Check out git repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Get npm cache directory
|
||||
shell: bash
|
||||
run: echo "NPM_CACHE=$(npm config get cache)" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup Node Env
|
||||
env:
|
||||
NPM_CACHE: ${{ env.NPM_CACHE }}
|
||||
uses: ./.github/actions/setup
|
||||
|
||||
- name: Build src code
|
||||
run: |
|
||||
git status --porcelain
|
||||
npm run build
|
||||
|
||||
- name: Build Package deb amd64
|
||||
run: npm run pack:linux:deb:amd64
|
||||
- name: Upload Artifact deb amd64
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: lx-music-desktop-deb-amd64
|
||||
path: build/*_amd64.deb
|
||||
|
||||
- name: Build Package deb arm64
|
||||
run: npm run pack:linux:deb:arm64
|
||||
- name: Upload Artifact deb arm64
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: lx-music-desktop-deb-arm64
|
||||
path: build/*_arm64.deb
|
||||
|
||||
- name: Build Package deb armv7l
|
||||
run: npm run pack:linux:deb:armv7l
|
||||
- name: Upload Artifact deb armv7l
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: lx-music-desktop-deb-armv7l
|
||||
path: build/*_armv7l.deb
|
||||
|
||||
- name: Build Package x64 appImage
|
||||
run: npm run pack:linux:appImage
|
||||
- name: Upload Artifact x64 appImage
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: lx-music-desktop-x64-appImage
|
||||
path: build/*_x64.AppImage
|
||||
|
||||
- name: Build Package x64 rpm
|
||||
run: npm run pack:linux:rpm
|
||||
- name: Upload Artifact x64 rpm
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: lx-music-desktop-x64-rpm
|
||||
path: build/*.x64.rpm
|
||||
|
||||
- name: Build Package x64 pacman
|
||||
run: npm run pack:linux:pacman
|
||||
- name: Upload Artifact x64 pacman
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: lx-music-desktop-x64-pacman
|
||||
path: build/*_x64.pacman
|
||||
|
||||
- name: Generate file MD5
|
||||
run: |
|
||||
cd build
|
||||
md5sum *.deb *.rpm *.pacman *.AppImage
|
||||
28
.github/workflows/build-test.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
name: Run build test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- dev
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out git repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Eslint check
|
||||
run: npm run lint
|
||||
|
||||
- name: Test Build
|
||||
run: npm run build
|
||||
16
.github/workflows/publish-version-info.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
name: Publish NPM Version Info
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
dispatch:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Repository Dispatch
|
||||
uses: peter-evans/repository-dispatch@v4
|
||||
with:
|
||||
token: ${{ secrets.PAT }}
|
||||
repository: lyswhut/lx-music-desktop-version-info
|
||||
event-type: npm-release
|
||||
214
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,214 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
env:
|
||||
IS_CI: 'true'
|
||||
|
||||
jobs:
|
||||
# CheckCode:
|
||||
# name: Lint Code
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - name: Check out git repository
|
||||
# uses: actions/checkout@v6
|
||||
|
||||
# - name: Install Node.js
|
||||
# uses: actions/setup-node@v4
|
||||
# with:
|
||||
# node-version: 20
|
||||
|
||||
# - name: Cache file
|
||||
# uses: actions/cache@v4
|
||||
# with:
|
||||
# path: |
|
||||
# node_modules
|
||||
# $HOME/.cache/electron
|
||||
# $HOME/.cache/electron-builder
|
||||
# $HOME/.npm/_prebuilds
|
||||
# key: ${{ runner.os }}-build-caches-${{ hashFiles('**/package-lock.json') }}
|
||||
# restore-keys: |
|
||||
# ${{ runner.os }}-build-
|
||||
|
||||
# - name: Install Dependencies
|
||||
# run: |
|
||||
# npm ci
|
||||
|
||||
# - name: Lint src code
|
||||
# run: npm run lint
|
||||
|
||||
Windows:
|
||||
name: Windows
|
||||
runs-on: windows-latest
|
||||
# needs: CheckCode
|
||||
steps:
|
||||
- name: Check out git repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Get npm cache directory
|
||||
shell: pwsh
|
||||
run: echo "NPM_CACHE=$(npm config get cache)" >> $env:GITHUB_ENV
|
||||
|
||||
- name: Show Env
|
||||
run: echo "${{ env.NPM_CACHE }}"
|
||||
|
||||
- name: Setup Node Env
|
||||
env:
|
||||
NPM_CACHE: ${{ env.NPM_CACHE }}
|
||||
uses: ./.github/actions/setup
|
||||
|
||||
- name: Build src code
|
||||
run: |
|
||||
git status --porcelain
|
||||
npm run build
|
||||
|
||||
- name: Release package
|
||||
run: |
|
||||
npm run publish:win:7z:x64
|
||||
npm run publish:win:7z:arm64
|
||||
npm run publish:win:setup:arm64
|
||||
npm run publish:win:setup:x64
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
BT_TOKEN: ${{ secrets.BT_TOKEN }}
|
||||
|
||||
- name: Generate file MD5
|
||||
run: |
|
||||
cd build
|
||||
Get-FileHash *.exe,*.7z -Algorithm MD5 | Format-List
|
||||
|
||||
|
||||
Windows_7:
|
||||
name: Windows_7
|
||||
runs-on: windows-latest
|
||||
# needs: CheckCode
|
||||
steps:
|
||||
- name: Check out git repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Get npm cache directory
|
||||
shell: pwsh
|
||||
run: echo "NPM_CACHE=$(npm config get cache)" >> $env:GITHUB_ENV
|
||||
|
||||
- name: Setup Node Env
|
||||
env:
|
||||
NPM_CACHE: ${{ env.NPM_CACHE }}
|
||||
uses: ./.github/actions/setup
|
||||
|
||||
- name: Prepare win7 undici env
|
||||
run: |
|
||||
npm install undici@5
|
||||
Set-Content -Path .\src\common\utils\request.ts -Value "export * from './request_node16'"
|
||||
|
||||
- name: Build src code
|
||||
env:
|
||||
BUILD_WIN7: true
|
||||
run: |
|
||||
git status --porcelain
|
||||
npm run build
|
||||
|
||||
- name: Prepare win7 electron env
|
||||
run: |
|
||||
npm install electron@22 better-sqlite3@12
|
||||
pip.exe install setuptools
|
||||
|
||||
- name: Release win7 package
|
||||
run: |
|
||||
npm run publish:win7:setup:x64
|
||||
npm run publish:win7:7z:x64
|
||||
npm run publish:win7:7z:x86
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
BT_TOKEN: ${{ secrets.BT_TOKEN }}
|
||||
|
||||
- name: Generate file MD5
|
||||
run: |
|
||||
cd build
|
||||
Get-FileHash *.exe,*.7z -Algorithm MD5 | Format-List
|
||||
|
||||
Mac:
|
||||
name: Mac
|
||||
runs-on: macos-latest
|
||||
# needs: CheckCode
|
||||
steps:
|
||||
- name: Check out git repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install python3 setuptools
|
||||
run: brew install python-setuptools
|
||||
|
||||
- name: Get npm cache directory
|
||||
shell: bash
|
||||
run: echo "NPM_CACHE=$(npm config get cache)" >> $GITHUB_ENV
|
||||
|
||||
- name: Show Env
|
||||
run: echo "${{ env.NPM_CACHE }}"
|
||||
- name: Setup Node Env
|
||||
env:
|
||||
NPM_CACHE: ${{ env.NPM_CACHE }}
|
||||
uses: ./.github/actions/setup
|
||||
|
||||
- name: Build src code
|
||||
run: |
|
||||
git status --porcelain
|
||||
npm run build
|
||||
|
||||
- name: Release package
|
||||
run: |
|
||||
npm run publish:mac:dmg
|
||||
npm run publish:mac:dmg:arm64
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
BT_TOKEN: ${{ secrets.BT_TOKEN }}
|
||||
|
||||
- name: Generate file MD5
|
||||
run: |
|
||||
cd build
|
||||
md5 *.dmg
|
||||
|
||||
Linux:
|
||||
name: Linux
|
||||
runs-on: ubuntu-latest
|
||||
# needs: CheckCode
|
||||
steps:
|
||||
- name: Install package
|
||||
run: sudo apt-get update && sudo apt-get install -y rpm libarchive-tools
|
||||
|
||||
- name: Check out git repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Get npm cache directory
|
||||
shell: bash
|
||||
run: echo "NPM_CACHE=$(npm config get cache)" >> $GITHUB_ENV
|
||||
|
||||
- name: Show Env
|
||||
run: echo "${{ env.NPM_CACHE }}"
|
||||
- name: Setup Node Env
|
||||
env:
|
||||
NPM_CACHE: ${{ env.NPM_CACHE }}
|
||||
uses: ./.github/actions/setup
|
||||
|
||||
- name: Build src code
|
||||
run: |
|
||||
git status --porcelain
|
||||
npm run build
|
||||
|
||||
- name: Release package
|
||||
run: |
|
||||
npm run publish:linux:deb:amd64
|
||||
npm run publish:linux:deb:arm64
|
||||
npm run publish:linux:deb:armv7l
|
||||
npm run publish:linux:appImage
|
||||
npm run publish:linux:rpm
|
||||
npm run publish:linux:pacman
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
BT_TOKEN: ${{ secrets.BT_TOKEN }}
|
||||
|
||||
- name: Generate file MD5
|
||||
run: |
|
||||
cd build
|
||||
md5sum *.deb *.rpm *.pacman *.AppImage
|
||||
59
.ncurc.js
Normal file
@@ -0,0 +1,59 @@
|
||||
module.exports = {
|
||||
upgrade: true,
|
||||
reject: [
|
||||
'electron',
|
||||
'chalk',
|
||||
'del',
|
||||
'comlink',
|
||||
'vue',
|
||||
'vue-router',
|
||||
'image-size',
|
||||
'message2call',
|
||||
'@types/ws',
|
||||
'eslint',
|
||||
'@types/node',
|
||||
'electron-debug',
|
||||
'eslint-webpack-plugin',
|
||||
'typescript',
|
||||
'undici',
|
||||
'@types/better-sqlite3',
|
||||
'changelog-parser',
|
||||
'webpack-dev-server',
|
||||
|
||||
'eslint-plugin-vue',
|
||||
'vue-eslint-parser',
|
||||
// 'eslint-config-standard-with-typescript',
|
||||
|
||||
'webpack',
|
||||
],
|
||||
|
||||
// target: 'newest',
|
||||
// filter: [
|
||||
// 'electron-builder',
|
||||
// 'electron-updater',
|
||||
// ],
|
||||
|
||||
// target: 'patch',
|
||||
// filter: [
|
||||
// 'electron',
|
||||
// 'vue',
|
||||
// 'vue-router',
|
||||
// ],
|
||||
|
||||
// target: 'minor',
|
||||
// filter: [
|
||||
// 'electron',
|
||||
// 'eslint',
|
||||
// 'eslint-webpack-plugin',
|
||||
// 'electron-debug',
|
||||
// 'typescript',
|
||||
// '@types/node',
|
||||
// 'undici',
|
||||
|
||||
// 'eslint-plugin-vue',
|
||||
// 'vue-eslint-parser',
|
||||
// 'better-sqlite3',
|
||||
// '@types/better-sqlite3',
|
||||
// 'webpack-dev-server',
|
||||
// ],
|
||||
}
|
||||
43
.travis.yml
@@ -1,43 +0,0 @@
|
||||
sudo: true
|
||||
language: node_js
|
||||
node_js: 12
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: osx
|
||||
osx_image: xcode10.2
|
||||
env:
|
||||
- ELECTRON_CACHE=$HOME/.cache/electron
|
||||
- ELECTRON_BUILDER_CACHE=$HOME/.cache/electron-builder
|
||||
|
||||
- os: linux
|
||||
dist: trusty
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
||||
- $HOME/.cache/electron
|
||||
- $HOME/.cache/electron-builder
|
||||
- $HOME/.npm/_prebuilds
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
script:
|
||||
- node --version
|
||||
- npm --version
|
||||
- |
|
||||
if [ "$TRAVIS_OS_NAME" == "linux" ]; then
|
||||
npm install && npm run publish:gh:linux
|
||||
else
|
||||
npm run publish:gh:mac
|
||||
fi
|
||||
|
||||
before_cache:
|
||||
- rm -rf $HOME/.cache/electron-builder/wine
|
||||
|
||||
# only run this script on pull requests and merges into
|
||||
# the 'master' and 'prod' branches
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
29
.vscode/i18n-ally-custom-framework.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
# .vscode/i18n-ally-custom-framework.yml
|
||||
|
||||
# An array of strings which contain Language Ids defined by VS Code
|
||||
# You can check avaliable language ids here: https://code.visualstudio.com/docs/languages/overview#_language-id
|
||||
languageIds:
|
||||
- javascript
|
||||
- typescript
|
||||
- vue
|
||||
|
||||
# An array of RegExes to find the key usage. **The key should be captured in the first match group**.
|
||||
# You should unescape RegEx strings in order to fit in the YAML file
|
||||
# To help with this, you can use https://www.freeformatter.com/json-escape.html
|
||||
usageMatchRegex:
|
||||
# The following example shows how to detect `t("your.i18n.keys")`
|
||||
# the `{key}` will be placed by a proper keypath matching regex,
|
||||
# you can ignore it and use your own matching rules as well
|
||||
- "[^\\w\\d]t\\(['\"`]({key})['\"`]"
|
||||
|
||||
|
||||
# An array of strings containing refactor templates.
|
||||
# The "$1" will be replaced by the keypath specified.
|
||||
# Optional: uncomment the following two lines to use
|
||||
|
||||
# refactorTemplates:
|
||||
# - i18n.get("$1")
|
||||
|
||||
|
||||
# If set to true, only enables this custom framework (will disable all built-in frameworks)
|
||||
monopoly: true
|
||||
37
.vscode/javascript.code-snippets
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
// Place your lx-music-desktop-new 工作区 snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
|
||||
// description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope
|
||||
// is left empty or omitted, the snippet gets applied to all languages. The prefix is what is
|
||||
// used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
|
||||
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
|
||||
// Placeholders with the same ids are connected.
|
||||
// Example:
|
||||
// "Print to console": {
|
||||
// "scope": "javascript,typescript",
|
||||
// "prefix": "log",
|
||||
// "body": [
|
||||
// "console.log('$1');",
|
||||
// "$2"
|
||||
// ],
|
||||
// "description": "Log output to console"
|
||||
// }
|
||||
"use i18n": {
|
||||
"prefix": "ui18n",
|
||||
"body": [
|
||||
"import { useI18n } from '@renderer/plugins/i18n'",
|
||||
"${1:const t = useI18n()}"
|
||||
]
|
||||
},
|
||||
"list action": {
|
||||
"prefix": "listacion",
|
||||
"body": [
|
||||
"import { $1 } from '@renderer/store/list/action'",
|
||||
]
|
||||
},
|
||||
"import vue tools": {
|
||||
"prefix": "imvt",
|
||||
"body": [
|
||||
"import { $1 } from '@common/utils/vueTools'",
|
||||
]
|
||||
}
|
||||
}
|
||||
17
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"i18n-ally.localesPaths": [
|
||||
"src/lang"
|
||||
],
|
||||
// "i18n-ally.fullReloadOnChanged": true,
|
||||
"i18n-ally.keystyle": "nested",
|
||||
"i18n-ally.displayLanguage": "zh-cn",
|
||||
"i18n-ally.sourceLanguage": "zh-cn",
|
||||
"i18n-ally.translate.engines": [
|
||||
"google-cn",
|
||||
"google"
|
||||
],
|
||||
"i18n-ally.sortKeys": true,
|
||||
"javascript.preferences.importModuleSpecifier": "non-relative",
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"vue.codeActions.enabled": false
|
||||
}
|
||||
31
.vscode/typescript.code-snippets
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
// Place your lx-music-desktop-new 工作区 snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
|
||||
// description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope
|
||||
// is left empty or omitted, the snippet gets applied to all languages. The prefix is what is
|
||||
// used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
|
||||
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
|
||||
// Placeholders with the same ids are connected.
|
||||
// Example:
|
||||
// "Print to console": {
|
||||
// "scope": "javascript,typescript",
|
||||
// "prefix": "log",
|
||||
// "body": [
|
||||
// "console.log('$1');",
|
||||
// "$2"
|
||||
// ],
|
||||
// "description": "Log output to console"
|
||||
// }
|
||||
"use i18n": {
|
||||
"prefix": "ui18n",
|
||||
"body": [
|
||||
"import { useI18n } from '@renderer/plugins/i18n'",
|
||||
"${1:const t = useI18n()}"
|
||||
]
|
||||
},
|
||||
"import vue tools": {
|
||||
"prefix": "imvt",
|
||||
"body": [
|
||||
"import { $1 } from '@common/utils/vueTools'",
|
||||
]
|
||||
}
|
||||
}
|
||||
1747
CHANGELOG.md
560
FAQ.md
@@ -1,28 +1,284 @@
|
||||
# lx-music-desktop 常见问题
|
||||
|
||||
在阅读本常见问题后,仍然无法解决你的问题,请提交issue或者加企鹅群`830125506`反馈,反馈时请**注明**已阅读常见问题!
|
||||
本文档已迁移至:<https://lyswhut.github.io/lx-music-doc/desktop/faq>
|
||||
|
||||
## 软件为什么没有桌面歌词与自定义列表功能
|
||||
<!--
|
||||
在阅读本常见问题后,仍然无法解决你的问题,请提交issue或者加企鹅群`830125506`反馈(无事勿加,入群先看群公告),反馈时请**注明**已阅读常见问题!
|
||||
|
||||
洛雪音乐的最初定位不是作为播放器开发的,它主要用于**查找歌曲**,软件的播放功能仅用于试听,不建议用作为常用播放器使用,因此无桌面、界面歌词,不可自定义列表等功能。
|
||||
## ~~软件为什么没有桌面歌词与自定义列表功能~~
|
||||
|
||||
洛雪音乐的最初定位不是作为播放器开发的,它主要用于**查找歌曲**,软件的播放功能仅用于试听,不建议用作为常用播放器使用。
|
||||
|
||||
## 音乐播放列表机制
|
||||
|
||||
1. 默认情况下,播放搜索列表、歌单列表、排行榜列表的歌曲时会自动将该歌曲添加到“我的列表”的试听列表后再播放,这与手动将歌曲添加到试听列表,再去试听列表找到这首歌点播放是等价的
|
||||
2. 如果你想要播放多首歌曲,需要使用多选功能(若不知道如何多选请看常见问题)多选后,将这些歌曲添加到“我的列表”播放,或使用稍后播放功能播放
|
||||
3. 第2条适用于搜索列表、歌单列表、排行榜列表、我的列表中的歌曲
|
||||
4. 对于歌单详情列表,除了可以使用第2条的方式播放外,你可以点击详情页上面的播放按钮临时播放当前歌单,或点击收藏将当前歌单收藏到“我的列表”后再去播放
|
||||
5. 对于排行榜详情列表,除了可以使用第2条的方式播放外,你可以在右击排行榜名字后弹出的菜单中,播放或收藏整个排行榜,这与第四条的歌单中的播放、与收藏按钮功能一致
|
||||
6. v1.18.0及之后新增了“双击列表里的歌曲时自动切换到当前列表播放”设置,默认关闭,此功能仅对歌单、排行榜有效
|
||||
7. 将歌曲添加“稍后播放”后,它们会被放在一个优先级最高的特殊队列中,点击“下一曲”时会消耗该队列中的歌曲,并且无法通过“上一曲”功能播放该队列的上一首歌曲
|
||||
8. 在切歌时若不是通过“上一曲”、“下一曲”功能切歌(例如直接点击“排行榜列表”、“我的列表”中的歌曲切歌),“稍后播放”队列将会被清空
|
||||
|
||||
## 可用的鼠标、键盘快捷操作
|
||||
|
||||
- 鼠标右击播放栏的歌曲图片封面可以定位当前播放的歌曲
|
||||
- 鼠标右击播放栏进度条上的`LRC`按钮可以锁定/解锁桌面歌词
|
||||
- 歌曲搜索框、歌单链接输入框内鼠标右击可以将当前剪贴板上的文字粘贴到输入框内
|
||||
- 鼠标右击搜索界面中的单条搜索历史可以将其移除
|
||||
- 歌曲列表内的文字在选中后,鼠标右击可以复制已选中的文字,此功能只对搜索、歌单、排行榜、我的列表中的列表有效
|
||||
- 鼠标在播放详情页内右键双击可以关闭播放详情页
|
||||
- 鼠标左击播放栏上的歌曲名字可以将它复制
|
||||
- 鼠标右击设置-主题设置的“道法自然(英文Auto)”主题可以打开亮、暗主题设置窗口
|
||||
- 歌曲搜索框的候选内容可以用键盘上下方向键选择,按回车键搜索已选内容
|
||||
- 在歌单详情页按退格键可以返回歌单列表
|
||||
- 歌曲列表中可以使用`Ctrl`、`Shift`键进行多选,这类似Windows下的文件选择,详情看常见问题列表多选部分
|
||||
- 在我的列表内可以使用`Ctrl + f`键打开搜索框进行列表内歌曲搜索,搜索框按`Esc`键可以关闭搜索框,搜索框内按上下方向键可以选择歌曲,按`回车`键跳转到已选歌曲,按`Ctrl + 回车`可以跳转并播放已选歌曲
|
||||
- 在我的列表按住`Ctrl`键可以进入列表拖动模式,此时可以用鼠标拖动列表调整列表的位置
|
||||
- 编辑列表名时按`Esc`键可以取消编辑
|
||||
- 按`F11`可以进入、退出全屏状态(v1.19.0新增)
|
||||
- 在歌曲添加弹窗中,若按住`Ctrl`键后再点击列表名,将不会自动关闭添加窗口,这对想要将同一首(一批)歌曲添加到多个列表时会很有用(v1.22.0新增)
|
||||
|
||||
注:在macOS上`Ctrl`键对应`Command`键
|
||||
|
||||
## 歌曲无法试听与下载
|
||||
|
||||
该问题解决顺序如下:
|
||||
### 所有歌曲都提示 `请求异常😮,可以多试几次,若还是不行就换一首吧。。。`
|
||||
|
||||
尝试更换网络,如切换到移动网络,若移动网络还是不行则尝试开关下手机的飞行模式后再试,<br>
|
||||
若使用家庭网络的话,可尝试将光猫断电5分钟左右再通电联网后播放。
|
||||
|
||||
### 提示 `getaddrinfo EAI_AGAIN ...` 或 `无法连接到服务器`
|
||||
|
||||
尝试在在浏览器打开这个地址`http://ts.tempmusics.tk`,浏览器显示404是正常的,如果不是404那就证明所在网络无法访问接口服务器。
|
||||
若网页无法打开或打开来不是404,则可能是DNS的问题,可以尝试以下办法:
|
||||
|
||||
1. 将DNS改成自动获取试试(注:改完可能需要清理下系统DNS缓存才生效)
|
||||
2. 手动把DNS改一下,不要用360的DNS,可以把DNS改成`223.6.6.6`、`8.8.8.8`(注:改完可能需要清理下系统DNS缓存才生效)
|
||||
|
||||
改完DNS后可能需要重启软件才生效
|
||||
|
||||
### 通用解决方法
|
||||
|
||||
尝试按以下顺序解决:
|
||||
|
||||
1. 尝试更新到最新版本
|
||||
2. 尝试切换其他歌曲(或直接搜索该歌曲),若全部歌曲都无法试听与下载则进行下一步
|
||||
3. 尝试到设置-接口来源切换到其他接口
|
||||
4. 尝试切换网络,比如用手机开热点(目前存在某些网络无法访问接口服务器的情况)
|
||||
3. 尝试到 设置-音乐来源 切换到其他接口
|
||||
4. 尝试切换网络,比如用手机开热点(所有歌曲都提示请求异常时可通过此方法解决,或等一两天后再试)
|
||||
5. 若还不行请到这个链接查看详情:<https://github.com/lyswhut/lx-music-desktop/issues/5>
|
||||
6. 若没有在第5条链接中的第一条评论中看到接口无法使用的说明,则应该是你网络无法访问接口服务器的问题,如果接口有问题我会在那里说明。
|
||||
|
||||
想要知道是不是自己网络的问题可以看看`https://ts.tempmusic.tk`能不能在浏览器打开,浏览器显示404是正常的,如果不是404那就证明所在网络无法访问接口服务器。
|
||||
想要知道是不是自己网络的问题可以看看`http://ts.tempmusics.tk`能不能在浏览器打开,浏览器显示404是正常的,如果不是404那就证明所在网络无法访问接口服务器。
|
||||
若网页无法打开或打来不是404,则应该是DNS的问题,可以尝试以下办法:
|
||||
|
||||
1. 改成自动获取试试
|
||||
2. 手动把DNS改一下,不要用360的DNS,可以把DNS改成`114.114.114.114`、`8.8.8.8`
|
||||
3. 软件设置里面的代理不要勾起来
|
||||
1. 将DNS改成自动获取试试
|
||||
2. 手动把DNS改一下,不要用360的DNS,可以把DNS改成`223.6.6.6`、`8.8.8.8`
|
||||
|
||||
### Windows版所有歌曲都提示 `音频加载错误,5秒后切换下一首`
|
||||
|
||||
尝试关闭 Internet选项 的代理设置。
|
||||
|
||||
如果你不知道怎么做,可以尝试按以下步骤去做:
|
||||
|
||||
按<kbd>windows</kbd>+<kbd>r</kbd>键打开“运行”窗口,输入`inetcpl.cpl`后回车,在打开的 Internet选项 对话框中,切换到 连接 -> 局域网设置,在弹出的新窗口中把代理服务器下的勾去掉,如果自动配置下的勾也有被勾选,那么建议也去掉,最后按确定关闭所有弹窗。
|
||||
|
||||
> 来源:<https://github.com/lyswhut/lx-music-desktop/issues/873#issuecomment-1146945724>
|
||||
|
||||
## 列表多选
|
||||
|
||||
从v0.18.0起,列表多选需要键盘配合,想要多选前需按下`Shift`或`Ctrl`键然后再鼠标点击想要选中的内容即可触发多选机制,其中`Shift`键用于连续选择,`Ctrl`键用于不连续选择,`Ctrl+a`用于快速全选。
|
||||
|
||||
- 例子一:想要选中1-5项,则先按下`Shift`键后,鼠标点击第一项,再点击第五项即可完成选择;
|
||||
- 例子二:想要选中1项与第3项,则先按下`Ctrl`键后,鼠标点击第一项,再点击第三项即可完成选择;
|
||||
- 例子三:想要选中当前列表的全部内容,键盘先按下`Ctrl`键不放,然后按`a`键,即可完成选择。
|
||||
|
||||
用`Shift`或`Ctrl`选择时,鼠标点击未选中的内容会将其选中,点击已选择的内容会将其取消选择,若想全部取消选择,在不按`Shift`或`Alt`键的情况下,随意点击列表里的一项内容即可全部取消选择。(P.S:`Ctrl`键对应Mac OS上的`Command`键)
|
||||
|
||||
注:选完后可用鼠标右击弹出右键菜单操作已选的内容
|
||||
|
||||
## 播放整个歌单或排行榜
|
||||
|
||||
播放在线列表内的歌曲需要将它们都添加到我的列表才能播放,你可以全选列表内的歌曲然后添加到现有列表或者新创建的列表,然后去播放该列表内的歌曲。
|
||||
|
||||
从v1.10.0起,你可以右击排行榜名字的弹出菜单中直接播放或收藏整个排行榜的歌曲。
|
||||
|
||||
## 无法打开外部歌单
|
||||
|
||||
不支持跨源打开歌单,请**确认**你需要打开的歌单平台是否与软件标签所写的**歌单源**对应(不一样的话请通过右上角切换歌单源);<br>
|
||||
对于分享出来的歌单,若打开失败,可尝试先在浏览器中打开后,再从浏览器地址栏复制URL地址到软件打开;<br>
|
||||
或者如果你知道歌单 id 也可以直接输入歌单 id 打开。<br>
|
||||
|
||||
注:网易源的“我喜欢”歌单无法在未登录的情况下打开,所以你需要手动创建一个歌单后将“我喜欢”里的歌曲移动到该歌单打开
|
||||
|
||||
### 打开网易源“我喜欢”歌单
|
||||
|
||||
由于网易源的“我喜欢”歌单需要登录才能打开,从v1.13.0起提供了可以以注入token的方式打开网易源“我喜欢”歌单的功能,现若想要打开此类歌单,需要在歌单链接或id后面拼上 `###` 再加上有效的token,拼接格式:`[id|url]###token`,例子(最后面的xxxxxx替换成你的token):
|
||||
- `https://music.163.com/#/playlist?id=11332&userid=123456###xxxxxx`
|
||||
- `11332###xxxxxx`
|
||||
|
||||
即:将 `歌单链接或者歌单ID`、`###`、`token` 这三者拼到一起。
|
||||
|
||||
#### `token`的获取方法
|
||||
|
||||
**注:`token`是你账号的临时身份令牌,不要随便泄露给他人**<br>
|
||||
在浏览器打开登录网易云音乐并**登录**后,按`F12`,此时将会打开开发者窗口,然后按你使用的浏览器操作:
|
||||
|
||||
##### Chrome、360、QQ等浏览器
|
||||
|
||||
这些浏览器打开此窗口时界面可能是中文也可能是英文,英文的话按括号里的来
|
||||
|
||||
1. 点击窗口顶部`应用程序(application)`(若找不到此选项,则可能是被折叠起来了,看看顶部菜单的`>>`)
|
||||
2. 展开左侧 `Cookies`
|
||||
3. 点击 `https://music.163.com`
|
||||
4. 在右侧窗口找到 `名称(Name)` 为 `MUSIC_U` 的这行,这行的第二列(`值(Value)`)内的那串内容就是`token`,双击它进入编辑状态,然后按`ctrl + c`键就可以将它复制
|
||||
|
||||
##### 火狐浏览器
|
||||
|
||||
1. 点击窗口顶部`存储`
|
||||
2. 展开左侧 `Cookie`
|
||||
3. 点击 `https://music.163.com`
|
||||
4. 在右侧窗口找到 `名称` 为 `MUSIC_U` 的这行,这行的最后一列(`值`)内的那串内容就是`token`,双击它进入编辑状态,然后按`ctrl + c`键就可以将它复制
|
||||
|
||||
## 更新已收藏的在线歌单
|
||||
|
||||
该功能仅对直接从歌单详情页点“收藏”按钮收藏的歌单有效,可右击已收藏的列表名从弹出的菜单中选择“更新”使用该功能,
|
||||
|
||||
需要注意的是:这将会覆盖本地的目标列表,歌曲将被替换成最新的在线列表。
|
||||
|
||||
## 调整我的列表的列表顺序
|
||||
|
||||
按住Ctrl键(Mac上对应Command键)的时候将进入“拖动模式”,此时可以拖动列表的位置来调整顺序。
|
||||
|
||||
## 同步功能的使用(实验性,首次使用前建议先备份一次列表)
|
||||
|
||||
**注意:由于同步传输时的数据是明文传输,请在受信任的网络下使用此功能!**<br>
|
||||
此功能需要配合移动端使用,PC端与移动端处在同一个局域网(路由器的网络)下时,可以多端实时同步歌曲列表,使用方法:
|
||||
|
||||
1. 在PC端的设置-数据同步开启同步功能(这时如果出现安全软件、防火墙等提示网络连接弹窗时需要点击允许)
|
||||
2. 在移动端的设置-同步-同步服务器地址输入PC端显示的同步服务器地址(如果显示可以多个,则输入与**移动端上显示的本机地址**最相似的那个),端口号与PC端的同步端口一致(**输入完毕后需要按一下键盘上的回车键使输入的内容生效**)
|
||||
3. 输入完这两项后点击“启动同步”
|
||||
4. 若连接成功,对于首次同步时,若两边的设备的列表不为空,则PC端会弹出选择列表同步方式的弹窗,同步方式的说明弹窗下面有介绍
|
||||
|
||||
#### 关于同步弹窗的说明
|
||||
|
||||
对于首次同步时,若两边的设备的列表不为空,则PC端会弹出选择列表同步方式的弹窗,此弹窗内的同步方式仅针对**首次同步**,<br>
|
||||
第一次同步成功后,以后再同步时将会自动根据两边设备的列表内容合并同步,不信你可以在同步完成后断开两边的连接,然后在两边增删一些歌曲或列表后再同步试试看~😉
|
||||
|
||||
#### 连接同步服务失败的可能原因
|
||||
|
||||
- 此功能需要PC端与移动端都连接在同一个路由器下的网络才能使用
|
||||
- 检查防火墙是否拦截了PC端的服务端口
|
||||
- 路由器若开启了AP隔离,则此功能无法使用
|
||||
|
||||
#### 连接同步服务失败的检查
|
||||
|
||||
1. 确保PC端的同步服务已启用成功(若连接码、同步服务地址没有内容,则证明服务启动失败,此时看启用同步功能复选框后面的错误信息自行解决,另外若你不知道端口号是什么意思就不要乱改,或不要改得太大与太小)
|
||||
2. 在手机浏览器地址栏输入`http://x.x.x.x:23332/hello` **(注:将`x.x.x.x`换成PC端显示的同步服务地址,`23332`为PC端的端口号)** 后回车,若此地址可以打开并显示 `Hello~::^-^::`则证明移动端与PC端网络已互通,
|
||||
3. 若移动端无法打开第2步的地址,则在PC端的浏览器地址栏输入并打开该地址,若可以打开,则要么是被LX Music PC端被电脑防火墙拦截,要么PC端与移动端不在同一个网络下,或者路由器开启了AP隔离(一般在公共网络下会出现这种情况)
|
||||
|
||||
## 界面异常(界面显示不完整)
|
||||
|
||||
### Windows 10、11界面异常、界面无法显示
|
||||
|
||||
尝试添加运行参数 `--disable-gpu-sandbox` 启动,例如:`.\lx-music-desktop.exe --disable-gpu-sandbox`,添加方法可自行百度“给快捷方式加参数”。
|
||||
|
||||
若以上方法无效,则尝试将 `--disable-gpu-sandbox` 逐个换成以下参数启动,直到恢复正常为止:
|
||||
|
||||
- `--no-sandbox`
|
||||
- `-dha`
|
||||
- `--disable-gpu`
|
||||
|
||||
:::caution
|
||||
这些参数会禁用程序的某些安全特性或降低程序性能,没有遇到问题不要使用它们!
|
||||
:::
|
||||
|
||||
对于界面无法显示,任务栏里也没看到图标,但是任务管理器里面看到进程的问题,还可尝试更换软件安装目录(对于安装版需要先卸载再换目录安装,绿色版直接剪切移动即可,只要目录换了就行),<br />
|
||||
此方法的相关讨论看:<https://github.com/lyswhut/lx-music-desktop/issues/943#issuecomment-1217832186>
|
||||
|
||||
### Windows 7 下界面异常
|
||||
|
||||
由于软件默认使用了透明窗口,根据Electron官方文档的[说明](https://www.electronjs.org/docs/latest/tutorial/window-customization#limitations):
|
||||
> 在 windows 操作系统上, 当 DWM 被禁用时, 透明窗口将无法工作。
|
||||
|
||||
因此,当 win7 没有使用**Aero**主题时界面将会显示异常,开启AERO的方法请自行百度:`win7开启Aero效果`(开启后可看到任务栏变透明)。<br>
|
||||
从`0.14.0`版本起不再强制要求开启透明效果,若你实在不想开启(若非电脑配置太低,墙裂建议开启!),可通过添加运行参数`-dt`来运行程序即可,例如:`.\lx-music-desktop.exe -dt`,添加方法可自行百度“给快捷方式加参数”,该参数的作用是用来控制程序是否使用非透明窗口运行。
|
||||
|
||||
注:启用**Aero**主题后,若软件出现黑边框,则重启软件即可恢复正常。
|
||||
|
||||
对于一些完全无法正常显示界面、开启了AERO后问题仍未解决的情况,请阅读下面的 **Window 7 下软件启动后,界面无法显示** 解决。
|
||||
|
||||
### Linux 下界面异常
|
||||
|
||||
根据Electron里issue的[解决方案](https://github.com/electron/electron/issues/2170#issuecomment-736223269),<br>
|
||||
若你遇到透明问题可尝试添加启动参数 `-dha` 来禁用硬件加速,例如:`.\lx-music-desktop.exe -dha`。
|
||||
|
||||
注:v1.6.0及之后的版本才支持`-dha`参数
|
||||
|
||||
## Windows 7 下软件启动后,界面无法显示
|
||||
|
||||
对于软件启动后,可以在任务栏看到软件,但软件界面在桌面上无任何显示,或者整个界面偶尔闪烁的情况。<br>
|
||||
原始问题看:<https://github.com/electron/electron/issues/19569#issuecomment-522231083><br>
|
||||
解决办法:下载`.NET Framework 4.7.1`或**更高**版本安装即可(建议安装最新版,若安装过程中遇到问题可尝试自行百度解决)。<br>
|
||||
微软官方下载地址:<https://dotnet.microsoft.com/download/dotnet-framework><br>
|
||||
下载`Runtime(运行时)`版即可,安装完成后可能需要重启才生效,**若出现闪烁的情况**,可阅读下面的**Windows 7 下整个界面闪烁**解决。
|
||||
|
||||
## Windows 7 下整个界面闪烁(消失又出现)
|
||||
|
||||
可尝试在关掉软件后,在桌面空白处鼠标右击,在弹出的菜单中选择**个性化**,在弹出的窗口中**切换到系统内置的Aero主题**,然后再启动软件看是否解决。
|
||||
|
||||
## Windows 7 下桌面歌词字体列表为空
|
||||
|
||||
Windows 7 系统系统需要安装 Powershell 5.1及以上版本才可正常获取系统字体列表。
|
||||
|
||||
想要查看当前 Powershell 版本可以在 Powershell 窗口输入命令:`Get-Host`
|
||||
|
||||
最新 Powershell 安装包可以去官方 [Github releases](https://github.com/PowerShell/PowerShell/releases) 页下载,安装过程中若出现错误,请自行按照提示或者百度/Google解决。
|
||||
|
||||
## 安装版安装失败,提示安装程序并未成功地运行完成
|
||||
|
||||
对于部分电脑出现安装失败的问题,可以做出以下尝试:
|
||||
|
||||
- 若你之前可以安装成功,但现在安装失败,就去**控制面板-程序和功能**或用第三方卸载工具看下有没有之前的版本残留,若同时在不同路径下安装了多个版本就可能会出现该问题,这种情况卸载掉所有版本重新安装即可
|
||||
- 清理安装路径下的残留文件
|
||||
- 清理注册表(建议用清理工具清理)
|
||||
|
||||
## 软件无法联网
|
||||
|
||||
软件的排行榜、歌单、搜索列表**都**无法加载:
|
||||
|
||||
- 检查是否在设置界面开启了代理(当代理乱设置时软件将无法联网)
|
||||
- 检查软件是否被第三方软件/防火墙阻止联网
|
||||
|
||||
## 桌面歌词显示异常
|
||||
|
||||
### Windows 7 系统桌面歌词显示异常
|
||||
|
||||
Windows 7 未开启 Aero 效果时桌面歌词会有问题,详情看上面的 **Windows 7 下界面异常** 方法解决。
|
||||
|
||||
### MAC OS 系统、桌面歌词有残留阴影
|
||||
|
||||
此问题似乎是Electron的Bug,翻阅electron的issue列表发现该Bug以存在很久了,遗憾的是没有一直都没有修复,由于我没有装MAC平台的电脑,没法重现,就没再去electron提issue,更多信息看:
|
||||
|
||||
- <https://github.com/electron/electron/issues/21173>
|
||||
- <https://github.com/electron/electron/issues/14304>
|
||||
|
||||
### Linux 系统下桌面歌词窗口异常
|
||||
|
||||
`v1.2.1`以前的版本在 Ubuntu 18.10 下第一次开启桌面歌词时歌词窗口会变白,需要关闭后再开启,
|
||||
`v1.2.1`及之后的版本已修复该问题。
|
||||
|
||||
其他 Linux 系统未测试,如有异常也是意料之中,目前不打算去处理 Linux 平台的桌面歌词问题,但你可以尝试按照`Linux 下界面异常`的解决方案去解决。
|
||||
|
||||
## 歌曲下载失败,提示 `ENOENT: no such file or directory, mkdir`
|
||||
|
||||
更换下载歌曲目录即可解决(一般是设置的歌曲下载目录没有读写权限导致的)。
|
||||
|
||||
## 使用软件时导致耳机意外关机
|
||||
|
||||
据反馈,漫步者部分型号的耳机与本软件一起使用时将会导致耳机意外关机,
|
||||
详情看:<https://github.com/lyswhut/lx-music-desktop/issues/457>,
|
||||
若出现该问题可尝试添加`-dhmkh`启动参数解决,启动参数添加方法请自行百度“windows给快捷方式添加启动参数”。
|
||||
|
||||
## 软件安装包说明
|
||||
|
||||
@@ -34,9 +290,9 @@
|
||||
|
||||
以 **`.dmg`** 结尾的文件为 MAC 版本;
|
||||
|
||||
以 **`.AppImage`**、**`.deb`** 结尾的为 Linux 版本。
|
||||
以 **`.AppImage`**、**`.deb`**、**`.rpm`**、**`.pacman`** 结尾的为 Linux 版本。
|
||||
|
||||
带有`x64`的为64位的系统版本,带`x86`的为32位的系统版本;若两个都带有的则为集合版,安装时会自动根据系统位数选择对应的版本安装。
|
||||
带有`x64`的为64位的系统版本,带`x86`的为32位的系统版本;若两个都带有的则为集合版,安装时会自动根据系统位数选择对应的版本安装;带有`arm`的为arm架构系统的版本。
|
||||
|
||||
## 软件更新
|
||||
|
||||
@@ -44,34 +300,13 @@
|
||||
若下载未完成时软件被关闭,下次启动软件会再次自动下载。<br>
|
||||
若还是**更新失败**,可能是无法访问GitHub导致的,这时需要手动更新,即下载最新安装包直接覆盖安装即可。<br>
|
||||
注意:**绿色版**的软件自动更新功能**不可用**,建议使用安装版!!<br>
|
||||
注意:**Mac版**、**Linux deb**版不支持自动更新!
|
||||
注意:**Mac版**、**Linux**版不支持自动更新!
|
||||
|
||||
## Windows 7 下界面异常
|
||||
### Windows 安装版在升级后,卸载了旧版本,但没有安装新版本
|
||||
|
||||
由于软件默认使用了透明窗口,根据Electron官方文档的[说明](https://electronjs.org/docs/api/frameless-window#%E5%B1%80%E9%99%90%E6%80%A7):
|
||||
> 在 windows 操作系统上, 当 DWM 被禁用时, 透明窗口将无法工作。
|
||||
出现这个问题的原因一般是你当初在安装本软件的时候是以管理员身份安装的,运行软件的时候没有以管理员身份运行,所以卸载后无法再装上。
|
||||
|
||||
因此,当 win7 没有开启**透明效果**时界面将会显示异常,开启方法请自行百度(开启后可看到任务栏变透明)。<br>
|
||||
从`0.14.0`版本起不再强制要求开启透明效果,若你实在不想开启(若非电脑配置太低,墙裂建议开启!),可通过添加运行参数`-nt`来运行程序即可,例如:`.\lx-music-desktop.exe -nt`,添加方法可自行百度“给快捷方式加参数”,该参数的作用是用来控制程序是否使用非透明窗口运行。
|
||||
|
||||
对于一些完全无法正常显示界面的情况,请阅读下面的 **软件启动后,界面无法显示**
|
||||
|
||||
## 软件启动后,界面无法显示
|
||||
|
||||
软件启动后,可以在任务栏看到软件,但软件界面在桌面上无任何显示。<br>
|
||||
解决办法:下载`.NET Framework 4.7.1`或更高版本安装即可。<br>
|
||||
原始问题看:<https://github.com/electron/electron/issues/19569#issuecomment-522231083>
|
||||
|
||||
若还是不行可尝试更新显卡驱动。
|
||||
|
||||
## 安装版安装失败,提示安装程序并未成功地运行完成
|
||||
|
||||
对于部分电脑出现安装失败的问题,可以做出以下尝试:
|
||||
|
||||
- 若你之前可以安装成功,但现在安装失败,就去**控制面板-程序和功能**或用第三方卸载工具看下有没有之前的版本残留,若同时在不同路径下安装了多个版本就可能会出现该问题,这种情况卸载掉所有版本重新安装即可
|
||||
- 清理安装路径下的残留文件
|
||||
- 以管理员权限打开`cmd`,输入`sfc /scannow`回车等待检查完成重启电脑
|
||||
- 若还是不行我也没办法了。。
|
||||
安装本软件时建议选择 `为当前用户安装`,并安装在当前用户目录或者安装在不需要管理员权限的目录(即其他分区下),不要选`为所有用户安装`。
|
||||
|
||||
## 缺少`xxx.dll`
|
||||
|
||||
@@ -80,17 +315,252 @@
|
||||
- 以管理员权限打开`cmd`,输入`sfc /scannow`回车等待检查完成重启电脑
|
||||
- 若上面的方法**修复、重启**电脑后仍然不行,就自行百度弹出的**错误信息**看下别人是怎么解决的
|
||||
|
||||
## MAC OS无法启动软件,提示 lx-music-desktop 已损坏
|
||||
|
||||
这是因为软件没有签名,被系统阻止运行,<br>
|
||||
在终端里输入 `sudo xattr -rd com.apple.quarantine /Applications/lx-music-desktop.app`,然后输入你的电脑密码即可
|
||||
|
||||
还可以参考:
|
||||
|
||||
- <http://www.pc6.com/edu/168719.html>
|
||||
- <https://blog.csdn.net/for641/article/details/104811538>
|
||||
|
||||
## 数据存储路径
|
||||
|
||||
默认情况下,软件的数据存储在:
|
||||
|
||||
- Windows:`%APPDATA%/lx-music-desktop`
|
||||
- Linux:`$XDG_CONFIG_HOME/lx-music-desktop` 或 `~/.config/lx-music-desktop`
|
||||
- macOS:`~/Library/Application/lx-music-desktop`
|
||||
|
||||
在Windows平台下,若程序目录下存在`portable`目录,则自动使用此目录作为数据存储目录(v1.17.0新增)。
|
||||
|
||||
## 杀毒软件提示有病毒或恶意行为
|
||||
|
||||
本人只能保证我写的代码不包含任何**恶意代码**、**收集用户信息**的行为,并且软件代码已开源,请自行查阅,软件安装包也是由CI拉取源代码构建,构建日志:[windows包](https://ci.appveyor.com/project/lyswhut/lx-music-desktop)、[Mac/Linux包](https://travis-ci.org/lyswhut/lx-music-desktop)<br>
|
||||
尽管如此,但这不意味着软件是100%安全的,由于软件使用了第三方依赖,当这些依赖存在恶意行为时(供应链攻击),软件也将会受到牵连,所以我只能尽量选择使用较多人用、信任度较高的依赖。<br>
|
||||
当然,以上说明建立的前提是在你所用的安装包是从**官方渠道**下载的,或者有相关能力者还可以下载源代码自己构建安装包。
|
||||
本人只能保证我写的代码不包含任何**恶意代码**、**收集用户信息**的行为,并且软件代码已开源,请自行查阅,软件安装包也是由CI拉取源代码构建,构建日志:[GitHub Actions](https://github.com/lyswhut/lx-music-desktop/actions)<br>
|
||||
尽管如此,但这不意味着软件是100%安全的,由于软件使用了第三方依赖,当这些依赖存在恶意行为时([供应链攻击](https://docs.microsoft.com/zh-cn/windows/security/threat-protection/intelligence/supply-chain-malware)),软件也将会受到牵连,所以我只能尽量选择使用较多人用、信任度较高的依赖。<br>
|
||||
当然,以上说明建立的前提是在你所用的安装包是从**本项目主页上写的链接**下载的,或者有相关能力者还可以下载源代码自己构建安装包。
|
||||
|
||||
最后,若出现杀毒软件报毒,请自行判断选择是否继续使用本软件!
|
||||
从`v0.17.0`起,由于加入了音频输出设备切换功能,该功能调用了 [MediaDevices.enumerateDevices()](https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/enumerateDevices),可能导致安全软件提示洛雪要访问摄像头(目前发现卡巴斯基会提示),但实际上没有用到摄像头,并且摄像头的提示灯也不会亮,你可以选择阻止访问。
|
||||
|
||||
## 软件无法联网
|
||||
最后,若出现杀毒软件报毒、存在恶意行为,请自行判断选择是否继续使用本软件!
|
||||
|
||||
软件的排行榜、歌单、搜索列表**都**无法加载:
|
||||
## 启动参数
|
||||
|
||||
- 检查是否在设置界面开启了代理(当代理乱设置时软件将无法联网)
|
||||
- 检查软件是否被第三方软件/防火墙阻止联网
|
||||
目前软件已支持的启动参数如下:
|
||||
|
||||
- `-search` 启动软件时自动在搜索框搜索指定的内容,例如:`-search="突然的自我 - 伍佰"`
|
||||
- `-dha` 禁用硬件加速启动(Disable Hardware Acceleration),窗口显示有问题时可以尝试添加此参数启动(v1.6.0起新增)
|
||||
- `-dt` 以非透明模式启动(Disable Transparent),对于未开启AERO效果的win7系统可加此参数启动以确保界面正常显示(注:该参数对桌面歌词无效),原来的`-nt`参数已重命名为`-dt`(v1.6.0起重命名)
|
||||
- `-dhmkh` 禁用硬件媒体密钥处理(Disable Hardware Media Key Handling),此选项将禁用Chromium的Hardware Media Key Handling特性(v1.9.0起新增)
|
||||
- `-proxy-server` 设置代理服务器,代理应用的所有流量,例:`-proxy-server="127.0.0.1:1081"`(不支持设置账号密码,v1.17.0起新增)。注:应用内“设置-网络-代理设置”仅代理接口请求的流量,优先级更高
|
||||
- `-proxy-bypass-list` 以分号分隔的主机列表绕过代理服务器,例:`-proxy-bypass-list="<local>;*.google.com;*foo.com;1.2.3.4:5678"`(与`-proxy-server`一起使用才有效,v1.17.0起新增)。注:此设置对应用内接口请求无效
|
||||
- `-play` 启动时播放指定列表的音乐,参数说明:
|
||||
- `type`:播放类型,目前固定为`songList`
|
||||
- `source`:播放源,可用值为`kw/kg/tx/wy/mg/myList`,其中`kw/kg/tx/wy/mg`对应各源的在线列表,`myList`为本地列表
|
||||
- `link`:要播放的在线列表歌单链接、或ID,source为`kw/kg/tx/wy/mg`之一(在线列表)时必传,举例:`./lx-music-desktop -play="type=songList&source=kw&link=歌单URL or ID"`,注意:如果传入URL时必须对URL进行编码后再传入
|
||||
- `name`:要播放的本地列表歌单名字,source为`myList`时必传,举例:`./lx-music-desktop -play="type=songList&source=myList&name=默认列表"`
|
||||
- `index`:从列表的哪个位置开始播放,选传,若不传默认播放第一首歌曲,举例:`./lx-music-desktop -play="type=songList&source=myList&name=默认列表&index=2"`
|
||||
|
||||
## Scheme URL支持
|
||||
|
||||
从v1.17.0起支持 Scheme URL,可以使用此功能从浏览器等场景下调用LX Music,我们开发了一个[油猴脚本](https://github.com/lyswhut/lx-music-script#readme)配套使用<br>
|
||||
脚本安装地址:<https://greasyfork.org/zh-CN/scripts/438148><br>
|
||||
以下是目前可用的Scheme URL调用方式:
|
||||
|
||||
- URL统一以`lxmusic://`开头
|
||||
- 若无特别说明,源的可用值为:`kw/kg/tx/wy/mg`
|
||||
- 若无特别说明,音质的可用值为:`128k/320k/flac/flac24bit`
|
||||
|
||||
目前支持两种传参方式:
|
||||
|
||||
- 通过`data`传参,以经过URL编码的JSON数据传参,例:`lxmusic://music/play?data=xxxx`,其中`xxxx`为经过URL编码后的JSON数据,支持复杂的参数调用
|
||||
- 通过`URL`传参,适用于简单传参的调用,不需要转成JSON格式,例:`lxmusic://music/search/xxxx`,但仍然需要对数据进行URL编码,只适应于简单参数调用(v1.18.0新增)
|
||||
|
||||
### `data`方式传参
|
||||
|
||||
以经过URL编码的JSON数据传参,例:`lxmusic://music/play?data=xxxx`,其中`xxxx`为经过URL编码后的JSON数据,JSON数据内容取决于下表的参数部分
|
||||
|
||||
| 描述 | URL | 参数
|
||||
| --- | --- | ---
|
||||
| 打开歌单 | `songlist/open` | `source<String>`(源,必须)<br>`id<String/Number>`(歌单ID,可选)<br>`url<String>`(歌单URL,可选)其中ID与URL必需传一个
|
||||
| 播放歌单 | `songlist/play` | `source<String>`(源,必须)<br>`id<String/Number>`(歌单ID,可选)<br>`url<String>`(歌单URL,可选)其中`id`与`url`必需传一个<br>`index<Number>`(播放第几首歌,可选,从0开始)
|
||||
| 搜索歌曲 | `music/search` | `keywords<String/Number>`(要搜索的内容,必须)<br>`source<String>`(源,可选)
|
||||
| 播放歌曲 | `music/play` | `name<String>`(歌曲名,必传)<br>`singer<String>`(艺术家名,必传)<br>`source<String>`(源,必传)<br>`songmid<String/Number>`(歌曲ID,必传)<br>`img<String>`(歌曲图片链接,选传)<br>`albumId<String/Number>`(歌曲专辑ID,选传)<br>`interval<String>`(格式化后的歌曲时长,选传,例:`03:55`)<br>`albumName<String>`(歌曲专辑名称,选传)<br>`types<Object>`(歌曲可用音质数组,必传,<br>数组格式:`[{"type": "<音质>", size: "<格式化后的文件大小,选传>", hash: "<kg源必传>"}]`,<br>例:`[{"type": "128k", size: "3.56M"}, {"type": "320k", size: null}]`)<br><br>以下为平台特定参数:<br>`hash<String>`(歌曲hash,kg源必传)<br>`strMediaMid<String>`(歌曲strMediaMid,tx源必传)<br>`albumMid<String>`(歌曲albumMid,tx源专用,选传)<br>`copyrightId<String>`(歌曲copyrightId,mg源必传)<br>`lrcUrl<String>`(歌曲lrcUrl,mg源专用,选传)
|
||||
|
||||
### `URL`方式传参
|
||||
|
||||
由于URL传参只适用于简单传参场景,所以目前只支持以下功能的调用:
|
||||
|
||||
| 描述 | URL | 参数
|
||||
| --- | --- | ---
|
||||
| 搜索歌曲 | `music/search/{source}/{keywords}` | `source`(源,可选)<br>`keywords`(要搜索的内容,必须)<br>例:`music/search/kw/xxx`、`music/search/xxx`
|
||||
| 打开歌单 | `songlist/open/{source}/{id/url}` | `source`(源,必须)<br>`id/url`(歌单ID或歌单URL,必须)<br>例:`songlist/open/kw/123456`
|
||||
|
||||
## 自定义源脚本编写说明
|
||||
|
||||
文件请使用UTF-8编码格式编写,脚本所用编程语言为JavaScript,可以使用ES6+语法,脚本与应用的交互是使用类似事件收发的方式进行,这是一个基本的脚本例子:
|
||||
|
||||
```js
|
||||
/**
|
||||
* @name 测试音乐源
|
||||
* @description 我只是一个测试音乐源哦
|
||||
* @version 1.0.0
|
||||
* @author xxx
|
||||
* @homepage http://xxx
|
||||
*/
|
||||
|
||||
|
||||
const { EVENT_NAMES, request, on, send } = window.lx
|
||||
|
||||
const qualitys = {
|
||||
kw: {
|
||||
'128k': '128',
|
||||
'320k': '320',
|
||||
flac: 'flac',
|
||||
},
|
||||
}
|
||||
const httpRequest = (url, options) => new Promise((resolve, reject) => {
|
||||
request(url, options, (err, resp) => {
|
||||
if (err) return reject(err)
|
||||
resolve(resp.body)
|
||||
})
|
||||
})
|
||||
|
||||
const apis = {
|
||||
kw: {
|
||||
musicUrl({ songmid }, quality) {
|
||||
return httpRequest('http://xxx').then(data => {
|
||||
return data.url
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// 注册应用API请求事件
|
||||
// source 音乐源,可能的值取决于初始化时传入的sources对象的源key值
|
||||
// info 请求附加信息,内容根据action变化
|
||||
// action 请求操作类型,目前只有musicUrl,即获取音乐URL链接,
|
||||
// 当action为musicUrl时info的结构:{type, musicInfo},
|
||||
// info.type:音乐质量,可能的值有128k / 320k / flac(取决于初始化时对应源传入的qualitys值中的一个),
|
||||
// info.musicInfo:音乐信息对象,里面有音乐ID、名字等信息
|
||||
on(EVENT_NAMES.request, ({ source, action, info }) => {
|
||||
// 回调必须返回 Promise 对象
|
||||
switch (action) {
|
||||
// action 为 musicUrl 时需要在 Promise 返回歌曲 url
|
||||
case 'musicUrl':
|
||||
return apis[source].musicUrl(info.musicInfo, qualitys[source][info.type]).catch(err => {
|
||||
console.log(err)
|
||||
return Promise.reject(err)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// 脚本初始化完成后需要发送inited事件告知应用
|
||||
send(EVENT_NAMES.inited, {
|
||||
status: true, // 初始化成功 or 失败
|
||||
openDevTools: false, // 是否打开开发者工具,方便用于调试脚本
|
||||
sources: { // 当前脚本支持的源
|
||||
kw: { // 支持的源对象,可用key值:kw/kg/tx/wy/mg
|
||||
name: '酷我音乐',
|
||||
type: 'music', // 目前固定为 music
|
||||
actions: ['musicUrl'], // 目前固定为 ['musicUrl']
|
||||
qualitys: ['128k', '320k', 'flac', 'flac24bit'], // 当前脚本的该源所支持获取的Url音质,有效的值有:['128k', '320k', 'flac', 'flac24bit']
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
```
|
||||
|
||||
### 自定义源信息
|
||||
|
||||
文件的开头必须包含以下注释:
|
||||
|
||||
```js
|
||||
/**
|
||||
* @name 测试脚本
|
||||
* @description 我只是一个测试脚本
|
||||
* @version 1.0.0
|
||||
* @author xxx
|
||||
* @homepage http://xxx
|
||||
*/
|
||||
|
||||
```
|
||||
|
||||
- `@name `:源的名字,建议不要过长,24个字符以内
|
||||
- `@description `:源的描述,建议不要过长,36个字符以内,可不填,不填时必须保留 @description
|
||||
- `@version`:源的版本号,可不填,不填时可以删除 @version
|
||||
- `@author `:脚本作者名字,可不填,不填时可以删除 @author
|
||||
- `@homepage `:脚本主页,可不填,不填时可以删除 @homepage
|
||||
|
||||
### `window.lx`
|
||||
|
||||
应用为脚本暴露的API对象。
|
||||
|
||||
#### `window.lx.version`
|
||||
|
||||
自定义源API版本,API变更时此版本号将会更改(新增于v1.14.0之后)
|
||||
|
||||
#### `window.lx.EVENT_NAMES`
|
||||
|
||||
常量事件名称对象,发送、注册事件时传入事件名时使用,可用值:
|
||||
|
||||
| 事件名 | 描述
|
||||
| --- | ---
|
||||
| `inited` | 脚本初始化完成后发送给应用的事件名,发送该事件时需要传入以下信息:`{status, sources, openDevTools}`<br>`status`:初始化结果(`true`成功,`false`失败)<br>`openDevTools`:是否打开DevTools,此选项可用于开发脚本时的调试<br>`sources`:支持的源信息对象,<br>`sources[kw/kg/tx/wy/mg].name`:源的名字(目前非必须)<br>`sources[kw/kg/tx/wy/mg].type`:源类型,目前固定值需为`music`<br>`sources[kw/kg/tx/wy/mg].actions`:支持的actions,由于目前只支持`musicUrl`,所以固定传`['musicUrl']`即可<br>`sources[kw/kg/tx/wy/mg].qualitys`:该源支持的音质列表,有效的值为`['128k', '320k', 'flac', 'flac24bit']`,该字段用于控制应用可用的音质类型
|
||||
| `request` | 应用API请求事件名,回调入参:`handler({ source, action, info})`,回调必须返回`Promise`对象<br>`source`:音乐源,可能的值取决于初始化时传入的`sources`对象的源key值<br>`info`:请求附加信息,内容根据`action`变化<br>`action`:请求操作类型,目前只有`musicUrl`,即获取音乐URL链接,需要在 Promise 返回歌曲 url,`info`的结构:`{type, musicInfo}`,`info.type`:音乐质量,可能的值有`128k` / `320k` / `flac` / `flac24bit`(取决于初始化时对应源传入的`qualitys`值中的一个),`info.musicInfo`:音乐信息对象,里面有音乐ID、名字等信息
|
||||
| `updateAlert` | 显示源更新弹窗,发送该事件时的参数:`{log, updateUrl}`<br>`log`:更新日志,必传,字符串类型,内容可以使用`\n`换行,最大长度1024,超过此长度后将被截取超出的部分<br>`updateUrl`:更新地址,用于引导用户去该地址更新源,选传,需为http协议的url地址,最大长度1024<br>此事件每次运行脚本只能调用一次(源版本v1.2.0新增)<br>例子:`lx.send(lx.EVENT_NAMES.updateAlert, { log: 'hello world', updateUrl: 'https://xxx.com' })`
|
||||
|
||||
|
||||
#### `window.lx.on`
|
||||
|
||||
事件注册方法,应用主动与脚本通信时使用:
|
||||
|
||||
```js
|
||||
/**
|
||||
* @param event_name 事件名
|
||||
* @param handler 事件处理回调 -- 注意:注册的回调必须返回 Promise 对象
|
||||
*/
|
||||
window.lx.on(event_name, handler)
|
||||
```
|
||||
|
||||
**注意:** 注册的回调必须返回 `Promise` 对象。
|
||||
|
||||
#### `window.lx.send`
|
||||
|
||||
事件发送方法,脚本主动与应用通信时使用:
|
||||
|
||||
```js
|
||||
/**
|
||||
* @param event_name 事件名
|
||||
* @param datas 要传给应用的数据
|
||||
*/
|
||||
window.lx.send(event_name, datas)
|
||||
```
|
||||
|
||||
#### `window.lx.request`
|
||||
|
||||
HTTP请求方法,用于发送HTTP请求,此HTTP请求方法不受跨域规则限制:
|
||||
|
||||
```js
|
||||
/**
|
||||
* @param url 请求的URL
|
||||
* @param options 请求选项,可用选项有 method / headers / body / form / formData / timeout
|
||||
* @param callback 请求结果的回调 入参:err, resp, body
|
||||
* @return 返回一个方法,调用此方法可以终止HTTP请求
|
||||
*/
|
||||
const cancelHttp = window.lx.request(url, options, callback)
|
||||
```
|
||||
|
||||
#### `window.lx.utils`
|
||||
|
||||
应用提供给脚本的工具方法:
|
||||
|
||||
- `window.lx.utils.buffer.from`:对应Node.js的 `Buffer.from`
|
||||
- `window.lx.utils.buffer.bufToString`:Buffer转字符串 `bufToString(buffer, format)`,`format`对应Node.js `Buffer.toString`的参数(v1.14.0之后新增)
|
||||
- `window.lx.utils.crypto.aesEncrypt`:AES加密 `aesEncrypt(buffer, mode, key, iv)`
|
||||
- `window.lx.utils.crypto.md5`:MD5加密 `md5(str)`
|
||||
- `window.lx.utils.crypto.randomBytes`:生成随机字符串 `randomBytes(size)`
|
||||
- `window.lx.utils.crypto.rsaEncrypt`:RSA加密 `rsaEncrypt(buffer, key)`
|
||||
|
||||
目前仅提供以上工具方法,如果需要其他方法可以开issue讨论。 -->
|
||||
|
||||
151
README.md
@@ -1,9 +1,11 @@
|
||||
<p align="center"><a href="https://github.com/lyswhut/lx-music-desktop"><img width="200" src="https://github.com/lyswhut/lx-music-desktop/blob/master/doc/images/icon.png" alt="lx-music logo"></a></p>
|
||||
|
||||
<h1 align="center">LX Music 桌面版</h1>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/lyswhut/lx-music-desktop/releases"><img src="https://img.shields.io/github/release/lyswhut/lx-music-desktop" alt="Release version"></a>
|
||||
<a href="https://ci.appveyor.com/project/lyswhut/lx-music-desktop"><img src="https://ci.appveyor.com/api/projects/status/flrsqd5ymp8fnte5?svg=true" alt="Build status"></a>
|
||||
<a href="https://travis-ci.org/lyswhut/lx-music-desktop"><img src="https://travis-ci.org/lyswhut/lx-music-desktop.svg?branch=master" alt="Build status"></a>
|
||||
<a href="https://github.com/lyswhut/lx-music-desktop/actions/workflows/release.yml"><img src="https://github.com/lyswhut/lx-music-desktop/workflows/Build/badge.svg" alt="Build status"></a>
|
||||
<a href="https://github.com/lyswhut/lx-music-desktop/actions/workflows/beta-pack.yml"><img src="https://github.com/lyswhut/lx-music-desktop/workflows/Build%20Beta/badge.svg" alt="Build status"></a>
|
||||
<a href="https://electronjs.org/releases/stable"><img src="https://img.shields.io/github/package-json/dependency-version/lyswhut/lx-music-desktop/dev/electron/master" alt="Electron version"></a>
|
||||
<!-- <a href="https://github.com/lyswhut/lx-music-desktop/releases"><img src="https://img.shields.io/github/downloads/lyswhut/lx-music-desktop/latest/total" alt="Downloads"></a> -->
|
||||
<a href="https://github.com/lyswhut/lx-music-desktop/tree/dev"><img src="https://img.shields.io/github/package-json/v/lyswhut/lx-music-desktop/dev" alt="Dev branch version"></a>
|
||||
@@ -28,63 +30,138 @@
|
||||
[9]: https://img.shields.io/github/license/lyswhut/lx-music-desktop
|
||||
[10]: https://github.com/lyswhut/lx-music-desktop/blob/master/LICENSE -->
|
||||
|
||||
<h2 align="center">洛雪音乐助手桌面版</h2>
|
||||
<p align="center">一个基于 Electron & Vue 开发的音乐软件</p>
|
||||
|
||||
### 说明
|
||||
|
||||
一个基于 Electron + Vue 开发的音乐软件。
|
||||
## 说明
|
||||
|
||||
所用技术栈:
|
||||
|
||||
- Electron 7
|
||||
- Vue 2
|
||||
- Electron 30+
|
||||
- Vue 3
|
||||
|
||||
已支持的平台:
|
||||
|
||||
- Windows 7 及以上
|
||||
- Mac OS
|
||||
- Linux
|
||||
- macOS
|
||||
- Windows 7 及以上
|
||||
|
||||
软件变化请查看:[更新日志](https://github.com/lyswhut/lx-music-desktop/blob/master/CHANGELOG.md)<br>
|
||||
软件下载请转到:[发布页面](https://github.com/lyswhut/lx-music-desktop/releases)<br>
|
||||
或者到网盘下载(网盘内有MAC、windows版):`https://www.lanzous.com/b906260/` 密码:`glqw`<br>
|
||||
使用常见问题请转至:[常见问题](https://github.com/lyswhut/lx-music-desktop/blob/master/FAQ.md)
|
||||
*移动版项目地址:https://github.com/lyswhut/lx-music-mobile*
|
||||
|
||||
### 源码使用方法
|
||||
> [!NOTE]
|
||||
> 目前新项目 [Any Listen](https://github.com/any-listen/any-listen) 的桌面版、Web 版已实现 LX Music 的大部分功能,并额外支持 WebDAV 歌曲播放、WebDAV 数据同步、独立播放列表等功能。
|
||||
> 我们以后的开发精力将主要集中在新项目上,之前大家在 LX Music 提的功能我们也会考虑在新项目中添加。
|
||||
> 对于日常使用 LX Music 的人可以试试迁移到 Any Listen,若遇到任何问题可以发 issue 反馈。
|
||||
>
|
||||
> 关于我们开发新项目的原因,可以参考:[LX Music 项目发展调整与新项目计划](https://github.com/lyswhut/lx-music-desktop/issues/1912)。
|
||||
|
||||
环境要求:Node.js 12.x
|
||||
软件变化请查看[更新日志](https://github.com/lyswhut/lx-music-desktop/blob/master/CHANGELOG.md)。
|
||||
|
||||
```bash
|
||||
# 开发模式
|
||||
npm run dev
|
||||
软件下载请查看 [GitHub Releases](https://github.com/lyswhut/lx-music-desktop/releases)。
|
||||
|
||||
# 构建免安装版
|
||||
npm run pack:dir
|
||||
使用常见问题请参阅[桌面版常见问题](https://lyswhut.github.io/lx-music-doc/desktop/faq)。
|
||||
|
||||
# 构建安装包(windows版)
|
||||
npm run pack
|
||||
目前本项目的原始发布地址只有 [**GitHub**](https://github.com/lyswhut/lx-music-desktop/releases),其他渠道均为第三方转载发布,与本项目无关!
|
||||
|
||||
```
|
||||
为了提高使用门槛,本软件内的默认设置、UI 操作不以新手友好为目标,所以使用前建议先根据你的喜好浏览调整一遍软件设置,阅读一遍[音乐播放列表机制](https://lyswhut.github.io/lx-music-doc/desktop/faq/playlist)及[可用的鼠标、键盘快捷操作](https://lyswhut.github.io/lx-music-doc/desktop/faq/hotkey)。
|
||||
|
||||
### UI界面
|
||||
### Scheme URL 支持
|
||||
|
||||
<p><a href="https://github.com/lyswhut/lx-music-desktop"><img width="100%" src="https://github.com/lyswhut/lx-music-desktop/blob/master/doc/images/app.png" alt="lx-music UI"></a></p>
|
||||
从 v1.17.0 起支持 Scheme URL,可以使用此功能在浏览器等场景下调用 LX Music,我们开发了一个[油猴脚本](https://github.com/lyswhut/lx-music-script#readme)配套使用。
|
||||
|
||||
### 常见问题
|
||||
脚本安装地址:[LX Music 辅助脚本](https://greasyfork.org/zh-CN/scripts/438148)。
|
||||
|
||||
常见问题已移至:<https://github.com/lyswhut/lx-music-desktop/blob/master/FAQ.md>
|
||||
若你想自己调用 LX Music,可以参考文档「[Scheme URL 支持](https://lyswhut.github.io/lx-music-doc/desktop/scheme-url)」部分。
|
||||
|
||||
### 致谢
|
||||
### 数据同步服务
|
||||
|
||||
感谢 [@messoer](https://github.com/messoer) 曾经提供的部分音乐API!
|
||||
从 v2.2.0 起,我们发布了一个独立的[数据同步服务](https://github.com/lyswhut/lx-music-sync-server#readme)。如果你有服务器,可以将其部署到服务器上作为私人多端同步服务使用,详情看该项目说明。
|
||||
|
||||
### 免责声明
|
||||
### 开放 API 支持
|
||||
|
||||
本项目**不开发或者破解直接获取音频数据**的功能,所有音频数据均来自**第三方接口**!<br>
|
||||
本软件仅用于**测试 `electron 7` 在各种系统上的兼容性**及用于**对比各大音乐平台歌单、排行榜等数据列表的差异性**,使用本软件产生的**任何涉及版权相关的数据**请于**24小时内删除**。<br>
|
||||
本软件仅用于学习交流使用,禁止用于商业用途,使用本软件所造成的的后果由使用者承担!<br>
|
||||
若对此有疑问请 mail to: lyswhut@qq.com
|
||||
从 v2.7.0 起支持开放 API 服务。启用该功能后,将会在本地启动一个 HTTP 服务,提供播放器相关的接口供第三方软件调用,详情看文档「[开放 API 服务](https://lyswhut.github.io/lx-music-doc/desktop/open-api)」部分。
|
||||
|
||||
### 许可证
|
||||
### 数据存储目录
|
||||
|
||||
[Apache License 2.0](https://github.com/lyswhut/lx-music-desktop/blob/master/LICENSE)
|
||||
默认情况下,软件的数据存储在:
|
||||
|
||||
- Linux:`$XDG_CONFIG_HOME/lx-music-desktop` 或 `~/.config/lx-music-desktop`
|
||||
- macOS:`~/Library/Application Support/lx-music-desktop`
|
||||
- Windows:`%APPDATA%/lx-music-desktop`
|
||||
|
||||
在 Windows 平台上,若程序文件夹中存在 `portable` 文件夹,则自动使用此文件夹作为数据存储文件夹(适用于 v1.17.0 及以上版本)。
|
||||
|
||||
## 用户界面
|
||||
|
||||
<p><img width="100%" src="./doc/images/app.png" alt="lx-music desktop UI"></p>
|
||||
|
||||
## 贡献代码
|
||||
|
||||
本项目欢迎 PR,但为了 PR 能顺利合并,需要注意以下几点:
|
||||
|
||||
- 对于添加新功能的 PR,建议在提交 PR 前先创建 Issue 进行说明,以确认该功能是否确实需要。
|
||||
- 对于修复 bug 的 PR,请提供修复前后的说明及重现方式。
|
||||
- 对于其他类型的 PR,则适当附上说明。
|
||||
|
||||
贡献代码步骤:
|
||||
|
||||
1. 参照[源码使用方法](https://lyswhut.github.io/lx-music-doc/desktop/use-source-code)设置开发环境;
|
||||
2. 克隆本仓库代码并切换至 `dev` 分支进行开发;
|
||||
3. 提交 PR 至 `dev` 分支。
|
||||
|
||||
## 源码使用方法
|
||||
|
||||
请参阅:<https://lyswhut.github.io/lx-music-doc/desktop/use-source-code>
|
||||
|
||||
## 项目协议
|
||||
|
||||
本项目基于 [Apache License 2.0](https://github.com/lyswhut/lx-music-desktop/blob/master/LICENSE) 许可证发行,以下协议是对于 Apache License 2.0 的补充,如有冲突,以以下协议为准。
|
||||
|
||||
---
|
||||
|
||||
*词语约定:本协议中的“本项目”指 LX Music(洛雪音乐助手)桌面版项目;“使用者”指签署本协议的使用者;“官方音乐平台”指对本项目内置的包括酷我、酷狗、咪咕等音乐源的官方平台统称;“版权数据”指包括但不限于图像、音频、名字等在内的他人拥有所属版权的数据。*
|
||||
|
||||
### 一、数据来源
|
||||
|
||||
1.1 本项目的各官方平台在线数据来源原理是从其公开服务器中拉取数据(与未登录状态在官方平台 APP 获取的数据相同),经过对数据简单地筛选与合并后进行展示,因此本项目不对数据的合法性、准确性负责。
|
||||
|
||||
1.2 本项目本身没有获取某个音频数据的能力,本项目使用的在线音频数据来源来自软件设置内“自定义源”设置所选择的“源”返回的在线链接。例如播放某首歌,本项目所做的只是将希望播放的歌曲名、艺术家等信息传递给“源”,若“源”返回了一个链接,则本项目将认为这就是该歌曲的音频数据而进行使用,至于这是不是正确的音频数据本项目无法校验其准确性,所以使用本项目的过程中可能会出现希望播放的音频与实际播放的音频不对应或者无法播放的问题。
|
||||
|
||||
1.3 本项目的非官方平台数据(例如“我的列表”内列表)来自使用者本地系统或者使用者连接的同步服务,本项目不对这些数据的合法性、准确性负责。
|
||||
|
||||
### 二、版权数据
|
||||
|
||||
2.1 使用本项目的过程中可能会产生版权数据。对于这些版权数据,本项目不拥有它们的所有权。为了避免侵权,使用者务必在 **24 小时内** 清除使用本项目的过程中所产生的版权数据。
|
||||
|
||||
### 三、音乐平台别名
|
||||
|
||||
3.1 本项目内的官方音乐平台别名为本项目内对官方音乐平台的一个称呼,不包含恶意。如果官方音乐平台觉得不妥,可联系本项目更改或移除。
|
||||
|
||||
### 四、资源使用
|
||||
|
||||
4.1 本项目内使用的部分包括但不限于字体、图片等资源来源于互联网。如果出现侵权可联系本项目移除。
|
||||
|
||||
### 五、免责声明
|
||||
|
||||
5.1 由于使用本项目产生的包括由于本协议或由于使用或无法使用本项目而引起的任何性质的任何直接、间接、特殊、偶然或结果性损害(包括但不限于因商誉损失、停工、计算机故障或故障引起的损害赔偿,或任何及所有其他商业损害或损失)由使用者负责。
|
||||
|
||||
### 六、使用限制
|
||||
|
||||
6.1 本项目完全免费,且开源发布于 GitHub 面向全世界人用作对技术的学习交流。本项目不对项目内的技术可能存在违反当地法律法规的行为作保证。
|
||||
|
||||
6.2 **禁止在违反当地法律法规的情况下使用本项目。** 对于使用者在明知或不知当地法律法规不允许的情况下使用本项目所造成的任何违法违规行为由使用者承担,本项目不承担由此造成的任何直接、间接、特殊、偶然或结果性责任。
|
||||
|
||||
### 七、版权保护
|
||||
|
||||
7.1 音乐平台不易,请尊重版权,支持正版。
|
||||
|
||||
### 八、非商业性质
|
||||
|
||||
8.1 本项目仅用于对技术可行性的探索及研究,不接受任何商业(包括但不限于广告等)合作及捐赠。
|
||||
|
||||
### 九、接受协议
|
||||
|
||||
9.1 若你使用了本项目,即代表你接受本协议。
|
||||
|
||||
---
|
||||
|
||||
若对此有疑问请 mail to: lyswhut+qq.com (请将 `+` 替换为 `@`)
|
||||
|
||||
28
build-config/build-after-pack.js
Normal file
@@ -0,0 +1,28 @@
|
||||
const { afterPack } = require('./deps')
|
||||
|
||||
const fs = require('fs').promises
|
||||
|
||||
// https://github.com/electron-userland/electron-builder/issues/4630
|
||||
// https://github.com/electron-userland/electron-builder/issues/4630#issuecomment-782020139
|
||||
|
||||
module.exports = async(context) => {
|
||||
await afterPack()
|
||||
const { electronPlatformName, appOutDir } = context
|
||||
if (electronPlatformName !== 'darwin') return
|
||||
const {
|
||||
productFilename,
|
||||
info: {
|
||||
_metadata: { macLanguagesInfoPlistStrings },
|
||||
},
|
||||
} = context.packager.appInfo
|
||||
|
||||
const resPath = `${appOutDir}/${productFilename}.app/Contents/Resources`
|
||||
|
||||
// 创建APP语言包文件
|
||||
return Promise.all(
|
||||
Object.entries(macLanguagesInfoPlistStrings).map(([lang, config]) => {
|
||||
let infos = Object.entries(config).map(([k, v]) => `"${k}" = "${v}";`).join('\n')
|
||||
return fs.writeFile(`${resPath}/${lang}.lproj/InfoPlist.strings`, infos)
|
||||
}),
|
||||
)
|
||||
}
|
||||
60
build-config/build-before-pack.js
Normal file
@@ -0,0 +1,60 @@
|
||||
// const fs = require('fs')
|
||||
// const fsPromises = require('fs').promises
|
||||
// const path = require('path')
|
||||
const { Arch } = require('electron-builder')
|
||||
// const nodeAbi = require('node-abi')
|
||||
const { beforePack, copyLib } = require('./deps')
|
||||
|
||||
// const better_sqlite3_fileNameMap = {
|
||||
// [Arch.x64]: 'linux-x64',
|
||||
// [Arch.arm64]: 'linux-arm64',
|
||||
// [Arch.armv7l]: 'linux-arm',
|
||||
// }
|
||||
|
||||
// const replaceSqliteLib = async(arch) => {
|
||||
// // console.log(await fs.readdir(path.join(context.appOutDir, './resources/')))
|
||||
// // if (context.electronPlatformName != 'linux' || context.arch != Arch.arm64) return
|
||||
// // https://github.com/lyswhut/lx-music-desktop/issues/1102
|
||||
// // https://github.com/lyswhut/lx-music-desktop/issues/1161
|
||||
// console.log('replace sqlite lib...')
|
||||
// const filePath = path.join(__dirname, `./lib/better_sqlite3_${better_sqlite3_fileNameMap[arch]}.node`)
|
||||
// console.log(filePath)
|
||||
// const targetPath = path.join(__dirname, '../node_modules/better-sqlite3/build/Release/better_sqlite3.node')
|
||||
// await fsPromises.unlink(targetPath).catch(_ => _)
|
||||
// await fsPromises.copyFile(filePath, targetPath)
|
||||
// }
|
||||
|
||||
const archMap = {
|
||||
[Arch.x64]: 'x64',
|
||||
[Arch.ia32]: 'ia32',
|
||||
[Arch.arm64]: 'arm64',
|
||||
[Arch.armv7l]: 'arm',
|
||||
}
|
||||
module.exports = async(context) => {
|
||||
await beforePack()
|
||||
const { arch } = context
|
||||
const electronVersion = context.packager?.info?._framework?.version ?? require('../package.json').devDependencies.electron.replace(/^[^\d]*?(\d+)/, '$1')
|
||||
await copyLib(archMap[arch], parseInt(electronVersion) == 22)
|
||||
// const electronNodeAbi = nodeAbi.getAbi(electronVersion, 'electron')
|
||||
// if (electronPlatformName !== 'linux' || process.env.FORCE) return
|
||||
// // const bindingFilePath = path.join(__dirname, '../node_modules/better-sqlite3/binding.gyp')
|
||||
// // const bindingBakFilePath = path.join(__dirname, '../node_modules/better-sqlite3/binding.gyp.bak')
|
||||
// switch (arch) {
|
||||
// case Arch.x64:
|
||||
// case Arch.arm64:
|
||||
// case Arch.armv7l:
|
||||
// // if (fs.existsSync(bindingFilePath)) {
|
||||
// // // console.log('rename binding file...')
|
||||
// // await fsPromises.rename(bindingFilePath, bindingBakFilePath)
|
||||
// // }
|
||||
// await replaceSqliteLib(arch)
|
||||
// break
|
||||
|
||||
// default:
|
||||
// // if (fs.existsSync(bindingFilePath)) return
|
||||
// // console.log('restore binding file...')
|
||||
// // await fsPromises.rename(bindingBakFilePath, bindingFilePath)
|
||||
// await copyLib(arch)
|
||||
// break
|
||||
// }
|
||||
}
|
||||
308
build-config/build-pack.js
Normal file
@@ -0,0 +1,308 @@
|
||||
/* eslint-disable no-template-curly-in-string */
|
||||
|
||||
const builder = require('electron-builder')
|
||||
const beforePack = require('./build-before-pack')
|
||||
const afterPack = require('./build-after-pack')
|
||||
|
||||
/**
|
||||
* @type {import('electron-builder').Configuration}
|
||||
* @see https://www.electron.build/configuration/configuration
|
||||
*/
|
||||
const options = {
|
||||
appId: 'cn.toside.music.desktop',
|
||||
productName: 'lx-music-desktop',
|
||||
beforePack,
|
||||
afterPack,
|
||||
protocols: {
|
||||
name: 'lx-music-protocol',
|
||||
schemes: [
|
||||
'lxmusic',
|
||||
],
|
||||
},
|
||||
directories: {
|
||||
buildResources: './resources',
|
||||
output: './build',
|
||||
},
|
||||
files: [
|
||||
'!node_modules/**/*',
|
||||
'node_modules/font-list',
|
||||
'node_modules/better-sqlite3/lib',
|
||||
'node_modules/better-sqlite3/package.json',
|
||||
'node_modules/better-sqlite3/build/Release/better_sqlite3.node',
|
||||
'node_modules/electron-font-manager/index.js',
|
||||
'node_modules/electron-font-manager/package.json',
|
||||
'node_modules/electron-font-manager/build/Release/font_manager.node',
|
||||
'node_modules/node-gyp-build',
|
||||
'node_modules/bufferutil',
|
||||
'node_modules/utf-8-validate',
|
||||
'dist/**/*',
|
||||
],
|
||||
asar: {
|
||||
smartUnpack: false,
|
||||
},
|
||||
extraResources: [
|
||||
'./licenses',
|
||||
],
|
||||
publish: [
|
||||
{
|
||||
provider: 'github',
|
||||
owner: 'lyswhut',
|
||||
repo: 'lx-music-desktop',
|
||||
},
|
||||
],
|
||||
}
|
||||
/**
|
||||
* @type {import('electron-builder').Configuration}
|
||||
* @see https://www.electron.build/configuration/configuration
|
||||
*/
|
||||
const winOptions = {
|
||||
win: {
|
||||
icon: './resources/icons/icon.ico',
|
||||
legalTrademarks: 'lyswhut',
|
||||
// artifactName: '${productName}-v${version}-${env.ARCH}-${env.TARGET}.${ext}',
|
||||
},
|
||||
nsis: {
|
||||
oneClick: false,
|
||||
language: '2052',
|
||||
allowToChangeInstallationDirectory: true,
|
||||
// differentialPackage: true,
|
||||
license: './licenses/license.rtf',
|
||||
shortcutName: 'LX Music',
|
||||
},
|
||||
}
|
||||
/**
|
||||
* @type {import('electron-builder').Configuration}
|
||||
* @see https://www.electron.build/configuration/configuration
|
||||
*/
|
||||
const linuxOptions = {
|
||||
linux: {
|
||||
maintainer: 'lyswhut <lyswhut@qq.com>',
|
||||
// artifactName: '${productName}-${version}.${env.ARCH}.${ext}',
|
||||
icon: './resources/icons',
|
||||
category: 'Utility;AudioVideo;Audio;Player;Music;',
|
||||
desktop: {
|
||||
// https://www.electron.build/app-builder-lib.interface.linuxdesktopfile
|
||||
// https://www.electronjs.org/docs/latest/tutorial/linux-desktop-actions
|
||||
// https://specifications.freedesktop.org/desktop-entry-spec/latest/example.html
|
||||
// https://developer.gnome.org/documentation/guidelines/maintainer/integrating.html#desktop-files
|
||||
entry: {
|
||||
Name: 'LX Music',
|
||||
'Name[zh_CN]': 'LX Music',
|
||||
'Name[zh_TW]': 'LX Music',
|
||||
Encoding: 'UTF-8',
|
||||
MimeType: 'x-scheme-handler/lxmusic',
|
||||
StartupNotify: 'false',
|
||||
},
|
||||
},
|
||||
},
|
||||
appImage: {
|
||||
license: './licenses/license_zh.txt',
|
||||
category: 'Utility;AudioVideo;Audio;Player;Music;',
|
||||
},
|
||||
}
|
||||
/**
|
||||
* @type {import('electron-builder').Configuration}
|
||||
* @see https://www.electron.build/configuration/configuration
|
||||
*/
|
||||
const macOptions = {
|
||||
mac: {
|
||||
icon: './resources/icons/icon.icns',
|
||||
category: 'public.app-category.music',
|
||||
// artifactName: '${productName}-${version}.${ext}',
|
||||
},
|
||||
dmg: {
|
||||
window: {
|
||||
width: 530,
|
||||
height: 380,
|
||||
},
|
||||
contents: [
|
||||
{
|
||||
x: 140,
|
||||
y: 200,
|
||||
},
|
||||
{
|
||||
x: 390,
|
||||
y: 200,
|
||||
type: 'link',
|
||||
path: '/Applications',
|
||||
},
|
||||
],
|
||||
title: 'LX Music v${version}',
|
||||
},
|
||||
}
|
||||
|
||||
// win: {
|
||||
// tagret: {
|
||||
// setup: ['nsis', '${productName}-v${version}-${env.ARCH}-Setup.${ext}'],
|
||||
// green: ['7z', '${productName}-v${version}-${env.ARCH}-green.${ext}'],
|
||||
// portable: ['portable', '${productName}-v${version}-${env.ARCH}-portable.${ext}'],
|
||||
// },
|
||||
// },
|
||||
// linux: {
|
||||
// platform: Platform.WINDOWS,
|
||||
// arch: {
|
||||
// x64: builder.Arch.x64,
|
||||
// arm64: builder.Arch.arm64,
|
||||
// armv7l: builder.Arch.armv7l,
|
||||
// },
|
||||
// tagret: {
|
||||
// deb: ['deb', '${productName}_${version}_${env.ARCH}.${ext}'],
|
||||
// appImage: ['AppImage', '${productName}_${version}_${env.ARCH}.${ext}'],
|
||||
// pacman: ['pacman', '${productName}_${version}_${env.ARCH}.${ext}'],
|
||||
// rpm: ['rpm', '${productName}-${version}.${env.ARCH}.${ext}'],
|
||||
// },
|
||||
// },
|
||||
// mac: {
|
||||
// arch: {
|
||||
// x64: builder.Arch.x64,
|
||||
// x86: builder.Arch.ia32,
|
||||
// arm64: builder.Arch.arm64,
|
||||
// },
|
||||
// tagret: {
|
||||
// dmg: ['dmg', '${productName}-${version}-${env.ARCH}.${ext}'],
|
||||
// },
|
||||
// },
|
||||
|
||||
const createTarget = {
|
||||
/**
|
||||
*
|
||||
* @param {*} arch
|
||||
* @param {*} packageType
|
||||
* @returns {{ buildOptions: import('electron-builder').CliOptions, options: import('electron-builder').Configuration }}
|
||||
*/
|
||||
win(arch, packageType) {
|
||||
switch (packageType) {
|
||||
case 'setup':
|
||||
winOptions.artifactName = `\${productName}-v\${version}-${arch}-Setup.\${ext}`
|
||||
return {
|
||||
buildOptions: { win: ['nsis'] },
|
||||
options: winOptions,
|
||||
}
|
||||
case 'green':
|
||||
winOptions.artifactName = `\${productName}-v\${version}-win_${arch}-green.\${ext}`
|
||||
return {
|
||||
buildOptions: { win: ['7z'] },
|
||||
options: winOptions,
|
||||
}
|
||||
case 'win7_setup':
|
||||
winOptions.artifactName = `\${productName}-v\${version}-win7_${arch}-Setup.\${ext}`
|
||||
return {
|
||||
buildOptions: { win: ['nsis'] },
|
||||
options: winOptions,
|
||||
}
|
||||
case 'win7_green':
|
||||
winOptions.artifactName = `\${productName}-v\${version}-win7_${arch}-green.\${ext}`
|
||||
return {
|
||||
buildOptions: { win: ['7z'] },
|
||||
options: winOptions,
|
||||
}
|
||||
case 'portable':
|
||||
winOptions.artifactName = `\${productName}-v\${version}-${arch}-portable.\${ext}`
|
||||
return {
|
||||
buildOptions: { win: ['portable'] },
|
||||
options: winOptions,
|
||||
}
|
||||
default: throw new Error('Unknown package type: ' + packageType)
|
||||
}
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {*} arch
|
||||
* @param {*} packageType
|
||||
* @returns {{ buildOptions: import('electron-builder').CliOptions, options: import('electron-builder').Configuration }}
|
||||
*/
|
||||
linux(arch, packageType) {
|
||||
switch (packageType) {
|
||||
case 'deb':
|
||||
linuxOptions.artifactName = `\${productName}_\${version}_${arch == 'x64' ? 'amd64' : arch}.\${ext}`
|
||||
return {
|
||||
buildOptions: { linux: ['deb'] },
|
||||
options: linuxOptions,
|
||||
}
|
||||
case 'appImage':
|
||||
linuxOptions.artifactName = `\${productName}_\${version}_${arch}.\${ext}`
|
||||
return {
|
||||
buildOptions: { linux: ['AppImage'] },
|
||||
options: linuxOptions,
|
||||
}
|
||||
case 'pacman':
|
||||
linuxOptions.artifactName = `\${productName}_\${version}_${arch}.\${ext}`
|
||||
return {
|
||||
buildOptions: { linux: ['pacman'] },
|
||||
options: linuxOptions,
|
||||
}
|
||||
case 'rpm':
|
||||
linuxOptions.artifactName = `\${productName}-\${version}.${arch}.\${ext}`
|
||||
return {
|
||||
buildOptions: { linux: ['rpm'] },
|
||||
options: linuxOptions,
|
||||
}
|
||||
default: throw new Error('Unknown package type: ' + packageType)
|
||||
}
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {*} arch
|
||||
* @param {*} packageType
|
||||
* @returns {{ buildOptions: import('electron-builder').CliOptions, options: import('electron-builder').Configuration }}
|
||||
*/
|
||||
mac(arch, packageType) {
|
||||
switch (packageType) {
|
||||
case 'dmg':
|
||||
macOptions.artifactName = `\${productName}-\${version}-${arch}.\${ext}`
|
||||
return {
|
||||
buildOptions: { mac: ['dmg'] },
|
||||
options: macOptions,
|
||||
}
|
||||
default: throw new Error('Unknown package type: ' + packageType)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {'win' | 'mac' | 'linux' | 'dir'} target 构建目标平台
|
||||
* @param {'x86_64' | 'x64' | 'x86' | 'arm64' | 'armv7l'} arch 包架构
|
||||
* @param {*} packageType 包类型
|
||||
* @param {'onTagOrDraft' | 'always' | 'never'} publishType 发布类型
|
||||
*/
|
||||
const build = async(target, arch, packageType, publishType) => {
|
||||
if (target == 'dir') {
|
||||
await builder.build({
|
||||
dir: true,
|
||||
config: { ...options, ...winOptions, ...linuxOptions, ...macOptions },
|
||||
})
|
||||
return
|
||||
}
|
||||
const targetInfo = createTarget[target](arch, packageType)
|
||||
// Promise is returned
|
||||
await builder.build({
|
||||
...targetInfo.buildOptions,
|
||||
publish: publishType ?? 'never',
|
||||
x64: arch == 'x64' || arch == 'x86_64',
|
||||
ia32: arch == 'x86' || arch == 'x86_64',
|
||||
arm64: arch == 'arm64',
|
||||
armv7l: arch == 'armv7l',
|
||||
config: { ...options, ...targetInfo.options },
|
||||
})
|
||||
// .then((result) => {
|
||||
// console.log(JSON.stringify(result))
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// console.error(error)
|
||||
// })
|
||||
}
|
||||
|
||||
const params = {}
|
||||
|
||||
for (const param of process.argv.slice(2)) {
|
||||
const [name, value] = param.split('=')
|
||||
params[name] = value
|
||||
}
|
||||
|
||||
if (params.target == null) throw new Error('Missing target')
|
||||
if (params.target != 'dir' && params.arch == null) throw new Error('Missing arch')
|
||||
if (params.target != 'dir' && params.type == null) throw new Error('Missing type')
|
||||
|
||||
console.log(params.target, params.arch, params.type, params.publish ?? '')
|
||||
build(params.target, params.arch, params.type, params.publish)
|
||||
@@ -2,7 +2,9 @@ const isDev = process.env.NODE_ENV === 'development'
|
||||
|
||||
module.exports = {
|
||||
modules: {
|
||||
localIdentName: isDev ? '[folder]-[name]--[local]--[hash:base64:5]' : '[hash:base64:5]',
|
||||
localIdentName: isDev ? '[path][name]__[local]--[hash:base64:5]' : '[hash:base64:5]',
|
||||
exportLocalsConvention: 'camelCase',
|
||||
namedExport: false,
|
||||
},
|
||||
localsConvention: 'camelCase',
|
||||
sourceMap: isDev,
|
||||
}
|
||||
|
||||
46
build-config/dependencies-patch.js
Normal file
@@ -0,0 +1,46 @@
|
||||
// 修补依赖源码以使vite构建的依赖恢复正常工作
|
||||
|
||||
const fs = require('node:fs')
|
||||
const path = require('node:path')
|
||||
|
||||
const rootPath = path.join(__dirname, '../')
|
||||
|
||||
const patchs = [
|
||||
// [
|
||||
// path.join(rootPath, './node_modules/ws/package.json'),
|
||||
// '\n "browser": "./browser.js",',
|
||||
// '',
|
||||
// ],
|
||||
// [
|
||||
// path.join(rootPath, './node_modules/music-metadata/package.json'),
|
||||
// '"default": "./lib/core.js"',
|
||||
// '"default": "./lib/index.js"',
|
||||
// ],
|
||||
// [
|
||||
// path.join(rootPath, './node_modules/strtok3/package.json'),
|
||||
// '"default": "./lib/core.js"',
|
||||
// '"default": "./lib/index.js"',
|
||||
// ],
|
||||
[
|
||||
path.join(rootPath, './node_modules/better-sqlite3/package.json'),
|
||||
`{
|
||||
"build-release": "node-gyp clean && node-gyp rebuild --release --force_build=1",`,
|
||||
`{
|
||||
"install": "node -e \\"process.exit(require('fs').existsSync('build/Release/better_sqlite3.node') ? 0 : 1)\\" || node-gyp rebuild --release --force_build=1",
|
||||
"build-release": "node-gyp clean && node-gyp rebuild --release --force_build=1",`,
|
||||
],
|
||||
]
|
||||
|
||||
;(async() => {
|
||||
for (const [filePath, fromStr, toStr] of patchs) {
|
||||
console.log(`Patching ${filePath.replace(rootPath, '')}`)
|
||||
try {
|
||||
const file = (await fs.promises.readFile(filePath)).toString()
|
||||
await fs.promises.writeFile(filePath, file.replace(fromStr, toStr))
|
||||
} catch (err) {
|
||||
console.error(`Patch ${filePath.replace(rootPath, '')} failed: ${err.message}`)
|
||||
}
|
||||
}
|
||||
console.log('\nDependencies patch finished.\n')
|
||||
})()
|
||||
|
||||
55
build-config/deps.js
Normal file
@@ -0,0 +1,55 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const bindingFilePath = path.join(__dirname, '../node_modules/better-sqlite3/binding.gyp')
|
||||
const bindingBakFilePath = path.join(__dirname, '../node_modules/better-sqlite3/binding.gyp.bak')
|
||||
exports.beforePack = async() => {
|
||||
if (!fs.existsSync(bindingFilePath)) return
|
||||
fs.renameSync(bindingFilePath, bindingBakFilePath)
|
||||
// try {
|
||||
// fs.writeFileSync(
|
||||
// bindingFilePath,
|
||||
// fs.readFileSync(bindingFilePath, 'utf-8').replace('\'force_build%\': 0,', '\'force_build%\': 1,'),
|
||||
// )
|
||||
// } catch (error) {
|
||||
// console.error(error)
|
||||
// }
|
||||
}
|
||||
exports.afterPack = async() => {
|
||||
if (fs.existsSync(bindingFilePath)) return
|
||||
fs.renameSync(bindingBakFilePath, bindingFilePath)
|
||||
// try {
|
||||
// fs.writeFileSync(
|
||||
// bindingFilePath,
|
||||
// fs.readFileSync(bindingFilePath, 'utf-8').replace('\'force_build%\': 1,', '\'force_build%\': 0,'),
|
||||
// )
|
||||
// } catch (error) {
|
||||
// console.error(error)
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
const replaceSqliteLib = async(arch) => {
|
||||
// console.log(await fs.readdir(path.join(context.appOutDir, './resources/')))
|
||||
// if (context.electronPlatformName != 'linux' || context.arch != Arch.arm64) return
|
||||
// https://github.com/lyswhut/lx-music-desktop/issues/1102
|
||||
// https://github.com/lyswhut/lx-music-desktop/issues/1161
|
||||
console.log('replace sqlite lib...')
|
||||
const filePath = path.join(__dirname, `./lib/better_sqlite3_${process.platform}-${arch}.node`)
|
||||
console.log(filePath)
|
||||
const targetPath = path.join(__dirname, '../node_modules/better-sqlite3/build/Release/better_sqlite3.node')
|
||||
await fs.promises.unlink(targetPath).catch(_ => _)
|
||||
await fs.promises.copyFile(filePath, targetPath)
|
||||
}
|
||||
exports.copyLib = async(arch = process.arch, replaceLocal = false) => {
|
||||
if (process.platform === 'linux' || replaceLocal) {
|
||||
await replaceSqliteLib(arch)
|
||||
return
|
||||
}
|
||||
const libPath = path.join(__dirname, `../node_modules/better-sqlite3/prebuilds/${process.platform}-${arch}.node`)
|
||||
if (!fs.existsSync(libPath)) {
|
||||
console.error(`Better-sqlite3 prebuild not found for ${process.platform}-${arch}`)
|
||||
return
|
||||
}
|
||||
const targetPath = path.join(__dirname, '../node_modules/better-sqlite3/build/Release/better_sqlite3.node')
|
||||
await fs.promises.cp(libPath, targetPath, { recursive: true, force: true })
|
||||
}
|
||||
49
build-config/lib-update.js
Normal file
@@ -0,0 +1,49 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const tar = require('tar')
|
||||
|
||||
const libDir = path.join(__dirname, 'lib')
|
||||
|
||||
const getGzipFiles = async() => {
|
||||
const names = await fs.promises.readdir(libDir)
|
||||
// for (const name of names) {
|
||||
// if (name.endsWith('.node')) await fs.promises.unlink(path.join(libDir, name))
|
||||
// }
|
||||
return names.filter((name) => name.endsWith('.gz'))
|
||||
}
|
||||
|
||||
const unzip = async(filePath) => {
|
||||
const targetDir = filePath.replace('.tar.gz', '')
|
||||
if (fs.existsSync(targetDir)) await fs.promises.rm(targetDir, { recursive: true })
|
||||
await fs.promises.mkdir(targetDir)
|
||||
await tar.x({
|
||||
file: filePath,
|
||||
strip: 0,
|
||||
C: targetDir,
|
||||
})
|
||||
return targetDir
|
||||
}
|
||||
|
||||
const files = ['better_sqlite3']
|
||||
const moveFile = async(filePath) => {
|
||||
const name = `${path.basename(filePath).split('_v')[0].replace('_', '-')}`
|
||||
for (const fileName of files) {
|
||||
// if (fileName == 'better_sqlite3' && !name.includes('linux')) continue
|
||||
const targetPath = path.join(libDir, `${fileName}_${name}.node`)
|
||||
if (fs.existsSync(targetPath)) await fs.promises.unlink(targetPath)
|
||||
await fs.promises.rename(path.join(filePath, `${fileName}.node`), targetPath)
|
||||
}
|
||||
await fs.promises.rm(filePath, { recursive: true })
|
||||
}
|
||||
|
||||
const run = async() => {
|
||||
const files = await getGzipFiles()
|
||||
for (const name of files) {
|
||||
await moveFile(await unzip(path.join(libDir, name)))
|
||||
}
|
||||
for (const name of files) {
|
||||
await fs.promises.unlink(path.join(libDir, name))
|
||||
}
|
||||
}
|
||||
|
||||
run()
|
||||
BIN
build-config/lib/better_sqlite3_linux-arm.node
Normal file
BIN
build-config/lib/better_sqlite3_linux-arm64.node
Normal file
BIN
build-config/lib/better_sqlite3_linux-x64.node
Normal file
BIN
build-config/lib/better_sqlite3_win32-ia32.node
Normal file
BIN
build-config/lib/better_sqlite3_win32-x64.node
Normal file
@@ -1,39 +1,45 @@
|
||||
const path = require('path')
|
||||
const ESLintPlugin = require('eslint-webpack-plugin')
|
||||
|
||||
module.exports = {
|
||||
target: 'electron-main',
|
||||
output: {
|
||||
filename: '[name].js',
|
||||
libraryTarget: 'commonjs2',
|
||||
path: path.join(__dirname, '../../dist/electron'),
|
||||
library: {
|
||||
type: 'commonjs2',
|
||||
},
|
||||
path: path.join(__dirname, '../../dist'),
|
||||
},
|
||||
externals: {
|
||||
'font-list': 'font-list',
|
||||
'better-sqlite3': 'better-sqlite3',
|
||||
'electron-font-manager': 'electron-font-manager',
|
||||
bufferutil: 'bufferutil',
|
||||
'utf-8-validate': 'utf-8-validate',
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
common: path.join(__dirname, '../../src/common'),
|
||||
'@main': path.join(__dirname, '../../src/main'),
|
||||
'@renderer': path.join(__dirname, '../../src/renderer'),
|
||||
'@lyric': path.join(__dirname, '../../src/renderer-lyric'),
|
||||
'@common': path.join(__dirname, '../../src/common'),
|
||||
},
|
||||
extensions: ['*', '.js', '.json', '.node'],
|
||||
extensions: ['.tsx', '.ts', '.js', '.mjs', '.json', '.node'],
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
use: {
|
||||
loader: 'eslint-loader',
|
||||
options: {
|
||||
formatter: require('eslint-formatter-friendly'),
|
||||
},
|
||||
},
|
||||
exclude: /node_modules/,
|
||||
enforce: 'pre',
|
||||
test: /\.node$/,
|
||||
use: 'node-loader',
|
||||
},
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
// {
|
||||
// test: /\.js$/,
|
||||
// loader: 'babel-loader',
|
||||
// exclude: /node_modules/,
|
||||
// },
|
||||
],
|
||||
},
|
||||
performance: {
|
||||
maxEntrypointSize: 300000,
|
||||
},
|
||||
plugins: [
|
||||
new ESLintPlugin(),
|
||||
],
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const path = require('path')
|
||||
const merge = require('webpack-merge')
|
||||
const { merge } = require('webpack-merge')
|
||||
const webpack = require('webpack')
|
||||
|
||||
const baseConfig = require('./webpack.config.base')
|
||||
@@ -8,15 +8,21 @@ const baseConfig = require('./webpack.config.base')
|
||||
module.exports = merge(baseConfig, {
|
||||
mode: 'development',
|
||||
entry: {
|
||||
main: path.join(__dirname, '../../src/main/index.dev.js'),
|
||||
main: path.join(__dirname, '../../src/main/index-dev.ts'),
|
||||
// 'dbService.worker': path.join(__dirname, '../../src/main/worker/dbService/index.ts'),
|
||||
},
|
||||
devtool: 'eval-source-map',
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: '"development"',
|
||||
},
|
||||
__static: `"${path.join(__dirname, '../../src/static').replace(/\\/g, '\\\\')}"`,
|
||||
webpackStaticPath: `"${path.join(__dirname, '../../src/static').replace(/\\/g, '\\\\')}"`,
|
||||
webpackUserApiPath: `"${path.join(__dirname, '../../src/main/modules/userApi').replace(/\\/g, '\\\\')}"`,
|
||||
}),
|
||||
new webpack.NoEmitOnErrorsPlugin(),
|
||||
],
|
||||
performance: {
|
||||
maxEntrypointSize: 1024 * 1024 * 50,
|
||||
maxAssetSize: 1024 * 1024 * 30,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,29 +1,51 @@
|
||||
const path = require('path')
|
||||
const merge = require('webpack-merge')
|
||||
const { merge } = require('webpack-merge')
|
||||
const webpack = require('webpack')
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||
|
||||
const baseConfig = require('./webpack.config.base')
|
||||
|
||||
const { dependencies } = require('../../package.json')
|
||||
// const { dependencies } = require('../../package.json')
|
||||
|
||||
// const buildConfig = require('../webpack-build-config')
|
||||
|
||||
|
||||
module.exports = merge(baseConfig, {
|
||||
mode: 'production',
|
||||
devtool: false,
|
||||
entry: {
|
||||
main: path.join(__dirname, '../../src/main/index.js'),
|
||||
main: path.join(__dirname, '../../src/main/index.ts'),
|
||||
// 'dbService.worker': path.join(__dirname, '../../src/main/worker/dbService/index.ts'),
|
||||
},
|
||||
externals: [
|
||||
...Object.keys(dependencies || {}),
|
||||
],
|
||||
node: {
|
||||
__dirname: false,
|
||||
__filename: false,
|
||||
},
|
||||
plugins: [
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [
|
||||
{
|
||||
from: path.join(__dirname, '../../src/main/modules/userApi/renderer/user-api.html'),
|
||||
to: path.join(__dirname, '../../dist/userApi/renderer/user-api.html'),
|
||||
},
|
||||
{
|
||||
from: path.join(__dirname, '../../src/common/theme/images/*').replace(/\\/g, '/'),
|
||||
to: path.join(__dirname, '../../dist/theme_images/[name][ext]'),
|
||||
},
|
||||
],
|
||||
}),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: '"production"',
|
||||
BUILD_WIN7: `'${process.env.BUILD_WIN7}'`,
|
||||
},
|
||||
}),
|
||||
],
|
||||
performance: {
|
||||
maxEntrypointSize: 1024 * 1024 * 10,
|
||||
maxAssetSize: 1024 * 1024 * 20,
|
||||
},
|
||||
optimization: {
|
||||
minimize: false,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -3,56 +3,101 @@ process.env.NODE_ENV = 'production'
|
||||
const chalk = require('chalk')
|
||||
const del = require('del')
|
||||
const webpack = require('webpack')
|
||||
const Multispinner = require('multispinner')
|
||||
const Spinnies = require('spinnies')
|
||||
|
||||
const mainConfig = require('./main/webpack.config.prod')
|
||||
const rendererConfig = require('./renderer/webpack.config.prod')
|
||||
const mainConfig = './main/webpack.config.prod'
|
||||
const rendererConfig = './renderer/webpack.config.prod'
|
||||
const rendererLyricConfig = './renderer-lyric/webpack.config.prod'
|
||||
const rendererScriptConfig = './renderer-scripts/webpack.config.prod'
|
||||
|
||||
const errorLog = chalk.bgRed.white(' ERROR ') + ' '
|
||||
const okayLog = chalk.bgGreen.white(' OKAY ') + ' '
|
||||
|
||||
const { Worker, isMainThread, parentPort } = require('worker_threads')
|
||||
|
||||
|
||||
function build() {
|
||||
del.sync(['dist/electron', 'build'])
|
||||
|
||||
const tasks = ['main', 'renderer']
|
||||
const m = new Multispinner(tasks, {
|
||||
preText: 'building',
|
||||
postText: 'process',
|
||||
})
|
||||
console.time('build')
|
||||
del.sync(['dist/**', 'build/**'])
|
||||
|
||||
const spinners = new Spinnies({ color: 'blue' })
|
||||
spinners.add('main', { text: 'main building' })
|
||||
spinners.add('renderer', { text: 'renderer building' })
|
||||
spinners.add('renderer-lyric', { text: 'renderer-lyric building' })
|
||||
spinners.add('renderer-scripts', { text: 'renderer-scripts building' })
|
||||
let results = ''
|
||||
|
||||
m.on('success', () => {
|
||||
// m.on('success', () => {
|
||||
// process.stdout.write('\x1B[2J\x1B[0f')
|
||||
// console.log(`\n\n${results}`)
|
||||
// console.log(`${okayLog}take it away ${chalk.yellow('`electron-builder`')}\n`)
|
||||
// process.exit()
|
||||
// })
|
||||
function handleSuccess() {
|
||||
process.stdout.write('\x1B[2J\x1B[0f')
|
||||
console.log(`\n\n${results}`)
|
||||
console.log(`${okayLog}take it away ${chalk.yellow('`electron-builder`')}\n`)
|
||||
console.timeEnd('build')
|
||||
process.exit()
|
||||
})
|
||||
}
|
||||
|
||||
pack(mainConfig).then(result => {
|
||||
results += result + '\n\n'
|
||||
m.success('main')
|
||||
}).catch(err => {
|
||||
m.error('main')
|
||||
console.log(`\n ${errorLog}failed to build main process`)
|
||||
console.error(`\n${err}\n`)
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
pack(rendererConfig).then(result => {
|
||||
results += result + '\n\n'
|
||||
m.success('renderer')
|
||||
}).catch(err => {
|
||||
m.error('renderer')
|
||||
console.log(`\n ${errorLog}failed to build renderer process`)
|
||||
console.error(`\n${err}\n`)
|
||||
process.exit(1)
|
||||
})
|
||||
Promise.all([
|
||||
pack(mainConfig).then(result => {
|
||||
results += result + '\n\n'
|
||||
spinners.succeed('main', { text: 'main build success!' })
|
||||
}).catch(err => {
|
||||
spinners.fail('main', { text: 'main build fail :(' })
|
||||
console.log(`\n ${errorLog}failed to build main process`)
|
||||
console.error(`\n${err}\n`)
|
||||
process.exit(1)
|
||||
}),
|
||||
pack(rendererConfig).then(result => {
|
||||
results += result + '\n\n'
|
||||
spinners.succeed('renderer', { text: 'renderer build success!' })
|
||||
}).catch(err => {
|
||||
spinners.fail('renderer', { text: 'renderer build fail :(' })
|
||||
console.log(`\n ${errorLog}failed to build renderer process`)
|
||||
console.error(`\n${err}\n`)
|
||||
process.exit(1)
|
||||
}),
|
||||
pack(rendererLyricConfig).then(result => {
|
||||
results += result + '\n\n'
|
||||
spinners.succeed('renderer-lyric', { text: 'renderer-lyric build success!' })
|
||||
}).catch(err => {
|
||||
spinners.fail('renderer-lyric', { text: 'renderer-lyric build fail :(' })
|
||||
console.log(`\n ${errorLog}failed to build renderer-lyric process`)
|
||||
console.error(`\n${err}\n`)
|
||||
process.exit(1)
|
||||
}),
|
||||
pack(rendererScriptConfig).then(result => {
|
||||
results += result + '\n\n'
|
||||
spinners.succeed('renderer-scripts', { text: 'renderer-scripts build success!' })
|
||||
}).catch(err => {
|
||||
spinners.fail('renderer-scripts', { text: 'renderer-scripts build fail :(' })
|
||||
console.log(`\n ${errorLog}failed to build renderer-scripts process`)
|
||||
console.error(`\n${err}\n`)
|
||||
process.exit(1)
|
||||
}),
|
||||
]).then(handleSuccess)
|
||||
}
|
||||
|
||||
function pack(config) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const worker = new Worker(__filename)
|
||||
const subChannel = new MessageChannel()
|
||||
worker.postMessage({ port: subChannel.port1, config }, [subChannel.port1])
|
||||
subChannel.port2.on('message', ({ status, message }) => {
|
||||
switch (status) {
|
||||
case 'success': return resolve(message)
|
||||
case 'error': return reject(message)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function runPack(config) {
|
||||
return new Promise((resolve, reject) => {
|
||||
config = require(config)
|
||||
config.mode = 'production'
|
||||
webpack(config, (err, stats) => {
|
||||
if (err) reject(err.stack || err)
|
||||
@@ -80,5 +125,22 @@ function pack(config) {
|
||||
})
|
||||
}
|
||||
|
||||
build()
|
||||
|
||||
if (isMainThread) build()
|
||||
else {
|
||||
parentPort.once('message', ({ port, config }) => {
|
||||
// assert(port instanceof MessagePort)
|
||||
runPack(config).then((result) => {
|
||||
port.postMessage({
|
||||
status: 'success',
|
||||
message: result,
|
||||
})
|
||||
}).catch((err) => {
|
||||
port.postMessage({
|
||||
status: 'error',
|
||||
message: err,
|
||||
})
|
||||
}).finally(() => {
|
||||
port.close()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
2
build-config/post-install.js
Normal file
@@ -0,0 +1,2 @@
|
||||
const { Arch } = require('electron-builder')
|
||||
require('./build-before-pack')({ electronPlatformName: process.platform, arch: Arch[process.arch] })
|
||||
3
build-config/postinstall.js
Normal file
@@ -0,0 +1,3 @@
|
||||
const { copyLib } = require('./deps')
|
||||
|
||||
copyLib()
|
||||
147
build-config/renderer-lyric/webpack.config.base.js
Normal file
@@ -0,0 +1,147 @@
|
||||
const path = require('path')
|
||||
const { VueLoaderPlugin } = require('vue-loader')
|
||||
const HTMLPlugin = require('html-webpack-plugin')
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
|
||||
const ESLintPlugin = require('eslint-webpack-plugin')
|
||||
|
||||
const vueLoaderConfig = require('../vue-loader.config')
|
||||
const { mergeCSSLoader } = require('../utils')
|
||||
|
||||
const isDev = process.env.NODE_ENV === 'development'
|
||||
|
||||
module.exports = {
|
||||
target: 'electron-renderer',
|
||||
entry: {
|
||||
'renderer-lyric': path.join(__dirname, '../../src/renderer-lyric/main.ts'),
|
||||
},
|
||||
output: {
|
||||
filename: '[name].js',
|
||||
library: {
|
||||
type: 'commonjs2',
|
||||
},
|
||||
path: path.join(__dirname, '../../dist'),
|
||||
publicPath: '',
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@root': path.join(__dirname, '../../src'),
|
||||
'@main': path.join(__dirname, '../../src/main'),
|
||||
'@renderer': path.join(__dirname, '../../src/renderer'),
|
||||
'@lyric': path.join(__dirname, '../../src/renderer-lyric'),
|
||||
'@static': path.join(__dirname, '../../src/static'),
|
||||
'@common': path.join(__dirname, '../../src/common'),
|
||||
},
|
||||
extensions: ['.tsx', '.ts', '.js', '.json', '.node'],
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
appendTsSuffixTo: [/\.vue$/],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.node$/,
|
||||
use: 'node-loader',
|
||||
},
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader',
|
||||
options: vueLoaderConfig,
|
||||
},
|
||||
{
|
||||
test: /\.pug$/,
|
||||
loader: 'pug-plain-loader',
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
oneOf: mergeCSSLoader(),
|
||||
},
|
||||
{
|
||||
test: /\.less$/,
|
||||
oneOf: mergeCSSLoader({
|
||||
loader: 'less-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
||||
exclude: path.join(__dirname, '../../src/renderer/assets/svgs'),
|
||||
type: 'asset',
|
||||
parser: {
|
||||
dataUrlCondition: {
|
||||
maxSize: 10000,
|
||||
},
|
||||
},
|
||||
generator: {
|
||||
filename: 'imgs/[name]-[contenthash:8][ext]',
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.svg$/,
|
||||
include: path.join(__dirname, '../../src/renderer/assets/svgs'),
|
||||
use: [
|
||||
{
|
||||
loader: 'svg-sprite-loader',
|
||||
options: {
|
||||
symbolId: 'icon-[name]',
|
||||
},
|
||||
},
|
||||
'svg-transform-loader',
|
||||
'svgo-loader',
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
|
||||
type: 'asset',
|
||||
parser: {
|
||||
dataUrlCondition: {
|
||||
maxSize: 10000,
|
||||
},
|
||||
},
|
||||
generator: {
|
||||
filename: 'media/[name]-[contenthash:8][ext]',
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
||||
type: 'asset',
|
||||
parser: {
|
||||
dataUrlCondition: {
|
||||
maxSize: 10000,
|
||||
},
|
||||
},
|
||||
generator: {
|
||||
filename: 'fonts/[name]-[contenthash:8][ext]',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new HTMLPlugin({
|
||||
filename: 'lyric.html',
|
||||
template: path.join(__dirname, '../../src/renderer-lyric/index.html'),
|
||||
isProd: process.env.NODE_ENV == 'production',
|
||||
browser: process.browser,
|
||||
__dirname,
|
||||
}),
|
||||
new VueLoaderPlugin(),
|
||||
new MiniCssExtractPlugin({
|
||||
// Options similar to the same options in webpackOptions.output
|
||||
// both options are optional
|
||||
filename: isDev ? '[name].css' : '[name].[contenthash:8].css',
|
||||
chunkFilename: isDev ? '[id].css' : '[id].[contenthash:8].css',
|
||||
}),
|
||||
new ESLintPlugin({
|
||||
extensions: ['js', 'vue'],
|
||||
formatter: require('eslint-formatter-friendly'),
|
||||
}),
|
||||
],
|
||||
}
|
||||
27
build-config/renderer-lyric/webpack.config.dev.js
Normal file
@@ -0,0 +1,27 @@
|
||||
const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
|
||||
const { merge } = require('webpack-merge')
|
||||
|
||||
const baseConfig = require('./webpack.config.base')
|
||||
|
||||
module.exports = merge(baseConfig, {
|
||||
mode: 'development',
|
||||
devtool: 'eval-source-map',
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: '"development"',
|
||||
ELECTRON_DISABLE_SECURITY_WARNINGS: 'true',
|
||||
},
|
||||
__VUE_OPTIONS_API__: 'true',
|
||||
__VUE_PROD_DEVTOOLS__: 'false',
|
||||
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false',
|
||||
staticPath: `"${path.join(__dirname, '../../src/static').replace(/\\/g, '\\\\')}"`,
|
||||
}),
|
||||
],
|
||||
performance: {
|
||||
hints: false,
|
||||
},
|
||||
})
|
||||
|
||||
50
build-config/renderer-lyric/webpack.config.prod.js
Normal file
@@ -0,0 +1,50 @@
|
||||
// const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
|
||||
const TerserPlugin = require('terser-webpack-plugin')
|
||||
const { merge } = require('webpack-merge')
|
||||
|
||||
const baseConfig = require('./webpack.config.base')
|
||||
const buildConfig = require('../webpack-build-config')
|
||||
|
||||
// const { dependencies } = require('../../package.json')
|
||||
|
||||
// let whiteListedModules = ['vue']
|
||||
// let whiteListedModules = ['vue', 'vue-router', 'vuex', 'vue-i18n']
|
||||
|
||||
|
||||
module.exports = merge(baseConfig, {
|
||||
mode: 'production',
|
||||
devtool: 'source-map',
|
||||
externals: [
|
||||
// ...Object.keys(dependencies || {}).filter(d => !whiteListedModules.includes(d)),
|
||||
],
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: '"production"',
|
||||
},
|
||||
__VUE_OPTIONS_API__: 'true',
|
||||
__VUE_PROD_DEVTOOLS__: 'false',
|
||||
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false',
|
||||
}),
|
||||
],
|
||||
optimization: {
|
||||
minimize: buildConfig.minimize,
|
||||
minimizer: [
|
||||
new TerserPlugin(),
|
||||
new CssMinimizerPlugin(),
|
||||
],
|
||||
},
|
||||
performance: {
|
||||
maxEntrypointSize: 1024 * 1024 * 10,
|
||||
maxAssetSize: 1024 * 1024 * 20,
|
||||
hints: 'warning',
|
||||
},
|
||||
node: {
|
||||
__dirname: false,
|
||||
__filename: false,
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
52
build-config/renderer-scripts/webpack.config.base.js
Normal file
@@ -0,0 +1,52 @@
|
||||
const path = require('path')
|
||||
const ESLintPlugin = require('eslint-webpack-plugin')
|
||||
|
||||
module.exports = {
|
||||
target: 'electron-renderer',
|
||||
entry: {
|
||||
'user-api-preload': path.join(__dirname, '../../src/main/modules/userApi/renderer/preload.js'),
|
||||
},
|
||||
output: {
|
||||
filename: '[name].js',
|
||||
library: {
|
||||
type: 'commonjs2',
|
||||
},
|
||||
path: path.join(__dirname, '../../dist'),
|
||||
publicPath: '',
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@root': path.join(__dirname, '../../src'),
|
||||
'@main': path.join(__dirname, '../../src/main'),
|
||||
'@renderer': path.join(__dirname, '../../src/renderer'),
|
||||
'@lyric': path.join(__dirname, '../../src/renderer-lyric'),
|
||||
'@static': path.join(__dirname, '../../src/static'),
|
||||
'@common': path.join(__dirname, '../../src/common'),
|
||||
},
|
||||
extensions: ['.tsx', '.ts', '.js', '.json', '.node'],
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
appendTsSuffixTo: [/\.vue$/],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.node$/,
|
||||
use: 'node-loader',
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new ESLintPlugin({
|
||||
extensions: ['js'],
|
||||
formatter: require('eslint-formatter-friendly'),
|
||||
}),
|
||||
],
|
||||
}
|
||||
24
build-config/renderer-scripts/webpack.config.dev.js
Normal file
@@ -0,0 +1,24 @@
|
||||
const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
|
||||
const { merge } = require('webpack-merge')
|
||||
|
||||
const baseConfig = require('./webpack.config.base')
|
||||
|
||||
module.exports = merge(baseConfig, {
|
||||
mode: 'development',
|
||||
devtool: 'eval-source-map',
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: '"development"',
|
||||
ELECTRON_DISABLE_SECURITY_WARNINGS: 'true',
|
||||
},
|
||||
staticPath: `"${path.join(__dirname, '../../src/static').replace(/\\/g, '\\\\')}"`,
|
||||
}),
|
||||
],
|
||||
performance: {
|
||||
hints: false,
|
||||
},
|
||||
})
|
||||
|
||||
45
build-config/renderer-scripts/webpack.config.prod.js
Normal file
@@ -0,0 +1,45 @@
|
||||
// const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
const TerserPlugin = require('terser-webpack-plugin')
|
||||
const { merge } = require('webpack-merge')
|
||||
|
||||
const baseConfig = require('./webpack.config.base')
|
||||
const buildConfig = require('../webpack-build-config')
|
||||
|
||||
// const { dependencies } = require('../../package.json')
|
||||
|
||||
// let whiteListedModules = ['vue']
|
||||
// let whiteListedModules = ['vue', 'vue-router', 'vuex', 'vue-i18n']
|
||||
|
||||
|
||||
module.exports = merge(baseConfig, {
|
||||
mode: 'production',
|
||||
devtool: 'source-map',
|
||||
externals: [
|
||||
// ...Object.keys(dependencies || {}).filter(d => !whiteListedModules.includes(d)),
|
||||
],
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: '"production"',
|
||||
},
|
||||
}),
|
||||
],
|
||||
optimization: {
|
||||
minimize: buildConfig.minimize,
|
||||
minimizer: [
|
||||
new TerserPlugin(),
|
||||
],
|
||||
},
|
||||
performance: {
|
||||
maxEntrypointSize: 1024 * 1024 * 10,
|
||||
maxAssetSize: 1024 * 1024 * 20,
|
||||
hints: 'warning',
|
||||
},
|
||||
node: {
|
||||
__dirname: false,
|
||||
__filename: false,
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -1,40 +1,59 @@
|
||||
const path = require('path')
|
||||
const VueLoaderPlugin = require('vue-loader/lib/plugin')
|
||||
const { VueLoaderPlugin } = require('vue-loader')
|
||||
const HTMLPlugin = require('html-webpack-plugin')
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
|
||||
const ESLintPlugin = require('eslint-webpack-plugin')
|
||||
|
||||
const vueLoaderConfig = require('../vue-loader.config')
|
||||
const { mergeCSSLoader } = require('../utils')
|
||||
|
||||
const isDev = process.env.NODE_ENV === 'development'
|
||||
|
||||
module.exports = {
|
||||
target: 'electron-renderer',
|
||||
entry: {
|
||||
renderer: path.join(__dirname, '../../src/renderer/main.js'),
|
||||
renderer: path.join(__dirname, '../../src/renderer/main.ts'),
|
||||
},
|
||||
output: {
|
||||
filename: '[name].js',
|
||||
libraryTarget: 'commonjs2',
|
||||
path: path.join(__dirname, '../../dist/electron'),
|
||||
publicPath: './',
|
||||
library: {
|
||||
type: 'commonjs2',
|
||||
},
|
||||
path: path.join(__dirname, '../../dist'),
|
||||
publicPath: '',
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.join(__dirname, '../../src/renderer'),
|
||||
common: path.join(__dirname, '../../src/common'),
|
||||
'@root': path.join(__dirname, '../../src'),
|
||||
'@main': path.join(__dirname, '../../src/main'),
|
||||
'@renderer': path.join(__dirname, '../../src/renderer'),
|
||||
'@lyric': path.join(__dirname, '../../src/renderer-lyric'),
|
||||
'@static': path.join(__dirname, '../../src/static'),
|
||||
'@common': path.join(__dirname, '../../src/common'),
|
||||
},
|
||||
extensions: ['*', '.js', '.json', '.vue', '.node'],
|
||||
extensions: ['.tsx', '.ts', '.js', '.json', '.node'],
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(vue|js)$/,
|
||||
test: /\.tsx?$/,
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: 'eslint-loader',
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
formatter: require('eslint-formatter-friendly'),
|
||||
appendTsSuffixTo: [/\.vue$/],
|
||||
},
|
||||
},
|
||||
exclude: /node_modules/,
|
||||
enforce: 'pre',
|
||||
parser: {
|
||||
worker: [
|
||||
'*audioContext.audioWorklet.addModule()',
|
||||
'...',
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.node$/,
|
||||
use: 'node-loader',
|
||||
},
|
||||
{
|
||||
test: /\.vue$/,
|
||||
@@ -42,61 +61,93 @@ module.exports = {
|
||||
options: vueLoaderConfig,
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
loader: 'babel-loader',
|
||||
exclude: /node_modules/,
|
||||
test: /\.pug$/,
|
||||
loader: 'pug-plain-loader',
|
||||
},
|
||||
{
|
||||
test: /\.pug$/,
|
||||
oneOf: [
|
||||
// Use pug-plain-loader handle .vue file
|
||||
{
|
||||
resourceQuery: /vue/,
|
||||
use: ['pug-plain-loader'],
|
||||
test: /\.css$/,
|
||||
oneOf: mergeCSSLoader(),
|
||||
},
|
||||
{
|
||||
test: /\.less$/,
|
||||
oneOf: mergeCSSLoader({
|
||||
loader: 'less-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
},
|
||||
// Use pug-loader handle .pug file
|
||||
{
|
||||
use: ['pug-loader'],
|
||||
},
|
||||
],
|
||||
}),
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: 'imgs/[name]--[folder].[ext]',
|
||||
exclude: path.join(__dirname, '../../src/renderer/assets/svgs'),
|
||||
type: 'asset',
|
||||
parser: {
|
||||
dataUrlCondition: {
|
||||
maxSize: 10000,
|
||||
},
|
||||
},
|
||||
generator: {
|
||||
filename: 'imgs/[name]-[contenthash:8][ext]',
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: 'media/[name]--[folder].[ext]',
|
||||
test: /\.svg$/,
|
||||
include: path.join(__dirname, '../../src/renderer/assets/svgs'),
|
||||
use: [
|
||||
{
|
||||
loader: 'svg-sprite-loader',
|
||||
options: {
|
||||
symbolId: 'icon-[name]',
|
||||
},
|
||||
},
|
||||
'svg-transform-loader',
|
||||
'svgo-loader',
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)$/,
|
||||
type: 'asset',
|
||||
parser: {
|
||||
dataUrlCondition: {
|
||||
maxSize: 10000,
|
||||
},
|
||||
},
|
||||
generator: {
|
||||
filename: 'media/[name]-[contenthash:8][ext]',
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: 'fonts/[name]--[folder].[ext]',
|
||||
type: 'asset',
|
||||
parser: {
|
||||
dataUrlCondition: {
|
||||
maxSize: 10000,
|
||||
},
|
||||
},
|
||||
generator: {
|
||||
filename: 'fonts/[name]-[contenthash:8][ext]',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
performance: {
|
||||
maxEntrypointSize: 300000,
|
||||
},
|
||||
plugins: [
|
||||
new HTMLPlugin({
|
||||
filename: 'index.html',
|
||||
template: path.join(__dirname, '../../src/index.pug'),
|
||||
template: path.join(__dirname, '../../src/renderer/index.html'),
|
||||
isProd: process.env.NODE_ENV == 'production',
|
||||
browser: process.browser,
|
||||
__dirname,
|
||||
}),
|
||||
new VueLoaderPlugin(),
|
||||
new MiniCssExtractPlugin({
|
||||
// Options similar to the same options in webpackOptions.output
|
||||
// both options are optional
|
||||
filename: isDev ? '[name].css' : '[name].[contenthash:8].css',
|
||||
chunkFilename: isDev ? '[id].css' : '[id].[contenthash:8].css',
|
||||
}),
|
||||
new ESLintPlugin({
|
||||
extensions: ['js', 'vue'],
|
||||
formatter: require('eslint-formatter-friendly'),
|
||||
}),
|
||||
],
|
||||
}
|
||||
|
||||
@@ -1,52 +1,31 @@
|
||||
const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
|
||||
|
||||
const merge = require('webpack-merge')
|
||||
const { merge } = require('webpack-merge')
|
||||
|
||||
const baseConfig = require('./webpack.config.base')
|
||||
|
||||
const { mergeCSSLoaderDev } = require('../utils')
|
||||
const gitInfo = {
|
||||
commit_id: '',
|
||||
commit_date: '',
|
||||
}
|
||||
|
||||
module.exports = merge(baseConfig, {
|
||||
mode: 'development',
|
||||
devtool: 'eval-source-map',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.css$/,
|
||||
oneOf: mergeCSSLoaderDev(),
|
||||
},
|
||||
{
|
||||
test: /\.less$/,
|
||||
oneOf: mergeCSSLoaderDev({
|
||||
loader: 'less-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
test: /\.styl(:?us)?$/,
|
||||
oneOf: mergeCSSLoaderDev({
|
||||
loader: 'stylus-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
},
|
||||
}),
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.NoEmitOnErrorsPlugin(),
|
||||
new FriendlyErrorsPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: '"development"',
|
||||
ELECTRON_DISABLE_SECURITY_WARNINGS: 'true',
|
||||
},
|
||||
__static: `"${path.join(__dirname, '../../src/static').replace(/\\/g, '\\\\')}"`,
|
||||
// ENVIRONMENT: 'process.env',
|
||||
__VUE_OPTIONS_API__: 'true',
|
||||
__VUE_PROD_DEVTOOLS__: 'false',
|
||||
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false',
|
||||
COMMIT_ID: `"${gitInfo.commit_id}"`,
|
||||
COMMIT_DATE: `"${gitInfo.commit_date}"`,
|
||||
staticPath: `"${path.join(__dirname, '../../src/static').replace(/\\/g, '\\\\')}"`,
|
||||
}),
|
||||
],
|
||||
performance: {
|
||||
|
||||
@@ -1,80 +1,79 @@
|
||||
const path = require('path')
|
||||
const { execSync } = require('child_process')
|
||||
const webpack = require('webpack')
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
|
||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
|
||||
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
|
||||
const TerserPlugin = require('terser-webpack-plugin')
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||
const merge = require('webpack-merge')
|
||||
const { merge } = require('webpack-merge')
|
||||
|
||||
const baseConfig = require('./webpack.config.base')
|
||||
const buildConfig = require('../webpack-build-config')
|
||||
|
||||
const { mergeCSSLoaderProd } = require('../utils')
|
||||
const { dependencies } = require('../../package.json')
|
||||
// const { dependencies } = require('../../package.json')
|
||||
|
||||
let whiteListedModules = ['vue']
|
||||
// let whiteListedModules = ['vue', 'vue-router', 'vuex', 'vue-i18n']
|
||||
|
||||
const gitInfo = {
|
||||
commit_id: '',
|
||||
commit_date: '',
|
||||
}
|
||||
|
||||
try {
|
||||
let isClean = !execSync('git status --porcelain').toString().trim()
|
||||
if (process.env.BUILD_WIN7) {
|
||||
console.warn('BUILD_WIN7 is set, skipping git status check.')
|
||||
console.log('Workspace status:', execSync('git status --porcelain').toString().trim())
|
||||
isClean = true
|
||||
}
|
||||
if (isClean) {
|
||||
gitInfo.commit_id = execSync('git log -1 --pretty=format:"%H"').toString().trim()
|
||||
gitInfo.commit_date = execSync('git log -1 --pretty=format:"%ad" --date=iso-strict').toString().trim()
|
||||
} else if (process.env.IS_CI) {
|
||||
throw new Error('Working directory is not clean')
|
||||
}
|
||||
} catch {}
|
||||
|
||||
module.exports = merge(baseConfig, {
|
||||
mode: 'production',
|
||||
devtool: false,
|
||||
devtool: 'source-map',
|
||||
externals: [
|
||||
...Object.keys(dependencies || {}).filter(d => !whiteListedModules.includes(d)),
|
||||
// ...Object.keys(dependencies || {}).filter(d => !whiteListedModules.includes(d)),
|
||||
],
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.css$/,
|
||||
oneOf: mergeCSSLoaderProd(),
|
||||
},
|
||||
{
|
||||
test: /\.less$/,
|
||||
oneOf: mergeCSSLoaderProd({
|
||||
loader: 'less-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
test: /\.styl(:?us)?$/,
|
||||
oneOf: mergeCSSLoaderProd({
|
||||
loader: 'stylus-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
},
|
||||
}),
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new CopyWebpackPlugin([
|
||||
{
|
||||
from: path.join(__dirname, '../../src/static'),
|
||||
to: path.join(__dirname, '../../dist/electron/static'),
|
||||
ignore: ['.*'],
|
||||
},
|
||||
]),
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [
|
||||
{
|
||||
from: path.join(__dirname, '../../src/static'),
|
||||
to: path.join(__dirname, '../../dist/static'),
|
||||
},
|
||||
],
|
||||
}),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: '"production"',
|
||||
},
|
||||
// ENVIRONMENT: 'process.env',
|
||||
__VUE_OPTIONS_API__: 'true',
|
||||
__VUE_PROD_DEVTOOLS__: 'false',
|
||||
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false',
|
||||
COMMIT_ID: `"${gitInfo.commit_id}"`,
|
||||
COMMIT_DATE: `"${gitInfo.commit_date}"`,
|
||||
}),
|
||||
new MiniCssExtractPlugin({
|
||||
filename: '[name].css',
|
||||
}),
|
||||
new webpack.NamedChunksPlugin(),
|
||||
],
|
||||
optimization: {
|
||||
minimize: buildConfig.minimize,
|
||||
minimizer: [
|
||||
new TerserPlugin({
|
||||
cache: true,
|
||||
parallel: true,
|
||||
sourceMap: false, // set to true if you want JS source maps
|
||||
}),
|
||||
new OptimizeCSSAssetsPlugin({}),
|
||||
new TerserPlugin(),
|
||||
new CssMinimizerPlugin(),
|
||||
],
|
||||
splitChunks: {
|
||||
chunks: 'initial',
|
||||
minChunks: 2,
|
||||
},
|
||||
},
|
||||
performance: {
|
||||
maxEntrypointSize: 1024 * 1024 * 10,
|
||||
maxAssetSize: 1024 * 1024 * 20,
|
||||
hints: 'warning',
|
||||
},
|
||||
node: {
|
||||
|
||||
@@ -7,16 +7,21 @@ const path = require('path')
|
||||
const { spawn } = require('child_process')
|
||||
const webpack = require('webpack')
|
||||
const WebpackDevServer = require('webpack-dev-server')
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
const webpackHotMiddleware = require('webpack-hot-middleware')
|
||||
|
||||
const mainConfig = require('./main/webpack.config.dev')
|
||||
const rendererConfig = require('./renderer/webpack.config.dev')
|
||||
|
||||
const { logStats } = require('./utils')
|
||||
const rendererLyricConfig = require('./renderer-lyric/webpack.config.dev')
|
||||
const rendererScriptConfig = require('./renderer-scripts/webpack.config.dev')
|
||||
const { Arch } = require('electron-builder')
|
||||
const replaceLib = require('./build-before-pack')
|
||||
const treeKill = require('tree-kill')
|
||||
const { debounce } = require('./utils')
|
||||
|
||||
let electronProcess = null
|
||||
let manualRestart = false
|
||||
let hotMiddleware
|
||||
let hotMiddlewareRenderer
|
||||
let hotMiddlewareRendererLyric
|
||||
|
||||
|
||||
function startRenderer() {
|
||||
@@ -24,80 +29,143 @@ function startRenderer() {
|
||||
// rendererConfig.entry.renderer = [path.join(__dirname, 'dev-client')].concat(rendererConfig.entry.renderer)
|
||||
// rendererConfig.mode = 'development'
|
||||
const compiler = webpack(rendererConfig)
|
||||
hotMiddleware = webpackHotMiddleware(compiler, {
|
||||
hotMiddlewareRenderer = webpackHotMiddleware(compiler, {
|
||||
log: false,
|
||||
heartbeat: 2500,
|
||||
})
|
||||
|
||||
compiler.hooks.compilation.tap('compilation', compilation => {
|
||||
// console.log(Object.keys(compilation.hooks))
|
||||
compilation.hooks.htmlWebpackPluginAfterEmit.tapAsync('html-webpack-plugin-after-emit', (data, cb) => {
|
||||
hotMiddleware.publish({ action: 'reload' })
|
||||
HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync('html-webpack-plugin-after-emit', (data, cb) => {
|
||||
hotMiddlewareRenderer.publish({ action: 'reload' })
|
||||
cb()
|
||||
})
|
||||
})
|
||||
|
||||
compiler.hooks.done.tap('done', stats => {
|
||||
// logStats('Renderer', 'Compile done')
|
||||
// logStats('Renderer', stats)
|
||||
})
|
||||
// compiler.hooks.done.tap('done', stats => {
|
||||
// // logStats('Renderer', 'Compile done')
|
||||
// // logStats('Renderer', stats)
|
||||
// })
|
||||
|
||||
const server = new WebpackDevServer(
|
||||
compiler,
|
||||
{
|
||||
contentBase: path.join(__dirname, '../'),
|
||||
quiet: true,
|
||||
hot: true,
|
||||
historyApiFallback: true,
|
||||
clientLogLevel: 'warning',
|
||||
overlay: {
|
||||
errors: true,
|
||||
},
|
||||
before(app, ctx) {
|
||||
app.use(hotMiddleware)
|
||||
ctx.middleware.waitUntilValid(() => {
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
}
|
||||
)
|
||||
const server = new WebpackDevServer({
|
||||
port: 9080,
|
||||
hot: true,
|
||||
historyApiFallback: true,
|
||||
static: {
|
||||
directory: path.join(__dirname, '../src/common/theme/images'),
|
||||
publicPath: '/theme_images',
|
||||
},
|
||||
client: {
|
||||
logging: 'warn',
|
||||
overlay: true,
|
||||
},
|
||||
setupMiddlewares(middlewares, devServer) {
|
||||
devServer.app.use(hotMiddlewareRenderer)
|
||||
setImmediate(() => {
|
||||
devServer.middleware.waitUntilValid(resolve)
|
||||
})
|
||||
|
||||
server.listen(9080)
|
||||
return middlewares
|
||||
},
|
||||
}, compiler)
|
||||
|
||||
server.start()
|
||||
})
|
||||
}
|
||||
|
||||
function startMain() {
|
||||
function startRendererLyric() {
|
||||
return new Promise((resolve, reject) => {
|
||||
// rendererConfig.entry.renderer = [path.join(__dirname, 'dev-client')].concat(rendererConfig.entry.renderer)
|
||||
// rendererConfig.mode = 'development'
|
||||
const compiler = webpack(rendererLyricConfig)
|
||||
hotMiddlewareRendererLyric = webpackHotMiddleware(compiler, {
|
||||
log: false,
|
||||
heartbeat: 2500,
|
||||
})
|
||||
|
||||
compiler.hooks.compilation.tap('compilation', compilation => {
|
||||
// console.log(Object.keys(compilation.hooks))
|
||||
HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync('html-webpack-plugin-after-emit', (data, cb) => {
|
||||
hotMiddlewareRendererLyric.publish({ action: 'reload' })
|
||||
cb()
|
||||
})
|
||||
})
|
||||
|
||||
// compiler.hooks.done.tap('done', stats => {
|
||||
// // logStats('Renderer', 'Compile done')
|
||||
// // logStats('Renderer', stats)
|
||||
// })
|
||||
|
||||
const server = new WebpackDevServer({
|
||||
port: 9081,
|
||||
hot: true,
|
||||
historyApiFallback: true,
|
||||
// static: {
|
||||
// directory: path.join(__dirname, '../'),
|
||||
// },
|
||||
client: {
|
||||
logging: 'warn',
|
||||
overlay: true,
|
||||
},
|
||||
setupMiddlewares(middlewares, devServer) {
|
||||
devServer.app.use(hotMiddlewareRenderer)
|
||||
setImmediate(() => {
|
||||
devServer.middleware.waitUntilValid(resolve)
|
||||
})
|
||||
return middlewares
|
||||
},
|
||||
}, compiler)
|
||||
|
||||
server.start()
|
||||
})
|
||||
}
|
||||
|
||||
function startRendererScripts() {
|
||||
return new Promise((resolve, reject) => {
|
||||
// mainConfig.entry.main = [path.join(__dirname, '../src/main/index.dev.js')].concat(mainConfig.entry.main)
|
||||
// mainConfig.mode = 'development'
|
||||
const compiler = webpack(mainConfig)
|
||||
|
||||
compiler.hooks.watchRun.tapAsync('watch-run', (compilation, done) => {
|
||||
logStats('Main', chalk.white.bold('compiling...'))
|
||||
hotMiddleware.publish({ action: 'compiling' })
|
||||
done()
|
||||
})
|
||||
const compiler = webpack(rendererScriptConfig)
|
||||
|
||||
compiler.watch({}, (err, stats) => {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
return
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// logStats('Main', stats)
|
||||
function startMain() {
|
||||
let firstRun = true
|
||||
return new Promise((resolve, reject) => {
|
||||
// mainConfig.entry.main = [path.join(__dirname, '../src/main/index.dev.js')].concat(mainConfig.entry.main)
|
||||
// mainConfig.mode = 'development'
|
||||
const runElectronDelay = debounce(startElectron, 200)
|
||||
const compiler = webpack(mainConfig)
|
||||
|
||||
if (electronProcess && electronProcess.kill) {
|
||||
manualRestart = true
|
||||
process.kill(electronProcess.pid)
|
||||
electronProcess = null
|
||||
startElectron()
|
||||
compiler.hooks.watchRun.tapAsync('watch-run', (compilation, done) => {
|
||||
hotMiddlewareRenderer.publish({ action: 'compiling' })
|
||||
hotMiddlewareRendererLyric.publish({ action: 'compiling' })
|
||||
done()
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
manualRestart = false
|
||||
}, 5000)
|
||||
compiler.watch({}, (err, stats) => {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
reject(err)
|
||||
return
|
||||
}
|
||||
|
||||
resolve()
|
||||
// logStats('Main', stats)
|
||||
if (electronProcess) {
|
||||
electronProcess.removeAllListeners()
|
||||
treeKill(electronProcess.pid)
|
||||
}
|
||||
if (firstRun) {
|
||||
firstRun = false
|
||||
resolve()
|
||||
} else runElectronDelay()
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -106,7 +174,7 @@ function startElectron() {
|
||||
let args = [
|
||||
'--inspect=5858',
|
||||
// 'NODE_ENV=development',
|
||||
path.join(__dirname, '../dist/electron/main.js'),
|
||||
path.join(__dirname, '../dist/main.js'),
|
||||
]
|
||||
|
||||
// detect yarn or npm and process commandline args accordingly
|
||||
@@ -126,45 +194,60 @@ function startElectron() {
|
||||
})
|
||||
|
||||
electronProcess.on('close', () => {
|
||||
if (!manualRestart) process.exit()
|
||||
process.exit()
|
||||
})
|
||||
}
|
||||
|
||||
const logs = [
|
||||
'Manifest version 2 is deprecated, and support will be removed in 2023',
|
||||
'"Extension server error: Operation failed: Permission denied", source: devtools://devtools/bundled',
|
||||
|
||||
// https://github.com/electron/electron/issues/32133
|
||||
'"Electron sandbox_bundle.js script failed to run"',
|
||||
'"TypeError: object null is not iterable (cannot read property Symbol(Symbol.iterator))",',
|
||||
]
|
||||
function electronLog(data, color) {
|
||||
let log = data.toString()
|
||||
if (/[0-9A-z]+/.test(log)) {
|
||||
// 抑制某些无关的报错日志
|
||||
if (color == 'red' && typeof log === 'string' && logs.some(l => log.includes(l))) return
|
||||
|
||||
console.log(chalk[color](log))
|
||||
}
|
||||
}
|
||||
|
||||
function greeting() {
|
||||
/* const cols = process.stdout.columns
|
||||
let text = ''
|
||||
|
||||
if (cols > 104) text = 'electron-vue'
|
||||
else if (cols > 76) text = 'electron-|vue'
|
||||
else text = false
|
||||
|
||||
if (text) {
|
||||
say(text, {
|
||||
colors: ['yellow'],
|
||||
font: 'simple3d',
|
||||
space: false,
|
||||
})
|
||||
} else console.log(chalk.yellow.bold('\n electron-vue')) */
|
||||
console.log(chalk.blue('getting ready...') + '\n')
|
||||
}
|
||||
|
||||
function init() {
|
||||
greeting()
|
||||
const Spinnies = require('spinnies')
|
||||
const spinners = new Spinnies({ color: 'blue' })
|
||||
spinners.add('main', { text: 'main compiling' })
|
||||
spinners.add('renderer', { text: 'renderer compiling' })
|
||||
spinners.add('renderer-lyric', { text: 'renderer-lyric compiling' })
|
||||
spinners.add('renderer-scripts', { text: 'renderer-scripts compiling' })
|
||||
function handleSuccess(name) {
|
||||
spinners.succeed(name, { text: name + ' compile success!' })
|
||||
}
|
||||
function handleFail(name) {
|
||||
spinners.fail(name, { text: name + ' compile fail!' })
|
||||
}
|
||||
replaceLib({ electronPlatformName: process.platform, arch: Arch[process.arch] })
|
||||
|
||||
Promise.all([startRenderer(), startMain()])
|
||||
.then(() => {
|
||||
startElectron()
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
})
|
||||
Promise.all([
|
||||
startRenderer().then(() => handleSuccess('renderer')).catch((err) => {
|
||||
console.error(err.message)
|
||||
return handleFail('renderer')
|
||||
}),
|
||||
startRendererLyric().then(() => handleSuccess('renderer-lyric')).catch((err) => {
|
||||
console.error(err.message)
|
||||
return handleFail('renderer-lyric')
|
||||
}),
|
||||
startRendererScripts().then(() => handleSuccess('renderer-scripts')).catch((err) => {
|
||||
console.error(err.message)
|
||||
return handleFail('renderer-scripts')
|
||||
}),
|
||||
startMain().then(() => handleSuccess('main')).catch(() => handleFail('main')),
|
||||
]).then(startElectron).catch(err => {
|
||||
console.error(err)
|
||||
})
|
||||
}
|
||||
|
||||
init()
|
||||
|
||||
@@ -2,62 +2,19 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin')
|
||||
const cssLoaderConfig = require('./css-loader.config')
|
||||
const chalk = require('chalk')
|
||||
|
||||
// merge css-loader in development
|
||||
exports.mergeCSSLoaderDev = beforeLoader => {
|
||||
// merge css-loader
|
||||
exports.mergeCSSLoader = beforeLoader => {
|
||||
const loader = [
|
||||
// 这里匹配 `<style module>`
|
||||
{
|
||||
resourceQuery: /module/,
|
||||
use: [
|
||||
'vue-style-loader',
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: Object.assign({
|
||||
sourceMap: true,
|
||||
}, cssLoaderConfig),
|
||||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
loader: MiniCssExtractPlugin.loader,
|
||||
options: {
|
||||
sourceMap: true,
|
||||
esModule: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
// 这里匹配普通的 `<style>` 或 `<style scoped>`
|
||||
{
|
||||
use: [
|
||||
'vue-style-loader',
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
if (beforeLoader) {
|
||||
loader[0].use.push(beforeLoader)
|
||||
loader[1].use.push(beforeLoader)
|
||||
}
|
||||
return loader
|
||||
}
|
||||
|
||||
// merge css-loader in production
|
||||
exports.mergeCSSLoaderProd = beforeLoader => {
|
||||
const loader = [
|
||||
// 这里匹配 `<style module>`
|
||||
{
|
||||
resourceQuery: /module/,
|
||||
use: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: cssLoaderConfig,
|
||||
@@ -68,8 +25,18 @@ exports.mergeCSSLoaderProd = beforeLoader => {
|
||||
// 这里匹配普通的 `<style>` 或 `<style scoped>`
|
||||
{
|
||||
use: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
'css-loader',
|
||||
{
|
||||
loader: MiniCssExtractPlugin.loader,
|
||||
options: {
|
||||
esModule: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
esModule: false,
|
||||
},
|
||||
},
|
||||
'postcss-loader',
|
||||
],
|
||||
},
|
||||
@@ -101,3 +68,15 @@ exports.logStats = (proc, data) => {
|
||||
console.log(log)
|
||||
}
|
||||
|
||||
exports.debounce = (fn, delay = 100) => {
|
||||
let timer = null
|
||||
let _args
|
||||
return (...args) => {
|
||||
_args = args
|
||||
if (timer) clearTimeout(timer)
|
||||
timer = setTimeout(() => {
|
||||
timer = null
|
||||
fn(..._args)
|
||||
}, delay)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
const HTMLPlugin = require('html-webpack-plugin')
|
||||
const VueLoaderPlugin = require('vue-loader/lib/plugin')
|
||||
|
||||
const vueLoaderConfig = require('../vue-loader.config')
|
||||
|
||||
module.exports = {
|
||||
target: 'web',
|
||||
entry: path.join(__dirname, '../../src/renderer/main.js'),
|
||||
output: {
|
||||
path: path.join(__dirname, '../../dist/web'),
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.join(__dirname, '../../src/renderer'),
|
||||
common: path.join(__dirname, '../../src/common'),
|
||||
},
|
||||
extensions: ['*', '.js', '.vue', '.json', '.css'],
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(vue|js)$/,
|
||||
use: {
|
||||
loader: 'eslint-loader',
|
||||
options: {
|
||||
formatter: require('eslint-formatter-friendly'),
|
||||
},
|
||||
},
|
||||
exclude: /node_modules/,
|
||||
enforce: 'pre',
|
||||
},
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader',
|
||||
options: vueLoaderConfig,
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
loader: 'babel-loader',
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
{
|
||||
test: /\.pug$/,
|
||||
oneOf: [
|
||||
// Use pug-plain-loader handle .vue file
|
||||
{
|
||||
resourceQuery: /vue/,
|
||||
use: ['pug-plain-loader'],
|
||||
},
|
||||
// Use pug-loader handle .pug file
|
||||
{
|
||||
use: ['pug-loader'],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
||||
use: {
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: 'imgs/[name].[ext]',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
||||
use: {
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: 'fonts/[name].[ext]',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
performance: {
|
||||
maxEntrypointSize: 300000,
|
||||
},
|
||||
plugins: [
|
||||
new VueLoaderPlugin(),
|
||||
new HTMLPlugin({
|
||||
filename: 'index.html',
|
||||
template: path.resolve(__dirname, '../../src/index.pug'),
|
||||
nodeModules: false,
|
||||
isProd: process.env.NODE_ENV == 'production',
|
||||
browser: process.browser,
|
||||
__dirname,
|
||||
}),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.IS_WEB': 'true',
|
||||
}),
|
||||
],
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
const merge = require('webpack-merge')
|
||||
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
|
||||
|
||||
const baseConfig = require('./webpack.config.base')
|
||||
|
||||
const { mergeCSSLoaderDev } = require('../utils')
|
||||
|
||||
module.exports = merge(baseConfig, {
|
||||
mode: 'development',
|
||||
devtool: 'eval-source-map',
|
||||
output: {
|
||||
filename: '[name].js',
|
||||
path: path.join(__dirname, '../../dist/web'),
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.css$/,
|
||||
oneOf: mergeCSSLoaderDev(),
|
||||
},
|
||||
{
|
||||
test: /\.less$/,
|
||||
oneOf: mergeCSSLoaderDev({
|
||||
loader: 'less-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
test: /\.styl$/,
|
||||
oneOf: mergeCSSLoaderDev({
|
||||
loader: 'stylus-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
},
|
||||
}),
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: '"development"',
|
||||
},
|
||||
}),
|
||||
new FriendlyErrorsPlugin(),
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.NoEmitOnErrorsPlugin(),
|
||||
],
|
||||
performance: {
|
||||
hints: false,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||
const merge = require('webpack-merge')
|
||||
const TerserPlugin = require('terser-webpack-plugin')
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
|
||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
|
||||
const baseConfig = require('./webpack.config.base')
|
||||
|
||||
const { mergeCSSLoaderProd } = require('../utils')
|
||||
|
||||
|
||||
module.exports = merge(baseConfig, {
|
||||
mode: 'production',
|
||||
devtool: false,
|
||||
output: {
|
||||
filename: '[name].[chunkhash:8].js',
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.css$/,
|
||||
oneOf: mergeCSSLoaderProd(),
|
||||
},
|
||||
{
|
||||
test: /\.less$/,
|
||||
oneOf: mergeCSSLoaderProd({
|
||||
loader: 'less-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
test: /\.styl$/,
|
||||
oneOf: mergeCSSLoaderProd({
|
||||
loader: 'stylus-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
},
|
||||
}),
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new CopyWebpackPlugin([
|
||||
{
|
||||
from: path.join(__dirname, '../../src/static'),
|
||||
to: path.join(__dirname, '../dist/web/static'),
|
||||
ignore: ['.*'],
|
||||
},
|
||||
]),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: '"production"',
|
||||
},
|
||||
}),
|
||||
new MiniCssExtractPlugin({
|
||||
filename: '[name].[contentHash:8].css',
|
||||
}),
|
||||
new webpack.NamedChunksPlugin(),
|
||||
],
|
||||
optimization: {
|
||||
minimizer: [
|
||||
new TerserPlugin({
|
||||
cache: true,
|
||||
parallel: true,
|
||||
sourceMap: false, // set to true if you want JS source maps
|
||||
}),
|
||||
new OptimizeCSSAssetsPlugin({}),
|
||||
],
|
||||
splitChunks: {
|
||||
cacheGroups: {
|
||||
// chunks: 'all',
|
||||
vendors: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
name: 'vendors',
|
||||
enforce: true,
|
||||
chunks: 'all',
|
||||
},
|
||||
styles: {
|
||||
name: 'styles',
|
||||
test: /\.(css|less)$/,
|
||||
chunks: 'all',
|
||||
enforce: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
runtimeChunk: true,
|
||||
},
|
||||
performance: {
|
||||
hints: 'warning',
|
||||
},
|
||||
})
|
||||
3
build-config/webpack-build-config.js
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
minimize: true,
|
||||
}
|
||||
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 487 KiB |
18
jsconfig.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"rootDir": "./",
|
||||
"paths": {
|
||||
"@main/*": ["./src/main/*"],
|
||||
"@renderer/*": ["./src/renderer/*"],
|
||||
"@lyric/*": ["./src/renderer-lyric/*"],
|
||||
"@static/*": ["./src/static/*"],
|
||||
"@common/*": ["./src/common/*"],
|
||||
}
|
||||
},
|
||||
"vueCompilerOptions": {
|
||||
"plugins": [
|
||||
"@vue/language-plugin-pug"
|
||||
]
|
||||
},
|
||||
"exclude": ["node_modules", "build", "dist"]
|
||||
}
|
||||
@@ -1,42 +1,49 @@
|
||||
{\rtf1\adeflang1025\ansi\ansicpg936\uc2\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi31507\deflang1033\deflangfe2052\themelang1033\themelangfe2052\themelangcs0{\fonttbl{\f2\fbidi \fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;}
|
||||
{\rtf1\adeflang1025\ansi\ansicpg936\uc2\adeff0\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi0\deflang1033\deflangfe2052\themelang1033\themelangfe2052\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f2\fbidi \fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;}
|
||||
{\f13\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}\'cb\'ce\'cc\'e5{\*\falt SimSun};}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;}
|
||||
{\f44\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}@\'cb\'ce\'cc\'e5;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
|
||||
{\f36\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}\'b5\'c8\'cf\'df{\*\falt DengXian};}{\f44\fbidi \fnil\fcharset134\fprq2{\*\panose 00000000000000000000}@\'cb\'ce\'cc\'e5;}
|
||||
{\f45\fbidi \fnil\fcharset134\fprq2{\*\panose 00000000000000000000}@\'b5\'c8\'cf\'df;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
|
||||
{\fdbmajor\f31501\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}\'b5\'c8\'cf\'df Light;}{\fhimajor\f31502\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}\'b5\'c8\'cf\'df Light;}
|
||||
{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
|
||||
{\fdbminor\f31505\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}\'b5\'c8\'cf\'df{\*\falt DengXian};}{\fhiminor\f31506\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}\'b5\'c8\'cf\'df{\*\falt DengXian};}
|
||||
{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f65\fbidi \fmodern\fcharset238\fprq1 Courier New CE;}{\f66\fbidi \fmodern\fcharset204\fprq1 Courier New Cyr;}
|
||||
{\f68\fbidi \fmodern\fcharset161\fprq1 Courier New Greek;}{\f69\fbidi \fmodern\fcharset162\fprq1 Courier New Tur;}{\f70\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew);}{\f71\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic);}
|
||||
{\f72\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f73\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f177\fbidi \fnil\fcharset0\fprq2 SimSun Western{\*\falt SimSun};}{\f487\fbidi \fnil\fcharset0\fprq2 @SimSun Western;}
|
||||
{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
|
||||
{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
|
||||
{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31520\fbidi \fnil\fcharset0\fprq2 DengXian Light Western;}
|
||||
{\fdbmajor\f31518\fbidi \fnil\fcharset238\fprq2 DengXian Light CE;}{\fdbmajor\f31519\fbidi \fnil\fcharset204\fprq2 DengXian Light Cyr;}{\fdbmajor\f31521\fbidi \fnil\fcharset161\fprq2 DengXian Light Greek;}
|
||||
{\fhimajor\f31530\fbidi \fnil\fcharset0\fprq2 DengXian Light Western;}{\fhimajor\f31528\fbidi \fnil\fcharset238\fprq2 DengXian Light CE;}{\fhimajor\f31529\fbidi \fnil\fcharset204\fprq2 DengXian Light Cyr;}
|
||||
{\fhimajor\f31531\fbidi \fnil\fcharset161\fprq2 DengXian Light Greek;}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
|
||||
{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
|
||||
{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
|
||||
{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
|
||||
{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
|
||||
{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31560\fbidi \fnil\fcharset0\fprq2 DengXian Western{\*\falt DengXian};}
|
||||
{\fdbminor\f31558\fbidi \fnil\fcharset238\fprq2 DengXian CE{\*\falt DengXian};}{\fdbminor\f31559\fbidi \fnil\fcharset204\fprq2 DengXian Cyr{\*\falt DengXian};}{\fdbminor\f31561\fbidi \fnil\fcharset161\fprq2 DengXian Greek{\*\falt DengXian};}
|
||||
{\fhiminor\f31570\fbidi \fnil\fcharset0\fprq2 DengXian Western{\*\falt DengXian};}{\fhiminor\f31568\fbidi \fnil\fcharset238\fprq2 DengXian CE{\*\falt DengXian};}{\fhiminor\f31569\fbidi \fnil\fcharset204\fprq2 DengXian Cyr{\*\falt DengXian};}
|
||||
{\fhiminor\f31571\fbidi \fnil\fcharset161\fprq2 DengXian Greek{\*\falt DengXian};}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
|
||||
{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
|
||||
{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
|
||||
{\f45\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f46\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\f48\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f49\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
|
||||
{\f50\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f51\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f52\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
|
||||
{\f53\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;
|
||||
\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\red0\green0\blue0;\red0\green0\blue0;}
|
||||
{\*\defchp \fs21\kerning2\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{
|
||||
\qj \li0\ri0\nowidctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs21\lang1033\langfe2052\kerning2\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp2052
|
||||
{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f46\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f47\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
|
||||
{\f49\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f50\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f51\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f52\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
|
||||
{\f53\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f54\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f66\fbidi \fmodern\fcharset238\fprq1 Courier New CE;}{\f67\fbidi \fmodern\fcharset204\fprq1 Courier New Cyr;}
|
||||
{\f69\fbidi \fmodern\fcharset161\fprq1 Courier New Greek;}{\f70\fbidi \fmodern\fcharset162\fprq1 Courier New Tur;}{\f71\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew);}{\f72\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic);}
|
||||
{\f73\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f74\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f178\fbidi \fnil\fcharset0\fprq2 SimSun Western{\*\falt SimSun};}{\f386\fbidi \froman\fcharset238\fprq2 Cambria Math CE;}
|
||||
{\f387\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}{\f389\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f390\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f393\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}
|
||||
{\f394\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}{\f408\fbidi \fnil\fcharset0\fprq2 DengXian Western{\*\falt DengXian};}{\f406\fbidi \fnil\fcharset238\fprq2 DengXian CE{\*\falt DengXian};}
|
||||
{\f407\fbidi \fnil\fcharset204\fprq2 DengXian Cyr{\*\falt DengXian};}{\f409\fbidi \fnil\fcharset161\fprq2 DengXian Greek{\*\falt DengXian};}{\f488\fbidi \fnil\fcharset0\fprq2 @SimSun Western;}{\f498\fbidi \fnil\fcharset0\fprq2 @DengXian Western;}
|
||||
{\f496\fbidi \fnil\fcharset238\fprq2 @DengXian CE;}{\f497\fbidi \fnil\fcharset204\fprq2 @DengXian Cyr;}{\f499\fbidi \fnil\fcharset161\fprq2 @DengXian Greek;}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
|
||||
{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
|
||||
{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
|
||||
{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31520\fbidi \fnil\fcharset0\fprq2 DengXian Light Western;}{\fdbmajor\f31518\fbidi \fnil\fcharset238\fprq2 DengXian Light CE;}
|
||||
{\fdbmajor\f31519\fbidi \fnil\fcharset204\fprq2 DengXian Light Cyr;}{\fdbmajor\f31521\fbidi \fnil\fcharset161\fprq2 DengXian Light Greek;}{\fhimajor\f31530\fbidi \fnil\fcharset0\fprq2 DengXian Light Western;}
|
||||
{\fhimajor\f31528\fbidi \fnil\fcharset238\fprq2 DengXian Light CE;}{\fhimajor\f31529\fbidi \fnil\fcharset204\fprq2 DengXian Light Cyr;}{\fhimajor\f31531\fbidi \fnil\fcharset161\fprq2 DengXian Light Greek;}
|
||||
{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
|
||||
{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
|
||||
{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
|
||||
{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
|
||||
{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
|
||||
{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31560\fbidi \fnil\fcharset0\fprq2 DengXian Western{\*\falt DengXian};}{\fdbminor\f31558\fbidi \fnil\fcharset238\fprq2 DengXian CE{\*\falt DengXian};}
|
||||
{\fdbminor\f31559\fbidi \fnil\fcharset204\fprq2 DengXian Cyr{\*\falt DengXian};}{\fdbminor\f31561\fbidi \fnil\fcharset161\fprq2 DengXian Greek{\*\falt DengXian};}{\fhiminor\f31570\fbidi \fnil\fcharset0\fprq2 DengXian Western{\*\falt DengXian};}
|
||||
{\fhiminor\f31568\fbidi \fnil\fcharset238\fprq2 DengXian CE{\*\falt DengXian};}{\fhiminor\f31569\fbidi \fnil\fcharset204\fprq2 DengXian Cyr{\*\falt DengXian};}{\fhiminor\f31571\fbidi \fnil\fcharset161\fprq2 DengXian Greek{\*\falt DengXian};}
|
||||
{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
|
||||
{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
|
||||
{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;
|
||||
\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;
|
||||
\red192\green192\blue192;\red0\green0\blue0;\red0\green0\blue0;\chyperlink\ctint255\cshade255\red5\green99\blue193;\red96\green94\blue92;\red225\green223\blue221;\cfollowedhyperlink\ctint255\cshade255\red149\green79\blue114;}{\*\defchp
|
||||
\fs21\kerning2\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{
|
||||
\qj \li0\ri0\nowidctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs21\lang1033\langfe2052\kerning2\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp2052
|
||||
\snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\*
|
||||
\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv
|
||||
\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs21\lang1033\langfe2052\kerning2\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp2052
|
||||
\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs21\alang1025 \ltrch\fcs0 \fs21\lang1033\langfe2052\kerning2\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp2052
|
||||
\snext11 \ssemihidden \sunhideused Normal Table;}{\s15\qj \li0\ri0\nowidctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af2\afs22\alang1025 \ltrch\fcs0
|
||||
\fs21\lang1033\langfe2052\kerning2\loch\f31505\hich\af2\dbch\af31505\cgrid\langnp1033\langfenp2052 \sbasedon0 \snext15 \slink16 \sunhideused Plain Text;}{\*\cs16 \additive \rtlch\fcs1 \af2 \ltrch\fcs0 \loch\f31505\hich\af2 \sbasedon10 \slink15 \slocked
|
||||
\'b4\'bf\'ce\'c4\'b1\'be \'d7\'d6\'b7\'fb;}}{\*\rsidtbl \rsid927107\rsid3950508\rsid11081282\rsid12910709\rsid13643782\rsid14384001}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0
|
||||
\mnaryLim1}{\info{\author lysyw}{\operator lysyw}{\creatim\yr2019\mo8\dy17\hr10\min22}{\revtim\yr2019\mo8\dy17\hr10\min22}{\version2}{\edmins0}{\nofpages1}{\nofwords8}{\nofchars49}{\nofcharsws56}{\vern111}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.co
|
||||
m/office/word/2003/wordml}}\paperw11906\paperh16838\margl2253\margr2253\margt1440\margb1440\gutter0\ltrsect
|
||||
\'b4\'bf\'ce\'c4\'b1\'be \'d7\'d6\'b7\'fb;}{\*\cs17 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf19 \sbasedon10 \sunhideused \styrsid9533173 Hyperlink;}{\*\cs18 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \cf20\chshdng0\chcfpat0\chcbpat21
|
||||
\sbasedon10 \ssemihidden \sunhideused \styrsid9533173 Unresolved Mention;}{\*\cs19 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf22 \sbasedon10 \ssemihidden \sunhideused \styrsid9533173 FollowedHyperlink;}}{\*\pgptbl {\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}}
|
||||
{\*\rsidtbl \rsid927107\rsid1398824\rsid2109456\rsid2766548\rsid3758332\rsid3950508\rsid4133944\rsid4355753\rsid9533173\rsid10447395\rsid11081282\rsid12910709\rsid13643782\rsid14384001\rsid14511311\rsid15225067\rsid15226681}{\mmathPr\mmathFont34\mbrkBin0
|
||||
\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\author lysyw}{\operator lysyw}{\creatim\yr2019\mo8\dy17\hr10\min22}{\revtim\yr2025\mo2\dy22\hr15\min34}{\version12}{\edmins5}{\nofpages2}
|
||||
{\nofwords195}{\nofchars1117}{\nofcharsws1310}{\vern77}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}\paperw11906\paperh16838\margl2253\margr2253\margt1440\margb1440\gutter0\ltrsect
|
||||
\deftab420\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata0\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors1\formshade\horzdoc\dgmargin\dghspace180\dgvspace156
|
||||
\dghorigin2253\dgvorigin1440\dghshow0\dgvshow2\jcompress\lnongrid
|
||||
\viewkind1\viewscale100\splytwnine\ftnlytwnine\htmautsp\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct\asianbrkrule\rsidroot3950508\newtblstyruls
|
||||
@@ -49,18 +56,129 @@ $([\'7b{\uc2\u163 \'a1\'ea\u165 \'a3\'a4\'a1\'a4\'a1\'ae\'a1\'b0\'a1\'b4\'a1\'b6
|
||||
\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\headery851\footery992\colsx425\endnhere\sectlinegrid312\sectspecifyl\sectrsid2109456\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta \dbch .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang
|
||||
{\pntxta \dbch .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta \dbch .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta \dbch )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb \dbch (}{\pntxta \dbch )}}{\*\pnseclvl6
|
||||
\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb \dbch (}{\pntxta \dbch )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb \dbch (}{\pntxta \dbch )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb \dbch (}{\pntxta \dbch )}}{\*\pnseclvl9
|
||||
\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb \dbch (}{\pntxta \dbch )}}\pard\plain \ltrpar\s15\qj \li0\ri0\nowidctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid12910709 \rtlch\fcs1 \af2\afs22\alang1025 \ltrch\fcs0
|
||||
\fs21\lang1033\langfe2052\kerning2\loch\af31505\hich\af2\dbch\af31505\cgrid\langnp1033\langfenp2052 {\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid12910709\charrsid12910709 \loch\af13\hich\af13\dbch\f13 \'b1\'be\'b3\'cc\'d0\'f2
|
||||
\'bd\'f6\'d3\'c3\'d3\'da\'d1\'a7\'cf\'b0\'bd\'bb\'c1\'f7\'ca\'b9\'d3\'c3\'a3\'a1}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid12910709\charrsid12910709
|
||||
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid12910709\charrsid12910709 \loch\af13\hich\af13\dbch\f13 \'c7\'eb\'ce\'f0\'d3\'c3\'d3\'da\'c9\'cc\'d2\'b5\'d3\'c3\'cd\'be\'a3\'a1\'a3\'a1}{\rtlch\fcs1 \af13 \ltrch\fcs0
|
||||
\loch\af13\hich\af13\dbch\af13\insrsid12910709\charrsid12910709
|
||||
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid12910709\charrsid12910709 \loch\af13\hich\af13\dbch\f13 \'ca\'b9\'d3\'c3\'b1\'be\'c8\'ed\'bc\'fe\'d4\'ec\'b3\'c9\'b5\'c4\'d2\'bb\'c7\'d0\'ba\'f3\'b9\'fb\'d3\'c9\'ca\'b9\'d3\'c3\'d5\'df
|
||||
\'b3\'d0\'b5\'a3\'a3\'a1}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid12910709\charrsid12910709
|
||||
\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb \dbch (}{\pntxta \dbch )}}\pard\plain \ltrpar\qj \li0\ri0\nowidctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid2766548 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0
|
||||
\fs21\lang1033\langfe2052\kerning2\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp2052 {\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'b1\'be\'cf\'ee\'c4\'bf
|
||||
\'bb\'f9\'d3\'da}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \hich\af13\dbch\af13\loch\f13 Apache License 2.0 }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\loch\af13\hich\af13\dbch\f13 \'d0\'ed\'bf\'c9\'d6\'a4\'b7\'a2\'d0\'d0\'a3\'ac\'d2\'d4\'cf\'c2\'d0\'ad\'d2\'e9\'ca\'c7\'b6\'d4\'d3\'da}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\hich\af13\dbch\af13\loch\f13 Apache License 2.0 }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'b5\'c4\'b2\'b9\'b3\'e4\'a3\'ac\'c8\'e7\'d3\'d0\'b3\'e5\'cd\'bb\'a3\'ac\'d2\'d4
|
||||
\'d2\'d4\'cf\'c2\'d0\'ad\'d2\'e9\'ce\'aa\'d7\'bc\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par \hich\af13\dbch\af13\loch\f13 By: }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid12910709\charrsid12910709 \loch\af13\hich\af13\dbch\f13 \'c2\'e4\'d1\'a9\'ce\'de\'ba\'db}{\rtlch\fcs1 \af13 \ltrch\fcs0
|
||||
\loch\af13\hich\af13\dbch\af13\insrsid12910709\charrsid12910709
|
||||
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'b4\'ca\'d3\'ef\'d4\'bc\'b6\'a8\'a3\'ba\'b1\'be\'d0\'ad\'d2\'e9\'d6\'d0\'b5\'c4\'a1\'b0\'b1\'be\'cf\'ee\'c4\'bf\'a1\'b1\'d6\'b8}{
|
||||
\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \hich\af13\dbch\af13\loch\f13 LX Music }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\loch\af13\hich\af13\dbch\f13 \'d7\'c0\'c3\'e6\'b0\'e6\'cf\'ee\'c4\'bf\'a3\'bb}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \u8220\'a1\'b0}{\rtlch\fcs1 \af13 \ltrch\fcs0
|
||||
\loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'ca\'b9\'d3\'c3\'d5\'df}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \u8221\'a1\'b1}{\rtlch\fcs1 \af13
|
||||
\ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'d6\'b8\'c7\'a9\'ca\'f0\'b1\'be\'d0\'ad\'d2\'e9\'b5\'c4\'ca\'b9\'d3\'c3\'d5\'df\'a3\'bb}{\rtlch\fcs1 \af13 \ltrch\fcs0
|
||||
\loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \u8220\'a1\'b0}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'b9\'d9\'b7\'bd\'d2\'f4\'c0\'d6\'c6\'bd\'cc\'a8}{
|
||||
\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \u8221\'a1\'b1}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'d6\'b8\'b6\'d4\'b1\'be
|
||||
\'cf\'ee\'c4\'bf\'c4\'da\'d6\'c3\'b5\'c4\'b0\'fc\'c0\'a8\'bf\'e1\'ce\'d2\'a1\'a2\'bf\'e1\'b9\'b7\'a1\'a2\'df\'e4\'b9\'be\'b5\'c8\'d2\'f4\'c0\'d6\'d4\'b4\'b5\'c4\'b9\'d9\'b7\'bd\'c6\'bd\'cc\'a8\'cd\'b3\'b3\'c6\'a3\'bb}{\rtlch\fcs1 \af13 \ltrch\fcs0
|
||||
\loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \u8220\'a1\'b0}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'b0\'e6\'c8\'a8\'ca\'fd\'be\'dd}{\rtlch\fcs1 \af13
|
||||
\ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \u8221\'a1\'b1}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'d6\'b8\'b0\'fc\'c0\'a8\'b5\'ab\'b2\'bb
|
||||
\'cf\'de\'d3\'da\'cd\'bc\'cf\'f1\'a1\'a2\'d2\'f4\'c6\'b5\'a1\'a2\'c3\'fb\'d7\'d6\'b5\'c8\'d4\'da\'c4\'da\'b5\'c4\'cb\'fb\'c8\'cb\'d3\'b5\'d3\'d0\'cb\'f9\'ca\'f4\'b0\'e6\'c8\'a8\'b5\'c4\'ca\'fd\'be\'dd\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0
|
||||
\loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'d2\'bb\'a1\'a2\'ca\'fd\'be\'dd\'c0\'b4\'d4\'b4}{\rtlch\fcs1 \af13 \ltrch\fcs0
|
||||
\loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par \hich\af13\dbch\af13\loch\f13 1.1 }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'b1\'be\'cf\'ee\'c4\'bf\'b5\'c4\'b8\'f7\'b9\'d9\'b7\'bd\'c6\'bd\'cc\'a8\'d4\'da\'cf\'df\'ca\'fd
|
||||
\'be\'dd\'c0\'b4\'d4\'b4\'d4\'ad\'c0\'ed\'ca\'c7\'b4\'d3\'c6\'e4\'b9\'ab\'bf\'aa\'b7\'fe\'ce\'f1\'c6\'f7\'d6\'d0\'c0\'ad\'c8\'a1\'ca\'fd\'be\'dd\'a3\'a8\'d3\'eb\'ce\'b4\'b5\'c7\'c2\'bc\'d7\'b4\'cc\'ac\'d4\'da\'b9\'d9\'b7\'bd\'c6\'bd\'cc\'a8}{\rtlch\fcs1
|
||||
\af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \hich\af13\dbch\af13\loch\f13 APP }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'bb\'f1\'c8\'a1
|
||||
\'b5\'c4\'ca\'fd\'be\'dd\'cf\'e0\'cd\'ac\'a3\'a9\'a3\'ac\'be\'ad\'b9\'fd\'b6\'d4\'ca\'fd\'be\'dd\'bc\'f2\'b5\'a5\'b5\'d8\'c9\'b8\'d1\'a1\'d3\'eb\'ba\'cf\'b2\'a2\'ba\'f3\'bd\'f8\'d0\'d0\'d5\'b9\'ca\'be\'a3\'ac\'d2\'f2\'b4\'cb\'b1\'be\'cf\'ee\'c4\'bf
|
||||
\'b2\'bb\'b6\'d4\'ca\'fd\'be\'dd\'b5\'c4\'ba\'cf\'b7\'a8\'d0\'d4\'a1\'a2\'d7\'bc\'c8\'b7\'d0\'d4\'b8\'ba\'d4\'f0\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par \hich\af13\dbch\af13\loch\f13 1.2 }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'b1\'be\'cf\'ee\'c4\'bf\'b1\'be\'c9\'ed\'c3\'bb\'d3\'d0\'bb\'f1\'c8\'a1\'c4\'b3\'b8\'f6\'d2\'f4
|
||||
\'c6\'b5\'ca\'fd\'be\'dd\'b5\'c4\'c4\'dc\'c1\'a6\'a3\'ac\'b1\'be\'cf\'ee\'c4\'bf\'ca\'b9\'d3\'c3\'b5\'c4\'d4\'da\'cf\'df\'d2\'f4\'c6\'b5\'ca\'fd\'be\'dd\'c0\'b4\'d4\'b4\'c0\'b4\'d7\'d4\'c8\'ed\'bc\'fe\'c9\'e8\'d6\'c3\'c4\'da}{\rtlch\fcs1 \af13
|
||||
\ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \u8220\'a1\'b0}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'d7\'d4\'b6\'a8\'d2\'e5\'d4\'b4}{
|
||||
\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \u8221\'a1\'b1}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'c9\'e8\'d6\'c3\'cb\'f9
|
||||
\'d1\'a1\'d4\'f1\'b5\'c4}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \u8220\'a1\'b0}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\loch\af13\hich\af13\dbch\f13 \'d4\'b4}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \u8221\'a1\'b1}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\loch\af13\hich\af13\dbch\f13 \'b7\'b5\'bb\'d8\'b5\'c4\'d4\'da\'cf\'df\'c1\'b4\'bd\'d3\'a1\'a3\'c0\'fd\'c8\'e7\'b2\'a5\'b7\'c5\'c4\'b3\'ca\'d7\'b8\'e8\'a3\'ac\'b1\'be\'cf\'ee\'c4\'bf\'cb\'f9\'d7\'f6\'b5\'c4\'d6\'bb\'ca\'c7\'bd\'ab\'cf\'a3\'cd\'fb\'b2\'a5
|
||||
\'b7\'c5\'b5\'c4\'b8\'e8\'c7\'fa\'c3\'fb\'a1\'a2\'d2\'d5\'ca\'f5\'bc\'d2\'b5\'c8\'d0\'c5\'cf\'a2\'b4\'ab\'b5\'dd\'b8\'f8}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \u8220\'a1\'b0}{\rtlch\fcs1 \af13
|
||||
\ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'d4\'b4}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \u8221\'a1\'b1}{\rtlch\fcs1 \af13 \ltrch\fcs0
|
||||
\loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'a3\'ac\'c8\'f4}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \u8220\'a1\'b0}{\rtlch\fcs1 \af13 \ltrch\fcs0
|
||||
\loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'d4\'b4}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \u8221\'a1\'b1}{\rtlch\fcs1 \af13 \ltrch\fcs0
|
||||
\loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'b7\'b5\'bb\'d8\'c1\'cb\'d2\'bb\'b8\'f6\'c1\'b4\'bd\'d3\'a3\'ac\'d4\'f2\'b1\'be\'cf\'ee\'c4\'bf\'bd\'ab\'c8\'cf\'ce\'aa\'d5\'e2\'be\'cd\'ca\'c7\'b8\'c3\'b8\'e8
|
||||
\'c7\'fa\'b5\'c4\'d2\'f4\'c6\'b5\'ca\'fd\'be\'dd\'b6\'f8\'bd\'f8\'d0\'d0\'ca\'b9\'d3\'c3\'a3\'ac\'d6\'c1\'d3\'da\'d5\'e2\'ca\'c7\'b2\'bb\'ca\'c7\'d5\'fd\'c8\'b7\'b5\'c4\'d2\'f4\'c6\'b5\'ca\'fd\'be\'dd\'b1\'be\'cf\'ee\'c4\'bf\'ce\'de\'b7\'a8\'d0\'a3
|
||||
\'d1\'e9\'c6\'e4\'d7\'bc\'c8\'b7\'d0\'d4\'a3\'ac\'cb\'f9\'d2\'d4\'ca\'b9\'d3\'c3\'b1\'be\'cf\'ee\'c4\'bf\'b5\'c4\'b9\'fd\'b3\'cc\'d6\'d0\'bf\'c9\'c4\'dc\'bb\'e1\'b3\'f6\'cf\'d6\'cf\'a3\'cd\'fb\'b2\'a5\'b7\'c5\'b5\'c4\'d2\'f4\'c6\'b5\'d3\'eb\'ca\'b5
|
||||
\'bc\'ca\'b2\'a5\'b7\'c5\'b5\'c4\'d2\'f4\'c6\'b5\'b2\'bb\'b6\'d4\'d3\'a6\'bb\'f2\'d5\'df\'ce\'de\'b7\'a8\'b2\'a5\'b7\'c5\'b5\'c4\'ce\'ca\'cc\'e2\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par \hich\af13\dbch\af13\loch\f13 1.3 }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'b1\'be\'cf\'ee\'c4\'bf\'b5\'c4\'b7\'c7\'b9\'d9\'b7\'bd\'c6\'bd\'cc\'a8\'ca\'fd\'be\'dd\'a3\'a8
|
||||
\'c0\'fd\'c8\'e7}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \u8220\'a1\'b0}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13
|
||||
\'ce\'d2\'b5\'c4\'c1\'d0\'b1\'ed}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \u8221\'a1\'b1}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\loch\af13\hich\af13\dbch\f13 \'c4\'da\'c1\'d0\'b1\'ed\'a3\'a9\'c0\'b4\'d7\'d4\'ca\'b9\'d3\'c3\'d5\'df\'b1\'be\'b5\'d8\'cf\'b5\'cd\'b3\'bb\'f2\'d5\'df\'ca\'b9\'d3\'c3\'d5\'df\'c1\'ac\'bd\'d3\'b5\'c4\'cd\'ac\'b2\'bd\'b7\'fe\'ce\'f1\'a3\'ac\'b1\'be\'cf\'ee
|
||||
\'c4\'bf\'b2\'bb\'b6\'d4\'d5\'e2\'d0\'a9\'ca\'fd\'be\'dd\'b5\'c4\'ba\'cf\'b7\'a8\'d0\'d4\'a1\'a2\'d7\'bc\'c8\'b7\'d0\'d4\'b8\'ba\'d4\'f0\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'b6\'fe\'a1\'a2\'b0\'e6\'c8\'a8\'ca\'fd\'be\'dd}{\rtlch\fcs1 \af13 \ltrch\fcs0
|
||||
\loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par \hich\af13\dbch\af13\loch\f13 2\hich\af13\dbch\af13\loch\f13 .1 }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'ca\'b9\'d3\'c3\'b1\'be\'cf\'ee\'c4\'bf\'b5\'c4\'b9\'fd\'b3\'cc
|
||||
\'d6\'d0\'bf\'c9\'c4\'dc\'bb\'e1\'b2\'fa\'c9\'fa\'b0\'e6\'c8\'a8\'ca\'fd\'be\'dd\'a1\'a3\'b6\'d4\'d3\'da\'d5\'e2\'d0\'a9\'b0\'e6\'c8\'a8\'ca\'fd\'be\'dd\'a3\'ac\'b1\'be\'cf\'ee\'c4\'bf\'b2\'bb\'d3\'b5\'d3\'d0\'cb\'fc\'c3\'c7\'b5\'c4\'cb\'f9\'d3\'d0
|
||||
\'c8\'a8\'a1\'a3\'ce\'aa\'c1\'cb\'b1\'dc\'c3\'e2\'c7\'d6\'c8\'a8\'a3\'ac\'ca\'b9\'d3\'c3\'d5\'df\'ce\'f1\'b1\'d8\'d4\'da}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \hich\af13\dbch\af13\loch\f13 **24 }{
|
||||
\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'d0\'a1\'ca\'b1\'c4\'da}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\hich\af13\dbch\af13\loch\f13 ** }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'c7\'e5\'b3\'fd\'ca\'b9\'d3\'c3\'b1\'be\'cf\'ee\'c4\'bf\'b5\'c4\'b9\'fd\'b3\'cc\'d6\'d0\'cb\'f9
|
||||
\'b2\'fa\'c9\'fa\'b5\'c4\'b0\'e6\'c8\'a8\'ca\'fd\'be\'dd\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'c8\'fd\'a1\'a2\'d2\'f4\'c0\'d6\'c6\'bd\'cc\'a8\'b1\'f0\'c3\'fb}{\rtlch\fcs1 \af13 \ltrch\fcs0
|
||||
\loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par \hich\af13\dbch\af13\loch\f13 3.1 }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'b1\'be\'cf\'ee\'c4\'bf\'c4\'da\'b5\'c4\'b9\'d9\'b7\'bd\'d2\'f4\'c0\'d6\'c6\'bd\'cc\'a8\'b1\'f0
|
||||
\'c3\'fb\'ce\'aa\'b1\'be\'cf\'ee\'c4\'bf\'c4\'da\'b6\'d4\'b9\'d9\'b7\'bd\'d2\'f4\'c0\'d6\'c6\'bd\'cc\'a8\'b5\'c4\'d2\'bb\'b8\'f6\'b3\'c6\'ba\'f4\'a3\'ac\'b2\'bb\'b0\'fc\'ba\'ac\'b6\'f1\'d2\'e2\'a1\'a3\'c8\'e7\'b9\'fb\'b9\'d9\'b7\'bd\'d2\'f4\'c0\'d6
|
||||
\'c6\'bd\'cc\'a8\'be\'f5\'b5\'c3\'b2\'bb\'cd\'d7\'a3\'ac\'bf\'c9\'c1\'aa\'cf\'b5\'b1\'be\'cf\'ee\'c4\'bf\'b8\'fc\'b8\'c4\'bb\'f2\'d2\'c6\'b3\'fd\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'cb\'c4\'a1\'a2\'d7\'ca\'d4\'b4\'ca\'b9\'d3\'c3}{\rtlch\fcs1 \af13 \ltrch\fcs0
|
||||
\loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par \hich\af13\dbch\af13\loch\f13 4.1 }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'b1\'be\'cf\'ee\'c4\'bf\'c4\'da\'ca\'b9\'d3\'c3\'b5\'c4\'b2\'bf\'b7\'d6\'b0\'fc\'c0\'a8\'b5\'ab
|
||||
\'b2\'bb\'cf\'de\'d3\'da\'d7\'d6\'cc\'e5\'a1\'a2\'cd\'bc\'c6\'ac\'b5\'c8\'d7\'ca\'d4\'b4\'c0\'b4\'d4\'b4\'d3\'da\'bb\'a5\'c1\'aa\'cd\'f8\'a1\'a3\'c8\'e7\'b9\'fb\'b3\'f6\'cf\'d6\'c7\'d6\'c8\'a8\'bf\'c9\'c1\'aa\'cf\'b5\'b1\'be\'cf\'ee\'c4\'bf\'d2\'c6
|
||||
\'b3\'fd\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'ce\'e5\'a1\'a2\'c3\'e2\'d4\'f0\'c9\'f9\'c3\'f7}{\rtlch\fcs1 \af13 \ltrch\fcs0
|
||||
\loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par \hich\af13\dbch\af13\loch\f13 5.1 }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'d3\'c9\'d3\'da\'ca\'b9\'d3\'c3\'b1\'be\'cf\'ee\'c4\'bf\'b2\'fa\'c9\'fa\'b5\'c4\'b0\'fc\'c0\'a8
|
||||
\'d3\'c9\'d3\'da\'b1\'be\'d0\'ad\'d2\'e9\'bb\'f2\'d3\'c9\'d3\'da\'ca\'b9\'d3\'c3\'bb\'f2\'ce\'de\'b7\'a8\'ca\'b9\'d3\'c3\'b1\'be\'cf\'ee\'c4\'bf\'b6\'f8\'d2\'fd\'c6\'f0\'b5\'c4\'c8\'ce\'ba\'ce\'d0\'d4\'d6\'ca\'b5\'c4\'c8\'ce\'ba\'ce\'d6\'b1\'bd\'d3
|
||||
\'a1\'a2\'bc\'e4\'bd\'d3\'a1\'a2\'cc\'d8\'ca\'e2\'a1\'a2\'c5\'bc\'c8\'bb\'bb\'f2\'bd\'e1\'b9\'fb\'d0\'d4\'cb\'f0\'ba\'a6\'a3\'a8\'b0\'fc\'c0\'a8\'b5\'ab\'b2\'bb\'cf\'de\'d3\'da\'d2\'f2\'c9\'cc\'d3\'fe\'cb\'f0\'ca\'a7\'a1\'a2\'cd\'a3\'b9\'a4\'a1\'a2
|
||||
\'bc\'c6\'cb\'e3\'bb\'fa\'b9\'ca\'d5\'cf\'bb\'f2\'b9\'ca\'d5\'cf\'d2\'fd\'c6\'f0\'b5\'c4\'cb\'f0\'ba\'a6\'c5\'e2\'b3\'a5\'a3\'ac\'bb\'f2\'c8\'ce\'ba\'ce\'bc\'b0\'cb\'f9\'d3\'d0\'c6\'e4\'cb\'fb\'c9\'cc\'d2\'b5\'cb\'f0\'ba\'a6\'bb\'f2\'cb\'f0\'ca\'a7
|
||||
\'a3\'a9\'d3\'c9\'ca\'b9\'d3\'c3\'d5\'df\'b8\'ba\'d4\'f0\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'c1\'f9\'a1\'a2\'ca\'b9\'d3\'c3\'cf\'de\'d6\'c6}{\rtlch\fcs1 \af13 \ltrch\fcs0
|
||||
\loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par \hich\af13\dbch\af13\loch\f13 6.1 }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'b1\'be\'cf\'ee\'c4\'bf\'cd\'ea\'c8\'ab\'c3\'e2\'b7\'d1\'a3\'ac\'c7\'d2\'bf\'aa\'d4\'b4\'b7\'a2
|
||||
\'b2\'bc\'d3\'da}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \hich\af13\dbch\af13\loch\f13 GitHub }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\loch\af13\hich\af13\dbch\f13 \'c3\'e6\'cf\'f2\'c8\'ab\'ca\'c0\'bd\'e7\'c8\'cb\'d3\'c3\'d7\'f7\'b6\'d4\'bc\'bc\'ca\'f5\'b5\'c4\'d1\'a7\'cf\'b0\'bd\'bb\'c1\'f7\'a1\'a3\'b1\'be\'cf\'ee\'c4\'bf\'b2\'bb\'b6\'d4\'cf\'ee\'c4\'bf\'c4\'da\'b5\'c4\'bc\'bc\'ca\'f5
|
||||
\'bf\'c9\'c4\'dc\'b4\'e6\'d4\'da\'ce\'a5\'b7\'b4\'b5\'b1\'b5\'d8\'b7\'a8\'c2\'c9\'b7\'a8\'b9\'e6\'b5\'c4\'d0\'d0\'ce\'aa\'d7\'f7\'b1\'a3\'d6\'a4\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par \hich\af13\dbch\af13\loch\f13 6.2 **}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'bd\'fb\'d6\'b9\'d4\'da\'ce\'a5\'b7\'b4\'b5\'b1\'b5\'d8\'b7\'a8\'c2\'c9\'b7\'a8\'b9\'e6
|
||||
\'b5\'c4\'c7\'e9\'bf\'f6\'cf\'c2\'ca\'b9\'d3\'c3\'b1\'be\'cf\'ee\'c4\'bf\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \hich\af13\dbch\af13\loch\f13 ** }{\rtlch\fcs1 \af13 \ltrch\fcs0
|
||||
\loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'b6\'d4\'d3\'da\'ca\'b9\'d3\'c3\'d5\'df\'d4\'da\'c3\'f7\'d6\'aa\'bb\'f2\'b2\'bb\'d6\'aa\'b5\'b1\'b5\'d8\'b7\'a8\'c2\'c9\'b7\'a8\'b9\'e6\'b2\'bb\'d4\'ca\'d0\'ed
|
||||
\'b5\'c4\'c7\'e9\'bf\'f6\'cf\'c2\'ca\'b9\'d3\'c3\'b1\'be\'cf\'ee\'c4\'bf\'cb\'f9\'d4\'ec\'b3\'c9\'b5\'c4\'c8\'ce\'ba\'ce\'ce\'a5\'b7\'a8\'ce\'a5\'b9\'e6\'d0\'d0\'ce\'aa\'d3\'c9\'ca\'b9\'d3\'c3\'d5\'df\'b3\'d0\'b5\'a3\'a3\'ac\'b1\'be\'cf\'ee\'c4\'bf
|
||||
\'b2\'bb\'b3\'d0\'b5\'a3\'d3\'c9\'b4\'cb\'d4\'ec\'b3\'c9\'b5\'c4\'c8\'ce\'ba\'ce\'d6\'b1\'bd\'d3\'a1\'a2\'bc\'e4\'bd\'d3\'a1\'a2\'cc\'d8\'ca\'e2\'a1\'a2\'c5\'bc\'c8\'bb\'bb\'f2\'bd\'e1\'b9\'fb\'d0\'d4\'d4\'f0\'c8\'ce\'a1\'a3}{\rtlch\fcs1 \af13
|
||||
\ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'c6\'df\'a1\'a2\'b0\'e6\'c8\'a8\'b1\'a3\'bb\'a4}{\rtlch\fcs1 \af13 \ltrch\fcs0
|
||||
\loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par \hich\af13\dbch\af13\loch\f13 7.1 }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'d2\'f4\'c0\'d6\'c6\'bd\'cc\'a8\'b2\'bb\'d2\'d7\'a3\'ac\'c7\'eb\'d7\'f0\'d6\'d8\'b0\'e6\'c8\'a8
|
||||
\'a3\'ac\'d6\'a7\'b3\'d6\'d5\'fd\'b0\'e6\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'b0\'cb\'a1\'a2\'b7\'c7\'c9\'cc\'d2\'b5\'d0\'d4\'d6\'ca}{\rtlch\fcs1 \af13 \ltrch\fcs0
|
||||
\loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par \hich\af13\dbch\af13\loch\f13 8.1 }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'b1\'be\'cf\'ee\'c4\'bf\'bd\'f6\'d3\'c3\'d3\'da\'b6\'d4\'bc\'bc\'ca\'f5\'bf\'c9\'d0\'d0\'d0\'d4
|
||||
\'b5\'c4\'cc\'bd\'cb\'f7\'bc\'b0\'d1\'d0\'be\'bf\'a3\'ac\'b2\'bb\'bd\'d3\'ca\'dc\'c8\'ce\'ba\'ce\'c9\'cc\'d2\'b5\'a3\'a8\'b0\'fc\'c0\'a8\'b5\'ab\'b2\'bb\'cf\'de\'d3\'da\'b9\'e3\'b8\'e6\'b5\'c8\'a3\'a9\'ba\'cf\'d7\'f7\'bc\'b0\'be\'e8\'d4\'f9\'a1\'a3}{
|
||||
\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'be\'c5\'a1\'a2\'bd\'d3\'ca\'dc\'d0\'ad\'d2\'e9}{\rtlch\fcs1 \af13 \ltrch\fcs0
|
||||
\loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par \hich\af13\dbch\af13\loch\f13 9.1 }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'c8\'f4\'c4\'e3\'ca\'b9\'d3\'c3\'c1\'cb\'b1\'be\'cf\'ee\'c4\'bf\'a3\'ac\'bc\'b4\'b4\'fa\'b1\'ed
|
||||
\'c4\'e3\'bd\'d3\'ca\'dc\'b1\'be\'d0\'ad\'d2\'e9\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par \hich\af13\dbch\af13\loch\f13 * }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'c8\'f4\'d0\'ad\'d2\'e9\'b8\'fc\'d0\'c2\'a3\'ac\'cb\'a1\'b2\'bb\'c1\'ed\'d0\'d0\'cd\'a8\'d6\'aa
|
||||
\'a3\'ac\'bf\'c9\'b5\'bd\'bf\'aa\'d4\'b4\'b5\'d8\'d6\'b7\'b2\'e9\'bf\'b4\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548
|
||||
\par
|
||||
\par \hich\af13\dbch\af13\loch\f13 By: }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid2766548\charrsid2766548 \loch\af13\hich\af13\dbch\f13 \'c2\'e4\'d1\'a9\'ce\'de\'ba\'db}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid12910709\charrsid2766548
|
||||
|
||||
\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a
|
||||
9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad
|
||||
5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6
|
||||
@@ -114,7 +232,7 @@ e4350d363f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8
|
||||
617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169
|
||||
6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363
|
||||
656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e}
|
||||
{\*\latentstyles\lsdstimax377\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;
|
||||
{\*\latentstyles\lsdstimax376\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 1;
|
||||
@@ -143,18 +261,8 @@ e4350d363f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Cite;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Code;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Definition;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Keyboard;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Preformatted;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Sample;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Typewriter;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Variable;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation subject;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 No List;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 1;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 2;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 3;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 3;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 4;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 3;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 7;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 3;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 7;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 3;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Contemporary;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Elegant;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Professional;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Subtle 1;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Subtle 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Balloon Text;
|
||||
\lsdpriority39 \lsdlocked0 Table Grid;\lsdsemihidden1 \lsdlocked0 Placeholder Text;\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Balloon Text;\lsdpriority39 \lsdlocked0 Table Grid;
|
||||
\lsdsemihidden1 \lsdlocked0 Placeholder Text;\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;
|
||||
\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2;\lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2;
|
||||
\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List;\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List;\lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1;
|
||||
\lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;
|
||||
@@ -202,8 +310,8 @@ e4350d363f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8
|
||||
\lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5;
|
||||
\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6;
|
||||
\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Mention;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hashtag;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Unresolved Mention;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link Error;}}{\*\datastore 0105000002000000180000004d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000060000
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hashtag;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Unresolved Mention;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link;}}{\*\datastore 01050000
|
||||
02000000180000004d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000060000
|
||||
d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
@@ -212,8 +320,8 @@ fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e5000000000000000000000000908a
|
||||
0599a254d501feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000
|
||||
ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e5000000000000000000000000d096
|
||||
bf3efc84db01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000105000000000000}}
|
||||
@@ -1,5 +1,52 @@
|
||||
This program is only for learning to communicate!
|
||||
Do not use for commercial purposes! !
|
||||
All consequences of using this software are borne by the user!
|
||||
This project is issued based on the Apache License 2.0 license. The following agreements are supplemental to the Apache License 2.0. In the event of a conflict, the following agreements shall prevail.
|
||||
|
||||
DEFINITIONS:
|
||||
|
||||
"This Project" refers to the LX Music Desktop Edition (aka lx-music-desktop) project. "User" refers to the user who signed this agreement. "Official Music Streaming Service" refers to collectively the official streaming service corresponding to the music source. "Copyrighted Data" refers to data including, but not limited to, pictures, audio, names, etc., for which others own the copyright.
|
||||
|
||||
1. Data Source
|
||||
|
||||
1.1 The principle of the online data sources of the various official music streaming services of this project is to draw data from its open servers (the same as the data obtained in the unlogged-in state in the official music streaming service app). After simply screening and merging the data, this project is responsible for the legitimacy and accuracy of the data.
|
||||
|
||||
1.2 The ability of this project itself does not obtain certain audio data. The online audio data source used in this project comes from the online link provided by the "API" selected in the software settings. For example, when playing a song, this project only transmits information such as the song title, artist, and other information to the "API". If the "API" returns a link, this project will think that this is the audio data of the song for use, but as for whether this is the correct audio data, this project cannot verify its accuracy. So, in the process of using this project, there may be a problem that the audio you want to play does not correspond to the audio you actually play, or you cannot play it.
|
||||
|
||||
1.3 Data in this project other than official music streaming service (such as lists in "Your Library") comes from the user's local system or a synchronization service that the user connected to. This project is not responsible for the legality and accuracy of this data.
|
||||
|
||||
2. Copyrighted Data
|
||||
|
||||
2.1 During the process of using this project, copyrighted data may be generated. For this copyrighted data, this project does not have their ownership. In order to avoid infringement, users must remove copyrighted data generated during the process of using this project ** within 24 hours **.
|
||||
|
||||
3. Alias of Music Streaming Service
|
||||
|
||||
3.1 The official music streaming service alias within this project is a term used within this project to refer to the official music streaming service and does not contain malicious intent. If the operator of the official music streaming service feels it is inappropriate, you can contact this project to request changes or removals.
|
||||
|
||||
4. Use of Resources
|
||||
|
||||
4.1 The parts used in this project include, but are not limited to, fonts, pictures, and other resources from the Internet. If infringement occurs, you can contact this project.
|
||||
|
||||
5. Disclaimer
|
||||
|
||||
5.1 The use of this project includes any direct, indirect, special, accidental, or result damage due to any nature caused by this agreement or use or inability to use this item (including but not limited to the loss of goodwill, stop work, computer, computer Damage compensation caused by faults or any or all other commercial damage or losses) is the responsibility of users.
|
||||
|
||||
6. Use Restrictions
|
||||
|
||||
6.1 This project is completely free and open source and is published on GitHub for the learning exchanges of technology for people all over the world. This project does not guarantee that the technology in this project may violate local laws and regulations.
|
||||
|
||||
6.2 ** This project is prohibited in violation of local laws and regulations. ** The user is solely responsible for any violation of law caused by the use of this project that the user knows or does not know is not permitted by local law and regulations.
|
||||
|
||||
7. Copyright Protection
|
||||
|
||||
7.1 The operation of a music streaming service is not an easy task. Please respect copyrights and support the genuine.
|
||||
|
||||
8. Non-commercial Nature
|
||||
|
||||
8.1 This project is only used for exploring and research on technical feasibility and does not accept any business (including but not limited to advertising, etc.) cooperation and donations.
|
||||
|
||||
9. Accepting Agreement
|
||||
|
||||
9.1 If you use this project, it will represent you accept this agreement.
|
||||
|
||||
* If the agreement is updated, you will not be notified separately. You can check it out by visiting the project address.
|
||||
* The content of this agreement is translated from the Chinese version of the agreement.
|
||||
|
||||
By: lyswhut
|
||||
|
||||
@@ -1,5 +1,49 @@
|
||||
本程序仅用于学习交流使用!
|
||||
请勿用于商业用途!!
|
||||
使用本软件造成的一切后果由使用者承担!
|
||||
本项目基于 Apache License 2.0 许可证发行,以下协议是对于 Apache License 2.0 的补充,如有冲突,以以下协议为准。
|
||||
|
||||
词语约定:本协议中的“本项目”指 LX Music 桌面版项目;“使用者”指签署本协议的使用者;“官方音乐平台”指对本项目内置的包括酷我、酷狗、咪咕等音乐源的官方平台统称;“版权数据”指包括但不限于图像、音频、名字等在内的他人拥有所属版权的数据。
|
||||
|
||||
一、数据来源
|
||||
|
||||
1.1 本项目的各官方平台在线数据来源原理是从其公开服务器中拉取数据(与未登录状态在官方平台 APP 获取的数据相同),经过对数据简单地筛选与合并后进行展示,因此本项目不对数据的合法性、准确性负责。
|
||||
|
||||
1.2 本项目本身没有获取某个音频数据的能力,本项目使用的在线音频数据来源来自软件设置内“自定义源”设置所选择的“源”返回的在线链接。例如播放某首歌,本项目所做的只是将希望播放的歌曲名、艺术家等信息传递给“源”,若“源”返回了一个链接,则本项目将认为这就是该歌曲的音频数据而进行使用,至于这是不是正确的音频数据本项目无法校验其准确性,所以使用本项目的过程中可能会出现希望播放的音频与实际播放的音频不对应或者无法播放的问题。
|
||||
|
||||
1.3 本项目的非官方平台数据(例如“我的列表”内列表)来自使用者本地系统或者使用者连接的同步服务,本项目不对这些数据的合法性、准确性负责。
|
||||
|
||||
二、版权数据
|
||||
|
||||
2.1 使用本项目的过程中可能会产生版权数据。对于这些版权数据,本项目不拥有它们的所有权。为了避免侵权,使用者务必在 **24 小时内** 清除使用本项目的过程中所产生的版权数据。
|
||||
|
||||
三、音乐平台别名
|
||||
|
||||
3.1 本项目内的官方音乐平台别名为本项目内对官方音乐平台的一个称呼,不包含恶意。如果官方音乐平台觉得不妥,可联系本项目更改或移除。
|
||||
|
||||
四、资源使用
|
||||
|
||||
4.1 本项目内使用的部分包括但不限于字体、图片等资源来源于互联网。如果出现侵权可联系本项目移除。
|
||||
|
||||
五、免责声明
|
||||
|
||||
5.1 由于使用本项目产生的包括由于本协议或由于使用或无法使用本项目而引起的任何性质的任何直接、间接、特殊、偶然或结果性损害(包括但不限于因商誉损失、停工、计算机故障或故障引起的损害赔偿,或任何及所有其他商业损害或损失)由使用者负责。
|
||||
|
||||
六、使用限制
|
||||
|
||||
6.1 本项目完全免费,且开源发布于 GitHub 面向全世界人用作对技术的学习交流。本项目不对项目内的技术可能存在违反当地法律法规的行为作保证。
|
||||
|
||||
6.2 **禁止在违反当地法律法规的情况下使用本项目。** 对于使用者在明知或不知当地法律法规不允许的情况下使用本项目所造成的任何违法违规行为由使用者承担,本项目不承担由此造成的任何直接、间接、特殊、偶然或结果性责任。
|
||||
|
||||
七、版权保护
|
||||
|
||||
7.1 音乐平台不易,请尊重版权,支持正版。
|
||||
|
||||
八、非商业性质
|
||||
|
||||
8.1 本项目仅用于对技术可行性的探索及研究,不接受任何商业(包括但不限于广告等)合作及捐赠。
|
||||
|
||||
九、接受协议
|
||||
|
||||
9.1 若你使用了本项目,即代表你接受本协议。
|
||||
|
||||
* 若协议更新,恕不另行通知,可到开源地址查看。
|
||||
|
||||
By: 落雪无痕
|
||||
|
||||
31092
package-lock.json
generated
377
package.json
@@ -1,124 +1,92 @@
|
||||
{
|
||||
"name": "lx-music-desktop",
|
||||
"version": "0.14.0",
|
||||
"description": "一个免费的音乐下载助手",
|
||||
"main": "./dist/electron/main.js",
|
||||
"productName": "lx-music-desktop",
|
||||
"version": "2.12.6-beta.2",
|
||||
"description": "一个免费的音乐查找助手",
|
||||
"main": "./dist/main.js",
|
||||
"scripts": {
|
||||
"pack": "node build-config/pack.js && npm run pack:win",
|
||||
"pack:win": "npm run pack:win:setup && npm run pack:win:7z",
|
||||
"pack:win:setup": "cross-env TARGET=win_安装版 ARCH=x64_x86 electron-builder -w=nsis --x64 --ia32",
|
||||
"pack:win:portable": "npm run pack:win:portable:x64_x86 && npm run pack:win:portable:x64 && npm run pack:win:portable:x86",
|
||||
"pack:win:portable:x64_x86": "cross-env TARGET=便携版 ARCH=x64_x86 electron-builder -w=portable --x64 --ia32",
|
||||
"pack:win:portable:x64": "cross-env TARGET=便携版 ARCH=x64 electron-builder -w=portable --x64",
|
||||
"pack:win:portable:x86": "cross-env TARGET=便携版 ARCH=x86 electron-builder -w=portable --ia32",
|
||||
"pack:win:7z": "npm run pack:win:7z:x64 && npm run pack:win:7z:x86",
|
||||
"pack:win:7z:x64": "cross-env TARGET=win_绿色版 ARCH=x64 electron-builder -w=7z --x64",
|
||||
"pack:win:7z:x86": "cross-env TARGET=win_绿色版 ARCH=x86 electron-builder -w=7z --ia32",
|
||||
"pack": "node build-config/pack.js && npm run pack:win:setup:x64",
|
||||
"pack:win": "node build-config/pack.js && npm run pack:win:setup:x64 && npm run pack:win:setup:x86 && npm run pack:win:setup:arm64 && npm run pack:win:setup:x86_64 && npm run pack:win:7z",
|
||||
"pack:win:setup:x86_64": "node build-config/build-pack.js target=win arch=x86_64 type=setup",
|
||||
"pack:win:setup:x64": "node build-config/build-pack.js target=win arch=x64 type=setup",
|
||||
"pack:win:setup:x86": "node build-config/build-pack.js target=win arch=x86 type=setup",
|
||||
"pack:win:setup:arm64": "node build-config/build-pack.js target=win arch=arm64 type=setup",
|
||||
"pack:win:portable": "npm run pack:win:portable:x86_64 && npm run pack:win:portable:x64 && npm run pack:win:portable:x86",
|
||||
"pack:win:portable:x86_64": "node build-config/build-pack.js target=win arch=x86_64 type=portable",
|
||||
"pack:win:portable:x64": "node build-config/build-pack.js target=win arch=x64 type=portable",
|
||||
"pack:win:portable:x86": "node build-config/build-pack.js target=win arch=x86 type=portable",
|
||||
"pack:win:7z": "npm run pack:win:7z:x64",
|
||||
"pack:win:7z:x64": "node build-config/build-pack.js target=win arch=x64 type=green",
|
||||
"pack:win:7z:arm64": "node build-config/build-pack.js target=win arch=arm64 type=green",
|
||||
"pack:win7:setup:x64": "node build-config/build-pack.js target=win arch=x64 type=win7_setup",
|
||||
"pack:win7:7z:x64": "node build-config/build-pack.js target=win arch=x64 type=win7_green",
|
||||
"pack:win7:7z:x86": "node build-config/build-pack.js target=win arch=x86 type=win7_green",
|
||||
"pack:linux": "node build-config/pack.js && npm run pack:linux:deb && npm run pack:linux:appImage && npm run pack:linux:rpm && npm run pack:linux:pacman",
|
||||
"pack:linux:appImage": "node build-config/build-pack.js target=linux arch=x64 type=appImage",
|
||||
"pack:linux:deb": "npm run pack:linux:deb:amd64 && npm run pack:linux:deb:arm64 && npm run pack:linux:deb:armv7l",
|
||||
"pack:linux:deb:amd64": "node build-config/build-pack.js target=linux arch=x64 type=deb",
|
||||
"pack:linux:deb:arm64": "node build-config/build-pack.js target=linux arch=arm64 type=deb",
|
||||
"pack:linux:deb:armv7l": "node build-config/build-pack.js target=linux arch=armv7l type=deb",
|
||||
"pack:linux:rpm": "node build-config/build-pack.js target=linux arch=x64 type=rpm",
|
||||
"pack:linux:pacman": "node build-config/build-pack.js target=linux arch=x64 type=pacman",
|
||||
"pack:mac": "node build-config/pack.js && npm run pack:mac:dmg && npm run pack:mac:dmg:arm64",
|
||||
"pack:mac:dmg": "node build-config/build-pack.js target=mac arch=x64 type=dmg",
|
||||
"pack:mac:dmg:arm64": "node build-config/build-pack.js target=mac arch=arm64 type=dmg",
|
||||
"pack:dir": "node build-config/pack.js && node build-config/build-pack.js target=dir",
|
||||
"publish": "node publish",
|
||||
"publish:gh": "node build-config/pack.js && npm run publish:win",
|
||||
"publish:win": "npm run publish:win:7z && npm run publish:win:setup",
|
||||
"publish:win:setup": "cross-env TARGET=Setup ARCH=x64_x86 electron-builder -w=nsis --x64 --ia32 -p onTagOrDraft",
|
||||
"publish:win:portable": "npm run publish:win:portable:x64_x86 && npm run publish:win:portable:x64 && npm run publish:win:portable:x86",
|
||||
"publish:win:portable:x64_x86": "cross-env TARGET=portable ARCH=x64_x86 electron-builder -w=portable --x64 --ia32 -p onTagOrDraft",
|
||||
"publish:win:portable:x64": "cross-env TARGET=portable ARCH=x64 electron-builder -w=portable --x64 -p onTagOrDraft",
|
||||
"publish:win:portable:x86": "cross-env TARGET=portable ARCH=x86 electron-builder -w=portable --ia32 -p onTagOrDraft",
|
||||
"publish:win:7z": "npm run publish:win:7z:x64 && npm run publish:win:7z:x86",
|
||||
"publish:win:7z:x64": "cross-env TARGET=green ARCH=win_x64 electron-builder -w=7z --x64 -p always",
|
||||
"publish:win:7z:x86": "cross-env TARGET=green ARCH=win_x86 electron-builder -w=7z --ia32 -p onTagOrDraft",
|
||||
"publish:gh:mac": "node build-config/pack.js && npm run publish:mac",
|
||||
"publish:mac": "npm run publish:mac:dmg",
|
||||
"publish:mac:dmg": "electron-builder -m=dmg -p onTagOrDraft",
|
||||
"publish:gh:linux": "node build-config/pack.js && npm run publish:linux",
|
||||
"publish:linux": "npm run publish:linux:deb && npm run publish:linux:appImage",
|
||||
"publish:linux:appImage": "cross-env ARCH=x64 electron-builder -l=AppImage -p onTagOrDraft",
|
||||
"publish:linux:deb": "npm run publish:linux:deb:x64 && npm run publish:linux:deb:x86",
|
||||
"publish:linux:deb:x64": "cross-env ARCH=x64 electron-builder -l=deb --x64 -p onTagOrDraft",
|
||||
"publish:linux:deb:x86": "cross-env ARCH=x86 electron-builder -l=deb --ia32 -p onTagOrDraft",
|
||||
"pack:linux": "node build-config/pack.js && electron-builder -l",
|
||||
"pack:dir": "node build-config/pack.js && electron-builder --dir",
|
||||
"dev": "node build-config/runner-dev.js",
|
||||
"clean:electron": "rimraf dist/electron",
|
||||
"clean:web": "rimraf dist/web",
|
||||
"clean": "rimraf dist && rimraf build",
|
||||
"build:main": "cross-env NODE_ENV=production webpack --config build-config/main/webpack.config.prod.js --progress --hide-modules",
|
||||
"build:renderer": "cross-env NODE_ENV=production webpack --config build-config/renderer/webpack.config.prod.js --progress --hide-modules",
|
||||
"build:web": "npm run clean:web && cross-env NODE_ENV=production webpack --config build-config/web/webpack.config.prod.js --progress --hide-modules",
|
||||
"build": "npm run clean:electron && npm run build:main && npm run build:renderer",
|
||||
"lint": "eslint --ext .js,.vue -f ./node_modules/eslint-formatter-friendly src",
|
||||
"lint:fix": "eslint --ext .js,.vue -f ./node_modules/eslint-formatter-friendly --fix src"
|
||||
"publish:win:setup:x64": "node build-config/build-pack.js target=win arch=x64 type=setup publish=always",
|
||||
"publish:win:setup:x86": "node build-config/build-pack.js target=win arch=x86 type=setup publish=always",
|
||||
"publish:win:setup:arm64": "node build-config/build-pack.js target=win arch=arm64 type=setup publish=always",
|
||||
"publish:win:setup:x86_64": "node build-config/build-pack.js target=win arch=x86_64 type=setup publish=always",
|
||||
"publish:win:portable": "npm run publish:win:portable:x86_64 && npm run publish:win:portable:x64 && npm run publish:win:portable:x86",
|
||||
"publish:win:portable:x86_64": "node build-config/build-pack.js target=win arch=x86_64 type=portable publish=always",
|
||||
"publish:win:portable:x64": "node build-config/build-pack.js target=win arch=x64 type=portable publish=always",
|
||||
"publish:win:portable:x86": "node build-config/build-pack.js target=win arch=x86 type=portable publish=always",
|
||||
"publish:win:7z:x64": "node build-config/build-pack.js target=win arch=x64 type=green publish=always",
|
||||
"publish:win:7z:arm64": "node build-config/build-pack.js target=win arch=arm64 type=green publish=always",
|
||||
"publish:win7:setup:x64": "node build-config/build-pack.js target=win arch=x64 type=win7_setup publish=always",
|
||||
"publish:win7:7z:x64": "node build-config/build-pack.js target=win arch=x64 type=win7_green publish=always",
|
||||
"publish:win7:7z:x86": "node build-config/build-pack.js target=win arch=x86 type=win7_green publish=always",
|
||||
"publish:mac:dmg": "node build-config/build-pack.js target=mac arch=x64 type=dmg publish=always",
|
||||
"publish:mac:dmg:arm64": "node build-config/build-pack.js target=mac arch=arm64 type=dmg publish=always",
|
||||
"publish:linux:deb:amd64": "node build-config/build-pack.js target=linux arch=x64 type=deb publish=always",
|
||||
"publish:linux:deb:arm64": "node build-config/build-pack.js target=linux arch=arm64 type=deb publish=always",
|
||||
"publish:linux:deb:armv7l": "node build-config/build-pack.js target=linux arch=armv7l type=deb publish=always",
|
||||
"publish:linux:appImage": "node build-config/build-pack.js target=linux arch=x64 type=appImage publish=always",
|
||||
"publish:linux:rpm": "node build-config/build-pack.js target=linux arch=x64 type=rpm publish=always",
|
||||
"publish:linux:pacman": "node build-config/build-pack.js target=linux arch=x64 type=pacman publish=always",
|
||||
"dev": "cross-env NODE_OPTIONS=--max-http-header-size=200000 node build-config/runner-dev.js",
|
||||
"build:theme": "node src/common/theme/createThemes.js",
|
||||
"build": "node build-config/pack.js",
|
||||
"build:main": "cross-env NODE_ENV=production webpack --config build-config/main/webpack.config.prod.js --progress",
|
||||
"build:renderer": "cross-env NODE_ENV=production webpack --config build-config/renderer/webpack.config.prod.js --progress",
|
||||
"build:renderer-lyric": "cross-env NODE_ENV=production webpack --config build-config/renderer-lyric/webpack.config.prod.js --progress",
|
||||
"build:renderer-scripts": "cross-env NODE_ENV=production webpack --config build-config/renderer-scripts/webpack.config.prod.js --progress",
|
||||
"lint": "eslint --ext .ts,.js,.vue -f node_modules/eslint-formatter-friendly src",
|
||||
"lint:fix": "eslint --ext .ts,.js,.vue -f node_modules/eslint-formatter-friendly --fix src",
|
||||
"postinstall": "node build-config/postinstall.js",
|
||||
"dp": "cross-env ELECTRON_GET_USE_PROXY=true GLOBAL_AGENT_HTTPS_PROXY=http://127.0.0.1:2081 npm run pack",
|
||||
"up": "cross-env ELECTRON_GET_USE_PROXY=true GLOBAL_AGENT_HTTPS_PROXY=http://127.0.0.1:2081 npm i"
|
||||
},
|
||||
"browserslist": [
|
||||
"Electron 7.1.9"
|
||||
"Electron 22.3.0"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
"node": ">= 22",
|
||||
"npm": ">=8.5.2"
|
||||
},
|
||||
"build": {
|
||||
"appId": "cn.toside.music.desktop",
|
||||
"directories": {
|
||||
"output": "./build"
|
||||
"macLanguagesInfoPlistStrings": {
|
||||
"en": {
|
||||
"CFBundleDisplayName": "LX Music",
|
||||
"CFBundleName": "LX Music"
|
||||
},
|
||||
"files": [
|
||||
"dist/electron/**/*"
|
||||
],
|
||||
"extraResources": [
|
||||
"./licenses"
|
||||
],
|
||||
"win": {
|
||||
"icon": "./resources/icons/256x256.ico",
|
||||
"legalTrademarks": "lyswhut",
|
||||
"artifactName": "${productName} v${version} ${env.ARCH} ${env.TARGET}.${ext}"
|
||||
"zh_CN": {
|
||||
"CFBundleDisplayName": "LX Music",
|
||||
"CFBundleName": "LX Music"
|
||||
},
|
||||
"mac": {
|
||||
"icon": "./resources/icons/512x512.icns",
|
||||
"category": "public.app-category.music"
|
||||
},
|
||||
"linux": {
|
||||
"maintainer": "lyswhut <lyswuhut@qq.com>",
|
||||
"artifactName": "${productName} v${version} ${env.ARCH}.${ext}",
|
||||
"icon": "./resources/icons",
|
||||
"category": "Utility;AudioVideo;Audio;Player;Music;",
|
||||
"desktop": {
|
||||
"Name[zh_CN]": "洛雪音乐助手"
|
||||
}
|
||||
},
|
||||
"nsis": {
|
||||
"oneClick": false,
|
||||
"language": "2052",
|
||||
"allowToChangeInstallationDirectory": true,
|
||||
"differentialPackage": true,
|
||||
"license": "./licenses/license.rtf",
|
||||
"shortcutName": "lx-music"
|
||||
},
|
||||
"dmg": {
|
||||
"contents": [
|
||||
{
|
||||
"x": 110,
|
||||
"y": 150,
|
||||
"name": "lx-music"
|
||||
},
|
||||
{
|
||||
"x": 240,
|
||||
"y": 150,
|
||||
"type": "link",
|
||||
"path": "/Applications",
|
||||
"name": "lx-music"
|
||||
}
|
||||
],
|
||||
"title": "洛雪音乐助手 v${version}"
|
||||
},
|
||||
"appImage": {
|
||||
"license": "./licenses/license_zh.txt",
|
||||
"category": "Utility;AudioVideo;Audio;Player;Music;"
|
||||
},
|
||||
"publish": [
|
||||
{
|
||||
"provider": "github",
|
||||
"owner": "lyswhut",
|
||||
"repo": "lx-music-desktop"
|
||||
}
|
||||
]
|
||||
"zh_TW": {
|
||||
"CFBundleDisplayName": "LX Music",
|
||||
"CFBundleName": "LX Music"
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -127,11 +95,11 @@
|
||||
"keywords": [
|
||||
"music-player",
|
||||
"electron-app",
|
||||
"vuejs2"
|
||||
"vuejs3"
|
||||
],
|
||||
"author": {
|
||||
"name": "lyswhut",
|
||||
"email": "lyswuhut@qq.com"
|
||||
"email": "lyswhut@qq.com"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"bugs": {
|
||||
@@ -139,82 +107,117 @@
|
||||
},
|
||||
"homepage": "https://github.com/lyswhut/lx-music-desktop#readme",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.8.3",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||
"@babel/polyfill": "^7.8.3",
|
||||
"@babel/preset-env": "^7.8.3",
|
||||
"autoprefixer": "^9.7.4",
|
||||
"babel-eslint": "^10.0.3",
|
||||
"babel-loader": "^8.0.6",
|
||||
"babel-minify-webpack-plugin": "^0.3.1",
|
||||
"babel-preset-minify": "^0.5.1",
|
||||
"browserslist": "^4.8.5",
|
||||
"cfonts": "^2.4.8",
|
||||
"chalk": "^3.0.0",
|
||||
"changelog-parser": "^2.8.0",
|
||||
"copy-webpack-plugin": "^5.1.1",
|
||||
"core-js": "^3.6.4",
|
||||
"cos-nodejs-sdk-v5": "^2.5.14",
|
||||
"cross-env": "^6.0.3",
|
||||
"css-loader": "^3.4.2",
|
||||
"del": "^5.1.0",
|
||||
"electron": "^7.1.9",
|
||||
"electron-builder": "^22.2.0",
|
||||
"electron-debug": "^3.0.1",
|
||||
"electron-devtools-installer": "^2.2.4",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-standard": "^14.1.0",
|
||||
"eslint-formatter-friendly": "^7.0.0",
|
||||
"eslint-loader": "^3.0.3",
|
||||
"eslint-plugin-html": "^6.0.0",
|
||||
"eslint-plugin-import": "^2.20.0",
|
||||
"eslint-plugin-node": "^11.0.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.1",
|
||||
"file-loader": "^5.0.2",
|
||||
"friendly-errors-webpack-plugin": "^1.7.0",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"less": "^3.10.3",
|
||||
"less-loader": "^5.0.0",
|
||||
"markdown-it": "^10.0.0",
|
||||
"mini-css-extract-plugin": "^0.9.0",
|
||||
"multispinner": "^0.2.1",
|
||||
"optimize-css-assets-webpack-plugin": "^5.0.3",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"pug": "^2.0.4",
|
||||
"pug-loader": "^2.4.0",
|
||||
"pug-plain-loader": "^1.0.0",
|
||||
"raw-loader": "^4.0.0",
|
||||
"rimraf": "^3.0.0",
|
||||
"stylus": "^0.54.7",
|
||||
"stylus-loader": "^3.0.2",
|
||||
"terser-webpack-plugin": "^2.3.2",
|
||||
"url-loader": "^3.0.0",
|
||||
"vue-loader": "^15.8.3",
|
||||
"vue-style-loader": "^4.1.2",
|
||||
"vue-template-compiler": "^2.6.11",
|
||||
"webpack": "^4.41.5",
|
||||
"webpack-cli": "^3.3.10",
|
||||
"webpack-dev-server": "^3.10.1",
|
||||
"webpack-hot-middleware": "^2.25.0",
|
||||
"webpack-merge": "^4.2.2"
|
||||
"@tsconfig/recommended": "^1.0.13",
|
||||
"@types/better-sqlite3": "^7.6.13",
|
||||
"@types/needle": "^3.3.0",
|
||||
"@types/node": "^20.19.43",
|
||||
"@types/tunnel": "^0.0.7",
|
||||
"@types/ws": "8.5.4",
|
||||
"@vue/language-plugin-pug": "^3.3.11",
|
||||
"browserslist": "^4.28.9",
|
||||
"chalk": "^4.1.2",
|
||||
"changelog-parser": "3.0.1",
|
||||
"copy-webpack-plugin": "^14.0.0",
|
||||
"core-js": "^3.50.0",
|
||||
"cross-env": "^10.1.0",
|
||||
"css-loader": "^7.1.5",
|
||||
"css-minimizer-webpack-plugin": "^8.0.0",
|
||||
"del": "^6.1.1",
|
||||
"electron": "42.11.3",
|
||||
"electron-builder": "^26.15.7",
|
||||
"electron-debug": "^3.2.0",
|
||||
"electron-devtools-installer": "github:lyswhut/electron-devtools-installer#64596d615c1fc891eefd8aef1dfcb2c87aaadf03",
|
||||
"electron-to-chromium": "^1.5.427",
|
||||
"electron-updater": "6.8.9",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-standard": "^17.1.0",
|
||||
"eslint-config-standard-with-typescript": "^43.0.1",
|
||||
"eslint-formatter-friendly": "github:lyswhut/eslint-friendly-formatter#2170d1320e2fad13615a9dcf229669f0bb473a53",
|
||||
"eslint-plugin-html": "^8.2.0",
|
||||
"eslint-plugin-vue": "^9.33.0",
|
||||
"eslint-plugin-vue-pug": "^0.6.2",
|
||||
"eslint-webpack-plugin": "^4.2.0",
|
||||
"html-webpack-plugin": "^5.6.8",
|
||||
"less": "^4.9.1",
|
||||
"less-loader": "^13.0.0",
|
||||
"mini-css-extract-plugin": "^2.10.2",
|
||||
"node-loader": "^2.1.0",
|
||||
"postcss": "^8.5.28",
|
||||
"postcss-loader": "^8.2.1",
|
||||
"postcss-pxtorem": "^6.1.0",
|
||||
"pug": "^3.0.4",
|
||||
"pug-plain-loader": "^1.1.0",
|
||||
"rimraf": "^6.1.3",
|
||||
"spinnies": "github:lyswhut/spinnies#233305c58694aa3b053e3ab9af9049993f918b9d",
|
||||
"svg-sprite-loader": "^6.0.11",
|
||||
"svg-transform-loader": "^2.0.13",
|
||||
"svgo-loader": "^5.0.0",
|
||||
"terser": "^5.51.2",
|
||||
"terser-webpack-plugin": "^5.6.1",
|
||||
"tree-kill": "^1.2.2",
|
||||
"ts-loader": "^9.6.2",
|
||||
"typescript": "5.9.3",
|
||||
"vue-eslint-parser": "^9.4.3",
|
||||
"vue-loader": "^17.4.2",
|
||||
"webpack": "5.106.2",
|
||||
"webpack-cli": "^7.2.3",
|
||||
"webpack-dev-server": "5.2.6",
|
||||
"webpack-hot-middleware": "github:lyswhut/webpack-hot-middleware#329c4375134b89d39da23a56a94db651247c74a1",
|
||||
"webpack-merge": "^6.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"crypto-js": "^3.1.9-1",
|
||||
"dnscache": "^1.0.2",
|
||||
"electron-log": "^4.0.3",
|
||||
"electron-store": "^5.1.0",
|
||||
"electron-updater": "^4.2.0",
|
||||
"flac-metadata": "^0.1.1",
|
||||
"js-htmlencode": "^0.3.0",
|
||||
"lrc-file-parser": "^1.0.0",
|
||||
"node-id3": "^0.1.13",
|
||||
"request": "^2.88.0",
|
||||
"vue": "^2.6.11",
|
||||
"vue-electron": "^1.0.6",
|
||||
"vue-router": "^3.1.5",
|
||||
"vuex": "^3.1.2",
|
||||
"vuex-electron": "^1.0.3",
|
||||
"vuex-router-sync": "^5.0.0"
|
||||
"@simonwep/pickr": "1.9.1",
|
||||
"better-sqlite3": "^13.0.3",
|
||||
"bufferutil": "^4.1.0",
|
||||
"comlink": "~4.3.1",
|
||||
"crypto-js": "^4.2.0",
|
||||
"electron-log": "^5.4.4",
|
||||
"font-list": "^2.1.0",
|
||||
"iconv-lite": "^0.7.3",
|
||||
"image-size": "^1.1.0",
|
||||
"jschardet": "^3.1.4",
|
||||
"long": "^5.3.2",
|
||||
"message2call": "^0.1.3",
|
||||
"music-metadata": "^11.15.0",
|
||||
"needle": "github:lyswhut/needle#93299ac841b7e9a9f82ca7279b88aaaeda404060",
|
||||
"node-id3": "^0.2.9",
|
||||
"sortablejs": "^1.15.7",
|
||||
"tunnel": "^0.0.6",
|
||||
"undici": "^7.29.1",
|
||||
"utf-8-validate": "^6.0.6",
|
||||
"vue": "~3.3.13",
|
||||
"vue-router": "~4.5.1",
|
||||
"ws": "^8.21.3"
|
||||
},
|
||||
"overrides": {
|
||||
"got": "^11",
|
||||
"json5": "latest",
|
||||
"node-abi": "latest",
|
||||
"minimatch": "latest",
|
||||
"semver": "latest",
|
||||
"posthtml": "latest",
|
||||
"node-gyp": "latest",
|
||||
"sockjs": {
|
||||
"uuid": "^12"
|
||||
},
|
||||
"svg-transform-loader": {
|
||||
"postcss": "^8"
|
||||
},
|
||||
"svg-sprite-loader": {
|
||||
"postcss": "^8"
|
||||
},
|
||||
"svg-baker": {
|
||||
"postcss": "^8"
|
||||
},
|
||||
"braces": "latest",
|
||||
"node-gyp-build": "latest",
|
||||
"micromatch": "latest",
|
||||
"http-cache-semantics": "latest"
|
||||
},
|
||||
"allowScripts": {
|
||||
"bufferutil": false,
|
||||
"core-js": false,
|
||||
"electron-winstaller": false,
|
||||
"utf-8-validate": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,28 @@
|
||||
const autoprefixer = require('autoprefixer')
|
||||
// const autoprefixer = require('autoprefixer')
|
||||
const pxtorem = require('postcss-pxtorem')
|
||||
|
||||
module.exports = {
|
||||
plugins: [
|
||||
autoprefixer(),
|
||||
pxtorem({
|
||||
rootValue: 16,
|
||||
unitPrecision: 5,
|
||||
propList: [
|
||||
'font', 'font-size',
|
||||
'letter-spacing',
|
||||
'padding', 'margin',
|
||||
'padding-*', 'margin-*',
|
||||
'height', 'width',
|
||||
'*-height', '*-width',
|
||||
'flex', '::-webkit-scrollbar',
|
||||
'top', 'left', 'bottom', 'right',
|
||||
'border-radius', 'gap',
|
||||
],
|
||||
selectorBlackList: ['html', 'ignore-to-rem'],
|
||||
replace: true,
|
||||
mediaQuery: false,
|
||||
minPixelValue: 0,
|
||||
exclude: [/node_modules/i],
|
||||
}),
|
||||
// autoprefixer(),
|
||||
],
|
||||
}
|
||||
|
||||
@@ -1,26 +1,15 @@
|
||||
洛雪提前祝大家新年快乐、身体健康、阖家幸福!
|
||||
|
||||
### 新增
|
||||
|
||||
- 新增各大平台歌单热门标签显示(显示在歌单界面的第一个下拉标签菜单中)
|
||||
- 恢复QQ音乐源128k音质试听
|
||||
- 新增不强制win7开启透明效果即可使用,但要配置运行参数`-nt`,例如:`.\lx-music-desktop.exe -nt`,添加方法可自行百度“给快捷方式加参数”
|
||||
- 新增“新年快乐”主题,可自行切换体验
|
||||
目前新项目 Any Listen 的桌面版、Web 版已实现 LX Music 的大部分功能,并额外支持 WebDAV 歌曲播放、WebDAV 数据同步、独立播放列表等功能。
|
||||
以后的开发精力将主要集中在新项目上,之前大家在 LX Music 提的功能我们也会考虑在新项目中添加。
|
||||
对于日常使用 LX Music 的人可以试试迁移到 Any Listen,若遇到任何问题可以发 issue 反馈。
|
||||
Any Listen 的项目地址为 https://github.com/any-listen/any-listen
|
||||
|
||||
### 优化
|
||||
|
||||
- 减淡各个主题的歌曲列表分隔线颜色
|
||||
- 在线音乐列表音质标签优化,当歌曲有无损音质时隐藏高品质标签
|
||||
- 更新改进的歌词播放插件,现在歌词的播放显示将更准确
|
||||
- 优化 tx 推荐歌单列表
|
||||
- 优化禁用透明窗口的窗口边框显示效果
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复咪咕源无法搜索的问题
|
||||
- 修复更新弹窗底部文字颜色没有适配当前主题颜色的问题
|
||||
- 修复导入设置窗口大小、代理设置不立即生效的问题
|
||||
- 修复在线音乐列表获取失败时无限循环请求的问题
|
||||
|
||||
### 其他
|
||||
|
||||
- 将软件设置与播放列表分离存储成两个文件
|
||||
- 更新 Electron 到 7.1.9
|
||||
- 修复打开某些 kg 歌单时歌曲丢失的问题
|
||||
- 修复 Windows 7 无法启动的问题
|
||||
- 修复禁用透明窗口时按 F11 无法全屏的问题
|
||||
|
||||
@@ -34,7 +34,7 @@ function fm(value) {
|
||||
exports.sizeFormate = size => {
|
||||
// https://gist.github.com/thomseddon/3511330
|
||||
if (!size) return '0 b'
|
||||
let units = ['b', 'kB', 'MB', 'GB', 'TB']
|
||||
let units = ['B', 'KiB', 'MiB', 'GiB', 'TiB']
|
||||
let number = Math.floor(Math.log(size) / Math.log(1024))
|
||||
return `${(size / Math.pow(1024, Math.floor(number))).toFixed(2)} ${units[number]}`
|
||||
}
|
||||
|
||||
40
publish/utils/parseChangelog.js
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
*
|
||||
* @param {string} text
|
||||
* @returns
|
||||
*/
|
||||
export const parseChangelog = async(text) => {
|
||||
const versions = []
|
||||
const lines = text.split(/\r\n|\r|\n/)
|
||||
let currentVersion = null
|
||||
let currentDate = null
|
||||
let currentDesc = ''
|
||||
|
||||
for (const line of lines) {
|
||||
const versionMatch = line.match(/^\s*##\s+\[?(\d+\.\d+\.\d+)\]?.*?-\s+(\d{4}-\d{2}-\d{2})$/)
|
||||
if (versionMatch) {
|
||||
if (currentVersion) {
|
||||
versions.push({
|
||||
version: currentVersion,
|
||||
date: currentDate,
|
||||
desc: currentDesc.trim(),
|
||||
})
|
||||
}
|
||||
currentVersion = versionMatch[1]
|
||||
currentDate = versionMatch[3]
|
||||
currentDesc = ''
|
||||
} else {
|
||||
currentDesc += `${line}\n`
|
||||
}
|
||||
}
|
||||
|
||||
if (currentVersion) {
|
||||
versions.push({
|
||||
version: currentVersion,
|
||||
date: currentDate,
|
||||
desc: currentDesc.trim(),
|
||||
})
|
||||
}
|
||||
|
||||
return versions
|
||||
}
|
||||
@@ -6,50 +6,46 @@ const version = require('../version.json')
|
||||
const chalk = require('chalk')
|
||||
const pkg_bak = JSON.stringify(pkg, null, 2)
|
||||
const version_bak = JSON.stringify(version, null, 2)
|
||||
const parseChangelog = require('changelog-parser')
|
||||
const changelogPath = jp('../../CHANGELOG.md')
|
||||
const { parseChangelog } = require('./parseChangelog')
|
||||
|
||||
const md_renderer = markdownStr => new (require('markdown-it'))({
|
||||
html: true,
|
||||
linkify: true,
|
||||
typographer: true,
|
||||
breaks: true,
|
||||
}).render(markdownStr)
|
||||
// const md_renderer = markdownStr => new (require('markdown-it'))({
|
||||
// html: true,
|
||||
// linkify: true,
|
||||
// typographer: true,
|
||||
// breaks: true,
|
||||
// }).render(markdownStr)
|
||||
|
||||
const getPrevVer = () => parseChangelog(changelogPath).then(res => {
|
||||
if (!res.versions.length) throw new Error('CHANGELOG 无法解析到版本号')
|
||||
return res.versions[0].version
|
||||
const getPrevVer = () => parseChangelog(fs.readFileSync(changelogPath, 'utf-8').toString()).then(versions => {
|
||||
if (!versions.length) throw new Error('CHANGELOG 无法解析到版本号')
|
||||
return versions[0].version
|
||||
})
|
||||
|
||||
const updateChangeLog = async(newVerNum, newChangeLog) => {
|
||||
let changeLog = fs.readFileSync(changelogPath, 'utf-8')
|
||||
const prevVer = await getPrevVer()
|
||||
const log = `## [${newVerNum}](${pkg.repository.url.replace(/^git\+(http.+)\.git$/, '$1')}/compare/v${prevVer}...v${newVerNum}) - ${formatTime()}\n\n${newChangeLog}`
|
||||
fs.writeFileSync(changelogPath, changeLog.replace(new RegExp(`(## [?0.1.1]?)`), log + '\n$1'), 'utf-8')
|
||||
fs.writeFileSync(changelogPath, changeLog.replace(/(## \[(?:\d+\.))/, log + '\n$1'), 'utf-8')
|
||||
}
|
||||
|
||||
const renderChangeLog = md => md_renderer(md)
|
||||
// const renderChangeLog = md => md_renderer(md)
|
||||
|
||||
|
||||
module.exports = async newVerNum => {
|
||||
if (!newVerNum) {
|
||||
let verArr = pkg.version.split('.')
|
||||
verArr[verArr.length - 1] = parseInt(verArr[verArr.length - 1]) + 1
|
||||
newVerNum = verArr.join('.')
|
||||
}
|
||||
if (!newVerNum) newVerNum = pkg.version
|
||||
const newMDChangeLog = fs.readFileSync(jp('../changeLog.md'), 'utf-8')
|
||||
const newChangeLog = renderChangeLog(newMDChangeLog)
|
||||
// const newChangeLog = renderChangeLog(newMDChangeLog)
|
||||
version.history.unshift({
|
||||
version: version.version,
|
||||
desc: version.desc,
|
||||
})
|
||||
version.version = newVerNum
|
||||
version.desc = newChangeLog
|
||||
version.desc = newMDChangeLog.replace(/(?:^|(\n))#{1,6} (.+)\n/g, '$1$2').trim()
|
||||
pkg.version = newVerNum
|
||||
|
||||
console.log(chalk.blue('new version: ') + chalk.green(newVerNum))
|
||||
|
||||
fs.writeFileSync(jp('../version.json'), JSON.stringify(version, null, 2) + '\n', 'utf-8')
|
||||
fs.writeFileSync(jp('../version.json'), JSON.stringify(version) + '\n', 'utf-8')
|
||||
|
||||
fs.writeFileSync(jp(pkgDir), JSON.stringify(pkg, null, 2) + '\n', 'utf-8')
|
||||
|
||||
@@ -58,7 +54,7 @@ module.exports = async newVerNum => {
|
||||
return {
|
||||
pkg_bak,
|
||||
version_bak,
|
||||
changeLog: newChangeLog,
|
||||
// changeLog: newChangeLog,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BIN
resources/icons/128x128.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
resources/icons/16x16.png
Normal file
|
After Width: | Height: | Size: 488 B |
|
Before Width: | Height: | Size: 7.4 KiB |
BIN
resources/icons/256x256.png
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
BIN
resources/icons/32x32.png
Normal file
|
After Width: | Height: | Size: 901 B |
BIN
resources/icons/48x48.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 17 KiB |
BIN
resources/icons/64x64.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
resources/icons/icon.icns
Normal file
BIN
resources/icons/icon.ico
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
resources/icons/icon.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
15
src/common/.eslintrc.cjs
Normal file
@@ -0,0 +1,15 @@
|
||||
/* eslint-env node */
|
||||
const { base, typescript } = require('../../.eslintrc.base.cjs')
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
...base,
|
||||
overrides: [
|
||||
{
|
||||
...typescript,
|
||||
parserOptions: {
|
||||
project: './tsconfig.json',
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
module.exports = {
|
||||
windowSizeList: [
|
||||
{
|
||||
id: 1,
|
||||
name: '小',
|
||||
width: 920,
|
||||
height: 590,
|
||||
tabList: '645px',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '中',
|
||||
width: 1012,
|
||||
height: 650,
|
||||
tabList: '719px',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '大',
|
||||
width: 1104,
|
||||
height: 708,
|
||||
tabList: '792px',
|
||||
},
|
||||
],
|
||||
}
|
||||
86
src/common/config.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
export interface WindowSize {
|
||||
id: number
|
||||
name: string
|
||||
width: number
|
||||
height: number
|
||||
}
|
||||
|
||||
export const windowSizeList: WindowSize[] = [
|
||||
{
|
||||
id: 0,
|
||||
name: 'smaller',
|
||||
width: 828,
|
||||
height: 540,
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
name: 'small',
|
||||
width: 920,
|
||||
height: 600,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'medium',
|
||||
width: 1020,
|
||||
height: 660,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: 'big',
|
||||
width: 1114,
|
||||
height: 718,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: 'larger',
|
||||
width: 1202,
|
||||
height: 776,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: 'oversized',
|
||||
width: 1385,
|
||||
height: 896,
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: 'huge',
|
||||
width: 1700,
|
||||
height: 1070,
|
||||
},
|
||||
]
|
||||
|
||||
export const navigationUrlWhiteList: RegExp[] = []
|
||||
|
||||
// 基础黑白色
|
||||
// export const commonColorNames = [
|
||||
// '--color-000', '--color-050', '--color-100', '--color-200', '--color-300', '--color-400',
|
||||
// '--color-500', '--color-600', '--color-700', '--color-800', '--color-900',
|
||||
// ] as const
|
||||
// export const commonLightColorValues = [
|
||||
// 'rgb(255, 255, 255)',
|
||||
// 'rgb(217,217,217)',
|
||||
// 'rgb(184,184,184)',
|
||||
// 'rgb(156,156,156)',
|
||||
// 'rgb(133,133,133)',
|
||||
// 'rgb(113,113,113)',
|
||||
// 'rgb(96,96,96)',
|
||||
// 'rgb(82,82,82)',
|
||||
// 'rgb(70,70,70)',
|
||||
// 'rgb(60,60,60)',
|
||||
// 'rgb(51,51,51)',
|
||||
// ] as const
|
||||
// export const commonDarkColorValues = [
|
||||
// 'rgb(11, 11, 11)',
|
||||
// 'rgb(60,60,60)',
|
||||
// 'rgb(99,99,99)',
|
||||
// 'rgb(130,130,130)',
|
||||
// 'rgb(155,155,155)',
|
||||
// 'rgb(175,175,175)',
|
||||
// 'rgb(191,191,191)',
|
||||
// 'rgb(204,204,204)',
|
||||
// 'rgb(214,214,214)',
|
||||
// 'rgb(222,222,222)',
|
||||
// 'rgb(229,229,229)',
|
||||
// ] as const
|
||||
|
||||
84
src/common/constants.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
export const URL_SCHEME_RXP = /^lxmusic:\/\//
|
||||
|
||||
export const SPLIT_CHAR = {
|
||||
DISLIKE_NAME: '@',
|
||||
DISLIKE_NAME_ALIAS: '#',
|
||||
} as const
|
||||
|
||||
export const STORE_NAMES = {
|
||||
APP_SETTINGS: 'config_v2',
|
||||
DATA: 'data',
|
||||
SYNC: 'sync',
|
||||
HOTKEY: 'hot_key',
|
||||
USER_API: 'user_api',
|
||||
LRC_RAW: 'lyrics',
|
||||
LRC_EDITED: 'lyrics_edited',
|
||||
THEME: 'theme',
|
||||
SOUND_EFFECT: 'sound_effect',
|
||||
} as const
|
||||
|
||||
export const APP_EVENT_NAMES = {
|
||||
winMainName: 'win_main',
|
||||
winLyricName: 'win_lyric',
|
||||
trayName: 'tray',
|
||||
} as const
|
||||
|
||||
export const LIST_IDS = {
|
||||
DEFAULT: 'default',
|
||||
LOVE: 'love',
|
||||
TEMP: 'temp',
|
||||
DOWNLOAD: 'download',
|
||||
PLAY_LATER: null,
|
||||
} as const
|
||||
|
||||
export const DATA_KEYS = {
|
||||
viewPrevState: 'viewPrevState',
|
||||
playInfo: 'playInfo',
|
||||
searchHistoryList: 'searchHistoryList',
|
||||
listScrollPosition: 'listScrollPosition',
|
||||
listPrevSelectId: 'listPrevSelectId',
|
||||
listUpdateInfo: 'listUpdateInfo',
|
||||
ignoreVersion: 'ignoreVersion',
|
||||
|
||||
leaderboardSetting: 'leaderboardSetting',
|
||||
songListSetting: 'songListSetting',
|
||||
searchSetting: 'searchSetting',
|
||||
|
||||
lastStartInfo: 'lastStartInfo',
|
||||
} as const
|
||||
|
||||
export const DEFAULT_SETTING = {
|
||||
leaderboard: {
|
||||
source: 'kw',
|
||||
boardId: 'kw__16',
|
||||
},
|
||||
|
||||
songList: {
|
||||
source: 'kw',
|
||||
sortId: 'new',
|
||||
tagId: '',
|
||||
},
|
||||
|
||||
search: {
|
||||
temp_source: 'kw',
|
||||
source: 'all',
|
||||
type: 'music',
|
||||
},
|
||||
|
||||
viewPrevState: {
|
||||
url: '/search',
|
||||
query: {},
|
||||
},
|
||||
}
|
||||
|
||||
export const DOWNLOAD_STATUS = {
|
||||
RUN: 'run',
|
||||
WAITING: 'waiting',
|
||||
PAUSE: 'pause',
|
||||
ERROR: 'error',
|
||||
COMPLETED: 'completed',
|
||||
} as const
|
||||
|
||||
export const QUALITYS = ['flac24bit', 'flac', 'wav', 'ape', '320k', '192k', '128k'] as const
|
||||
|
||||
export const TRAY_AUTO_ID = -1
|
||||
74
src/common/constants_sync.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
export const ENV_PARAMS = [
|
||||
'PORT',
|
||||
'BIND_IP',
|
||||
'CONFIG_PATH',
|
||||
'LOG_PATH',
|
||||
'DATA_PATH',
|
||||
'PROXY_HEADER',
|
||||
'MAX_SNAPSHOT_NUM',
|
||||
'LIST_ADD_MUSIC_LOCATION_TYPE',
|
||||
'LX_USER_',
|
||||
] as const
|
||||
|
||||
|
||||
export const LIST_IDS = {
|
||||
DEFAULT: 'default',
|
||||
LOVE: 'love',
|
||||
TEMP: 'temp',
|
||||
DOWNLOAD: 'download',
|
||||
PLAY_LATER: null,
|
||||
} as const
|
||||
|
||||
export const SYNC_CODE = {
|
||||
helloMsg: 'Hello~::^-^::~v4~',
|
||||
idPrefix: 'OjppZDo6',
|
||||
authMsg: 'lx-music auth::',
|
||||
msgAuthFailed: 'Auth failed',
|
||||
msgBlockedIp: 'Blocked IP',
|
||||
msgConnect: 'lx-music connect',
|
||||
|
||||
|
||||
authFailed: 'Auth failed',
|
||||
missingAuthCode: 'Missing auth code',
|
||||
getServiceIdFailed: 'Get service id failed',
|
||||
connectServiceFailed: 'Connect service failed',
|
||||
connecting: 'Connecting...',
|
||||
unknownServiceAddress: 'Unknown service address',
|
||||
} as const
|
||||
|
||||
export const SYNC_CLOSE_CODE = {
|
||||
normal: 1000,
|
||||
failed: 4100,
|
||||
} as const
|
||||
|
||||
export const TRANS_MODE: Readonly<Record<LX.Sync.List.SyncMode, LX.Sync.List.SyncMode>> = {
|
||||
merge_local_remote: 'merge_remote_local',
|
||||
merge_remote_local: 'merge_local_remote',
|
||||
overwrite_local_remote: 'overwrite_remote_local',
|
||||
overwrite_remote_local: 'overwrite_local_remote',
|
||||
overwrite_local_remote_full: 'overwrite_remote_local_full',
|
||||
overwrite_remote_local_full: 'overwrite_local_remote_full',
|
||||
cancel: 'cancel',
|
||||
} as const
|
||||
|
||||
export const File = {
|
||||
serverDataPath: 'sync/server',
|
||||
clientDataPath: 'sync/client',
|
||||
|
||||
serverInfoJSON: 'serverInfo.json',
|
||||
userDir: 'users',
|
||||
userDevicesJSON: 'devices.json',
|
||||
listDir: 'list',
|
||||
listSnapshotDir: 'snapshot',
|
||||
listSnapshotInfoJSON: 'snapshotInfo.json',
|
||||
dislikeDir: 'dislike',
|
||||
dislikeSnapshotDir: 'snapshot',
|
||||
dislikeSnapshotInfoJSON: 'snapshotInfo.json',
|
||||
|
||||
syncAuthKeysJSON: 'syncAuthKey.json',
|
||||
} as const
|
||||
|
||||
export const FeaturesList = [
|
||||
'list',
|
||||
'dislike',
|
||||
] as const
|
||||
93
src/common/defaultHotKey.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import { HOTKEY_PLAYER, HOTKEY_COMMON, HOTKEY_DESKTOP_LYRIC } from './hotKey'
|
||||
|
||||
const local: LX.HotKeyConfig = {
|
||||
enable: true,
|
||||
keys: {
|
||||
'mod+f5': {
|
||||
type: HOTKEY_PLAYER.toggle_play.type,
|
||||
name: HOTKEY_PLAYER.toggle_play.name,
|
||||
action: HOTKEY_PLAYER.toggle_play.action,
|
||||
},
|
||||
'mod+arrowleft': {
|
||||
type: HOTKEY_PLAYER.prev.type,
|
||||
name: HOTKEY_PLAYER.prev.name,
|
||||
action: HOTKEY_PLAYER.prev.action,
|
||||
},
|
||||
'mod+arrowright': {
|
||||
type: HOTKEY_PLAYER.next.type,
|
||||
name: HOTKEY_PLAYER.next.name,
|
||||
action: HOTKEY_PLAYER.next.action,
|
||||
},
|
||||
f1: {
|
||||
type: HOTKEY_COMMON.focusSearchInput.type,
|
||||
name: HOTKEY_COMMON.focusSearchInput.name,
|
||||
action: HOTKEY_COMMON.focusSearchInput.action,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const global: LX.HotKeyConfig = {
|
||||
enable: false,
|
||||
keys: {
|
||||
// MediaPlayPause: {
|
||||
// type: HOTKEY_PLAYER.toggle_play.type,
|
||||
// name: '',
|
||||
// action: HOTKEY_PLAYER.toggle_play.action,
|
||||
// },
|
||||
// MediaPreviousTrack: {
|
||||
// type: HOTKEY_PLAYER.prev.type,
|
||||
// name: '',
|
||||
// action: HOTKEY_PLAYER.prev.action,
|
||||
// },
|
||||
// MediaNextTrack: {
|
||||
// type: HOTKEY_PLAYER.next.type,
|
||||
// name: '',
|
||||
// action: HOTKEY_PLAYER.next.action,
|
||||
// },
|
||||
'mod+alt+f5': {
|
||||
type: HOTKEY_PLAYER.toggle_play.type,
|
||||
name: HOTKEY_PLAYER.toggle_play.name,
|
||||
action: HOTKEY_PLAYER.toggle_play.action,
|
||||
},
|
||||
'mod+alt+arrowleft': {
|
||||
type: HOTKEY_PLAYER.prev.type,
|
||||
name: HOTKEY_PLAYER.prev.name,
|
||||
action: HOTKEY_PLAYER.prev.action,
|
||||
},
|
||||
'mod+alt+arrowright': {
|
||||
type: HOTKEY_PLAYER.next.type,
|
||||
name: HOTKEY_PLAYER.next.name,
|
||||
action: HOTKEY_PLAYER.next.action,
|
||||
},
|
||||
'mod+alt+arrowup': {
|
||||
type: HOTKEY_PLAYER.volume_up.type,
|
||||
name: HOTKEY_PLAYER.volume_up.name,
|
||||
action: HOTKEY_PLAYER.volume_up.action,
|
||||
},
|
||||
'mod+alt+arrowdown': {
|
||||
type: HOTKEY_PLAYER.volume_down.type,
|
||||
name: HOTKEY_PLAYER.volume_down.name,
|
||||
action: HOTKEY_PLAYER.volume_down.action,
|
||||
},
|
||||
'mod+alt+0': {
|
||||
type: HOTKEY_DESKTOP_LYRIC.toggle_visible.type,
|
||||
name: HOTKEY_DESKTOP_LYRIC.toggle_visible.name,
|
||||
action: HOTKEY_DESKTOP_LYRIC.toggle_visible.action,
|
||||
},
|
||||
'mod+alt+-': {
|
||||
type: HOTKEY_DESKTOP_LYRIC.toggle_lock.type,
|
||||
name: HOTKEY_DESKTOP_LYRIC.toggle_lock.name,
|
||||
action: HOTKEY_DESKTOP_LYRIC.toggle_lock.action,
|
||||
},
|
||||
'mod+alt+=': {
|
||||
type: HOTKEY_DESKTOP_LYRIC.toggle_always_top.type,
|
||||
name: HOTKEY_DESKTOP_LYRIC.toggle_always_top.name,
|
||||
action: HOTKEY_DESKTOP_LYRIC.toggle_always_top.action,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export default {
|
||||
local,
|
||||
global,
|
||||
}
|
||||
171
src/common/defaultSetting.ts
Normal file
@@ -0,0 +1,171 @@
|
||||
import path from 'node:path'
|
||||
import os from 'node:os'
|
||||
|
||||
const isMac = process.platform == 'darwin'
|
||||
const isWin = process.platform == 'win32'
|
||||
|
||||
const defaultSetting: LX.AppSetting = {
|
||||
version: '2.1.0',
|
||||
|
||||
'common.windowSizeId': 3,
|
||||
'common.fontSize': 16,
|
||||
'common.startInFullscreen': false,
|
||||
'common.langId': null,
|
||||
'common.apiSource': 'temp',
|
||||
'common.sourceNameType': 'alias',
|
||||
'common.font': '',
|
||||
'common.isShowAnimation': true,
|
||||
'common.randomAnimate': true,
|
||||
'common.isAgreePact': false,
|
||||
'common.controlBtnPosition': isMac ? 'left' : 'right',
|
||||
'common.playBarProgressStyle': 'mini',
|
||||
'common.transparentWindow': !isMac,
|
||||
'common.tryAutoUpdate': true,
|
||||
'common.showChangeLog': true,
|
||||
|
||||
'player.startupAutoPlay': false,
|
||||
'player.togglePlayMethod': 'listLoop',
|
||||
'player.playQuality': '128k',
|
||||
'player.isShowTaskProgess': true,
|
||||
'player.isShowStatusBarLyric': false,
|
||||
'player.volume': 1,
|
||||
'player.powerSaveBlocker': true,
|
||||
'player.isMute': false,
|
||||
'player.playbackRate': 1,
|
||||
'player.preservesPitch': true,
|
||||
'player.isMaxOutputChannelCount': false,
|
||||
'player.mediaDeviceId': 'default',
|
||||
'player.isMediaDeviceRemovedStopPlay': false,
|
||||
'player.isShowLyricTranslation': false,
|
||||
'player.isShowLyricRoma': false,
|
||||
'player.isSwapLyricTranslationAndRoma': false,
|
||||
'player.isS2t': false,
|
||||
'player.isPlayLxlrc': !isMac,
|
||||
'player.isSavePlayTime': false,
|
||||
'player.audioVisualization': false,
|
||||
'player.waitPlayEndStop': true,
|
||||
'player.waitPlayEndStopTime': '',
|
||||
'player.autoSkipOnError': true,
|
||||
'player.isAutoCleanPlayedList': false,
|
||||
'player.soundEffect.convolution.fileName': '',
|
||||
'player.soundEffect.convolution.mainGain': 10,
|
||||
'player.soundEffect.convolution.sendGain': 0,
|
||||
'player.soundEffect.biquadFilter.hz31': 0,
|
||||
'player.soundEffect.biquadFilter.hz62': 0,
|
||||
'player.soundEffect.biquadFilter.hz125': 0,
|
||||
'player.soundEffect.biquadFilter.hz250': 0,
|
||||
'player.soundEffect.biquadFilter.hz500': 0,
|
||||
'player.soundEffect.biquadFilter.hz1000': 0,
|
||||
'player.soundEffect.biquadFilter.hz2000': 0,
|
||||
'player.soundEffect.biquadFilter.hz4000': 0,
|
||||
'player.soundEffect.biquadFilter.hz8000': 0,
|
||||
'player.soundEffect.biquadFilter.hz16000': 0,
|
||||
'player.soundEffect.panner.enable': false,
|
||||
'player.soundEffect.panner.soundR': 5,
|
||||
'player.soundEffect.panner.speed': 25,
|
||||
'player.soundEffect.pitchShifter.playbackRate': 1,
|
||||
|
||||
'playDetail.isZoomActiveLrc': false,
|
||||
'playDetail.isShowLyricProgressSetting': false,
|
||||
'playDetail.style.fontSize': 140,
|
||||
'playDetail.style.align': 'center',
|
||||
'playDetail.isDelayScroll': true,
|
||||
|
||||
'desktopLyric.enable': false,
|
||||
'desktopLyric.isLock': false,
|
||||
'desktopLyric.isAlwaysOnTop': false,
|
||||
'desktopLyric.isAlwaysOnTopLoop': false,
|
||||
'desktopLyric.isShowTaskbar': false,
|
||||
'desktopLyric.audioVisualization': false,
|
||||
'desktopLyric.fullscreenHide': true,
|
||||
'desktopLyric.pauseHide': true,
|
||||
'desktopLyric.width': 450,
|
||||
'desktopLyric.height': 300,
|
||||
'desktopLyric.x': null,
|
||||
'desktopLyric.y': null,
|
||||
'desktopLyric.isLockScreen': isWin,
|
||||
'desktopLyric.isDelayScroll': true,
|
||||
'desktopLyric.scrollAlign': 'center',
|
||||
'desktopLyric.isHoverHide': false,
|
||||
'desktopLyric.direction': 'horizontal',
|
||||
'desktopLyric.style.align': 'center',
|
||||
'desktopLyric.style.font': '',
|
||||
'desktopLyric.style.fontSize': 20,
|
||||
'desktopLyric.style.lineGap': 15,
|
||||
'desktopLyric.style.lyricUnplayColor': 'rgba(255, 255, 255, 1)',
|
||||
'desktopLyric.style.lyricPlayedColor': 'rgba(7, 197, 86, 1)',
|
||||
'desktopLyric.style.lyricShadowColor': 'rgba(0, 0, 0, 0.18)',
|
||||
// 'desktopLyric.style.fontWeight': false,
|
||||
'desktopLyric.style.opacity': 95,
|
||||
'desktopLyric.style.ellipsis': false,
|
||||
'desktopLyric.style.isZoomActiveLrc': false,
|
||||
'desktopLyric.style.isFontWeightFont': true,
|
||||
'desktopLyric.style.isFontWeightLine': true,
|
||||
'desktopLyric.style.isFontWeightExtended': true,
|
||||
|
||||
'list.isClickPlayList': false,
|
||||
'list.isShowSource': true,
|
||||
'list.isSaveScrollLocation': true,
|
||||
'list.addMusicLocationType': 'top',
|
||||
'list.actionButtonsVisible': false,
|
||||
|
||||
'download.enable': false,
|
||||
'download.isSavePathGroupByListName': false,
|
||||
'download.savePath': path.join(os.homedir(), 'Desktop'),
|
||||
'download.fileName': '歌名 - 歌手',
|
||||
'download.maxDownloadNum': 3,
|
||||
'download.skipExistFile': true,
|
||||
'download.isDownloadLrc': false,
|
||||
'download.isDownloadLxLrc': true,
|
||||
'download.isDownloadTLrc': false,
|
||||
'download.isDownloadRLrc': false,
|
||||
'download.lrcFormat': 'utf8',
|
||||
'download.isEmbedPic': true,
|
||||
'download.isEmbedLyric': false,
|
||||
'download.isEmbedLyricLx': true,
|
||||
'download.isEmbedLyricT': false,
|
||||
'download.isEmbedLyricR': false,
|
||||
'download.isUseOtherSource': false,
|
||||
|
||||
'search.isShowHotSearch': false,
|
||||
'search.isShowHistorySearch': false,
|
||||
'search.isFocusSearchBox': false,
|
||||
|
||||
'network.proxy.enable': false,
|
||||
'network.proxy.host': '',
|
||||
'network.proxy.port': '',
|
||||
|
||||
'tray.enable': false,
|
||||
// 'tray.isToTray': false,
|
||||
'tray.themeId': 0,
|
||||
|
||||
'sync.mode': 'server',
|
||||
'sync.enable': false,
|
||||
'sync.server.port': '23332',
|
||||
'sync.server.maxSsnapshotNum': 5,
|
||||
'sync.client.host': '',
|
||||
|
||||
'openAPI.enable': false,
|
||||
'openAPI.port': '23330',
|
||||
'openAPI.bindLan': false,
|
||||
|
||||
// 'theme.id': 'blue_plus',
|
||||
'theme.id': 'green',
|
||||
'theme.lightId': 'green',
|
||||
'theme.darkId': 'black',
|
||||
|
||||
'odc.isAutoClearSearchInput': false,
|
||||
'odc.isAutoClearSearchList': false,
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 使用新年皮肤
|
||||
if (new Date().getMonth() < 2) {
|
||||
defaultSetting['theme.id'] = 'happy_new_year'
|
||||
defaultSetting['desktopLyric.style.lyricPlayedColor'] = 'rgba(255, 57, 71, 1)'
|
||||
}
|
||||
|
||||
|
||||
export default defaultSetting
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
const { log } = require('./utils')
|
||||
import { log } from './utils'
|
||||
|
||||
process.on('uncaughtException', function(err) {
|
||||
const ignoreErrorMessage = [
|
||||
'Possible side-effect in debug-evaluate',
|
||||
'Unexpected end of input',
|
||||
]
|
||||
|
||||
process.on('uncaughtException', err => {
|
||||
if (ignoreErrorMessage.includes(err?.message)) return
|
||||
console.error('An uncaught error occurred!')
|
||||
console.error(err)
|
||||
log.error(err)
|
||||
126
src/common/hotKey.ts
Normal file
@@ -0,0 +1,126 @@
|
||||
import { APP_EVENT_NAMES } from './constants'
|
||||
|
||||
|
||||
const keyName = {
|
||||
common: APP_EVENT_NAMES.winMainName,
|
||||
player: APP_EVENT_NAMES.winMainName,
|
||||
desktop_lyric: APP_EVENT_NAMES.winLyricName,
|
||||
}
|
||||
|
||||
const hotKey = {
|
||||
common: {
|
||||
min: {
|
||||
name: 'min',
|
||||
action: 'min',
|
||||
type: '',
|
||||
},
|
||||
min_toggle: {
|
||||
name: 'toggle_min',
|
||||
action: 'toggle_min',
|
||||
type: '',
|
||||
},
|
||||
hide_toggle: {
|
||||
name: 'toggle_hide',
|
||||
action: 'toggle_hide',
|
||||
type: '',
|
||||
},
|
||||
close: {
|
||||
name: 'toggle_close',
|
||||
action: 'toggle_close',
|
||||
type: '',
|
||||
},
|
||||
focusSearchInput: {
|
||||
name: 'focus_search_input',
|
||||
action: 'focus_search_input',
|
||||
type: '',
|
||||
},
|
||||
},
|
||||
player: {
|
||||
toggle_play: {
|
||||
name: 'toggle_play',
|
||||
action: 'toggle_play',
|
||||
type: '',
|
||||
},
|
||||
next: {
|
||||
name: 'next',
|
||||
action: 'next',
|
||||
type: '',
|
||||
},
|
||||
prev: {
|
||||
name: 'prev',
|
||||
action: 'prev',
|
||||
type: '',
|
||||
},
|
||||
seekbackward: {
|
||||
name: 'seekbackward',
|
||||
action: 'seekbackward',
|
||||
type: '',
|
||||
},
|
||||
seekforward: {
|
||||
name: 'seekforward',
|
||||
action: 'seekforward',
|
||||
type: '',
|
||||
},
|
||||
volume_up: {
|
||||
name: 'volume_up',
|
||||
action: 'volume_up',
|
||||
type: '',
|
||||
},
|
||||
volume_down: {
|
||||
name: 'volume_down',
|
||||
action: 'volume_down',
|
||||
type: '',
|
||||
},
|
||||
volume_mute: {
|
||||
name: 'volume_mute',
|
||||
action: 'volume_mute',
|
||||
type: '',
|
||||
},
|
||||
music_love: {
|
||||
name: 'music_love',
|
||||
action: 'music_love',
|
||||
type: '',
|
||||
},
|
||||
music_unlove: {
|
||||
name: 'music_unlove',
|
||||
action: 'music_unlove',
|
||||
type: '',
|
||||
},
|
||||
music_dislike: {
|
||||
name: 'music_dislike',
|
||||
action: 'music_dislike',
|
||||
type: '',
|
||||
},
|
||||
},
|
||||
desktop_lyric: {
|
||||
toggle_visible: {
|
||||
name: 'toggle_visible',
|
||||
action: 'toggle_visible',
|
||||
type: '',
|
||||
},
|
||||
toggle_lock: {
|
||||
name: 'toggle_lock',
|
||||
action: 'toggle_lock',
|
||||
type: '',
|
||||
},
|
||||
toggle_always_top: {
|
||||
name: 'toggle_always_top',
|
||||
action: 'toggle_always_top',
|
||||
type: '',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for (const type of Object.keys(hotKey) as Array<keyof typeof hotKey>) {
|
||||
let keys = hotKey[type]
|
||||
for (const key of Object.keys(keys) as Array<keyof typeof keys>) {
|
||||
const keyInfo: LX.HotKey = keys[key]
|
||||
keyInfo.action = `${type}_${keyInfo.action}`
|
||||
keyInfo.name = `${type}_${keyInfo.name}`
|
||||
keyInfo.type = keyName[type] as keyof typeof hotKey
|
||||
}
|
||||
}
|
||||
|
||||
export const HOTKEY_COMMON = hotKey.common
|
||||
export const HOTKEY_PLAYER = hotKey.player
|
||||
export const HOTKEY_DESKTOP_LYRIC = hotKey.desktop_lyric
|
||||
@@ -1,31 +0,0 @@
|
||||
const { ipcMain, ipcRenderer } = require('electron')
|
||||
|
||||
|
||||
exports.mainOn = (event, callback) => {
|
||||
ipcMain.on(event, callback)
|
||||
}
|
||||
exports.mainOnce = (event, callback) => {
|
||||
ipcMain.once(event, callback)
|
||||
}
|
||||
|
||||
exports.mainHandle = (name, callback) => {
|
||||
ipcMain.handle(name, callback)
|
||||
}
|
||||
exports.mainHandleOnce = (name, callback) => {
|
||||
ipcMain.handleOnce(name, callback)
|
||||
}
|
||||
|
||||
|
||||
exports.rendererSend = (name, params) => {
|
||||
ipcRenderer.send(name, params)
|
||||
}
|
||||
exports.rendererSendSync = (name, params) => ipcRenderer.sendSync(name, params)
|
||||
|
||||
exports.rendererInvoke = (name, params) => ipcRenderer.invoke(name, params)
|
||||
|
||||
exports.rendererOn = (name, callback) => {
|
||||
ipcRenderer.on(name, callback)
|
||||
}
|
||||
exports.rendererOnce = (name, callback) => {
|
||||
ipcRenderer.once(name, callback)
|
||||
}
|
||||
195
src/common/ipcNames.ts
Normal file
@@ -0,0 +1,195 @@
|
||||
const modules = {
|
||||
common: {
|
||||
get_env_params: 'get_env_params',
|
||||
deeplink: 'deeplink',
|
||||
clear_env_params_deeplink: 'clear_env_params_deeplink',
|
||||
system_theme_change: 'system_theme_change',
|
||||
theme_change: 'theme_change',
|
||||
get_system_fonts: 'get_system_fonts',
|
||||
get_app_setting: 'get_app_setting',
|
||||
set_app_setting: 'set_app_setting',
|
||||
},
|
||||
player: {
|
||||
invoke_play_music: 'play_music',
|
||||
invoke_play_next: 'play_next',
|
||||
invoke_play_prev: 'play_prev',
|
||||
invoke_toggle_play: 'toggle_play',
|
||||
player_play: 'player_play',
|
||||
player_pause: 'player_pause',
|
||||
player_stop: 'player_stop',
|
||||
player_error: 'player_error',
|
||||
|
||||
list_data_overwire: 'list_data_overwire',
|
||||
list_get: 'list_get',
|
||||
list_add: 'list_add',
|
||||
list_remove: 'list_remove',
|
||||
list_update: 'list_update',
|
||||
list_update_position: 'list_update_position',
|
||||
list_music_get: 'list_music_get',
|
||||
list_music_add: 'list_music_add',
|
||||
list_music_move: 'list_music_move',
|
||||
list_music_remove: 'list_music_remove',
|
||||
list_music_update: 'list_music_update',
|
||||
list_music_update_position: 'list_music_update_position',
|
||||
list_music_overwrite: 'list_music_overwrite',
|
||||
list_music_clear: 'list_music_clear',
|
||||
list_music_check_exist: 'list_music_check_exist',
|
||||
list_music_get_list_ids: 'list_music_get_list_ids',
|
||||
},
|
||||
dislike: {
|
||||
get_dislike_music_infos: 'get_dislike_music_infos',
|
||||
add_dislike_music_infos: 'add_dislike_music_infos',
|
||||
overwrite_dislike_music_infos: 'overwrite_dislike_music_infos',
|
||||
clear_dislike_music_infos: 'clear_dislike_music_infos',
|
||||
},
|
||||
winMain: {
|
||||
focus: 'focus',
|
||||
close: 'close',
|
||||
min: 'min',
|
||||
max: 'max',
|
||||
fullscreen: 'fullscreen',
|
||||
set_app_name: 'set_app_name',
|
||||
clear_cache: 'clear_cache',
|
||||
get_cache_size: 'get_cache_size',
|
||||
inited: 'inited',
|
||||
show_save_dialog: 'show_save_dialog',
|
||||
show_select_dialog: 'show_select_dialog',
|
||||
show_dialog: 'show_dialog',
|
||||
open_dir_in_explorer: 'open_dir_in_explorer',
|
||||
open_dev_tools: 'open_dev_tools',
|
||||
set_power_save_blocker: 'set_power_save_blocker',
|
||||
|
||||
player_status: 'player_status',
|
||||
change_tray: 'change_tray',
|
||||
quit_update: 'quit_update',
|
||||
update_check: 'update_check',
|
||||
update_download_update: 'update_download_update',
|
||||
update_available: 'update_available',
|
||||
update_error: 'update_error',
|
||||
update_progress: 'update_progress',
|
||||
update_downloaded: 'update_downloaded',
|
||||
update_not_available: 'update_not_available',
|
||||
set_ignore_mouse_events: 'set_ignore_mouse_events',
|
||||
set_window_size: 'set_window_size',
|
||||
|
||||
handle_request: 'handle_request',
|
||||
cancel_request: 'cancel_request',
|
||||
|
||||
|
||||
restart_window: 'restart_window',
|
||||
|
||||
get_lyric_info: 'get_lyric_info',
|
||||
set_lyric_info: 'set_lyric_info',
|
||||
set_config: 'set_config',
|
||||
set_hot_key_config: 'set_hot_key_config',
|
||||
on_config_change: 'on_config_change',
|
||||
key_down: 'key_down',
|
||||
quit: 'quit',
|
||||
min_toggle: 'min_toggle',
|
||||
hide_toggle: 'hide_toggle',
|
||||
|
||||
get_other_source: 'get_other_source',
|
||||
save_other_source: 'save_other_source',
|
||||
clear_other_source: 'clear_other_source',
|
||||
get_other_source_count: 'get_other_source_count',
|
||||
get_data: 'get_data',
|
||||
save_data: 'save_data',
|
||||
get_sound_effect_eq_preset: 'get_sound_effect_eq_preset',
|
||||
save_sound_effect_eq_preset: 'save_sound_effect_eq_preset',
|
||||
get_sound_effect_convolution_preset: 'get_sound_effect_convolution_preset',
|
||||
save_sound_effect_convolution_preset: 'save_sound_effect_convolution_preset',
|
||||
// get_sound_effect_pitch_shifter_preset: 'get_sound_effect_pitch_shifter_preset',
|
||||
// save_sound_effect_pitch_shifter_preset: 'save_sound_effect_pitch_shifter_preset',
|
||||
get_hot_key: 'get_hot_key',
|
||||
|
||||
import_user_api: 'import_user_api',
|
||||
remove_user_api: 'remove_user_api',
|
||||
set_user_api: 'set_user_api',
|
||||
get_user_api_list: 'get_user_api_list',
|
||||
request_user_api: 'request_user_api',
|
||||
request_user_api_cancel: 'request_user_api_cancel',
|
||||
get_user_api_status: 'get_user_api_status',
|
||||
user_api_status: 'user_api_status',
|
||||
user_api_show_update_alert: 'user_api_show_update_alert',
|
||||
user_api_set_allow_update_alert: 'user_api_set_allow_update_alert',
|
||||
|
||||
get_palyer_lyric: 'get_lyric',
|
||||
// save_lyric: 'save_lyric',
|
||||
// clear_lyric: 'clear_lyric',
|
||||
get_lyric_raw: 'get_lyric_raw',
|
||||
save_lyric_raw: 'save_lyric_raw',
|
||||
clear_lyric_raw: 'clear_lyric_raw',
|
||||
get_lyric_raw_count: 'get_lyric_raw_count',
|
||||
get_lyric_edited: 'get_lyric_edited',
|
||||
save_lyric_edited: 'save_lyric_edited',
|
||||
remove_lyric_edited: 'remove_lyric_edited',
|
||||
clear_lyric_edited: 'clear_lyric_edited',
|
||||
get_lyric_edited_count: 'get_lyric_edited_count',
|
||||
get_music_url: 'get_music_url',
|
||||
save_music_url: 'save_music_url',
|
||||
clear_music_url: 'clear_music_url',
|
||||
get_music_url_count: 'get_music_url_count',
|
||||
|
||||
open_api_action: 'open_api_action',
|
||||
sync_action: 'sync_action',
|
||||
sync_get_server_devices: 'sync_get_server_devices',
|
||||
sync_remove_server_device: 'sync_remove_server_device',
|
||||
|
||||
process_new_desktop_lyric_client: 'process_new_desktop_lyric_client',
|
||||
|
||||
player_action_set_buttons: 'player_action_set_buttons',
|
||||
// player_action_set_thumbnail_clip: 'player_action_set_thumbnail_clip',
|
||||
player_action_on_button_click: 'player_action_on_button_click',
|
||||
|
||||
get_themes: 'get_themes',
|
||||
save_theme: 'save_theme',
|
||||
remove_theme: 'remove_theme',
|
||||
|
||||
download_list_get: 'download_list_get',
|
||||
download_list_add: 'download_list_add',
|
||||
download_list_update: 'download_list_update',
|
||||
download_list_remove: 'download_list_remove',
|
||||
download_list_clear: 'download_list_clear',
|
||||
},
|
||||
winLyric: {
|
||||
close: 'close',
|
||||
set_config: 'set_config',
|
||||
get_config: 'get_config',
|
||||
on_config_change: 'on_config_change',
|
||||
main_window_inited: 'main_window_inited',
|
||||
set_win_bounds: 'set_win_bounds',
|
||||
set_win_resizeable: 'set_win_resizeable',
|
||||
key_down: 'key_down',
|
||||
request_main_window_channel: 'request_main_window_channel',
|
||||
provide_main_window_channel: 'provide_main_window_channel',
|
||||
mouse_enter_leave: 'mouse_enter_leave',
|
||||
},
|
||||
hotKey: {
|
||||
enable: 'enable',
|
||||
status: 'status',
|
||||
set_config: 'set_config',
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
for (const moduleName of Object.keys(modules) as Array<keyof typeof modules>) {
|
||||
let eventNames = modules[moduleName]
|
||||
for (const eventName of Object.keys(eventNames) as Array<keyof typeof eventNames>) {
|
||||
eventNames[eventName] = `${moduleName}_${eventName as string}` as never
|
||||
}
|
||||
}
|
||||
|
||||
// for (const moduleName of Object.keys(modules) as Array<keyof typeof modules>) {
|
||||
// let eventNames = modules[moduleName]
|
||||
// for (const eventName of Object.keys(eventNames)) {
|
||||
// eventNames[eventName] = `${moduleName}_${eventName}`
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
export const CMMON_EVENT_NAME = modules.common
|
||||
export const PLAYER_EVENT_NAME = modules.player
|
||||
export const DISLIKE_EVENT_NAME = modules.dislike
|
||||
export const WIN_MAIN_RENDERER_EVENT_NAME = modules.winMain
|
||||
export const WIN_LYRIC_RENDERER_EVENT_NAME = modules.winLyric
|
||||
export const HOTKEY_RENDERER_EVENT_NAME = modules.hotKey
|
||||
54
src/common/mainIpc.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { ipcMain } from 'electron'
|
||||
|
||||
export function mainOn(name: string, listener: LX.IpcMainEventListener): void
|
||||
export function mainOn<T>(name: string, listener: LX.IpcMainEventListenerParams<T>): void
|
||||
export function mainOn<T>(name: string, listener: LX.IpcMainEventListenerParams<T>): void {
|
||||
ipcMain.on(name, (event, params) => {
|
||||
listener({ event, params })
|
||||
})
|
||||
}
|
||||
|
||||
export function mainOnce(name: string, listener: LX.IpcMainEventListener): void
|
||||
export function mainOnce<T>(name: string, listener: LX.IpcMainEventListenerParams<T>): void
|
||||
export function mainOnce<T>(name: string, listener: LX.IpcMainEventListenerParams<T>): void {
|
||||
ipcMain.once(name, (event, params) => {
|
||||
listener({ event, params })
|
||||
})
|
||||
}
|
||||
|
||||
export const mainOff = (name: string, listener: (...args: any[]) => void) => {
|
||||
ipcMain.removeListener(name, listener)
|
||||
}
|
||||
|
||||
export const mainOffAll = (name: string) => {
|
||||
ipcMain.removeAllListeners(name)
|
||||
}
|
||||
|
||||
export function mainHandle(name: string, listener: LX.IpcMainInvokeEventListener): void
|
||||
export function mainHandle<T>(name: string, listener: LX.IpcMainInvokeEventListenerParams<T>): void
|
||||
export function mainHandle<V>(name: string, listener: LX.IpcMainInvokeEventListenerValue<V>): void
|
||||
export function mainHandle<T, V>(name: string, listener: LX.IpcMainInvokeEventListenerParamsValue<T, V>): void
|
||||
export function mainHandle<T, V>(name: string, listener: LX.IpcMainInvokeEventListenerParamsValue<T, V>): void {
|
||||
ipcMain.handle(name, async(event, params) => {
|
||||
return listener({ event, params })
|
||||
})
|
||||
}
|
||||
|
||||
export function mainHandleOnce(name: string, listener: LX.IpcMainInvokeEventListener): void
|
||||
export function mainHandleOnce<T>(name: string, listener: LX.IpcMainInvokeEventListenerParams<T>): void
|
||||
export function mainHandleOnce<V>(name: string, listener: LX.IpcMainInvokeEventListenerValue<V>): void
|
||||
export function mainHandleOnce<T, V>(name: string, listener: LX.IpcMainInvokeEventListenerParamsValue<T, V>): void
|
||||
export function mainHandleOnce<T, V>(name: string, listener: LX.IpcMainInvokeEventListenerParamsValue<T, V>): void {
|
||||
ipcMain.handleOnce(name, async(event, params) => {
|
||||
return listener({ event, params })
|
||||
})
|
||||
}
|
||||
export const mainHandleRemove = (name: string) => {
|
||||
ipcMain.removeHandler(name)
|
||||
}
|
||||
|
||||
export function mainSend(window: Electron.BrowserWindow, name: string): void
|
||||
export function mainSend<T>(window: Electron.BrowserWindow, name: string, params: T): void
|
||||
export function mainSend<T>(window: Electron.BrowserWindow, name: string, params?: T): void {
|
||||
window.webContents.send(name, params)
|
||||
}
|
||||
45
src/common/rendererIpc.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { ipcRenderer } from 'electron'
|
||||
|
||||
export function rendererSend(name: string): void
|
||||
export function rendererSend<T>(name: string, params: T): void
|
||||
export function rendererSend<T>(name: string, params?: T): void {
|
||||
ipcRenderer.send(name, params)
|
||||
}
|
||||
|
||||
export function rendererSendSync(name: string): void
|
||||
export function rendererSendSync<T>(name: string, params: T): void
|
||||
export function rendererSendSync<T>(name: string, params?: T): void {
|
||||
ipcRenderer.sendSync(name, params)
|
||||
}
|
||||
|
||||
export async function rendererInvoke(name: string): Promise<void>
|
||||
export async function rendererInvoke<V>(name: string): Promise<V>
|
||||
export async function rendererInvoke<T>(name: string, params: T): Promise<void>
|
||||
export async function rendererInvoke<T, V>(name: string, params: T): Promise<V>
|
||||
export async function rendererInvoke <T, V>(name: string, params?: T): Promise<V> {
|
||||
return ipcRenderer.invoke(name, params)
|
||||
}
|
||||
|
||||
export function rendererOn(name: string, listener: LX.IpcRendererEventListener): void
|
||||
export function rendererOn<T>(name: string, listener: LX.IpcRendererEventListenerParams<T>): void
|
||||
export function rendererOn<T>(name: string, listener: LX.IpcRendererEventListenerParams<T>): void {
|
||||
ipcRenderer.on(name, (event, params) => {
|
||||
listener({ event, params })
|
||||
})
|
||||
}
|
||||
|
||||
export function rendererOnce(name: string, listener: LX.IpcRendererEventListener): void
|
||||
export function rendererOnce<T>(name: string, listener: LX.IpcRendererEventListenerParams<T>): void
|
||||
export function rendererOnce<T>(name: string, listener: LX.IpcRendererEventListenerParams<T>): void {
|
||||
ipcRenderer.once(name, (event, params) => {
|
||||
listener({ event, params })
|
||||
})
|
||||
}
|
||||
|
||||
export const rendererOff = (name: string, listener: (...args: any[]) => any) => {
|
||||
ipcRenderer.removeListener(name, listener)
|
||||
}
|
||||
|
||||
export const rendererOffAll = (name: string) => {
|
||||
ipcRenderer.removeAllListeners(name)
|
||||
}
|
||||
73
src/common/theme/colorUtils.js
Normal file
@@ -0,0 +1,73 @@
|
||||
/* eslint-disable */
|
||||
// https://github.com/PimpTrizkit/PJs/wiki/12.-Shade,-Blend-and-Convert-a-Web-Color-(pSBC.js)#micro-functions-version-4
|
||||
|
||||
/**
|
||||
* Blend color (Lighten or Darken)
|
||||
* @param {number} p 混合百分比 范围 0.0 - 1.0
|
||||
* @param {string} c0 rgb(a) color1
|
||||
* @param {string} c1 rgb(a) color2
|
||||
* @returns color
|
||||
*/
|
||||
exports.RGB_Linear_Blend=(p,c0,c1)=>{
|
||||
var i=parseInt,r=Math.round,P=1-p,[a,b,c,d]=c0.split(","),[e,f,g,h]=c1.split(","),x=d||h,j=x?","+(!d?h:!h?d:r((parseFloat(d)*P+parseFloat(h)*p)*1000)/1000+")"):")";
|
||||
return"rgb"+(x?"a(":"(")+r(i(a[3]=="a"?a.slice(5):a.slice(4))*P+i(e[3]=="a"?e.slice(5):e.slice(4))*p)+","+r(i(b)*P+i(f)*p)+","+r(i(c)*P+i(g)*p)+j;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blend color (Lighten or Darken)
|
||||
* @param {number} p 混合百分比 范围 0.0 - 1.0
|
||||
* @param {string} c0 rgb(a) color1
|
||||
* @param {string} c1 rgb(a) color2
|
||||
* @returns color
|
||||
*/
|
||||
exports.RGB_Log_Blend=(p,c0,c1)=>{
|
||||
var i=parseInt,r=Math.round,P=1-p,[a,b,c,d]=c0.split(","),[e,f,g,h]=c1.split(","),x=d||h,j=x?","+(!d?h:!h?d:r((parseFloat(d)*P+parseFloat(h)*p)*1000)/1000+")"):")";
|
||||
return"rgb"+(x?"a(":"(")+r((P*i(a[3]=="a"?a.slice(5):a.slice(4))**2+p*i(e[3]=="a"?e.slice(5):e.slice(4))**2)**0.5)+","+r((P*i(b)**2+p*i(f)**2)**0.5)+","+r((P*i(c)**2+p*i(g)**2)**0.5)+j;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shade color (Lighten or Darken)
|
||||
* @param {number} p Shade 百分比范围为 -1.0 - 1.0 负为黑色,正为白色
|
||||
* @param {string} c0 rgb(a) color
|
||||
* @returns color
|
||||
*/
|
||||
exports.RGB_Linear_Shade=(p,c0)=>{
|
||||
var i=parseInt,r=Math.round,[a,b,c,d]=c0.split(","),n=p<0,t=n?0:255*p,P=n?1+p:1-p;
|
||||
return"rgb"+(d?"a(":"(")+r(i(a[3]=="a"?a.slice(5):a.slice(4))*P+t)+","+r(i(b)*P+t)+","+r(i(c)*P+t)+(d?","+d:")");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shade color (Lighten or Darken)
|
||||
* @param {number} p Shade 百分比范围为 -1.0 - 1.0 负为黑色,正为白色
|
||||
* @param {string} c0 rgb(a) color
|
||||
* @returns color
|
||||
*/
|
||||
exports.RGB_Log_Shade=(p,c0)=>{
|
||||
var i=parseInt,r=Math.round,[a,b,c,d]=c0.split(","),n=p<0,t=n?0:p*255**2,P=n?1+p:1-p;
|
||||
return"rgb"+(d?"a(":"(")+r((P*i(a[3]=="a"?a.slice(5):a.slice(4))**2+t)**0.5)+","+r((P*i(b)**2+t)**0.5)+","+r((P*i(c)**2+t)**0.5)+(d?","+d:")");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修改透明度
|
||||
* @param {number} p 透明度 -1.0 - 1.0
|
||||
* @param {string} color
|
||||
* @returns color
|
||||
*/
|
||||
exports.RGB_Alpha_Shade = (p, color) => {
|
||||
var i = parseInt
|
||||
var n = p < 0
|
||||
var [r, g, b, a] = color.split(",")
|
||||
r = r[3] == 'a' ? r.slice(5) : r.slice(4)
|
||||
if (a) {
|
||||
a = parseFloat(a)
|
||||
a = a - (n ? (1 - a) * p : a * p)
|
||||
a = n ? Math.max(0, a) : Math.min(1, a)
|
||||
} else {
|
||||
a = 1 - p
|
||||
a = Math.min(1, a)
|
||||
}
|
||||
return `rgba(${i(r)}, ${i(g)}, ${i(b)}, ${a.toFixed(2)})`
|
||||
}
|
||||
384
src/common/theme/createThemes.js
Normal file
@@ -0,0 +1,384 @@
|
||||
//! 更新默认主题配置后,需要执行 npm run build:theme 重新构建index.json
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const { createThemeColors } = require('./utils')
|
||||
|
||||
const defaultThemes = [
|
||||
{
|
||||
id: 'green',
|
||||
name: '绿意盎然',
|
||||
isDark: false,
|
||||
isDarkFont: false,
|
||||
config: {
|
||||
primary: 'rgb(77, 175, 124)',
|
||||
font: 'rgb(33, 33, 33)',
|
||||
'--color-app-background': 'var(--color-primary-light-600-alpha-700)',
|
||||
'--color-main-background': 'rgba(255, 255, 255, 1)',
|
||||
'--color-nav-font': 'var(--color-primary)',
|
||||
'--background-image': 'none',
|
||||
'--background-image-position': 'center',
|
||||
'--background-image-size': 'cover',
|
||||
|
||||
'--color-btn-hide': '#3bc2b2',
|
||||
'--color-btn-min': '#85c43b',
|
||||
'--color-btn-close': '#fab4a0',
|
||||
|
||||
'--color-badge-primary': 'var(--color-primary)',
|
||||
'--color-badge-secondary': '#4baed5',
|
||||
'--color-badge-tertiary': '#e7aa36',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'blue',
|
||||
name: '蓝田生玉',
|
||||
isDark: false,
|
||||
isDarkFont: false,
|
||||
config: {
|
||||
primary: 'rgb(52, 152, 219)',
|
||||
font: 'rgb(33, 33, 33)',
|
||||
'--color-app-background': 'var(--color-primary-light-600-alpha-700)',
|
||||
'--color-main-background': 'rgba(255, 255, 255, 1)',
|
||||
'--color-nav-font': 'var(--color-primary)',
|
||||
'--background-image': 'none',
|
||||
'--background-image-position': 'center',
|
||||
'--background-image-size': 'cover',
|
||||
|
||||
'--color-btn-hide': '#3bc2b2',
|
||||
'--color-btn-min': '#85c43b',
|
||||
'--color-btn-close': '#fab4a0',
|
||||
|
||||
'--color-badge-primary': 'var(--color-primary)',
|
||||
'--color-badge-secondary': '#5cbf9b',
|
||||
'--color-badge-tertiary': '#5cbf9b',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'blue_plus',
|
||||
name: '蛋雅深蓝',
|
||||
isDark: false,
|
||||
isDarkFont: false,
|
||||
config: {
|
||||
primary: 'rgb(77, 131, 175)',
|
||||
font: 'rgb(33, 33, 33)',
|
||||
'--color-app-background': 'var(--color-primary-light-600-alpha-600)',
|
||||
'--color-main-background': 'rgba(255, 255, 255, 1)',
|
||||
'--color-nav-font': 'var(--color-primary)',
|
||||
'--background-image': 'none',
|
||||
'--background-image-position': 'center',
|
||||
'--background-image-size': 'cover',
|
||||
|
||||
'--color-btn-hide': '#3bc2b2',
|
||||
'--color-btn-min': '#85c43b',
|
||||
'--color-btn-close': '#fab4a0',
|
||||
|
||||
'--color-badge-primary': 'var(--color-primary)',
|
||||
'--color-badge-secondary': 'rgba(66.6, 150.7, 171, 1)',
|
||||
'--color-badge-tertiary': 'rgba(54, 196, 231, 1)',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'orange',
|
||||
name: '橙黄橘绿',
|
||||
isDark: false,
|
||||
isDarkFont: false,
|
||||
config: {
|
||||
primary: 'rgb(245, 171, 53)',
|
||||
font: 'rgb(33, 33, 33)',
|
||||
'--color-app-background': 'var(--color-primary-light-600-alpha-700)',
|
||||
'--color-main-background': 'rgba(255, 255, 255, 1)',
|
||||
'--color-nav-font': 'var(--color-primary)',
|
||||
'--background-image': 'none',
|
||||
'--background-image-position': 'center',
|
||||
'--background-image-size': 'cover',
|
||||
|
||||
'--color-btn-hide': '#3bc2b2',
|
||||
'--color-btn-min': '#85c43b',
|
||||
'--color-btn-close': '#fab4a0',
|
||||
|
||||
'--color-badge-primary': 'var(--color-primary)',
|
||||
'--color-badge-secondary': '#9ed458',
|
||||
'--color-badge-tertiary': '#9ed458',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'red',
|
||||
name: '热情似火',
|
||||
isDark: false,
|
||||
isDarkFont: false,
|
||||
config: {
|
||||
primary: 'rgb(214, 69, 65)',
|
||||
font: 'rgb(33, 33, 33)',
|
||||
'--color-app-background': 'var(--color-primary-light-600-alpha-700)',
|
||||
'--color-main-background': 'rgba(255, 255, 255, 1)',
|
||||
'--color-nav-font': 'var(--color-primary)',
|
||||
'--background-image': 'none',
|
||||
'--background-image-position': 'center',
|
||||
'--background-image-size': 'cover',
|
||||
|
||||
'--color-btn-hide': '#3bc2b2',
|
||||
'--color-btn-min': '#85c43b',
|
||||
'--color-btn-close': '#fab4a0',
|
||||
|
||||
'--color-badge-primary': 'var(--color-primary)',
|
||||
'--color-badge-secondary': '#dfbb6b',
|
||||
'--color-badge-tertiary': '#dfbb6b',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'pink',
|
||||
name: '粉装玉琢',
|
||||
isDark: false,
|
||||
isDarkFont: false,
|
||||
config: {
|
||||
primary: 'rgb(241, 130, 141)',
|
||||
font: 'rgb(33, 33, 33)',
|
||||
'--color-app-background': 'var(--color-primary-light-600-alpha-700)',
|
||||
'--color-main-background': 'rgba(255, 255, 255, 1)',
|
||||
'--color-nav-font': 'var(--color-primary)',
|
||||
'--background-image': 'none',
|
||||
'--background-image-position': 'center',
|
||||
'--background-image-size': 'cover',
|
||||
|
||||
'--color-btn-hide': '#3bc2b2',
|
||||
'--color-btn-min': '#85c43b',
|
||||
'--color-btn-close': '#fab4a0',
|
||||
|
||||
'--color-badge-primary': 'var(--color-primary)',
|
||||
'--color-badge-secondary': '#f5b684',
|
||||
'--color-badge-tertiary': '#f5b684',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'purple',
|
||||
name: '重斤球紫',
|
||||
isDark: false,
|
||||
isDarkFont: false,
|
||||
config: {
|
||||
primary: 'rgb(155, 89, 182)',
|
||||
font: 'rgb(33, 33, 33)',
|
||||
'--color-app-background': 'var(--color-primary-light-600-alpha-700)',
|
||||
'--color-main-background': 'rgba(255, 255, 255, 1)',
|
||||
'--color-nav-font': 'var(--color-primary)',
|
||||
'--background-image': 'none',
|
||||
'--background-image-position': 'center',
|
||||
'--background-image-size': 'cover',
|
||||
|
||||
'--color-btn-hide': '#3bc2b2',
|
||||
'--color-btn-min': '#85c43b',
|
||||
'--color-btn-close': '#fab4a0',
|
||||
|
||||
'--color-badge-primary': 'var(--color-primary)',
|
||||
'--color-badge-secondary': '#e5a39f',
|
||||
'--color-badge-tertiary': '#e5a39f',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'grey',
|
||||
name: '灰常美丽',
|
||||
isDark: false,
|
||||
isDarkFont: false,
|
||||
config: {
|
||||
primary: 'rgb(108, 122, 137)',
|
||||
font: 'rgb(33, 33, 33)',
|
||||
'--color-app-background': 'var(--color-primary-light-600-alpha-700)',
|
||||
'--color-main-background': 'rgba(255, 255, 255, 1)',
|
||||
'--color-nav-font': 'var(--color-primary)',
|
||||
'--background-image': 'none',
|
||||
'--background-image-position': 'center',
|
||||
'--background-image-size': 'cover',
|
||||
|
||||
'--color-btn-hide': '#3bc2b2',
|
||||
'--color-btn-min': '#85c43b',
|
||||
'--color-btn-close': '#fab4a0',
|
||||
|
||||
'--color-badge-primary': 'var(--color-primary)',
|
||||
'--color-badge-secondary': '#b19b9f',
|
||||
'--color-badge-tertiary': '#b19b9f',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'ming',
|
||||
name: '青出于黑',
|
||||
isDark: false,
|
||||
isDarkFont: false,
|
||||
config: {
|
||||
primary: 'rgb(51, 110, 123)',
|
||||
font: 'rgb(33, 33, 33)',
|
||||
'--color-app-background': 'var(--color-primary-light-600-alpha-700)',
|
||||
'--color-main-background': 'rgba(255, 255, 255, 1)',
|
||||
'--color-nav-font': 'var(--color-primary)',
|
||||
'--background-image': 'none',
|
||||
'--background-image-position': 'center',
|
||||
'--background-image-size': 'cover',
|
||||
|
||||
'--color-btn-hide': '#3bc2b2',
|
||||
'--color-btn-min': '#85c43b',
|
||||
'--color-btn-close': '#fab4a0',
|
||||
|
||||
'--color-badge-primary': 'var(--color-primary)',
|
||||
'--color-badge-secondary': '#6376a2',
|
||||
'--color-badge-tertiary': '#6376a2',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'blue2',
|
||||
name: '清热板蓝',
|
||||
isDark: false,
|
||||
isDarkFont: false,
|
||||
config: {
|
||||
primary: 'rgb(79, 98, 208)',
|
||||
font: 'rgb(33, 33, 33)',
|
||||
'--color-app-background': 'var(--color-primary-light-600-alpha-700)',
|
||||
'--color-main-background': 'rgba(255, 255, 255, 1)',
|
||||
'--color-nav-font': 'var(--color-primary)',
|
||||
'--background-image': 'none',
|
||||
'--background-image-position': 'center',
|
||||
'--background-image-size': 'cover',
|
||||
|
||||
'--color-btn-hide': '#3bc2b2',
|
||||
'--color-btn-min': '#85c43b',
|
||||
'--color-btn-close': '#fab4a0',
|
||||
|
||||
'--color-badge-primary': 'var(--color-primary)',
|
||||
'--color-badge-secondary': '#b080db',
|
||||
'--color-badge-tertiary': '#b080db',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'black',
|
||||
name: '黑灯瞎火',
|
||||
isDark: true,
|
||||
isDarkFont: false,
|
||||
config: {
|
||||
primary: 'rgb(150, 150, 150)',
|
||||
font: 'rgb(229, 229, 229)',
|
||||
'--color-app-background': 'rgba(0, 0, 0, 0)',
|
||||
'--color-main-background': 'rgba(19, 19, 19, 0.9)',
|
||||
'--color-nav-font': 'var(--color-primary)',
|
||||
'--background-image': 'url(./theme_images/landingMoon.png)',
|
||||
'--background-image-position': 'center',
|
||||
'--background-image-size': 'cover',
|
||||
|
||||
'--color-btn-hide': '#3bc2b2',
|
||||
'--color-btn-min': '#85c43b',
|
||||
'--color-btn-close': '#fab4a0',
|
||||
|
||||
'--color-badge-primary': 'var(--color-primary-dark-200)',
|
||||
'--color-badge-secondary': 'var(--color-primary)',
|
||||
'--color-badge-tertiary': 'var(--color-primary-dark-300)',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'mid_autumn',
|
||||
name: '月里嫦娥',
|
||||
isDark: false,
|
||||
isDarkFont: false,
|
||||
config: {
|
||||
primary: 'rgb(74, 55, 82)',
|
||||
font: 'rgb(33, 33, 33)',
|
||||
'--color-app-background': 'rgba(255, 255, 255, 0)',
|
||||
'--color-main-background': 'rgba(255, 255, 255, 0.9)',
|
||||
'--color-nav-font': 'var(--color-primary-light-600)',
|
||||
'--background-image': 'url(./theme_images/jqbg.jpg)',
|
||||
'--background-image-position': 'center',
|
||||
'--background-image-size': 'cover',
|
||||
|
||||
|
||||
'--color-btn-hide': '#3bc2b2',
|
||||
'--color-btn-min': '#85c43b',
|
||||
'--color-btn-close': '#fab4a0',
|
||||
|
||||
'--color-badge-primary': 'var(--color-primary)',
|
||||
'--color-badge-secondary': '#af9479',
|
||||
'--color-badge-tertiary': '#af9479',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'naruto',
|
||||
name: '木叶之村',
|
||||
isDark: false,
|
||||
isDarkFont: false,
|
||||
config: {
|
||||
primary: 'rgb(87, 144, 167)',
|
||||
font: 'rgb(33, 33, 33)',
|
||||
'--color-app-background': 'rgba(255, 255, 255, 0.15)',
|
||||
'--color-main-background': 'rgba(255, 255, 255, 0.8)',
|
||||
'--color-nav-font': 'var(--color-primary)',
|
||||
'--background-image': 'url(./theme_images/myzcbg.jpg)',
|
||||
'--background-image-position': 'center',
|
||||
'--background-image-size': 'cover',
|
||||
|
||||
'--color-btn-hide': '#3bc2b2',
|
||||
'--color-btn-min': '#85c43b',
|
||||
'--color-btn-close': '#fab4a0',
|
||||
|
||||
'--color-badge-primary': 'var(--color-primary)',
|
||||
'--color-badge-secondary': 'var(--color-primary-light-100)',
|
||||
'--color-badge-tertiary': 'var(--color-primary-light-100)',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'china_ink',
|
||||
name: '近墨者黑',
|
||||
isDark: false,
|
||||
isDarkFont: false,
|
||||
config: {
|
||||
primary: 'rgba(47, 47, 47, 1)',
|
||||
font: 'rgb(33, 33, 33)',
|
||||
'--color-app-background': 'rgba(255, 255, 255, 0)',
|
||||
'--color-main-background': 'rgba(255, 255, 255, 0.8)',
|
||||
'--color-nav-font': 'var(--color-primary)',
|
||||
'--background-image': 'url(./theme_images/china_ink.jpg)',
|
||||
'--background-image-position': 'center',
|
||||
'--background-image-size': 'cover',
|
||||
|
||||
|
||||
'--color-btn-hide': 'rgba(183, 212, 208, 1)',
|
||||
'--color-btn-min': 'rgba(200, 214, 183, 1)',
|
||||
'--color-btn-close': 'rgba(218, 195, 188, 1)',
|
||||
|
||||
'--color-badge-primary': 'rgba(137, 70, 70, 1)',
|
||||
'--color-badge-secondary': 'rgba(67, 139, 65, 1)',
|
||||
'--color-badge-tertiary': 'rgba(132, 135, 65, 1)',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'happy_new_year',
|
||||
name: '新年快乐',
|
||||
isDark: false,
|
||||
isDarkFont: false,
|
||||
config: {
|
||||
primary: 'rgb(192, 57, 43)',
|
||||
font: 'rgb(33, 33, 33)',
|
||||
'--color-app-background': 'rgba(255, 255, 255, 0.15)',
|
||||
'--color-main-background': 'rgba(255, 255, 255, 0.8)',
|
||||
'--color-nav-font': 'var(--color-primary)',
|
||||
'--background-image': 'url(./theme_images/xnkl.png)',
|
||||
'--background-image-position': 'center',
|
||||
'--background-image-size': 'cover',
|
||||
|
||||
'--color-btn-hide': '#3bc2b2',
|
||||
'--color-btn-min': '#85c43b',
|
||||
'--color-btn-close': '#fab4a0',
|
||||
|
||||
'--color-badge-primary': '#7fb575',
|
||||
'--color-badge-secondary': '#dfbb6b',
|
||||
'--color-badge-tertiary': 'var(--color-primary-light-100)',
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
const themes = defaultThemes.map(({ config: { primary, font, ...extInfo }, ...themeInfo }) => {
|
||||
return {
|
||||
...themeInfo,
|
||||
isCustom: false,
|
||||
config: {
|
||||
themeColors: createThemeColors(primary, font, themeInfo.isDark),
|
||||
extInfo,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
fs.writeFileSync(path.join(__dirname, 'index.json'), JSON.stringify(themes, null, 2))
|
||||
|
||||
BIN
src/common/theme/images/china_ink.jpg
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
src/common/theme/images/jqbg.jpg
Normal file
|
After Width: | Height: | Size: 353 KiB |
BIN
src/common/theme/images/landingMoon.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
src/common/theme/images/myzcbg.jpg
Normal file
|
After Width: | Height: | Size: 1.1 MiB |