Compare commits

..

173 Commits

Author SHA1 Message Date
akwizgran
934997ed91 Check for partial setup of clients due to feature flags reverting. 2023-01-31 11:23:19 +00:00
Torsten Grote
0b94814620 Merge branch 'remove-migration-code' into 'master'
Remove various bits of code whose migration periods have passed

See merge request briar/briar!1750
2023-01-30 13:59:02 +00:00
akwizgran
e82e11acfa Merge branch '2384-mailbox-problem-notification' into 'master'
Clear mailbox problem notification after unlinking

Closes #2384

See merge request briar/briar!1764
2023-01-27 15:09:27 +00:00
Torsten Grote
795461d9a8 Clear mailbox problem notification after unlinking 2023-01-27 11:49:01 -03:00
Torsten Grote
7b8d01cfe0 Merge branch '1822-rss-feeds-backend' into 'master'
Resolve "Import RSS feeds shared by other apps"

See merge request briar/briar!1763
2023-01-25 11:39:34 +00:00
akwizgran
abd04ee7f5 Add tests for feed serialisation/deserialisation. 2023-01-24 17:27:52 +00:00
akwizgran
cc5365eaf0 Remove redundant comparison from test. 2023-01-24 17:27:34 +00:00
akwizgran
6b20b03698 Bump version numbers for 1.4.20 release. 2023-01-24 15:51:48 +00:00
akwizgran
9da7fbf4f6 Update translations. 2023-01-24 15:51:26 +00:00
akwizgran
f64f442fcf Merge branch 'add-comment-for-is-connected' into 'master'
Add comment about NetworkInfo#isConnected()

See merge request briar/briar!1762
2023-01-24 15:25:52 +00:00
akwizgran
6eda2f6d13 AnimalSniffer doesn't allow StandardCharsets in tests. 2023-01-24 14:50:40 +00:00
akwizgran
6faa095dfb FeedMatcher interface doesn't need to be public. 2023-01-24 14:48:55 +00:00
akwizgran
4007fca668 Add integration tests for importing an RSS feed from a file. 2023-01-24 14:15:03 +00:00
akwizgran
28a747f7f3 Add method for adding an RSS feed from an input stream. 2023-01-24 13:57:44 +00:00
Sebastian Kürten
fd2d5c9173 Add comment about NetworkInfo#isConnected() 2023-01-24 14:48:03 +01:00
akwizgran
8f7bb9d26b Don't overwrite the list of feeds after fetching. 2023-01-24 13:28:22 +00:00
akwizgran
dc220200b6 Match newly added RSS feeds to existing feeds. 2023-01-24 12:43:14 +00:00
Torsten Grote
0cea137d75 Merge branch 'update-tor-bridges' into 'master'
Update Tor bridges

See merge request briar/briar!1761
2023-01-23 15:06:28 +00:00
akwizgran
2eef34f424 Use new transaction wrappers. 2023-01-23 13:02:16 +00:00
akwizgran
a68fff9dd2 Merge branch 'tor-0.4.7.13' into 'master'
Upgrade Tor to 0.4.7.13

See merge request briar/briar!1760
2023-01-23 12:11:32 +00:00
akwizgran
ddc8f4a7d7 Add three non-default obfs4 bridges. 2023-01-20 16:12:47 +00:00
akwizgran
f961b6a80b Remove three failing bridges. 2023-01-20 16:11:11 +00:00
akwizgran
93439d9c17 Update translations. 2023-01-20 15:50:28 +00:00
akwizgran
f3ee884816 Upgrade Tor to 0.4.7.13. 2023-01-20 15:34:23 +00:00
akwizgran
8ca22043cf Merge branch '1897-sharing-status' into 'master'
Introduce SharingStatus to report more fine-grained status

Closes #1897

See merge request briar/briar!1758
2023-01-20 14:33:32 +00:00
Torsten Grote
9353b78da8 Clarify sharing state docs 2023-01-20 11:13:35 -03:00
Torsten Grote
429bbe1275 Introduce more sharing states 2023-01-20 11:13:35 -03:00
Torsten Grote
c5fb1416bd Update JavaDoc for SharingState change 2023-01-20 11:13:34 -03:00
Torsten Grote
e52cbd896e Introduce SharingStatus to report more fine-grained status 2023-01-20 11:13:34 -03:00
akwizgran
ab1b8784b7 Merge branch '90-clickable-links' into 'master'
Resolve "Handle Hyperlinks (Clickable Links)"

Closes #90

See merge request briar/briar!1757
2023-01-20 13:47:08 +00:00
akwizgran
55a4daa92f Merge branch 'progressbar-remove-contact' into 'master'
Show progress bar while removing contact

See merge request briar/briar!1759
2023-01-20 13:44:29 +00:00
akwizgran
e52250f1e4 Don't sort list of RSS feeds in UI. 2023-01-18 15:04:38 +00:00
akwizgran
33d01aac8c Add matcher for matching an imported feed against existing feeds. 2023-01-18 15:04:38 +00:00
akwizgran
b920382e44 Store additional properties of RSS feed in metadata. 2023-01-18 15:04:38 +00:00
akwizgran
1a2f85f701 Small code cleanups for feed manager, don't fetch new feeds twice. 2023-01-18 15:04:33 +00:00
Airplane Mode
186bcc0b47 Show progress bar while removing contact 2023-01-16 23:56:26 +00:00
Torsten Grote
8b9140f477 Merge branch 'tor-0.4.7.12' into 'master'
Upgrade Tor to 0.4.7.12

See merge request briar/briar!1755
2023-01-13 16:25:42 +00:00
Katelyn Dickey
f959c32935 Remove autoLink attribute which was causing warnings to show twice, and highlight links in comments before a blog is expanded 2023-01-05 17:20:40 -05:00
akwizgran
1c060bc6db Upgrade Tor to 0.4.7.12. 2023-01-04 17:51:46 +00:00
Katelyn Dickey
5e44e4d308 Add clickable links to blog comments 2023-01-03 20:52:36 -05:00
Katelyn Dickey
75d5dec45f Add clickable links to notices/requests 2023-01-03 18:38:13 -05:00
Katelyn Dickey
d825227eb5 Add clickable links to threads (forums/groups) 2023-01-03 18:38:07 -05:00
Katelyn Dickey
967dd1f18d Add clickable links for conversations 2023-01-03 18:37:40 -05:00
akwizgran
4a4147b563 Bump version numbers for 1.4.19 release. 2022-12-30 11:15:32 +00:00
akwizgran
08b72af647 Update translations. 2022-12-30 11:07:38 +00:00
akwizgran
528e090c6f Merge branch '2409-require-obsolete-bluetooth-permission' into 'master'
Require obsolete BLUETOOTH permission on API 31

Closes #2409

See merge request briar/briar!1754
2022-12-30 10:56:29 +00:00
akwizgran
652f9e5705 Require obsolete BLUETOOTH permission on API 31.
This is a workaround for a platform bug on Xiaomi/Redmi/POCO devices that still checks for the obsolete permission.
2022-12-28 14:12:30 +00:00
akwizgran
6a91ec7a6b Merge branch '2407-bluetooth-permission' into 'master'
Always check Bluetooth permission when trying to get own address

Closes #2407

See merge request briar/briar!1753
2022-12-28 11:07:31 +00:00
akwizgran
c3a9eff96b Always check Bluetooth permission when trying to get own address. 2022-12-22 17:46:12 +00:00
akwizgran
bd05d893eb Merge branch '2397-wrong-type-of-qr-code' into 'master'
Tweak text for unknown QR code type

See merge request briar/briar!1752
2022-12-21 12:29:48 +00:00
akwizgran
6965bc0acd Tweak text for unknown QR code type. 2022-12-21 12:19:31 +00:00
akwizgran
c6e9554026 Merge branch '2397-wrong-type-of-qr-code' into 'master'
Show appropriate error message if user scans wrong kind of QR code

Closes #2397

See merge request briar/briar!1748
2022-12-19 15:43:16 +00:00
akwizgran
ab8734e373 Show relevant message when contact QR code has unknown format. 2022-12-19 10:24:58 +00:00
akwizgran
267956b36c Restore javadoc for qrCodeTooOld flag. 2022-12-19 10:04:55 +00:00
akwizgran
ec84ddb38b Merge branch '2403-show-progress-while-connecting-to-mailbox' into 'master'
Show progress while connecting to mailbox

Closes #2403

See merge request briar/briar!1747
2022-12-14 12:20:43 +00:00
akwizgran
ba2db48d8e Center text, add margin at bottom to center layout. 2022-12-14 12:03:06 +00:00
akwizgran
186f61f771 Set width of text views to 0dp so margins are applied. 2022-12-12 16:14:34 +00:00
akwizgran
47971517cd Bump version numbers for 1.4.18 release. 2022-12-12 14:03:52 +00:00
akwizgran
8db182d7e5 Update translations. 2022-12-12 14:03:01 +00:00
akwizgran
d44a609d0c Merge branch '2405-bonded-devices' into 'master'
Don't try to get bonded Bluetooth devices on API 31+

See merge request briar/briar!1751
2022-12-12 13:58:21 +00:00
akwizgran
0a1892d39f Merge branch 'do-not-crash-when-tor-crashes' into 'master'
Don't crash when the Tor process crashes

See merge request briar/briar!1749
2022-12-12 11:04:52 +00:00
akwizgran
9b092da37a Don't try to get bonded Bluetooth devices on API 31+. 2022-12-07 18:38:36 +00:00
akwizgran
7a3ffcbae6 Remove various bits of code whose migration periods have passed. 2022-12-07 17:47:02 +00:00
akwizgran
852e2c29e3 Don't crash when the Tor process crashes. 2022-12-07 17:28:33 +00:00
akwizgran
1b087d59d4 Merge branch '2400-outline-buttons' into 'master'
Use outlined button style

Closes #2400

See merge request briar/briar!1746
2022-12-07 16:54:34 +00:00
akwizgran
30ce8651b5 Fix ripple effect for outlined buttons on API 21+. 2022-12-07 15:50:56 +00:00
akwizgran
80a8ee4de9 Fix button inheritance. 2022-12-07 11:16:34 +00:00
akwizgran
354f3bc1cf Use chain so that margins are enforced. 2022-12-07 11:13:42 +00:00
akwizgran
1e6b018ff4 Add corner radius and increase top inset. 2022-12-07 11:03:46 +00:00
akwizgran
eba489bb98 Merge branch 'project-dependencies' into 'master'
Refactor dependencies to satisfy Android Studio's linter

See merge request briar/briar!1745
2022-12-05 14:54:12 +00:00
akwizgran
2bfdcaaa42 Declare dependencies for custom jar tasks. 2022-12-02 18:05:28 +00:00
akwizgran
c2e71ef52f Remove configuration: default, make transitive dependencies explicit. 2022-12-02 17:43:52 +00:00
akwizgran
9ee8fe74ba Export bramble/briar-api as API of bramble/briar-core. 2022-12-02 15:53:23 +00:00
akwizgran
95d8783852 Show appropriate error message if contact QR code is scanned. 2022-12-02 14:27:42 +00:00
akwizgran
b4f3604584 Show appropriate error message if mailbox QR code is scanned. 2022-12-02 13:35:00 +00:00
akwizgran
badccac90c Factor out recognition of QR code format. 2022-12-02 13:35:00 +00:00
akwizgran
1b8d1a5a8d Update test expectations. 2022-11-30 17:30:33 +00:00
akwizgran
2fe57d2597 Show progress while connecting to mailbox. 2022-11-30 17:17:08 +00:00
akwizgran
904d5b2ce2 Remove unused dimension. 2022-11-30 10:58:44 +00:00
akwizgran
1911b3dd97 Make OfflineFragment suitable for small screens. 2022-11-30 10:44:39 +00:00
akwizgran
bd430a1009 Use outlined button style for secondary actions. 2022-11-30 10:33:11 +00:00
akwizgran
c16d0e8f45 Refactor dependencies to satisfy Android Studio's linter.
If an Android module depends on another module's default configuration, Android Studio's linter won't recognise references to classes in the other module. Instead, the Android module must depend on the other module without specifying a configuration. This entails some changes in the handling of transitive dependencies, and the other module must include its main classes in its testOutput artifact so the Android module's tests can use them.
2022-11-29 13:35:29 +00:00
akwizgran
847273c558 Merge branch 'transactions-forum' into 'master'
Add transactional versions to functions related to forums

See merge request briar/briar!1743
2022-11-23 17:47:59 +00:00
ialokim
b9bac8b6a5 add transactional versions to functions related to forums 2022-11-23 18:37:07 +01:00
akwizgran
c855967d56 Bump version numbers for 1.4.17 release. 2022-11-14 10:41:58 +00:00
Torsten Grote
bae97e3312 Merge branch 'unpack-tor-binaries-earlier' into 'master'
Unpack Tor binaries earlier to avoid issues with task order

See merge request briar/briar!1742
2022-11-11 18:21:31 +00:00
akwizgran
f1be3031a7 Unpack Tor binaries earlier to avoid issues with task order. 2022-11-11 15:28:21 +00:00
akwizgran
3173486b3b Bump version numbers for 1.4.16 release. 2022-11-10 14:55:11 +00:00
akwizgran
c445b21d58 Update translations. 2022-11-10 14:54:30 +00:00
akwizgran
9a16cf6e54 Update translations. 2022-11-07 17:52:57 +00:00
akwizgran
a22990c1ed Merge branch 'illustration-revert' into 'master'
Don't change icons for thinner versions

See merge request briar/briar!1740
2022-11-07 13:56:42 +00:00
Torsten Grote
8262fa183b Revert "Replace illustration for mailbox success"
This reverts commit 65509137
2022-11-07 10:05:09 -03:00
akwizgran
c3f3c6211d Merge branch 'mailbox-integration-tests' into 'master'
First integration test for mailbox with two contacts

See merge request briar/briar!1725
2022-11-07 12:58:18 +00:00
Torsten Grote
0c40f39a90 Revert "Replace illustration for error fragment"
This reverts commit dab8d731
2022-11-07 09:53:19 -03:00
Torsten Grote
20b9aa86f7 revert icon changes 2022-11-07 09:53:19 -03:00
Torsten Grote
a00c920382 Merge branch 'update-play-store-translations' into 'master'
Update Play Store translations and config

See merge request briar/briar!1739
2022-11-04 17:36:08 +00:00
akwizgran
e40d6552bc Merge branch 'fix-fastlane-metadata' into 'master'
Execute Transifex for fastlane metadata from correct directory

See merge request briar/briar!1738
2022-11-04 17:09:36 +00:00
Torsten Grote
5e1564de6c don't insist on 2 uploaded messages in case Bob deletes one of them quickly 2022-11-04 13:53:58 -03:00
Torsten Grote
155daae8d0 Execute Transifex for fastlane metadata from correct directory 2022-11-04 13:19:23 -03:00
Torsten Grote
6680abf925 Make MailboxIntegrationTest a bit more thorough
by checking, after adding the contact to the mailbox but before creating the message, that the first file containing the mailbox update gets uploaded. Then after creating the message, the second file should be uploaded.
2022-11-04 12:01:00 -03:00
akwizgran
9bbfea525a Merge branch '2370-fix-readme-for-headless-jar' into 'master'
Update instructions on how to build and run briar-headless

Closes #2370

See merge request briar/briar!1726
2022-11-04 13:01:53 +00:00
akwizgran
979ef077b3 Update Play Store translations and config. 2022-11-04 12:51:49 +00:00
Torsten Grote
b7e1a987fc Don't depend on briar for mailbox integration tests
Use transport properties instead of sending private messages
2022-11-03 10:57:06 -03:00
Torsten Grote
a705caa5fa Add better logging for integration tests by injecting a ThreadFactory that can set thread names 2022-11-02 13:25:30 -03:00
akwizgran
441b28fede Merge branch 'remove-jcenter' into 'master'
Remove jcenter repository from gradle files

See merge request briar/briar!1736
2022-11-01 13:18:17 +00:00
Torsten Grote
9c95534f39 Merge branch 'merge-redundant-strings' into 'master'
Merge redundant strings

See merge request briar/briar!1737
2022-11-01 13:17:04 +00:00
Torsten Grote
57015c36b2 Re-format witness.gradle to make it easier to see what changed 2022-11-01 09:57:48 -03:00
akwizgran
a2815c75a3 Merge redundant strings. 2022-11-01 12:53:52 +00:00
Torsten Grote
9ce82af856 Merge branch '348-add-hint-to-scan-both-qr-codes' into 'master'
Add hints that both users need to scan each other's QR codes/add each other's links

See merge request briar/briar!1734
2022-11-01 12:49:39 +00:00
Torsten Grote
4b792ff040 Remove jcenter repo from gradle files 2022-11-01 09:48:39 -03:00
Torsten Grote
904355b0a6 Replace khttp test library with a fork that is available on maven central 2022-11-01 09:48:38 -03:00
Torsten Grote
02f2fdd4a1 Vendorize TrustedIntents library and upgrade screengrab 2022-11-01 09:48:38 -03:00
akwizgran
9f039ff0b8 Address review feedback. 2022-11-01 12:23:26 +00:00
akwizgran
ba83290fcd Add a hint that both parties need to add each other's links. 2022-11-01 12:23:26 +00:00
Torsten Grote
05f84000b3 Merge branch 'testdatacreator-featureflags' into 'master'
Prevent crash in TestDataCreator if blogs or forums are not enabled in core

Closes briar-desktop#420

See merge request briar/briar!1735
2022-11-01 12:18:35 +00:00
akwizgran
7302bf9d7a Add a hint that both parties need to scan each other's QR codes. 2022-11-01 12:05:28 +00:00
akwizgran
8c269541c3 Merge branch 'illustration-revamp' into 'master'
Illustration revamp

See merge request briar/briar!1722
2022-11-01 11:50:29 +00:00
Torsten Grote
324ca1b50b Address review feedback 2022-10-31 18:16:27 -03:00
akwizgran
79730484c0 Merge branch 'android-12' 2022-10-31 13:56:21 +00:00
akwizgran
86fb648dae Merge branch 'client-version-update-events' into 'master'
Send ClientVersionUpdatedEvent for each client state change, not only on version updates

See merge request briar/briar!1724
2022-10-31 12:36:25 +00:00
Torsten Grote
52809d8f2d Add permission rationale for camera and Bluetooth combined 2022-10-27 10:47:06 -03:00
Torsten Grote
0a906998fe Address review feedback 2022-10-27 10:47:06 -03:00
Torsten Grote
4a65bc1726 Update some libraries 2022-10-27 10:43:30 -03:00
Torsten Grote
f395ab1cb5 Disable our splash screen on Android 11+
in order to avoid two splash screens from being shown.
2022-10-27 10:42:41 -03:00
Torsten Grote
e6c051fee4 Require location for hotspot on Android 12+
This seems to be necessary. Without the location turned on, the hotspot does not start showing a p2p error.
2022-10-27 10:42:41 -03:00
Torsten Grote
e76701f988 Add current AppStandbyBucket to BriarReportCollector 2022-10-27 10:42:41 -03:00
Torsten Grote
e6616a8c36 Exclude all files from D2D transfers 2022-10-27 10:42:40 -03:00
Torsten Grote
824a9e1124 Handle new BLUETOOTH_SCAN and BLUETOOTH_CONNECT permission
We need to have those permissions before doing things like accessing the Bluetooth address. So we force-disable the Bluetooth plugin if the permission is not granted. The UI then forces the permission before allowing to enable the plugin.
2022-10-27 10:42:40 -03:00
Torsten Grote
113793045f Set pending intents to be immutable 2022-10-27 10:42:40 -03:00
Torsten Grote
c04937b1fa Do export only activities that need to react to external intents
For some reason SettingsActivity does not need to be exported for it to be launched from system app settings.

androidx.test.ext:junit needed to be upgraded because it somehow brought in an activity without exported attribute
2022-10-27 10:42:40 -03:00
Torsten Grote
e8994d503e Bump targetSdk to 31 (Android 12) 2022-10-27 10:42:38 -03:00
ialokim
768bb6fc64 send ClientVersionUpdatedEvent for each client state change, not only on version updates 2022-10-27 11:45:46 +02:00
Torsten Grote
645eba7fe7 Replace illustration for add contact nearby error 2022-10-25 15:49:04 -03:00
Torsten Grote
c76ed41958 Replace illustration for share app offline intro 2022-10-25 15:49:04 -03:00
Torsten Grote
4a2c1113c1 Replace illustration for crash 2022-10-25 15:49:04 -03:00
Torsten Grote
b6f78a8667 Replace illustration for connecting via Bluetooth 2022-10-25 15:49:03 -03:00
ialokim
53c7c81c0f prevent crash in testDataCreator when blogs or forums are not enabled in core 2022-10-25 10:47:03 +02:00
Torsten Grote
6dd250a1ed Merge branch 'only-retry-bridges-that-have-failed' into 'master'
Speed up BridgeTest by only retrying bridges that have failed

See merge request briar/briar!1732
2022-10-21 16:46:22 +00:00
akwizgran
87df641b5d Bump version numbers for 1.4.15 release. 2022-10-21 17:18:01 +01:00
akwizgran
a56a70a947 Merge branch 'update-bridges' into 'master'
Update bridges

See merge request briar/briar!1731
2022-10-21 16:16:26 +00:00
Torsten Grote
2e2c720241 Replace illustration for transfer data onboarding 2022-10-21 12:25:19 -03:00
Torsten Grote
7e3cf8f162 Replace illustration for mailbox problem 2022-10-21 12:25:19 -03:00
Torsten Grote
dab8d731fa Replace illustration for error fragment 2022-10-21 12:25:19 -03:00
Torsten Grote
65509137b6 Replace illustration for mailbox success 2022-10-21 12:25:19 -03:00
Torsten Grote
48ab5f4966 Replace illustration for mailbox download 2022-10-21 12:25:19 -03:00
Torsten Grote
a37447d3e8 Replace illustration for mailbox onboarding 2022-10-21 12:25:18 -03:00
Torsten Grote
5d1d0fb12a Replace illustration for adding contacts nearby 2022-10-21 12:25:18 -03:00
Torsten Grote
790818623f Replace illustration for adding a nickname for pending contact 2022-10-21 12:25:18 -03:00
Torsten Grote
d46a227cfc Add new illustration for adding contact remotely 2022-10-21 12:25:18 -03:00
Torsten Grote
e986d4b214 Replace empty state images with new illustrations 2022-10-21 12:25:18 -03:00
Torsten Grote
7bcffdf0d1 Replace illustration for sending data from removable drive 2022-10-21 12:25:18 -03:00
Torsten Grote
f4dd3c4f06 Replace illustration for receiving data from removable drive 2022-10-21 12:25:17 -03:00
Torsten Grote
f42cf00c35 Fix BriarButton rendering in AS EditMode
loses the style, but at least there's a preview now
2022-10-21 12:25:17 -03:00
Torsten Grote
38c347552b Add UiUtils for hiding illustrations on small screens 2022-10-21 12:25:17 -03:00
Torsten Grote
bab6ec70f5 Factor out mailbox constants into a MailboxConfig
so that we can change them for integration tests via the new ModularMailboxModule that now also includes the UrlProvider
2022-10-21 12:22:57 -03:00
akwizgran
8db25738e2 Speed up BridgeTest by only retrying bridges that have failed. 2022-10-21 16:02:44 +01:00
Torsten Grote
28f770df89 Always run mailbox tests when changing them 2022-10-21 10:01:32 -03:00
Torsten Grote
a720501fde First integration test for mailbox with two contacts
one private message gets send via mailbox from one contact to the other
2022-10-21 10:01:32 -03:00
Torsten Grote
648911b3ed clean up mailbox integration tests 2022-10-21 10:01:31 -03:00
akwizgran
3767aeb8b2 Add some non-default and vanilla bridges. 2022-10-21 13:41:13 +01:00
akwizgran
6344e29c29 Remove some failing bridges. 2022-10-21 13:34:32 +01:00
Torsten Grote
3734e36782 Merge branch 'obfs4proxy-0.0.14-tor1' into 'master'
Upgrade obfs4proxy to 0.0.14-tor1 and enable uTLS for meek-lite

See merge request briar/briar!1730
2022-10-21 12:03:49 +00:00
akwizgran
48ac5e2bc5 Upgrade obfs4proxy to 0.0.14-tor1 and enable uTLS for meek-lite. 2022-10-21 12:33:31 +01:00
akwizgran
404e30bb0f Bump version numbers for 1.4.14 release. 2022-10-20 15:25:58 +01:00
Torsten Grote
6a5024e8a2 Merge branch 'update-meek-bridge' into 'master'
Update meek bridge

See merge request briar/briar!1729
2022-10-20 14:24:23 +00:00
akwizgran
f19c636ddb Update meek bridge. 2022-10-20 11:20:45 +01:00
akwizgran
45833a2ec0 Bump version numbers for 1.4.13 release. 2022-10-19 18:02:22 +01:00
Torsten Grote
55efb5f41d Merge branch 'snowflake-utls' into 'master'
Use uTLS with Chrome profile for Snowflake

See merge request briar/briar!1728
2022-10-19 17:00:33 +00:00
akwizgran
6ec0fba5a2 Update translations. 2022-10-19 17:58:05 +01:00
akwizgran
1eb39eeea8 Use uTLS with Chrome profile for Snowflake. 2022-10-19 17:41:07 +01:00
akwizgran
bc9c4c9e3f Merge branch 'add-test-lan-tcp-plugin-factory' into 'master'
Add TestLanTcpPluginFactory

See merge request briar/briar!1723
2022-10-18 11:17:43 +00:00
Sebastian Kürten
ab6c925a9c Update instructions on how to build and run briar-headless 2022-10-14 16:39:44 +02:00
Sebastian Kürten
3844d33015 Add TestLanTcpPluginFactory
This factory provides a LanTcpPlugin that can connect to its own
address, useful for testing.
2022-10-06 12:07:07 +02:00
396 changed files with 12395 additions and 5390 deletions

View File

@@ -107,6 +107,10 @@ bridge test:
mailbox integration test:
extends: .optional_tests
rules:
- changes:
- mailbox-integration-tests/**/*
when: on_success
allow_failure: false
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: on_success
- if: '$CI_COMMIT_TAG == null'

View File

@@ -35,9 +35,6 @@
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" />
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<XML>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML>
<codeStyleSettings language="Groovy">
<indentOptions>
<option name="USE_TAB_CHARACTER" value="true" />

View File

@@ -1,12 +1,10 @@
import com.android.build.gradle.tasks.MergeResources
apply plugin: 'com.android.library'
apply plugin: 'witness'
apply from: 'witness.gradle'
android {
compileSdkVersion 30
buildToolsVersion '30.0.3'
compileSdkVersion 33
buildToolsVersion '33.0.0'
packagingOptions {
doNotStrip '**/*.so'
@@ -14,12 +12,13 @@ android {
defaultConfig {
minSdkVersion 16
targetSdkVersion 30
versionCode 10412
versionName "1.4.12"
targetSdkVersion 31
versionCode 10420
versionName "1.4.20"
consumerProguardFiles 'proguard-rules.txt'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments disableAnalytics: 'true'
}
compileOptions {
@@ -41,8 +40,16 @@ configurations {
}
dependencies {
implementation project(path: ':bramble-core', configuration: 'default')
// In theory this dependency shouldn't be needed, but without it Android Studio's linter will
// complain about unresolved symbols for bramble-api test classes in bramble-android tests,
// even though the bramble-api test classes are provided by the testImplementation dependency
// below and the compiler can find them
implementation project(':bramble-api')
implementation project(':bramble-core')
implementation 'androidx.annotation:annotation:1.5.0'
tor "org.briarproject:tor-android:$tor_version"
tor "org.briarproject:obfs4proxy-android:$obfs4proxy_version"
tor "org.briarproject:snowflake-android:$snowflake_version"
@@ -52,18 +59,18 @@ dependencies {
compileOnly 'javax.annotation:jsr250-api:1.0'
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
testImplementation "junit:junit:$junit_version"
testImplementation "org.jmock:jmock:$jmock_version"
testImplementation "org.jmock:jmock-junit4:$jmock_version"
testImplementation "org.jmock:jmock-imposters:$jmock_version"
}
def torBinariesDir = 'src/main/res/raw'
def torLibsDir = 'src/main/jniLibs'
task cleanTorBinaries {
outputs.dir torLibsDir
doLast {
delete fileTree(torBinariesDir) { include '*.zip' }
delete fileTree(torLibsDir) { include '**/*.so' }
}
}
@@ -71,6 +78,7 @@ task cleanTorBinaries {
clean.dependsOn cleanTorBinaries
task unpackTorBinaries {
outputs.dir torLibsDir
doLast {
configurations.tor.each { outer ->
zipTree(outer).each { inner ->
@@ -105,8 +113,4 @@ task unpackTorBinaries {
dependsOn cleanTorBinaries
}
tasks.withType(MergeResources) {
inputs.dir torBinariesDir
inputs.dir torLibsDir
dependsOn unpackTorBinaries
}
preBuild.dependsOn unpackTorBinaries

View File

@@ -1,15 +1,28 @@
<manifest
package="org.briarproject.bramble"
xmlns:android="http://schemas.android.com/apk/res/android">
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="org.briarproject.bramble">
<uses-feature android:name="android.hardware.bluetooth" android:required="false"/>
<uses-feature
android:name="android.hardware.bluetooth"
android:required="false" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- The BLUETOOTH permission was supposed to be removed in API 31 but is still needed on some Xiaomi/Redmi/POCO devices running API 31 -->
<uses-permission
android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="31" />
<uses-permission
android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<uses-permission
android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation"
tools:targetApi="31" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="false"

View File

@@ -9,6 +9,7 @@ import org.briarproject.bramble.socks.SocksModule;
import org.briarproject.bramble.system.AndroidSystemModule;
import org.briarproject.bramble.system.AndroidTaskSchedulerModule;
import org.briarproject.bramble.system.AndroidWakefulIoExecutorModule;
import org.briarproject.bramble.system.DefaultThreadFactoryModule;
import dagger.Module;
@@ -18,6 +19,7 @@ import dagger.Module;
AndroidSystemModule.class,
AndroidTaskSchedulerModule.class,
AndroidWakefulIoExecutorModule.class,
DefaultThreadFactoryModule.class,
CircumventionModule.class,
DnsModule.class,
ReportingModule.class,

View File

@@ -118,6 +118,11 @@ class AndroidNetworkManager implements NetworkManager, Service {
try {
NetworkInfo net = connectivityManager.getActiveNetworkInfo();
boolean connected = net != null && net.isConnected();
// Research into Android's behavior to check network connectivity
// (https://code.briarproject.org/briar/public-mesh-research/-/issues/19)
// has shown that NetworkInfo#isConnected() returns true if the device
// is connected to any Wifi, independent of whether any specific IP
// address can be reached using it or any domain names can be resolved.
boolean wifi = false, ipv6Only = false;
if (connected) {
wifi = net.getType() == TYPE_WIFI;

View File

@@ -55,6 +55,7 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.AndroidUtils.hasBtConnectPermission;
import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress;
@MethodsNotNullByDefault
@@ -97,6 +98,11 @@ class AndroidBluetoothPlugin extends
this.clock = clock;
}
@Override
protected boolean isBluetoothAccessible() {
return hasBtConnectPermission(app);
}
@Override
public void start() throws PluginException {
super.start();

View File

@@ -6,7 +6,6 @@ import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.ContentResolver;
import android.content.Context;
import android.os.Build;
import android.os.Parcel;
import android.os.StrictMode;
import android.provider.Settings;
@@ -15,11 +14,17 @@ import org.briarproject.nullsafety.NotNullByDefault;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Set;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static android.os.Build.FINGERPRINT;
import static android.os.Build.SERIAL;
import static android.os.Build.VERSION.SDK_INT;
import static android.os.Process.myPid;
import static android.os.Process.myTid;
import static android.os.Process.myUid;
import static android.provider.Settings.Secure.ANDROID_ID;
@Immutable
@@ -39,22 +44,27 @@ class AndroidSecureRandomProvider extends UnixSecureRandomProvider {
@Override
protected void writeToEntropyPool(DataOutputStream out) throws IOException {
super.writeToEntropyPool(out);
out.writeInt(android.os.Process.myPid());
out.writeInt(android.os.Process.myTid());
out.writeInt(android.os.Process.myUid());
if (Build.FINGERPRINT != null) out.writeUTF(Build.FINGERPRINT);
if (Build.SERIAL != null) out.writeUTF(Build.SERIAL);
out.writeInt(myPid());
out.writeInt(myTid());
out.writeInt(myUid());
if (FINGERPRINT != null) out.writeUTF(FINGERPRINT);
if (SERIAL != null) out.writeUTF(SERIAL);
ContentResolver contentResolver = appContext.getContentResolver();
String id = Settings.Secure.getString(contentResolver, ANDROID_ID);
if (id != null) out.writeUTF(id);
Parcel parcel = Parcel.obtain();
BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
if (bt != null) {
for (BluetoothDevice device : bt.getBondedDevices())
parcel.writeParcelable(device, 0);
// On API 31 and higher we need permission to access bonded devices
if (SDK_INT < 31) {
Parcel parcel = Parcel.obtain();
BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
if (bt != null) {
@SuppressLint("MissingPermission")
Set<BluetoothDevice> deviceSet = bt.getBondedDevices();
for (BluetoothDevice device : deviceSet)
parcel.writeParcelable(device, 0);
}
out.write(parcel.marshall());
parcel.recycle();
}
out.write(parcel.marshall());
parcel.recycle();
}
@Override
@@ -77,7 +87,7 @@ class AndroidSecureRandomProvider extends UnixSecureRandomProvider {
.invoke(null, (Object) seed);
// Mix the output of the Linux PRNG into the OpenSSL PRNG
int bytesRead = (Integer) Class.forName(
"org.apache.harmony.xnet.provider.jsse.NativeCrypto")
"org.apache.harmony.xnet.provider.jsse.NativeCrypto")
.getMethod("RAND_load_file", String.class, long.class)
.invoke(null, "/dev/urandom", 1024);
if (bytesRead != 1024) throw new IOException();

View File

@@ -41,6 +41,7 @@ import static java.util.logging.Level.INFO;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.system.AlarmConstants.EXTRA_PID;
import static org.briarproject.bramble.system.AlarmConstants.REQUEST_ALARM;
import static org.briarproject.bramble.util.AndroidUtils.getImmutableFlags;
@ThreadSafe
@NotNullByDefault
@@ -199,7 +200,7 @@ class AndroidTaskScheduler implements TaskScheduler, Service, AlarmListener {
Intent i = new Intent(app, AlarmReceiver.class);
i.putExtra(EXTRA_PID, android.os.Process.myPid());
return PendingIntent.getBroadcast(app, REQUEST_ALARM, i,
FLAG_CANCEL_CURRENT);
getImmutableFlags(FLAG_CANCEL_CURRENT));
}
private class ScheduledTask

View File

@@ -22,8 +22,13 @@ import java.util.Scanner;
import javax.annotation.Nullable;
import static android.Manifest.permission.BLUETOOTH_CONNECT;
import static android.app.PendingIntent.FLAG_IMMUTABLE;
import static android.content.Context.MODE_PRIVATE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Build.VERSION.SDK_INT;
import static android.os.Process.myPid;
import static android.os.Process.myUid;
import static java.lang.Runtime.getRuntime;
import static java.util.Arrays.asList;
import static org.briarproject.nullsafety.NullSafety.requireNonNull;
@@ -48,6 +53,11 @@ public class AndroidUtils {
return abis;
}
public static boolean hasBtConnectPermission(Context ctx) {
return SDK_INT < 31 || ctx.checkPermission(BLUETOOTH_CONNECT, myPid(),
myUid()) == PERMISSION_GRANTED;
}
public static String getBluetoothAddress(Context ctx,
BluetoothAdapter adapter) {
return getBluetoothAddressAndMethod(ctx, adapter).getFirst();
@@ -55,6 +65,9 @@ public class AndroidUtils {
public static Pair<String, String> getBluetoothAddressAndMethod(Context ctx,
BluetoothAdapter adapter) {
// If we don't have permission to access the adapter's address, let
// the caller know we can't find it
if (!hasBtConnectPermission(ctx)) return new Pair<>("", "");
// Return the adapter's address if it's valid and not fake
@SuppressLint("HardwareIds")
String address = adapter.getAddress();
@@ -139,4 +152,11 @@ public class AndroidUtils {
public static boolean isUiThread() {
return Looper.myLooper() == Looper.getMainLooper();
}
public static int getImmutableFlags(int flags) {
if (SDK_INT >= 23) {
return FLAG_IMMUTABLE | flags;
}
return flags;
}
}

View File

@@ -2,164 +2,58 @@ dependencyVerification {
verify = [
'androidx.annotation:annotation:1.5.0:annotation-1.5.0.jar:261fb7c0210858500bab66d34354972a75166ab4182add283780b05513d6ec4a',
'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db',
'com.android.tools.analytics-library:protos:30.0.3:protos-30.0.3.jar:f62b89dcd9de719c6a7b7e15fb1dd20e45b57222e675cf633607bd0ed6bca7e7',
'com.android.tools.analytics-library:shared:30.0.3:shared-30.0.3.jar:05aa9ba3cc890354108521fdf99802565aae5dd6ca44a6ac8bb8d594d1c1cd15',
'com.android.tools.analytics-library:tracker:30.0.3:tracker-30.0.3.jar:5d0ef35bf6733e96210b5085a2a202152921bf834d345959dce1ca3369b528df',
'com.android.tools.build:aapt2-proto:4.1.0-alpha01-6193524:aapt2-proto-4.1.0-alpha01-6193524.jar:17e75523e1e92dd4f222c7368ee41df9e964a508232f591e265d0c499baf9dca',
'com.android.tools.build:apksig:7.0.3:apksig-7.0.3.jar:012337a2803c9a30dfc41dcbc6450686ee9e5f582549f7f126479f743a343ec9',
'com.android.tools.build:apkzlib:7.0.3:apkzlib-7.0.3.jar:b31e53174c92db83c5cc6e7dac6734ea4e907a72e452c2bf1818dfd082c59397',
'com.android.tools.build:builder-model:7.0.3:builder-model-7.0.3.jar:483f99d7494a5bed027e1e8d29111384cf535d4842f0be5a79805bd44bb68d4e',
'com.android.tools.build:builder-test-api:7.0.3:builder-test-api-7.0.3.jar:f6de4bc2cef545e8367bf82d7c733829c7be3b0b3b8b09fd8c58f2150e59ab46',
'com.android.tools.build:builder:7.0.3:builder-7.0.3.jar:c6952da0094b094c2ba0fe84c675622097c5d9b9f9beb53485b860320540cf1d',
'com.android.tools.build:manifest-merger:30.0.3:manifest-merger-30.0.3.jar:72b346ba6318b4b6260e6e49df4bea5da2e12329ab6c2beb2269c49a9f51f178',
'com.android.tools.ddms:ddmlib:30.0.3:ddmlib-30.0.3.jar:7a914a68ab93393657297234e2f37b22410ae9a433cba692ce8c727c9607e3bb',
'com.android.tools.external.com-intellij:intellij-core:30.0.3:intellij-core-30.0.3.jar:1ebe858d3f58eeaa8c06507f8ac0f1c7051e6c61f35a70f3c3967d5734d3abc5',
'com.android.tools.external.com-intellij:kotlin-compiler:30.0.3:kotlin-compiler-30.0.3.jar:ed00e441f427cb4e0d418287b9da30b12b7f735f9af32e6b5d3dc960b6a742fc',
'com.android.tools.external.org-jetbrains:uast:30.0.3:uast-30.0.3.jar:a77801bee6ff509910e459525c9c34d7f04b066ade123547f16f1917548eadea',
'com.android.tools.layoutlib:layoutlib-api:30.0.3:layoutlib-api-30.0.3.jar:4caa87e9ca2e11315f650d576cd59fec1793373bc3fca3f6d53c029e7534e7c4',
'com.android.tools.lint:lint-api:30.0.3:lint-api-30.0.3.jar:bcecbd2f752a6560096a9029a47d1de6bd788a51bab505c5ebfba6a18524b983',
'com.android.tools.lint:lint-checks:30.0.3:lint-checks-30.0.3.jar:25a7cd42dc3ad502337f131fb8b7e873c53301db0a67b1c64dd4ae7a8eb66cec',
'com.android.tools.lint:lint-gradle:30.0.3:lint-gradle-30.0.3.jar:94544d6147a809bf2fd3440e51f28a4e42e547d74aab53eefd74938cdad42c26',
'com.android.tools.lint:lint-model:30.0.3:lint-model-30.0.3.jar:0b940a7f575c2ff5cbd038260f41dde686a93c672213881ead3ce8af3513b396',
'com.android.tools.lint:lint:30.0.3:lint-30.0.3.jar:ee4f11001e0c7e3b776e0d67399ad354b19b0f168822ec2b7db47c0910ed227d',
'com.android.tools:annotations:30.0.3:annotations-30.0.3.jar:5c1944982fda8555855c4f5422fabf0dc8e2306e1f5460e9ad82dae71316bc31',
'com.android.tools:common:30.0.3:common-30.0.3.jar:8751efaaf2c2ddd1f0a37526c794347def6a3057ca9fc510307c13a6cf0d036f',
'com.android.tools:dvlib:30.0.3:dvlib-30.0.3.jar:5affafcec390041e5afd64cb924153f5e474db47ee8ccc2f555b495083141233',
'com.android.tools:repository:30.0.3:repository-30.0.3.jar:0a40c6f16c506903ce2c609affd8228aceda73a69d93dfa42d4f02b8491449f6',
'com.android.tools:sdk-common:30.0.3:sdk-common-30.0.3.jar:b45570a380360236ffee0f6bb593d66b673bad3834dfe0d6c9871fa7188ee0eb',
'com.android.tools:sdklib:30.0.3:sdklib-30.0.3.jar:7088f20a414fab170a21e457825e14ebe099f753558e02c8acc12c67eb412162',
'com.android:signflinger:7.0.3:signflinger-7.0.3.jar:903a4536db3e96b4e1e1dc1e400eb0b91bf7866d9b39cd7ec94d75dde158f152',
'com.android:zipflinger:7.0.3:zipflinger-7.0.3.jar:fd209c960a3eff7a339e6fcba07d5e9ef4604d1633c69ab2df987460d9804140',
'com.beust:jcommander:1.78:jcommander-1.78.jar:7891debb84b5f83e9bd57593ebece3399abbe0fd938cf306b3534c57913b9615',
'com.github.javaparser:javaparser-core:3.17.0:javaparser-core-3.17.0.jar:23f5c982e1c7771423d37d52c774e8d2e80fd7ea7305ebe448797a96f67e6fca',
'com.google.code.findbugs:annotations:3.0.1:annotations-3.0.1.jar:6b47ff0a6de0ce17cbedc3abb0828ca5bce3009d53ea47b3723ff023c4742f79',
'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
'com.google.code.gson:gson:2.8.6:gson-2.8.6.jar:c8fb4839054d280b3033f800d1f5a97de2f028eb8ba2eb458ad287e536f3f25f',
'com.google.dagger:dagger-compiler:2.33:dagger-compiler-2.33.jar:aa8a0d8370c578fd6999802d0d90b9829377a46d2c1141e11b8f737970e7155e',
'com.google.dagger:dagger-producers:2.33:dagger-producers-2.33.jar:5897f0b6eef799c2adfe3ccacc58c0fb374d58acb063c3ebe5366c38a8bce5c8',
'com.google.dagger:dagger-spi:2.33:dagger-spi-2.33.jar:e2dcab2221b8afb9556ef0a1c83b0bd5f42552e254322a257330f754cdbbb9d4',
'com.google.dagger:dagger:2.33:dagger-2.33.jar:d8798c5b8cf6b125234e33af5c6293bb9f2208ce29b57924c35b8c0be7b6bdcb',
'com.google.errorprone:error_prone_annotations:2.2.0:error_prone_annotations-2.2.0.jar:6ebd22ca1b9d8ec06d41de8d64e0596981d9607b42035f9ed374f9de271a481a',
'com.google.errorprone:error_prone_annotations:2.3.4:error_prone_annotations-2.3.4.jar:baf7d6ea97ce606c53e11b6854ba5f2ce7ef5c24dddf0afa18d1260bd25b002c',
'com.google.dagger:dagger-compiler:2.43.2:dagger-compiler-2.43.2.jar:298c020ee6ed2f4cc651ebbfdb7f8de329b07c44b618d65be117846a850e2a03',
'com.google.dagger:dagger-producers:2.43.2:dagger-producers-2.43.2.jar:e7f5d9ffc85d48a49c8e22e02833d418f7ccad5d7512f529964db5127ab915ff',
'com.google.dagger:dagger-spi:2.43.2:dagger-spi-2.43.2.jar:3bae8d9dadeaaa5927da6f094389a560c12c05fec3d2711d2fa79292c7a7d7ad',
'com.google.dagger:dagger:2.43.2:dagger-2.43.2.jar:c89681f7cbbf8c527bf4ac2748515d617fdb54a1d425c08d914fdc28192b5fe4',
'com.google.devtools.ksp:symbol-processing-api:1.7.0-1.0.6:symbol-processing-api-1.7.0-1.0.6.jar:adc29417be5ca9ff42118105fea4e36d9ef44987abfc41432309371a60198941',
'com.google.errorprone:error_prone_annotations:2.7.1:error_prone_annotations-2.7.1.jar:cd5257c08a246cf8628817ae71cb822be192ef91f6881ca4a3fcff4f1de1cff3',
'com.google.errorprone:javac-shaded:9-dev-r4023-3:javac-shaded-9-dev-r4023-3.jar:65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30',
'com.google.googlejavaformat:google-java-format:1.5:google-java-format-1.5.jar:aa19ad7850fb85178aa22f2fddb163b84d6ce4d0035872f30d4408195ca1144e',
'com.google.guava:failureaccess:1.0.1:failureaccess-1.0.1.jar:a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26',
'com.google.guava:guava:27.1-jre:guava-27.1-jre.jar:4a5aa70cc968a4d137e599ad37553e5cfeed2265e8c193476d7119036c536fe7',
'com.google.guava:guava:30.1-jre:guava-30.1-jre.jar:e6dd072f9d3fe02a4600688380bd422bdac184caf6fe2418cfdd0934f09432aa',
'com.google.guava:guava:31.0.1-jre:guava-31.0.1-jre.jar:d5be94d65e87bd219fb3193ad1517baa55a3b88fc91d21cf735826ab5af087b9',
'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava:listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99',
'com.google.j2objc:j2objc-annotations:1.1:j2objc-annotations-1.1.jar:2994a7eb78f2710bd3d3bfb639b2c94e219cedac0d4d084d516e78c16dddecf6',
'com.google.j2objc:j2objc-annotations:1.3:j2objc-annotations-1.3.jar:21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b',
'com.google.jimfs:jimfs:1.1:jimfs-1.1.jar:c4828e28d7c0a930af9387510b3bada7daa5c04d7c25a75c7b8b081f1c257ddd',
'com.google.protobuf:protobuf-java:3.10.0:protobuf-java-3.10.0.jar:161d7d61a8cb3970891c299578702fd079646e032329d6c2cabf998d191437c9',
'com.googlecode.json-simple:json-simple:1.1:json-simple-1.1.jar:2d9484f4c649f708f47f9a479465fc729770ee65617dca3011836602264f6439',
'com.squareup:javapoet:1.13.0:javapoet-1.13.0.jar:4c7517e848a71b36d069d12bb3bf46a70fd4cda3105d822b0ed2e19c00b69291',
'com.squareup:javawriter:2.5.0:javawriter-2.5.0.jar:fcfb09fb0ea0aa97d3cfe7ea792398081348e468f126b3603cb3803f240197f0',
'com.sun.activation:javax.activation:1.2.0:javax.activation-1.2.0.jar:993302b16cd7056f21e779cc577d175a810bb4900ef73cd8fbf2b50f928ba9ce',
'com.sun.istack:istack-commons-runtime:3.0.8:istack-commons-runtime-3.0.8.jar:4ffabb06be454a05e4398e20c77fa2b6308d4b88dfbef7ca30a76b5b7d5505ef',
'com.sun.xml.fastinfoset:FastInfoset:1.2.16:FastInfoset-1.2.16.jar:056f3a1e144409f21ed16afc26805f58e9a21f3fce1543c42d400719d250c511',
'com.thoughtworks.qdox:qdox:1.12.1:qdox-1.12.1.jar:21fba22f830e9268f07cf4ab2d99e8181abbdcb0cb91ee0228eb3cb918dcdd1d',
'commons-codec:commons-codec:1.10:commons-codec-1.10.jar:4241dfa94e711d435f29a4604a3e2de5c4aa3c165e23bd066be6fc1fc4309569',
'commons-io:commons-io:2.4:commons-io-2.4.jar:cc6a41dc3eaacc9e440a6bd0d2890b20d36b4ee408fe2d67122f328bb6e01581',
'commons-logging:commons-logging:1.2:commons-logging-1.2.jar:daddea1ea0be0f56978ab3006b8ac92834afeefbd9b7e4e6316fca57df0fa636',
'info.picocli:picocli:4.5.2:picocli-4.5.2.jar:b4395e9a67932616efd2245d984bf5fcd453c2c5049558c3ce959ac2af4d3fac',
'it.unimi.dsi:fastutil:8.4.0:fastutil-8.4.0.jar:2ad2824a4a0a0eb836b52ee2fc84ba2134f44bce7bfa54015ae3f31c710a3071',
'jakarta.activation:jakarta.activation-api:1.2.1:jakarta.activation-api-1.2.1.jar:8b0a0f52fa8b05c5431921a063ed866efaa41dadf2e3a7ee3e1961f2b0d9645b',
'jakarta.xml.bind:jakarta.xml.bind-api:2.3.2:jakarta.xml.bind-api-2.3.2.jar:69156304079bdeed9fc0ae3b39389f19b3cc4ba4443bc80508995394ead742ea',
'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f',
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
'jline:jline:2.14.6:jline-2.14.6.jar:97d1acaac82409be42e622d7a54d3ae9d08517e8aefdea3d2ba9791150c2f02d',
'junit:junit:4.13.1:junit-4.13.1.jar:c30719db974d6452793fe191b3638a5777005485bae145924044530ffa5f6122',
'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3',
'net.bytebuddy:byte-buddy:1.9.12:byte-buddy-1.9.12.jar:3688c3d434bebc3edc5516296a2ed0f47b65e451071b4afecad84f902f0efc11',
'net.java.dev.jna:jna-platform:5.6.0:jna-platform-5.6.0.jar:9ecea8bf2b1b39963939d18b70464eef60c508fed8820f9dcaba0c35518eabf7',
'net.java.dev.jna:jna:5.6.0:jna-5.6.0.jar:5557e235a8aa2f9766d5dc609d67948f2a8832c2d796cea9ef1d6cbe0b3b7eaf',
'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0',
'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd',
'net.sf.jopt-simple:jopt-simple:4.9:jopt-simple-4.9.jar:26c5856e954b5f864db76f13b86919b59c6eecf9fd930b96baa8884626baf2f5',
'net.sf.kxml:kxml2:2.3.0:kxml2-2.3.0.jar:f264dd9f79a1fde10ce5ecc53221eff24be4c9331c830b7d52f2f08a7b633de2',
'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047',
'org.apache.ant:ant-antlr:1.10.9:ant-antlr-1.10.9.jar:7623dc9d0f20ea713290c6bf1a23f4c059447aef7ff9f5b2be75960f3f028d2e',
'org.apache.ant:ant-junit:1.10.9:ant-junit-1.10.9.jar:960bdc8827954d62206ba42d0a68a7ee4476175ba47bb113e17e77cce7394630',
'org.apache.ant:ant-launcher:1.10.9:ant-launcher-1.10.9.jar:fcce891f57f3be72149ff96ac2a80574165b3e0839866b95d24528f3027d50c1',
'org.apache.ant:ant:1.10.9:ant-1.10.9.jar:0715478af585ea80a18985613ebecdc7922122d45b2c3c970ff9b352cddb75fc',
'org.apache.commons:commons-compress:1.20:commons-compress-1.20.jar:0aeb625c948c697ea7b205156e112363b59ed5e2551212cd4e460bdb72c7c06e',
'org.apache.httpcomponents:httpclient:4.5.6:httpclient-4.5.6.jar:c03f813195e7a80e3608d0ddd8da80b21696a4c92a6a2298865bf149071551c7',
'org.apache.httpcomponents:httpcore:4.4.10:httpcore-4.4.10.jar:78ba1096561957db1b55200a159b648876430342d15d461277e62360da19f6fd',
'org.apache.httpcomponents:httpmime:4.5.6:httpmime-4.5.6.jar:0b2b1102c18d3c7e05a77214b9b7501a6f6056174ae5604e0e256776eda7553e',
'org.bouncycastle:bcpkix-jdk15on:1.56:bcpkix-jdk15on-1.56.jar:7043dee4e9e7175e93e0b36f45b1ec1ecb893c5f755667e8b916eb8dd201c6ca',
'org.bouncycastle:bcprov-jdk15on:1.56:bcprov-jdk15on-1.56.jar:963e1ee14f808ffb99897d848ddcdb28fa91ddda867eb18d303e82728f878349',
'org.briarproject:obfs4proxy-android:0.0.14:obfs4proxy-android-0.0.14.jar:ad9b1ee4757b05867a19e993147bbb018bddd1f26ce3da746d5f037d5991a8c8',
'org.briarproject:obfs4proxy-android:0.0.14-tor1:obfs4proxy-android-0.0.14-tor1.jar:8b08068778b133484b17956d8f7a7710739c33f671a26a68156f4d34e6f28c30',
'org.briarproject:snowflake-android:2.3.1:snowflake-android-2.3.1.jar:1f83c9a070f87b7074af13627709a8b5aced5460104be7166af736b1bb73c293',
'org.briarproject:tor-android:0.4.5.14:tor-android-0.4.5.14.jar:7cf1beaa6c1db51fc8fac263aba9624ef289c3db29772509efcbc59f7057330a',
'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d',
'org.checkerframework:checker-qual:2.5.2:checker-qual-2.5.2.jar:64b02691c8b9d4e7700f8ee2e742dce7ea2c6e81e662b7522c9ee3bf568c040a',
'org.checkerframework:checker-qual:3.5.0:checker-qual-3.5.0.jar:729990b3f18a95606fc2573836b6958bcdb44cb52bfbd1b7aa9c339cff35a5a4',
'org.codehaus.groovy:groovy-ant:3.0.7:groovy-ant-3.0.7.jar:6ed2ba82813d128f7050c24142e87b3dc2ad8b504786280eb03e81f0cf6a5793',
'org.codehaus.groovy:groovy-astbuilder:3.0.7:groovy-astbuilder-3.0.7.jar:b290451eb1583666e906c41f7d14747b4cc96363c99c478b244634fd5dfc9013',
'org.codehaus.groovy:groovy-cli-picocli:3.0.7:groovy-cli-picocli-3.0.7.jar:71b4bd11fb30a9c7b5618e22122c9c5141958fb27f4dcf0068b6f715088f6916',
'org.codehaus.groovy:groovy-console:3.0.7:groovy-console-3.0.7.jar:0541b358b6b8e5363215026736168fccfec1d91bac678d066fa77349eeeaa5dd',
'org.codehaus.groovy:groovy-datetime:3.0.7:groovy-datetime-3.0.7.jar:b9823d14b1a4f94236ae2f8a471701aab17e093e1b33402b91550b5c8dd88f04',
'org.codehaus.groovy:groovy-docgenerator:3.0.7:groovy-docgenerator-3.0.7.jar:bf53f7a11c9eb1e278e1b8ed2714c741bcf781235c803ad3ba1555f2614573f3',
'org.codehaus.groovy:groovy-groovydoc:3.0.7:groovy-groovydoc-3.0.7.jar:86b24dfc23c005066ab83927cdb54177f06c9531773f2e2d2ecc9a131f7c2677',
'org.codehaus.groovy:groovy-groovysh:3.0.7:groovy-groovysh-3.0.7.jar:5c40e78cbc09726aedd1c75fab112d245d665d6294870f9119e6cd3013ed14ab',
'org.codehaus.groovy:groovy-jmx:3.0.7:groovy-jmx-3.0.7.jar:0a89f3007884eb156751937d93382038b83d39c7c2f0ab156ebf251a7251f2ab',
'org.codehaus.groovy:groovy-json:3.0.7:groovy-json-3.0.7.jar:df1f0ee475e3fc93a6a0d17548294e160cca5de6d9d36817a7be1fbe650de03b',
'org.codehaus.groovy:groovy-jsr223:3.0.7:groovy-jsr223-3.0.7.jar:1dbd969595332416193baa660fbb45743d19696eaa25fe98e591a2739e13517e',
'org.codehaus.groovy:groovy-macro:3.0.7:groovy-macro-3.0.7.jar:c6cc06df526b39e2c359e2435f0071594c5a1c7babafaa6c184fdd8fa931531f',
'org.codehaus.groovy:groovy-nio:3.0.7:groovy-nio-3.0.7.jar:db54c577882b294cd8c975ec5451596441baf54781319c61627dca0e0c2361ef',
'org.codehaus.groovy:groovy-servlet:3.0.7:groovy-servlet-3.0.7.jar:5b6a909bf501c209adfb6205b9e740649609074455fd979bf9da4853e6ff9a39',
'org.codehaus.groovy:groovy-sql:3.0.7:groovy-sql-3.0.7.jar:252bb6c74e1a9f41756ad4fbd3b0d2eddc93bb61109961dd1952a37bf2d57a64',
'org.codehaus.groovy:groovy-swing:3.0.7:groovy-swing-3.0.7.jar:bd942032d9328d54c6679c49a41f6caa0d4a0039ebe598493b8a647730d98cff',
'org.codehaus.groovy:groovy-templates:3.0.7:groovy-templates-3.0.7.jar:f119e07f650ef186ae5a4b944f9e30915b14311bad47c94a6b32de8d4f69bc80',
'org.codehaus.groovy:groovy-test-junit5:3.0.7:groovy-test-junit5-3.0.7.jar:c16eeea07b8e396891e266d7ba9388b24ac804237ffdd9a792b0d08969bad014',
'org.codehaus.groovy:groovy-test:3.0.7:groovy-test-3.0.7.jar:f71afd7c25d43017f89ea47e6de6daec971d159047dae083c1513a8422d44b90',
'org.codehaus.groovy:groovy-testng:3.0.7:groovy-testng-3.0.7.jar:713d5f2231bbb5712aefd362151b9ffd884aeb7ef2e773315cc54259cbdd063d',
'org.codehaus.groovy:groovy-xml:3.0.7:groovy-xml-3.0.7.jar:8a62e7c9ddece3e82676c4bef2f2c100f459602cd1fb6a14e94187bf863e97ff',
'org.codehaus.groovy:groovy:3.0.7:groovy-3.0.7.jar:51d1777e8dd1f00e60ea56e00d8a354ff5aab1f00fc8464ae8d39d71867e401f',
'org.codehaus.mojo:animal-sniffer-annotations:1.17:animal-sniffer-annotations-1.17.jar:92654f493ecfec52082e76354f0ebf87648dc3d5cec2e3c3cdb947c016747a53',
'org.glassfish.jaxb:jaxb-runtime:2.3.2:jaxb-runtime-2.3.2.jar:e6e0a1e89fb6ff786279e6a0082d5cef52dc2ebe67053d041800737652b4fd1b',
'org.glassfish.jaxb:txw2:2.3.2:txw2-2.3.2.jar:4a6a9f483388d461b81aa9a28c685b8b74c0597993bf1884b04eddbca95f48fe',
'org.hamcrest:hamcrest-core:1.3:hamcrest-core-1.3.jar:66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9',
'org.briarproject:tor-android:0.4.7.13:tor-android-0.4.7.13.jar:7852aab7d2298b80878c7719f34ce665725b494d673ecf2e6f9e697564638cc6',
'org.checkerframework:checker-compat-qual:2.5.5:checker-compat-qual-2.5.5.jar:11d134b245e9cacc474514d2d66b5b8618f8039a1465cdc55bbc0b34e0008b7a',
'org.checkerframework:checker-qual:3.12.0:checker-qual-3.12.0.jar:ff10785ac2a357ec5de9c293cb982a2cbb605c0309ea4cc1cb9b9bc6dbe7f3cb',
'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9',
'org.hamcrest:hamcrest-library:2.1:hamcrest-library-2.1.jar:b7e2b6895b3b679f0e47b6380fda391b225e9b78505db9d8bdde8d3cc8d52a21',
'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050',
'org.jacoco:org.jacoco.agent:0.8.3:org.jacoco.agent-0.8.3.jar:522deb254ee16a04cc8341cc8f335f5cb7232982994d961b9cf3a0454709209f',
'org.jacoco:org.jacoco.ant:0.8.3:org.jacoco.ant-0.8.3.jar:735844e1ae15f9b875b42a27ac5cb61cc26e106d9e839e5d1c6756709b424ce0',
'org.jacoco:org.jacoco.core:0.8.3:org.jacoco.core-0.8.3.jar:0818437bc060a0c7cc798148f22b713702aae2771aba104444407697d578f1ea',
'org.jacoco:org.jacoco.report:0.8.3:org.jacoco.report-0.8.3.jar:aae08fa4ff043c807b8876cdb2d8705eb8449a55efce461baa6c09da245088c1',
'org.jetbrains.intellij.deps:trove4j:1.0.20181211:trove4j-1.0.20181211.jar:affb7c85a3c87bdcf69ff1dbb84de11f63dc931293934bc08cd7ab18de083601',
'org.jetbrains.kotlin:kotlin-reflect:1.4.32:kotlin-reflect-1.4.32.jar:dbf19e9cdaa9c3c170f3f6f6ce3922f38dfc1d7fa1cab5b7c23a19da8b5eec5b',
'org.jetbrains.kotlin:kotlin-stdlib-common:1.4.20:kotlin-stdlib-common-1.4.20.jar:a7112c9b3cefee418286c9c9372f7af992bd1e6e030691d52f60cb36dbec8320',
'org.jetbrains.kotlin:kotlin-stdlib-common:1.4.32:kotlin-stdlib-common-1.4.32.jar:e1ff6f55ee9e7591dcc633f7757bac25a7edb1cc7f738b37ec652f10f66a4145',
'org.jacoco:org.jacoco.agent:0.8.7:org.jacoco.agent-0.8.7.jar:9cbcc986e0fbe821a78ff1f8f7d5216f200e5eb124e7f6837d1dc4a77b28b143',
'org.jacoco:org.jacoco.ant:0.8.7:org.jacoco.ant-0.8.7.jar:97ca96a382c3f23a44d8eb4c4e6c3742a30cb8005774a76ced0fc4806ce49605',
'org.jacoco:org.jacoco.core:0.8.7:org.jacoco.core-0.8.7.jar:ad7739b5fb5969aa1a8aead3d74ed54dc82ed012f1f10f336bd1b96e71c1a13c',
'org.jacoco:org.jacoco.report:0.8.7:org.jacoco.report-0.8.7.jar:cc89258623700a6c932592153cb528785876b6da183d5431f97efbba6f020e5b',
'org.jetbrains.kotlin:kotlin-stdlib-common:1.7.0:kotlin-stdlib-common-1.7.0.jar:59c6ff64fe9a6604afce03e8aaa75f83586c6030ac71fb0b34ee7cdefed3618f',
'org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10:kotlin-stdlib-common-1.7.10.jar:19f102efe9629f8eabc63853ad15c533e47c47f91fca09285c5bde86e59f91d4',
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.32:kotlin-stdlib-jdk7-1.4.32.jar:5f801e75ca27d8791c14b07943c608da27620d910a8093022af57f543d5d98b6',
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.32:kotlin-stdlib-jdk8-1.4.32.jar:adc43e54757b106e0cd7b3b7aa257dff471b61efdabe067fc02b2f57e2396262',
'org.jetbrains.kotlin:kotlin-stdlib:1.4.20:kotlin-stdlib-1.4.20.jar:b8ab1da5cdc89cb084d41e1f28f20a42bd431538642a5741c52bbfae3fa3e656',
'org.jetbrains.kotlin:kotlin-stdlib:1.4.32:kotlin-stdlib-1.4.32.jar:13e9fd3e69dc7230ce0fc873a92a4e5d521d179bcf1bef75a6705baac3bfecba',
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.0:kotlin-stdlib-jdk7-1.7.0.jar:07e91be9b2ca20672d2bdb7e181b766e73453a2da13492b5ddaee8fa47aea239',
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.0:kotlin-stdlib-jdk8-1.7.0.jar:cf058e11db1dfc9944680c8c61b95ac689aaaa8a3eb30bced028100f038f030b',
'org.jetbrains.kotlin:kotlin-stdlib:1.7.0:kotlin-stdlib-1.7.0.jar:aa88e9625577957f3249a46cb6e166ee09b369e600f7a11d148d16b0a6d87f05',
'org.jetbrains.kotlin:kotlin-stdlib:1.7.10:kotlin-stdlib-1.7.10.jar:e771fe74250a943e8f6346713201ff1d8cb95c3a5d1a91a22b65a9e04f6a8901',
'org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.1.0:kotlinx-metadata-jvm-0.1.0.jar:9753bb39efef35957c5c15df9a3cb769aabf2cdfa74b47afcb7760e5146be3b5',
'org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.5.0:kotlinx-metadata-jvm-0.5.0.jar:ca063a96639b08b9eaa0de4d65e899480740a6efbe28ab9a8681a2ced03055a4',
'org.jetbrains:annotations:13.0:annotations-13.0.jar:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478',
'org.jmock:jmock-imposters:2.12.0:jmock-imposters-2.12.0.jar:3b836269745a137c9b2347e8d7c2104845b126ef04f012d6bfd94f1a7dea7b09',
'org.jmock:jmock-junit4:2.12.0:jmock-junit4-2.12.0.jar:3233062fc889637c151a24f1ee086bad04321ab7d8264fef279daff0fa27205b',
'org.jmock:jmock-legacy:2.12.0:jmock-legacy-2.12.0.jar:dea3a9cca653d082e2fe7e40232e982fe03a9984c7d67ceff24f3e03fe580dcd',
'org.jmock:jmock-testjar:2.12.0:jmock-testjar-2.12.0.jar:efefbcf6cd294d0e29f0c46eb2a3380d4ca4e1763ff719c69e2f2ac62f564a04',
'org.jmock:jmock:2.12.0:jmock-2.12.0.jar:266d07314c0cd343c46ff8a55601272de8cf406807caf55e6f313295f83d10be',
'org.junit.jupiter:junit-jupiter-api:5.7.0:junit-jupiter-api-5.7.0.jar:b03f78e0daeed2d77a0af9bcd662b4cdb9693f7ee72e01a539b508b84c63d182',
'org.junit.jupiter:junit-jupiter-engine:5.7.0:junit-jupiter-engine-5.7.0.jar:dfa26af94644ac2612dde6625852fcb550a0d21caa243257de54cba738ba87af',
'org.junit.platform:junit-platform-commons:1.7.0:junit-platform-commons-1.7.0.jar:5330ee87cc7586e6e25175a34e9251624ff12ff525269d3415d0b4ca519b6fea',
'org.junit.platform:junit-platform-engine:1.7.0:junit-platform-engine-1.7.0.jar:75f21a20dc594afdc875736725b408cec6d0344874d29f34b2dd3075500236f2',
'org.junit.platform:junit-platform-launcher:1.7.0:junit-platform-launcher-1.7.0.jar:fbdc748fde4c4279fe1d3c607447cb3b7ccd45d7338fc574f8a894ddf2d16818',
'org.jvnet.staxex:stax-ex:1.8.1:stax-ex-1.8.1.jar:20522549056e9e50aa35ef0b445a2e47a53d06be0b0a9467d704e2483ffb049a',
'org.objenesis:objenesis:3.0.1:objenesis-3.0.1.jar:7a8ff780b9ff48415d7c705f60030b0acaa616e7f823c98eede3b63508d4e984',
'org.opentest4j:opentest4j:1.2.0:opentest4j-1.2.0.jar:58812de60898d976fb81ef3b62da05c6604c18fd4a249f5044282479fc286af2',
'org.ow2.asm:asm-analysis:7.0:asm-analysis-7.0.jar:e981f8f650c4d900bb033650b18e122fa6b161eadd5f88978d08751f72ee8474',
'org.ow2.asm:asm-commons:7.0:asm-commons-7.0.jar:fed348ef05958e3e846a3ac074a12af5f7936ef3d21ce44a62c4fa08a771927d',
'org.ow2.asm:asm-tree:7.0:asm-tree-7.0.jar:cfd7a0874f9de36a999c127feeadfbfe6e04d4a71ee954d7af3d853f0be48a6c',
'org.ow2.asm:asm-util:7.0:asm-util-7.0.jar:75fbbca440ef463f41c2b0ab1a80abe67e910ac486da60a7863cbcb5bae7e145',
'org.ow2.asm:asm:7.0:asm-7.0.jar:b88ef66468b3c978ad0c97fd6e90979e56155b4ac69089ba7a44e9aa7ffe9acf',
'org.ow2.asm:asm-analysis:9.1:asm-analysis-9.1.jar:81a88041b1b8beda5a8a99646098046c48709538270c49def68abff25ac3be34',
'org.ow2.asm:asm-commons:9.1:asm-commons-9.1.jar:afcb26dc1fc12c0c4a99ada670908dd82e18dfc488caf5ee92546996b470c00c',
'org.ow2.asm:asm-tree:9.1:asm-tree-9.1.jar:fd00afa49e9595d7646205b09cecb4a776a8ff0ba06f2d59b8f7bf9c704b4a73',
'org.ow2.asm:asm:7.1:asm-7.1.jar:4ab2fa2b6d2cc9ccb1eaa05ea329c407b47b13ed2915f62f8c4b8cc96258d4de',
'org.testng:testng:7.3.0:testng-7.3.0.jar:63727488f9717d57f0d0a0fee5a1fc10a2be9cfcff2ec3a7187656d663c0774e',
'xerces:xercesImpl:2.12.0:xercesImpl-2.12.0.jar:b50d3a4ca502faa4d1c838acb8aa9480446953421f7327e338c5dda3da5e76d0',
'xml-apis:xml-apis:1.4.01:xml-apis-1.4.01.jar:a840968176645684bb01aed376e067ab39614885f9eee44abe35a5f20ebe7fad',
'org.ow2.asm:asm:9.1:asm-9.1.jar:cda4de455fab48ff0bcb7c48b4639447d4de859a7afc30a094a986f0936beba2',
]
}

View File

@@ -8,9 +8,10 @@ apply from: 'witness.gradle'
dependencies {
api 'org.briarproject:null-safety:0.1'
api 'com.google.code.findbugs:jsr305:3.0.2'
api 'javax.inject:javax.inject:1'
api "com.google.dagger:dagger:$dagger_version"
implementation "com.google.dagger:dagger:$dagger_version"
implementation 'com.google.code.findbugs:jsr305:3.0.2'
implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_version"
testImplementation "junit:junit:$junit_version"
@@ -25,7 +26,7 @@ configurations {
testOutput.extendsFrom(testCompile)
}
task jarTest(type: Jar, dependsOn: testClasses) {
from sourceSets.test.output
from sourceSets.test.output, sourceSets.main.output
classifier = 'test'
}
artifacts {

View File

@@ -1,18 +1,26 @@
package org.briarproject.bramble.api.keyagreement;
public interface KeyAgreementConstants {
import org.briarproject.bramble.api.mailbox.MailboxConstants;
/**
* The version of the BQP protocol used in beta releases. This version
* number is reserved.
*/
byte BETA_PROTOCOL_VERSION = 89;
public interface KeyAgreementConstants {
/**
* The current version of the BQP protocol.
*/
byte PROTOCOL_VERSION = 4;
/**
* The QR code format identifier, used to distinguish BQP QR codes from
* QR codes used for other purposes. See
* {@link MailboxConstants#QR_FORMAT_ID}.
*/
byte QR_FORMAT_ID = 0;
/**
* The QR code format version.
*/
byte QR_FORMAT_VERSION = PROTOCOL_VERSION;
/**
* The length of the BQP key commitment in bytes.
*/

View File

@@ -7,5 +7,5 @@ import java.io.IOException;
@NotNullByDefault
public interface PayloadParser {
Payload parse(byte[] raw) throws IOException;
Payload parse(String payload) throws IOException;
}

View File

@@ -1,5 +1,6 @@
package org.briarproject.bramble.api.mailbox;
import org.briarproject.bramble.api.keyagreement.KeyAgreementConstants;
import org.briarproject.bramble.api.plugin.TransportId;
import java.util.List;
@@ -19,6 +20,18 @@ public interface MailboxConstants {
*/
TransportId ID = new TransportId("org.briarproject.bramble.mailbox");
/**
* The QR code format identifier, used to distinguish mailbox QR codes
* from QR codes used for other purposes. See
* {@link KeyAgreementConstants#QR_FORMAT_ID};
*/
byte QR_FORMAT_ID = 1;
/**
* The QR code format version.
*/
byte QR_FORMAT_VERSION = 0;
/**
* Mailbox API versions that we support as a client. This is reported to our
* contacts by {@link MailboxUpdateManager}.

View File

@@ -1,17 +1,44 @@
package org.briarproject.bramble.api.mailbox;
import org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType;
public abstract class MailboxPairingState {
public static class QrCodeReceived extends MailboxPairingState {
public abstract static class Pending extends MailboxPairingState {
public final long timeStarted;
private Pending(long timeStarted) {
this.timeStarted = timeStarted;
}
}
public static class Pairing extends MailboxPairingState {
public static class QrCodeReceived extends Pending {
public QrCodeReceived(long timeStarted) {
super(timeStarted);
}
}
public static class Pairing extends Pending {
public Pairing(long timeStarted) {
super(timeStarted);
}
}
public static class Paired extends MailboxPairingState {
}
public static class InvalidQrCode extends MailboxPairingState {
public final QrCodeType qrCodeType;
public final int formatVersion;
public InvalidQrCode(QrCodeType qrCodeType, int formatVersion) {
this.qrCodeType = qrCodeType;
this.formatVersion = formatVersion;
}
}
public static class MailboxAlreadyPaired extends MailboxPairingState {

View File

@@ -27,8 +27,6 @@ public interface TorConstants {
int PREF_TOR_NETWORK_AUTOMATIC = 0;
int PREF_TOR_NETWORK_WITHOUT_BRIDGES = 1;
int PREF_TOR_NETWORK_WITH_BRIDGES = 2;
// TODO: Remove when settings migration code is removed
int PREF_TOR_NETWORK_NEVER = 3;
// Default values for local settings
boolean DEFAULT_PREF_PLUGIN_ENABLE = true;

View File

@@ -0,0 +1,16 @@
package org.briarproject.bramble.api.qrcode;
import org.briarproject.bramble.api.Pair;
import org.briarproject.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface QrCodeClassifier {
enum QrCodeType {
BQP,
MAILBOX,
UNKNOWN
}
Pair<QrCodeType, Integer> classifyQrCode(String payload);
}

View File

@@ -0,0 +1,25 @@
package org.briarproject.bramble.api.qrcode;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType;
import org.briarproject.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
/**
* Thrown when a QR code that has been scanned does not have the expected type.
*/
@Immutable
@NotNullByDefault
public class WrongQrCodeTypeException extends FormatException {
private final QrCodeType qrCodeType;
public WrongQrCodeTypeException(QrCodeType qrCodeType) {
this.qrCodeType = qrCodeType;
}
public QrCodeType getQrCodeType() {
return qrCodeType;
}
}

View File

@@ -3,7 +3,6 @@ package org.briarproject.bramble.util;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.nullsafety.NotNullByDefault;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
@@ -17,13 +16,18 @@ import javax.annotation.Nullable;
import static java.nio.charset.CodingErrorAction.IGNORE;
import static java.util.regex.Pattern.CASE_INSENSITIVE;
@SuppressWarnings("CharsetObjectCanBeUsed")
@NotNullByDefault
public class StringUtils {
private static final Charset UTF_8 = Charset.forName("UTF-8");
private static Pattern MAC = Pattern.compile("[0-9a-f]{2}:[0-9a-f]{2}:" +
"[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}",
CASE_INSENSITIVE);
public static final Charset UTF_8 = Charset.forName("UTF-8");
public static final Charset US_ASCII = Charset.forName("US-ASCII");
public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
private static final Pattern MAC =
Pattern.compile("[0-9a-f]{2}:[0-9a-f]{2}:" +
"[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}",
CASE_INSENSITIVE);
private static final char[] HEX = new char[] {
'0', '1', '2', '3', '4', '5', '6', '7',
@@ -45,11 +49,7 @@ public class StringUtils {
}
public static byte[] toUtf8(String s) {
try {
return s.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new AssertionError(e);
}
return s.getBytes(UTF_8);
}
public static String fromUtf8(byte[] bytes) {

View File

@@ -1,10 +1,10 @@
dependencyVerification {
verify = [
'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db',
'com.fasterxml.jackson.core:jackson-annotations:2.13.0:jackson-annotations-2.13.0.jar:81f9724d8843e8b08f8f6c0609e7a2b030d00c34861c4ac7e2099a7235047d6f',
'com.fasterxml.jackson.core:jackson-annotations:2.13.4:jackson-annotations-2.13.4.jar:ac5b27a634942391ca113850ee7db01df1499a240174021263501c05fc653b44',
'com.google.code.findbugs:annotations:3.0.1:annotations-3.0.1.jar:6b47ff0a6de0ce17cbedc3abb0828ca5bce3009d53ea47b3723ff023c4742f79',
'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
'com.google.dagger:dagger:2.33:dagger-2.33.jar:d8798c5b8cf6b125234e33af5c6293bb9f2208ce29b57924c35b8c0be7b6bdcb',
'com.google.dagger:dagger:2.43.2:dagger-2.43.2.jar:c89681f7cbbf8c527bf4ac2748515d617fdb54a1d425c08d914fdc28192b5fe4',
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3',
'net.bytebuddy:byte-buddy:1.9.12:byte-buddy-1.9.12.jar:3688c3d434bebc3edc5516296a2ed0f47b65e451071b4afecad84f902f0efc11',

View File

@@ -9,30 +9,31 @@ apply from: 'witness.gradle'
apply from: '../dagger.gradle'
dependencies {
implementation project(path: ':bramble-api', configuration: 'default')
implementation 'org.bouncycastle:bcprov-jdk15to18:1.70'
api project(':bramble-api')
api 'org.briarproject:jtorctl:0.5'
implementation "org.bouncycastle:bcprov-jdk15to18:$bouncy_castle_version"
//noinspection GradleDependency
implementation 'com.h2database:h2:1.4.192' // The last version that supports Java 1.6
implementation 'org.bitlet:weupnp:0.1.4'
implementation 'net.i2p.crypto:eddsa:0.2.0'
implementation 'org.whispersystems:curve25519-java:0.5.0'
implementation 'org.briarproject:jtorctl:0.5'
implementation 'org.briarproject:socks-socket:0.1'
//noinspection GradleDependency
implementation "com.squareup.okhttp3:okhttp:$okhttp_version"
implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_version"
annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
testImplementation 'org.hsqldb:hsqldb:2.3.5' // The last version that supports Java 1.6
testImplementation 'net.jodah:concurrentunit:0.4.2'
testImplementation "junit:junit:$junit_version"
testImplementation "org.jmock:jmock:$jmock_version"
testImplementation "org.jmock:jmock-junit4:$jmock_version"
testImplementation "org.jmock:jmock-imposters:$jmock_version"
testImplementation "com.squareup.okhttp3:mockwebserver:4.9.3"
testImplementation "com.squareup.okhttp3:mockwebserver:$mockwebserver_version"
testAnnotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
@@ -52,7 +53,7 @@ configurations {
testOutput.extendsFrom(testCompile)
}
task jarTest(type: Jar, dependsOn: testClasses) {
from sourceSets.test.output
from sourceSets.test.output, sourceSets.main.output
classifier = 'test'
}
artifacts {

View File

@@ -17,6 +17,7 @@ import org.briarproject.bramble.lifecycle.LifecycleModule;
import org.briarproject.bramble.mailbox.MailboxModule;
import org.briarproject.bramble.plugin.PluginModule;
import org.briarproject.bramble.properties.PropertiesModule;
import org.briarproject.bramble.qrcode.QrCodeModule;
import org.briarproject.bramble.record.RecordModule;
import org.briarproject.bramble.reliability.ReliabilityModule;
import org.briarproject.bramble.rendezvous.RendezvousModule;
@@ -47,6 +48,7 @@ import dagger.Module;
MailboxModule.class,
PluginModule.class,
PropertiesModule.class,
QrCodeModule.class,
RecordModule.class,
ReliabilityModule.class,
RendezvousModule.class,

View File

@@ -4,6 +4,7 @@ import org.briarproject.nullsafety.NotNullByDefault;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
@@ -19,9 +20,10 @@ public class TimeLoggingExecutor extends ThreadPoolExecutor {
public TimeLoggingExecutor(String tag, int corePoolSize, int maxPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
super(corePoolSize, maxPoolSize, keepAliveTime, unit, workQueue,
handler);
threadFactory, handler);
log = Logger.getLogger(tag);
}

View File

@@ -19,7 +19,6 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.logging.Logger;
import javax.annotation.Nullable;
@@ -29,6 +28,7 @@ import javax.inject.Inject;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.crypto.DecryptionResult.INVALID_CIPHERTEXT;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.StringUtils.UTF_8;
import static org.briarproject.bramble.util.StringUtils.fromHexString;
import static org.briarproject.bramble.util.StringUtils.toHexString;
@@ -99,7 +99,7 @@ class AccountManagerImpl implements AccountManager {
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
new FileInputStream(f), Charset.forName("UTF-8")));
new FileInputStream(f), UTF_8));
String key = reader.readLine();
reader.close();
return key;
@@ -151,7 +151,7 @@ class AccountManagerImpl implements AccountManager {
@GuardedBy("stateChangeLock")
private void writeDbKeyToFile(String key, File f) throws IOException {
FileOutputStream out = new FileOutputStream(f);
out.write(key.getBytes(Charset.forName("UTF-8")));
out.write(key.getBytes(UTF_8));
out.flush();
out.close();
}

View File

@@ -29,7 +29,6 @@ import org.briarproject.nullsafety.NotNullByDefault;
import org.whispersystems.curve25519.Curve25519;
import org.whispersystems.curve25519.Curve25519KeyPair;
import java.nio.charset.Charset;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
@@ -51,6 +50,7 @@ import static org.briarproject.bramble.api.crypto.DecryptionResult.KEY_STRENGTHE
import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.bramble.util.StringUtils.US_ASCII;
@NotNullByDefault
class CryptoComponentImpl implements CryptoComponent {
@@ -460,7 +460,7 @@ class CryptoComponentImpl implements CryptoComponent {
@Override
public String encodeOnion(byte[] publicKey) {
Digest digest = new SHA3Digest(256);
byte[] label = ".onion checksum".getBytes(Charset.forName("US-ASCII"));
byte[] label = ".onion checksum".getBytes(US_ASCII);
digest.update(label, 0, label.length);
digest.update(publicKey, 0, publicKey.length);
digest.update(ONION_HS_PROTOCOL_VERSION);

View File

@@ -9,6 +9,7 @@ import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import javax.inject.Inject;
@@ -37,31 +38,31 @@ public class CryptoExecutorModule {
private static final int MAX_EXECUTOR_THREADS =
Math.max(1, Runtime.getRuntime().availableProcessors() - 1);
private final ExecutorService cryptoExecutor;
public CryptoExecutorModule() {
// Use an unbounded queue
BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
// Discard tasks that are submitted during shutdown
RejectedExecutionHandler policy =
new ThreadPoolExecutor.DiscardPolicy();
// Create a limited # of threads and keep them in the pool for 60 secs
cryptoExecutor = new TimeLoggingExecutor("CryptoExecutor", 0,
MAX_EXECUTOR_THREADS, 60, SECONDS, queue, policy);
}
@Provides
@Singleton
@CryptoExecutor
ExecutorService provideCryptoExecutorService(
LifecycleManager lifecycleManager) {
LifecycleManager lifecycleManager, ThreadFactory threadFactory) {
// Use an unbounded queue
BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
// Discard tasks that are submitted during shutdown
RejectedExecutionHandler policy =
new ThreadPoolExecutor.DiscardPolicy();
// Create a limited # of threads and keep them in the pool for 60 secs
ExecutorService cryptoExecutor = new TimeLoggingExecutor(
"CryptoExecutor", 0, MAX_EXECUTOR_THREADS, 60, SECONDS, queue,
threadFactory, policy);
lifecycleManager.registerForShutdown(cryptoExecutor);
return cryptoExecutor;
}
@Provides
@CryptoExecutor
Executor provideCryptoExecutor() {
Executor provideCryptoExecutor(
@CryptoExecutor ExecutorService cryptoExecutor) {
return cryptoExecutor;
}
}

View File

@@ -39,12 +39,13 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.nio.charset.Charset;
import java.security.SecureRandom;
import java.util.Scanner;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.util.StringUtils.UTF_8;
@Immutable
@NotNullByDefault
public class MessageEncrypter {
@@ -228,7 +229,7 @@ public class MessageEncrypter {
PublicKey publicKey =
encrypter.getKeyParser().parsePublicKey(keyBytes);
String message = readFully(System.in);
byte[] plaintext = message.getBytes(Charset.forName("UTF-8"));
byte[] plaintext = message.getBytes(UTF_8);
byte[] ciphertext = encrypter.encrypt(publicKey, plaintext);
System.out.println(AsciiArmour.wrap(ciphertext, LINE_LENGTH));
}
@@ -242,7 +243,7 @@ public class MessageEncrypter {
encrypter.getKeyParser().parsePrivateKey(keyBytes);
byte[] ciphertext = AsciiArmour.unwrap(readFully(System.in));
byte[] plaintext = encrypter.decrypt(privateKey, ciphertext);
System.out.println(new String(plaintext, Charset.forName("UTF-8")));
System.out.println(new String(plaintext, UTF_8));
}
private static String readFully(InputStream in) throws IOException {

View File

@@ -9,6 +9,7 @@ import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import javax.inject.Inject;
@@ -28,24 +29,20 @@ public class DatabaseExecutorModule {
ExecutorService executorService;
}
private final ExecutorService databaseExecutor;
public DatabaseExecutorModule() {
@Provides
@Singleton
@DatabaseExecutor
ExecutorService provideDatabaseExecutorService(
LifecycleManager lifecycleManager, ThreadFactory threadFactory) {
// Use an unbounded queue
BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
// Discard tasks that are submitted during shutdown
RejectedExecutionHandler policy =
new ThreadPoolExecutor.DiscardPolicy();
// Use a single thread and keep it in the pool for 60 secs
databaseExecutor = new TimeLoggingExecutor("DatabaseExecutor", 0, 1,
60, SECONDS, queue, policy);
}
@Provides
@Singleton
@DatabaseExecutor
ExecutorService provideDatabaseExecutorService(
LifecycleManager lifecycleManager) {
ExecutorService databaseExecutor = new TimeLoggingExecutor(
"DatabaseExecutor", 0, 1, 60, SECONDS, queue, threadFactory,
policy);
lifecycleManager.registerForShutdown(databaseExecutor);
return databaseExecutor;
}

View File

@@ -3,6 +3,7 @@ package org.briarproject.bramble.event;
import org.briarproject.bramble.api.event.EventExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadFactory;
import javax.inject.Singleton;
@@ -22,10 +23,11 @@ public class DefaultEventExecutorModule {
@Provides
@Singleton
@EventExecutor
Executor provideEventExecutor() {
Executor provideEventExecutor(ThreadFactory threadFactory) {
return newSingleThreadExecutor(r -> {
Thread t = new Thread(r);
Thread t = threadFactory.newThread(r);
t.setDaemon(true);
t.setName(t.getName() + "-Event");
return t;
});
}

View File

@@ -1,7 +1,5 @@
package org.briarproject.bramble.keyagreement;
import org.briarproject.bramble.api.data.BdfReaderFactory;
import org.briarproject.bramble.api.data.BdfWriterFactory;
import org.briarproject.bramble.api.keyagreement.KeyAgreementTask;
import org.briarproject.bramble.api.keyagreement.PayloadEncoder;
import org.briarproject.bramble.api.keyagreement.PayloadParser;
@@ -19,13 +17,13 @@ public class KeyAgreementModule {
}
@Provides
PayloadEncoder providePayloadEncoder(BdfWriterFactory bdfWriterFactory) {
return new PayloadEncoderImpl(bdfWriterFactory);
PayloadEncoder providePayloadEncoder(PayloadEncoderImpl payloadEncoder) {
return payloadEncoder;
}
@Provides
PayloadParser providePayloadParser(BdfReaderFactory bdfReaderFactory) {
return new PayloadParserImpl(bdfReaderFactory);
PayloadParser providePayloadParser(PayloadParserImpl payloadParser) {
return payloadParser;
}
@Provides

View File

@@ -13,7 +13,8 @@ import java.io.IOException;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.QR_FORMAT_ID;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.QR_FORMAT_VERSION;
@Immutable
@NotNullByDefault
@@ -29,7 +30,8 @@ class PayloadEncoderImpl implements PayloadEncoder {
@Override
public byte[] encode(Payload p) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(PROTOCOL_VERSION);
int formatIdAndVersion = (QR_FORMAT_ID << 5) | QR_FORMAT_VERSION;
out.write(formatIdAndVersion);
BdfWriter w = bdfWriterFactory.createWriter(out);
try {
w.writeListStart(); // Payload start

View File

@@ -1,6 +1,7 @@
package org.briarproject.bramble.keyagreement;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.Pair;
import org.briarproject.bramble.api.UnsupportedVersionException;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.data.BdfReader;
@@ -11,6 +12,9 @@ import org.briarproject.bramble.api.keyagreement.TransportDescriptor;
import org.briarproject.bramble.api.plugin.BluetoothConstants;
import org.briarproject.bramble.api.plugin.LanTcpConstants;
import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
import org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType;
import org.briarproject.bramble.api.qrcode.WrongQrCodeTypeException;
import org.briarproject.nullsafety.NotNullByDefault;
import java.io.ByteArrayInputStream;
@@ -21,34 +25,42 @@ import java.util.List;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.BETA_PROTOCOL_VERSION;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.QR_FORMAT_VERSION;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_BLUETOOTH;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_LAN;
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.BQP;
import static org.briarproject.bramble.util.StringUtils.ISO_8859_1;
@Immutable
@NotNullByDefault
class PayloadParserImpl implements PayloadParser {
private final BdfReaderFactory bdfReaderFactory;
private final QrCodeClassifier qrCodeClassifier;
@Inject
PayloadParserImpl(BdfReaderFactory bdfReaderFactory) {
PayloadParserImpl(BdfReaderFactory bdfReaderFactory,
QrCodeClassifier qrCodeClassifier) {
this.bdfReaderFactory = bdfReaderFactory;
this.qrCodeClassifier = qrCodeClassifier;
}
@Override
public Payload parse(byte[] raw) throws IOException {
ByteArrayInputStream in = new ByteArrayInputStream(raw);
// First byte: the protocol version
int protocolVersion = in.read();
if (protocolVersion == -1) throw new FormatException();
if (protocolVersion != PROTOCOL_VERSION) {
boolean tooOld = protocolVersion < PROTOCOL_VERSION ||
protocolVersion == BETA_PROTOCOL_VERSION;
public Payload parse(String payloadString) throws IOException {
Pair<QrCodeType, Integer> typeAndVersion =
qrCodeClassifier.classifyQrCode(payloadString);
QrCodeType qrCodeType = typeAndVersion.getFirst();
if (qrCodeType != BQP) throw new WrongQrCodeTypeException(qrCodeType);
int formatVersion = typeAndVersion.getSecond();
if (formatVersion != QR_FORMAT_VERSION) {
boolean tooOld = formatVersion < QR_FORMAT_VERSION;
throw new UnsupportedVersionException(tooOld);
}
byte[] raw = payloadString.getBytes(ISO_8859_1);
ByteArrayInputStream in = new ByteArrayInputStream(raw);
// First byte: the format identifier and version (already parsed)
if (in.read() == -1) throw new AssertionError();
// The rest of the payload is a BDF list with one or more elements
BdfReader r = bdfReaderFactory.createReader(in);
BdfList payload = r.readList();

View File

@@ -9,6 +9,7 @@ import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import javax.inject.Inject;
@@ -28,19 +29,6 @@ public class LifecycleModule {
Executor executor;
}
private final ExecutorService ioExecutor;
public LifecycleModule() {
// The thread pool is unbounded, so use direct handoff
BlockingQueue<Runnable> queue = new SynchronousQueue<>();
// Discard tasks that are submitted during shutdown
RejectedExecutionHandler policy =
new ThreadPoolExecutor.DiscardPolicy();
// Create threads as required and keep them in the pool for 60 seconds
ioExecutor = new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60, SECONDS, queue, policy);
}
@Provides
@Singleton
ShutdownManager provideShutdownManager() {
@@ -57,7 +45,16 @@ public class LifecycleModule {
@Provides
@Singleton
@IoExecutor
Executor provideIoExecutor(LifecycleManager lifecycleManager) {
Executor provideIoExecutor(LifecycleManager lifecycleManager,
ThreadFactory threadFactory) {
// The thread pool is unbounded, so use direct handoff
BlockingQueue<Runnable> queue = new SynchronousQueue<>();
// Discard tasks that are submitted during shutdown
RejectedExecutionHandler policy =
new ThreadPoolExecutor.DiscardPolicy();
// Create threads as required and keep them in the pool for 60 seconds
ExecutorService ioExecutor = new ThreadPoolExecutor(0,
Integer.MAX_VALUE, 60, SECONDS, queue, threadFactory, policy);
lifecycleManager.registerForShutdown(ioExecutor);
return ioExecutor;
}

View File

@@ -20,12 +20,15 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS;
class MailboxApiCallerImpl implements MailboxApiCaller {
private final TaskScheduler taskScheduler;
private final MailboxConfig mailboxConfig;
private final Executor ioExecutor;
@Inject
MailboxApiCallerImpl(TaskScheduler taskScheduler,
MailboxConfig mailboxConfig,
@IoExecutor Executor ioExecutor) {
this.taskScheduler = taskScheduler;
this.mailboxConfig = mailboxConfig;
this.ioExecutor = ioExecutor;
}
@@ -49,7 +52,8 @@ class MailboxApiCallerImpl implements MailboxApiCaller {
private boolean cancelled = false;
@GuardedBy("lock")
private long retryIntervalMs = MIN_RETRY_INTERVAL_MS;
private long retryIntervalMs =
mailboxConfig.getApiCallerMinRetryInterval();
private Task(ApiCall apiCall) {
this.apiCall = apiCall;
@@ -74,8 +78,9 @@ class MailboxApiCallerImpl implements MailboxApiCaller {
scheduledTask = taskScheduler.schedule(this::callApi,
ioExecutor, retryIntervalMs, MILLISECONDS);
// Increase the retry interval each time we retry
retryIntervalMs =
min(MAX_RETRY_INTERVAL_MS, retryIntervalMs * 2);
retryIntervalMs = min(
mailboxConfig.getApiCallerMaxRetryInterval(),
retryIntervalMs * 2);
}
} else {
synchronized (lock) {

View File

@@ -0,0 +1,24 @@
package org.briarproject.bramble.mailbox;
import org.briarproject.bramble.api.plugin.Plugin;
interface MailboxConfig {
/**
* The minimum interval between API call retries in milliseconds.
*/
long getApiCallerMinRetryInterval();
/**
* The maximum interval between API call retries in milliseconds.
*/
long getApiCallerMaxRetryInterval();
/**
* How long (in milliseconds) the Tor plugin needs to be continuously
* {@link Plugin.State#ACTIVE active} before we assume our contacts can
* reach our hidden service.
*/
long getTorReachabilityPeriod();
}

View File

@@ -0,0 +1,30 @@
package org.briarproject.bramble.mailbox;
import org.briarproject.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
@Immutable
@NotNullByDefault
class MailboxConfigImpl implements MailboxConfig {
@Inject
MailboxConfigImpl() {
}
@Override
public long getApiCallerMinRetryInterval() {
return MailboxApiCaller.MIN_RETRY_INTERVAL_MS;
}
@Override
public long getApiCallerMaxRetryInterval() {
return MailboxApiCaller.MAX_RETRY_INTERVAL_MS;
}
@Override
public long getTorReachabilityPeriod() {
return TorReachabilityMonitor.REACHABILITY_PERIOD_MS;
}
}

View File

@@ -6,6 +6,7 @@ import org.briarproject.bramble.api.event.EventExecutor;
import org.briarproject.bramble.api.mailbox.MailboxPairingTask;
import org.briarproject.bramble.api.mailbox.MailboxSettingsManager;
import org.briarproject.bramble.api.mailbox.MailboxUpdateManager;
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.nullsafety.NotNullByDefault;
@@ -25,6 +26,7 @@ class MailboxPairingTaskFactoryImpl implements MailboxPairingTaskFactory {
private final MailboxApi api;
private final MailboxSettingsManager mailboxSettingsManager;
private final MailboxUpdateManager mailboxUpdateManager;
private final QrCodeClassifier qrCodeClassifier;
@Inject
MailboxPairingTaskFactoryImpl(
@@ -34,7 +36,8 @@ class MailboxPairingTaskFactoryImpl implements MailboxPairingTaskFactory {
Clock clock,
MailboxApi api,
MailboxSettingsManager mailboxSettingsManager,
MailboxUpdateManager mailboxUpdateManager) {
MailboxUpdateManager mailboxUpdateManager,
QrCodeClassifier qrCodeClassifier) {
this.eventExecutor = eventExecutor;
this.db = db;
this.crypto = crypto;
@@ -42,12 +45,13 @@ class MailboxPairingTaskFactoryImpl implements MailboxPairingTaskFactory {
this.api = api;
this.mailboxSettingsManager = mailboxSettingsManager;
this.mailboxUpdateManager = mailboxUpdateManager;
this.qrCodeClassifier = qrCodeClassifier;
}
@Override
public MailboxPairingTask createPairingTask(String qrCodePayload) {
return new MailboxPairingTaskImpl(qrCodePayload, eventExecutor, db,
crypto, clock, api, mailboxSettingsManager,
mailboxUpdateManager);
mailboxUpdateManager, qrCodeClassifier);
}
}

View File

@@ -2,6 +2,7 @@ package org.briarproject.bramble.mailbox;
import org.briarproject.bramble.api.Consumer;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.Pair;
import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.db.DatabaseComponent;
@@ -9,18 +10,26 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.event.EventExecutor;
import org.briarproject.bramble.api.mailbox.MailboxAuthToken;
import org.briarproject.bramble.api.mailbox.MailboxPairingState;
import org.briarproject.bramble.api.mailbox.MailboxPairingState.ConnectionError;
import org.briarproject.bramble.api.mailbox.MailboxPairingState.InvalidQrCode;
import org.briarproject.bramble.api.mailbox.MailboxPairingState.MailboxAlreadyPaired;
import org.briarproject.bramble.api.mailbox.MailboxPairingState.Paired;
import org.briarproject.bramble.api.mailbox.MailboxPairingState.Pairing;
import org.briarproject.bramble.api.mailbox.MailboxPairingState.QrCodeReceived;
import org.briarproject.bramble.api.mailbox.MailboxPairingState.UnexpectedError;
import org.briarproject.bramble.api.mailbox.MailboxPairingTask;
import org.briarproject.bramble.api.mailbox.MailboxProperties;
import org.briarproject.bramble.api.mailbox.MailboxSettingsManager;
import org.briarproject.bramble.api.mailbox.MailboxUpdate;
import org.briarproject.bramble.api.mailbox.MailboxUpdateManager;
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
import org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.mailbox.MailboxApi.ApiException;
import org.briarproject.bramble.mailbox.MailboxApi.MailboxAlreadyPairedException;
import org.briarproject.nullsafety.NotNullByDefault;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -32,7 +41,10 @@ import javax.annotation.concurrent.ThreadSafe;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.mailbox.MailboxConstants.QR_FORMAT_VERSION;
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.MAILBOX;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.StringUtils.ISO_8859_1;
@ThreadSafe
@NotNullByDefault
@@ -40,9 +52,6 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
private final static Logger LOG =
getLogger(MailboxPairingTaskImpl.class.getName());
@SuppressWarnings("CharsetObjectCanBeUsed") // Requires minSdkVersion >= 19
private static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
private static final int VERSION_REQUIRED = 32;
private final String payload;
private final Executor eventExecutor;
@@ -52,6 +61,8 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
private final MailboxApi api;
private final MailboxSettingsManager mailboxSettingsManager;
private final MailboxUpdateManager mailboxUpdateManager;
private final QrCodeClassifier qrCodeClassifier;
private final long timeStarted;
private final Object lock = new Object();
@GuardedBy("lock")
@@ -68,7 +79,8 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
Clock clock,
MailboxApi api,
MailboxSettingsManager mailboxSettingsManager,
MailboxUpdateManager mailboxUpdateManager) {
MailboxUpdateManager mailboxUpdateManager,
QrCodeClassifier qrCodeClassifier) {
this.payload = payload;
this.eventExecutor = eventExecutor;
this.db = db;
@@ -77,7 +89,9 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
this.api = api;
this.mailboxSettingsManager = mailboxSettingsManager;
this.mailboxUpdateManager = mailboxUpdateManager;
state = new MailboxPairingState.QrCodeReceived();
this.qrCodeClassifier = qrCodeClassifier;
timeStarted = clock.currentTimeMillis();
state = new QrCodeReceived(timeStarted);
}
@Override
@@ -99,22 +113,30 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
@Override
public void run() {
Pair<QrCodeType, Integer> typeAndVersion =
qrCodeClassifier.classifyQrCode(payload);
QrCodeType qrCodeType = typeAndVersion.getFirst();
int formatVersion = typeAndVersion.getSecond();
if (qrCodeType != MAILBOX || formatVersion != QR_FORMAT_VERSION) {
setState(new InvalidQrCode(qrCodeType, formatVersion));
return;
}
try {
pairMailbox();
} catch (FormatException e) {
onMailboxError(e, new MailboxPairingState.InvalidQrCode());
onMailboxError(e, new InvalidQrCode(qrCodeType, formatVersion));
} catch (MailboxAlreadyPairedException e) {
onMailboxError(e, new MailboxPairingState.MailboxAlreadyPaired());
onMailboxError(e, new MailboxAlreadyPaired());
} catch (IOException e) {
onMailboxError(e, new MailboxPairingState.ConnectionError());
onMailboxError(e, new ConnectionError());
} catch (ApiException | DbException e) {
onMailboxError(e, new MailboxPairingState.UnexpectedError());
onMailboxError(e, new UnexpectedError());
}
}
private void pairMailbox() throws IOException, ApiException, DbException {
MailboxProperties mailboxProperties = decodeQrCodePayload(payload);
setState(new MailboxPairingState.Pairing());
setState(new Pairing(timeStarted));
MailboxProperties ownerProperties = api.setup(mailboxProperties);
long time = clock.currentTimeMillis();
db.transaction(false, txn -> {
@@ -133,7 +155,7 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
}
}
});
setState(new MailboxPairingState.Paired());
setState(new Paired());
}
private void onMailboxError(Exception e, MailboxPairingState state) {
@@ -167,14 +189,6 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
}
throw new FormatException();
}
int version = bytes[0] & 0xFF;
if (version != VERSION_REQUIRED) {
if (LOG.isLoggable(WARNING)) {
LOG.warning("QR code has not version " + VERSION_REQUIRED +
": " + version);
}
throw new FormatException();
}
LOG.info("QR code is valid");
byte[] onionPubKey = Arrays.copyOfRange(bytes, 1, 33);
String onion = crypto.encodeOnion(onionPubKey);

View File

@@ -4,7 +4,11 @@ import dagger.Module;
import dagger.Provides;
@Module
public class UrlConverterModule {
public class ModularMailboxModule {
@Provides
MailboxConfig provideMailboxConfig(MailboxConfigImpl mailboxConfig) {
return mailboxConfig;
}
@Provides
UrlConverter provideUrlConverter(UrlConverterImpl urlConverter) {

View File

@@ -32,6 +32,7 @@ class TorReachabilityMonitorImpl
private final Executor ioExecutor;
private final TaskScheduler taskScheduler;
private final MailboxConfig mailboxConfig;
private final PluginManager pluginManager;
private final EventBus eventBus;
private final Object lock = new Object();
@@ -50,10 +51,12 @@ class TorReachabilityMonitorImpl
TorReachabilityMonitorImpl(
@IoExecutor Executor ioExecutor,
TaskScheduler taskScheduler,
MailboxConfig mailboxConfig,
PluginManager pluginManager,
EventBus eventBus) {
this.ioExecutor = ioExecutor;
this.taskScheduler = taskScheduler;
this.mailboxConfig = mailboxConfig;
this.pluginManager = pluginManager;
this.eventBus = eventBus;
}
@@ -110,7 +113,7 @@ class TorReachabilityMonitorImpl
synchronized (lock) {
if (destroyed || task != null) return;
task = taskScheduler.schedule(this::onTorReachable, ioExecutor,
REACHABILITY_PERIOD_MS, MILLISECONDS);
mailboxConfig.getTorReachabilityPeriod(), MILLISECONDS);
}
}

View File

@@ -89,6 +89,17 @@ abstract class AbstractBluetoothPlugin<S, SS> implements BluetoothPlugin,
private volatile String contactConnectionsUuid = null;
/**
* Override and return true, if the plugin is now allowed to access the
* Bluetooth hardware.
* If this returns false, the plugin must be
* {@link org.briarproject.bramble.api.plugin.Plugin.State#DISABLED}
* in {@link #start()} and not attempt to access Bluetooth hardware.
*/
protected boolean isBluetoothAccessible() {
return true;
}
abstract void initialiseAdapter() throws IOException;
abstract boolean isAdapterEnabled();
@@ -176,19 +187,28 @@ abstract class AbstractBluetoothPlugin<S, SS> implements BluetoothPlugin,
DEFAULT_PREF_PLUGIN_ENABLE);
everConnected.set(settings.getBoolean(PREF_EVER_CONNECTED,
DEFAULT_PREF_EVER_CONNECTED));
// disable plugin, if conditions for enabling are not met
if (enabledByUser && !isBluetoothAccessible()) {
enabledByUser = false;
settings.putBoolean(PREF_PLUGIN_ENABLE, false);
callback.mergeSettings(settings);
}
state.setStarted(enabledByUser);
try {
initialiseAdapter();
} catch (IOException e) {
throw new PluginException(e);
}
updateProperties();
if (enabledByUser && isAdapterEnabled()) bind();
if (enabledByUser) {
updateProperties();
if (isAdapterEnabled()) bind();
}
}
private void bind() {
ioExecutor.execute(() -> {
if (getState() != INACTIVE) return;
if (contactConnectionsUuid == null) updateProperties();
// Bind a server socket to accept connections from contacts
SS ss;
try {
@@ -534,7 +554,8 @@ abstract class AbstractBluetoothPlugin<S, SS> implements BluetoothPlugin,
private void onSettingsUpdated(Settings settings) {
boolean enabledByUser = settings.getBoolean(PREF_PLUGIN_ENABLE,
DEFAULT_PREF_PLUGIN_ENABLE);
SS ss = state.setEnabledByUser(enabledByUser);
boolean shouldEnable = enabledByUser && isBluetoothAccessible();
SS ss = state.setEnabledByUser(shouldEnable);
State s = getState();
if (ss != null) {
LOG.info("Disabled by user, closing server socket");

View File

@@ -21,9 +21,6 @@ import static org.briarproject.bramble.plugin.tor.CircumventionProvider.BridgeTy
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.BridgeType.NON_DEFAULT_OBFS4;
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.BridgeType.SNOWFLAKE;
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.BridgeType.VANILLA;
import static org.briarproject.bramble.plugin.tor.CircumventionProviderImpl.SnowflakeBroker.AMP_CACHE;
import static org.briarproject.bramble.plugin.tor.CircumventionProviderImpl.SnowflakeBroker.AZURE;
import static org.briarproject.bramble.plugin.tor.CircumventionProviderImpl.SnowflakeBroker.FASTLY;
import static org.briarproject.nullsafety.NullSafety.requireNonNull;
@Immutable
@@ -45,20 +42,6 @@ class CircumventionProviderImpl implements CircumventionProvider {
private static final Set<String> DPI_COUNTRIES =
new HashSet<>(asList(DPI_BRIDGES));
// Package access for testing
enum SnowflakeBroker {
FASTLY('F'),
AZURE('A'),
AMP_CACHE('M');
private final char value;
SnowflakeBroker(char value) {
this.value = value;
}
}
@Inject
CircumventionProviderImpl() {
}
@@ -103,17 +86,7 @@ class CircumventionProviderImpl implements CircumventionProvider {
(type == MEEK && line.startsWith("m "))) {
bridges.add(line.substring(2));
} else if (type == SNOWFLAKE && line.startsWith("s ")) {
String params;
// If the client can verify Let's Encrypt certificates then
// use the Fastly broker, otherwise use Azure
if (letsEncrypt) {
params = getSnowflakeParams(countryCode, FASTLY);
} else {
params = getSnowflakeParams(countryCode, AZURE);
}
bridges.add(line.substring(2) + " " + params);
// Also use the AMP cache broker
params = getSnowflakeParams(countryCode, AMP_CACHE);
String params = getSnowflakeParams(countryCode, letsEncrypt);
bridges.add(line.substring(2) + " " + params);
}
}
@@ -122,14 +95,15 @@ class CircumventionProviderImpl implements CircumventionProvider {
}
// Package access for testing
String getSnowflakeParams(String countryCode, SnowflakeBroker broker) {
@SuppressWarnings("WeakerAccess")
String getSnowflakeParams(String countryCode, boolean letsEncrypt) {
Map<String, String> params = loadSnowflakeParams();
if (countryCode.isEmpty()) countryCode = DEFAULT_COUNTRY_CODE;
// If we have parameters for this country code, return them
String value = params.get(makeKey(countryCode, broker));
String value = params.get(makeKey(countryCode, letsEncrypt));
if (value != null) return value;
// Return the default parameters
value = params.get(makeKey(DEFAULT_COUNTRY_CODE, broker));
value = params.get(makeKey(DEFAULT_COUNTRY_CODE, letsEncrypt));
return requireNonNull(value);
}
@@ -141,7 +115,7 @@ class CircumventionProviderImpl implements CircumventionProvider {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.length() < 5) continue;
String key = line.substring(0, 4); // Country code, space, broker
String key = line.substring(0, 4); // Country code, space, digit
String value = line.substring(5);
params.put(key, value);
}
@@ -149,7 +123,7 @@ class CircumventionProviderImpl implements CircumventionProvider {
return params;
}
private String makeKey(String countryCode, SnowflakeBroker broker) {
return countryCode + " " + broker.value;
private String makeKey(String countryCode, boolean letsEncrypt) {
return countryCode + " " + (letsEncrypt ? "1" : "0");
}
}

View File

@@ -46,7 +46,6 @@ import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -100,6 +99,7 @@ import static org.briarproject.bramble.util.IoUtils.copyAndClose;
import static org.briarproject.bramble.util.IoUtils.tryToClose;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubOnion;
import static org.briarproject.bramble.util.StringUtils.UTF_8;
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
@MethodsNotNullByDefault
@@ -140,7 +140,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private final long maxLatency;
private final int maxIdleTime;
private final int socketTimeout;
private final File torDirectory, geoIpFile, configFile;
private final File torDirectory;
private final File configFile;
private final int torSocksPort;
private final int torControlPort;
private final File doneFile, cookieFile;
@@ -195,7 +196,6 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
this.torDirectory = torDirectory;
this.torSocksPort = torSocksPort;
this.torControlPort = torControlPort;
geoIpFile = new File(torDirectory, "geoip");
configFile = new File(torDirectory, "torrc");
doneFile = new File(torDirectory, "done");
cookieFile = new File(torDirectory, ".tor/control_auth_cookie");
@@ -332,12 +332,6 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
// The done file may already exist from a previous installation
//noinspection ResultOfMethodCallIgnored
doneFile.delete();
// The GeoIP file may exist from a previous installation - we can
// save some space by deleting it.
// TODO: Remove after a reasonable migration period
// (added 2022-03-29)
//noinspection ResultOfMethodCallIgnored
geoIpFile.delete();
installTorExecutable();
installObfs4Executable();
installSnowflakeExecutable();
@@ -419,9 +413,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
append(strb, "ClientTransportPlugin meek_lite exec", obfs4Path);
String snowflakePath = getSnowflakeExecutableFile().getAbsolutePath();
append(strb, "ClientTransportPlugin snowflake exec", snowflakePath);
//noinspection CharsetObjectCanBeUsed
return new ByteArrayInputStream(
strb.toString().getBytes(Charset.forName("UTF-8")));
return new ByteArrayInputStream(strb.toString().getBytes(UTF_8));
}
private void listFiles(File f) {
@@ -811,7 +803,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
@Override
public void controlConnectionClosed() {
if (state.isTorRunning()) {
throw new RuntimeException("Control connection closed");
// TODO: Restart the Tor process
LOG.warning("Control connection closed");
}
}

View File

@@ -7,7 +7,7 @@ import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
import org.bouncycastle.util.encoders.Base64;
import org.briarproject.bramble.api.crypto.CryptoComponent;
import java.nio.charset.Charset;
import static org.briarproject.bramble.util.StringUtils.US_ASCII;
class TorRendezvousCryptoImpl implements TorRendezvousCrypto {
@@ -31,6 +31,6 @@ class TorRendezvousCryptoImpl implements TorRendezvousCrypto {
EdDSAPrivateKeySpec spec = new EdDSAPrivateKeySpec(seed, CURVE_SPEC);
byte[] hash = spec.getH();
byte[] base64 = Base64.encode(hash);
return "ED25519-V3:" + new String(base64, Charset.forName("US-ASCII"));
return "ED25519-V3:" + new String(base64, US_ASCII);
}
}

View File

@@ -0,0 +1,42 @@
package org.briarproject.bramble.qrcode;
import org.briarproject.bramble.api.Pair;
import org.briarproject.bramble.api.keyagreement.KeyAgreementConstants;
import org.briarproject.bramble.api.mailbox.MailboxConstants;
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
import org.briarproject.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.BQP;
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.MAILBOX;
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.UNKNOWN;
import static org.briarproject.bramble.util.StringUtils.ISO_8859_1;
@Immutable
@NotNullByDefault
class QrCodeClassifierImpl implements QrCodeClassifier {
@Inject
QrCodeClassifierImpl() {
}
@Override
public Pair<QrCodeType, Integer> classifyQrCode(String payload) {
byte[] bytes = payload.getBytes(ISO_8859_1);
if (bytes.length == 0) return new Pair<>(UNKNOWN, 0);
// If this is a Bramble QR code then the first byte encodes the
// format ID (3 bits) and version (5 bits)
int formatIdAndVersion = bytes[0] & 0xFF;
int formatId = formatIdAndVersion >> 5;
int formatVersion = formatIdAndVersion & 0x1F;
if (formatId == KeyAgreementConstants.QR_FORMAT_ID) {
return new Pair<>(BQP, formatVersion);
}
if (formatId == MailboxConstants.QR_FORMAT_ID) {
return new Pair<>(MAILBOX, formatVersion);
}
return new Pair<>(UNKNOWN, 0);
}
}

View File

@@ -0,0 +1,16 @@
package org.briarproject.bramble.qrcode;
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
import dagger.Module;
import dagger.Provides;
@Module
public class QrCodeModule {
@Provides
QrCodeClassifier provideQrCodeClassifier(
QrCodeClassifierImpl qrCodeClassifier) {
return qrCodeClassifier;
}
}

View File

@@ -6,6 +6,7 @@ import org.briarproject.bramble.api.system.TaskScheduler;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -21,18 +22,15 @@ public class DefaultTaskSchedulerModule {
TaskScheduler scheduler;
}
private final ScheduledExecutorService scheduledExecutorService;
public DefaultTaskSchedulerModule() {
@Provides
@Singleton
TaskScheduler provideTaskScheduler(LifecycleManager lifecycleManager,
ThreadFactory threadFactory) {
// Discard tasks that are submitted during shutdown
RejectedExecutionHandler policy =
new ScheduledThreadPoolExecutor.DiscardPolicy();
scheduledExecutorService = new ScheduledThreadPoolExecutor(1, policy);
}
@Provides
@Singleton
TaskScheduler provideTaskScheduler(LifecycleManager lifecycleManager) {
ScheduledExecutorService scheduledExecutorService =
new ScheduledThreadPoolExecutor(1, threadFactory, policy);
lifecycleManager.registerForShutdown(scheduledExecutorService);
return new TaskSchedulerImpl(scheduledExecutorService);
}

View File

@@ -0,0 +1,18 @@
package org.briarproject.bramble.system;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@Module
public class DefaultThreadFactoryModule {
@Provides
@Singleton
ThreadFactory provideThreadFactory() {
return Executors.defaultThreadFactory();
}
}

View File

@@ -228,15 +228,11 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
Contact contact = db.getContact(txn, c);
callVisibilityHooks(txn, contact, before, after);
}
// Broadcast events for any new client versions
Set<ClientVersion> oldRemoteVersions = new HashSet<>();
for (ClientState cs : oldRemoteStates) {
oldRemoteVersions.add(cs.clientVersion);
}
// Broadcast events for any client version update
for (ClientState cs : newRemoteStates) {
if (!oldRemoteVersions.contains(cs.clientVersion)) {
txn.attach(new ClientVersionUpdatedEvent(c,
cs.clientVersion));
if (!oldRemoteStates.contains(cs)) {
txn.attach(
new ClientVersionUpdatedEvent(c, cs.clientVersion));
}
}
} catch (FormatException e) {

View File

@@ -1,6 +1,4 @@
d Bridge obfs4 192.95.36.142:443 CDF2E852BF539B82BD10E27E9115A31734E378C2 cert=qUVQ0srL1JI/vO6V6m/24anYXiJD3QP2HgzUKQtQ7GRqqUvs7P+tG43RtAqdhLOALP7DJQ iat-mode=1
d Bridge obfs4 38.229.1.78:80 C8CBDB2464FC9804A69531437BCF2BE31FDD2EE4 cert=Hmyfd2ev46gGY7NoVxA9ngrPF2zCZtzskRTzoWXbxNkzeVnGFPWmrTtILRyqCTjHR+s9dg iat-mode=1
d Bridge obfs4 38.229.33.83:80 0BAC39417268B96B9F514E7F63FA6FBA1A788955 cert=VwEFpk9F/UN9JED7XpG1XOjm/O8ZCXK80oPecgWnNDZDv5pdkhq1OpbAH0wNqOT6H6BmRQ iat-mode=1
d Bridge obfs4 37.218.245.14:38224 D9A82D2F9C2F65A18407B1D2B764F130847F8B5D cert=bjRaMrr1BRiAW8IE9U5z27fQaYgOhX1UCmOpg2pFpoMvo6ZgQMzLsaTzzQNTlm7hNcb+Sg iat-mode=0
d Bridge obfs4 85.31.186.98:443 011F2599C0E9B27EE74B353155E244813763C3E5 cert=ayq0XzCwhpdysn5o0EyDUbmSOx3X/oTEbzDMvczHOdBJKlvIdHHLJGkZARtT4dcBFArPPg iat-mode=0
d Bridge obfs4 85.31.186.26:443 91A6354697E6B02A386312F68D82CF86824D3606 cert=PBwr+S8JTVZo6MPdHnkTwXJPILWADLqfMGoVvhZClMq/Urndyd42BwX9YFJHZnBB3H0XCw iat-mode=0
@@ -15,22 +13,24 @@ n Bridge obfs4 185.181.11.86:443 A961609729E7FDF520B4E81F1F1B8FA1045285C3 cert=e
n Bridge obfs4 93.95.226.151:41185 460B0CFFC0CF1D965F3DE064E08BA1915E7C916A cert=inluPzp5Jp5OzZar1eQb4dcQ/YlAj/v0kHAUCoCr3rmLt03+pVuVTjoH4mRy4+acXpn+Gw iat-mode=0
n Bridge obfs4 120.29.217.52:5223 40FE3DB9800272F9CDC76422F8ED7883280EE96D cert=/71PS4l8c/XJ4DIItlH9xMqNvPFg2RUTrHvPlQWh48u5et8h/yyyjCcYphUadDsfBWpaGQ iat-mode=0
n Bridge obfs4 185.177.207.138:8443 53716FE26F23C8C6A71A2BC5D9D8DC64747278C7 cert=6jcYVilMEzxdsWghSrQFpYYJlkkir/GPIXw/EnddUK3S8ToVpMG8u1SwMOEdEs735RrMHw iat-mode=0
n Bridge obfs4 87.121.72.109:9002 C8081D4731C953FA4AE166946E72B29153351E34 cert=bikAqxKV6Ch5gFCBTdPI28VeShYa1ZgkLmvc7YZNLWFsFZoaCULL/3AQKjpIfvSiJs5jGQ iat-mode=0
n Bridge obfs4 70.34.249.113:443 F441B16ABB1055794C2CE01821FC05047B2C8CFC cert=MauLNoyq8EwjY4Qe0oASYzs2hXdSjNgy+BtP9oo1naHhRsyKTtAZzeNv08RnzWjMJrTwcg iat-mode=0
n Bridge obfs4 104.168.68.90:443 ED55B3C321E44EA7E50EF568C8A63CF75E89A58C cert=fgonxDvltTp8nmcOE9sUG94eOAALxETVVXAwnTZJLPpf7rjPuTp+abKl4VyFkxfcLRr5KQ iat-mode=0
n Bridge obfs4 158.247.207.151:443 6170ADBBB6C1859A8E7E4416BB8AB3AF471AE47F cert=Od4izlwLnXcq7LMSOJtnZLtklaUn+X+gPcBwN7RUEkk9rqxRRYNHW7as8g6+jheDsazxAQ iat-mode=0
n Bridge obfs4 45.142.181.131:42069 6EBCF6B02DA2B982F4080A7119D737366AFB74FA cert=9HyWH/BCwWzNirZdTQtluCgJk+gFhpOqydIuyQ1iDvpnqsAynKF+zcPE/INZFefm86UlBg iat-mode=0
n Bridge obfs4 85.214.28.204:47111 78A36E46BB082A471848239D3F4390A8F8C6084D cert=96sr3eaUFBDu4wFVAQIfNFElh0UNuutJ/3/Fh2Vu2PHfacQ8bwfY02bwG351U8BZpLnfUQ iat-mode=0
n Bridge obfs4 152.67.77.101:4096 B82DB9CDDF887AB8A859420E07DF298E30AF8A6E cert=21OWn3yFo+hulmQNAOtF5uwwOqWtdT5PrLhk8BG9DpOd0/k5DEkQEYPyDdXbS9nZ0E5BJA iat-mode=0
n Bridge obfs4 82.39.132.97:6969 F505EF4C41C77FFDC0C440C122A02129FBE25823 cert=bwNWuL7UYB9aiKajE1gkffylYx/EM4FjSZxIJ0pVT/xaR21xXlIdaXw7l+EYmC4nVIh2HQ iat-mode=0
n Bridge obfs4 185.103.252.72:443 75F15E9339FF572F88F5588D429FEA379744BC53 cert=nOZ/SaRE3L1dChvjfe0Ks/wM/F8iFhwd3g2G5zgtcLB8x+wiZRWCwjRrbbiQyb3Gh2mxRQ iat-mode=0
n Bridge obfs4 185.177.207.13:22662 928C1E4289A01F34C8FB423FC32C0E77EE0F8736 cert=p9L6+25s8bnfkye1ZxFeAE4mAGY7DH4Gaj7dxngIIzP9BtqrHHwZXdjMK0RVIQ34C7aqZw iat-mode=2
n Bridge obfs4 207.181.229.55:40132 37FE8D782F5DD2BAEEDAAB8257B701344676B6DD cert=f5Hbfn3ToMzH170cV8DfLly3vRynveidfOfDcbradIDtbLDX15V2yQ8eEH2CPKQJmQR2Hg iat-mode=0
n Bridge obfs4 76.255.201.112:8888 96CF36C2ECCFB7376AB6BE905BECD2C2AE8AEFCD cert=+q0pjaiM0JMqHL/BKqCRD+pjflaw/S406eUDF7CnFgamvQW3l2HVLJhQ6uX9P8zff0PLGg iat-mode=0
n Bridge obfs4 94.142.246.132:8088 135C158527AA9FE9A2F26EC515EB6999D813D347 cert=wTUz0/5FhAZRkitil5MprGbSF3JzjxjxI1kAmxAdSeDy98NgcLr11f/qUXWDC76Y97RiSg iat-mode=0
n Bridge obfs4 20.102.79.78:22022 B5705F7E616DAB0F477E3E1ADC23E40413F683FE cert=1Cc/hwPtPjzFKGHVOP0j/qmBgnvquRx8+im35/u5TIYjDQ3FlMfA5VvTrQ/hbX8BZZooLQ iat-mode=0
n Bridge obfs4 152.70.180.20:1993 3327C43587E66AD5F874C4234A1D72C938AD7318 cert=s7xLRUO2psaX7TMUP2YhXdxItR4U6K7D+E3gQaS/+yWUppevtazIibq4dN1g5Reu6dD2QQ iat-mode=0
n Bridge obfs4 144.202.12.254:10002 4E220F45CD404C8A3082A36326A5ED19BB8D4404 cert=iLz5YYWO4pUw7U7MRNOSvE0qO+IVeE4kVfFVWPO3coH3FmZtrkvlaTklfXxHZaCcXWBgaA iat-mode=0
n Bridge obfs4 109.14.168.159:5082 BFE1416DEFFE969581F016A4A319A87FFB26BA91 cert=n3X1CDdKBPXPIzfKh83p3ydfMzb0AD9gKC+/gIpHb7+xjjAnYO9x3LT+T/MvOIfAXxYySg iat-mode=0
n Bridge obfs4 45.150.172.16:80 82849E69CBB25EA7F479155F7DCD89D85717FF47 cert=+Krdu1jmVQOxWkMj0mqJHgwbQV49eyD6mZDS+mRExssWNHosa60g4P5Gp81sBJKzN8NrSw iat-mode=0
n Bridge obfs4 185.177.207.132:8443 4FB781F7A9DD39DA53A7996907817FC479874D19 cert=UL2gCAXWW5kEWY4TQ0lNeu6OAmzh40bXYVhMnTWVG8USnyy/zEKGSIPgmwTDMumWr9c1Pg iat-mode=0
v Bridge 92.243.15.235:9001 477EAD3C04036B48235F1F27FC91420A286A4B7F
v Bridge 213.108.108.145:17674 A39C0FE47963B6E8CFE9815549864DE544935A31
v Bridge 185.189.195.124:8199 A1F3EE78F9C2343668E68FEB84358A4C742831A5
v Bridge 213.196.191.96:9060 05E222E2A8C234234FE0CEB58B08A93B8FC360DB
v Bridge 75.100.92.154:22815 465E990FA8A752DDE861EDF31E42454ACC037AB4
m Bridge meek_lite 192.0.2.2:80 97700DFE9F483596DDA6264C4D7DF7641E1E39CE url=https://meek.azureedge.net/ front=ajax.aspnetcdn.com
v Bridge 87.100.193.2:9010 13FB63452AADFA082BD2BC3E1E320AD301F07877
v Bridge 65.21.240.163:33245 20BD59649212CFE7412BFC9B94C3CCCFD8F807A8
m Bridge meek_lite 192.0.2.18:80 BE776A53492E1E044A26F17306E1BC46A55A1625 url=https://meek.azureedge.net/ front=ajax.aspnetcdn.com utls=hellochrome_auto
s Bridge snowflake 192.0.2.3:80 2B280B23E1107BB62ABFC40DDCC8824814F80A72

View File

@@ -1,6 +1,4 @@
ZZ F url=https://snowflake-broker.torproject.net.global.prod.fastly.net/ front=cdn.sstatic.net ice=stun:stun.l.google.com:19302,stun:stun.voip.blackberry.com:3478,stun:stun.altar.com.pl:3478,stun:stun.antisip.com:3478,stun:stun.bluesip.net:3478,stun:stun.dus.net:3478,stun:stun.epygi.com:3478,stun:stun.sonetel.com:3478,stun:stun.sonetel.net:3478,stun:stun.stunprotocol.org:3478,stun:stun.uls.co.za:3478,stun:stun.voipgate.com:3478,stun:stun.voys.nl:3478
ZZ A url=https://snowflake-broker.azureedge.net/ front=ajax.aspnetcdn.com ice=stun:stun.l.google.com:19302,stun:stun.voip.blackberry.com:3478,stun:stun.altar.com.pl:3478,stun:stun.antisip.com:3478,stun:stun.bluesip.net:3478,stun:stun.dus.net:3478,stun:stun.epygi.com:3478,stun:stun.sonetel.com:3478,stun:stun.sonetel.net:3478,stun:stun.stunprotocol.org:3478,stun:stun.uls.co.za:3478,stun:stun.voipgate.com:3478,stun:stun.voys.nl:3478
ZZ M url=https://snowflake-broker.torproject.net/ ampcache=https://cdn.ampproject.org/ front=cdn.ampproject.org ice=stun:stun.voip.blackberry.com:3478,stun:stun.altar.com.pl:3478,stun:stun.antisip.com:3478,stun:stun.bluesip.net:3478,stun:stun.dus.net:3478,stun:stun.epygi.com:3478,stun:stun.sonetel.com:3478,stun:stun.sonetel.net:3478,stun:stun.stunprotocol.org:3478,stun:stun.uls.co.za:3478,stun:stun.voipgate.com:3478,stun:stun.voys.nl:3478
TM F url=https://snowflake-broker.azureedge.net/ front=ajax.aspnetcdn.com ice=stun:206.53.159.130:3479,stun:176.119.42.11:3479,stun:94.23.17.185:3479,stun:217.74.179.29:3479,stun:83.125.8.47:3479,stun:23.253.102.137:3479,stun:52.26.251.34:3479,stun:52.26.251.34:3479,stun:18.191.223.12:3479,stun:154.73.34.8:3479,stun:185.125.180.70:3479,stun:195.35.115.37:3479
TM A url=https://snowflake-broker.azureedge.net/ front=ajax.aspnetcdn.com ice=stun:206.53.159.130:3479,stun:176.119.42.11:3479,stun:94.23.17.185:3479,stun:217.74.179.29:3479,stun:83.125.8.47:3479,stun:23.253.102.137:3479,stun:52.26.251.34:3479,stun:52.26.251.34:3479,stun:18.191.223.12:3479,stun:154.73.34.8:3479,stun:185.125.180.70:3479,stun:195.35.115.37:3479
TM M url=https://snowflake-broker.torproject.net/ ampcache=https://cdn.ampproject.org/ front=cdn.ampproject.org ice=stun:206.53.159.130:3479,stun:176.119.42.11:3479,stun:94.23.17.185:3479,stun:217.74.179.29:3479,stun:83.125.8.47:3479,stun:23.253.102.137:3479,stun:52.26.251.34:3479,stun:52.26.251.34:3479,stun:18.191.223.12:3479,stun:154.73.34.8:3479,stun:185.125.180.70:3479,stun:195.35.115.37:3479
ZZ 1 url=https://snowflake-broker.torproject.net.global.prod.fastly.net/ front=cdn.sstatic.net ice=stun:stun.l.google.com:19302,stun:stun.voip.blackberry.com:3478,stun:stun.altar.com.pl:3478,stun:stun.antisip.com:3478,stun:stun.bluesip.net:3478,stun:stun.dus.net:3478,stun:stun.epygi.com:3478,stun:stun.sonetel.com:3478,stun:stun.sonetel.net:3478,stun:stun.stunprotocol.org:3478,stun:stun.uls.co.za:3478,stun:stun.voipgate.com:3478,stun:stun.voys.nl:3478 utls-imitate=hellochrome_auto
ZZ 0 url=https://snowflake-broker.azureedge.net/ front=ajax.aspnetcdn.com ice=stun:stun.l.google.com:19302,stun:stun.voip.blackberry.com:3478,stun:stun.altar.com.pl:3478,stun:stun.antisip.com:3478,stun:stun.bluesip.net:3478,stun:stun.dus.net:3478,stun:stun.epygi.com:3478,stun:stun.sonetel.com:3478,stun:stun.sonetel.net:3478,stun:stun.stunprotocol.org:3478,stun:stun.uls.co.za:3478,stun:stun.voipgate.com:3478,stun:stun.voys.nl:3478 utls-imitate=hellochrome_auto
TM 1 url=https://snowflake-broker.azureedge.net/ front=ajax.aspnetcdn.com ice=stun:206.53.159.130:3479,stun:176.119.42.11:3479,stun:94.23.17.185:3479,stun:217.74.179.29:3479,stun:83.125.8.47:3479,stun:23.253.102.137:3479,stun:52.26.251.34:3479,stun:52.26.251.34:3479,stun:18.191.223.12:3479,stun:154.73.34.8:3479,stun:185.125.180.70:3479,stun:195.35.115.37:3479 utls-imitate=hellochrome_auto
TM 0 url=https://snowflake-broker.azureedge.net/ front=ajax.aspnetcdn.com ice=stun:206.53.159.130:3479,stun:176.119.42.11:3479,stun:94.23.17.185:3479,stun:217.74.179.29:3479,stun:83.125.8.47:3479,stun:23.253.102.137:3479,stun:52.26.251.34:3479,stun:52.26.251.34:3479,stun:18.191.223.12:3479,stun:154.73.34.8:3479,stun:185.125.180.70:3479,stun:195.35.115.37:3479 utls-imitate=hellochrome_auto

View File

@@ -20,7 +20,6 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import javax.annotation.Nullable;
@@ -34,6 +33,7 @@ import static org.briarproject.bramble.test.TestUtils.getIdentity;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
import static org.briarproject.bramble.util.StringUtils.UTF_8;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.bramble.util.StringUtils.toHexString;
import static org.junit.Assert.assertArrayEquals;
@@ -342,7 +342,7 @@ public class AccountManagerImplTest extends BrambleMockTestCase {
private void storeDatabaseKey(File f, String hex) throws IOException {
f.getParentFile().mkdirs();
FileOutputStream out = new FileOutputStream(f);
out.write(hex.getBytes(Charset.forName("UTF-8")));
out.write(hex.getBytes(UTF_8));
out.flush();
out.close();
}
@@ -350,7 +350,7 @@ public class AccountManagerImplTest extends BrambleMockTestCase {
@Nullable
private String loadDatabaseKey(File f) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(
new FileInputStream(f), Charset.forName("UTF-8")));
new FileInputStream(f), UTF_8));
String hex = reader.readLine();
reader.close();
return hex;

View File

@@ -9,7 +9,7 @@ import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.lifecycle.IoExecutor;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.mailbox.UrlConverterModule;
import org.briarproject.bramble.mailbox.ModularMailboxModule;
import org.briarproject.bramble.test.BrambleCoreIntegrationTestModule;
import org.briarproject.bramble.test.TestDnsModule;
import org.briarproject.bramble.test.TestPluginConfigModule;
@@ -25,7 +25,7 @@ import dagger.Component;
@Component(modules = {
BrambleCoreIntegrationTestModule.class,
BrambleCoreModule.class,
UrlConverterModule.class,
ModularMailboxModule.class,
TestDnsModule.class,
TestSocksModule.class,
TestPluginConfigModule.class,

View File

@@ -2,21 +2,27 @@ package org.briarproject.bramble.keyagreement;
import org.briarproject.bramble.api.Bytes;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.Pair;
import org.briarproject.bramble.api.UnsupportedVersionException;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.data.BdfReader;
import org.briarproject.bramble.api.data.BdfReaderFactory;
import org.briarproject.bramble.api.keyagreement.Payload;
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
import org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType;
import org.briarproject.bramble.api.qrcode.WrongQrCodeTypeException;
import org.briarproject.bramble.test.BrambleMockTestCase;
import org.jmock.Expectations;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.BETA_PROTOCOL_VERSION;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.QR_FORMAT_VERSION;
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.BQP;
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.MAILBOX;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -26,32 +32,29 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
private final BdfReaderFactory bdfReaderFactory =
context.mock(BdfReaderFactory.class);
private final QrCodeClassifier qrCodeClassifier =
context.mock(QrCodeClassifier.class);
private final BdfReader bdfReader = context.mock(BdfReader.class);
private final PayloadParserImpl payloadParser =
new PayloadParserImpl(bdfReaderFactory);
private final String payload = getRandomString(123);
@Test(expected = FormatException.class)
public void testThrowsFormatExceptionIfPayloadIsEmpty() throws Exception {
payloadParser.parse(new byte[0]);
private final PayloadParserImpl payloadParser =
new PayloadParserImpl(bdfReaderFactory, qrCodeClassifier);
@Test(expected = WrongQrCodeTypeException.class)
public void testThrowsExceptionForWrongQrCodeType() throws Exception {
expectClassifyQrCode(payload, MAILBOX, QR_FORMAT_VERSION);
payloadParser.parse(payload);
}
@Test
public void testThrowsUnsupportedVersionExceptionForOldVersion()
throws Exception {
try {
payloadParser.parse(new byte[] {PROTOCOL_VERSION - 1});
fail();
} catch (UnsupportedVersionException e) {
assertTrue(e.isTooOld());
}
}
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION - 1);
@Test
public void testThrowsUnsupportedVersionExceptionForBetaVersion()
throws Exception {
try {
payloadParser.parse(new byte[] {BETA_PROTOCOL_VERSION});
payloadParser.parse(payload);
fail();
} catch (UnsupportedVersionException e) {
assertTrue(e.isTooOld());
@@ -61,8 +64,10 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
@Test
public void testThrowsUnsupportedVersionExceptionForNewVersion()
throws Exception {
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION + 1);
try {
payloadParser.parse(new byte[] {PROTOCOL_VERSION + 1});
payloadParser.parse(payload);
fail();
} catch (UnsupportedVersionException e) {
assertFalse(e.isTooOld());
@@ -71,6 +76,8 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
@Test(expected = FormatException.class)
public void testThrowsFormatExceptionForEmptyList() throws Exception {
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION);
context.checking(new Expectations() {{
oneOf(bdfReaderFactory).createReader(
with(any(ByteArrayInputStream.class)));
@@ -79,7 +86,7 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
will(returnValue(new BdfList()));
}});
payloadParser.parse(new byte[] {PROTOCOL_VERSION});
payloadParser.parse(payload);
}
@Test(expected = FormatException.class)
@@ -87,6 +94,8 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
throws Exception {
byte[] commitment = getRandomBytes(COMMIT_LENGTH);
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION);
context.checking(new Expectations() {{
oneOf(bdfReaderFactory).createReader(
with(any(ByteArrayInputStream.class)));
@@ -97,7 +106,7 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
will(returnValue(false));
}});
payloadParser.parse(new byte[] {PROTOCOL_VERSION});
payloadParser.parse(payload);
}
@Test(expected = FormatException.class)
@@ -105,6 +114,7 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
throws Exception {
byte[] commitment = getRandomBytes(COMMIT_LENGTH - 1);
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION);
context.checking(new Expectations() {{
oneOf(bdfReaderFactory).createReader(
with(any(ByteArrayInputStream.class)));
@@ -115,7 +125,7 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
will(returnValue(true));
}});
payloadParser.parse(new byte[] {PROTOCOL_VERSION});
payloadParser.parse(payload);
}
@Test(expected = FormatException.class)
@@ -123,6 +133,7 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
throws Exception {
byte[] commitment = getRandomBytes(COMMIT_LENGTH + 1);
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION);
context.checking(new Expectations() {{
oneOf(bdfReaderFactory).createReader(
with(any(ByteArrayInputStream.class)));
@@ -133,12 +144,14 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
will(returnValue(true));
}});
payloadParser.parse(new byte[] {PROTOCOL_VERSION});
payloadParser.parse(payload);
}
@Test
public void testAcceptsPayloadWithNoDescriptors() throws Exception {
byte[] commitment = getRandomBytes(COMMIT_LENGTH);
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION);
context.checking(new Expectations() {{
oneOf(bdfReaderFactory).createReader(
with(any(ByteArrayInputStream.class)));
@@ -149,8 +162,16 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
will(returnValue(true));
}});
Payload p = payloadParser.parse(new byte[] {PROTOCOL_VERSION});
Payload p = payloadParser.parse(payload);
assertArrayEquals(commitment, p.getCommitment());
assertTrue(p.getTransportDescriptors().isEmpty());
}
private void expectClassifyQrCode(String payload, QrCodeType qrCodeType,
int formatVersion) {
context.checking(new Expectations() {{
oneOf(qrCodeClassifier).classifyQrCode(payload);
will(returnValue(new Pair<>(qrCodeType, formatVersion)));
}});
}
}

View File

@@ -21,12 +21,13 @@ public class MailboxApiCallerImplTest extends BrambleMockTestCase {
private final TaskScheduler taskScheduler =
context.mock(TaskScheduler.class);
private final MailboxConfig mailboxConfig = new MailboxConfigImpl();
private final Executor ioExecutor = context.mock(Executor.class);
private final ApiCall apiCall = context.mock(ApiCall.class);
private final Cancellable scheduledTask = context.mock(Cancellable.class);
private final MailboxApiCallerImpl caller =
new MailboxApiCallerImpl(taskScheduler, ioExecutor);
new MailboxApiCallerImpl(taskScheduler, mailboxConfig, ioExecutor);
@Test
public void testSubmitsTaskImmediately() {

View File

@@ -24,9 +24,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Nonnull;
import javax.net.SocketFactory;
import okhttp3.OkHttpClient;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
@@ -34,8 +31,8 @@ import okhttp3.mockwebserver.RecordedRequest;
import okio.Buffer;
import static java.util.Collections.singletonList;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.briarproject.bramble.api.mailbox.MailboxConstants.CLIENT_SUPPORTS;
import static org.briarproject.bramble.mailbox.MailboxTestUtils.createHttpClientProvider;
import static org.briarproject.bramble.test.TestUtils.getContactId;
import static org.briarproject.bramble.test.TestUtils.getMailboxProperties;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
@@ -56,18 +53,8 @@ public class MailboxApiTest extends BrambleTestCase {
@Rule
public TemporaryFolder folder = new TemporaryFolder();
private final OkHttpClient client = new OkHttpClient.Builder()
.socketFactory(SocketFactory.getDefault())
.connectTimeout(60_000, MILLISECONDS)
.build();
private final WeakSingletonProvider<OkHttpClient> httpClientProvider =
new WeakSingletonProvider<OkHttpClient>() {
@Override
@Nonnull
public OkHttpClient createInstance() {
return client;
}
};
createHttpClientProvider();
// We aren't using a real onion address, so use the given address verbatim
private final UrlConverter urlConverter = onion -> onion;
private final MailboxApiImpl api = new MailboxApiImpl(httpClientProvider,

View File

@@ -1,5 +1,6 @@
package org.briarproject.bramble.mailbox;
import org.briarproject.bramble.api.Pair;
import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.db.DatabaseComponent;
@@ -7,13 +8,24 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.mailbox.MailboxAuthToken;
import org.briarproject.bramble.api.mailbox.MailboxPairingState;
import org.briarproject.bramble.api.mailbox.MailboxPairingState.ConnectionError;
import org.briarproject.bramble.api.mailbox.MailboxPairingState.InvalidQrCode;
import org.briarproject.bramble.api.mailbox.MailboxPairingState.MailboxAlreadyPaired;
import org.briarproject.bramble.api.mailbox.MailboxPairingState.Paired;
import org.briarproject.bramble.api.mailbox.MailboxPairingState.Pairing;
import org.briarproject.bramble.api.mailbox.MailboxPairingState.QrCodeReceived;
import org.briarproject.bramble.api.mailbox.MailboxPairingState.UnexpectedError;
import org.briarproject.bramble.api.mailbox.MailboxPairingTask;
import org.briarproject.bramble.api.mailbox.MailboxProperties;
import org.briarproject.bramble.api.mailbox.MailboxSettingsManager;
import org.briarproject.bramble.api.mailbox.MailboxUpdate;
import org.briarproject.bramble.api.mailbox.MailboxUpdateManager;
import org.briarproject.bramble.api.mailbox.MailboxVersion;
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
import org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.mailbox.MailboxApi.ApiException;
import org.briarproject.bramble.mailbox.MailboxApi.MailboxAlreadyPairedException;
import org.briarproject.bramble.test.BrambleMockTestCase;
import org.briarproject.bramble.test.DbExpectations;
import org.briarproject.bramble.test.ImmediateExecutor;
@@ -22,13 +34,15 @@ import org.jmock.Expectations;
import org.junit.Test;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
import static java.util.Collections.singletonList;
import static org.briarproject.bramble.api.mailbox.MailboxConstants.QR_FORMAT_VERSION;
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.BQP;
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.MAILBOX;
import static org.briarproject.bramble.mailbox.MailboxTestUtils.getQrCodePayload;
import static org.briarproject.bramble.test.TestUtils.getContact;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
@@ -49,9 +63,8 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
context.mock(MailboxSettingsManager.class);
private final MailboxUpdateManager mailboxUpdateManager =
context.mock(MailboxUpdateManager.class);
private final MailboxPairingTaskFactory factory =
new MailboxPairingTaskFactoryImpl(executor, db, crypto, clock, api,
mailboxSettingsManager, mailboxUpdateManager);
private final QrCodeClassifier qrCodeClassifier =
context.mock(QrCodeClassifier.class);
private final String onion = getRandomString(56);
private final byte[] onionBytes = getRandomBytes(32);
@@ -59,7 +72,8 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
new MailboxAuthToken(getRandomId());
private final MailboxAuthToken ownerToken =
new MailboxAuthToken(getRandomId());
private final String validPayload = getValidPayload();
private final String validPayload =
getQrCodePayload(onionBytes, setupToken.getBytes());
private final long time = System.currentTimeMillis();
private final MailboxProperties setupProperties = new MailboxProperties(
onion, setupToken, new ArrayList<>());
@@ -68,32 +82,50 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
@Test
public void testInitialQrCodeReceivedState() {
MailboxPairingTask task =
factory.createPairingTask(getRandomString(42));
MailboxPairingTask task = createPairingTask(getRandomString(42));
task.addObserver(state ->
assertTrue(state instanceof MailboxPairingState.QrCodeReceived)
);
assertTrue(state instanceof QrCodeReceived));
}
@Test
public void testInvalidQrCode() {
MailboxPairingTask task1 =
factory.createPairingTask(getRandomString(42));
task1.run();
task1.addObserver(state ->
assertTrue(state instanceof MailboxPairingState.InvalidQrCode)
);
public void testInvalidQrCodeType() {
String payload = getRandomString(65);
MailboxPairingTask task = createPairingTask(payload);
String goodLength = "00" + getRandomString(63);
MailboxPairingTask task2 = factory.createPairingTask(goodLength);
task2.run();
task2.addObserver(state ->
assertTrue(state instanceof MailboxPairingState.InvalidQrCode)
);
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION);
task.run();
task.addObserver(state ->
assertTrue(state instanceof InvalidQrCode));
}
@Test
public void testInvalidQrCodeVersion() {
String payload = getRandomString(65);
MailboxPairingTask task = createPairingTask(payload);
expectClassifyQrCode(payload, MAILBOX, QR_FORMAT_VERSION + 1);
task.run();
task.addObserver(state ->
assertTrue(state instanceof InvalidQrCode));
}
@Test
public void testInvalidQrCodeLength() {
String payload = getRandomString(42);
MailboxPairingTask task = createPairingTask(payload);
expectClassifyQrCode(payload, MAILBOX, QR_FORMAT_VERSION);
task.run();
task.addObserver(state ->
assertTrue(state instanceof InvalidQrCode));
}
@Test
public void testSuccessfulPairing() throws Exception {
expectClassifyQrCode(validPayload, MAILBOX, QR_FORMAT_VERSION);
context.checking(new Expectations() {{
oneOf(crypto).encodeOnion(onionBytes);
will(returnValue(onion));
@@ -121,17 +153,14 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
}});
AtomicInteger i = new AtomicInteger(0);
MailboxPairingTask task = factory.createPairingTask(validPayload);
MailboxPairingTask task = createPairingTask(validPayload);
task.addObserver(state -> {
if (i.get() == 0) {
assertEquals(MailboxPairingState.QrCodeReceived.class,
state.getClass());
assertEquals(QrCodeReceived.class, state.getClass());
} else if (i.get() == 1) {
assertEquals(MailboxPairingState.Pairing.class,
state.getClass());
assertEquals(Pairing.class, state.getClass());
} else if (i.get() == 2) {
assertEquals(MailboxPairingState.Paired.class,
state.getClass());
assertEquals(Paired.class, state.getClass());
} else fail("Unexpected change of state " + state.getClass());
i.getAndIncrement();
});
@@ -140,24 +169,23 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
@Test
public void testAlreadyPaired() throws Exception {
testApiException(new MailboxApi.MailboxAlreadyPairedException(),
MailboxPairingState.MailboxAlreadyPaired.class);
testApiException(new MailboxAlreadyPairedException(),
MailboxAlreadyPaired.class);
}
@Test
public void testMailboxApiException() throws Exception {
testApiException(new MailboxApi.ApiException(),
MailboxPairingState.UnexpectedError.class);
testApiException(new ApiException(), UnexpectedError.class);
}
@Test
public void testApiIOException() throws Exception {
testApiException(new IOException(),
MailboxPairingState.ConnectionError.class);
testApiException(new IOException(), ConnectionError.class);
}
private void testApiException(Exception e,
Class<? extends MailboxPairingState> s) throws Exception {
expectClassifyQrCode(validPayload, MAILBOX, QR_FORMAT_VERSION);
context.checking(new Expectations() {{
oneOf(crypto).encodeOnion(onionBytes);
will(returnValue(onion));
@@ -165,13 +193,14 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
will(throwException(e));
}});
MailboxPairingTask task = factory.createPairingTask(validPayload);
MailboxPairingTask task = createPairingTask(validPayload);
task.run();
task.addObserver(state -> assertEquals(state.getClass(), s));
}
@Test
public void testDbException() throws Exception {
expectClassifyQrCode(validPayload, MAILBOX, QR_FORMAT_VERSION);
context.checking(new Expectations() {{
oneOf(crypto).encodeOnion(onionBytes);
will(returnValue(onion));
@@ -188,20 +217,10 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
will(throwException(new DbException()));
}});
MailboxPairingTask task = factory.createPairingTask(validPayload);
MailboxPairingTask task = createPairingTask(validPayload);
task.run();
task.addObserver(state -> assertEquals(state.getClass(),
MailboxPairingState.UnexpectedError.class));
}
private String getValidPayload() {
byte[] payloadBytes = ByteBuffer.allocate(65)
.put((byte) 32) // 1
.put(onionBytes) // 32
.put(setupToken.getBytes()) // 32
.array();
//noinspection CharsetObjectCanBeUsed
return new String(payloadBytes, Charset.forName("ISO-8859-1"));
task.addObserver(state ->
assertEquals(state.getClass(), UnexpectedError.class));
}
private PredicateMatcher<MailboxProperties> matches(MailboxProperties p2) {
@@ -212,4 +231,22 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
p1.getServerSupports().equals(p2.getServerSupports()));
}
private MailboxPairingTask createPairingTask(String qrCodePayload) {
context.checking(new Expectations() {{
oneOf(clock).currentTimeMillis();
will(returnValue(time));
}});
return new MailboxPairingTaskImpl(qrCodePayload, executor, db,
crypto, clock, api, mailboxSettingsManager,
mailboxUpdateManager, qrCodeClassifier);
}
private void expectClassifyQrCode(String payload, QrCodeType qrCodeType,
int formatVersion) {
context.checking(new Expectations() {{
oneOf(qrCodeClassifier).classifyQrCode(payload);
will(returnValue(new Pair<>(qrCodeType, formatVersion)));
}});
}
}

View File

@@ -0,0 +1,47 @@
package org.briarproject.bramble.mailbox;
import org.briarproject.bramble.api.WeakSingletonProvider;
import java.nio.ByteBuffer;
import javax.annotation.Nonnull;
import javax.net.SocketFactory;
import okhttp3.OkHttpClient;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.briarproject.bramble.api.mailbox.MailboxConstants.QR_FORMAT_ID;
import static org.briarproject.bramble.api.mailbox.MailboxConstants.QR_FORMAT_VERSION;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.ISO_8859_1;
class MailboxTestUtils {
static String getQrCodePayload(byte[] onionBytes, byte[] setupToken) {
int formatIdAndVersion = (QR_FORMAT_ID << 5) | QR_FORMAT_VERSION;
byte[] payloadBytes = ByteBuffer.allocate(65)
.put((byte) formatIdAndVersion) // 1
.put(onionBytes) // 32
.put(setupToken) // 32
.array();
return new String(payloadBytes, ISO_8859_1);
}
// Used by mailbox integration tests
static String getQrCodePayload(byte[] setupToken) {
return getQrCodePayload(getRandomId(), setupToken);
}
static WeakSingletonProvider<OkHttpClient> createHttpClientProvider() {
return new WeakSingletonProvider<OkHttpClient>() {
@Override
@Nonnull
public OkHttpClient createInstance() {
return new OkHttpClient.Builder()
.socketFactory(SocketFactory.getDefault())
.connectTimeout(60_000, MILLISECONDS)
.build();
}
};
}
}

View File

@@ -29,6 +29,7 @@ public class TorReachabilityMonitorImplTest extends BrambleMockTestCase {
private final Executor ioExecutor = context.mock(Executor.class);
private final TaskScheduler taskScheduler =
context.mock(TaskScheduler.class);
private final MailboxConfig mailboxConfig = new MailboxConfigImpl();
private final PluginManager pluginManager =
context.mock(PluginManager.class);
private final EventBus eventBus = context.mock(EventBus.class);
@@ -39,7 +40,7 @@ public class TorReachabilityMonitorImplTest extends BrambleMockTestCase {
private final TorReachabilityMonitorImpl monitor =
new TorReachabilityMonitorImpl(ioExecutor, taskScheduler,
pluginManager, eventBus);
mailboxConfig, pluginManager, eventBus);
@Test
public void testSchedulesTaskWhenStartedIfTorIsActive() {

View File

@@ -9,7 +9,8 @@ import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.plugin.file.RemovableDriveManager;
import org.briarproject.bramble.battery.DefaultBatteryManagerModule;
import org.briarproject.bramble.event.DefaultEventExecutorModule;
import org.briarproject.bramble.mailbox.UrlConverterModule;
import org.briarproject.bramble.mailbox.ModularMailboxModule;
import org.briarproject.bramble.system.DefaultThreadFactoryModule;
import org.briarproject.bramble.system.DefaultWakefulIoExecutorModule;
import org.briarproject.bramble.system.TimeTravelModule;
import org.briarproject.bramble.test.TestDatabaseConfigModule;
@@ -29,13 +30,14 @@ import dagger.Component;
DefaultBatteryManagerModule.class,
DefaultEventExecutorModule.class,
DefaultWakefulIoExecutorModule.class,
DefaultThreadFactoryModule.class,
TestDatabaseConfigModule.class,
TestDnsModule.class,
TestFeatureFlagModule.class,
TestMailboxDirectoryModule.class,
RemovableDriveIntegrationTestModule.class,
RemovableDriveModule.class,
UrlConverterModule.class,
ModularMailboxModule.class,
TestSecureRandomModule.class,
TimeTravelModule.class,
TestSocksModule.class,

View File

@@ -0,0 +1,73 @@
package org.briarproject.bramble.plugin.tcp;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.lifecycle.IoExecutor;
import org.briarproject.bramble.api.plugin.Backoff;
import org.briarproject.bramble.api.plugin.BackoffFactory;
import org.briarproject.bramble.api.plugin.PluginCallback;
import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory;
import org.briarproject.bramble.api.system.WakefulIoExecutor;
import org.briarproject.nullsafety.NotNullByDefault;
import java.util.concurrent.Executor;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static org.briarproject.bramble.api.plugin.LanTcpConstants.ID;
@Immutable
@NotNullByDefault
@SuppressWarnings("unused") // This class is used in briar-desktop
public class TestLanTcpPluginFactory implements DuplexPluginFactory {
private static final int MAX_LATENCY = 30_000; // 30 seconds
private static final int MAX_IDLE_TIME = 30_000; // 30 seconds
private static final int CONNECTION_TIMEOUT = 3_000; // 3 seconds
private static final int MIN_POLLING_INTERVAL = 60_000; // 1 minute
private static final int MAX_POLLING_INTERVAL = 600_000; // 10 mins
private static final double BACKOFF_BASE = 1.2;
private final Executor ioExecutor, wakefulIoExecutor;
private final EventBus eventBus;
private final BackoffFactory backoffFactory;
@Inject
public TestLanTcpPluginFactory(@IoExecutor Executor ioExecutor,
@WakefulIoExecutor Executor wakefulIoExecutor,
EventBus eventBus,
BackoffFactory backoffFactory) {
this.ioExecutor = ioExecutor;
this.wakefulIoExecutor = wakefulIoExecutor;
this.eventBus = eventBus;
this.backoffFactory = backoffFactory;
}
@Override
public TransportId getId() {
return ID;
}
@Override
public long getMaxLatency() {
return MAX_LATENCY;
}
@Override
public DuplexPlugin createPlugin(PluginCallback callback) {
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
MAX_POLLING_INTERVAL, BACKOFF_BASE);
LanTcpPlugin plugin = new LanTcpPlugin(ioExecutor, wakefulIoExecutor,
backoff, callback, MAX_LATENCY, MAX_IDLE_TIME,
CONNECTION_TIMEOUT) {
@Override
protected boolean canConnectToOwnAddress() {
return true;
}
};
eventBus.addListener(plugin);
return plugin;
}
}

View File

@@ -1,6 +1,5 @@
package org.briarproject.bramble.plugin.tor;
import org.briarproject.bramble.plugin.tor.CircumventionProviderImpl.SnowflakeBroker;
import org.briarproject.bramble.test.BrambleTestCase;
import org.junit.Test;
@@ -18,9 +17,6 @@ import static org.briarproject.bramble.plugin.tor.CircumventionProvider.BridgeTy
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.DEFAULT_BRIDGES;
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.DPI_BRIDGES;
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.NON_DEFAULT_BRIDGES;
import static org.briarproject.bramble.plugin.tor.CircumventionProviderImpl.SnowflakeBroker.AMP_CACHE;
import static org.briarproject.bramble.plugin.tor.CircumventionProviderImpl.SnowflakeBroker.AZURE;
import static org.briarproject.bramble.plugin.tor.CircumventionProviderImpl.SnowflakeBroker.FASTLY;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
@@ -71,23 +67,18 @@ public class CircumventionProviderImplTest extends BrambleTestCase {
}
@Test
public void testHasSnowflakeParamsForFastly() {
testHasSnowflakeParams(FASTLY);
public void testHasSnowflakeParamsWithLetsEncrypt() {
testHasSnowflakeParams(true);
}
@Test
public void testHasSnowflakeParamsForAzure() {
testHasSnowflakeParams(AZURE);
public void testHasSnowflakeParamsWithoutLetsEncrypt() {
testHasSnowflakeParams(false);
}
@Test
public void testHasSnowflakeParamsForAmpCache() {
testHasSnowflakeParams(AMP_CACHE);
}
private void testHasSnowflakeParams(SnowflakeBroker broker) {
String tmParams = provider.getSnowflakeParams("TM", broker);
String defaultParams = provider.getSnowflakeParams("ZZ", broker);
private void testHasSnowflakeParams(boolean letsEncrypt) {
String tmParams = provider.getSnowflakeParams("TM", letsEncrypt);
String defaultParams = provider.getSnowflakeParams("ZZ", letsEncrypt);
assertFalse(tmParams.isEmpty());
assertFalse(defaultParams.isEmpty());
assertNotEquals(defaultParams, tmParams);

View File

@@ -0,0 +1,70 @@
package org.briarproject.bramble.qrcode;
import org.briarproject.bramble.api.Pair;
import org.briarproject.bramble.api.keyagreement.KeyAgreementConstants;
import org.briarproject.bramble.api.mailbox.MailboxConstants;
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
import org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType;
import org.briarproject.bramble.test.BrambleTestCase;
import org.junit.Test;
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.BQP;
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.MAILBOX;
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.UNKNOWN;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.util.StringUtils.ISO_8859_1;
import static org.junit.Assert.assertEquals;
public class QrCodeClassifierImplTest extends BrambleTestCase {
private final QrCodeClassifier classifier = new QrCodeClassifierImpl();
@Test
public void testClassifiesEmptyStringAsUnknown() {
Pair<QrCodeType, Integer> result = classifier.classifyQrCode("");
assertEquals(UNKNOWN, result.getFirst());
assertEquals(0, result.getSecond().intValue());
}
@Test
public void testClassifiesKeyAgreement() {
byte[] payloadBytes = getRandomBytes(123);
for (int version = 0; version < 32; version++) {
int typeAndVersion =
(KeyAgreementConstants.QR_FORMAT_ID << 5) | version;
payloadBytes[0] = (byte) typeAndVersion;
String payload = new String(payloadBytes, ISO_8859_1);
Pair<QrCodeType, Integer> result =
classifier.classifyQrCode(payload);
assertEquals(BQP, result.getFirst());
assertEquals(version, result.getSecond().intValue());
}
}
@Test
public void testClassifiesMailbox() {
byte[] payloadBytes = getRandomBytes(123);
for (int version = 0; version < 32; version++) {
int typeAndVersion =
(MailboxConstants.QR_FORMAT_ID << 5) | version;
payloadBytes[0] = (byte) typeAndVersion;
String payload = new String(payloadBytes, ISO_8859_1);
Pair<QrCodeType, Integer> result =
classifier.classifyQrCode(payload);
assertEquals(MAILBOX, result.getFirst());
assertEquals(version, result.getSecond().intValue());
}
}
@Test
public void testClassifiesUnknownFormatIdAsUnknown() {
byte[] payloadBytes = getRandomBytes(123);
int unknownFormatId = MailboxConstants.QR_FORMAT_ID + 1;
int typeAndVersion = unknownFormatId << 5;
payloadBytes[0] = (byte) typeAndVersion;
String payload = new String(payloadBytes, ISO_8859_1);
Pair<QrCodeType, Integer> result = classifier.classifyQrCode(payload);
assertEquals(UNKNOWN, result.getFirst());
assertEquals(0, result.getSecond().intValue());
}
}

View File

@@ -2,7 +2,7 @@ package org.briarproject.bramble.sync;
import org.briarproject.bramble.BrambleCoreIntegrationTestEagerSingletons;
import org.briarproject.bramble.BrambleCoreModule;
import org.briarproject.bramble.mailbox.UrlConverterModule;
import org.briarproject.bramble.mailbox.ModularMailboxModule;
import org.briarproject.bramble.test.BrambleCoreIntegrationTestModule;
import org.briarproject.bramble.test.TestDnsModule;
import org.briarproject.bramble.test.TestPluginConfigModule;
@@ -16,7 +16,7 @@ import dagger.Component;
@Component(modules = {
BrambleCoreIntegrationTestModule.class,
BrambleCoreModule.class,
UrlConverterModule.class,
ModularMailboxModule.class,
TestDnsModule.class,
TestSocksModule.class,
TestPluginConfigModule.class,

View File

@@ -11,6 +11,7 @@ import dagger.Module;
DefaultBatteryManagerModule.class,
DefaultEventExecutorModule.class,
DefaultWakefulIoExecutorModule.class,
TestThreadFactoryModule.class,
TestDatabaseConfigModule.class,
TestFeatureFlagModule.class,
TestMailboxDirectoryModule.class,

View File

@@ -235,11 +235,16 @@ public abstract class BrambleIntegrationTest<C extends BrambleIntegrationTestCom
protected void awaitPendingMessageDelivery(int num)
throws TimeoutException {
deliveryWaiter.await(TIMEOUT, num);
awaitPendingMessageDelivery(num, TIMEOUT);
}
protected void awaitPendingMessageDelivery(int num, long timeout)
throws TimeoutException {
deliveryWaiter.await(timeout, num);
assertEquals("Messages delivered", num, deliveryCounter.getAndSet(0));
try {
messageSemaphore.tryAcquire(num, TIMEOUT, MILLISECONDS);
messageSemaphore.tryAcquire(num, timeout, MILLISECONDS);
} catch (InterruptedException e) {
LOG.info("Interrupted while waiting for messages");
Thread.currentThread().interrupt();

View File

@@ -6,7 +6,7 @@ import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.connection.ConnectionManager;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.mailbox.UrlConverterModule;
import org.briarproject.bramble.mailbox.ModularMailboxModule;
import javax.inject.Singleton;
@@ -16,7 +16,7 @@ import dagger.Component;
@Component(modules = {
BrambleCoreIntegrationTestModule.class,
BrambleCoreModule.class,
UrlConverterModule.class,
ModularMailboxModule.class,
TestDnsModule.class,
TestSocksModule.class,
TestPluginConfigModule.class,

View File

@@ -0,0 +1,66 @@
package org.briarproject.bramble.test;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import dagger.Module;
import dagger.Provides;
@Module
public class TestThreadFactoryModule {
@Nullable
private final String prefix;
public TestThreadFactoryModule() {
this(null);
}
public TestThreadFactoryModule(@Nullable String prefix) {
this.prefix = prefix;
}
@Provides
ThreadFactory provideThreadFactory() {
if (prefix == null) return Executors.defaultThreadFactory();
return new TestThreadFactory(prefix);
}
/**
* This class is mostly copied from
* {@link Executors#defaultThreadFactory()} only adds a given prefix.
*/
static class TestThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
private TestThreadFactory(String prefix) {
SecurityManager s = System.getSecurityManager();
this.group = s != null ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
this.namePrefix =
prefix + "-p-" + poolNumber.getAndIncrement() + "-t-";
}
@Override
public Thread newThread(@Nonnull Runnable r) {
Thread t = new Thread(this.group, r,
this.namePrefix + this.threadNumber.getAndIncrement(), 0L);
if (t.isDaemon()) {
t.setDaemon(false);
}
if (t.getPriority() != 5) {
t.setPriority(5);
}
return t;
}
}
}

View File

@@ -7,7 +7,7 @@ import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.properties.TransportPropertyManager;
import org.briarproject.bramble.api.transport.KeyManager;
import org.briarproject.bramble.mailbox.UrlConverterModule;
import org.briarproject.bramble.mailbox.ModularMailboxModule;
import org.briarproject.bramble.test.BrambleCoreIntegrationTestModule;
import org.briarproject.bramble.test.BrambleIntegrationTestComponent;
import org.briarproject.bramble.test.TestDnsModule;
@@ -22,7 +22,7 @@ import dagger.Component;
@Component(modules = {
BrambleCoreIntegrationTestModule.class,
BrambleCoreModule.class,
UrlConverterModule.class,
ModularMailboxModule.class,
TestDnsModule.class,
TestSocksModule.class,
TestPluginConfigModule.class,

View File

@@ -1,22 +1,23 @@
dependencyVerification {
verify = [
'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db',
'com.fasterxml.jackson.core:jackson-annotations:2.13.0:jackson-annotations-2.13.0.jar:81f9724d8843e8b08f8f6c0609e7a2b030d00c34861c4ac7e2099a7235047d6f',
'com.fasterxml.jackson.core:jackson-core:2.13.0:jackson-core-2.13.0.jar:348bc59b348df2e807b356f1d62d2afb41a974073328abc773eb0932b855d2c8',
'com.fasterxml.jackson.core:jackson-databind:2.13.0:jackson-databind-2.13.0.jar:9c826d27176268777adcf97e1c6e2051c7e33a7aaa2c370c2e8c6077fd9da3f4',
'com.fasterxml.jackson.core:jackson-annotations:2.13.4:jackson-annotations-2.13.4.jar:ac5b27a634942391ca113850ee7db01df1499a240174021263501c05fc653b44',
'com.fasterxml.jackson.core:jackson-core:2.13.4:jackson-core-2.13.4.jar:4c2e043200edd9ee7ba6fc378bd5c17784a5bf2388e152d208068b51fd0839cf',
'com.fasterxml.jackson.core:jackson-databind:2.13.4:jackson-databind-2.13.4.jar:c9faff420d9e2c7e1e4711dbeebec2506a32c9942027211c5c293d8d87807eb6',
'com.google.code.findbugs:annotations:3.0.1:annotations-3.0.1.jar:6b47ff0a6de0ce17cbedc3abb0828ca5bce3009d53ea47b3723ff023c4742f79',
'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
'com.google.dagger:dagger-compiler:2.33:dagger-compiler-2.33.jar:aa8a0d8370c578fd6999802d0d90b9829377a46d2c1141e11b8f737970e7155e',
'com.google.dagger:dagger-producers:2.33:dagger-producers-2.33.jar:5897f0b6eef799c2adfe3ccacc58c0fb374d58acb063c3ebe5366c38a8bce5c8',
'com.google.dagger:dagger-spi:2.33:dagger-spi-2.33.jar:e2dcab2221b8afb9556ef0a1c83b0bd5f42552e254322a257330f754cdbbb9d4',
'com.google.dagger:dagger:2.33:dagger-2.33.jar:d8798c5b8cf6b125234e33af5c6293bb9f2208ce29b57924c35b8c0be7b6bdcb',
'com.google.errorprone:error_prone_annotations:2.2.0:error_prone_annotations-2.2.0.jar:6ebd22ca1b9d8ec06d41de8d64e0596981d9607b42035f9ed374f9de271a481a',
'com.google.dagger:dagger-compiler:2.43.2:dagger-compiler-2.43.2.jar:298c020ee6ed2f4cc651ebbfdb7f8de329b07c44b618d65be117846a850e2a03',
'com.google.dagger:dagger-producers:2.43.2:dagger-producers-2.43.2.jar:e7f5d9ffc85d48a49c8e22e02833d418f7ccad5d7512f529964db5127ab915ff',
'com.google.dagger:dagger-spi:2.43.2:dagger-spi-2.43.2.jar:3bae8d9dadeaaa5927da6f094389a560c12c05fec3d2711d2fa79292c7a7d7ad',
'com.google.dagger:dagger:2.43.2:dagger-2.43.2.jar:c89681f7cbbf8c527bf4ac2748515d617fdb54a1d425c08d914fdc28192b5fe4',
'com.google.devtools.ksp:symbol-processing-api:1.7.0-1.0.6:symbol-processing-api-1.7.0-1.0.6.jar:adc29417be5ca9ff42118105fea4e36d9ef44987abfc41432309371a60198941',
'com.google.errorprone:error_prone_annotations:2.7.1:error_prone_annotations-2.7.1.jar:cd5257c08a246cf8628817ae71cb822be192ef91f6881ca4a3fcff4f1de1cff3',
'com.google.errorprone:javac-shaded:9-dev-r4023-3:javac-shaded-9-dev-r4023-3.jar:65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30',
'com.google.googlejavaformat:google-java-format:1.5:google-java-format-1.5.jar:aa19ad7850fb85178aa22f2fddb163b84d6ce4d0035872f30d4408195ca1144e',
'com.google.guava:failureaccess:1.0.1:failureaccess-1.0.1.jar:a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26',
'com.google.guava:guava:27.1-jre:guava-27.1-jre.jar:4a5aa70cc968a4d137e599ad37553e5cfeed2265e8c193476d7119036c536fe7',
'com.google.guava:guava:31.0.1-jre:guava-31.0.1-jre.jar:d5be94d65e87bd219fb3193ad1517baa55a3b88fc91d21cf735826ab5af087b9',
'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava:listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99',
'com.google.j2objc:j2objc-annotations:1.1:j2objc-annotations-1.1.jar:2994a7eb78f2710bd3d3bfb639b2c94e219cedac0d4d084d516e78c16dddecf6',
'com.google.j2objc:j2objc-annotations:1.3:j2objc-annotations-1.3.jar:21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b',
'com.h2database:h2:1.4.192:h2-1.4.192.jar:225b22e9857235c46c93861410b60b8c81c10dc8985f4faf188985ba5445126c',
'com.squareup.okhttp3:mockwebserver:4.9.3:mockwebserver-4.9.3.jar:9c8c581c29f22f877a35d11380462f75bb24bf1886204fe835ee695594a2784e',
'com.squareup.okhttp3:okhttp:3.12.13:okhttp-3.12.13.jar:508234e024ef7e270ab1a6d5b356f5b98e786511239ca986d684fd1e2cf7bc82',
@@ -24,7 +25,6 @@ dependencyVerification {
'com.squareup.okio:okio:1.15.0:okio-1.15.0.jar:693fa319a7e8843300602b204023b7674f106ebcb577f2dd5807212b66118bd2',
'com.squareup.okio:okio:2.8.0:okio-jvm-2.8.0.jar:4496b06e73982fcdd8a5393f46e5df2ce2fa4465df5895454cac68a32f09bbc8',
'com.squareup:javapoet:1.13.0:javapoet-1.13.0.jar:4c7517e848a71b36d069d12bb3bf46a70fd4cda3105d822b0ed2e19c00b69291',
'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f',
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3',
'net.bytebuddy:byte-buddy:1.9.12:byte-buddy-1.9.12.jar:3688c3d434bebc3edc5516296a2ed0f47b65e451071b4afecad84f902f0efc11',
@@ -34,14 +34,13 @@ dependencyVerification {
'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd',
'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047',
'org.bitlet:weupnp:0.1.4:weupnp-0.1.4.jar:88df7e6504929d00bdb832863761385c68ab92af945b04f0770b126270a444fb',
'org.bouncycastle:bcprov-jdk15to18:1.70:bcprov-jdk15to18-1.70.jar:7df4c54f29ce2dd616dc3b198ca4db3dfcc79e3cb397c084a0aff97b85c0bf38',
'org.bouncycastle:bcprov-jdk15to18:1.71:bcprov-jdk15to18-1.71.jar:143aaa4a40edd5fc2a18db7900059f6c16f4d931b94b94b20f7e2238e6662886',
'org.briarproject:jtorctl:0.5:jtorctl-0.5.jar:43f8c7d390169772b9a2c82ab806c8414c136a2a8636c555e22754bb7260793b',
'org.briarproject:null-safety:0.1:null-safety-0.1.jar:161760de5e838cb982bafa973df820675d4397098e9a91637a36a306d43ba011',
'org.briarproject:socks-socket:0.1:socks-socket-0.1.jar:e5898822d10f5390363c5dddb945891648c92cf93ba50709e07f0d173ec0eb4b',
'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d',
'org.checkerframework:checker-qual:2.5.2:checker-qual-2.5.2.jar:64b02691c8b9d4e7700f8ee2e742dce7ea2c6e81e662b7522c9ee3bf568c040a',
'org.checkerframework:checker-compat-qual:2.5.5:checker-compat-qual-2.5.5.jar:11d134b245e9cacc474514d2d66b5b8618f8039a1465cdc55bbc0b34e0008b7a',
'org.checkerframework:checker-qual:3.12.0:checker-qual-3.12.0.jar:ff10785ac2a357ec5de9c293cb982a2cbb605c0309ea4cc1cb9b9bc6dbe7f3cb',
'org.codehaus.mojo.signature:java16:1.1:java16-1.1.signature:53799223a2c98dba2d0add810bed76315460df285c69e4f397ae6098f87dd619',
'org.codehaus.mojo:animal-sniffer-annotations:1.17:animal-sniffer-annotations-1.17.jar:92654f493ecfec52082e76354f0ebf87648dc3d5cec2e3c3cdb947c016747a53',
'org.codehaus.mojo:animal-sniffer-ant-tasks:1.20:animal-sniffer-ant-tasks-1.20.jar:bb7d2498144118311d968bb08ff6fae3fc535fb1cb9cca8b8e9ea65b189422ac',
'org.codehaus.mojo:animal-sniffer:1.20:animal-sniffer-1.20.jar:80c422523c38db91260c6d78e5ee4b012862ab61cc55020c9e243dd7b5c62249',
'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9',
@@ -49,12 +48,14 @@ dependencyVerification {
'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050',
'org.hsqldb:hsqldb:2.3.5:hsqldb-2.3.5.jar:6676a6977ac98997a80f827ddbd3fe8ca1e0853dad1492512135fd1a222ccfad',
'org.jetbrains.kotlin:kotlin-stdlib-common:1.4.10:kotlin-stdlib-common-1.4.10.jar:4681f2d436a68c7523595d84ed5758e1382f9da0f67c91e6a848690d711274fe',
'org.jetbrains.kotlin:kotlin-stdlib-common:1.4.20:kotlin-stdlib-common-1.4.20.jar:a7112c9b3cefee418286c9c9372f7af992bd1e6e030691d52f60cb36dbec8320',
'org.jetbrains.kotlin:kotlin-stdlib-common:1.7.0:kotlin-stdlib-common-1.7.0.jar:59c6ff64fe9a6604afce03e8aaa75f83586c6030ac71fb0b34ee7cdefed3618f',
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.10:kotlin-stdlib-jdk7-1.4.10.jar:f9566380c08722c780ce33ceee23e98ddf765ca98fabd3e2fabae7975c8d232b',
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.0:kotlin-stdlib-jdk7-1.7.0.jar:07e91be9b2ca20672d2bdb7e181b766e73453a2da13492b5ddaee8fa47aea239',
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.10:kotlin-stdlib-jdk8-1.4.10.jar:39b7a9442d7a3865e0f4a732c56c1d5da0e11ffb3bb82a461d32deb0c0ca7673',
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.0:kotlin-stdlib-jdk8-1.7.0.jar:cf058e11db1dfc9944680c8c61b95ac689aaaa8a3eb30bced028100f038f030b',
'org.jetbrains.kotlin:kotlin-stdlib:1.4.10:kotlin-stdlib-1.4.10.jar:01ecb09782c042b931c1839acf21a188340b295d05400afd6e3415d4475b8daa',
'org.jetbrains.kotlin:kotlin-stdlib:1.4.20:kotlin-stdlib-1.4.20.jar:b8ab1da5cdc89cb084d41e1f28f20a42bd431538642a5741c52bbfae3fa3e656',
'org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.1.0:kotlinx-metadata-jvm-0.1.0.jar:9753bb39efef35957c5c15df9a3cb769aabf2cdfa74b47afcb7760e5146be3b5',
'org.jetbrains.kotlin:kotlin-stdlib:1.7.0:kotlin-stdlib-1.7.0.jar:aa88e9625577957f3249a46cb6e166ee09b369e600f7a11d148d16b0a6d87f05',
'org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.5.0:kotlinx-metadata-jvm-0.5.0.jar:ca063a96639b08b9eaa0de4d65e899480740a6efbe28ab9a8681a2ced03055a4',
'org.jetbrains:annotations:13.0:annotations-13.0.jar:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478',
'org.jmock:jmock-imposters:2.12.0:jmock-imposters-2.12.0.jar:3b836269745a137c9b2347e8d7c2104845b126ef04f012d6bfd94f1a7dea7b09',
'org.jmock:jmock-junit4:2.12.0:jmock-junit4-2.12.0.jar:3233062fc889637c151a24f1ee086bad04321ab7d8264fef279daff0fa27205b',

View File

@@ -12,11 +12,13 @@ configurations {
}
dependencies {
implementation project(path: ':bramble-core', configuration: 'default')
implementation project(':bramble-core')
implementation fileTree(dir: 'libs', include: '*.jar')
def jna_version = '4.5.2'
implementation "net.java.dev.jna:jna:$jna_version"
implementation "net.java.dev.jna:jna-platform:$jna_version"
tor "org.briarproject:tor-linux:$tor_version"
tor "org.briarproject:tor-windows:$tor_version"
tor "org.briarproject:obfs4proxy-linux:$obfs4proxy_version"
@@ -28,9 +30,11 @@ dependencies {
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
testImplementation project(path: ':bramble-core', configuration: 'testOutput')
testImplementation "junit:junit:$junit_version"
testImplementation "org.jmock:jmock:$jmock_version"
testImplementation "org.jmock:jmock-junit4:$jmock_version"
testImplementation "com.squareup.okhttp3:okhttp:$okhttp_version"
testAnnotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
}

View File

@@ -1,7 +1,7 @@
package org.briarproject.bramble;
import org.briarproject.bramble.io.DnsModule;
import org.briarproject.bramble.mailbox.UrlConverterModule;
import org.briarproject.bramble.mailbox.ModularMailboxModule;
import org.briarproject.bramble.network.JavaNetworkModule;
import org.briarproject.bramble.plugin.tor.CircumventionModule;
import org.briarproject.bramble.socks.SocksModule;
@@ -14,7 +14,7 @@ import dagger.Module;
DnsModule.class,
JavaNetworkModule.class,
JavaSystemModule.class,
UrlConverterModule.class,
ModularMailboxModule.class,
SocksModule.class
})
public class BrambleJavaModule {

View File

@@ -12,7 +12,6 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.concurrent.Executor;
import java.util.concurrent.Semaphore;
@@ -33,6 +32,7 @@ import static java.util.logging.Level.WARNING;
import static jssc.SerialPort.PURGE_RXCLEAR;
import static jssc.SerialPort.PURGE_TXCLEAR;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.StringUtils.US_ASCII;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
@@ -41,7 +41,6 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
private static final Logger LOG =
Logger.getLogger(ModemImpl.class.getName());
private static final Charset US_ASCII = Charset.forName("US-ASCII");
private static final int MAX_LINE_LENGTH = 256;
private static final int[] BAUD_RATES = {
256000, 128000, 115200, 57600, 38400, 19200, 14400, 9600, 4800, 1200

View File

@@ -30,6 +30,7 @@ import org.junit.runners.Parameterized.Parameters;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
@@ -198,6 +199,11 @@ public class BridgeTest extends BrambleTestCase {
@Test
public void testBridges() throws Exception {
if (params.stats.hasSucceeded(params.bridge)) {
LOG.info("Skipping previously successful bridge: " + params.bridge);
return;
}
DuplexPlugin duplexPlugin =
factory.createPlugin(new TestPluginCallback());
assertNotNull(duplexPlugin);
@@ -209,10 +215,13 @@ public class BridgeTest extends BrambleTestCase {
long start = clock.currentTimeMillis();
long timeout = params.bridgeType == MEEK ? MEEK_TIMEOUT : TIMEOUT;
while (clock.currentTimeMillis() - start < timeout) {
if (plugin.getState() == ACTIVE) return;
if (plugin.getState() == ACTIVE) break;
clock.sleep(500);
}
if (plugin.getState() != ACTIVE) {
if (plugin.getState() == ACTIVE) {
LOG.info("Connected to Tor: " + params.bridge);
params.stats.countSuccess(params.bridge);
} else {
LOG.warning("Could not connect to Tor within timeout: "
+ params.bridge);
params.stats.countFailure(params.bridge, params.essential);
@@ -240,11 +249,21 @@ public class BridgeTest extends BrambleTestCase {
private static class Stats {
@GuardedBy("this")
private final Set<String> successes = new HashSet<>();
@GuardedBy("this")
private final Multiset<String> failures = new Multiset<>();
@GuardedBy("this")
private final Set<String> unreachable = new TreeSet<>();
private synchronized boolean hasSucceeded(String bridge) {
return successes.contains(bridge);
}
private synchronized void countSuccess(String bridge) {
successes.add(bridge);
}
private synchronized void countFailure(String bridge,
boolean essential) {
if (failures.add(bridge) == ATTEMPTS_PER_BRIDGE) {

View File

@@ -3,7 +3,7 @@ package org.briarproject.bramble.test;
import org.briarproject.bramble.BrambleCoreIntegrationTestEagerSingletons;
import org.briarproject.bramble.BrambleCoreModule;
import org.briarproject.bramble.BrambleJavaModule;
import org.briarproject.bramble.mailbox.UrlConverterModule;
import org.briarproject.bramble.mailbox.ModularMailboxModule;
import org.briarproject.bramble.plugin.tor.BridgeTest;
import org.briarproject.bramble.plugin.tor.CircumventionProvider;
@@ -16,7 +16,7 @@ import dagger.Component;
BrambleCoreIntegrationTestModule.class,
BrambleCoreModule.class,
BrambleJavaModule.class,
UrlConverterModule.class,
ModularMailboxModule.class,
TestTorPortsModule.class,
TestPluginConfigModule.class,
})

View File

@@ -3,19 +3,21 @@ dependencyVerification {
'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db',
'com.google.code.findbugs:annotations:3.0.1:annotations-3.0.1.jar:6b47ff0a6de0ce17cbedc3abb0828ca5bce3009d53ea47b3723ff023c4742f79',
'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
'com.google.dagger:dagger-compiler:2.33:dagger-compiler-2.33.jar:aa8a0d8370c578fd6999802d0d90b9829377a46d2c1141e11b8f737970e7155e',
'com.google.dagger:dagger-producers:2.33:dagger-producers-2.33.jar:5897f0b6eef799c2adfe3ccacc58c0fb374d58acb063c3ebe5366c38a8bce5c8',
'com.google.dagger:dagger-spi:2.33:dagger-spi-2.33.jar:e2dcab2221b8afb9556ef0a1c83b0bd5f42552e254322a257330f754cdbbb9d4',
'com.google.dagger:dagger:2.33:dagger-2.33.jar:d8798c5b8cf6b125234e33af5c6293bb9f2208ce29b57924c35b8c0be7b6bdcb',
'com.google.errorprone:error_prone_annotations:2.2.0:error_prone_annotations-2.2.0.jar:6ebd22ca1b9d8ec06d41de8d64e0596981d9607b42035f9ed374f9de271a481a',
'com.google.dagger:dagger-compiler:2.43.2:dagger-compiler-2.43.2.jar:298c020ee6ed2f4cc651ebbfdb7f8de329b07c44b618d65be117846a850e2a03',
'com.google.dagger:dagger-producers:2.43.2:dagger-producers-2.43.2.jar:e7f5d9ffc85d48a49c8e22e02833d418f7ccad5d7512f529964db5127ab915ff',
'com.google.dagger:dagger-spi:2.43.2:dagger-spi-2.43.2.jar:3bae8d9dadeaaa5927da6f094389a560c12c05fec3d2711d2fa79292c7a7d7ad',
'com.google.dagger:dagger:2.43.2:dagger-2.43.2.jar:c89681f7cbbf8c527bf4ac2748515d617fdb54a1d425c08d914fdc28192b5fe4',
'com.google.devtools.ksp:symbol-processing-api:1.7.0-1.0.6:symbol-processing-api-1.7.0-1.0.6.jar:adc29417be5ca9ff42118105fea4e36d9ef44987abfc41432309371a60198941',
'com.google.errorprone:error_prone_annotations:2.7.1:error_prone_annotations-2.7.1.jar:cd5257c08a246cf8628817ae71cb822be192ef91f6881ca4a3fcff4f1de1cff3',
'com.google.errorprone:javac-shaded:9-dev-r4023-3:javac-shaded-9-dev-r4023-3.jar:65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30',
'com.google.googlejavaformat:google-java-format:1.5:google-java-format-1.5.jar:aa19ad7850fb85178aa22f2fddb163b84d6ce4d0035872f30d4408195ca1144e',
'com.google.guava:failureaccess:1.0.1:failureaccess-1.0.1.jar:a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26',
'com.google.guava:guava:27.1-jre:guava-27.1-jre.jar:4a5aa70cc968a4d137e599ad37553e5cfeed2265e8c193476d7119036c536fe7',
'com.google.guava:guava:31.0.1-jre:guava-31.0.1-jre.jar:d5be94d65e87bd219fb3193ad1517baa55a3b88fc91d21cf735826ab5af087b9',
'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava:listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99',
'com.google.j2objc:j2objc-annotations:1.1:j2objc-annotations-1.1.jar:2994a7eb78f2710bd3d3bfb639b2c94e219cedac0d4d084d516e78c16dddecf6',
'com.google.j2objc:j2objc-annotations:1.3:j2objc-annotations-1.3.jar:21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b',
'com.squareup.okhttp3:okhttp:3.12.13:okhttp-3.12.13.jar:508234e024ef7e270ab1a6d5b356f5b98e786511239ca986d684fd1e2cf7bc82',
'com.squareup.okio:okio:1.15.0:okio-1.15.0.jar:693fa319a7e8843300602b204023b7674f106ebcb577f2dd5807212b66118bd2',
'com.squareup:javapoet:1.13.0:javapoet-1.13.0.jar:4c7517e848a71b36d069d12bb3bf46a70fd4cda3105d822b0ed2e19c00b69291',
'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f',
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3',
'net.bytebuddy:byte-buddy:1.9.12:byte-buddy-1.9.12.jar:3688c3d434bebc3edc5516296a2ed0f47b65e451071b4afecad84f902f0efc11',
@@ -24,21 +26,22 @@ dependencyVerification {
'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0',
'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd',
'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047',
'org.briarproject:obfs4proxy-linux:0.0.14:obfs4proxy-linux-0.0.14.jar:6391d323d45a279362236c7c62e21b903d07d4f31f5e0c8d49d009769b720cc6',
'org.briarproject:obfs4proxy-windows:0.0.14:obfs4proxy-windows-0.0.14.jar:801d48525f52583a470a1671026b87992176d4432b299774989387cb87bc8ba3',
'org.briarproject:obfs4proxy-linux:0.0.14-tor1:obfs4proxy-linux-0.0.14-tor1.jar:9783b9c7ec588a5246f534a9c5782783c8c9821825f81c3e0c6f1ecee61cfcbb',
'org.briarproject:obfs4proxy-windows:0.0.14-tor1:obfs4proxy-windows-0.0.14-tor1.jar:9dd122b31b3cd1616f168091dcdb01de049d1e052fe5c089b7627618a8a2694b',
'org.briarproject:snowflake-linux:2.3.1:snowflake-linux-2.3.1.jar:99ecf4546d8f79eb8408168c09380fec596558ac934554bf7d4247ea7ef2c9f3',
'org.briarproject:snowflake-windows:2.3.1:snowflake-windows-2.3.1.jar:d011f1a72c00a221f56380c19aad8ff11db8c2bb1adb0784125572d80b4d275a',
'org.briarproject:tor-linux:0.4.5.14:tor-linux-0.4.5.14.jar:1844e54cf6df0c85cec219381a3364c759ae444a6b63f7558b757becb7d41d08',
'org.briarproject:tor-windows:0.4.5.14:tor-windows-0.4.5.14.jar:d337afa1043f0cfa7e6e8c2473d682a5663a2c8052bb97a770450893c78c9b4f',
'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d',
'org.checkerframework:checker-qual:2.5.2:checker-qual-2.5.2.jar:64b02691c8b9d4e7700f8ee2e742dce7ea2c6e81e662b7522c9ee3bf568c040a',
'org.codehaus.mojo:animal-sniffer-annotations:1.17:animal-sniffer-annotations-1.17.jar:92654f493ecfec52082e76354f0ebf87648dc3d5cec2e3c3cdb947c016747a53',
'org.briarproject:tor-linux:0.4.7.13:tor-linux-0.4.7.13.jar:9819ee973cbcdc133f7d04aef9d4b957a35087627a790e532142d15412a9636f',
'org.briarproject:tor-windows:0.4.7.13:tor-windows-0.4.7.13.jar:853d2769665614e26703cbe02e43b218b064c04a0bcd120fdc459cda45bd2606',
'org.checkerframework:checker-compat-qual:2.5.5:checker-compat-qual-2.5.5.jar:11d134b245e9cacc474514d2d66b5b8618f8039a1465cdc55bbc0b34e0008b7a',
'org.checkerframework:checker-qual:3.12.0:checker-qual-3.12.0.jar:ff10785ac2a357ec5de9c293cb982a2cbb605c0309ea4cc1cb9b9bc6dbe7f3cb',
'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9',
'org.hamcrest:hamcrest-library:2.1:hamcrest-library-2.1.jar:b7e2b6895b3b679f0e47b6380fda391b225e9b78505db9d8bdde8d3cc8d52a21',
'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050',
'org.jetbrains.kotlin:kotlin-stdlib-common:1.4.20:kotlin-stdlib-common-1.4.20.jar:a7112c9b3cefee418286c9c9372f7af992bd1e6e030691d52f60cb36dbec8320',
'org.jetbrains.kotlin:kotlin-stdlib:1.4.20:kotlin-stdlib-1.4.20.jar:b8ab1da5cdc89cb084d41e1f28f20a42bd431538642a5741c52bbfae3fa3e656',
'org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.1.0:kotlinx-metadata-jvm-0.1.0.jar:9753bb39efef35957c5c15df9a3cb769aabf2cdfa74b47afcb7760e5146be3b5',
'org.jetbrains.kotlin:kotlin-stdlib-common:1.7.0:kotlin-stdlib-common-1.7.0.jar:59c6ff64fe9a6604afce03e8aaa75f83586c6030ac71fb0b34ee7cdefed3618f',
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.0:kotlin-stdlib-jdk7-1.7.0.jar:07e91be9b2ca20672d2bdb7e181b766e73453a2da13492b5ddaee8fa47aea239',
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.0:kotlin-stdlib-jdk8-1.7.0.jar:cf058e11db1dfc9944680c8c61b95ac689aaaa8a3eb30bced028100f038f030b',
'org.jetbrains.kotlin:kotlin-stdlib:1.7.0:kotlin-stdlib-1.7.0.jar:aa88e9625577957f3249a46cb6e166ee09b369e600f7a11d148d16b0a6d87f05',
'org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.5.0:kotlinx-metadata-jvm-0.5.0.jar:ca063a96639b08b9eaa0de4d65e899480740a6efbe28ab9a8681a2ced03055a4',
'org.jetbrains:annotations:13.0:annotations-13.0.jar:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478',
'org.jmock:jmock-imposters:2.12.0:jmock-imposters-2.12.0.jar:3b836269745a137c9b2347e8d7c2104845b126ef04f012d6bfd94f1a7dea7b09',
'org.jmock:jmock-junit4:2.12.0:jmock-junit4-2.12.0.jar:3233062fc889637c151a24f1ee086bad04321ab7d8264fef279daff0fa27205b',

View File

@@ -13,7 +13,6 @@ src/main/res/values-iw
/fastlane/README.md
/fastlane/metadata/android/*/changelogs
# Local Fastlane installation
/fastlane/vendor
/fastlane/.bundle
/fastlane/Gemfile
/fastlane/Gemfile.lock
/vendor
/Gemfile
/Gemfile.lock

View File

@@ -9,7 +9,7 @@ source_lang = en
type = TXT
minimum_perc = 100
# https://support.google.com/googleplay/android-developer/answer/9844778?hl=en#zippy=%2Cview-list-of-available-languages
lang_map = de: de-DE, is: is-IS, ja: ja-JP, tr: tr-TR, zh-Hans: zh-CN, ru: ru-RU, sv: sv-SE, hu: hu-HU, it: it-IT, my: my-MM, en: en-US, es: es-ES, fr: fr-FR, gl: gl-ES, pl: pl-PL, el: el-GR
lang_map = de: de-DE, is: is-IS, ja: ja-JP, tr: tr-TR, zh-Hans: zh-CN, ru: ru-RU, sv: sv-SE, hu: hu-HU, it: it-IT, my: my-MM, en: en-US, es: es-ES, fr: fr-FR, gl: gl-ES, pl: pl-PL, el: el-GR, ka: ka-GE, pt-rBR: pt-BR
[o:otf:p:briar:r:google-play-short-description]
file_filter = fastlane/metadata/android/<lang>/short_description.txt
@@ -17,7 +17,7 @@ source_file = fastlane/metadata/android/en-US/short_description.txt
source_lang = en
type = TXT
minimum_perc = 100
lang_map = en: en-US, es: es-ES, is: is-IS, tr: tr-TR, gl: gl-ES, it: it-IT, my: my-MM, sv: sv-SE, zh-Hans: zh-CN, de: de-DE, ja: ja-JP, ru: ru-RU, fr: fr-FR, hu: hu-HU, pl: pl-PL, el: el-GR
lang_map = en: en-US, es: es-ES, is: is-IS, tr: tr-TR, gl: gl-ES, it: it-IT, my: my-MM, sv: sv-SE, zh-Hans: zh-CN, de: de-DE, ja: ja-JP, ru: ru-RU, fr: fr-FR, hu: hu-HU, pl: pl-PL, el: el-GR, ka: ka-GE, pt-rBR: pt-BR
[o:otf:p:briar:r:stringsxml-5]
file_filter = src/main/res/values-<lang>/strings.xml

View File

@@ -1,61 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="500" height="175" viewBox="0 0 500 175"
id="svg2" version="1.1" sodipodi:docname="bluetooth.svg" inkscape:version="1.0.2 (e86c870879, 2021-01-15)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="892"
id="namedview10"
showgrid="false"
inkscape:zoom="0.93337848"
inkscape:cx="-49.861215"
inkscape:cy="137.66042"
inkscape:window-x="0"
inkscape:window-y="144"
inkscape:window-maximized="0"
inkscape:current-layer="svg2" />
<defs
id="defs4" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<path
id="path4201"
d="m 459.80937,167.15983 -4.32657,-4.3343 -7.06956,-2.42737 c -3.88825,-1.33505 -8.72285,-2.99587 -10.74354,-3.6907 l -3.674,-1.26333 3.524,-0.1726 c 8.24183,-0.40367 12.98778,-4.00671 14.33634,-10.88389 0.79628,-4.06078 1.12887,-17.29805 0.83016,-33.04122 -0.15338,-8.08375 -0.16617,-15.41641 -0.0284,-16.29481 0.13775,-0.8784 0.53527,-2.42011 0.88339,-3.42602 1.22247,-3.53243 0.33996,-11.90828 -1.8577,-17.63146 -0.34848,-0.9075 -1.93434,-4.215 -3.52415,-7.35 -4.15849,-8.2003 -4.50458,-8.94188 -4.89292,-10.4841 -0.45865,-1.82145 -0.21161,-5.43531 0.4625,-6.7659 0.66625,-1.31505 2.15695,-2.91616 3.24622,-3.48662 1.29885,-0.68024 2.61568,0.12202 4.6864,2.85512 3.42153,4.51599 14.00135,19.44095 15.73191,22.19301 3.74551,5.95636 5.95558,11.16496 7.9722,18.78849 0.6547,2.475 1.88525,6.9975 2.73456,10.05 0.84931,3.0525 2.71404,10.15792 4.14385,15.78983 l 2.59964,10.23983 4.65,5.19319 c 2.5575,2.85626 5.7975,6.46371 7.2,8.01657 1.4025,1.55286 2.55,2.97543 2.55,3.16127 0,0.33546 -34.49955,29.29931 -34.89913,29.29931 -0.11475,0 -2.15559,-1.95044 -4.5352,-4.3343 z M 365.9443,150.77206 c -1.25762,-0.62844 -2.20557,-1.3788 -2.91402,-2.30663 -2.08931,-2.73629 -1.95034,2.36868 -1.86433,-68.48249 l 0.0777,-64.03881 0.66066,-1.23494 c 1.0152,-1.89767 1.99201,-2.91087 3.73952,-3.87887 l 1.59982,-0.88619 37.78387,-0.0796 c 42.45592,-0.0894 39.40239,-0.2483 42.11646,2.19188 0.87544,0.78709 1.75715,1.95946 2.18393,2.90385 0.71264,1.57698 0.71613,1.63839 0.80561,14.20405 l 0.0899,12.62022 -1.79817,-0.13007 c -1.42577,-0.10313 -2.08143,0.007 -3.16601,0.5321 -2.01294,0.97445 -3.93993,2.89871 -5.11476,5.10753 l -1.03717,1.95 -0.007,-12.825 -0.007,-12.825 h -33.6 -33.6 v 51.3 51.3 h 33.59873 33.59874 l 0.0763,-34.425 c 0.073,-32.96021 0.0982,-34.36117 0.59098,-32.925 0.28309,0.825 1.80562,3.9975 3.3834,7.05 5.49252,10.62624 5.40494,9.86009 5.39597,47.20335 -0.007,27.62122 -0.12358,29.95084 -1.66204,33.10906 -1.07144,2.19949 -2.71143,3.71042 -5.05823,4.66019 l -1.67381,0.6774 -36.1677,0.0797 -36.16769,0.0797 -1.864,-0.93145 z m 42.39939,-5.03813 c 2.87119,-1.30885 4.45771,-3.6784 4.43003,-6.61652 -0.0388,-4.11587 -3.1088,-7.22328 -7.1364,-7.22328 -2.11956,0 -3.56727,0.60889 -5.16364,2.17177 -2.24518,2.19807 -2.75398,5.43897 -1.30101,8.28704 0.71312,1.39782 2.52137,3.00905 3.96214,3.53045 1.49707,0.54176 3.84003,0.47454 5.20888,-0.14946 z"
style="fill:#000000;stroke:none" />
<path
id="path4201-1"
d="m 39.434334,167.15983 4.32657,-4.3343 7.06956,-2.42737 c 3.88825,-1.33505 8.72285,-2.99587 10.74354,-3.6907 l 3.674,-1.26333 -3.524,-0.1726 c -8.24183,-0.40367 -12.98778,-4.00671 -14.33634,-10.88389 -0.79628,-4.06078 -1.12887,-17.29805 -0.83016,-33.04122 0.15338,-8.08375 0.16617,-15.41641 0.0284,-16.29481 -0.13775,-0.8784 -0.53527,-2.42011 -0.88339,-3.42602 -1.22247,-3.53243 -0.33996,-11.90828 1.8577,-17.63146 0.34848,-0.9075 1.93434,-4.215 3.52415,-7.35 4.15849,-8.2003 4.50458,-8.94188 4.89292,-10.4841 0.45865,-1.82145 0.21161,-5.43531 -0.4625,-6.7659 -0.66625,-1.31505 -2.15695,-2.91616 -3.24622,-3.48662 -1.29885,-0.68024 -2.61568,0.12202 -4.6864,2.85512 -3.42153,4.51599 -14.00135,19.44095 -15.73191,22.19301 -3.74551,5.95636 -5.955584,11.16496 -7.972204,18.78849 -0.6547,2.475 -1.88525,6.9975 -2.73456,10.05 -0.84931,3.0525 -2.71404,10.15792 -4.14385,15.78983 L 14.4,125.82379 9.75,131.01698 c -2.5575,2.85626 -5.7975,6.46371 -7.2,8.01657 -1.4025,1.55286 -2.55,2.97543 -2.55,3.16127 0,0.33546 34.499554,29.29931 34.899134,29.29931 0.11475,0 2.15559,-1.95044 4.53519,-4.3343 z m 93.865056,-16.38777 c 1.25762,-0.62844 2.20557,-1.3788 2.91402,-2.30663 2.08931,-2.73629 1.95034,2.36868 1.86433,-68.48249 l -0.0777,-64.03881 -0.66066,-1.23494 c -1.0152,-1.89767 -1.99201,-2.91087 -3.73952,-3.87887 L 132.00004,9.94413 94.216184,9.86453 c -42.45592,-0.0894 -39.40239,-0.2483 -42.11646,2.19188 -0.87544,0.78709 -1.75715,1.95946 -2.18393,2.90385 -0.71264,1.57698 -0.71613,1.63839 -0.80561,14.20405 l -0.0899,12.62022 1.79817,-0.13007 c 1.42577,-0.10313 2.08143,0.007 3.16601,0.5321 2.01294,0.97445 3.93993,2.89871 5.11476,5.10753 l 1.03717,1.95 0.007,-12.825 0.007,-12.825 h 33.6 33.599986 v 51.3 51.3 H 93.751664 60.152924 l -0.0763,-34.425 c -0.073,-32.96021 -0.0982,-34.36117 -0.59098,-32.925 -0.28309,0.825 -1.80562,3.9975 -3.3834,7.05 -5.49252,10.62624 -5.40494,9.86009 -5.39597,47.20335 0.007,27.62122 0.12358,29.95084 1.66204,33.10906 1.07144,2.19949 2.71143,3.71042 5.05823,4.66019 l 1.67381,0.6774 36.1677,0.0797 36.167676,0.0797 1.864,-0.93145 z m -42.399376,-5.03813 c -2.87119,-1.30885 -4.45771,-3.6784 -4.43003,-6.61652 0.0388,-4.11587 3.1088,-7.22328 7.1364,-7.22328 2.11956,0 3.56727,0.60889 5.16364,2.17177 2.245176,2.19807 2.753976,5.43897 1.301006,8.28704 -0.713116,1.39782 -2.521366,3.00905 -3.962136,3.53045 -1.49707,0.54176 -3.84003,0.47454 -5.20888,-0.14946 z"
style="fill:#000000;stroke:none" />
<path
id="rect4270"
d="m 247.25369,71.97921 h 4.73637 c 13.16497,0 23.76348,10.598514 23.76348,23.763485 v 32.174615 c 0,13.16497 -10.59851,23.76348 -23.76348,23.76348 h -4.73637 c -13.16497,0 -23.76349,-10.59851 -23.76349,-23.76348 V 95.742695 c 0,-13.164971 10.59852,-23.763485 23.76349,-23.763485 z"
style="fill:#0a3d91;stroke:none" />
<path
id="path4844"
d="m 143.67921,23.5571 c -1.59043,2.623831 0.18153,5.574737 2.78461,6.642714 2.69504,1.572445 6.1706,4.987176 9.14793,2.232151 2.23313,-2.039515 0.60129,-5.727894 -2.04109,-6.67035 -3.06433,-1.676733 -6.55172,-5.514807 -9.89145,-2.204515 z M 351.7046,23.12937 c -2.76779,1.960623 -7.06819,2.694997 -8.37782,6.042717 -0.64195,2.73095 1.93572,4.99255 4.58419,4.426453 3.2021,-1.637914 7.05658,-2.8424 9.17849,-5.94769 0.56931,-2.60435 -1.49324,-5.35066 -4.26769,-4.745697 -0.41558,-0.107679 -0.76003,0.03505 -1.11717,0.224217 z m -26.76172,13.17187 c -2.93431,1.708015 -7.32039,1.922759 -8.93076,5.153004 -0.90775,2.654328 1.43202,5.159236 4.12365,4.861044 3.35587,-1.304271 7.31954,-2.112696 9.73662,-5.002268 0.81368,-2.537666 -0.97658,-5.469583 -3.79644,-5.128908 -0.4035,-0.14574 -0.75969,-0.03824 -1.13307,0.117128 z m -155.23633,2.46289 c -1.21948,2.711869 0.75683,5.460507 3.4437,6.14538 2.85847,1.080772 6.66937,4.11785 9.31224,1.23392 2.3151,-2.03652 0.33929,-5.835383 -2.40983,-6.41823 -3.32833,-1.175814 -7.38479,-4.713633 -10.34611,-0.96107 z m 127.27344,7.61719 c -3.12289,1.309174 -7.49226,0.970678 -9.49244,3.970097 -1.23184,2.518748 0.7727,5.298264 3.48037,5.339749 3.48706,-0.907308 7.56742,-1.1128 10.30314,-3.739116 1.11397,-2.422222 -0.31199,-5.546068 -3.1516,-5.551016 -0.3827,-0.195662 -0.75023,-0.126964 -1.13947,-0.01971 z m -97.49023,1.54492 c -2.22858,1.461838 -2.68005,4.865948 -0.27553,6.376909 2.5869,1.470583 5.91459,1.954941 8.83971,2.495346 2.78485,0.332188 4.74603,-2.479173 3.89118,-5.048668 -2.04264,-3.279676 -6.47206,-2.73364 -9.71704,-4.089227 -0.91277,0.08855 -1.82555,0.177093 -2.73832,0.26564 z m 68.51367,4.50782 c -3.27623,0.788856 -7.46081,-0.187875 -9.93635,2.381992 -1.64972,2.268076 -0.15709,5.353662 2.50432,5.86185 3.61172,-0.292365 7.71764,0.09072 10.84009,-2.093962 1.46245,-2.227649 0.52336,-5.531725 -2.28478,-5.959415 -0.34949,-0.249225 -0.72211,-0.239347 -1.12328,-0.190465 z m -39.44922,1.41796 c -1.93309,1.83595 -1.76537,5.266611 0.87081,6.321491 2.80857,0.988807 6.17065,0.846733 9.1444,0.861366 2.79909,-0.172766 4.22635,-3.289835 2.92376,-5.664738 -2.60365,-2.851635 -6.84699,-1.541752 -10.29251,-2.269899 -0.88215,0.250593 -1.76431,0.501187 -2.64646,0.75178 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#0a3d91;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:7.55;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:7.55, 22.65;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<path
d="m 252.50083,112.08988 11.6563,-11.45156 -17.12592,-19.790888 0.0193,25.792048 -9.14185,-9.24454 -3.12531,3.09064 11.5214,11.58063 -11.49773,11.30756 c 3.03061,3.05593 0,0 3.03061,3.05593 l 9.18921,-8.97308 c 0.0443,4.73517 0.004,27.16515 0.004,27.16515 l 17.10224,-20.77257 z m -1.07721,-19.570428 6.79869,7.863838 -6.79869,6.63278 z m -0.0237,40.027828 0.0237,-15.39623 6.89338,6.9879 z"
id="path1536"
style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.254891"
sodipodi:nodetypes="ccccccccccccccccccccc" />
</svg>

Before

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -1,91 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="162"
height="156"
viewBox="0 0 162 156"
fill="none"
version="1.1"
id="svg16"
sodipodi:docname="No-Posts.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)">
<metadata
id="metadata22">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs20" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="754"
inkscape:window-height="480"
id="namedview18"
showgrid="false"
inkscape:zoom="1.5128205"
inkscape:cx="81"
inkscape:cy="78"
inkscape:window-x="0"
inkscape:window-y="20"
inkscape:window-maximized="0"
inkscape:current-layer="svg16" />
<rect
width="80.9997"
height="78"
fill="black"
fill-opacity="0"
transform="scale(2)"
id="rect2" />
<rect
width="80.9997"
height="78"
fill="black"
fill-opacity="0"
transform="scale(2)"
id="rect4" />
<path
d="M140.87 53.647H91.5654V64.2352H140.87V53.647Z"
fill="white"
fill-opacity="0.6"
id="path6" />
<path
d="M140.869 99.5292V88.9409H115.512L126.077 99.5292H140.869Z"
fill="white"
fill-opacity="0.6"
id="path8" />
<path
d="M140.869 71.2939H97.9038L108.469 81.8822H140.869V71.2939Z"
fill="white"
fill-opacity="0.6"
id="path10" />
<path
d="M147.912 14.8232H41.5557L84.5209 57.8821V28.9409H147.912V120.706H147.208L157.773 131.294C160.59 128.47 161.999 124.941 161.999 120.706V28.9409C161.999 21.1762 155.66 14.8232 147.912 14.8232Z"
fill="white"
fill-opacity="0.6"
id="path12" />
<path
d="M129.6 120.706L84.5217 75.5294L23.9478 14.8235L9.15652 0L0 9.17647L10.5652 19.7647C8.45217 21.8824 7.04348 25.4118 7.04348 28.9412V120.706C7.04348 128.471 13.3826 134.824 21.1304 134.824H125.374L146.504 156L155.661 146.824L143.687 134.824L129.6 120.706ZM84.5217 120.706V93.8824L111.287 120.706H84.5217Z"
fill="white"
fill-opacity="0.6"
id="path14" />
</svg>

Before

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -1,56 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="164"
height="164"
viewBox="0 0 164 164"
fill="none"
version="1.1"
id="svg12"
sodipodi:docname="empty_state_contact_list.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)">
<metadata
id="metadata18">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs16" />
<sodipodi:namedview
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1020"
id="namedview14"
showgrid="false"
inkscape:zoom="1.4390244"
inkscape:cx="81.305085"
inkscape:cy="109.79661"
inkscape:window-x="1440"
inkscape:window-y="24"
inkscape:window-maximized="0"
inkscape:current-layer="svg12" />
<path
style="clip-rule:evenodd;display:inline;fill:#ffffff;fill-rule:evenodd"
d="M 27.333984 0 L 27.333984 13.666016 L 136.66797 13.666016 L 136.66797 0 L 27.333984 0 z M 27.333984 27.333984 C 19.817284 27.333984 13.666016 33.4834 13.666016 41 L 13.666016 123 C 13.666016 130.517 19.817284 136.66797 27.333984 136.66797 L 136.66797 136.66797 C 144.18397 136.66797 150.33203 130.517 150.33203 123 L 150.33203 41 C 150.33203 33.4834 144.18397 27.333984 136.66797 27.333984 L 27.333984 27.333984 z M 82.150391 44.757812 C 89.592295 44.757812 95.348492 46.476807 99.419922 49.914062 C 103.52467 53.351338 105.57617 58.23949 105.57617 64.580078 C 105.57617 67.349967 105.0272 69.869409 103.92578 72.138672 C 102.82458 74.407935 101.05521 76.728225 98.619141 79.097656 L 92.863281 84.453125 C 91.227921 86.021639 90.093094 87.640125 89.458984 89.308594 C 88.824874 90.943745 88.475053 93.030171 88.408203 95.566406 L 74.091797 95.566406 C 74.091797 90.694273 74.640917 86.855942 75.742188 84.052734 C 76.843435 81.216209 78.63001 78.762286 81.099609 76.693359 C 83.568995 74.624218 85.436853 72.739109 86.705078 71.037109 C 88.006403 69.30179 88.658203 67.400958 88.658203 65.332031 C 88.658203 60.292857 86.488795 57.771484 82.150391 57.771484 C 80.1481 57.771484 78.529614 58.506262 77.294922 59.974609 C 76.060186 61.442955 75.40854 63.42881 75.341797 65.931641 L 58.423828 65.931641 C 58.490468 59.25736 60.592402 54.067509 64.730469 50.363281 C 68.868538 46.625672 74.675257 44.757813 82.150391 44.757812 z M 81.398438 102.32422 C 84.068159 102.32422 86.287795 103.12473 88.056641 104.72656 C 89.858601 106.29508 90.759766 108.31381 90.759766 110.7832 C 90.759766 113.2528 89.858601 115.28879 88.056641 116.89062 C 86.287795 118.45914 84.068159 119.24219 81.398438 119.24219 C 78.728717 119.24219 76.493467 118.45914 74.691406 116.89062 C 72.922705 115.28879 72.039062 113.2528 72.039062 110.7832 C 72.039062 108.31381 72.922705 106.29508 74.691406 104.72656 C 76.493467 103.12473 78.728716 102.32422 81.398438 102.32422 z M 27.333984 150.33203 L 27.333984 164 L 136.66797 164 L 136.66797 150.33203 L 27.333984 150.33203 z "
id="path8" />
</svg>

Before

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -1,81 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="148"
height="148"
viewBox="0 0 148 148"
fill="none"
version="1.1"
id="svg12"
sodipodi:docname="No-Forums.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)">
<metadata
id="metadata18">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs16" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1366"
inkscape:window-height="720"
id="namedview14"
showgrid="false"
inkscape:zoom="1.5945946"
inkscape:cx="74"
inkscape:cy="74"
inkscape:window-x="0"
inkscape:window-y="20"
inkscape:window-maximized="1"
inkscape:current-layer="svg12" />
<rect
width="74"
height="74"
fill="black"
fill-opacity="0"
transform="scale(2)"
id="rect2" />
<rect
width="74"
height="74"
fill="black"
fill-opacity="0"
transform="scale(2)"
id="rect4" />
<path
d="M107.266 74.6791C111.34 74.6791 114.055 71.9635 114.055 67.8901V6.78901C114.055 2.7156 111.34 0 107.266 0H24.4404L99.1194 74.6791H107.266Z"
fill="white"
fill-opacity="0.6"
id="path6" />
<path
d="M141.211 27.156H127.633V88.2571H112.697L148 123.56V33.945C148 29.8716 144.606 27.156 141.211 27.156Z"
fill="white"
fill-opacity="0.6"
id="path8" />
<path
d="M8.8257 1.35742L0 10.1831L12.2202 22.4033V101.835L39.3762 74.6787H64.4955L78.0735 88.2567H39.3762V101.835C39.3762 105.908 42.0918 108.624 46.1652 108.624H98.4405L137.817 148L146.642 139.174L8.8257 1.35742Z"
fill="white"
fill-opacity="0.6"
id="path10" />
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -1,86 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="172"
height="140"
viewBox="0 0 172 140"
fill="none"
version="1.1"
id="svg14"
sodipodi:docname="No-Groups.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)">
<metadata
id="metadata20">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs18" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="754"
inkscape:window-height="480"
id="namedview16"
showgrid="false"
inkscape:zoom="1.6857143"
inkscape:cx="86"
inkscape:cy="70"
inkscape:window-x="0"
inkscape:window-y="20"
inkscape:window-maximized="0"
inkscape:current-layer="svg14" />
<rect
width="85.9999"
height="70"
fill="black"
fill-opacity="0"
transform="scale(2)"
id="rect2" />
<rect
width="85.9999"
height="70"
fill="black"
fill-opacity="0"
transform="scale(2)"
id="rect4" />
<path
d="M125.091 103.444L71.9274 50.5556L38.3092 17.1111L21.1091 0L10.9455 10.1111L31.2728 30.3333C31.2728 31.8889 31.2728 32.6667 31.2728 34.2222C31.2728 47.4444 41.4365 57.5556 54.7274 57.5556C56.291 57.5556 57.0729 57.5556 58.6365 56.7778L78.182 76.2222C69.582 74.6667 60.982 73.1111 54.7274 73.1111C36.7455 73.1111 0 82.4444 0 100.333V119.778H109.455V107.333L142.291 140L152.455 129.889L142.291 119.778L125.091 103.444Z"
fill="white"
fill-opacity="0.6"
id="path6" />
<path
d="M117.273 57.5549C130.227 57.5549 140.728 47.1082 140.728 34.2215C140.728 21.3349 130.227 10.8882 117.273 10.8882C104.319 10.8882 93.8184 21.3349 93.8184 34.2215C93.8184 47.1082 104.319 57.5549 117.273 57.5549Z"
fill="white"
fill-opacity="0.6"
id="path8" />
<path
d="M78.1819 34.2215C78.1819 20.9993 68.0182 10.8882 54.7273 10.8882C53.9455 10.8882 53.1637 10.8882 52.3818 10.8882L78.1819 36.5548C78.1819 35.7771 78.1819 34.9993 78.1819 34.2215Z"
fill="white"
fill-opacity="0.6"
id="path10" />
<path
d="M117.272 73.1104C116.49 73.1104 115.709 73.1104 114.927 73.1104L161.836 119.777H172V100.333C172 82.4437 135.254 73.1104 117.272 73.1104Z"
fill="white"
fill-opacity="0.6"
id="path12" />
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -0,0 +1,34 @@
<svg width="289" height="145" viewBox="0 0 289 145" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M48.8682 41C48.8682 36.5817 45.2864 33 40.8682 33H14.8682C10.4499 33 6.86816 36.5817 6.86816 41V103C6.86816 107.418 10.4499 111 14.8682 111H40.8682C45.2864 111 48.8682 107.418 48.8682 103V41Z" fill="#1E293B"/>
<path d="M48.8682 47.248H6.86834V101.248H48.8682V47.248Z" fill="#0B1120"/>
<path d="M11.4736 69.1006C11.4736 66.8914 13.2645 65.1006 15.4736 65.1006H40.2633C42.4724 65.1006 44.2633 66.8914 44.2633 69.1006V79.3936C44.2633 81.6028 42.4724 83.3936 40.2633 83.3936H15.4736C13.2645 83.3936 11.4736 81.6028 11.4736 79.3936V69.1006Z" fill="#184080"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.2358 71.5547C17.2358 71.1405 17.5716 70.8047 17.9858 70.8047H37.8583C38.2726 70.8047 38.6083 71.1405 38.6083 71.5547C38.6083 71.9689 38.2726 72.3047 37.8583 72.3047H17.9858C17.5716 72.3047 17.2358 71.9689 17.2358 71.5547Z" fill="#52ADF9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.2358 77.6523C17.2358 77.2381 17.5716 76.9023 17.9858 76.9023H28.6658C29.08 76.9023 29.4158 77.2381 29.4158 77.6523C29.4158 78.0666 29.08 78.4023 28.6658 78.4023H17.9858C17.5716 78.4023 17.2358 78.0666 17.2358 77.6523Z" fill="#52ADF9"/>
<path d="M27.8682 42.0024C27.3159 42.0024 26.8682 41.5541 26.8682 41.0012C26.8682 40.4482 27.3159 40 27.8682 40C28.4204 40 28.8682 40.4482 28.8682 41.0012C28.8682 41.5541 28.4204 42.0024 27.8682 42.0024Z" fill="#A3E635"/>
<path d="M19.1182 41.0244C19.1182 40.6102 19.454 40.2744 19.8682 40.2744H23.8682C24.2824 40.2744 24.6182 40.6102 24.6182 41.0244C24.6182 41.4386 24.2824 41.7744 23.8682 41.7744H19.8682C19.454 41.7744 19.1182 41.4386 19.1182 41.0244Z" fill="#A3E635"/>
<path d="M31.8682 40.2744C31.454 40.2744 31.1182 40.6102 31.1182 41.0244C31.1182 41.4386 31.454 41.7744 31.8682 41.7744H35.8682C36.2824 41.7744 36.6182 41.4386 36.6182 41.0244C36.6182 40.6102 36.2824 40.2744 35.8682 40.2744H31.8682Z" fill="#A3E635"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M48.8682 41V103C48.8682 107.418 45.2864 111 40.8682 111H14.8682C10.4499 111 6.86816 107.418 6.86816 103V41C6.86816 36.5817 10.4499 33 14.8682 33H40.8682C45.2864 33 48.8682 36.5817 48.8682 41ZM14.8682 34.5H40.8682C44.458 34.5 47.3682 37.4101 47.3682 41V47.248H8.36816V41C8.36816 37.4101 11.2783 34.5 14.8682 34.5ZM47.3682 48.748V99.748H8.36834V48.748H47.3682ZM47.3682 103V101.248H8.36816V103C8.36816 106.59 11.2783 109.5 14.8682 109.5H40.8682C44.458 109.5 47.3682 106.59 47.3682 103Z" fill="#A3E635"/>
<path d="M281.868 41C281.868 36.5817 278.286 33 273.868 33H247.868C243.45 33 239.868 36.5817 239.868 41V103C239.868 107.418 243.45 111 247.868 111H273.868C278.286 111 281.868 107.418 281.868 103V41Z" fill="#1E293B"/>
<path d="M281.868 47.248H239.868V101.248H281.868V47.248Z" fill="#0B1120"/>
<path d="M244.473 69.1006C244.473 66.8914 246.264 65.1006 248.473 65.1006H273.263C275.472 65.1006 277.263 66.8914 277.263 69.1006V79.3936C277.263 81.6028 275.472 83.3936 273.263 83.3936H248.473C246.264 83.3936 244.473 81.6028 244.473 79.3936V69.1006Z" fill="#365314"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M250.236 71.5547C250.236 71.1405 250.572 70.8047 250.986 70.8047H270.858C271.273 70.8047 271.608 71.1405 271.608 71.5547C271.608 71.9689 271.273 72.3047 270.858 72.3047H250.986C250.572 72.3047 250.236 71.9689 250.236 71.5547Z" fill="#A3E635"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M250.236 77.6523C250.236 77.2381 250.572 76.9023 250.986 76.9023H261.666C262.08 76.9023 262.416 77.2381 262.416 77.6523C262.416 78.0666 262.08 78.4023 261.666 78.4023H250.986C250.572 78.4023 250.236 78.0666 250.236 77.6523Z" fill="#A3E635"/>
<path d="M260.868 42.0024C260.316 42.0024 259.868 41.5541 259.868 41.0012C259.868 40.4482 260.316 40 260.868 40C261.42 40 261.868 40.4482 261.868 41.0012C261.868 41.5541 261.42 42.0024 260.868 42.0024Z" fill="#52ADF9"/>
<path d="M252.118 41.0244C252.118 40.6102 252.454 40.2744 252.868 40.2744H256.868C257.282 40.2744 257.618 40.6102 257.618 41.0244C257.618 41.4386 257.282 41.7744 256.868 41.7744H252.868C252.454 41.7744 252.118 41.4386 252.118 41.0244Z" fill="#52ADF9"/>
<path d="M264.868 40.2744C264.454 40.2744 264.118 40.6102 264.118 41.0244C264.118 41.4386 264.454 41.7744 264.868 41.7744H268.868C269.282 41.7744 269.618 41.4386 269.618 41.0244C269.618 40.6102 269.282 40.2744 268.868 40.2744H264.868Z" fill="#52ADF9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M281.868 41V103C281.868 107.418 278.286 111 273.868 111H247.868C243.45 111 239.868 107.418 239.868 103V41C239.868 36.5817 243.45 33 247.868 33H273.868C278.286 33 281.868 36.5817 281.868 41ZM247.868 34.5H273.868C277.458 34.5 280.368 37.4101 280.368 41V47.248H241.368V41C241.368 37.4101 244.278 34.5 247.868 34.5ZM280.368 48.748V99.748H241.368V48.748H280.368ZM280.368 103V101.248H241.368V103C241.368 106.59 244.278 109.5 247.868 109.5H273.868C277.458 109.5 280.368 106.59 280.368 103Z" fill="#52ADF9"/>
<path d="M150.868 54C150.868 49.5817 147.286 46 142.868 46H126.868C122.45 46 118.868 49.5817 118.868 54V70C118.868 74.4183 122.45 78 126.868 78H142.868C147.286 78 150.868 74.4183 150.868 70V54Z" fill="#1E293B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M126.868 47.5H142.868C146.458 47.5 149.368 50.4101 149.368 54V70C149.368 73.5899 146.458 76.5 142.868 76.5H126.868C123.278 76.5 120.368 73.5899 120.368 70V54C120.368 50.4101 123.278 47.5 126.868 47.5ZM142.868 46C147.286 46 150.868 49.5817 150.868 54V70C150.868 74.4183 147.286 78 142.868 78H126.868C122.45 78 118.868 74.4183 118.868 70V54C118.868 49.5817 122.45 46 126.868 46H142.868Z" fill="#52ADF9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M138.934 61.3778C139.519 62.63 139.295 64.1672 138.261 65.2012L134.282 69.1801C132.962 70.5002 130.822 70.5002 129.501 69.1801C128.181 67.8599 128.181 65.7194 129.501 64.3992L133.48 60.4203C134.515 59.386 136.052 59.162 137.305 59.7485L136.108 60.9452C135.551 60.8746 134.969 61.0533 134.541 61.481L130.562 65.4599C129.828 66.1943 129.828 67.385 130.562 68.1194C131.296 68.8538 132.487 68.8538 133.222 68.1194L137.2 64.1405C137.628 63.7132 137.806 63.1314 137.736 62.5749L138.934 61.3778Z" fill="#BEF264"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M132.432 64.25C133.684 64.8362 135.222 64.6123 136.256 63.578L140.235 59.5991C141.555 58.2789 141.555 56.1385 140.235 54.8183C138.915 53.4981 136.774 53.4981 135.454 54.8183L131.475 58.7971C130.441 59.8312 130.217 61.3686 130.803 62.6209L132 61.4239C131.93 60.8672 132.109 60.2852 132.536 59.8578L136.515 55.8789C137.249 55.1445 138.44 55.1445 139.174 55.8789C139.909 56.6133 139.909 57.8041 139.174 58.5385L135.196 62.5173C134.768 62.945 134.186 63.1236 133.629 63.0532L132.432 64.25Z" fill="#BEF264"/>
<path d="M169.868 73C169.868 68.5817 166.286 65 161.868 65H145.868C141.45 65 137.868 68.5817 137.868 73V89C137.868 93.4183 141.45 97 145.868 97H161.868C166.286 97 169.868 93.4183 169.868 89V73Z" fill="#1E293B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M145.868 66.5H161.868C165.458 66.5 168.368 69.4101 168.368 73V89C168.368 92.5899 165.458 95.5 161.868 95.5H145.868C142.278 95.5 139.368 92.5899 139.368 89V73C139.368 69.4101 142.278 66.5 145.868 66.5ZM161.868 65C166.286 65 169.868 68.5817 169.868 73V89C169.868 93.4183 166.286 97 161.868 97H145.868C141.45 97 137.868 93.4183 137.868 89V73C137.868 68.5817 141.45 65 145.868 65H161.868Z" fill="#A3E635"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M157.934 80.3778C158.519 81.63 158.295 83.1672 157.261 84.2012L153.282 88.18C151.962 89.5002 149.822 89.5002 148.501 88.18C147.181 86.8599 147.181 84.7194 148.501 83.3992L152.48 79.4203C153.515 78.386 155.052 78.162 156.305 78.7485L155.108 79.9452C154.551 79.8746 153.969 80.0532 153.541 80.481L149.562 84.4599C148.828 85.1943 148.828 86.385 149.562 87.1194C150.296 87.8538 151.487 87.8538 152.222 87.1194L156.2 83.1405C156.628 82.7132 156.806 82.1314 156.736 81.5749L157.934 80.3778Z" fill="#BEF264"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M151.432 83.25C152.684 83.8362 154.222 83.6123 155.256 82.578L159.235 78.5991C160.555 77.2789 160.555 75.1385 159.235 73.8183C157.915 72.4981 155.774 72.4981 154.454 73.8183L150.475 77.7971C149.441 78.8312 149.217 80.3686 149.803 81.6209L151 80.4239C150.93 79.8672 151.109 79.2852 151.536 78.8578L155.515 74.8789C156.249 74.1445 157.44 74.1445 158.174 74.8789C158.909 75.6133 158.909 76.8041 158.174 77.5385L154.196 81.5173C153.768 81.945 153.186 82.1236 152.629 82.0532L151.432 83.25Z" fill="#BEF264"/>
<path d="M87.8682 62C87.8682 64.2091 86.0773 66 83.8682 66C81.659 66 79.8682 64.2091 79.8682 62C79.8682 59.7909 81.659 58 83.8682 58C86.0773 58 87.8682 59.7909 87.8682 62Z" fill="#1457C5"/>
<path d="M103.868 62C103.868 64.2091 102.077 66 99.8682 66C97.659 66 95.8682 64.2091 95.8682 62C95.8682 59.7909 97.659 58 99.8682 58C102.077 58 103.868 59.7909 103.868 62Z" fill="#2B8EF1"/>
<path d="M71.8682 62C71.8682 64.2091 70.0773 66 67.8682 66C65.659 66 63.8682 64.2091 63.8682 62C63.8682 59.7909 65.659 58 67.8682 58C70.0773 58 71.8682 59.7909 71.8682 62Z" fill="#184080"/>
<path d="M200.868 81C200.868 78.7909 202.659 77 204.868 77C207.077 77 208.868 78.7909 208.868 81C208.868 83.2091 207.077 85 204.868 85C202.659 85 200.868 83.2091 200.868 81Z" fill="#4D7C0F"/>
<path d="M184.868 81C184.868 78.7909 186.659 77 188.868 77C191.077 77 192.868 78.7909 192.868 81C192.868 83.2091 191.077 85 188.868 85C186.659 85 184.868 83.2091 184.868 81Z" fill="#82C91E"/>
<path d="M216.868 81C216.868 78.7909 218.659 77 220.868 77C223.077 77 224.868 78.7909 224.868 81C224.868 83.2091 223.077 85 220.868 85C218.659 85 216.868 83.2091 216.868 81Z" fill="#365314"/>
</svg>

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -0,0 +1,40 @@
<svg width="289" height="145" viewBox="0 0 289 145" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M48.3203 41C48.3203 36.5817 44.7386 33 40.3203 33H14.3203C9.90203 33 6.32031 36.5817 6.32031 41V103C6.32031 107.418 9.90203 111 14.3203 111H40.3203C44.7386 111 48.3203 107.418 48.3203 103V41Z" fill="#ECFCCB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.3203 34.5H40.3203C43.9102 34.5 46.8203 37.4101 46.8203 41V103C46.8203 106.59 43.9102 109.5 40.3203 109.5H14.3203C10.7305 109.5 7.82031 106.59 7.82031 103V41C7.82031 37.4101 10.7305 34.5 14.3203 34.5ZM40.3203 33C44.7386 33 48.3203 36.5817 48.3203 41V103C48.3203 107.418 44.7386 111 40.3203 111H14.3203C9.90203 111 6.32031 107.418 6.32031 103V41C6.32031 36.5817 9.90203 33 14.3203 33H40.3203Z" fill="#65A30D"/>
<path d="M48.3203 47.248H6.32049V101.248H48.3203V47.248Z" fill="#F9FAFB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.82049 48.748H46.8203V99.748H7.82049V48.748ZM48.3203 47.248V101.248H6.32049V47.248H48.3203Z" fill="#65A30D"/>
<path d="M10.9258 69.1006C10.9258 66.8914 12.7166 65.1006 14.9258 65.1006H39.7154C41.9245 65.1006 43.7154 66.8914 43.7154 69.1006V79.3936C43.7154 81.6028 41.9245 83.3936 39.7154 83.3936H14.9258C12.7166 83.3936 10.9258 81.6028 10.9258 79.3936V69.1006Z" fill="#DDEDFE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.6885 71.5547C16.6885 71.1405 17.0243 70.8047 17.4385 70.8047H37.311C37.7252 70.8047 38.061 71.1405 38.061 71.5547C38.061 71.9689 37.7252 72.3047 37.311 72.3047H17.4385C17.0243 72.3047 16.6885 71.9689 16.6885 71.5547Z" fill="#196FDE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.6885 77.6523C16.6885 77.2381 17.0243 76.9023 17.4385 76.9023H28.1185C28.5327 76.9023 28.8685 77.2381 28.8685 77.6523C28.8685 78.0666 28.5327 78.4023 28.1185 78.4023H17.4385C17.0243 78.4023 16.6885 78.0666 16.6885 77.6523Z" fill="#196FDE"/>
<path d="M26.3203 41.0012C26.3203 41.5541 26.768 42.0024 27.3203 42.0024C27.8726 42.0024 28.3203 41.5541 28.3203 41.0012C28.3203 40.4482 27.8726 40 27.3203 40C26.768 40 26.3203 40.4482 26.3203 41.0012Z" fill="#65A30D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.5703 41.0244C18.5703 40.6102 18.9061 40.2744 19.3203 40.2744H23.3203C23.7345 40.2744 24.0703 40.6102 24.0703 41.0244C24.0703 41.4386 23.7345 41.7744 23.3203 41.7744H19.3203C18.9061 41.7744 18.5703 41.4386 18.5703 41.0244Z" fill="#65A30D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M30.5703 41.0244C30.5703 40.6102 30.9061 40.2744 31.3203 40.2744H35.3203C35.7345 40.2744 36.0703 40.6102 36.0703 41.0244C36.0703 41.4386 35.7345 41.7744 35.3203 41.7744H31.3203C30.9061 41.7744 30.5703 41.4386 30.5703 41.0244Z" fill="#65A30D"/>
<path d="M150.32 54C150.32 49.5817 146.739 46 142.32 46H126.32C121.902 46 118.32 49.5817 118.32 54V70C118.32 74.4183 121.902 78 126.32 78H142.32C146.739 78 150.32 74.4183 150.32 70V54Z" fill="#DDEDFE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M126.32 47.5H142.32C145.91 47.5 148.82 50.4101 148.82 54V70C148.82 73.5899 145.91 76.5 142.32 76.5H126.32C122.73 76.5 119.82 73.5899 119.82 70V54C119.82 50.4101 122.73 47.5 126.32 47.5ZM142.32 46C146.739 46 150.32 49.5817 150.32 54V70C150.32 74.4183 146.739 78 142.32 78H126.32C121.902 78 118.32 74.4183 118.32 70V54C118.32 49.5817 121.902 46 126.32 46H142.32Z" fill="#196FDE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M132.932 60.4207C134.253 59.1005 136.393 59.1005 137.713 60.4207C139.033 61.7409 139.033 63.8814 137.713 65.2015L133.734 69.1804C132.414 70.5006 130.274 70.5006 128.953 69.1804C127.633 67.8602 127.633 65.7197 128.953 64.3996L132.932 60.4207ZM136.653 61.4814C135.918 60.7469 134.727 60.7469 133.993 61.4814L130.014 65.4602C129.28 66.1946 129.28 67.3853 130.014 68.1197C130.749 68.8541 131.939 68.8541 132.674 68.1197L136.653 64.1409C137.387 63.4065 137.387 62.2158 136.653 61.4814Z" fill="#BEF264"/>
<path d="M137.184 59.3223L138.813 60.9512L137.184 62.5802L135.555 60.9512L137.184 59.3223Z" fill="#D9D9D9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M135.708 63.5783C134.388 64.8985 132.248 64.8985 130.927 63.5783C129.607 62.2581 129.607 60.1177 130.927 58.7975L134.906 54.8186C136.226 53.4984 138.367 53.4984 139.687 54.8186C141.007 56.1388 141.007 58.2793 139.687 59.5995L135.708 63.5783ZM131.988 62.5177C132.723 63.2521 133.913 63.2521 134.648 62.5177L138.626 58.5388C139.361 57.8044 139.361 56.6137 138.626 55.8793C137.892 55.1449 136.701 55.1449 135.967 55.8793L131.988 59.8581C131.254 60.5925 131.254 61.7833 131.988 62.5177Z" fill="#BEF264"/>
<path d="M131.457 64.6768L129.828 63.0478L131.457 61.4189L133.086 63.0478L131.457 64.6768Z" fill="#D9D9D9"/>
<path d="M281.32 41C281.32 36.5817 277.739 33 273.32 33H247.32C242.902 33 239.32 36.5817 239.32 41V103C239.32 107.418 242.902 111 247.32 111H273.32C277.739 111 281.32 107.418 281.32 103V41Z" fill="#DDEDFE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M247.32 34.5H273.32C276.91 34.5 279.82 37.4101 279.82 41V103C279.82 106.59 276.91 109.5 273.32 109.5H247.32C243.73 109.5 240.82 106.59 240.82 103V41C240.82 37.4101 243.73 34.5 247.32 34.5ZM273.32 33C277.739 33 281.32 36.5817 281.32 41V103C281.32 107.418 277.739 111 273.32 111H247.32C242.902 111 239.32 107.418 239.32 103V41C239.32 36.5817 242.902 33 247.32 33H273.32Z" fill="#196FDE"/>
<path d="M281.32 47.248H239.32V101.248H281.32V47.248Z" fill="#F9FAFB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M240.82 48.748H279.82V99.748H240.82V48.748ZM281.32 47.248V101.248H239.32V47.248H281.32Z" fill="#196FDE"/>
<path d="M243.925 69.1006C243.925 66.8914 245.716 65.1006 247.925 65.1006H272.715C274.924 65.1006 276.715 66.8914 276.715 69.1006V79.3936C276.715 81.6028 274.924 83.3936 272.715 83.3936H247.925C245.716 83.3936 243.925 81.6028 243.925 79.3936V69.1006Z" fill="#ECFCCB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M249.688 71.5547C249.688 71.1405 250.023 70.8047 250.438 70.8047H270.31C270.724 70.8047 271.06 71.1405 271.06 71.5547C271.06 71.9689 270.724 72.3047 270.31 72.3047H250.438C250.023 72.3047 249.688 71.9689 249.688 71.5547Z" fill="#65A30D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M249.688 77.6523C249.688 77.2381 250.023 76.9023 250.438 76.9023H261.117C261.532 76.9023 261.867 77.2381 261.867 77.6523C261.867 78.0666 261.532 78.4023 261.117 78.4023H250.438C250.023 78.4023 249.688 78.0666 249.688 77.6523Z" fill="#65A30D"/>
<path d="M259.32 41.0012C259.32 41.5541 259.768 42.0024 260.32 42.0024C260.873 42.0024 261.32 41.5541 261.32 41.0012C261.32 40.4482 260.873 40 260.32 40C259.768 40 259.32 40.4482 259.32 41.0012Z" fill="#196FDE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M251.57 41.0244C251.57 40.6102 251.906 40.2744 252.32 40.2744H256.32C256.735 40.2744 257.07 40.6102 257.07 41.0244C257.07 41.4386 256.735 41.7744 256.32 41.7744H252.32C251.906 41.7744 251.57 41.4386 251.57 41.0244Z" fill="#196FDE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M263.57 41.0244C263.57 40.6102 263.906 40.2744 264.32 40.2744H268.32C268.735 40.2744 269.07 40.6102 269.07 41.0244C269.07 41.4386 268.735 41.7744 268.32 41.7744H264.32C263.906 41.7744 263.57 41.4386 263.57 41.0244Z" fill="#196FDE"/>
<path d="M169.32 73C169.32 68.5817 165.739 65 161.32 65H145.32C140.902 65 137.32 68.5817 137.32 73V89C137.32 93.4183 140.902 97 145.32 97H161.32C165.739 97 169.32 93.4183 169.32 89V73Z" fill="#ECFCCB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M145.32 66.5H161.32C164.91 66.5 167.82 69.4101 167.82 73V89C167.82 92.5899 164.91 95.5 161.32 95.5H145.32C141.73 95.5 138.82 92.5899 138.82 89V73C138.82 69.4101 141.73 66.5 145.32 66.5ZM161.32 65C165.739 65 169.32 68.5817 169.32 73V89C169.32 93.4183 165.739 97 161.32 97H145.32C140.902 97 137.32 93.4183 137.32 89V73C137.32 68.5817 140.902 65 145.32 65H161.32Z" fill="#65A30D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M151.932 79.4207C153.253 78.1005 155.393 78.1005 156.713 79.4207C158.033 80.7409 158.033 82.8814 156.713 84.2015L152.734 88.1804C151.414 89.5006 149.274 89.5006 147.953 88.1804C146.633 86.8602 146.633 84.7197 147.953 83.3996L151.932 79.4207ZM155.653 80.4814C154.918 79.7469 153.727 79.7469 152.993 80.4814L149.014 84.4602C148.28 85.1946 148.28 86.3853 149.014 87.1197C149.749 87.8541 150.939 87.8541 151.674 87.1197L155.653 83.1409C156.387 82.4065 156.387 81.2158 155.653 80.4814Z" fill="#BEF264"/>
<path d="M156.184 78.3223L157.813 79.9512L156.184 81.5802L154.555 79.9512L156.184 78.3223Z" fill="#D9D9D9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M154.708 82.5783C153.388 83.8985 151.248 83.8985 149.927 82.5783C148.607 81.2581 148.607 79.1177 149.927 77.7975L153.906 73.8186C155.226 72.4984 157.367 72.4984 158.687 73.8186C160.007 75.1388 160.007 77.2793 158.687 78.5995L154.708 82.5783ZM150.988 81.5177C151.723 82.2521 152.913 82.2521 153.648 81.5177L157.626 77.5388C158.361 76.8044 158.361 75.6137 157.626 74.8793C156.892 74.1449 155.701 74.1449 154.967 74.8793L150.988 78.8581C150.254 79.5925 150.254 80.7833 150.988 81.5177Z" fill="#BEF264"/>
<path d="M150.457 83.6768L148.828 82.0478L150.457 80.4189L152.086 82.0478L150.457 83.6768Z" fill="#D9D9D9"/>
<path d="M87.3203 62C87.3203 64.2091 85.5295 66 83.3203 66C81.1112 66 79.3203 64.2091 79.3203 62C79.3203 59.7909 81.1112 58 83.3203 58C85.5295 58 87.3203 59.7909 87.3203 62Z" fill="#8BCAFD"/>
<path d="M103.32 62C103.32 64.2091 101.529 66 99.3203 66C97.1112 66 95.3203 64.2091 95.3203 62C95.3203 59.7909 97.1112 58 99.3203 58C101.529 58 103.32 59.7909 103.32 62Z" fill="#52ADF9"/>
<path d="M71.3203 62C71.3203 64.2091 69.5295 66 67.3203 66C65.1112 66 63.3203 64.2091 63.3203 62C63.3203 59.7909 65.1112 58 67.3203 58C69.5295 58 71.3203 59.7909 71.3203 62Z" fill="#BDDFFE"/>
<path d="M200.32 81C200.32 78.7909 202.111 77 204.32 77C206.529 77 208.32 78.7909 208.32 81C208.32 83.2091 206.529 85 204.32 85C202.111 85 200.32 83.2091 200.32 81Z" fill="#BEF264"/>
<path d="M184.32 81C184.32 78.7909 186.111 77 188.32 77C190.529 77 192.32 78.7909 192.32 81C192.32 83.2091 190.529 85 188.32 85C186.111 85 184.32 83.2091 184.32 81Z" fill="#A3E635"/>
<path d="M216.32 81C216.32 78.7909 218.111 77 220.32 77C222.529 77 224.32 78.7909 224.32 81C224.32 83.2091 222.529 85 220.32 85C218.111 85 216.32 83.2091 216.32 81Z" fill="#D9F99D"/>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -0,0 +1,45 @@
<svg width="193" height="192" viewBox="0 0 193 192" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M41.8016 13.7002H95.8016C102.002 13.7002 107.002 18.7002 107.002 24.9002V145.9C107.002 152.1 102.002 157.1 95.8016 157.1H41.8016C35.6016 157.1 30.6016 152.1 30.6016 145.9V25.0002C30.6016 18.7002 35.6016 13.7002 41.8016 13.7002Z" fill="#1E293B"/>
<path d="M100.101 40.5999C100.101 36.5999 96.9012 33.3999 92.9012 33.3999H44.9012C40.9012 33.3999 37.7012 36.5999 37.7012 40.5999V136.6C37.7012 140.6 40.9012 143.8 44.9012 143.8H92.9012C96.9012 143.8 100.101 140.6 100.101 136.6V40.5999Z" fill="#0B1120"/>
<path d="M95.8013 13H41.8013C35.2013 13 29.8013 18.4 29.8013 25V146C29.8013 152.6 35.2013 158 41.8013 158H95.8013C102.401 158 107.801 152.6 107.801 146V25C107.801 18.3 102.501 13 95.8013 13ZM106.301 146C106.301 151.8 101.601 156.5 95.8013 156.5H41.8013C36.0013 156.5 31.3013 151.8 31.3013 146V25C31.3013 19.2 36.0013 14.5 41.8013 14.5H95.8013C101.601 14.5 106.301 19.2 106.301 25V146Z" fill="#52ADF9"/>
<path d="M68.8013 26.8999C70.5013 26.8999 71.8013 25.5999 71.8013 23.8999C71.8013 22.1999 70.5013 20.8999 68.8013 20.8999C67.1013 20.8999 65.8013 22.1999 65.8013 23.8999C65.8013 25.5999 67.2013 26.8999 68.8013 26.8999ZM68.8013 22.3999C69.6013 22.3999 70.3013 23.0999 70.3013 23.8999C70.3013 24.6999 69.6013 25.3999 68.8013 25.3999C68.0013 25.3999 67.3013 24.6999 67.3013 23.8999C67.3013 23.0999 68.0013 22.3999 68.8013 22.3999Z" fill="#52ADF9"/>
<path d="M50.8015 24.3998H60.8015C61.2015 24.3998 61.6015 24.0998 61.6015 23.5998C61.6015 23.0998 61.3015 22.7998 60.8015 22.7998H50.8015C50.4015 22.7998 50.0015 23.0998 50.0015 23.5998C50.0015 24.0998 50.4015 24.3998 50.8015 24.3998Z" fill="#52ADF9"/>
<path d="M76.8015 24.3998H86.8015C87.2015 24.3998 87.6015 24.0998 87.6015 23.5998C87.6015 23.0998 87.3015 22.7998 86.8015 22.7998H76.8015C76.4015 22.7998 76.0015 23.0998 76.0015 23.5998C76.0015 24.0998 76.4015 24.3998 76.8015 24.3998Z" fill="#52ADF9"/>
<path d="M92.8013 32.6001H44.8013C40.4013 32.6001 36.8013 36.2001 36.8013 40.6001V136.6C36.8013 141 40.4013 144.6 44.8013 144.6H92.8013C97.2013 144.6 100.801 141 100.801 136.6V40.6001C100.801 36.2001 97.2013 32.6001 92.8013 32.6001ZM99.3013 136.6C99.3013 140.2 96.4013 143.1 92.8013 143.1H44.8013C41.2013 143.1 38.3013 140.2 38.3013 136.6V40.6001C38.3013 37.0001 41.2013 34.1001 44.8013 34.1001H92.8013C96.4013 34.1001 99.3013 37.0001 99.3013 40.6001V136.6Z" fill="#52ADF9"/>
<path d="M90.8016 45.8002H61.4016C61.0016 45.8002 60.6016 45.5002 60.6016 45.0002C60.6016 44.5002 60.9016 44.2002 61.4016 44.2002H90.9016C91.3016 44.2002 91.7016 44.5002 91.7016 45.0002C91.7016 45.5002 91.2016 45.8002 90.8016 45.8002Z" fill="#184080"/>
<path d="M77.2016 51.7001H61.4016C61.0016 51.7001 60.6016 51.4001 60.6016 50.9001C60.6016 50.4001 60.9016 50.1001 61.4016 50.1001H77.2016C77.6016 50.1001 78.0016 50.4001 78.0016 50.9001C78.0016 51.4001 77.6016 51.7001 77.2016 51.7001Z" fill="#184080"/>
<path d="M90.8016 87.8002H61.4016C61.0016 87.8002 60.6016 87.5002 60.6016 87.0002C60.6016 86.5002 60.9016 86.2002 61.4016 86.2002H90.9016C91.3016 86.2002 91.7016 86.5002 91.7016 87.0002C91.7016 87.5002 91.2016 87.8002 90.8016 87.8002Z" fill="#184080"/>
<path d="M77.2016 93.7001H61.4016C61.0016 93.7001 60.6016 93.4001 60.6016 92.9001C60.6016 92.4001 60.9016 92.1001 61.4016 92.1001H77.2016C77.6016 92.1001 78.0016 92.4001 78.0016 92.9001C78.0016 93.4001 77.6016 93.7001 77.2016 93.7001Z" fill="#184080"/>
<path d="M90.8016 66.8002H61.4016C61.0016 66.8002 60.6016 66.5002 60.6016 66.0002C60.6016 65.5002 60.9016 65.2002 61.4016 65.2002H90.9016C91.3016 65.2002 91.7016 65.5002 91.7016 66.0002C91.7016 66.5002 91.2016 66.8002 90.8016 66.8002Z" fill="#184080"/>
<path d="M77.2016 72.7001H61.4016C61.0016 72.7001 60.6016 72.4001 60.6016 71.9001C60.6016 71.4001 60.9016 71.1001 61.4016 71.1001H77.2016C77.6016 71.1001 78.0016 71.4001 78.0016 71.9001C78.0016 72.4001 77.6016 72.7001 77.2016 72.7001Z" fill="#184080"/>
<path d="M90.8016 129.8H61.4016C61.0016 129.8 60.6016 129.5 60.6016 129C60.6016 128.5 60.9016 128.2 61.4016 128.2H90.9016C91.3016 128.2 91.7016 128.5 91.7016 129C91.7016 129.5 91.2016 129.8 90.8016 129.8Z" fill="#184080"/>
<path d="M77.2016 135.7H61.4016C61.0016 135.7 60.6016 135.4 60.6016 134.9C60.6016 134.4 60.9016 134.1 61.4016 134.1H77.2016C77.6016 134.1 78.0016 134.4 78.0016 134.9C78.0016 135.4 77.6016 135.7 77.2016 135.7Z" fill="#184080"/>
<path d="M90.8016 108.8H61.4016C61.0016 108.8 60.6016 108.5 60.6016 108C60.6016 107.5 60.9016 107.2 61.4016 107.2H90.9016C91.3016 107.2 91.7016 107.5 91.7016 108C91.7016 108.5 91.2016 108.8 90.8016 108.8Z" fill="#184080"/>
<path d="M77.2016 114.7H61.4016C61.0016 114.7 60.6016 114.4 60.6016 113.9C60.6016 113.4 60.9016 113.1 61.4016 113.1H77.2016C77.6016 113.1 78.0016 113.4 78.0016 113.9C78.0016 114.4 77.6016 114.7 77.2016 114.7Z" fill="#184080"/>
<path d="M96.8016 34.7998H150.802C157.002 34.7998 162.002 39.7998 162.002 45.9998V167C162.002 173.2 157.002 178.2 150.802 178.2H96.8016C90.6016 178.2 85.6016 173.2 85.6016 167V45.9998C85.6016 39.7998 90.6016 34.7998 96.8016 34.7998Z" fill="#1E293B"/>
<path d="M155.101 61.5999C155.101 57.5999 151.901 54.3999 147.901 54.3999H99.9012C95.9012 54.3999 92.7012 57.5999 92.7012 61.5999V157.6C92.7012 161.6 95.9012 164.8 99.9012 164.8H147.901C151.901 164.8 155.101 161.6 155.101 157.6V61.5999Z" fill="#0B1120"/>
<path d="M150.801 34H96.8013C90.2013 34 84.8013 39.4 84.8013 46V167C84.8013 173.6 90.2013 179 96.8013 179H150.801C157.401 179 162.801 173.6 162.801 167V46C162.801 39.4 157.501 34 150.801 34ZM161.301 167C161.301 172.8 156.601 177.5 150.801 177.5H96.8013C91.0013 177.5 86.3013 172.8 86.3013 167V46C86.3013 40.2 91.0013 35.5 96.8013 35.5H150.801C156.601 35.5 161.301 40.2 161.301 46V167Z" fill="#A3E635"/>
<path d="M123.801 47.8999C125.501 47.8999 126.801 46.5999 126.801 44.8999C126.801 43.1999 125.501 41.8999 123.801 41.8999C122.101 41.8999 120.801 43.1999 120.801 44.8999C120.801 46.5999 122.201 47.8999 123.801 47.8999ZM123.801 43.3999C124.601 43.3999 125.301 44.0999 125.301 44.8999C125.301 45.6999 124.601 46.3999 123.801 46.3999C123.001 46.3999 122.301 45.6999 122.301 44.8999C122.301 44.0999 123.001 43.3999 123.801 43.3999Z" fill="#A3E635"/>
<path d="M105.801 45.3998H115.801C116.201 45.3998 116.601 45.0998 116.601 44.5998C116.601 44.0998 116.301 43.7998 115.801 43.7998H105.801C105.401 43.7998 105.001 44.0998 105.001 44.5998C105.001 45.0998 105.401 45.3998 105.801 45.3998Z" fill="#A3E635"/>
<path d="M131.801 45.3998H141.801C142.201 45.3998 142.601 45.0998 142.601 44.5998C142.601 44.0998 142.301 43.7998 141.801 43.7998H131.801C131.401 43.7998 131.001 44.0998 131.001 44.5998C131.001 45.0998 131.401 45.3998 131.801 45.3998Z" fill="#A3E635"/>
<path d="M147.801 53.6001H99.8013C95.4013 53.6001 91.8013 57.2001 91.8013 61.6001V157.6C91.8013 162 95.4013 165.6 99.8013 165.6H147.801C152.201 165.6 155.801 162 155.801 157.6V61.6001C155.801 57.2001 152.201 53.6001 147.801 53.6001ZM154.301 157.6C154.301 161.2 151.401 164.1 147.801 164.1H99.8013C96.2013 164.1 93.3013 161.2 93.3013 157.6V61.6001C93.3013 58.0001 96.2013 55.1001 99.8013 55.1001H147.801C151.401 55.1001 154.301 58.0001 154.301 61.6001V157.6Z" fill="#A3E635"/>
<path d="M49.8014 54C53.0598 54 55.7014 51.3137 55.7014 48C55.7014 44.6863 53.0598 42 49.8014 42C46.5429 42 43.9014 44.6863 43.9014 48C43.9014 51.3137 46.5429 54 49.8014 54Z" fill="#1E293B"/>
<path d="M49.8014 96C53.0598 96 55.7014 93.3137 55.7014 90C55.7014 86.6863 53.0598 84 49.8014 84C46.5429 84 43.9014 86.6863 43.9014 90C43.9014 93.3137 46.5429 96 49.8014 96Z" fill="#1E293B"/>
<path d="M49.8014 75C53.0598 75 55.7014 72.3137 55.7014 69C55.7014 65.6863 53.0598 63 49.8014 63C46.5429 63 43.9014 65.6863 43.9014 69C43.9014 72.3137 46.5429 75 49.8014 75Z" fill="#1E293B"/>
<path d="M49.8014 138C53.0598 138 55.7014 135.314 55.7014 132C55.7014 128.686 53.0598 126 49.8014 126C46.5429 126 43.9014 128.686 43.9014 132C43.9014 135.314 46.5429 138 49.8014 138Z" fill="#1E293B"/>
<path d="M49.8014 117C53.0598 117 55.7014 114.314 55.7014 111C55.7014 107.686 53.0598 105 49.8014 105C46.5429 105 43.9014 107.686 43.9014 111C43.9014 114.314 46.5429 117 49.8014 117Z" fill="#1E293B"/>
<path d="M104.801 75C108.06 75 110.701 72.3137 110.701 69C110.701 65.6863 108.06 63 104.801 63C101.543 63 98.9014 65.6863 98.9014 69C98.9014 72.3137 101.543 75 104.801 75Z" fill="#1E293B"/>
<path d="M104.801 159C108.06 159 110.701 156.314 110.701 153C110.701 149.686 108.06 147 104.801 147C101.543 147 98.9014 149.686 98.9014 153C98.9014 156.314 101.543 159 104.801 159Z" fill="#1E293B"/>
<path d="M104.801 138C108.06 138 110.701 135.314 110.701 132C110.701 128.686 108.06 126 104.801 126C101.543 126 98.9014 128.686 98.9014 132C98.9014 135.314 101.543 138 104.801 138Z" fill="#1E293B"/>
<path d="M116.402 66.8002H145.902C146.302 66.8002 146.702 66.5002 146.702 66.0002C146.702 65.5002 146.402 65.2002 145.902 65.2002H116.402C116.002 65.2002 115.602 65.5002 115.602 66.0002C115.602 66.5002 116.002 66.8002 116.402 66.8002Z" fill="#365314"/>
<path d="M116.402 72.7001H132.202C132.602 72.7001 133.002 72.4001 133.002 71.9001C133.002 71.4001 132.702 71.1001 132.202 71.1001H116.402C116.002 71.1001 115.602 71.4001 115.602 71.9001C115.602 72.4001 116.002 72.7001 116.402 72.7001Z" fill="#365314"/>
<path d="M145.802 149.3H116.402C116.002 149.3 115.602 149.6 115.602 150.1C115.602 150.6 115.902 150.9 116.402 150.9H145.902C146.302 150.9 146.702 150.6 146.702 150.1C146.702 149.6 146.202 149.3 145.802 149.3Z" fill="#365314"/>
<path d="M132.202 155.2H116.402C116.002 155.2 115.602 155.5 115.602 156C115.602 156.5 115.902 156.8 116.402 156.8H132.202C132.602 156.8 133.002 156.5 133.002 156C133.002 155.5 132.602 155.2 132.202 155.2Z" fill="#365314"/>
<path d="M145.802 128.3H116.402C116.002 128.3 115.602 128.6 115.602 129.1C115.602 129.6 115.902 129.9 116.402 129.9H145.902C146.302 129.9 146.702 129.6 146.702 129.1C146.702 128.6 146.202 128.3 145.802 128.3Z" fill="#365314"/>
<path d="M116.402 135.7H132.202C132.602 135.7 133.002 135.4 133.002 134.9C133.002 134.4 132.702 134.1 132.202 134.1H116.402C116.002 134.1 115.602 134.4 115.602 134.9C115.602 135.4 116.002 135.7 116.402 135.7Z" fill="#365314"/>
<path d="M74.8013 83H172.801C175.001 83 176.801 84.8 176.801 87V114C176.801 116.2 175.001 118 172.801 118H74.8013C72.6013 118 70.8013 116.2 70.8013 114V87C70.8013 84.8 72.6013 83 74.8013 83Z" fill="#1649A0"/>
<path d="M164.801 95.2998H112.801C112.401 95.2998 112.001 95.5998 112.001 96.0998C112.001 96.5998 112.301 96.8998 112.801 96.8998H164.801C165.201 96.8998 165.601 96.5998 165.601 96.0998C165.601 95.5998 165.201 95.2998 164.801 95.2998Z" fill="#52ADF9"/>
<path d="M140.801 104.1H112.801C112.401 104.1 112.001 104.4 112.001 104.9C112.001 105.4 112.301 105.7 112.801 105.7H140.801C141.201 105.7 141.601 105.4 141.601 104.9C141.601 104.4 141.201 104.1 140.801 104.1Z" fill="#52ADF9"/>
<path d="M92.3015 102.2H90.8015C86.0015 102.2 82.0015 106.1 82.0015 111V111.1C82.0015 111.5 82.3015 111.8 82.8015 111.8C83.3015 111.8 83.6015 111.4 83.6015 111C83.6015 107 86.9015 103.8 90.8015 103.8H92.3015C96.3015 103.8 99.5015 107.1 99.5015 111.1C99.5015 111.5 99.8015 111.8 100.301 111.8C100.801 111.8 101.101 111.4 101.101 111C101.001 106.1 97.1015 102.2 92.3015 102.2Z" fill="#E2E8F0"/>
<path d="M91.6012 99.5002C94.3012 99.5002 96.5012 97.3002 96.5012 94.6002C96.5012 91.9002 94.3012 89.7002 91.6012 89.7002C88.9012 89.7002 86.7012 91.9002 86.7012 94.6002C86.7012 97.4002 88.9012 99.5002 91.6012 99.5002ZM91.6012 91.3002C93.5012 91.3002 95.0012 92.8002 95.0012 94.7002C95.0012 96.6002 93.4012 98.0002 91.6012 98.0002C89.8012 98.0002 88.2012 96.5002 88.2012 94.6002C88.2012 92.7002 89.7012 91.3002 91.6012 91.3002Z" fill="#E2E8F0"/>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,45 @@
<svg width="193" height="192" viewBox="0 0 193 192" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M41.3016 13.7002H95.3016C101.502 13.7002 106.502 18.7002 106.502 24.9002V145.9C106.502 152.1 101.502 157.1 95.3016 157.1H41.3016C35.1016 157.1 30.1016 152.1 30.1016 145.9V25.0002C30.1016 18.7002 35.1016 13.7002 41.3016 13.7002Z" fill="#DDEDFE"/>
<path d="M99.6012 40.5999C99.6012 36.5999 96.4012 33.3999 92.4012 33.3999H44.4012C40.4012 33.3999 37.2012 36.5999 37.2012 40.5999V136.6C37.2012 140.6 40.4012 143.8 44.4012 143.8H92.4012C96.4012 143.8 99.6012 140.6 99.6012 136.6V40.5999Z" fill="#F9FAFB"/>
<path d="M95.3013 13H41.3013C34.7013 13 29.3013 18.4 29.3013 25V146C29.3013 152.6 34.7013 158 41.3013 158H95.3013C101.901 158 107.301 152.6 107.301 146V25C107.301 18.3 102.001 13 95.3013 13ZM105.801 146C105.801 151.8 101.101 156.5 95.3013 156.5H41.3013C35.5013 156.5 30.8013 151.8 30.8013 146V25C30.8013 19.2 35.5013 14.5 41.3013 14.5H95.3013C101.101 14.5 105.801 19.2 105.801 25V146Z" fill="#196FDE"/>
<path d="M68.3013 26.8999C70.0013 26.8999 71.3013 25.5999 71.3013 23.8999C71.3013 22.1999 70.0013 20.8999 68.3013 20.8999C66.6013 20.8999 65.3013 22.1999 65.3013 23.8999C65.3013 25.5999 66.7013 26.8999 68.3013 26.8999ZM68.3013 22.3999C69.1013 22.3999 69.8013 23.0999 69.8013 23.8999C69.8013 24.6999 69.1013 25.3999 68.3013 25.3999C67.5013 25.3999 66.8013 24.6999 66.8013 23.8999C66.8013 23.0999 67.5013 22.3999 68.3013 22.3999Z" fill="#196FDE"/>
<path d="M50.3015 24.3998H60.3015C60.7015 24.3998 61.1015 24.0998 61.1015 23.5998C61.1015 23.0998 60.8015 22.7998 60.3015 22.7998H50.3015C49.9015 22.7998 49.5015 23.0998 49.5015 23.5998C49.5015 24.0998 49.9015 24.3998 50.3015 24.3998Z" fill="#196FDE"/>
<path d="M76.3015 24.3998H86.3015C86.7015 24.3998 87.1015 24.0998 87.1015 23.5998C87.1015 23.0998 86.8015 22.7998 86.3015 22.7998H76.3015C75.9015 22.7998 75.5015 23.0998 75.5015 23.5998C75.5015 24.0998 75.9015 24.3998 76.3015 24.3998Z" fill="#196FDE"/>
<path d="M92.3013 32.6001H44.3013C39.9013 32.6001 36.3013 36.2001 36.3013 40.6001V136.6C36.3013 141 39.9013 144.6 44.3013 144.6H92.3013C96.7013 144.6 100.301 141 100.301 136.6V40.6001C100.301 36.2001 96.7013 32.6001 92.3013 32.6001ZM98.8013 136.6C98.8013 140.2 95.9013 143.1 92.3013 143.1H44.3013C40.7013 143.1 37.8013 140.2 37.8013 136.6V40.6001C37.8013 37.0001 40.7013 34.1001 44.3013 34.1001H92.3013C95.9013 34.1001 98.8013 37.0001 98.8013 40.6001V136.6Z" fill="#196FDE"/>
<path d="M90.3016 45.8002H60.9016C60.5016 45.8002 60.1016 45.5002 60.1016 45.0002C60.1016 44.5002 60.4016 44.2002 60.9016 44.2002H90.4016C90.8016 44.2002 91.2016 44.5002 91.2016 45.0002C91.2016 45.5002 90.7016 45.8002 90.3016 45.8002Z" fill="#BDDFFE"/>
<path d="M76.7016 51.7001H60.9016C60.5016 51.7001 60.1016 51.4001 60.1016 50.9001C60.1016 50.4001 60.4016 50.1001 60.9016 50.1001H76.7016C77.1016 50.1001 77.5016 50.4001 77.5016 50.9001C77.5016 51.4001 77.1016 51.7001 76.7016 51.7001Z" fill="#BDDFFE"/>
<path d="M90.3016 87.8002H60.9016C60.5016 87.8002 60.1016 87.5002 60.1016 87.0002C60.1016 86.5002 60.4016 86.2002 60.9016 86.2002H90.4016C90.8016 86.2002 91.2016 86.5002 91.2016 87.0002C91.2016 87.5002 90.7016 87.8002 90.3016 87.8002Z" fill="#BDDFFE"/>
<path d="M76.7016 93.7001H60.9016C60.5016 93.7001 60.1016 93.4001 60.1016 92.9001C60.1016 92.4001 60.4016 92.1001 60.9016 92.1001H76.7016C77.1016 92.1001 77.5016 92.4001 77.5016 92.9001C77.5016 93.4001 77.1016 93.7001 76.7016 93.7001Z" fill="#BDDFFE"/>
<path d="M90.3016 66.8002H60.9016C60.5016 66.8002 60.1016 66.5002 60.1016 66.0002C60.1016 65.5002 60.4016 65.2002 60.9016 65.2002H90.4016C90.8016 65.2002 91.2016 65.5002 91.2016 66.0002C91.2016 66.5002 90.7016 66.8002 90.3016 66.8002Z" fill="#BDDFFE"/>
<path d="M76.7016 72.7001H60.9016C60.5016 72.7001 60.1016 72.4001 60.1016 71.9001C60.1016 71.4001 60.4016 71.1001 60.9016 71.1001H76.7016C77.1016 71.1001 77.5016 71.4001 77.5016 71.9001C77.5016 72.4001 77.1016 72.7001 76.7016 72.7001Z" fill="#BDDFFE"/>
<path d="M90.3016 129.8H60.9016C60.5016 129.8 60.1016 129.5 60.1016 129C60.1016 128.5 60.4016 128.2 60.9016 128.2H90.4016C90.8016 128.2 91.2016 128.5 91.2016 129C91.2016 129.5 90.7016 129.8 90.3016 129.8Z" fill="#BDDFFE"/>
<path d="M76.7016 135.7H60.9016C60.5016 135.7 60.1016 135.4 60.1016 134.9C60.1016 134.4 60.4016 134.1 60.9016 134.1H76.7016C77.1016 134.1 77.5016 134.4 77.5016 134.9C77.5016 135.4 77.1016 135.7 76.7016 135.7Z" fill="#BDDFFE"/>
<path d="M90.3016 108.8H60.9016C60.5016 108.8 60.1016 108.5 60.1016 108C60.1016 107.5 60.4016 107.2 60.9016 107.2H90.4016C90.8016 107.2 91.2016 107.5 91.2016 108C91.2016 108.5 90.7016 108.8 90.3016 108.8Z" fill="#BDDFFE"/>
<path d="M76.7016 114.7H60.9016C60.5016 114.7 60.1016 114.4 60.1016 113.9C60.1016 113.4 60.4016 113.1 60.9016 113.1H76.7016C77.1016 113.1 77.5016 113.4 77.5016 113.9C77.5016 114.4 77.1016 114.7 76.7016 114.7Z" fill="#BDDFFE"/>
<path d="M96.3016 34.7998H150.302C156.502 34.7998 161.502 39.7998 161.502 45.9998V167C161.502 173.2 156.502 178.2 150.302 178.2H96.3016C90.1016 178.2 85.1016 173.2 85.1016 167V45.9998C85.1016 39.7998 90.1016 34.7998 96.3016 34.7998Z" fill="#ECFCCB"/>
<path d="M154.601 61.5999C154.601 57.5999 151.401 54.3999 147.401 54.3999H99.4012C95.4012 54.3999 92.2012 57.5999 92.2012 61.5999V157.6C92.2012 161.6 95.4012 164.8 99.4012 164.8H147.401C151.401 164.8 154.601 161.6 154.601 157.6V61.5999Z" fill="#F9FAFB"/>
<path d="M150.301 34H96.3013C89.7013 34 84.3013 39.4 84.3013 46V167C84.3013 173.6 89.7013 179 96.3013 179H150.301C156.901 179 162.301 173.6 162.301 167V46C162.301 39.4 157.001 34 150.301 34ZM160.801 167C160.801 172.8 156.101 177.5 150.301 177.5H96.3013C90.5013 177.5 85.8013 172.8 85.8013 167V46C85.8013 40.2 90.5013 35.5 96.3013 35.5H150.301C156.101 35.5 160.801 40.2 160.801 46V167Z" fill="#65A30D"/>
<path d="M123.301 47.8999C125.001 47.8999 126.301 46.5999 126.301 44.8999C126.301 43.1999 125.001 41.8999 123.301 41.8999C121.601 41.8999 120.301 43.1999 120.301 44.8999C120.301 46.5999 121.701 47.8999 123.301 47.8999ZM123.301 43.3999C124.101 43.3999 124.801 44.0999 124.801 44.8999C124.801 45.6999 124.101 46.3999 123.301 46.3999C122.501 46.3999 121.801 45.6999 121.801 44.8999C121.801 44.0999 122.501 43.3999 123.301 43.3999Z" fill="#65A30D"/>
<path d="M105.301 45.3998H115.301C115.701 45.3998 116.101 45.0998 116.101 44.5998C116.101 44.0998 115.801 43.7998 115.301 43.7998H105.301C104.901 43.7998 104.501 44.0998 104.501 44.5998C104.501 45.0998 104.901 45.3998 105.301 45.3998Z" fill="#65A30D"/>
<path d="M131.301 45.3998H141.301C141.701 45.3998 142.101 45.0998 142.101 44.5998C142.101 44.0998 141.801 43.7998 141.301 43.7998H131.301C130.901 43.7998 130.501 44.0998 130.501 44.5998C130.501 45.0998 130.901 45.3998 131.301 45.3998Z" fill="#65A30D"/>
<path d="M147.301 53.6001H99.3013C94.9013 53.6001 91.3013 57.2001 91.3013 61.6001V157.6C91.3013 162 94.9013 165.6 99.3013 165.6H147.301C151.701 165.6 155.301 162 155.301 157.6V61.6001C155.301 57.2001 151.701 53.6001 147.301 53.6001ZM153.801 157.6C153.801 161.2 150.901 164.1 147.301 164.1H99.3013C95.7013 164.1 92.8013 161.2 92.8013 157.6V61.6001C92.8013 58.0001 95.7013 55.1001 99.3013 55.1001H147.301C150.901 55.1001 153.801 58.0001 153.801 61.6001V157.6Z" fill="#65A30D"/>
<path d="M49.3014 54C52.5598 54 55.2014 51.3137 55.2014 48C55.2014 44.6863 52.5598 42 49.3014 42C46.0429 42 43.4014 44.6863 43.4014 48C43.4014 51.3137 46.0429 54 49.3014 54Z" fill="#E5E7EB"/>
<path d="M49.3014 96C52.5598 96 55.2014 93.3137 55.2014 90C55.2014 86.6863 52.5598 84 49.3014 84C46.0429 84 43.4014 86.6863 43.4014 90C43.4014 93.3137 46.0429 96 49.3014 96Z" fill="#E5E7EB"/>
<path d="M49.3014 75C52.5598 75 55.2014 72.3137 55.2014 69C55.2014 65.6863 52.5598 63 49.3014 63C46.0429 63 43.4014 65.6863 43.4014 69C43.4014 72.3137 46.0429 75 49.3014 75Z" fill="#E5E7EB"/>
<path d="M49.3014 138C52.5598 138 55.2014 135.314 55.2014 132C55.2014 128.686 52.5598 126 49.3014 126C46.0429 126 43.4014 128.686 43.4014 132C43.4014 135.314 46.0429 138 49.3014 138Z" fill="#E5E7EB"/>
<path d="M49.3014 117C52.5598 117 55.2014 114.314 55.2014 111C55.2014 107.686 52.5598 105 49.3014 105C46.0429 105 43.4014 107.686 43.4014 111C43.4014 114.314 46.0429 117 49.3014 117Z" fill="#E5E7EB"/>
<path d="M104.301 75C107.56 75 110.201 72.3137 110.201 69C110.201 65.6863 107.56 63 104.301 63C101.043 63 98.4014 65.6863 98.4014 69C98.4014 72.3137 101.043 75 104.301 75Z" fill="#E5E7EB"/>
<path d="M104.301 159C107.56 159 110.201 156.314 110.201 153C110.201 149.686 107.56 147 104.301 147C101.043 147 98.4014 149.686 98.4014 153C98.4014 156.314 101.043 159 104.301 159Z" fill="#E5E7EB"/>
<path d="M104.301 138C107.56 138 110.201 135.314 110.201 132C110.201 128.686 107.56 126 104.301 126C101.043 126 98.4014 128.686 98.4014 132C98.4014 135.314 101.043 138 104.301 138Z" fill="#E5E7EB"/>
<path d="M115.902 66.8002H145.402C145.802 66.8002 146.202 66.5002 146.202 66.0002C146.202 65.5002 145.902 65.2002 145.402 65.2002H115.902C115.502 65.2002 115.102 65.5002 115.102 66.0002C115.102 66.5002 115.502 66.8002 115.902 66.8002Z" fill="#D9F99D"/>
<path d="M115.902 72.7001H131.702C132.102 72.7001 132.502 72.4001 132.502 71.9001C132.502 71.4001 132.202 71.1001 131.702 71.1001H115.902C115.502 71.1001 115.102 71.4001 115.102 71.9001C115.102 72.4001 115.502 72.7001 115.902 72.7001Z" fill="#D9F99D"/>
<path d="M145.301 149.3H115.801C115.401 149.3 115.001 149.6 115.001 150.1C115.001 150.6 115.301 150.9 115.801 150.9H145.301C145.701 150.9 146.101 150.6 146.101 150.1C146.101 149.6 145.701 149.3 145.301 149.3Z" fill="#D9F99D"/>
<path d="M131.702 155.2H115.902C115.502 155.2 115.102 155.5 115.102 156C115.102 156.5 115.402 156.8 115.902 156.8H131.702C132.102 156.8 132.502 156.5 132.502 156C132.502 155.5 132.102 155.2 131.702 155.2Z" fill="#D9F99D"/>
<path d="M145.301 128.3H115.801C115.401 128.3 115.001 128.6 115.001 129.1C115.001 129.6 115.301 129.9 115.801 129.9H145.301C145.701 129.9 146.101 129.6 146.101 129.1C146.101 128.6 145.701 128.3 145.301 128.3Z" fill="#D9F99D"/>
<path d="M115.902 135.7H131.702C132.102 135.7 132.502 135.4 132.502 134.9C132.502 134.4 132.202 134.1 131.702 134.1H115.902C115.502 134.1 115.102 134.4 115.102 134.9C115.102 135.4 115.502 135.7 115.902 135.7Z" fill="#D9F99D"/>
<path d="M74.3013 83H172.301C174.501 83 176.301 84.8 176.301 87V114C176.301 116.2 174.501 118 172.301 118H74.3013C72.1013 118 70.3013 116.2 70.3013 114V87C70.3013 84.8 72.1013 83 74.3013 83Z" fill="#52ADF9"/>
<path d="M164.301 95.2998H112.301C111.901 95.2998 111.501 95.5998 111.501 96.0998C111.501 96.5998 111.801 96.8998 112.301 96.8998H164.301C164.701 96.8998 165.101 96.5998 165.101 96.0998C165.101 95.5998 164.701 95.2998 164.301 95.2998Z" fill="#F9FAFB"/>
<path d="M140.301 104.1H112.301C111.901 104.1 111.501 104.4 111.501 104.9C111.501 105.4 111.801 105.7 112.301 105.7H140.301C140.701 105.7 141.101 105.4 141.101 104.9C141.101 104.4 140.701 104.1 140.301 104.1Z" fill="#F9FAFB"/>
<path d="M91.8015 102.2H90.3015C85.5015 102.2 81.5015 106.1 81.5015 111V111.1C81.5015 111.5 81.8015 111.8 82.3015 111.8C82.8015 111.8 83.1015 111.4 83.1015 111C83.1015 107 86.4015 103.8 90.3015 103.8H91.8015C95.8015 103.8 99.0015 107.1 99.0015 111.1C99.0015 111.5 99.3015 111.8 99.8015 111.8C100.301 111.8 100.601 111.4 100.601 111C100.501 106.1 96.6015 102.2 91.8015 102.2Z" fill="#F9FAFB"/>
<path d="M91.1012 99.5002C93.8012 99.5002 96.0012 97.3002 96.0012 94.6002C96.0012 91.9002 93.8012 89.7002 91.1012 89.7002C88.4012 89.7002 86.2012 91.9002 86.2012 94.6002C86.2012 97.4002 88.4012 99.5002 91.1012 99.5002ZM91.1012 91.3002C93.0012 91.3002 94.5012 92.8002 94.5012 94.7002C94.5012 96.6002 92.9012 98.0002 91.1012 98.0002C89.3012 98.0002 87.7012 96.5002 87.7012 94.6002C87.7012 92.7002 89.2012 91.3002 91.1012 91.3002Z" fill="#F9FAFB"/>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,25 @@
<svg width="289" height="145" viewBox="0 0 289 145" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M268.901 41.8047C268.901 37.3864 265.32 33.8047 260.901 33.8047H234.901C230.483 33.8047 226.901 37.3864 226.901 41.8047V103.805C226.901 108.223 230.483 111.805 234.901 111.805H260.901C265.32 111.805 268.901 108.223 268.901 103.805V41.8047Z" fill="#1E293B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M234.901 35.3047H260.901C264.491 35.3047 267.401 38.2148 267.401 41.8047V103.805C267.401 107.395 264.491 110.305 260.901 110.305H234.901C231.312 110.305 228.401 107.395 228.401 103.805V41.8047C228.401 38.2148 231.312 35.3047 234.901 35.3047ZM260.901 33.8047C265.32 33.8047 268.901 37.3864 268.901 41.8047V103.805C268.901 108.223 265.32 111.805 260.901 111.805H234.901C230.483 111.805 226.901 108.223 226.901 103.805V41.8047C226.901 37.3864 230.483 33.8047 234.901 33.8047H260.901Z" fill="#52ADF9"/>
<path d="M246.901 41.8059C246.901 42.3588 247.349 42.8071 247.901 42.8071C248.454 42.8071 248.901 42.3588 248.901 41.8059C248.901 41.2529 248.454 40.8047 247.901 40.8047C247.349 40.8047 246.901 41.2529 246.901 41.8059Z" fill="#52ADF9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M239.151 41.8291C239.151 41.4149 239.487 41.0791 239.901 41.0791H243.901C244.316 41.0791 244.651 41.4149 244.651 41.8291C244.651 42.2433 244.316 42.5791 243.901 42.5791H239.901C239.487 42.5791 239.151 42.2433 239.151 41.8291Z" fill="#52ADF9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M251.151 41.8291C251.151 41.4149 251.487 41.0791 251.901 41.0791H255.901C256.316 41.0791 256.651 41.4149 256.651 41.8291C256.651 42.2433 256.316 42.5791 255.901 42.5791H251.901C251.487 42.5791 251.151 42.2433 251.151 41.8291Z" fill="#52ADF9"/>
<path d="M268.901 48.0527H226.902V102.053H268.901V48.0527Z" fill="#0B1120"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M228.402 49.5527H267.401V100.553H228.402V49.5527ZM268.901 48.0527V102.053H226.902V48.0527H268.901Z" fill="#52ADF9"/>
<path d="M61.9014 41.8047C61.9014 37.3864 58.3196 33.8047 53.9014 33.8047H27.9014C23.4831 33.8047 19.9014 37.3864 19.9014 41.8047V103.805C19.9014 108.223 23.4831 111.805 27.9014 111.805H53.9014C58.3196 111.805 61.9014 108.223 61.9014 103.805V41.8047Z" fill="#1E293B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M27.9014 35.3047H53.9014C57.4912 35.3047 60.4014 38.2148 60.4014 41.8047V103.805C60.4014 107.395 57.4912 110.305 53.9014 110.305H27.9014C24.3115 110.305 21.4014 107.395 21.4014 103.805V41.8047C21.4014 38.2148 24.3115 35.3047 27.9014 35.3047ZM53.9014 33.8047C58.3196 33.8047 61.9014 37.3864 61.9014 41.8047V103.805C61.9014 108.223 58.3196 111.805 53.9014 111.805H27.9014C23.4831 111.805 19.9014 108.223 19.9014 103.805V41.8047C19.9014 37.3864 23.4831 33.8047 27.9014 33.8047H53.9014Z" fill="#A3E635"/>
<path d="M39.9014 41.8059C39.9014 42.3588 40.3491 42.8071 40.9014 42.8071C41.4537 42.8071 41.9014 42.3588 41.9014 41.8059C41.9014 41.2529 41.4537 40.8047 40.9014 40.8047C40.3491 40.8047 39.9014 41.2529 39.9014 41.8059Z" fill="#A3E635"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M32.1514 41.8291C32.1514 41.4149 32.4872 41.0791 32.9014 41.0791H36.9014C37.3156 41.0791 37.6514 41.4149 37.6514 41.8291C37.6514 42.2433 37.3156 42.5791 36.9014 42.5791H32.9014C32.4872 42.5791 32.1514 42.2433 32.1514 41.8291Z" fill="#A3E635"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M44.1514 41.8291C44.1514 41.4149 44.4872 41.0791 44.9014 41.0791H48.9014C49.3156 41.0791 49.6514 41.4149 49.6514 41.8291C49.6514 42.2433 49.3156 42.5791 48.9014 42.5791H44.9014C44.4872 42.5791 44.1514 42.2433 44.1514 41.8291Z" fill="#A3E635"/>
<path d="M61.9014 48.0527H19.9015V102.053H61.9014V48.0527Z" fill="#0B1120"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M21.4015 49.5527H60.4014V100.553H21.4015V49.5527ZM61.9014 48.0527V102.053H19.9015V48.0527H61.9014Z" fill="#A3E635"/>
<path d="M96.1514 72.8047C96.1514 75.0138 94.3605 76.8047 92.1514 76.8047C89.9422 76.8047 88.1514 75.0138 88.1514 72.8047C88.1514 70.5955 89.9422 68.8047 92.1514 68.8047C94.3605 68.8047 96.1514 70.5955 96.1514 72.8047Z" fill="#4D7C0F"/>
<path d="M112.151 72.8047C112.151 75.0138 110.361 76.8047 108.151 76.8047C105.942 76.8047 104.151 75.0138 104.151 72.8047C104.151 70.5955 105.942 68.8047 108.151 68.8047C110.361 68.8047 112.151 70.5955 112.151 72.8047Z" fill="#82C91E"/>
<path d="M80.1514 72.8047C80.1514 75.0138 78.3605 76.8047 76.1514 76.8047C73.9422 76.8047 72.1514 75.0138 72.1514 72.8047C72.1514 70.5955 73.9422 68.8047 76.1514 68.8047C78.3605 68.8047 80.1514 70.5955 80.1514 72.8047Z" fill="#365314"/>
<path d="M192.651 72.8047C192.651 70.5955 194.442 68.8047 196.651 68.8047C198.861 68.8047 200.651 70.5955 200.651 72.8047C200.651 75.0138 198.861 76.8047 196.651 76.8047C194.442 76.8047 192.651 75.0138 192.651 72.8047Z" fill="#1457C5"/>
<path d="M176.651 72.8047C176.651 70.5955 178.442 68.8047 180.651 68.8047C182.861 68.8047 184.651 70.5955 184.651 72.8047C184.651 75.0138 182.861 76.8047 180.651 76.8047C178.442 76.8047 176.651 75.0138 176.651 72.8047Z" fill="#2B8EF1"/>
<path d="M208.651 72.8047C208.651 70.5955 210.442 68.8047 212.651 68.8047C214.861 68.8047 216.651 70.5955 216.651 72.8047C216.651 75.0138 214.861 76.8047 212.651 76.8047C210.442 76.8047 208.651 75.0138 208.651 72.8047Z" fill="#184080"/>
<path d="M166.271 62.8047C166.271 56.1773 160.899 50.8047 154.271 50.8047H134.271C127.644 50.8047 122.271 56.1773 122.271 62.8047V82.8047C122.271 89.4321 127.644 94.8047 134.271 94.8047H154.271C160.899 94.8047 166.271 89.4321 166.271 82.8047V62.8047Z" fill="#1E293B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M134.271 52.3047H154.271C160.07 52.3047 164.771 57.0057 164.771 62.8047V82.8047C164.771 88.6037 160.07 93.3047 154.271 93.3047H134.271C128.472 93.3047 123.771 88.6037 123.771 82.8047V62.8047C123.771 57.0057 128.472 52.3047 134.271 52.3047ZM154.271 50.8047C160.899 50.8047 166.271 56.1773 166.271 62.8047V82.8047C166.271 89.4321 160.899 94.8047 154.271 94.8047H134.271C127.644 94.8047 122.271 89.4321 122.271 82.8047V62.8047C122.271 56.1773 127.644 50.8047 134.271 50.8047H154.271Z" fill="#52ADF9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M144.082 62.349C144.344 62.2252 144.655 62.264 144.879 62.4488L150.582 67.1538C150.753 67.2942 150.852 67.5025 150.855 67.7232C150.858 67.9439 150.763 68.1546 150.596 68.2991L145.547 72.6754L150.596 77.0516C150.761 77.1939 150.855 77.4004 150.855 77.6176C150.855 77.8348 150.761 78.0415 150.598 78.1841L144.894 83.1486C144.672 83.3416 144.358 83.3873 144.091 83.2655C143.823 83.1437 143.651 82.8768 143.651 82.5829V74.3178L139.189 78.1852C138.876 78.4564 138.402 78.4226 138.131 78.1096C137.86 77.7966 137.894 77.3229 138.207 77.0516L143.256 72.6754L138.207 68.2991C137.894 68.0278 137.86 67.5542 138.131 67.2411C138.402 66.9281 138.876 66.8943 139.189 67.1655L143.651 71.0329V63.0274C143.651 62.737 143.819 62.4728 144.082 62.349ZM145.151 74.3178L148.961 77.6196L145.151 80.9358V74.3178ZM145.151 71.0329V64.6183L148.944 67.7465L145.151 71.0329Z" fill="#52ADF9"/>
</svg>

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -0,0 +1,25 @@
<svg width="289" height="145" viewBox="0 0 289 145" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M268.901 40.8047C268.901 36.3864 265.32 32.8047 260.901 32.8047H234.901C230.483 32.8047 226.901 36.3864 226.901 40.8047V102.805C226.901 107.223 230.483 110.805 234.901 110.805H260.901C265.32 110.805 268.901 107.223 268.901 102.805V40.8047Z" fill="#DDEDFE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M234.901 34.3047H260.901C264.491 34.3047 267.401 37.2148 267.401 40.8047V102.805C267.401 106.395 264.491 109.305 260.901 109.305H234.901C231.312 109.305 228.401 106.395 228.401 102.805V40.8047C228.401 37.2148 231.312 34.3047 234.901 34.3047ZM260.901 32.8047C265.32 32.8047 268.901 36.3864 268.901 40.8047V102.805C268.901 107.223 265.32 110.805 260.901 110.805H234.901C230.483 110.805 226.901 107.223 226.901 102.805V40.8047C226.901 36.3864 230.483 32.8047 234.901 32.8047H260.901Z" fill="#196FDE"/>
<path d="M246.901 40.8059C246.901 41.3588 247.349 41.8071 247.901 41.8071C248.454 41.8071 248.901 41.3588 248.901 40.8059C248.901 40.2529 248.454 39.8047 247.901 39.8047C247.349 39.8047 246.901 40.2529 246.901 40.8059Z" fill="#196FDE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M239.151 40.8291C239.151 40.4149 239.487 40.0791 239.901 40.0791H243.901C244.316 40.0791 244.651 40.4149 244.651 40.8291C244.651 41.2433 244.316 41.5791 243.901 41.5791H239.901C239.487 41.5791 239.151 41.2433 239.151 40.8291Z" fill="#196FDE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M251.151 40.8291C251.151 40.4149 251.487 40.0791 251.901 40.0791H255.901C256.316 40.0791 256.651 40.4149 256.651 40.8291C256.651 41.2433 256.316 41.5791 255.901 41.5791H251.901C251.487 41.5791 251.151 41.2433 251.151 40.8291Z" fill="#196FDE"/>
<path d="M268.901 47.0527H226.902V101.053H268.901V47.0527Z" fill="#F9FAFB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M228.402 48.5527H267.401V99.5527H228.402V48.5527ZM268.901 47.0527V101.053H226.902V47.0527H268.901Z" fill="#196FDE"/>
<path d="M61.9014 40.8047C61.9014 36.3864 58.3196 32.8047 53.9014 32.8047H27.9014C23.4831 32.8047 19.9014 36.3864 19.9014 40.8047V102.805C19.9014 107.223 23.4831 110.805 27.9014 110.805H53.9014C58.3196 110.805 61.9014 107.223 61.9014 102.805V40.8047Z" fill="#ECFCCB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M27.9014 34.3047H53.9014C57.4912 34.3047 60.4014 37.2148 60.4014 40.8047V102.805C60.4014 106.395 57.4912 109.305 53.9014 109.305H27.9014C24.3115 109.305 21.4014 106.395 21.4014 102.805V40.8047C21.4014 37.2148 24.3115 34.3047 27.9014 34.3047ZM53.9014 32.8047C58.3196 32.8047 61.9014 36.3864 61.9014 40.8047V102.805C61.9014 107.223 58.3196 110.805 53.9014 110.805H27.9014C23.4831 110.805 19.9014 107.223 19.9014 102.805V40.8047C19.9014 36.3864 23.4831 32.8047 27.9014 32.8047H53.9014Z" fill="#65A30D"/>
<path d="M39.9014 40.8059C39.9014 41.3588 40.3491 41.8071 40.9014 41.8071C41.4537 41.8071 41.9014 41.3588 41.9014 40.8059C41.9014 40.2529 41.4537 39.8047 40.9014 39.8047C40.3491 39.8047 39.9014 40.2529 39.9014 40.8059Z" fill="#65A30D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M32.1514 40.8291C32.1514 40.4149 32.4872 40.0791 32.9014 40.0791H36.9014C37.3156 40.0791 37.6514 40.4149 37.6514 40.8291C37.6514 41.2433 37.3156 41.5791 36.9014 41.5791H32.9014C32.4872 41.5791 32.1514 41.2433 32.1514 40.8291Z" fill="#65A30D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M44.1514 40.8291C44.1514 40.4149 44.4872 40.0791 44.9014 40.0791H48.9014C49.3156 40.0791 49.6514 40.4149 49.6514 40.8291C49.6514 41.2433 49.3156 41.5791 48.9014 41.5791H44.9014C44.4872 41.5791 44.1514 41.2433 44.1514 40.8291Z" fill="#65A30D"/>
<path d="M61.9014 47.0527H19.9015V101.053H61.9014V47.0527Z" fill="#F9FAFB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M21.4015 48.5527H60.4014V99.5527H21.4015V48.5527ZM61.9014 47.0527V101.053H19.9015V47.0527H61.9014Z" fill="#65A30D"/>
<path d="M96.1514 71.8047C96.1514 74.0138 94.3605 75.8047 92.1514 75.8047C89.9422 75.8047 88.1514 74.0138 88.1514 71.8047C88.1514 69.5955 89.9422 67.8047 92.1514 67.8047C94.3605 67.8047 96.1514 69.5955 96.1514 71.8047Z" fill="#BEF264"/>
<path d="M112.151 71.8047C112.151 74.0138 110.361 75.8047 108.151 75.8047C105.942 75.8047 104.151 74.0138 104.151 71.8047C104.151 69.5955 105.942 67.8047 108.151 67.8047C110.361 67.8047 112.151 69.5955 112.151 71.8047Z" fill="#A3E635"/>
<path d="M80.1514 71.8047C80.1514 74.0138 78.3605 75.8047 76.1514 75.8047C73.9422 75.8047 72.1514 74.0138 72.1514 71.8047C72.1514 69.5955 73.9422 67.8047 76.1514 67.8047C78.3605 67.8047 80.1514 69.5955 80.1514 71.8047Z" fill="#D9F99D"/>
<path d="M192.651 71.8047C192.651 69.5955 194.442 67.8047 196.651 67.8047C198.861 67.8047 200.651 69.5955 200.651 71.8047C200.651 74.0138 198.861 75.8047 196.651 75.8047C194.442 75.8047 192.651 74.0138 192.651 71.8047Z" fill="#8BCAFD"/>
<path d="M176.651 71.8047C176.651 69.5955 178.442 67.8047 180.651 67.8047C182.861 67.8047 184.651 69.5955 184.651 71.8047C184.651 74.0138 182.861 75.8047 180.651 75.8047C178.442 75.8047 176.651 74.0138 176.651 71.8047Z" fill="#52ADF9"/>
<path d="M208.651 71.8047C208.651 69.5955 210.442 67.8047 212.651 67.8047C214.861 67.8047 216.651 69.5955 216.651 71.8047C216.651 74.0138 214.861 75.8047 212.651 75.8047C210.442 75.8047 208.651 74.0138 208.651 71.8047Z" fill="#BDDFFE"/>
<path d="M166.271 61.8047C166.271 55.1773 160.899 49.8047 154.271 49.8047H134.271C127.644 49.8047 122.271 55.1773 122.271 61.8047V81.8047C122.271 88.4321 127.644 93.8047 134.271 93.8047H154.271C160.899 93.8047 166.271 88.4321 166.271 81.8047V61.8047Z" fill="#DDEDFE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M134.271 51.3047H154.271C160.07 51.3047 164.771 56.0057 164.771 61.8047V81.8047C164.771 87.6037 160.07 92.3047 154.271 92.3047H134.271C128.472 92.3047 123.771 87.6037 123.771 81.8047V61.8047C123.771 56.0057 128.472 51.3047 134.271 51.3047ZM154.271 49.8047C160.899 49.8047 166.271 55.1773 166.271 61.8047V81.8047C166.271 88.4321 160.899 93.8047 154.271 93.8047H134.271C127.644 93.8047 122.271 88.4321 122.271 81.8047V61.8047C122.271 55.1773 127.644 49.8047 134.271 49.8047H154.271Z" fill="#196FDE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M144.082 61.349C144.344 61.2252 144.655 61.264 144.879 61.4488L150.582 66.1538C150.753 66.2942 150.852 66.5025 150.855 66.7232C150.858 66.9439 150.763 67.1546 150.596 67.2991L145.547 71.6754L150.596 76.0516C150.761 76.1939 150.855 76.4004 150.855 76.6176C150.855 76.8348 150.761 77.0415 150.598 77.1841L144.894 82.1486C144.672 82.3416 144.358 82.3873 144.091 82.2655C143.823 82.1437 143.651 81.8768 143.651 81.5829V73.3178L139.189 77.1852C138.876 77.4564 138.402 77.4226 138.131 77.1096C137.86 76.7966 137.894 76.3229 138.207 76.0516L143.256 71.6754L138.207 67.2991C137.894 67.0278 137.86 66.5542 138.131 66.2411C138.402 65.9281 138.876 65.8943 139.189 66.1655L143.651 70.0329V62.0274C143.651 61.737 143.819 61.4728 144.082 61.349ZM145.151 73.3178L148.961 76.6196L145.151 79.9358V73.3178ZM145.151 70.0329V63.6183L148.944 66.7465L145.151 70.0329Z" fill="#196FDE"/>
</svg>

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -0,0 +1,17 @@
<svg width="81" height="81" viewBox="0 0 81 81" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_142_9184)">
<path d="M14.4937 62.0026C13.3891 62.0026 12.4937 61.1071 12.4937 60.0026L12.4937 30.003C12.4936 28.8984 13.3891 28.003 14.4937 28.003L34.4936 28.003C35.5982 28.003 36.4936 28.8984 36.4936 30.003L36.4936 60.0029C36.4936 61.1075 35.5982 62.0029 34.4936 62.0029L14.4937 62.0026Z" fill="#334155"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M34.4936 29.503L14.4937 29.503C14.2175 29.503 13.9937 29.7268 13.9937 30.003L13.9937 60.0026C13.9937 60.2787 14.2176 60.5026 14.4937 60.5026L34.4936 60.5029C34.7698 60.5029 34.9936 60.2791 34.9936 60.0029L34.9936 30.003C34.9936 29.7268 34.7698 29.503 34.4936 29.503ZM12.4937 60.0026C12.4937 61.1071 13.3891 62.0026 14.4937 62.0026L34.4936 62.0029C35.5982 62.0029 36.4936 61.1075 36.4936 60.0029L36.4936 30.003C36.4936 28.8984 35.5982 28.003 34.4936 28.003L14.4937 28.003C13.3891 28.003 12.4936 28.8984 12.4937 30.003L12.4937 60.0026Z" fill="#64748B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M45.1289 40.6699C45.1289 40.2557 45.4647 39.9199 45.8789 39.9199L67.8786 39.9199C68.2928 39.9199 68.6286 40.2557 68.6286 40.6699C68.6286 41.0841 68.2928 41.4199 67.8786 41.4199L45.8789 41.4199C45.4647 41.4199 45.1289 41.0841 45.1289 40.6699Z" fill="#64748B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M45.1289 32.0039C45.1289 31.5897 45.4647 31.2539 45.8789 31.2539L67.8786 31.2539C68.2928 31.2539 68.6286 31.5897 68.6286 32.0039C68.6286 32.4181 68.2928 32.7539 67.8786 32.7539L45.8789 32.7539C45.4647 32.7539 45.1289 32.4181 45.1289 32.0039Z" fill="#64748B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M45.1289 49.3369C45.1289 48.9227 45.4647 48.5869 45.8789 48.5869L67.8789 48.5869C68.2931 48.5869 68.6289 48.9227 68.6289 49.3369C68.6289 49.7511 68.2931 50.0869 67.8789 50.0869L45.8789 50.0869C45.4647 50.0869 45.1289 49.7511 45.1289 49.3369Z" fill="#64748B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M45.1289 58.0029C45.1289 57.5887 45.4647 57.2529 45.8789 57.2529L56.879 57.2529C57.2932 57.2529 57.629 57.5887 57.629 58.0029C57.629 58.4171 57.2932 58.7529 56.879 58.7529L45.8789 58.7529C45.4647 58.7529 45.1289 58.4171 45.1289 58.0029Z" fill="#64748B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M79.4013 24.9019C79.3854 20.4972 75.8098 16.9314 71.4014 16.9314L9.40142 16.9314C4.98314 16.9314 1.40142 20.5131 1.40142 24.9314L1.40137 16.874C1.40137 12.4557 4.98309 8.87403 9.40137 8.87403L71.4013 8.87402C75.8196 8.87402 79.4013 12.4557 79.4013 16.874V24.9019Z" fill="#334155"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.651422 16.874C0.651429 12.0415 4.56894 8.12403 9.40142 8.12403L71.4014 8.12402C76.2339 8.12402 80.1514 12.0415 80.1514 16.874V64.874C80.1514 69.7065 76.2338 73.6241 71.4013 73.624L9.40129 73.6235C4.56882 73.6234 0.651361 69.7059 0.651367 64.8735L0.651378 56.8491L0.651367 56.8435L0.651422 16.874ZM9.40142 9.62403L71.4014 9.62402C75.4054 9.62402 78.6514 12.87 78.6514 16.874V19.954C77.0782 17.6312 74.4181 16.1046 71.4014 16.1046L9.40142 16.1046C6.38472 16.1046 3.72458 17.6312 2.15142 19.954L2.15142 16.874C2.15143 12.87 5.39736 9.62403 9.40142 9.62403ZM2.15137 64.8735C2.15136 68.8775 5.39726 72.1234 9.4013 72.1235L71.4013 72.124C75.4054 72.1241 78.6514 68.8781 78.6514 64.874L78.6514 24.9046L78.6514 24.9026C78.6358 20.9118 75.3959 17.6814 71.4014 17.6814L9.40147 17.6814C5.39741 17.6814 2.15148 20.9273 2.15147 24.9314L2.15137 64.8735Z" fill="#64748B"/>
</g>
<defs>
<clipPath id="clip0_142_9184">
<rect width="80" height="80" fill="white" transform="translate(0.401367 0.78125)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -0,0 +1,17 @@
<svg width="81" height="81" viewBox="0 0 81 81" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_142_9186)">
<path d="M14.9605 62.0026C13.8559 62.0026 12.9605 61.1071 12.9605 60.0026L12.9604 30.003C12.9604 28.8984 13.8559 28.003 14.9604 28.003L34.9604 28.003C36.065 28.003 36.9604 28.8984 36.9604 30.003L36.9604 60.0029C36.9604 61.1075 36.065 62.0029 34.9604 62.0029L14.9605 62.0026Z" fill="#E5E7EB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M34.9604 29.503L14.9604 29.503C14.6843 29.503 14.4604 29.7268 14.4604 30.003L14.4605 60.0026C14.4605 60.2787 14.6844 60.5026 14.9605 60.5026L34.9604 60.5029C35.2366 60.5029 35.4604 60.2791 35.4604 60.0029L35.4604 30.003C35.4604 29.7268 35.2366 29.503 34.9604 29.503ZM12.9605 60.0026C12.9605 61.1071 13.8559 62.0026 14.9605 62.0026L34.9604 62.0029C36.065 62.0029 36.9604 61.1075 36.9604 60.0029L36.9604 30.003C36.9604 28.8984 36.065 28.003 34.9604 28.003L14.9604 28.003C13.8559 28.003 12.9604 28.8984 12.9604 30.003L12.9605 60.0026Z" fill="#9CA3AF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M45.5957 40.6699C45.5957 40.2557 45.9315 39.9199 46.3457 39.9199L68.3454 39.9199C68.7596 39.9199 69.0954 40.2557 69.0954 40.6699C69.0954 41.0841 68.7596 41.4199 68.3454 41.4199L46.3457 41.4199C45.9315 41.4199 45.5957 41.0841 45.5957 40.6699Z" fill="#9CA3AF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M45.5957 32.0039C45.5957 31.5897 45.9315 31.2539 46.3457 31.2539L68.3454 31.2539C68.7596 31.2539 69.0954 31.5897 69.0954 32.0039C69.0954 32.4181 68.7596 32.7539 68.3454 32.7539L46.3457 32.7539C45.9315 32.7539 45.5957 32.4181 45.5957 32.0039Z" fill="#9CA3AF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M45.5957 49.3369C45.5957 48.9227 45.9315 48.5869 46.3457 48.5869L68.3457 48.5869C68.7599 48.5869 69.0957 48.9227 69.0957 49.3369C69.0957 49.7511 68.7599 50.0869 68.3457 50.0869L46.3457 50.0869C45.9315 50.0869 45.5957 49.7511 45.5957 49.3369Z" fill="#9CA3AF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M45.5957 58.0029C45.5957 57.5887 45.9315 57.2529 46.3457 57.2529L57.3458 57.2529C57.76 57.2529 58.0958 57.5887 58.0958 58.0029C58.0958 58.4171 57.76 58.7529 57.3458 58.7529L46.3457 58.7529C45.9315 58.7529 45.5957 58.4171 45.5957 58.0029Z" fill="#9CA3AF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M79.8681 24.9019C79.8522 20.4972 76.2766 16.9314 71.8682 16.9314L9.86821 16.9314C5.44994 16.9314 1.86822 20.5131 1.86822 24.9314L1.86816 16.874C1.86817 12.4557 5.44989 8.87403 9.86816 8.87403L71.8681 8.87402C76.2864 8.87402 79.8681 12.4557 79.8681 16.874V24.9019Z" fill="#E5E7EB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.11822 16.874C1.11823 12.0415 5.03573 8.12403 9.86822 8.12403L71.8682 8.12402C76.7007 8.12402 80.6182 12.0415 80.6182 16.874V64.874C80.6182 69.7065 76.7006 73.6241 71.8681 73.624L9.86809 73.6235C5.03562 73.6234 1.11816 69.7059 1.11816 64.8735L1.11818 56.8491L1.11816 56.8435L1.11822 16.874ZM9.86822 9.62403L71.8682 9.62402C75.8722 9.62402 79.1182 12.87 79.1182 16.874V19.954C77.545 17.6312 74.8849 16.1046 71.8682 16.1046L9.86822 16.1046C6.85152 16.1046 4.19138 17.6312 2.61822 19.954L2.61822 16.874C2.61822 12.87 5.86416 9.62403 9.86822 9.62403ZM2.61816 64.8735C2.61816 68.8775 5.86406 72.1234 9.8681 72.1235L71.8681 72.124C75.8722 72.1241 79.1182 68.8781 79.1182 64.874L79.1182 24.9046L79.1182 24.9026C79.1026 20.9118 75.8627 17.6814 71.8682 17.6814L9.86827 17.6814C5.86421 17.6814 2.61828 20.9273 2.61827 24.9314L2.61816 64.8735Z" fill="#9CA3AF"/>
</g>
<defs>
<clipPath id="clip0_142_9186">
<rect width="80" height="80" fill="white" transform="translate(0.868164 0.78125)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -0,0 +1,7 @@
<svg width="81" height="80" viewBox="0 0 81 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M55.8771 3.19912L71.2942 5.82176C76.4078 6.69164 79.8553 11.4996 79.0387 16.6225L70.73 68.746C69.7481 74.9062 63.0013 78.3146 57.4761 75.4418L58.1751 74.1118C62.7908 76.5117 68.4271 73.6643 69.2474 68.5181L77.5561 16.3946C78.2438 12.0806 75.3406 8.03176 71.0344 7.29922L57.3985 4.9796L58.1751 74.1118L56.6739 74.1365L55.8771 3.19912Z" fill="#64748B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.6021 74.9992L10.6021 4H58.6021C63.0203 4 66.6021 7.58172 66.6021 12V67C66.6021 71.4183 63.0202 75.0001 58.6019 75L10.6021 74.9992ZM22.8896 49.1657V53.0394C22.8896 57.4577 26.4714 61.0394 30.8896 61.0394H46.8472C51.2655 61.0394 54.8472 57.4577 54.8472 53.0394V49.1657C54.8472 44.7474 51.2655 41.1657 46.8472 41.1657H30.8896C26.4714 41.1657 22.8896 44.7474 22.8896 49.1657ZM38.8685 34.8533C43.5566 34.8533 47.3572 31.0717 47.3572 26.4069C47.3572 21.7421 43.5566 17.9606 38.8685 17.9606C34.1803 17.9606 30.3797 21.7421 30.3797 26.4069C30.3797 31.0717 34.1803 34.8533 38.8685 34.8533Z" fill="#334155"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M22.8896 49.1657V53.0394C22.8896 57.4577 26.4714 61.0394 30.8896 61.0394H46.8472C51.2655 61.0394 54.8472 57.4577 54.8472 53.0394V49.1657C54.8472 44.7474 51.2655 41.1657 46.8472 41.1657H30.8896C26.4714 41.1657 22.8896 44.7474 22.8896 49.1657ZM24.3896 53.0394V49.1657C24.3896 45.5758 27.2998 42.6657 30.8896 42.6657H46.8472C50.437 42.6657 53.3472 45.5758 53.3472 49.1657V53.0394C53.3472 56.6293 50.437 59.5394 46.8472 59.5394H30.8896C27.2998 59.5394 24.3896 56.6293 24.3896 53.0394Z" fill="#64748B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M38.8685 34.8532C43.5566 34.8532 47.3572 31.0717 47.3572 26.4069C47.3572 21.7421 43.5566 17.9606 38.8685 17.9606C34.1803 17.9606 30.3797 21.7421 30.3797 26.4069C30.3797 31.0717 34.1803 34.8532 38.8685 34.8532ZM45.8572 26.4069C45.8572 30.2362 42.7353 33.3533 38.8685 33.3533C35.0016 33.3533 31.8797 30.2362 31.8797 26.4069C31.8797 22.5776 35.0016 19.4606 38.8685 19.4606C42.7353 19.4606 45.8572 22.5776 45.8572 26.4069Z" fill="#64748B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M58.6021 2.5H9.10205L9.10205 17.7334H3.85059C3.43637 17.7334 3.10059 18.0692 3.10059 18.4834C3.10059 18.8976 3.43637 19.2334 3.85059 19.2334H9.10205L9.10205 38.8779H3.85059C3.43637 38.8779 3.10059 39.2137 3.10059 39.6279C3.10059 40.0421 3.43637 40.3779 3.85059 40.3779H9.10205L9.10205 60.752H3.85059C3.43637 60.752 3.10059 61.0877 3.10059 61.502C3.10059 61.9162 3.43637 62.252 3.85059 62.252H9.10205L9.10205 76.4992L58.6019 76.5C63.8487 76.5001 68.1021 72.2468 68.1021 67V12C68.1021 6.75329 63.8488 2.5 58.6021 2.5ZM10.6021 62.252L10.6021 74.9992L58.6019 75C63.0202 75.0001 66.6021 71.4183 66.6021 67V12C66.6021 7.58172 63.0203 4 58.6021 4H10.6021L10.6021 17.7334H15.6148C16.029 17.7334 16.3648 18.0692 16.3648 18.4834C16.3648 18.8976 16.029 19.2334 15.6148 19.2334H10.6021L10.6021 38.8779H15.6148C16.029 38.8779 16.3648 39.2137 16.3648 39.6279C16.3648 40.0421 16.029 40.3779 15.6148 40.3779H10.6021L10.6021 60.752H15.6148C16.029 60.752 16.3648 61.0877 16.3648 61.502C16.3648 61.9162 16.029 62.252 15.6148 62.252H10.6021Z" fill="#64748B"/>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -0,0 +1,7 @@
<svg width="81" height="80" viewBox="0 0 81 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M54.8771 3.19912L70.2942 5.82176C75.4078 6.69164 78.8553 11.4996 78.0387 16.6225L69.73 68.746C68.7481 74.9062 62.0013 78.3146 56.4761 75.4418L57.1751 74.1118C61.7908 76.5117 67.4271 73.6643 68.2474 68.5181L76.5561 16.3946C77.2438 12.0806 74.3406 8.03176 70.0344 7.29922L56.3985 4.9796L57.1751 74.1118L55.6739 74.1365L54.8771 3.19912Z" fill="#9CA3AF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.60205 74.9992L9.60205 4H57.6021C62.0203 4 65.6021 7.58172 65.6021 12V67C65.6021 71.4183 62.0202 75.0001 57.6019 75L9.60205 74.9992ZM21.8896 49.1657V53.0394C21.8896 57.4577 25.4714 61.0394 29.8896 61.0394H45.8472C50.2655 61.0394 53.8472 57.4577 53.8472 53.0394V49.1657C53.8472 44.7474 50.2655 41.1657 45.8472 41.1657H29.8896C25.4714 41.1657 21.8896 44.7474 21.8896 49.1657ZM37.8685 34.8533C42.5566 34.8533 46.3572 31.0717 46.3572 26.4069C46.3572 21.7421 42.5566 17.9606 37.8685 17.9606C33.1803 17.9606 29.3797 21.7421 29.3797 26.4069C29.3797 31.0717 33.1803 34.8533 37.8685 34.8533Z" fill="#E5E7EB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M21.8896 49.1657V53.0394C21.8896 57.4577 25.4714 61.0394 29.8896 61.0394H45.8472C50.2655 61.0394 53.8472 57.4577 53.8472 53.0394V49.1657C53.8472 44.7474 50.2655 41.1657 45.8472 41.1657H29.8896C25.4714 41.1657 21.8896 44.7474 21.8896 49.1657ZM23.3896 53.0394V49.1657C23.3896 45.5758 26.2998 42.6657 29.8896 42.6657H45.8472C49.437 42.6657 52.3472 45.5758 52.3472 49.1657V53.0394C52.3472 56.6293 49.437 59.5394 45.8472 59.5394H29.8896C26.2998 59.5394 23.3896 56.6293 23.3896 53.0394Z" fill="#9CA3AF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M37.8685 34.8532C42.5566 34.8532 46.3572 31.0717 46.3572 26.4069C46.3572 21.7421 42.5566 17.9606 37.8685 17.9606C33.1803 17.9606 29.3797 21.7421 29.3797 26.4069C29.3797 31.0717 33.1803 34.8532 37.8685 34.8532ZM44.8572 26.4069C44.8572 30.2362 41.7353 33.3533 37.8685 33.3533C34.0016 33.3533 30.8797 30.2362 30.8797 26.4069C30.8797 22.5776 34.0016 19.4606 37.8685 19.4606C41.7353 19.4606 44.8572 22.5776 44.8572 26.4069Z" fill="#9CA3AF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M57.6021 2.5H8.10205L8.10205 17.7334H2.85059C2.43637 17.7334 2.10059 18.0692 2.10059 18.4834C2.10059 18.8976 2.43637 19.2334 2.85059 19.2334H8.10205L8.10205 38.8779H2.85059C2.43637 38.8779 2.10059 39.2137 2.10059 39.6279C2.10059 40.0421 2.43637 40.3779 2.85059 40.3779H8.10205L8.10205 60.752H2.85059C2.43637 60.752 2.10059 61.0877 2.10059 61.502C2.10059 61.9162 2.43637 62.252 2.85059 62.252H8.10205L8.10205 76.4992L57.6019 76.5C62.8487 76.5001 67.1021 72.2468 67.1021 67V12C67.1021 6.75329 62.8488 2.5 57.6021 2.5ZM9.60205 62.252L9.60205 74.9992L57.6019 75C62.0202 75.0001 65.6021 71.4183 65.6021 67V12C65.6021 7.58172 62.0203 4 57.6021 4H9.60205L9.60205 17.7334H14.6148C15.029 17.7334 15.3648 18.0692 15.3648 18.4834C15.3648 18.8976 15.029 19.2334 14.6148 19.2334H9.60205L9.60205 38.8779H14.6148C15.029 38.8779 15.3648 39.2137 15.3648 39.6279C15.3648 40.0421 15.029 40.3779 14.6148 40.3779H9.60205L9.60205 60.752H14.6148C15.029 60.752 15.3648 61.0877 15.3648 61.502C15.3648 61.9162 15.029 62.252 14.6148 62.252H9.60205Z" fill="#9CA3AF"/>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -0,0 +1,11 @@
<svg width="81" height="81" viewBox="0 0 81 81" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_142_9249)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.3936 48.6422V58.2131C20.3936 62.6314 23.9753 66.2131 28.3936 66.2131H63.0813L79.4015 75.3286V30.9092C79.4015 26.4909 75.8198 22.9092 71.4015 22.9092H60.4067V40.6422C60.4067 45.0605 56.825 48.6422 52.4067 48.6422H20.3936Z" fill="#334155"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.40137 4.5791C4.56888 4.5791 0.651367 8.4966 0.651367 13.3291V59.0201L17.9148 49.3778H19.6436V58.2131C19.6436 63.0456 23.5611 66.9631 28.3936 66.9631H62.8861L80.1515 76.6065V30.9092C80.1515 26.0767 76.234 22.1592 71.4015 22.1592H61.1522V13.3291C61.1522 8.49661 57.2347 4.5791 52.4022 4.5791H9.40137ZM2.15137 13.3291C2.15137 9.32503 5.3973 6.0791 9.40137 6.0791H52.4022C56.4062 6.0791 59.6522 9.32504 59.6522 13.3291V40.6278C59.6522 44.6319 56.4062 47.8778 52.4022 47.8778H17.5243L2.15137 56.4642V13.3291ZM61.1567 40.6422V23.6592H71.4015C75.4055 23.6592 78.6515 26.9051 78.6515 30.9092V74.0506L63.2766 65.4631H28.3936C24.3895 65.4631 21.1436 62.2172 21.1436 58.2131V49.3922H52.4067C57.2392 49.3922 61.1567 45.4747 61.1567 40.6422Z" fill="#64748B"/>
</g>
<defs>
<clipPath id="clip0_142_9249">
<rect width="80" height="80" fill="white" transform="translate(0.401367 0.0859375)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,11 @@
<svg width="81" height="81" viewBox="0 0 81 81" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_142_9251)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.3936 48.6422V58.2131C20.3936 62.6314 23.9753 66.2131 28.3936 66.2131H63.0813L79.4015 75.3286V30.9092C79.4015 26.4909 75.8198 22.9092 71.4015 22.9092H60.4067V40.6422C60.4067 45.0605 56.825 48.6422 52.4067 48.6422H20.3936Z" fill="#E5E7EB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.40137 4.5791C4.56888 4.5791 0.651367 8.4966 0.651367 13.3291V59.0201L17.9148 49.3778H19.6436V58.2131C19.6436 63.0456 23.5611 66.9631 28.3936 66.9631H62.8861L80.1515 76.6065V30.9092C80.1515 26.0767 76.234 22.1592 71.4015 22.1592H61.1522V13.3291C61.1522 8.49661 57.2347 4.5791 52.4022 4.5791H9.40137ZM2.15137 13.3291C2.15137 9.32503 5.3973 6.0791 9.40137 6.0791H52.4022C56.4062 6.0791 59.6522 9.32504 59.6522 13.3291V40.6278C59.6522 44.6319 56.4062 47.8778 52.4022 47.8778H17.5243L2.15137 56.4642V13.3291ZM61.1567 40.6422V23.6592H71.4015C75.4055 23.6592 78.6515 26.9051 78.6515 30.9092V74.0506L63.2766 65.4631H28.3936C24.3895 65.4631 21.1436 62.2172 21.1436 58.2131V49.3922H52.4067C57.2392 49.3922 61.1567 45.4747 61.1567 40.6422Z" fill="#9CA3AF"/>
</g>
<defs>
<clipPath id="clip0_142_9251">
<rect width="80" height="80" fill="white" transform="translate(0.868164 0.0859375)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,13 @@
<svg width="81" height="81" viewBox="0 0 81 81" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_142_9298)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M48.6662 16.6539C48.6662 21.2186 44.9657 24.9191 40.401 24.9191C35.8362 24.9191 32.1357 21.2186 32.1357 16.6539C32.1357 12.0891 35.8362 8.38867 40.401 8.38867C44.9657 8.38867 48.6662 12.0891 48.6662 16.6539ZM47.1662 16.6539C47.1662 20.3902 44.1373 23.4191 40.401 23.4191C36.6646 23.4191 33.6357 20.3902 33.6357 16.6539C33.6357 12.9176 36.6646 9.88867 40.401 9.88867C44.1373 9.88867 47.1662 12.9176 47.1662 16.6539Z" fill="#64748B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M25.2785 25.9195C25.2785 30.4843 21.578 34.1847 17.0133 34.1847C12.4485 34.1847 8.74805 30.4843 8.74805 25.9195C8.74805 21.3548 12.4485 17.6543 17.0133 17.6543C21.578 17.6543 25.2785 21.3548 25.2785 25.9195ZM23.7785 25.9195C23.7785 29.6558 20.7496 32.6847 17.0133 32.6847C13.2769 32.6847 10.248 29.6558 10.248 25.9195C10.248 22.1832 13.2769 19.1543 17.0133 19.1543C20.7496 19.1543 23.7785 22.1832 23.7785 25.9195Z" fill="#64748B"/>
<path d="M2.15137 49.1689C2.15137 45.1649 5.3973 41.9189 9.40137 41.9189H24.0391V61.1648C24.0391 61.579 24.3748 61.9148 24.7891 61.9148C25.2033 61.9148 25.5391 61.579 25.5391 61.1648V41.976C29.1119 42.4252 31.8755 45.4743 31.8755 49.1689V72.3931C31.8755 72.8073 32.2113 73.1431 32.6255 73.1431C33.0397 73.1431 33.3755 72.8073 33.3755 72.3931V49.1689C33.3755 44.645 29.9422 40.9229 25.5391 40.4661V39.7774C25.5391 35.7733 28.785 32.5273 32.7891 32.5273H48.0132C52.0173 32.5273 55.2632 35.7733 55.2632 39.7773V40.4661C50.8603 40.9231 47.4272 44.6451 47.4272 49.169V70.5564C47.4272 70.9706 47.763 71.3064 48.1772 71.3064C48.5915 71.3064 48.9272 70.9706 48.9272 70.5564V49.169C48.9272 45.4745 51.6906 42.4254 55.2632 41.976V61.1648C55.2632 61.579 55.599 61.9148 56.0132 61.9148C56.4274 61.9148 56.7632 61.579 56.7632 61.1648V41.9189H71.4014C75.4054 41.9189 78.6514 45.1649 78.6514 49.1689V70.5564C78.6514 70.9706 78.9872 71.3064 79.4014 71.3064C79.8156 71.3064 80.1514 70.9706 80.1514 70.5564V49.1689C80.1514 44.3365 76.2339 40.4189 71.4014 40.4189H56.7632V39.7773C56.7632 34.9449 52.8457 31.0273 48.0132 31.0273H32.7891C27.9566 31.0273 24.0391 34.9449 24.0391 39.7774V40.4189H9.40137C4.56888 40.4189 0.651367 44.3365 0.651367 49.1689V72.3931C0.651367 72.8073 0.987154 73.1431 1.40137 73.1431C1.81558 73.1431 2.15137 72.8073 2.15137 72.3931V49.1689Z" fill="#64748B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M72.0543 25.9195C72.0543 30.4843 68.3539 34.1847 63.7891 34.1847C59.2244 34.1847 55.5239 30.4843 55.5239 25.9195C55.5239 21.3548 59.2244 17.6543 63.7891 17.6543C68.3539 17.6543 72.0543 21.3548 72.0543 25.9195ZM70.5543 25.9195C70.5543 29.6558 67.5255 32.6847 63.7891 32.6847C60.0528 32.6847 57.0239 29.6558 57.0239 25.9195C57.0239 22.1832 60.0528 19.1543 63.7891 19.1543C67.5255 19.1543 70.5543 22.1832 70.5543 25.9195Z" fill="#64748B"/>
</g>
<defs>
<clipPath id="clip0_142_9298">
<rect width="80" height="80" fill="white" transform="translate(0.401367 0.390625)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,13 @@
<svg width="81" height="81" viewBox="0 0 81 81" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_142_9300)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M49.1334 16.6539C49.1334 21.2186 45.4329 24.919 40.8682 24.919C36.3035 24.919 32.603 21.2186 32.603 16.6539C32.603 12.0891 36.3035 8.38867 40.8682 8.38867C45.4329 8.38867 49.1334 12.0891 49.1334 16.6539ZM47.6334 16.6539C47.6334 20.3902 44.6045 23.419 40.8682 23.419C37.1319 23.419 34.103 20.3902 34.103 16.6539C34.103 12.9175 37.1319 9.88867 40.8682 9.88867C44.6045 9.88867 47.6334 12.9175 47.6334 16.6539Z" fill="#9CA3AF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M25.7452 25.9195C25.7452 30.4842 22.0448 34.1847 17.48 34.1847C12.9153 34.1847 9.21484 30.4842 9.21484 25.9195C9.21484 21.3547 12.9153 17.6543 17.48 17.6543C22.0448 17.6543 25.7452 21.3547 25.7452 25.9195ZM24.2452 25.9195C24.2452 29.6558 21.2163 32.6847 17.48 32.6847C13.7437 32.6847 10.7148 29.6558 10.7148 25.9195C10.7148 22.1832 13.7437 19.1543 17.48 19.1543C21.2163 19.1543 24.2452 22.1832 24.2452 25.9195Z" fill="#9CA3AF"/>
<path d="M2.61816 49.168C2.61816 45.1639 5.8641 41.918 9.86816 41.918H24.5063V61.1647C24.5063 61.5789 24.8421 61.9147 25.2563 61.9147C25.6706 61.9147 26.0063 61.5789 26.0063 61.1647V41.975C29.5789 42.4245 32.3422 45.4735 32.3422 49.168V72.392C32.3422 72.8062 32.678 73.142 33.0922 73.142C33.5064 73.142 33.8422 72.8062 33.8422 72.392V49.168C33.8422 44.6442 30.4092 40.9222 26.0063 40.4651V39.7773C26.0063 35.7733 29.2523 32.5273 33.2563 32.5273H48.4804C52.4845 32.5273 55.7304 35.7733 55.7304 39.7773V40.4651C51.3273 40.9219 47.894 44.644 47.894 49.168V70.5553C47.894 70.9695 48.2298 71.3053 48.644 71.3053C49.0583 71.3053 49.394 70.9695 49.394 70.5553V49.168C49.394 45.4734 52.1576 42.4242 55.7304 41.975V61.1647C55.7304 61.5789 56.0662 61.9147 56.4804 61.9147C56.8946 61.9147 57.2304 61.5789 57.2304 61.1647V41.918H71.8681C75.8721 41.918 79.1181 45.1639 79.1181 49.168V70.5553C79.1181 70.9695 79.4539 71.3053 79.8681 71.3053C80.2823 71.3053 80.6181 70.9695 80.6181 70.5553V49.168C80.6181 44.3355 76.7006 40.418 71.8681 40.418H57.2304V39.7773C57.2304 34.9449 53.3129 31.0273 48.4804 31.0273H33.2563C28.4239 31.0273 24.5063 34.9449 24.5063 39.7773V40.418H9.86816C5.03567 40.418 1.11816 44.3355 1.11816 49.168V72.392C1.11816 72.8062 1.45395 73.142 1.86816 73.142C2.28238 73.142 2.61816 72.8062 2.61816 72.392V49.168Z" fill="#9CA3AF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M72.5216 25.9195C72.5216 30.4842 68.8211 34.1847 64.2564 34.1847C59.6917 34.1847 55.9912 30.4842 55.9912 25.9195C55.9912 21.3547 59.6917 17.6543 64.2564 17.6543C68.8211 17.6543 72.5216 21.3547 72.5216 25.9195ZM71.0216 25.9195C71.0216 29.6558 67.9927 32.6847 64.2564 32.6847C60.5201 32.6847 57.4912 29.6558 57.4912 25.9195C57.4912 22.1832 60.5201 19.1543 64.2564 19.1543C67.9927 19.1543 71.0216 22.1832 71.0216 25.9195Z" fill="#9CA3AF"/>
</g>
<defs>
<clipPath id="clip0_142_9300">
<rect width="80" height="80" fill="white" transform="translate(0.868164 0.390625)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,37 @@
<svg width="193" height="192" viewBox="0 0 193 192" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M112.401 21C112.401 16.5817 108.82 13 104.401 13H88.4014C83.9831 13 80.4014 16.5817 80.4014 21V37C80.4014 41.4183 83.9831 45 88.4014 45H104.401C108.82 45 112.401 41.4183 112.401 37V21Z" fill="#1E293B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M88.4014 14.5H104.401C107.991 14.5 110.901 17.4101 110.901 21V37C110.901 40.5899 107.991 43.5 104.401 43.5H88.4014C84.8115 43.5 81.9014 40.5899 81.9014 37V21C81.9014 17.4101 84.8115 14.5 88.4014 14.5ZM104.401 13C108.82 13 112.401 16.5817 112.401 21V37C112.401 41.4183 108.82 45 104.401 45H88.4014C83.9831 45 80.4014 41.4183 80.4014 37V21C80.4014 16.5817 83.9831 13 88.4014 13H104.401Z" fill="#52ADF9"/>
<path d="M60.4014 127C60.4014 122.582 56.8196 119 52.4014 119H36.4014C31.9831 119 28.4014 122.582 28.4014 127V143C28.4014 147.418 31.9831 151 36.4014 151H52.4014C56.8196 151 60.4014 147.418 60.4014 143V127Z" fill="#1E293B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M36.4014 120.5H52.4014C55.9912 120.5 58.9014 123.41 58.9014 127V143C58.9014 146.59 55.9912 149.5 52.4014 149.5H36.4014C32.8115 149.5 29.9014 146.59 29.9014 143V127C29.9014 123.41 32.8115 120.5 36.4014 120.5ZM52.4014 119C56.8196 119 60.4014 122.582 60.4014 127V143C60.4014 147.418 56.8196 151 52.4014 151H36.4014C31.9831 151 28.4014 147.418 28.4014 143V127C28.4014 122.582 31.9831 119 36.4014 119H52.4014Z" fill="#52ADF9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M43.6514 116L43.6514 100L45.1514 100L45.1514 116L43.6514 116Z" fill="#64748B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M95.6514 66L95.6514 48L97.1514 48L97.1514 66L95.6514 66Z" fill="#64748B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M95.6514 155L95.6514 126L97.1514 126L97.1514 155L95.6514 155Z" fill="#64748B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M150.151 67V92H148.651V67H150.151Z" fill="#64748B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M149.171 96.4512H126.401V94.9512H149.171C153.579 94.9512 157.151 98.524 157.151 102.931L157.151 121.701L155.651 121.701L155.651 102.931C155.651 99.3524 152.75 96.4512 149.171 96.4512Z" fill="#A3E635"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M43.6314 95.25L66.4014 95.25L66.4014 96.75L43.6314 96.75C39.2241 96.75 35.6514 93.1772 35.6515 88.77L35.6518 70L37.1518 70L37.1515 88.77C37.1514 92.3488 40.0526 95.25 43.6314 95.25Z" fill="#A3E635"/>
<path d="M157.401 52C157.401 49.7909 155.611 48 153.401 48H145.401C143.192 48 141.401 49.7909 141.401 52V60C141.401 62.2091 143.192 64 145.401 64H153.401C155.611 64 157.401 62.2091 157.401 60V52Z" fill="#1E293B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M145.401 49.5H153.401C154.782 49.5 155.901 50.6193 155.901 52V60C155.901 61.3807 154.782 62.5 153.401 62.5H145.401C144.021 62.5 142.901 61.3807 142.901 60V52C142.901 50.6193 144.021 49.5 145.401 49.5ZM153.401 48C155.611 48 157.401 49.7909 157.401 52V60C157.401 62.2091 155.611 64 153.401 64H145.401C143.192 64 141.401 62.2091 141.401 60V52C141.401 49.7909 143.192 48 145.401 48H153.401Z" fill="#64748B"/>
<path d="M104.401 162C104.401 159.791 102.611 158 100.401 158H92.4014C90.1922 158 88.4014 159.791 88.4014 162V170C88.4014 172.209 90.1922 174 92.4014 174H100.401C102.611 174 104.401 172.209 104.401 170V162Z" fill="#1E293B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M92.4014 159.5H100.401C101.782 159.5 102.901 160.619 102.901 162V170C102.901 171.381 101.782 172.5 100.401 172.5H92.4014C91.0207 172.5 89.9014 171.381 89.9014 170V162C89.9014 160.619 91.0207 159.5 92.4014 159.5ZM100.401 158C102.611 158 104.401 159.791 104.401 162V170C104.401 172.209 102.611 174 100.401 174H92.4014C90.1922 174 88.4014 172.209 88.4014 170V162C88.4014 159.791 90.1922 158 92.4014 158H100.401Z" fill="#64748B"/>
<path d="M123.242 81C123.242 74.3726 117.87 69 111.242 69H81.2422C74.6148 69 69.2422 74.3726 69.2422 81V111C69.2422 117.627 74.6148 123 81.2422 123H111.242C117.87 123 123.242 117.627 123.242 111V81Z" fill="#1E293B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M81.2422 70.5H111.242C117.041 70.5 121.742 75.201 121.742 81V111C121.742 116.799 117.041 121.5 111.242 121.5H81.2422C75.4432 121.5 70.7422 116.799 70.7422 111V81C70.7422 75.201 75.4432 70.5 81.2422 70.5ZM111.242 69C117.87 69 123.242 74.3726 123.242 81V111C123.242 117.627 117.87 123 111.242 123H81.2422C74.6148 123 69.2422 117.627 69.2422 111V81C69.2422 74.3726 74.6148 69 81.2422 69H111.242Z" fill="#A3E635"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M86.1254 83.5728H105.57C106.307 83.5728 107.013 83.8671 107.534 84.3911C108.055 84.9151 108.348 85.6257 108.348 86.3667L108.348 110.313C108.348 111.38 107.11 111.962 106.296 111.278L101.256 107.573H86.1254C85.3887 107.573 84.6822 107.278 84.1613 106.754C83.6403 106.23 83.3477 105.52 83.3477 104.779V86.3667C83.3477 85.6257 83.6403 84.9151 84.1613 84.3911C84.6822 83.8671 85.3887 83.5728 86.1254 83.5728ZM93.5152 95.9531H87.7921V88.0431H103.903V95.9531H98.2747V98.6887H100.333C100.705 98.6887 100.891 99.1402 100.628 99.4042L96.1896 103.869C96.0269 104.032 95.7631 104.032 95.6004 103.869L91.1619 99.4042C90.8994 99.1402 91.0853 98.6887 91.4566 98.6887H93.5152V95.9531Z" fill="#A3E635"/>
<path d="M172.401 132C172.401 127.582 168.82 124 164.401 124H148.401C143.983 124 140.401 127.582 140.401 132V148C140.401 152.418 143.983 156 148.401 156H164.401C168.82 156 172.401 152.418 172.401 148V132Z" fill="#1E293B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M148.401 125.5H164.401C167.991 125.5 170.901 128.41 170.901 132V148C170.901 151.59 167.991 154.5 164.401 154.5H148.401C144.812 154.5 141.901 151.59 141.901 148V132C141.901 128.41 144.812 125.5 148.401 125.5ZM164.401 124C168.82 124 172.401 127.582 172.401 132V148C172.401 152.418 168.82 156 164.401 156H148.401C143.983 156 140.401 152.418 140.401 148V132C140.401 127.582 143.983 124 148.401 124H164.401Z" fill="#A3E635"/>
<path d="M152 138.541V145.66C152 146.238 152.471 146.714 153.054 146.714H153.549C154.127 146.714 154.603 146.238 154.603 145.66V138.541H152Z" fill="#82C91E"/>
<path d="M154.597 135.109V133.769C154.597 133.191 154.127 132.714 153.549 132.714H153.054C152.477 132.714 152 133.191 152 133.769V135.109H154.597Z" fill="#82C91E"/>
<path d="M160.376 140.888V133.769C160.376 133.191 159.906 132.714 159.328 132.714H158.833C158.255 132.714 157.779 133.191 157.779 133.769V140.888H160.376Z" fill="#82C91E"/>
<path d="M157.779 144.319V145.66C157.779 146.238 158.255 146.714 158.833 146.714H159.328C159.906 146.714 160.382 146.238 160.382 145.66V144.319H157.779Z" fill="#82C91E"/>
<path d="M151.583 141.305H150.243C149.665 141.305 149.188 141.775 149.188 142.359V142.854C149.188 143.431 149.659 143.908 150.243 143.908H151.583V141.305Z" fill="#A3E635"/>
<path d="M162.134 141.305H155.015V143.908H162.134C162.712 143.908 163.188 143.431 163.188 142.854V142.359C163.188 141.775 162.712 141.305 162.134 141.305Z" fill="#A3E635"/>
<path d="M157.362 135.526H150.243C149.665 135.526 149.188 135.997 149.188 136.58V137.075C149.188 137.653 149.659 138.129 150.243 138.129H157.362V135.526Z" fill="#A3E635"/>
<path d="M162.134 135.526H160.794V138.129H162.134C162.712 138.129 163.188 137.659 163.188 137.075V136.58C163.188 135.997 162.712 135.526 162.134 135.526Z" fill="#A3E635"/>
<path d="M28.0254 50.6526V64.891C28.0254 66.0468 28.9667 67 30.1343 67H31.1233C32.279 67 33.2322 66.0468 33.2322 64.891V50.6526H28.0254Z" fill="#82C91E"/>
<path d="M33.2203 43.7899V41.109C33.2203 39.9532 32.279 39 31.1233 39H30.1343C28.9786 39 28.0254 39.9532 28.0254 41.109V43.7899H33.2203Z" fill="#82C91E"/>
<path d="M44.7777 55.3474V41.109C44.7777 39.9532 43.8364 39 42.6807 39H41.6917C40.536 39 39.5828 39.9532 39.5828 41.109V55.3474H44.7777Z" fill="#82C91E"/>
<path d="M39.5828 62.2099V64.8908C39.5828 66.0466 40.536 66.9998 41.6917 66.9998H42.6807C43.8364 66.9998 44.7896 66.0466 44.7896 64.8908V62.2099H39.5828Z" fill="#82C91E"/>
<path d="M27.1912 56.1805H24.5103C23.3546 56.1805 22.4014 57.1218 22.4014 58.2894V59.2784C22.4014 60.4341 23.3426 61.3873 24.5103 61.3873H27.1912V56.1805Z" fill="#A3E635"/>
<path d="M48.2924 56.1805H34.054V61.3873H48.2924C49.4481 61.3873 50.4013 60.4341 50.4013 59.2784V58.2894C50.4013 57.1218 49.4481 56.1805 48.2924 56.1805Z" fill="#A3E635"/>
<path d="M38.7486 44.6231H24.5103C23.3546 44.6231 22.4014 45.5644 22.4014 46.7321V47.721C22.4014 48.8768 23.3426 49.83 24.5103 49.83H38.7486V44.6231Z" fill="#A3E635"/>
<path d="M48.2924 44.623H45.6116V49.8299H48.2924C49.4482 49.8299 50.4014 48.8886 50.4014 47.721V46.732C50.4014 45.5643 49.4482 44.623 48.2924 44.623Z" fill="#A3E635"/>
</svg>

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@@ -0,0 +1,37 @@
<svg width="193" height="192" viewBox="0 0 193 192" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M112.401 21C112.401 16.5817 108.82 13 104.401 13H88.4014C83.9831 13 80.4014 16.5817 80.4014 21V37C80.4014 41.4183 83.9831 45 88.4014 45H104.401C108.82 45 112.401 41.4183 112.401 37V21Z" fill="#DDEDFE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M88.4014 14.5H104.401C107.991 14.5 110.901 17.4101 110.901 21V37C110.901 40.5899 107.991 43.5 104.401 43.5H88.4014C84.8115 43.5 81.9014 40.5899 81.9014 37V21C81.9014 17.4101 84.8115 14.5 88.4014 14.5ZM104.401 13C108.82 13 112.401 16.5817 112.401 21V37C112.401 41.4183 108.82 45 104.401 45H88.4014C83.9831 45 80.4014 41.4183 80.4014 37V21C80.4014 16.5817 83.9831 13 88.4014 13H104.401Z" fill="#196FDE"/>
<path d="M60.4014 127C60.4014 122.582 56.8196 119 52.4014 119H36.4014C31.9831 119 28.4014 122.582 28.4014 127V143C28.4014 147.418 31.9831 151 36.4014 151H52.4014C56.8196 151 60.4014 147.418 60.4014 143V127Z" fill="#DDEDFE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M36.4014 120.5H52.4014C55.9912 120.5 58.9014 123.41 58.9014 127V143C58.9014 146.59 55.9912 149.5 52.4014 149.5H36.4014C32.8115 149.5 29.9014 146.59 29.9014 143V127C29.9014 123.41 32.8115 120.5 36.4014 120.5ZM52.4014 119C56.8196 119 60.4014 122.582 60.4014 127V143C60.4014 147.418 56.8196 151 52.4014 151H36.4014C31.9831 151 28.4014 147.418 28.4014 143V127C28.4014 122.582 31.9831 119 36.4014 119H52.4014Z" fill="#196FDE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M43.6514 116L43.6514 100L45.1514 100L45.1514 116L43.6514 116Z" fill="#9CA3AF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M95.6514 66L95.6514 48L97.1514 48L97.1514 66L95.6514 66Z" fill="#9CA3AF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M95.6514 155L95.6514 126L97.1514 126L97.1514 155L95.6514 155Z" fill="#9CA3AF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M150.151 67V92H148.651V67H150.151Z" fill="#9CA3AF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M149.171 96.4512H126.401V94.9512H149.171C153.579 94.9512 157.151 98.524 157.151 102.931L157.151 121.701L155.651 121.701L155.651 102.931C155.651 99.3524 152.75 96.4512 149.171 96.4512Z" fill="#65A30D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M43.6314 95.25L66.4014 95.25L66.4014 96.75L43.6314 96.75C39.2241 96.75 35.6514 93.1772 35.6515 88.77L35.6518 70L37.1518 70L37.1515 88.77C37.1514 92.3488 40.0526 95.25 43.6314 95.25Z" fill="#65A30D"/>
<path d="M157.401 52C157.401 49.7909 155.611 48 153.401 48H145.401C143.192 48 141.401 49.7909 141.401 52V60C141.401 62.2091 143.192 64 145.401 64H153.401C155.611 64 157.401 62.2091 157.401 60V52Z" fill="#E5E7EB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M145.401 49.5H153.401C154.782 49.5 155.901 50.6193 155.901 52V60C155.901 61.3807 154.782 62.5 153.401 62.5H145.401C144.021 62.5 142.901 61.3807 142.901 60V52C142.901 50.6193 144.021 49.5 145.401 49.5ZM153.401 48C155.611 48 157.401 49.7909 157.401 52V60C157.401 62.2091 155.611 64 153.401 64H145.401C143.192 64 141.401 62.2091 141.401 60V52C141.401 49.7909 143.192 48 145.401 48H153.401Z" fill="#9CA3AF"/>
<path d="M104.401 162C104.401 159.791 102.611 158 100.401 158H92.4014C90.1922 158 88.4014 159.791 88.4014 162V170C88.4014 172.209 90.1922 174 92.4014 174H100.401C102.611 174 104.401 172.209 104.401 170V162Z" fill="#E5E7EB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M92.4014 159.5H100.401C101.782 159.5 102.901 160.619 102.901 162V170C102.901 171.381 101.782 172.5 100.401 172.5H92.4014C91.0207 172.5 89.9014 171.381 89.9014 170V162C89.9014 160.619 91.0207 159.5 92.4014 159.5ZM100.401 158C102.611 158 104.401 159.791 104.401 162V170C104.401 172.209 102.611 174 100.401 174H92.4014C90.1922 174 88.4014 172.209 88.4014 170V162C88.4014 159.791 90.1922 158 92.4014 158H100.401Z" fill="#9CA3AF"/>
<path d="M123.242 81C123.242 74.3726 117.87 69 111.242 69H81.2422C74.6148 69 69.2422 74.3726 69.2422 81V111C69.2422 117.627 74.6148 123 81.2422 123H111.242C117.87 123 123.242 117.627 123.242 111V81Z" fill="#F9FAFB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M81.2422 70.5H111.242C117.041 70.5 121.742 75.201 121.742 81V111C121.742 116.799 117.041 121.5 111.242 121.5H81.2422C75.4432 121.5 70.7422 116.799 70.7422 111V81C70.7422 75.201 75.4432 70.5 81.2422 70.5ZM111.242 69C117.87 69 123.242 74.3726 123.242 81V111C123.242 117.627 117.87 123 111.242 123H81.2422C74.6148 123 69.2422 117.627 69.2422 111V81C69.2422 74.3726 74.6148 69 81.2422 69H111.242Z" fill="#65A30D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M86.9663 83.5728H106.411C107.147 83.5728 107.854 83.8671 108.375 84.3911C108.896 84.9151 109.188 85.6257 109.188 86.3667L109.188 110.313C109.188 111.38 107.951 111.962 107.137 111.278L102.097 107.573H86.9663C86.2295 107.573 85.523 107.278 85.0021 106.754C84.4811 106.23 84.1885 105.52 84.1885 104.779V86.3667C84.1885 85.6257 84.4811 84.9151 85.0021 84.3911C85.523 83.8671 86.2295 83.5728 86.9663 83.5728ZM94.356 95.9531H88.6329V88.0431H104.744V95.9531H99.1156V98.6887H101.174C101.545 98.6887 101.731 99.1402 101.469 99.4042L97.0304 103.869C96.8677 104.032 96.6039 104.032 96.4412 103.869L92.0027 99.4042C91.7403 99.1402 91.9262 98.6887 92.2974 98.6887H94.356V95.9531Z" fill="#82C91E"/>
<path d="M172.401 132C172.401 127.582 168.82 124 164.401 124H148.401C143.983 124 140.401 127.582 140.401 132V148C140.401 152.418 143.983 156 148.401 156H164.401C168.82 156 172.401 152.418 172.401 148V132Z" fill="#F9FAFB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M148.401 125.5H164.401C167.991 125.5 170.901 128.41 170.901 132V148C170.901 151.59 167.991 154.5 164.401 154.5H148.401C144.812 154.5 141.901 151.59 141.901 148V132C141.901 128.41 144.812 125.5 148.401 125.5ZM164.401 124C168.82 124 172.401 127.582 172.401 132V148C172.401 152.418 168.82 156 164.401 156H148.401C143.983 156 140.401 152.418 140.401 148V132C140.401 127.582 143.983 124 148.401 124H164.401Z" fill="#65A30D"/>
<path d="M152 138.541V145.66C152 146.238 152.471 146.714 153.055 146.714H153.549C154.127 146.714 154.604 146.238 154.604 145.66V138.541H152Z" fill="#82C91E"/>
<path d="M154.598 135.109V133.769C154.598 133.191 154.127 132.714 153.549 132.714H153.055C152.477 132.714 152 133.191 152 133.769V135.109H154.598Z" fill="#82C91E"/>
<path d="M160.377 140.888V133.769C160.377 133.191 159.906 132.714 159.328 132.714H158.834C158.256 132.714 157.779 133.191 157.779 133.769V140.888H160.377Z" fill="#82C91E"/>
<path d="M157.779 144.319V145.66C157.779 146.238 158.256 146.714 158.834 146.714H159.328C159.906 146.714 160.383 146.238 160.383 145.66V144.319H157.779Z" fill="#82C91E"/>
<path d="M151.583 141.305H150.243C149.665 141.305 149.188 141.775 149.188 142.359V142.854C149.188 143.431 149.659 143.908 150.243 143.908H151.583V141.305Z" fill="#A3E635"/>
<path d="M162.134 141.305H155.015V143.908H162.134C162.712 143.908 163.188 143.431 163.188 142.854V142.359C163.188 141.775 162.712 141.305 162.134 141.305Z" fill="#A3E635"/>
<path d="M157.362 135.526H150.243C149.665 135.526 149.188 135.997 149.188 136.58V137.075C149.188 137.653 149.659 138.129 150.243 138.129H157.362V135.526Z" fill="#A3E635"/>
<path d="M162.134 135.526H160.794V138.129H162.134C162.712 138.129 163.188 137.659 163.188 137.075V136.58C163.188 135.997 162.712 135.526 162.134 135.526Z" fill="#A3E635"/>
<path d="M28.0254 50.6526V64.891C28.0254 66.0468 28.9667 67 30.1343 67H31.1233C32.279 67 33.2322 66.0468 33.2322 64.891V50.6526H28.0254Z" fill="#82C91E"/>
<path d="M33.2203 43.7899V41.109C33.2203 39.9532 32.279 39 31.1233 39H30.1343C28.9786 39 28.0254 39.9532 28.0254 41.109V43.7899H33.2203Z" fill="#82C91E"/>
<path d="M44.7777 55.3474V41.109C44.7777 39.9532 43.8364 39 42.6807 39H41.6917C40.536 39 39.5828 39.9532 39.5828 41.109V55.3474H44.7777Z" fill="#82C91E"/>
<path d="M39.5828 62.2099V64.8908C39.5828 66.0466 40.536 66.9998 41.6917 66.9998H42.6807C43.8364 66.9998 44.7896 66.0466 44.7896 64.8908V62.2099H39.5828Z" fill="#82C91E"/>
<path d="M27.1912 56.1805H24.5103C23.3546 56.1805 22.4014 57.1218 22.4014 58.2894V59.2784C22.4014 60.4341 23.3426 61.3873 24.5103 61.3873H27.1912V56.1805Z" fill="#A3E635"/>
<path d="M48.2924 56.1805H34.054V61.3873H48.2924C49.4481 61.3873 50.4013 60.4341 50.4013 59.2784V58.2894C50.4013 57.1218 49.4481 56.1805 48.2924 56.1805Z" fill="#A3E635"/>
<path d="M38.7486 44.6231H24.5103C23.3546 44.6231 22.4014 45.5644 22.4014 46.7321V47.721C22.4014 48.8768 23.3426 49.83 24.5103 49.83H38.7486V44.6231Z" fill="#A3E635"/>
<path d="M48.2924 44.623H45.6116V49.8299H48.2924C49.4482 49.8299 50.4014 48.8886 50.4014 47.721V46.732C50.4014 45.5643 49.4482 44.623 48.2924 44.623Z" fill="#A3E635"/>
</svg>

After

Width:  |  Height:  |  Size: 8.4 KiB

Some files were not shown because too many files have changed in this diff Show More