mirror of
https://github.com/bitwarden/mobile
synced 2026-01-04 17:43:17 +00:00
Compare commits
405 Commits
ps/sdk
...
a798ae0761
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a798ae0761 | ||
|
|
7f8b19a0a7 | ||
|
|
e50175abe1 | ||
|
|
8f435b2f26 | ||
|
|
cdbdec8943 | ||
|
|
3d42da2a29 | ||
|
|
16303e581b | ||
|
|
bc4b03b994 | ||
|
|
484eb03eca | ||
|
|
d59f80776c | ||
|
|
44849cb0a2 | ||
|
|
65794c02b1 | ||
|
|
8bc90b9649 | ||
|
|
466bb81cb7 | ||
|
|
c957e46ff8 | ||
|
|
d2d442253b | ||
|
|
f1a2714e8a | ||
|
|
9083bb1ab8 | ||
|
|
a69420257d | ||
|
|
ef81365ae0 | ||
|
|
81ad6b3cc4 | ||
|
|
5ca0167dbb | ||
|
|
e1f3f3dfd9 | ||
|
|
53a5a9caaa | ||
|
|
94381eebf0 | ||
|
|
b43eaf4a0a | ||
|
|
b89d8214d2 | ||
|
|
902ce67867 | ||
|
|
062b15aae9 | ||
|
|
dcf441afd7 | ||
|
|
c987840936 | ||
|
|
6e93983711 | ||
|
|
70de8245fe | ||
|
|
77d9920aab | ||
|
|
b908f1c721 | ||
|
|
46a249de46 | ||
|
|
837628e9bc | ||
|
|
3262fdc9ec | ||
|
|
c763b0072b | ||
|
|
b81ce44cc7 | ||
|
|
8a43bb4655 | ||
|
|
44f8901519 | ||
|
|
463d837fa8 | ||
|
|
ad6ffad5d1 | ||
|
|
9edcc8b4f7 | ||
|
|
cf5c5aa114 | ||
|
|
36c7beb1e6 | ||
|
|
f6d798af94 | ||
|
|
08ed70d5b1 | ||
|
|
33e0187460 | ||
|
|
2b78859d06 | ||
|
|
81205154c4 | ||
|
|
14d2660b61 | ||
|
|
bad5673724 | ||
|
|
67b76a777e | ||
|
|
02f5936fce | ||
|
|
fc208b08d7 | ||
|
|
f165135147 | ||
|
|
d458f17ad6 | ||
|
|
c3bd4b84b1 | ||
|
|
0af78d0e03 | ||
|
|
e86a01a7db | ||
|
|
e16074a73e | ||
|
|
a333e72448 | ||
|
|
ffb7b3b8ac | ||
|
|
c8d0db9f31 | ||
|
|
8566f5c00a | ||
|
|
b65f18d8e2 | ||
|
|
7a3816007b | ||
|
|
477b1cca44 | ||
|
|
dee9524b2c | ||
|
|
f5572511c6 | ||
|
|
9a17da009c | ||
|
|
b5443c79d2 | ||
|
|
9dc620b492 | ||
|
|
1f966e6cbe | ||
|
|
a4fa03656e | ||
|
|
12385d9add | ||
|
|
13ca0fd4cb | ||
|
|
0b28b954fe | ||
|
|
e4841bb322 | ||
|
|
98621341a2 | ||
|
|
2023fe6644 | ||
|
|
567a23e29f | ||
|
|
8b65d99442 | ||
|
|
f80ec1b221 | ||
|
|
ba1183234b | ||
|
|
5946af9eec | ||
|
|
b091051633 | ||
|
|
06488539b0 | ||
|
|
8f77822b1b | ||
|
|
3c1105b35d | ||
|
|
c847449db8 | ||
|
|
c2771eb3c7 | ||
|
|
6e41731dcb | ||
|
|
7c90b35592 | ||
|
|
93f9dc4498 | ||
|
|
e033832261 | ||
|
|
fa5d92fbf7 | ||
|
|
e672cb132f | ||
|
|
e7a7eed7e8 | ||
|
|
43a4915323 | ||
|
|
b1ae3cc325 | ||
|
|
b9dada07ea | ||
|
|
58442389df | ||
|
|
a3378d33ae | ||
|
|
2e1982b08e | ||
|
|
e9e9b6f7bc | ||
|
|
9be8fec219 | ||
|
|
9db32ca019 | ||
|
|
f04ff7777a | ||
|
|
64775694e0 | ||
|
|
3c0007a21a | ||
|
|
35ff235010 | ||
|
|
01bd5a7b8d | ||
|
|
3fce8c76bc | ||
|
|
3b64d7b979 | ||
|
|
f343a2cdbb | ||
|
|
9a9fb85ad8 | ||
|
|
e7f9d64edb | ||
|
|
459d20c019 | ||
|
|
a8529fa4b7 | ||
|
|
d1e82c9f1d | ||
|
|
9bc2901255 | ||
|
|
e3441845cd | ||
|
|
3f463647a0 | ||
|
|
4f169a6fe3 | ||
|
|
82c2e91446 | ||
|
|
7482808857 | ||
|
|
fd233fa27f | ||
|
|
19f238d9bb | ||
|
|
6f6487ccc9 | ||
|
|
dd3dc82595 | ||
|
|
40c80f082d | ||
|
|
bca5b95446 | ||
|
|
602627b5fa | ||
|
|
6f32afb919 | ||
|
|
2ca47a4da4 | ||
|
|
4ff56ba11e | ||
|
|
22d0cc681c | ||
|
|
4e0a18cce5 | ||
|
|
c9fdfa7a15 | ||
|
|
850a7e754a | ||
|
|
67c5f79625 | ||
|
|
04e7cfe06d | ||
|
|
d6c2ebe4c2 | ||
|
|
2a28294f91 | ||
|
|
8584bbaecc | ||
|
|
2f3cded9c5 | ||
|
|
eff0ea7ce7 | ||
|
|
6c3a53dd76 | ||
|
|
cf8d801c55 | ||
|
|
eaa6844742 | ||
|
|
29e2f728e0 | ||
|
|
fe160a570f | ||
|
|
a508bea4b0 | ||
|
|
a73923c4f7 | ||
|
|
11465e8975 | ||
|
|
4c88524f0e | ||
|
|
f1c20e03bc | ||
|
|
920a2273c5 | ||
|
|
96a9978ef8 | ||
|
|
1ae388cb03 | ||
|
|
c6aaf5002f | ||
|
|
75be6504e1 | ||
|
|
cae1825e3f | ||
|
|
c23100d281 | ||
|
|
c9c0d0b4d6 | ||
|
|
fec0743e4d | ||
|
|
118dcf164c | ||
|
|
bd03b6b5aa | ||
|
|
333917c00d | ||
|
|
450101d9e4 | ||
|
|
4e50f1697d | ||
|
|
3c96ae2220 | ||
|
|
fdbd16a6fd | ||
|
|
39a34bd8c4 | ||
|
|
f30158adf5 | ||
|
|
c6a086fe62 | ||
|
|
b217451ea9 | ||
|
|
8cb7d5e1a3 | ||
|
|
82b837ef33 | ||
|
|
ebb2a288a1 | ||
|
|
de7ae27a77 | ||
|
|
d3dd2e9342 | ||
|
|
a5878d3341 | ||
|
|
1dc55f78e7 | ||
|
|
37b62b317f | ||
|
|
528e412458 | ||
|
|
0f22f2750e | ||
|
|
7bbb711175 | ||
|
|
fd80a9ce7c | ||
|
|
3f10a6be24 | ||
|
|
f3537b1a74 | ||
|
|
849a0c24b0 | ||
|
|
f6a58e469f | ||
|
|
983937c9eb | ||
|
|
b2f93d3d4b | ||
|
|
64c694e593 | ||
|
|
56b9e3f615 | ||
|
|
7558f60a44 | ||
|
|
e66ac9dd44 | ||
|
|
d6c139cb8a | ||
|
|
6b7c6eac71 | ||
|
|
9e1d6c7b03 | ||
|
|
e107b893ea | ||
|
|
5de02c863f | ||
|
|
0e95d4d4ca | ||
|
|
a42b88b666 | ||
|
|
af6866cee1 | ||
|
|
0cec49f121 | ||
|
|
d091922017 | ||
|
|
f14be2a3a2 | ||
|
|
8ee744b746 | ||
|
|
15a03ba573 | ||
|
|
82711a0235 | ||
|
|
e6635564aa | ||
|
|
6c078fe343 | ||
|
|
743e71ff92 | ||
|
|
7b579b7aa5 | ||
|
|
fe10fd7766 | ||
|
|
3c0de8aacc | ||
|
|
18d9a77f25 | ||
|
|
9eca82a62b | ||
|
|
b90e030b8f | ||
|
|
9a28419a4e | ||
|
|
f4c468e6a1 | ||
|
|
2c346eb710 | ||
|
|
9c0908f7b7 | ||
|
|
827fbbc9ce | ||
|
|
5b249bed67 | ||
|
|
afbcb212f6 | ||
|
|
a71c28536d | ||
|
|
ba5fa8a518 | ||
|
|
65ea5574de | ||
|
|
f013f69669 | ||
|
|
f98dfa6581 | ||
|
|
0723999652 | ||
|
|
96343eccf7 | ||
|
|
793c5fef6f | ||
|
|
3a13ba4efa | ||
|
|
c5288d3921 | ||
|
|
9506595fdd | ||
|
|
7a65bf7fd7 | ||
|
|
d0ce89fedb | ||
|
|
3c94ea4579 | ||
|
|
658c1eaf64 | ||
|
|
02b0265767 | ||
|
|
bd2481b3e4 | ||
|
|
12c72b2833 | ||
|
|
2e5fb414b5 | ||
|
|
4dda7a6634 | ||
|
|
a1808f64b3 | ||
|
|
142c3145f0 | ||
|
|
72de17bd1d | ||
|
|
ed3467515e | ||
|
|
21fc56457d | ||
|
|
bc2eb212a6 | ||
|
|
a1912526c2 | ||
|
|
9d0209751c | ||
|
|
f2936c95fa | ||
|
|
bb2f1f0f5f | ||
|
|
5a0c2115a1 | ||
|
|
a67f50b145 | ||
|
|
757e5ea647 | ||
|
|
b23f29511c | ||
|
|
71731bb9b7 | ||
|
|
f2be840a7d | ||
|
|
685e0f407a | ||
|
|
bbef0f8c93 | ||
|
|
3cdf5ccd3b | ||
|
|
e97a37222a | ||
|
|
218a30b510 | ||
|
|
828043ec97 | ||
|
|
b25c8b0842 | ||
|
|
a4a0d31fc6 | ||
|
|
6ef6cf5d84 | ||
|
|
597f629920 | ||
|
|
b8cef16711 | ||
|
|
c4f6ae9077 | ||
|
|
8b9658d2c5 | ||
|
|
43bf0fbdb3 | ||
|
|
11922c6f49 | ||
|
|
a6f05338c2 | ||
|
|
b932824b5a | ||
|
|
efd1671f48 | ||
|
|
3e2005e5ed | ||
|
|
382eee2ed3 | ||
|
|
b0f1dd00ee | ||
|
|
5961a001ab | ||
|
|
9026dd10e5 | ||
|
|
355261679d | ||
|
|
7f14ec9b5d | ||
|
|
0c72626916 | ||
|
|
f21fae7fea | ||
|
|
6d4792bc24 | ||
|
|
dbadf8c56f | ||
|
|
4d0f9d1c03 | ||
|
|
68759fc608 | ||
|
|
47be3d6aef | ||
|
|
7ec5c8ccfd | ||
|
|
819aabb330 | ||
|
|
9c7ff853d7 | ||
|
|
e30f9903d1 | ||
|
|
249406e3a8 | ||
|
|
8cae840c68 | ||
|
|
e274c04107 | ||
|
|
7043be67dd | ||
|
|
afb8c515d6 | ||
|
|
bfcfd367dd | ||
|
|
a23454bc53 | ||
|
|
6f7100ae4f | ||
|
|
01ac20e6e4 | ||
|
|
8474f536ff | ||
|
|
f426c0e370 | ||
|
|
420dc09fd1 | ||
|
|
6d4793d592 | ||
|
|
eea7c6b7d7 | ||
|
|
ec93a61275 | ||
|
|
c34d1da6e6 | ||
|
|
c4e64e082b | ||
|
|
5aaff1ea20 | ||
|
|
0271a4db4c | ||
|
|
375718f945 | ||
|
|
9eda015371 | ||
|
|
ea81acb3bf | ||
|
|
174549e5bc | ||
|
|
87b1d18872 | ||
|
|
ae9ba810ff | ||
|
|
dd52ff0dcc | ||
|
|
c678c17ebc | ||
|
|
cd9e49b13b | ||
|
|
6d7970f767 | ||
|
|
9adc4d3080 | ||
|
|
1f20f70d13 | ||
|
|
a25da68437 | ||
|
|
fdc0313d10 | ||
|
|
f31c87b52e | ||
|
|
1e79e1182f | ||
|
|
11947ce99a | ||
|
|
4abb472998 | ||
|
|
1d541e5b8e | ||
|
|
175b9936b6 | ||
|
|
72e67bd6f2 | ||
|
|
216c6abcf6 | ||
|
|
1014563c75 | ||
|
|
3506269811 | ||
|
|
31487a31bb | ||
|
|
1407aa5655 | ||
|
|
16f59e2698 | ||
|
|
d876b54f45 | ||
|
|
6644e3b449 | ||
|
|
8d98d1d5bd | ||
|
|
3e9711f8f2 | ||
|
|
3af37f01d3 | ||
|
|
43d2d386b1 | ||
|
|
bc5c11b47f | ||
|
|
52843b4181 | ||
|
|
98705e443f | ||
|
|
1332ef7b43 | ||
|
|
04e30c2146 | ||
|
|
f604da13a1 | ||
|
|
dcf9acb51c | ||
|
|
3b087c50ae | ||
|
|
1c13ed9895 | ||
|
|
eeb634e698 | ||
|
|
8bc2df6c8a | ||
|
|
7cd40d4d89 | ||
|
|
bebf23785d | ||
|
|
e78833cbcb | ||
|
|
b7ff636862 | ||
|
|
0288a6659c | ||
|
|
c7fd113f26 | ||
|
|
79241731e7 | ||
|
|
74e9914f5b | ||
|
|
65307f6eab | ||
|
|
e9f83aee90 | ||
|
|
fdaf743868 | ||
|
|
9d6b938ba9 | ||
|
|
1c8328f62d | ||
|
|
f24b82f345 | ||
|
|
37f1a7087e | ||
|
|
6bb654e630 | ||
|
|
fc260f8159 | ||
|
|
bf463926a3 | ||
|
|
c1673a1bbf | ||
|
|
7b44395e1a | ||
|
|
0f3529aab8 | ||
|
|
a72779997c | ||
|
|
49da536c7a | ||
|
|
c985c0a62b | ||
|
|
0f417b8434 | ||
|
|
4f0238122b | ||
|
|
52ff634f00 | ||
|
|
e820537fce | ||
|
|
7130d8a18c | ||
|
|
659d34dfc2 | ||
|
|
6a5c999628 | ||
|
|
3bcb44ea71 | ||
|
|
b108b4e71d | ||
|
|
a72f267558 | ||
|
|
cc75cebdb8 | ||
|
|
3a0510d6b4 | ||
|
|
0c4b88e562 | ||
|
|
ac3b0c2bad |
51
.github/CODEOWNERS
vendored
Normal file
51
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
# Please sort into logical groups with comment headers. Sort groups in order of specificity.
|
||||
# For example, default owners should always be the first group.
|
||||
# Sort lines alphabetically within these groups to avoid accidentally adding duplicates.
|
||||
#
|
||||
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
|
||||
|
||||
# Default file owners
|
||||
* @bitwarden/dept-development-mobile
|
||||
|
||||
|
||||
## Auth team files ##
|
||||
|
||||
## Platform team files ##
|
||||
appIcons @bitwarden/team-platform-dev
|
||||
|
||||
## Vault team files ##
|
||||
src/watchOS @bitwarden/team-vault-dev
|
||||
|
||||
## Tools team files ##
|
||||
src/Core/Services/EmailForwarders @bitwarden/team-tools-dev
|
||||
|
||||
## Crowdin Sync files ##
|
||||
src/Core/Resources/Localization @bitwarden/team-tools-dev
|
||||
src/watchOS/bitwarden/bitwarden\ WatchKit\ Extension/Localization @bitwarden/team-tools-dev
|
||||
store/apple @bitwarden/team-tools-dev
|
||||
store/google @bitwarden/team-tools-dev
|
||||
|
||||
## Locales ##
|
||||
src/Core/Resources/Localization/AppResources.Designer.cs
|
||||
src/Core/Resources/Localization/AppResources.resx
|
||||
src/watchOS/bitwarden/bitwarden\ WatchKit\ Extension/Localization/en.lproj
|
||||
store/apple/en
|
||||
store/google/en
|
||||
|
||||
## Utils ##
|
||||
store/google/Publisher
|
||||
|
||||
## These workflows have joint ownership ##
|
||||
.github/workflows/build.yml @bitwarden/dept-bre @bitwarden/dept-development-mobile
|
||||
.github/workflows/build-beta.yml @bitwarden/dept-bre @bitwarden/dept-development-mobile
|
||||
.github/workflows/cleanup-rc-branch.yml @bitwarden/dept-bre @bitwarden/dept-development-mobile
|
||||
.github/workflows/release.yml @bitwarden/dept-bre @bitwarden/dept-development-mobile
|
||||
.github/workflows/version-auto-bump.yml @bitwarden/dept-bre @bitwarden/dept-development-mobile
|
||||
.github/workflows/version-bump.yml @bitwarden/dept-bre @bitwarden/dept-development-mobile
|
||||
|
||||
# Shared ownership for version bump automation
|
||||
src/App/Platforms/Android/AndroidManifest.xml
|
||||
src/iOS.Autofill/Info.plist
|
||||
src/iOS.Extension/Info.plist
|
||||
src/iOS.ShareExtension/Info.plist
|
||||
src/App/Platforms/iOS/Info.plist
|
||||
18
.github/ISSUE_TEMPLATE/bug.yml
vendored
18
.github/ISSUE_TEMPLATE/bug.yml
vendored
@@ -6,8 +6,20 @@ body:
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
|
||||
> [!WARNING]
|
||||
> Testing the new Bitwarden Beta apps? Submit your report in [bitwarden/android](https://github.com/bitwarden/android) or [bitwarden/ios](https://github.com/bitwarden/ios)
|
||||
|
||||
|
||||
Please do not submit feature requests. The [Community Forums](https://community.bitwarden.com) has a section for submitting, voting for, and discussing product feature requests.
|
||||
- type: checkboxes
|
||||
id: production
|
||||
attributes:
|
||||
label: Production Build
|
||||
options:
|
||||
- label: I'm using the legacy Bitwarden app pubicly available in App Store / Play Store and I'm aware that Bitwarden Beta bugs should be reported in [bitwarden/android](https://github.com/bitwarden/android) or [bitwarden/ios](https://github.com/bitwarden/ios)
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduce
|
||||
attributes:
|
||||
@@ -73,9 +85,3 @@ body:
|
||||
description: What version of our software are you running? (go to "Settings" → "About" in the app)
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: beta
|
||||
attributes:
|
||||
label: Beta
|
||||
options:
|
||||
- label: Using a pre-release version of the application.
|
||||
|
||||
12
.github/ISSUE_TEMPLATE/config.yml
vendored
12
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,5 +1,14 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Native Android Beta Bug Reports
|
||||
url: https://github.com/bitwarden/android/issues
|
||||
about: Bugs found in the new native Android Beta app should be reported in [bitwarden/android](https://github.com/bitwarden/android)
|
||||
- name: Native iOS BETA Bug Reports
|
||||
url: https://github.com/bitwarden/ios/issues
|
||||
about: Bugs found in the new native iOS Beta app should be reported in [bitwarden/ios](https://github.com/bitwarden/ios)
|
||||
- name: Customer Support
|
||||
url: https://bitwarden.com/contact/
|
||||
about: Please contact our customer support for account issues and general customer support.
|
||||
- name: Report mobile autofill failure
|
||||
url: https://docs.google.com/forms/d/e/1FAIpQLScMopHyN7KGJs8hW562VTzbIGL4KcFnx0wJcsW0GYE1BnPiGA/viewform
|
||||
about: We are aware of some situations where the Bitwarden mobile app will not autofill information correctly. This is something the Bitwarden team is actively working on but need your help as a community and active Bitwarden users!
|
||||
@@ -9,9 +18,6 @@ contact_links:
|
||||
- name: Bitwarden Community Forums
|
||||
url: https://community.bitwarden.com
|
||||
about: Please visit the community forums for general community discussion, support and the development roadmap.
|
||||
- name: Customer Support
|
||||
url: https://bitwarden.com/contact/
|
||||
about: Please contact our customer support for account issues and general customer support.
|
||||
- name: Security Issues
|
||||
url: https://hackerone.com/bitwarden
|
||||
about: We use HackerOne to manage security disclosures.
|
||||
|
||||
26
.github/labeler.yml
vendored
Normal file
26
.github/labeler.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
android:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- src/App/*
|
||||
- src/Core/*
|
||||
- src/Android/*
|
||||
- 'src/Xamarin.AndroidX.Credentials/*'
|
||||
|
||||
iOS:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- src/App/*
|
||||
- src/Core/*
|
||||
- lib/ios/*
|
||||
- src/iOS/*
|
||||
- 'src/iOS.Autofill/*'
|
||||
- 'src/iOS.Core/*'
|
||||
- 'src/iOS.Extension/*'
|
||||
- 'src/iOS.ShareExtension/*'
|
||||
- 'src/iOS.Widget/*'
|
||||
- src/watchOS/*
|
||||
|
||||
watchOS:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- src/watchOS/*
|
||||
57
.github/renovate.json
vendored
57
.github/renovate.json
vendored
@@ -1,22 +1,37 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:base",
|
||||
"schedule:monthly",
|
||||
":maintainLockFilesMonthly",
|
||||
":preserveSemverRanges",
|
||||
":rebaseStalePrs",
|
||||
":disableDependencyDashboard"
|
||||
],
|
||||
"enabledManagers": [
|
||||
"nuget"
|
||||
],
|
||||
"packageRules": [
|
||||
{
|
||||
"matchManagers": ["nuget"],
|
||||
"groupName": "Nuget updates",
|
||||
"groupSlug": "nuget",
|
||||
"separateMajorMinor": false
|
||||
}
|
||||
]
|
||||
}
|
||||
"enabled": false,
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:base",
|
||||
"github>bitwarden/renovate-config:pin-actions",
|
||||
":combinePatchMinorReleases",
|
||||
":dependencyDashboard",
|
||||
":maintainLockFilesWeekly",
|
||||
":pinAllExceptPeerDependencies",
|
||||
":prConcurrentLimit10",
|
||||
":rebaseStalePrs",
|
||||
":separateMajorReleases",
|
||||
"group:monorepos",
|
||||
"schedule:weekends"
|
||||
],
|
||||
"enabledManagers": ["github-actions", "npm", "nuget"],
|
||||
"commitMessagePrefix": "[deps]:",
|
||||
"commitMessageTopic": "{{depName}}",
|
||||
"packageRules": [
|
||||
{
|
||||
"groupName": "gh minor",
|
||||
"matchManagers": ["github-actions"],
|
||||
"matchUpdateTypes": ["minor", "patch"]
|
||||
},
|
||||
{
|
||||
"groupName": "npm minor",
|
||||
"matchManagers": ["npm"],
|
||||
"matchUpdateTypes": ["minor", "patch"]
|
||||
},
|
||||
{
|
||||
"groupName": "nuget minor",
|
||||
"matchManagers": ["nuget"],
|
||||
"matchUpdateTypes": ["minor", "patch"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
BIN
.github/secrets/GoogleService-Info.plist.gpg
vendored
BIN
.github/secrets/GoogleService-Info.plist.gpg
vendored
Binary file not shown.
BIN
.github/secrets/app_fdroid-keystore.jks.gpg
vendored
BIN
.github/secrets/app_fdroid-keystore.jks.gpg
vendored
Binary file not shown.
BIN
.github/secrets/app_play-keystore.jks.gpg
vendored
BIN
.github/secrets/app_play-keystore.jks.gpg
vendored
Binary file not shown.
BIN
.github/secrets/app_upload-keystore.jks.gpg
vendored
BIN
.github/secrets/app_upload-keystore.jks.gpg
vendored
Binary file not shown.
BIN
.github/secrets/bitwarden-mobile-key.p12.gpg
vendored
BIN
.github/secrets/bitwarden-mobile-key.p12.gpg
vendored
Binary file not shown.
BIN
.github/secrets/dist_autofill.mobileprovision.gpg
vendored
BIN
.github/secrets/dist_autofill.mobileprovision.gpg
vendored
Binary file not shown.
BIN
.github/secrets/dist_bitwarden.mobileprovision.gpg
vendored
BIN
.github/secrets/dist_bitwarden.mobileprovision.gpg
vendored
Binary file not shown.
BIN
.github/secrets/dist_extension.mobileprovision.gpg
vendored
BIN
.github/secrets/dist_extension.mobileprovision.gpg
vendored
Binary file not shown.
Binary file not shown.
BIN
.github/secrets/dist_watch_app.mobileprovision.gpg
vendored
BIN
.github/secrets/dist_watch_app.mobileprovision.gpg
vendored
Binary file not shown.
Binary file not shown.
3
.github/secrets/google-services.json.gpg
vendored
3
.github/secrets/google-services.json.gpg
vendored
@@ -1,3 +0,0 @@
|
||||
<EFBFBD>
|
||||
K<>Y#<23>(<28><><EFBFBD><EFBFBD>EI߄T?)l<><6C><EFBFBD><18><><10>"=<3D>|<7C>'e<><0E>m<EFBFBD>/~<7E><>'F<><46>><3E><><EFBFBD><EFBFBD>l<EFBFBD>b<EFBFBD>[<5B>+R<><52>iL<69><4C>"<22><><EFBFBD>~V:<3A><>p<EFBFBD>a<17>ڵel%8t<38><74>튖<EFBFBD>y<<3C>n<EFBFBD><6E><EFBFBD>aU<61>w<16>JD<4A><44><1F><>We<57>9<EFBFBD><39><EFBFBD><EFBFBD><x8d<38>O<EFBFBD>j\<14>ד<EFBFBD><D793><EFBFBD>Vq<56><71>
|
||||
Ǻ<EFBFBD>-<2D>#<23><><11><>]$<24>(<28>l,<2C>Br<42><02><>d<><64><EFBFBD>a-<2D><><EFBFBD>:<3A><>:<3A><04>9b,!Em<02><19><>Qf<>D<EFBFBD>g<EFBFBD><06><0E>x(P<>ȡ~<7E><EFBFBD><CDB9> <09><>[<06><>!:<3A>;f<><66>
|
||||
BIN
.github/secrets/iphone-distribution-cert.p12.gpg
vendored
BIN
.github/secrets/iphone-distribution-cert.p12.gpg
vendored
Binary file not shown.
BIN
.github/secrets/play_creds.json.gpg
vendored
BIN
.github/secrets/play_creds.json.gpg
vendored
Binary file not shown.
BIN
.github/secrets/store_fdroid-keystore.jks.gpg
vendored
BIN
.github/secrets/store_fdroid-keystore.jks.gpg
vendored
Binary file not shown.
13
.github/workflows/automatic-issue-responses.yml
vendored
13
.github/workflows/automatic-issue-responses.yml
vendored
@@ -1,4 +1,3 @@
|
||||
---
|
||||
name: Automatic responses
|
||||
on:
|
||||
issues:
|
||||
@@ -7,14 +6,14 @@ on:
|
||||
jobs:
|
||||
close-issue:
|
||||
name: 'Close issue with automatic response'
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
issues: write
|
||||
steps:
|
||||
# Feature request
|
||||
- if: github.event.label.name == 'feature-request'
|
||||
name: Feature request
|
||||
uses: peter-evans/close-issue@849549ba7c3a595a064c4b2c56f206ee78f93515 # v2.0.0
|
||||
uses: peter-evans/close-issue@276d7966e389d888f011539a86c8920025ea0626 # v3.0.1
|
||||
with:
|
||||
comment: |
|
||||
We use GitHub issues as a place to track bugs and other development related issues. The [Bitwarden Community Forums](https://community.bitwarden.com/) has a [Feature Requests](https://community.bitwarden.com/c/feature-requests) section for submitting, voting for, and discussing requests like this one.
|
||||
@@ -25,7 +24,7 @@ jobs:
|
||||
# Intended behavior
|
||||
- if: github.event.label.name == 'intended-behavior'
|
||||
name: Intended behaviour
|
||||
uses: peter-evans/close-issue@849549ba7c3a595a064c4b2c56f206ee78f93515 # v2.0.0
|
||||
uses: peter-evans/close-issue@276d7966e389d888f011539a86c8920025ea0626 # v3.0.1
|
||||
with:
|
||||
comment: |
|
||||
Your issue appears to be describing the intended behavior of the software. If you want this to be changed, it would be a feature request.
|
||||
@@ -38,7 +37,7 @@ jobs:
|
||||
# Customer support request
|
||||
- if: github.event.label.name == 'customer-support'
|
||||
name: Customer Support request
|
||||
uses: peter-evans/close-issue@849549ba7c3a595a064c4b2c56f206ee78f93515 # v2.0.0
|
||||
uses: peter-evans/close-issue@276d7966e389d888f011539a86c8920025ea0626 # v3.0.1
|
||||
with:
|
||||
comment: |
|
||||
We use GitHub issues as a place to track bugs and other development related issues. Your issue appears to be a support request, or would otherwise be better handled by our dedicated Customer Success team.
|
||||
@@ -49,14 +48,14 @@ jobs:
|
||||
# Resolved
|
||||
- if: github.event.label.name == 'resolved'
|
||||
name: Resolved
|
||||
uses: peter-evans/close-issue@849549ba7c3a595a064c4b2c56f206ee78f93515 # v2.0.0
|
||||
uses: peter-evans/close-issue@276d7966e389d888f011539a86c8920025ea0626 # v3.0.1
|
||||
with:
|
||||
comment: |
|
||||
We’ve closed this issue, as it appears the original problem has been resolved. If this happens again or continues to be an problem, please respond to this issue with any additional detail to assist with reproduction and root cause analysis.
|
||||
# Stale
|
||||
- if: github.event.label.name == 'stale'
|
||||
name: Stale
|
||||
uses: peter-evans/close-issue@849549ba7c3a595a064c4b2c56f206ee78f93515 # v2.0.0
|
||||
uses: peter-evans/close-issue@276d7966e389d888f011539a86c8920025ea0626 # v3.0.1
|
||||
with:
|
||||
comment: |
|
||||
As we haven’t heard from you about this problem in some time, this issue will now be closed.
|
||||
|
||||
349
.github/workflows/build-beta.yml
vendored
Normal file
349
.github/workflows/build-beta.yml
vendored
Normal file
@@ -0,0 +1,349 @@
|
||||
name: Build Beta
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
ref:
|
||||
description: 'Branch or tag to build'
|
||||
required: true
|
||||
default: 'main'
|
||||
type: string
|
||||
|
||||
env:
|
||||
main_app_folder_path: src/App
|
||||
main_app_project_path: src/App/App.csproj
|
||||
target-net-version: net8.0
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
name: Setup
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
rc_branch_exists: ${{ steps.branch-check.outputs.rc_branch_exists }}
|
||||
hotfix_branch_exists: ${{ steps.branch-check.outputs.hotfix_branch_exists }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
- name: Check if special branches exist
|
||||
id: branch-check
|
||||
run: |
|
||||
if [[ $(git ls-remote --heads origin rc) ]]; then
|
||||
echo "rc_branch_exists=1" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "rc_branch_exists=0" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
if [[ $(git ls-remote --heads origin hotfix-rc) ]]; then
|
||||
echo "hotfix_branch_exists=1" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "hotfix_branch_exists=0" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
ios:
|
||||
name: Apple iOS
|
||||
runs-on: macos-14
|
||||
needs: setup
|
||||
env:
|
||||
_IOS_FOLDER_PATH: src/App/Platforms/iOS
|
||||
_APP_OUTPUT_NAME: App
|
||||
_APP_CI_OUTPUT_FILENAME: App_x64_Debug
|
||||
steps:
|
||||
- name: Set XCode version
|
||||
uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
|
||||
with:
|
||||
xcode-version: 15.1
|
||||
|
||||
- name: Setup NuGet
|
||||
uses: nuget/setup-nuget@a21f25cd3998bf370fde17e3f1b4c12c175172f9 # v2.0.0
|
||||
with:
|
||||
nuget-version: 6.4.0
|
||||
|
||||
- name: Set up .NET
|
||||
uses: actions/setup-dotnet@6bd8b7f7774af54e05809fcc5431931b3eb1ddee # v4.0.1
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
|
||||
# This step might be obsolete at some point as .NET MAUI workloads
|
||||
# are starting to come pre-installed on the GH Actions build agents.
|
||||
- name: Install MAUI Workload
|
||||
run: dotnet workload install maui --ignore-failed-sources
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
nuget help | grep Version
|
||||
dotnet --info
|
||||
echo "GitHub ref: $GITHUB_REF"
|
||||
echo "GitHub event: $GITHUB_EVENT"
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ inputs.ref }}
|
||||
submodules: 'true'
|
||||
|
||||
- name: Login to Azure - CI Subscription
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: "bitwarden-ci"
|
||||
secrets: "appcenter-ios-token"
|
||||
|
||||
- name: Download Provisioning Profiles secrets
|
||||
env:
|
||||
ACCOUNT_NAME: bitwardenci
|
||||
CONTAINER_NAME: profiles
|
||||
run: |
|
||||
mkdir -p $HOME/secrets
|
||||
profiles=(
|
||||
"dist_beta_autofill.mobileprovision"
|
||||
"dist_beta_bitwarden.mobileprovision"
|
||||
"dist_beta_extension.mobileprovision"
|
||||
"dist_beta_share_extension.mobileprovision"
|
||||
"dist_beta_bitwarden_watch_app.mobileprovision"
|
||||
"dist_beta_bitwarden_watch_app_extension.mobileprovision"
|
||||
)
|
||||
|
||||
for FILE in "${profiles[@]}"
|
||||
do
|
||||
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME --name $FILE \
|
||||
--file $HOME/secrets/$FILE --output none
|
||||
done
|
||||
|
||||
- name: Download Google Services secret
|
||||
env:
|
||||
ACCOUNT_NAME: bitwardenci
|
||||
CONTAINER_NAME: mobile
|
||||
FILE: GoogleService-Info.plist
|
||||
run: |
|
||||
mkdir -p $HOME/secrets
|
||||
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME --name $FILE \
|
||||
--file $HOME/secrets/$FILE --output none
|
||||
|
||||
- name: Increment version
|
||||
run: |
|
||||
BUILD_NUMBER=$((100 + $GITHUB_RUN_NUMBER))
|
||||
echo "##### Setting CFBundleVersion $BUILD_NUMBER"
|
||||
|
||||
echo "### CFBundleVersion $BUILD_NUMBER" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
perl -0777 -pi.bak -e 's/<key>CFBundleVersion<\/key>\s*<string>1<\/string>/<key>CFBundleVersion<\/key>\n\t<string>'"$BUILD_NUMBER"'<\/string>/' ./${{ env._IOS_FOLDER_PATH }}/Info.plist
|
||||
perl -0777 -pi.bak -e 's/<key>CFBundleVersion<\/key>\s*<string>1<\/string>/<key>CFBundleVersion<\/key>\n\t<string>'"$BUILD_NUMBER"'<\/string>/' ./src/iOS.Extension/Info.plist
|
||||
perl -0777 -pi.bak -e 's/<key>CFBundleVersion<\/key>\s*<string>1<\/string>/<key>CFBundleVersion<\/key>\n\t<string>'"$BUILD_NUMBER"'<\/string>/' ./src/iOS.Autofill/Info.plist
|
||||
perl -0777 -pi.bak -e 's/<key>CFBundleVersion<\/key>\s*<string>1<\/string>/<key>CFBundleVersion<\/key>\n\t<string>'"$BUILD_NUMBER"'<\/string>/' ./src/iOS.ShareExtension/Info.plist
|
||||
cd src/watchOS/bitwarden
|
||||
agvtool new-version -all $BUILD_NUMBER
|
||||
|
||||
- name: Update Entitlements
|
||||
run: |
|
||||
echo "##### Updating Entitlements"
|
||||
perl -0777 -pi.bak -e 's/<key>aps-environment<\/key>\s*<string>development<\/string>/<key>aps-environment<\/key>\n\t<string>beta<\/string>/' ./${{ env._IOS_FOLDER_PATH }}/Entitlements.plist
|
||||
|
||||
- name: Get certificates
|
||||
run: |
|
||||
mkdir -p $HOME/certificates
|
||||
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/ios-distribution |
|
||||
jq -r .value | base64 -d > $HOME/certificates/ios-distribution.p12
|
||||
|
||||
- name: Set up Keychain
|
||||
env:
|
||||
KEYCHAIN_PASSWORD: ${{ secrets.IOS_KEYCHAIN_PASSWORD }}
|
||||
MOBILE_KEY_PASSWORD: ${{ secrets.IOS_KEY_PASSWORD }}
|
||||
DIST_CERT_PASSWORD: ${{ secrets.IOS_DIST_CERT_PASSWORD }}
|
||||
run: |
|
||||
security create-keychain -p $KEYCHAIN_PASSWORD build.keychain
|
||||
security default-keychain -s build.keychain
|
||||
security unlock-keychain -p $KEYCHAIN_PASSWORD build.keychain
|
||||
security set-keychain-settings -lut 1200 build.keychain
|
||||
|
||||
security import $HOME/certificates/ios-distribution.p12 -k build.keychain -P "" -T /usr/bin/codesign \
|
||||
-T /usr/bin/security
|
||||
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KEYCHAIN_PASSWORD build.keychain
|
||||
|
||||
- name: Set up provisioning profiles
|
||||
run: |
|
||||
AUTOFILL_PROFILE_PATH=$HOME/secrets/dist_beta_autofill.mobileprovision
|
||||
BITWARDEN_PROFILE_PATH=$HOME/secrets/dist_beta_bitwarden.mobileprovision
|
||||
EXTENSION_PROFILE_PATH=$HOME/secrets/dist_beta_extension.mobileprovision
|
||||
SHARE_EXTENSION_PROFILE_PATH=$HOME/secrets/dist_beta_share_extension.mobileprovision
|
||||
WATCH_APP_PROFILE_PATH=$HOME/secrets/dist_beta_bitwarden_watch_app.mobileprovision
|
||||
WATCH_APP_EXTENSION_PROFILE_PATH=$HOME/secrets/dist_beta_bitwarden_watch_app_extension.mobileprovision
|
||||
PROFILES_DIR_PATH=$HOME/Library/MobileDevice/Provisioning\ Profiles
|
||||
|
||||
mkdir -p "$PROFILES_DIR_PATH"
|
||||
|
||||
AUTOFILL_UUID=$(grep UUID -A1 -a $AUTOFILL_PROFILE_PATH | grep -io "[-A-F0-9]\{36\}")
|
||||
cp $AUTOFILL_PROFILE_PATH "$PROFILES_DIR_PATH/$AUTOFILL_UUID.mobileprovision"
|
||||
|
||||
BITWARDEN_UUID=$(grep UUID -A1 -a $BITWARDEN_PROFILE_PATH | grep -io "[-A-F0-9]\{36\}")
|
||||
cp $BITWARDEN_PROFILE_PATH "$PROFILES_DIR_PATH/$BITWARDEN_UUID.mobileprovision"
|
||||
|
||||
EXTENSION_UUID=$(grep UUID -A1 -a $EXTENSION_PROFILE_PATH | grep -io "[-A-F0-9]\{36\}")
|
||||
cp $EXTENSION_PROFILE_PATH "$PROFILES_DIR_PATH/$EXTENSION_UUID.mobileprovision"
|
||||
|
||||
SHARE_EXTENSION_UUID=$(grep UUID -A1 -a $SHARE_EXTENSION_PROFILE_PATH | grep -io "[-A-F0-9]\{36\}")
|
||||
cp $SHARE_EXTENSION_PROFILE_PATH "$PROFILES_DIR_PATH/$SHARE_EXTENSION_UUID.mobileprovision"
|
||||
|
||||
WATCH_APP_UUID=$(grep UUID -A1 -a $WATCH_APP_PROFILE_PATH | grep -io "[-A-F0-9]\{36\}")
|
||||
cp $WATCH_APP_PROFILE_PATH "$PROFILES_DIR_PATH/$WATCH_APP_UUID.mobileprovision"
|
||||
|
||||
WATCH_APP_EXTENSION_UUID=$(grep UUID -A1 -a $WATCH_APP_EXTENSION_PROFILE_PATH | grep -io "[-A-F0-9]\{36\}")
|
||||
cp $WATCH_APP_EXTENSION_PROFILE_PATH "$PROFILES_DIR_PATH/$WATCH_APP_EXTENSION_UUID.mobileprovision"
|
||||
|
||||
- name: Restore packages
|
||||
run: |
|
||||
dotnet restore
|
||||
dotnet tool restore
|
||||
|
||||
- name: Setup iOS build CAKE (Testing)
|
||||
run: dotnet cake build.cake --target iOS --variant beta
|
||||
|
||||
- name: Bulid WatchApp
|
||||
run: |
|
||||
echo "##### Build WatchApp with Release Configuration"
|
||||
xcodebuild archive -workspace ./src/watchOS/bitwarden/bitwarden.xcodeproj/project.xcworkspace -configuration Release -scheme bitwarden\ WatchKit\ App -archivePath ./src/watchOS/bitwarden
|
||||
|
||||
echo "##### Done"
|
||||
|
||||
- name: Archive Build for App Store
|
||||
shell: pwsh
|
||||
run: |
|
||||
Write-Output "##### Archive for Release ios-arm64"
|
||||
dotnet publish ${{ env.main_app_project_path }} -c Release -f ${{ env.target-net-version }}-ios /p:RuntimeIdentifier=ios-arm64 /p:ArchiveOnBuild=true /p:MtouchUseLlvm=false
|
||||
|
||||
Write-Output "##### Done"
|
||||
|
||||
- name: Archive Build for Mobile Automation
|
||||
shell: pwsh
|
||||
run: |
|
||||
Write-Output "##### Archive Debug for iossimulator-x64"
|
||||
dotnet build ${{ env.main_app_project_path }} -c Debug -f ${{ env.target-net-version }}-ios /p:RuntimeIdentifier=iossimulator-x64 /p:ArchiveOnBuild=true /p:MtouchUseLlvm=false
|
||||
|
||||
Write-Output "##### Done"
|
||||
ls ~/Library/Developer/Xcode/Archives
|
||||
|
||||
- name: Export .ipa for App Store
|
||||
env:
|
||||
EXPORT_OPTIONS_PATH: ./.github/resources/export-options-app-store.plist
|
||||
EXPORT_PATH: ./bitwarden-export
|
||||
run: |
|
||||
ARCHIVE_PATH="$HOME/Library/Developer/Xcode/Archives/*/*.xcarchive"
|
||||
|
||||
xcodebuild -exportArchive -archivePath $ARCHIVE_PATH -exportPath $EXPORT_PATH \
|
||||
-exportOptionsPlist $EXPORT_OPTIONS_PATH
|
||||
|
||||
- name: Export .app for Automation CI
|
||||
env:
|
||||
ARCHIVE_PATH: ./${{ env.main_app_folder_path }}/bin/Debug/${{ env.target-net-version }}-ios/iossimulator-x64
|
||||
EXPORT_PATH: ./bitwarden-export
|
||||
run: |
|
||||
zip -r -q ${{ env._APP_CI_OUTPUT_FILENAME }}.app.zip $ARCHIVE_PATH
|
||||
mv ${{ env._APP_CI_OUTPUT_FILENAME }}.app.zip $EXPORT_PATH
|
||||
|
||||
- name: Show Bitwarden Export
|
||||
shell: bash
|
||||
run: ls -a -R ./bitwarden-export
|
||||
|
||||
- name: Copy all dSYMs files to upload
|
||||
env:
|
||||
EXPORT_PATH: ./bitwarden-export
|
||||
WATCH_ARCHIVE_DSYMS_PATH: ./src/watchOS/bitwarden.xcarchive/dSYMs/
|
||||
WATCH_DSYMS_EXPORT_PATH: ./bitwarden-export/Watch_dSYMs
|
||||
run: |
|
||||
ARCHIVE_DSYMS_PATH="$HOME/Library/Developer/Xcode/Archives/*/*.xcarchive/dSYMs"
|
||||
|
||||
cp -r -v $ARCHIVE_DSYMS_PATH $EXPORT_PATH
|
||||
mkdir $WATCH_DSYMS_EXPORT_PATH
|
||||
cp -r -v $WATCH_ARCHIVE_DSYMS_PATH $WATCH_DSYMS_EXPORT_PATH
|
||||
|
||||
- name: Upload App Store .ipa & dSYMs artifacts
|
||||
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
|
||||
with:
|
||||
name: Bitwarden iOS
|
||||
path: |
|
||||
./bitwarden-export/Bitwarden*.ipa
|
||||
./bitwarden-export/dSYMs/*.*
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload .app file for Automation CI
|
||||
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
|
||||
with:
|
||||
name: ${{ env._APP_CI_OUTPUT_FILENAME }}.app.zip
|
||||
path: ./bitwarden-export/${{ env._APP_CI_OUTPUT_FILENAME }}.app.zip
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Install AppCenter CLI
|
||||
run: npm install -g appcenter-cli
|
||||
|
||||
- name: Upload dSYMs to App Center
|
||||
env:
|
||||
APPCENTER_IOS_TOKEN: ${{ steps.retrieve-secrets.outputs.appcenter-ios-token }}
|
||||
run: appcenter crashes upload-symbols -a bitwarden/bitwarden -s "./bitwarden-export/dSYMs" --token $APPCENTER_IOS_TOKEN
|
||||
|
||||
- name: Upload Watch dSYMs to Firebase Crashlytics
|
||||
run: |
|
||||
echo "##### Uploading Watch dSYMs to Firebase"
|
||||
find "$HOME/Library/Developer/XCode/DerivedData" -name "upload-symbols" -exec chmod +x {} \; -exec {} -gsp "./src/watchOS/bitwarden/GoogleService-Info.plist" -p ios "./bitwarden-export/Watch_dSYMs" \;
|
||||
|
||||
- name: Validate app in App Store
|
||||
env:
|
||||
APPLE_ID_USERNAME: ${{ secrets.APPLE_ID_USERNAME }}
|
||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||
run: |
|
||||
xcrun altool --validate-app --type ios --file "./bitwarden-export/Bitwarden Beta.ipa" \
|
||||
--username "$APPLE_ID_USERNAME" --password "$APPLE_ID_PASSWORD"
|
||||
shell: bash
|
||||
|
||||
- name: Deploy to App Store
|
||||
env:
|
||||
APPLE_ID_USERNAME: ${{ secrets.APPLE_ID_USERNAME }}
|
||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||
run: |
|
||||
xcrun altool --upload-app --type ios --file "./bitwarden-export/Bitwarden Beta.ipa" \
|
||||
--username "$APPLE_ID_USERNAME" --password "$APPLE_ID_PASSWORD"
|
||||
|
||||
check-failures:
|
||||
name: Check for failures
|
||||
if: always()
|
||||
runs-on: ubuntu-22.04
|
||||
needs:
|
||||
- setup
|
||||
- ios
|
||||
steps:
|
||||
- name: Check if any job failed
|
||||
if: |
|
||||
(github.ref == 'refs/heads/main'
|
||||
|| github.ref == 'refs/heads/rc'
|
||||
|| github.ref == 'refs/heads/hotfix-rc')
|
||||
&& contains(needs.*.result, 'failure')
|
||||
run: exit 1
|
||||
|
||||
- name: Login to Azure - CI Subscription
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
if: failure()
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
if: failure()
|
||||
with:
|
||||
keyvault: "bitwarden-ci"
|
||||
secrets: "devops-alerts-slack-webhook-url"
|
||||
|
||||
- name: Notify Slack on failure
|
||||
uses: act10ns/slack@44541246747a30eb3102d87f7a4cc5471b0ffb7d # v2.1.0
|
||||
if: failure()
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ steps.retrieve-secrets.outputs.devops-alerts-slack-webhook-url }}
|
||||
with:
|
||||
status: ${{ job.status }}
|
||||
754
.github/workflows/build.yml
vendored
754
.github/workflows/build.yml
vendored
File diff suppressed because it is too large
Load Diff
52
.github/workflows/cleanup-rc-branch.yml
vendored
Normal file
52
.github/workflows/cleanup-rc-branch.yml
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
name: Cleanup RC Branch
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v**
|
||||
|
||||
jobs:
|
||||
delete-rc:
|
||||
name: Delete RC Branch
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Login to Azure - CI Subscription
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
|
||||
- name: Retrieve bot secrets
|
||||
id: retrieve-bot-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: bitwarden-ci
|
||||
secrets: "github-pat-bitwarden-devops-bot-repo-scope"
|
||||
|
||||
- name: Checkout main
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
ref: main
|
||||
token: ${{ steps.retrieve-bot-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }}
|
||||
|
||||
- name: Check if a RC branch exists
|
||||
id: branch-check
|
||||
run: |
|
||||
hotfix_rc_branch_check=$(git ls-remote --heads origin hotfix-rc | wc -l)
|
||||
rc_branch_check=$(git ls-remote --heads origin rc | wc -l)
|
||||
|
||||
if [[ "${hotfix_rc_branch_check}" -gt 0 ]]; then
|
||||
echo "hotfix-rc branch exists." | tee -a $GITHUB_STEP_SUMMARY
|
||||
echo "name=hotfix-rc" >> $GITHUB_OUTPUT
|
||||
elif [[ "${rc_branch_check}" -gt 0 ]]; then
|
||||
echo "rc branch exists." | tee -a $GITHUB_STEP_SUMMARY
|
||||
echo "name=rc" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Delete RC branch
|
||||
env:
|
||||
BRANCH_NAME: ${{ steps.branch-check.outputs.name }}
|
||||
run: |
|
||||
if ! [[ -z "$BRANCH_NAME" ]]; then
|
||||
git push --quiet origin --delete $BRANCH_NAME
|
||||
echo "Deleted $BRANCH_NAME branch." | tee -a $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
38
.github/workflows/crowdin-pull.yml
vendored
38
.github/workflows/crowdin-pull.yml
vendored
@@ -1,42 +1,48 @@
|
||||
---
|
||||
name: Crowdin Sync
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs: {}
|
||||
schedule:
|
||||
- cron: '0 0 * * 5'
|
||||
|
||||
jobs:
|
||||
crowdin-sync:
|
||||
name: Autosync
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-24.04
|
||||
env:
|
||||
_CROWDIN_PROJECT_ID: "269690"
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
|
||||
|
||||
- name: Login to Azure
|
||||
uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a
|
||||
- name: Generate GH App token
|
||||
uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1
|
||||
id: app-token
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
|
||||
app-id: ${{ secrets.BW_GHAPP_ID }}
|
||||
private-key: ${{ secrets.BW_GHAPP_KEY }}
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
token: ${{ steps.app-token.outputs.token }}
|
||||
|
||||
- name: Login to Azure - CI Subscription
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@c3b3285993151c5af47cefcb3b9134c28ab479af
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: "bitwarden-prod-kv"
|
||||
keyvault: "bitwarden-ci"
|
||||
secrets: "crowdin-api-token, github-gpg-private-key, github-gpg-private-key-passphrase"
|
||||
|
||||
- name: Download translations
|
||||
uses: crowdin/github-action@12143a68c213f3c6d9913c9e5023224f7231face
|
||||
uses: crowdin/github-action@61ac8b980551f674046220c3e104bddae2916ac5 # v2.0.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
|
||||
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
|
||||
with:
|
||||
config: crowdin.yml
|
||||
crowdin_branch_name: master
|
||||
crowdin_branch_name: main
|
||||
upload_sources: false
|
||||
upload_translations: false
|
||||
download_translations: true
|
||||
@@ -48,4 +54,4 @@ jobs:
|
||||
pull_request_title: "Autosync Crowdin Translations"
|
||||
pull_request_body: "Autosync the updated translations"
|
||||
gpg_private_key: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key }}
|
||||
gpg_passphrase: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key-passphrase }}
|
||||
gpg_passphrase: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key-passphrase }}
|
||||
|
||||
5
.github/workflows/enforce-labels.yml
vendored
5
.github/workflows/enforce-labels.yml
vendored
@@ -1,4 +1,3 @@
|
||||
---
|
||||
name: Enforce PR labels
|
||||
|
||||
on:
|
||||
@@ -7,10 +6,10 @@ on:
|
||||
jobs:
|
||||
enforce-label:
|
||||
name: EnforceLabel
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Enforce Label
|
||||
uses: yogevbd/enforce-label-action@8d1e1709b1011e6d90400a0e6cf7c0b77aa5efeb
|
||||
uses: yogevbd/enforce-label-action@a3c219da6b8fa73f6ba62b68ff09c469b3a1c024 # 2.2.2
|
||||
with:
|
||||
BANNED_LABELS: "hold,needs-qa"
|
||||
BANNED_LABELS_DESCRIPTION: "PRs with the hold or needs-qa labels cannot be merged"
|
||||
|
||||
17
.github/workflows/pr-labeler.yml
vendored
Normal file
17
.github/workflows/pr-labeler.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
name: "Pull Request Labeler"
|
||||
|
||||
on:
|
||||
pull_request_target: {}
|
||||
|
||||
jobs:
|
||||
labeler:
|
||||
name: "Pull Request Labeler"
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Label PR
|
||||
uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5.0.0
|
||||
with:
|
||||
sync-labels: true
|
||||
169
.github/workflows/release.yml
vendored
169
.github/workflows/release.yml
vendored
@@ -1,4 +1,3 @@
|
||||
---
|
||||
name: Release
|
||||
run-name: Release ${{ inputs.release_type }}
|
||||
|
||||
@@ -23,12 +22,12 @@ on:
|
||||
jobs:
|
||||
release:
|
||||
name: Create Release
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
branch-name: ${{ steps.branch.outputs.branch-name }}
|
||||
steps:
|
||||
- name: Branch check
|
||||
if: github.event.inputs.release_type != 'Dry Run'
|
||||
if: inputs.release_type != 'Dry Run'
|
||||
run: |
|
||||
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ "$GITHUB_REF" != "refs/heads/hotfix-rc" ]]; then
|
||||
echo "==================================="
|
||||
@@ -38,15 +37,15 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 # v2.4.0
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: Check Release Version
|
||||
id: version
|
||||
uses: bitwarden/gh-actions/release-version-check@8f055ef543c7433c967a1b9b04a0f230923233bb
|
||||
uses: bitwarden/gh-actions/release-version-check@main
|
||||
with:
|
||||
release-type: ${{ github.event.inputs.release_type }}
|
||||
release-type: ${{ inputs.release_type }}
|
||||
project-type: xamarin
|
||||
file: src/Android/Properties/AndroidManifest.xml
|
||||
file: src/App/Platforms/Android/AndroidManifest.xml
|
||||
|
||||
- name: Get branch name
|
||||
id: branch
|
||||
@@ -55,8 +54,8 @@ jobs:
|
||||
echo "branch-name=$BRANCH_NAME" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Create GitHub deployment
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
uses: chrnorm/deployment-action@1b599fe41a0ef1f95191e7f2eec4743f2d7dfc48
|
||||
if: ${{ inputs.release_type != 'Dry Run' }}
|
||||
uses: chrnorm/deployment-action@55729fcebec3d284f60f5bcabbd8376437d696b1 # v2.0.7
|
||||
id: deployment
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
@@ -65,29 +64,35 @@ jobs:
|
||||
description: 'Deployment ${{ steps.version.outputs.version }} from branch ${{ steps.branch.outputs.branch-name }}'
|
||||
task: release
|
||||
|
||||
|
||||
- name: Download all artifacts
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
uses: dawidd6/action-download-artifact@575b1e4167df67acf7e692af784566618b23c71e # v2.17.10
|
||||
if: ${{ inputs.release_type != 'Dry Run' }}
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
with:
|
||||
workflow: build.yml
|
||||
workflow_conclusion: success
|
||||
branch: ${{ steps.branch.outputs.branch-name }}
|
||||
skip_unpack: true
|
||||
|
||||
- name: Dry Run - Download all artifacts
|
||||
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
|
||||
uses: dawidd6/action-download-artifact@575b1e4167df67acf7e692af784566618b23c71e # v2.17.10
|
||||
if: ${{ inputs.release_type == 'Dry Run' }}
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
with:
|
||||
workflow: build.yml
|
||||
workflow_conclusion: success
|
||||
branch: master
|
||||
branch: main
|
||||
skip_unpack: true
|
||||
|
||||
- name: Prep Bitwarden iOS release asset
|
||||
run: zip -r Bitwarden\ iOS.zip Bitwarden\ iOS
|
||||
- name: Unzip release assets
|
||||
run: |
|
||||
unzip bw-android-apk-sha256.txt.zip -d bw-android-apk-sha256.txt
|
||||
unzip bw-fdroid-apk-sha256.txt.zip -d bw-fdroid-apk-sha256.txt
|
||||
unzip com.x8bit.bitwarden-fdroid.apk.zip -d com.x8bit.bitwarden-fdroid.apk
|
||||
unzip com.x8bit.bitwarden.aab.zip -d com.x8bit.bitwarden.aab
|
||||
unzip com.x8bit.bitwarden.apk.zip -d com.x8bit.bitwarden.apk
|
||||
|
||||
- name: Create release
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
uses: ncipollo/release-action@40bb172bd05f266cf9ba4ff965cb61e9ee5f6d01 # v1.9.0
|
||||
if: ${{ inputs.release_type != 'Dry Run' }}
|
||||
uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0
|
||||
with:
|
||||
artifacts: "./com.x8bit.bitwarden.aab/com.x8bit.bitwarden.aab,
|
||||
./com.x8bit.bitwarden.apk/com.x8bit.bitwarden.apk,
|
||||
@@ -103,16 +108,16 @@ jobs:
|
||||
draft: true
|
||||
|
||||
- name: Update deployment status to Success
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' && success() }}
|
||||
uses: chrnorm/deployment-status@07b3930847f65e71c9c6802ff5a402f6dfb46b86
|
||||
if: ${{ inputs.release_type != 'Dry Run' && success() }}
|
||||
uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
state: 'success'
|
||||
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
|
||||
|
||||
- name: Update deployment status to Failure
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' && failure() }}
|
||||
uses: chrnorm/deployment-status@07b3930847f65e71c9c6802ff5a402f6dfb46b86
|
||||
if: ${{ inputs.release_type != 'Dry Run' && failure() }}
|
||||
uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
|
||||
with:
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
state: 'failure'
|
||||
@@ -121,40 +126,36 @@ jobs:
|
||||
|
||||
f-droid:
|
||||
name: F-Droid Release
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
needs: release
|
||||
if: inputs.fdroid_publish
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 # v2.4.0
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: Download F-Droid .apk artifact
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
uses: dawidd6/action-download-artifact@575b1e4167df67acf7e692af784566618b23c71e # v2.17.10
|
||||
if: ${{ inputs.release_type != 'Dry Run' }}
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
with:
|
||||
workflow: build.yml
|
||||
workflow_conclusion: success
|
||||
branch: ${{ needs.release.outputs.branch-name }}
|
||||
name: com.x8bit.bitwarden-fdroid.apk
|
||||
|
||||
- name: Dry Run - Download F-Droid .apk artifact
|
||||
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
|
||||
uses: dawidd6/action-download-artifact@575b1e4167df67acf7e692af784566618b23c71e # v2.17.10
|
||||
if: ${{ inputs.release_type == 'Dry Run' }}
|
||||
uses: bitwarden/gh-actions/download-artifacts@main
|
||||
with:
|
||||
workflow: build.yml
|
||||
workflow_conclusion: success
|
||||
branch: master
|
||||
name: com.x8bit.bitwarden-fdroid.apk
|
||||
branch: main
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561 # v2.5.1
|
||||
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
|
||||
with:
|
||||
node-version: '10.x'
|
||||
node-version: '16.x'
|
||||
|
||||
- name: Set up F-Droid server
|
||||
run: |
|
||||
sudo apt-get -qq update
|
||||
sudo apt-get -qqy install --no-install-recommends fdroidserver wget
|
||||
run: pip install git+https://gitlab.com/fdroid/fdroidserver.git
|
||||
|
||||
- name: Set up Git credentials
|
||||
env:
|
||||
@@ -167,49 +168,85 @@ jobs:
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
node --version
|
||||
npm --version
|
||||
git --version
|
||||
echo "Node Version: $(node --version)"
|
||||
echo "NPM Version: $(npm --version)"
|
||||
echo "Git Version: $(git --version)"
|
||||
echo "F-Droid Server Version: $(fdroid --version)"
|
||||
echo "GitHub ref: $GITHUB_REF"
|
||||
echo "GitHub event: $GITHUB_EVENT"
|
||||
|
||||
- name: Install Node dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Decrypt secrets
|
||||
env:
|
||||
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
|
||||
- name: Login to Azure - CI Subscription
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: "bitwarden-ci"
|
||||
secrets: "github-gpg-private-key,
|
||||
github-gpg-private-key-passphrase,
|
||||
github-pat-bitwarden-devops-bot-mobile-fdroid"
|
||||
|
||||
- name: Import GPG key
|
||||
uses: crazy-max/ghaction-import-gpg@01dd5d3ca463c7f10f7f4f7b4f177225ac661ee4 # v6.1.0
|
||||
with:
|
||||
gpg_private_key: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key }}
|
||||
passphrase: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key-passphrase }}
|
||||
git_user_signingkey: true
|
||||
git_commit_gpgsign: true
|
||||
|
||||
- name: Setup git
|
||||
run: |
|
||||
mkdir -p ~/secrets
|
||||
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
||||
--output ./store/fdroid/keystore.jks ./.github/secrets/store_fdroid-keystore.jks.gpg
|
||||
git config --local user.email "106330231+bitwarden-devops-bot@users.noreply.github.com"
|
||||
git config --local user.name "bitwarden-devops-bot"
|
||||
|
||||
- name: Download secrets
|
||||
env:
|
||||
ACCOUNT_NAME: bitwardenci
|
||||
CONTAINER_NAME: mobile
|
||||
run: |
|
||||
mkdir -p $HOME/secrets
|
||||
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
|
||||
--name store_fdroid-keystore.jks --file ./store/fdroid/keystore.jks --output none
|
||||
|
||||
- name: Compile for F-Droid Store
|
||||
env:
|
||||
FDROID_STORE_KEYSTORE_PASSWORD: ${{ secrets.FDROID_STORE_KEYSTORE_PASSWORD }}
|
||||
run: |
|
||||
cd $GITHUB_WORKSPACE
|
||||
# Create required directories.
|
||||
mkdir dist
|
||||
cp CNAME ./dist
|
||||
cd store
|
||||
chmod 600 fdroid/config.py fdroid/keystore.jks
|
||||
mkdir -p temp/fdroid
|
||||
mkdir -p store/temp/fdroid
|
||||
mkdir -p store/fdroid/repo
|
||||
|
||||
# Configure F-Droid server.
|
||||
cp CNAME dist/
|
||||
chmod 600 store/fdroid/config.yml store/fdroid/keystore.jks
|
||||
TEMP_DIR="$GITHUB_WORKSPACE/store/temp/fdroid"
|
||||
cd fdroid
|
||||
echo "keypass=\"$FDROID_STORE_KEYSTORE_PASSWORD\"" >>config.py
|
||||
echo "keystorepass=\"$FDROID_STORE_KEYSTORE_PASSWORD\"" >>config.py
|
||||
echo "local_copy_dir=\"$TEMP_DIR\"" >>config.py
|
||||
mkdir -p repo
|
||||
mv $GITHUB_WORKSPACE/com.x8bit.bitwarden-fdroid.apk ./repo/
|
||||
echo "keypass: $FDROID_STORE_KEYSTORE_PASSWORD" >> store/fdroid/config.yml
|
||||
echo "keystorepass: $FDROID_STORE_KEYSTORE_PASSWORD" >> store/fdroid/config.yml
|
||||
echo "local_copy_dir: $TEMP_DIR" >> store/fdroid/config.yml
|
||||
mv $GITHUB_WORKSPACE/com.x8bit.bitwarden-fdroid.apk store/fdroid/repo/
|
||||
|
||||
# Run update and deploy.
|
||||
cd store/fdroid
|
||||
fdroid update
|
||||
fdroid server update
|
||||
cd ..
|
||||
rm -rf temp/fdroid/archive
|
||||
mv -v temp/fdroid ../dist
|
||||
cd fdroid
|
||||
cp index.html btn.png qr.png ../../dist/fdroid
|
||||
cd $GITHUB_WORKSPACE
|
||||
fdroid deploy
|
||||
cd ../..
|
||||
|
||||
# Move files for distribution.
|
||||
rm -rf store/temp/fdroid/archive
|
||||
mv -v store/temp/fdroid dist
|
||||
cp store/fdroid/index.html store/fdroid/btn.png store/fdroid/qr.png dist/fdroid
|
||||
|
||||
- name: Deploy to gh-pages
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
run: npm run deploy
|
||||
if: ${{ inputs.release_type != 'Dry Run' }}
|
||||
env:
|
||||
TOKEN: ${{ steps.retrieve-secrets.outputs.github-pat-bitwarden-devops-bot-mobile-fdroid }}
|
||||
run: |
|
||||
git remote set-url origin https://git:${TOKEN}@github.com/${GITHUB_REPOSITORY}.git
|
||||
npm run deploy -- -u "bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>"
|
||||
|
||||
7
.github/workflows/stale-bot.yml
vendored
7
.github/workflows/stale-bot.yml
vendored
@@ -1,4 +1,3 @@
|
||||
---
|
||||
name: 'Close stale issues and PRs'
|
||||
on:
|
||||
workflow_dispatch:
|
||||
@@ -8,10 +7,10 @@ on:
|
||||
jobs:
|
||||
stale:
|
||||
name: 'Check for stale issues and PRs'
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: 'Run stale action'
|
||||
uses: actions/stale@3cc123766321e9f15a6676375c154ccffb12a358 # v5.0.0
|
||||
uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9.0.0
|
||||
with:
|
||||
stale-issue-label: 'needs-reply'
|
||||
stale-pr-label: 'needs-changes'
|
||||
@@ -27,4 +26,4 @@ jobs:
|
||||
|
||||
If you’re still working on this, please respond here after you’ve made the changes we’ve requested and our team will re-open it for further review.
|
||||
|
||||
Please make sure to resolve any conflicts with the master branch before requesting another review.
|
||||
Please make sure to resolve any conflicts with the main branch before requesting another review.
|
||||
|
||||
55
.github/workflows/version-auto-bump.yml
vendored
55
.github/workflows/version-auto-bump.yml
vendored
@@ -1,5 +1,4 @@
|
||||
---
|
||||
name: Version Auto Bump
|
||||
name: Auto Bump Mobile Version
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -7,39 +6,25 @@ on:
|
||||
- v**
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
name: "Setup"
|
||||
bump-version:
|
||||
name: Bump Mobile Version
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
version_number: ${{ steps.version.outputs.new-version }}
|
||||
steps:
|
||||
- name: Checkout Branch
|
||||
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
|
||||
|
||||
- name: Calculate bumped version
|
||||
id: version
|
||||
env:
|
||||
RELEASE_TAG: ${{ github.ref }}
|
||||
run: |
|
||||
CURR_MAJOR=$(echo $RELEASE_TAG | sed -r 's/refs\/tags\/v([0-9]{4}\.[0-9]{1,2})\.([0-9]{1,2})/\1/')
|
||||
CURR_PATCH=$(echo $RELEASE_TAG | sed -r 's/refs\/tags\/v([0-9]{4}\.[0-9]{1,2})\.([0-9]{1,2})/\2/')
|
||||
echo "Current Major: $CURR_MAJOR"
|
||||
echo "Current Patch: $CURR_PATCH"
|
||||
|
||||
NEW_PATCH=$((CURR_PATCH+1))
|
||||
NEW_VER=$CURR_MAJOR.$NEW_PATCH
|
||||
echo "New Version: $NEW_VER"
|
||||
echo "new-version=$NEW_VER" >> $GITHUB_OUTPUT
|
||||
|
||||
trigger_version_bump:
|
||||
name: "Version bump"
|
||||
runs-on: ubuntu-22.04
|
||||
needs:
|
||||
- setup
|
||||
steps:
|
||||
- name: Bump version to ${{ needs.setup.outputs.version_number }}
|
||||
uses: ./.github/workflows/version-bump.yml
|
||||
secrets:
|
||||
AZURE_PROD_KV_CREDENTIALS: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
|
||||
- name: Login to Azure - CI Subscription
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
with:
|
||||
version_number: ${{ needs.setup.outputs.version_number }}
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
|
||||
- name: Retrieve bot secrets
|
||||
id: retrieve-bot-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: bitwarden-ci
|
||||
secrets: "github-pat-bitwarden-devops-bot-repo-scope"
|
||||
|
||||
- name: Trigger Version Bump workflow
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.retrieve-bot-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }}
|
||||
run: |
|
||||
echo '{"cut_rc_branch": "false"}' | \
|
||||
gh workflow run version-bump.yml --json --repo bitwarden/mobile
|
||||
|
||||
322
.github/workflows/version-bump.yml
vendored
322
.github/workflows/version-bump.yml
vendored
@@ -1,86 +1,214 @@
|
||||
---
|
||||
name: Version Bump
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version_number:
|
||||
description: "New Version"
|
||||
required: true
|
||||
workflow_call:
|
||||
inputs:
|
||||
version_number:
|
||||
required: true
|
||||
secrets:
|
||||
AZURE_PROD_KV_CREDENTIALS:
|
||||
required: true
|
||||
version_number_override:
|
||||
description: "New version override (leave blank for automatic calculation, example: '2024.1.0')"
|
||||
required: false
|
||||
type: string
|
||||
cut_rc_branch:
|
||||
description: "Cut RC branch?"
|
||||
default: true
|
||||
type: boolean
|
||||
enable_slack_notification:
|
||||
description: "Enable Slack notifications for upcoming release?"
|
||||
default: false
|
||||
type: boolean
|
||||
|
||||
jobs:
|
||||
bump_version:
|
||||
name: "Create version_bump_${{ github.event.inputs.version_number }} branch"
|
||||
runs-on: ubuntu-20.04
|
||||
name: Bump Version
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
version: ${{ steps.set-final-version-output.outputs.version }}
|
||||
steps:
|
||||
- name: Checkout Branch
|
||||
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
|
||||
|
||||
- name: Login to Azure - Prod Subscription
|
||||
uses: Azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf
|
||||
- name: Validate version input
|
||||
if: ${{ inputs.version_number_override != '' }}
|
||||
uses: bitwarden/gh-actions/version-check@main
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
|
||||
version: ${{ inputs.version_number_override }}
|
||||
|
||||
- name: Slack Notification Check
|
||||
run: |
|
||||
if [[ "${{ inputs.enable_slack_notification }}" == true ]]; then
|
||||
echo "Slack notifications enabled."
|
||||
else
|
||||
echo "Slack notifications disabled."
|
||||
fi
|
||||
|
||||
- name: Checkout Branch
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
ref: main
|
||||
|
||||
- name: Check if RC branch exists
|
||||
if: ${{ inputs.cut_rc_branch == true }}
|
||||
run: |
|
||||
remote_rc_branch_check=$(git ls-remote --heads origin rc | wc -l)
|
||||
if [[ "${remote_rc_branch_check}" -gt 0 ]]; then
|
||||
echo "Remote RC branch exists."
|
||||
echo "Please delete current RC branch before running again."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Login to Azure - CI Subscription
|
||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@c3b3285993151c5af47cefcb3b9134c28ab479af
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: "bitwarden-prod-kv"
|
||||
secrets: "github-gpg-private-key, github-gpg-private-key-passphrase"
|
||||
keyvault: "bitwarden-ci"
|
||||
secrets: "github-gpg-private-key,
|
||||
github-gpg-private-key-passphrase,
|
||||
github-pat-bitwarden-devops-bot-repo-scope"
|
||||
|
||||
- name: Import GPG key
|
||||
uses: crazy-max/ghaction-import-gpg@c8bb57c57e8df1be8c73ff3d59deab1dbc00e0d1
|
||||
uses: crazy-max/ghaction-import-gpg@01dd5d3ca463c7f10f7f4f7b4f177225ac661ee4 # v6.1.0
|
||||
with:
|
||||
gpg_private_key: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key }}
|
||||
passphrase: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key-passphrase }}
|
||||
git_user_signingkey: true
|
||||
git_commit_gpgsign: true
|
||||
|
||||
- name: Create Version Branch
|
||||
run: git switch -c version_bump_${{ github.event.inputs.version_number }}
|
||||
|
||||
- name: Bump Version - Android XML
|
||||
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
|
||||
with:
|
||||
version: ${{ github.event.inputs.version_number }}
|
||||
file_path: "./src/Android/Properties/AndroidManifest.xml"
|
||||
|
||||
- name: Bump Version - iOS.Autofill
|
||||
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
|
||||
with:
|
||||
version: ${{ github.event.inputs.version_number }}
|
||||
file_path: "./src/iOS.Autofill/Info.plist"
|
||||
|
||||
- name: Bump Version - iOS.Extension
|
||||
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
|
||||
with:
|
||||
version: ${{ github.event.inputs.version_number }}
|
||||
file_path: "./src/iOS.Extension/Info.plist"
|
||||
|
||||
- name: Bump Version - iOS.ShareExtension
|
||||
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
|
||||
with:
|
||||
version: ${{ github.event.inputs.version_number }}
|
||||
file_path: "./src/iOS.ShareExtension/Info.plist"
|
||||
|
||||
- name: Bump Version - iOS
|
||||
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
|
||||
with:
|
||||
version: ${{ github.event.inputs.version_number }}
|
||||
file_path: "./src/iOS/Info.plist"
|
||||
|
||||
- name: Setup git
|
||||
run: |
|
||||
git config --local user.email "106330231+bitwarden-devops-bot@users.noreply.github.com"
|
||||
git config --local user.name "bitwarden-devops-bot"
|
||||
|
||||
- name: Create Version Branch
|
||||
id: create-branch
|
||||
run: |
|
||||
NAME=version_bump_${{ github.ref_name }}_$(date +"%Y-%m-%d")
|
||||
git switch -c $NAME
|
||||
echo "name=$NAME" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Install xmllint
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libxml2-utils
|
||||
|
||||
- name: Get current version
|
||||
id: current-version
|
||||
run: |
|
||||
CURRENT_VERSION=$(xmllint --xpath '
|
||||
string(/manifest/@*[local-name()="versionName"
|
||||
and namespace-uri()="http://schemas.android.com/apk/res/android"])
|
||||
' src/App/Platforms/Android/AndroidManifest.xml)
|
||||
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Verify input version
|
||||
if: ${{ inputs.version_number_override != '' }}
|
||||
env:
|
||||
CURRENT_VERSION: ${{ steps.current-version.outputs.version }}
|
||||
NEW_VERSION: ${{ inputs.version_number_override }}
|
||||
run: |
|
||||
# Error if version has not changed.
|
||||
if [[ "$NEW_VERSION" == "$CURRENT_VERSION" ]]; then
|
||||
echo "Version has not changed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if version is newer.
|
||||
printf '%s\n' "${CURRENT_VERSION}" "${NEW_VERSION}" | sort -C -V
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Version check successful."
|
||||
else
|
||||
echo "Version check failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Calculate next release version
|
||||
if: ${{ inputs.version_number_override == '' }}
|
||||
id: calculate-next-version
|
||||
uses: bitwarden/gh-actions/version-next@main
|
||||
with:
|
||||
version: ${{ steps.current-version.outputs.version }}
|
||||
|
||||
- name: Bump Version - Android XML - Version Override
|
||||
if: ${{ inputs.version_number_override != '' }}
|
||||
id: bump-version-override
|
||||
uses: bitwarden/gh-actions/version-bump@main
|
||||
with:
|
||||
file_path: "src/App/Platforms/Android/AndroidManifest.xml"
|
||||
version: ${{ inputs.version_number_override }}
|
||||
|
||||
- name: Bump Version - Android XML - Automatic Calculation
|
||||
if: ${{ inputs.version_number_override == '' }}
|
||||
id: bump-version-automatic
|
||||
uses: bitwarden/gh-actions/version-bump@main
|
||||
with:
|
||||
file_path: "src/App/Platforms/Android/AndroidManifest.xml"
|
||||
version: ${{ steps.calculate-next-version.outputs.version }}
|
||||
|
||||
- name: Bump Version - iOS.Autofill - Version Override
|
||||
if: ${{ inputs.version_number_override != '' }}
|
||||
uses: bitwarden/gh-actions/version-bump@main
|
||||
with:
|
||||
file_path: "src/iOS.Autofill/Info.plist"
|
||||
version: ${{ inputs.version_number_override }}
|
||||
|
||||
- name: Bump Version - iOS.Autofill - Automatic Calculation
|
||||
if: ${{ inputs.version_number_override == '' }}
|
||||
uses: bitwarden/gh-actions/version-bump@main
|
||||
with:
|
||||
file_path: "src/iOS.Autofill/Info.plist"
|
||||
version: ${{ steps.calculate-next-version.outputs.version }}
|
||||
|
||||
- name: Bump Version - iOS.Extension - Version Override
|
||||
if: ${{ inputs.version_number_override != '' }}
|
||||
uses: bitwarden/gh-actions/version-bump@main
|
||||
with:
|
||||
file_path: "src/iOS.Extension/Info.plist"
|
||||
version: ${{ inputs.version_number_override }}
|
||||
|
||||
- name: Bump Version - iOS.Extension - Automatic Calculation
|
||||
if: ${{ inputs.version_number_override == '' }}
|
||||
uses: bitwarden/gh-actions/version-bump@main
|
||||
with:
|
||||
file_path: "src/iOS.Extension/Info.plist"
|
||||
version: ${{ steps.calculate-next-version.outputs.version }}
|
||||
|
||||
- name: Bump Version - iOS.ShareExtension - Version Override
|
||||
if: ${{ inputs.version_number_override != '' }}
|
||||
uses: bitwarden/gh-actions/version-bump@main
|
||||
with:
|
||||
file_path: "src/iOS.ShareExtension/Info.plist"
|
||||
version: ${{ inputs.version_number_override }}
|
||||
|
||||
- name: Bump Version - iOS.ShareExtension - Automatic Calculation
|
||||
if: ${{ inputs.version_number_override == '' }}
|
||||
uses: bitwarden/gh-actions/version-bump@main
|
||||
with:
|
||||
file_path: "src/iOS.ShareExtension/Info.plist"
|
||||
version: ${{ steps.calculate-next-version.outputs.version }}
|
||||
|
||||
- name: Bump Version - iOS - Version Override
|
||||
if: ${{ inputs.version_number_override != '' }}
|
||||
uses: bitwarden/gh-actions/version-bump@main
|
||||
with:
|
||||
file_path: "src/App/Platforms/iOS/Info.plist"
|
||||
version: ${{ inputs.version_number_override }}
|
||||
|
||||
- name: Bump Version - iOS - Automatic Calculation
|
||||
if: ${{ inputs.version_number_override == '' }}
|
||||
uses: bitwarden/gh-actions/version-bump@main
|
||||
with:
|
||||
file_path: "src/App/Platforms/iOS/Info.plist"
|
||||
version: ${{ steps.calculate-next-version.outputs.version }}
|
||||
|
||||
- name: Set Job output
|
||||
id: set-final-version-output
|
||||
run: |
|
||||
if [[ "${{ steps.bump-version-override.outcome }}" == "success" ]]; then
|
||||
echo "version=${{ inputs.version_number_override }}" >> $GITHUB_OUTPUT
|
||||
elif [[ "${{ steps.bump-version-automatic.outcome }}" == "success" ]]; then
|
||||
echo "version=${{ steps.calculate-next-version.outputs.version }}" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Check if version changed
|
||||
id: version-changed
|
||||
run: |
|
||||
@@ -93,22 +221,24 @@ jobs:
|
||||
|
||||
- name: Commit files
|
||||
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
|
||||
run: git commit -m "Bumped version to ${{ github.event.inputs.version_number }}" -a
|
||||
run: git commit -m "Bumped version to ${{ steps.set-final-version-output.outputs.version }}" -a
|
||||
|
||||
- name: Push changes
|
||||
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
|
||||
run: git push -u origin version_bump_${{ github.event.inputs.version_number }}
|
||||
env:
|
||||
PR_BRANCH: ${{ steps.create-branch.outputs.name }}
|
||||
run: git push -u origin $PR_BRANCH
|
||||
|
||||
- name: Create Version PR
|
||||
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
|
||||
id: create-pr
|
||||
env:
|
||||
PR_BRANCH: "version_bump_${{ github.event.inputs.version_number }}"
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
BASE_BRANCH: master
|
||||
TITLE: "Bump version to ${{ github.event.inputs.version_number }}"
|
||||
GH_TOKEN: ${{ steps.retrieve-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }}
|
||||
PR_BRANCH: ${{ steps.create-branch.outputs.name }}
|
||||
TITLE: "Bump version to ${{ steps.set-final-version-output.outputs.version }}"
|
||||
run: |
|
||||
gh pr create --title "$TITLE" \
|
||||
--base "$BASE" \
|
||||
PR_URL=$(gh pr create --title "$TITLE" \
|
||||
--base "main" \
|
||||
--head "$PR_BRANCH" \
|
||||
--label "version update" \
|
||||
--label "automated pr" \
|
||||
@@ -121,4 +251,66 @@ jobs:
|
||||
- [X] Other
|
||||
|
||||
## Objective
|
||||
Automated version bump to ${{ github.event.inputs.version_number }}"
|
||||
Automated version bump to ${{ steps.set-final-version-output.outputs.version }}")
|
||||
echo "pr_number=${PR_URL##*/}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Approve PR
|
||||
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PR_NUMBER: ${{ steps.create-pr.outputs.pr_number }}
|
||||
run: gh pr review $PR_NUMBER --approve
|
||||
|
||||
- name: Merge PR
|
||||
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.retrieve-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }}
|
||||
PR_NUMBER: ${{ steps.create-pr.outputs.pr_number }}
|
||||
run: gh pr merge $PR_NUMBER --squash --auto --delete-branch
|
||||
|
||||
- name: Report upcoming release version to Slack
|
||||
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' && inputs.enable_slack_notification == true }}
|
||||
uses: bitwarden/gh-actions/report-upcoming-release-version@main
|
||||
with:
|
||||
version: ${{ steps.set-final-version-output.outputs.version }}
|
||||
project: ${{ github.repository }}
|
||||
AZURE_KV_CI_SERVICE_PRINCIPAL: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||
|
||||
cut_rc:
|
||||
name: Cut RC branch
|
||||
if: ${{ inputs.cut_rc_branch == true }}
|
||||
needs: bump_version
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout Branch
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
ref: main
|
||||
|
||||
- name: Install xmllint
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libxml2-utils
|
||||
|
||||
- name: Verify version has been updated
|
||||
env:
|
||||
NEW_VERSION: ${{ needs.bump_version.outputs.version }}
|
||||
run: |
|
||||
# Wait for version to change.
|
||||
while : ; do
|
||||
echo "Waiting for version to be updated..."
|
||||
git pull --force
|
||||
CURRENT_VERSION=$(xmllint --xpath '
|
||||
string(/manifest/@*[local-name()="versionName"
|
||||
and namespace-uri()="http://schemas.android.com/apk/res/android"])
|
||||
' src/App/Platforms/Android/AndroidManifest.xml)
|
||||
|
||||
# If the versions don't match we continue the loop, otherwise we break out of the loop.
|
||||
[[ "$NEW_VERSION" != "$CURRENT_VERSION" ]] || break
|
||||
sleep 10
|
||||
done
|
||||
|
||||
- name: Cut RC branch
|
||||
run: |
|
||||
git switch --quiet --create rc
|
||||
git push --quiet --set-upstream origin rc
|
||||
|
||||
11
.github/workflows/workflow-linter.yml
vendored
11
.github/workflows/workflow-linter.yml
vendored
@@ -1,11 +0,0 @@
|
||||
---
|
||||
name: Workflow Linter
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- .github/workflows/**
|
||||
|
||||
jobs:
|
||||
call-workflow:
|
||||
uses: bitwarden/gh-actions/.github/workflows/workflow-linter.yml@master
|
||||
18
.gitignore
vendored
18
.gitignore
vendored
@@ -31,6 +31,7 @@ Components/
|
||||
x64/
|
||||
x86/
|
||||
!src/lib/x86/
|
||||
!src/App/Platforms/Android/lib/x86/
|
||||
build/
|
||||
bld/
|
||||
[Bb]in/
|
||||
@@ -147,6 +148,7 @@ publish/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
!**/Xamarin.AndroidX.Credentials.1.0.0.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
@@ -294,17 +296,11 @@ iOSInjectionProject/
|
||||
timeline.xctimeline
|
||||
playground.xcworkspace
|
||||
|
||||
# Swift Package Manager
|
||||
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
|
||||
# Packages/
|
||||
# Package.pins
|
||||
# Package.resolved
|
||||
# *.xcodeproj
|
||||
# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
|
||||
# hence it is not needed unless you have added a package configuration file to your project
|
||||
# .swiftpm
|
||||
|
||||
.build/
|
||||
# xcode / swift package manager - used by the MessagePack lib
|
||||
/.build
|
||||
/Packages
|
||||
/*.xcodeproj
|
||||
.swiftpm
|
||||
|
||||
# CocoaPods
|
||||
# We recommend against adding the Pods directory to your .gitignore. However
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +0,0 @@
|
||||
[submodule "lib/MessagePack"]
|
||||
path = lib/MessagePack
|
||||
url = https://github.com/bitwarden/MessagePack.git
|
||||
15
Directory.Build.props
Normal file
15
Directory.Build.props
Normal file
@@ -0,0 +1,15 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<MauiVersion>8.0.7</MauiVersion>
|
||||
<ReleaseCodesignProvision>Automatic:AppStore</ReleaseCodesignProvision>
|
||||
<ReleaseCodesignKey>iPhone Distribution</ReleaseCodesignKey>
|
||||
<IncludeBitwardeniOSExtensions>True</IncludeBitwardeniOSExtensions>
|
||||
<IncludeBitwardenWatchOSApp>False</IncludeBitwardenWatchOSApp>
|
||||
<Argon2IdLoadMtouchExtraArgs>-gcc_flags "-L$(ProjectDir)../../lib/ios -largon2 -force_load $(ProjectDir)../../lib/ios/libargon2.a"</Argon2IdLoadMtouchExtraArgs>
|
||||
<!-- Uncomment this when Unit Testing-->
|
||||
<!-- <CustomConstants>UT</CustomConstants> -->
|
||||
|
||||
<!-- Uncomment this when building FDROID-->
|
||||
<!-- <CustomConstants>FDROID</CustomConstants> -->
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
14
README.md
14
README.md
@@ -1,18 +1,22 @@
|
||||
[](https://github.com/bitwarden/mobile/actions/workflows/build.yml?query=branch:master)
|
||||
[](https://github.com/bitwarden/mobile/actions/workflows/build.yml?query=branch:main)
|
||||
[](https://crowdin.com/project/bitwarden-mobile)
|
||||
[](https://gitter.im/bitwarden/Lobby)
|
||||
|
||||
# Bitwarden Mobile Application
|
||||
|
||||
<a href="https://play.google.com/store/apps/details?id=com.x8bit.bitwarden" target="_blank"><img alt="Get it on Google Play" src="https://imgur.com/YQzmZi9.png" width="153" height="46"></a> <a href="https://mobileapp.bitwarden.com/fdroid/" target="_blank"><img alt="Get it on Google Play" src="https://i.imgur.com/HDicnzz.png" width="154" height="46"></a> <a href="https://itunes.apple.com/us/app/bitwarden-free-password-manager/id1137397744?mt=8" target="_blank"><img src="https://imgur.com/GdGqPMY.png" width="135" height="40"></a>
|
||||
> [!TIP]
|
||||
> Looking for the new native apps? Head on over to [bitwarden/android](https://github.com/bitwarden/android) and [bitwarden/ios](https://github.com/bitwarden/ios)
|
||||
|
||||
The Bitwarden mobile application is written in C# with Xamarin Android, Xamarin iOS, and Xamarin Forms.
|
||||
|
||||
<a href="https://play.google.com/store/apps/details?id=com.x8bit.bitwarden" target="_blank"><img alt="Get it on Google Play" src="https://imgur.com/YQzmZi9.png" width="153" height="46"></a> <a href="https://mobileapp.bitwarden.com/fdroid/" target="_blank"><img alt="Get it on F-Droid" src="https://i.imgur.com/HDicnzz.png" width="154" height="46"></a> <a href="https://itunes.apple.com/us/app/bitwarden-free-password-manager/id1137397744?mt=8" target="_blank"><img src="https://imgur.com/GdGqPMY.png" width="135" height="40"></a>
|
||||
|
||||
The Bitwarden mobile application is written in C# using .NET MAUI.
|
||||
|
||||
<img src="https://raw.githubusercontent.com/bitwarden/brand/master/screenshots/mobile-android-myvault.png" alt="" width="325" height="650" /> <img src="https://raw.githubusercontent.com/bitwarden/brand/master/screenshots/mobile-ios-myvault.png" alt="" width="300" height="650" />
|
||||
|
||||
# Build/Run
|
||||
|
||||
Please refer to the [Mobile section](https://contributing.bitwarden.com/getting-started/clients/mobile/) of the [Contributing Documentation](https://contributing.bitwarden.com/) for build instructions, recommended tooling, code style tips, and lots of other great information to get you started.
|
||||
Please refer to the [Mobile section](https://contributing.bitwarden.com/getting-started/mobile/) of the [Contributing Documentation](https://contributing.bitwarden.com/) for build instructions, recommended tooling, code style tips, and lots of other great information to get you started.
|
||||
|
||||
# We're Hiring!
|
||||
|
||||
@@ -20,6 +24,6 @@ Interested in contributing in a big way? Consider joining our team! We're hiring
|
||||
|
||||
# Contribute
|
||||
|
||||
Code contributions are welcome! Please commit any pull requests against the `master` branch. Learn more about how to contribute by reading the [Contributing Guidelines](https://contributing.bitwarden.com/contributing/). Check out the [Contributing Documentation](https://contributing.bitwarden.com/) for how to get started with your first contribution.
|
||||
Code contributions are welcome! Please commit any pull requests against the `main` branch. Learn more about how to contribute by reading the [Contributing Guidelines](https://contributing.bitwarden.com/contributing/). Check out the [Contributing Documentation](https://contributing.bitwarden.com/) for how to get started with your first contribution.
|
||||
|
||||
Security audits and feedback are welcome. Please open an issue or email us privately if the report is sensitive in nature. You can read our security policy in the [`SECURITY.md`](SECURITY.md) file.
|
||||
|
||||
@@ -1,471 +1,233 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29009.5
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.8.34112.27
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Android", "src\Android\Android.csproj", "{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "App", "src\App\App.csproj", "{971FDF07-E288-4239-B47A-E9E7E912193B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "App", "src\App\App.csproj", "{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core", "src\Core\Core.csproj", "{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Core", "src\Core\Core.csproj", "{4B8A8C41-9820-4341-974C-41E65B7F4366}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Playground", "test\Playground\Playground.csproj", "{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D10CA4A9-F866-40E1-B658-F69051236C71}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{8904C536-C67D-420F-9971-51B26574C3AA}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "store", "store", "{92470CBD-9047-4C3C-8EA3-D972D6622D84}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "google", "google", "{2E399654-26A2-46F6-B9CA-1B496A3F370A}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{76690DFB-B7F4-4781-83E4-113FDC450AFE}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.editorconfig = .editorconfig
|
||||
.gitignore = .gitignore
|
||||
.github\workflows\build.yml = .github\workflows\build.yml
|
||||
CONTRIBUTING.md = CONTRIBUTING.md
|
||||
crowdin.yml = crowdin.yml
|
||||
README.md = README.md
|
||||
SECURITY.md = SECURITY.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Publisher", "store\google\Publisher\Publisher.csproj", "{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Core", "src\iOS.Core\iOS.Core.csproj", "{E71F3053-056C-4381-9638-048ED73BDFF6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS", "src\iOS\iOS.csproj", "{599E0201-420A-4C3E-A7BA-5349F72E0B15}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "iOS.Core", "src\iOS.Core\iOS.Core.csproj", "{E71F3053-056C-4381-9638-048ED73BDFF6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Extension", "src\iOS.Extension\iOS.Extension.csproj", "{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "test\Common\Common.csproj", "{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core.Test", "test\Core.Test\Core.Test.csproj", "{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.ShareExtension", "src\iOS.ShareExtension\iOS.ShareExtension.csproj", "{F8C3F648-EA5A-4719-8005-85D1690B1655}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Autofill", "src\iOS.Autofill\iOS.Autofill.csproj", "{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Autofill", "src\iOS.Autofill\iOS.Autofill.csproj", "{83449CC4-1F76-4CFE-92B1-D2E13A62506F}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{BB702EBD-3B79-4ECA-A2A6-1237B07F0AF0}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{B972BBFA-917F-4A10-B07E-B89CFEC6BBDC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core.Test", "test\Core.Test\Core.Test.csproj", "{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "test\Common\Common.csproj", "{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
|
||||
Ad-Hoc|iPhone = Ad-Hoc|iPhone
|
||||
Ad-Hoc|iPhoneSimulator = Ad-Hoc|iPhoneSimulator
|
||||
AppStore|Any CPU = AppStore|Any CPU
|
||||
AppStore|iPhone = AppStore|iPhone
|
||||
AppStore|iPhoneSimulator = AppStore|iPhoneSimulator
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|iPhone = Debug|iPhone
|
||||
Debug|iPhoneSimulator = Debug|iPhoneSimulator
|
||||
FDroid|Any CPU = FDroid|Any CPU
|
||||
FDroid|iPhone = FDroid|iPhone
|
||||
FDroid|iPhoneSimulator = FDroid|iPhoneSimulator
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|iPhone = Release|iPhone
|
||||
Debug|iPhoneSimulator = Debug|iPhoneSimulator
|
||||
Release|iPhoneSimulator = Release|iPhoneSimulator
|
||||
Debug|iPhone = Debug|iPhone
|
||||
Release|iPhone = Release|iPhone
|
||||
AppStore|iPhoneSimulator = AppStore|iPhoneSimulator
|
||||
AppStore|iPhone = AppStore|iPhone
|
||||
Ad-Hoc|iPhoneSimulator = Ad-Hoc|iPhoneSimulator
|
||||
Ad-Hoc|iPhone = Ad-Hoc|iPhone
|
||||
FDroid|Any CPU = FDroid|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|iPhone.Deploy.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|Any CPU.Build.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|iPhone.Deploy.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|iPhoneSimulator.Deploy.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|iPhone.Deploy.0 = Debug|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|Any CPU.Deploy.0 = FDroid|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|iPhone.Build.0 = FDroid|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|iPhone.Deploy.0 = FDroid|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|iPhoneSimulator.Build.0 = FDroid|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|iPhoneSimulator.Deploy.0 = FDroid|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|iPhone.Deploy.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhone.Deploy.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|Any CPU.Build.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhone.Deploy.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhoneSimulator.Deploy.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|iPhone.Deploy.0 = Debug|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.FDroid|iPhone.Build.0 = FDroid|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.FDroid|iPhoneSimulator.Build.0 = FDroid|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|iPhone.Deploy.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|Any CPU.Build.0 = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.FDroid|iPhone.Build.0 = FDroid|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.FDroid|iPhoneSimulator.Build.0 = FDroid|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.FDroid|iPhone.Build.0 = FDroid|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.FDroid|iPhoneSimulator.Build.0 = FDroid|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.AppStore|Any CPU.Build.0 = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.AppStore|iPhone.Build.0 = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.FDroid|iPhone.Build.0 = FDroid|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.FDroid|iPhoneSimulator.Build.0 = FDroid|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|Any CPU.Build.0 = Ad-Hoc|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|Any CPU.ActiveCfg = AppStore|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|Any CPU.Build.0 = AppStore|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhone.Build.0 = AppStore|iPhone
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.FDroid|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B}.FDroid|Any CPU.Build.0 = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.FDroid|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.FDroid|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhone.ActiveCfg = Debug|iPhone
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhone.Build.0 = Debug|iPhone
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|iPhone.Build.0 = FDroid|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|iPhoneSimulator.Build.0 = FDroid|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.AppStore|iPhone.Build.0 = AppStore|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|Any CPU.ActiveCfg = Debug|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|iPhone.ActiveCfg = Debug|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|iPhone.Build.0 = Debug|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|iPhone.Deploy.0 = Debug|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.FDroid|Any CPU.ActiveCfg = FDroid|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.FDroid|iPhone.ActiveCfg = FDroid|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.FDroid|iPhone.Build.0 = FDroid|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|iPhoneSimulator
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.FDroid|iPhoneSimulator.Build.0 = FDroid|iPhoneSimulator
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Release|Any CPU.ActiveCfg = Release|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Release|iPhone.ActiveCfg = Release|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Release|iPhone.Build.0 = Release|iPhone
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|Any CPU.Build.0 = Ad-Hoc|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|Any CPU.Build.0 = AppStore|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhone.Build.0 = AppStore|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|Any CPU.ActiveCfg = Debug|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhone.ActiveCfg = Debug|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhone.Build.0 = Debug|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhone.Deploy.0 = Debug|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|Any CPU.ActiveCfg = Release|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|Any CPU.Build.0 = Release|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|iPhone.ActiveCfg = Release|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|iPhone.Build.0 = Release|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|Any CPU.ActiveCfg = Release|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhone.ActiveCfg = Release|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhone.Build.0 = Release|iPhone
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|Any CPU.Build.0 = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|Any CPU.Build.0 = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|iPhone.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|iPhone.Build.0 = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|Any CPU.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|Any CPU.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|iPhone.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|iPhone.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|Any CPU.ActiveCfg = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|Any CPU.Build.0 = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhone.ActiveCfg = Release|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhone.Build.0 = Release|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|Any CPU.ActiveCfg = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|Any CPU.Build.0 = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhone.ActiveCfg = Release|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhone.Build.0 = Release|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhone.ActiveCfg = Debug|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhone.Build.0 = Debug|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|Any CPU.ActiveCfg = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|Any CPU.Build.0 = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|iPhone.ActiveCfg = Release|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|iPhone.Build.0 = Release|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|Any CPU.ActiveCfg = Release|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|Any CPU.Build.0 = Release|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhone.ActiveCfg = Release|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhone.Build.0 = Release|iPhone
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|Any CPU.Build.0 = Ad-Hoc|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|Any CPU.Build.0 = AppStore|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|iPhone.Build.0 = AppStore|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|Any CPU.ActiveCfg = Debug|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|iPhone.ActiveCfg = Debug|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|iPhone.Build.0 = Debug|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|iPhone.Deploy.0 = Debug|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|Any CPU.ActiveCfg = Release|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|Any CPU.Build.0 = Release|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|iPhone.ActiveCfg = Release|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|iPhone.Build.0 = Release|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|Any CPU.ActiveCfg = Release|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhone.ActiveCfg = Release|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhone.Build.0 = Release|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|Any CPU.Build.0 = Debug|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|Any CPU.Build.0 = Debug|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.FDroid|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F}.FDroid|Any CPU.Build.0 = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.FDroid|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6}.FDroid|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.FDroid|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44}.FDroid|Any CPU.Build.0 = Debug|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F} = {D10CA4A9-F866-40E1-B658-F69051236C71}
|
||||
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C} = {D10CA4A9-F866-40E1-B658-F69051236C71}
|
||||
{4B8A8C41-9820-4341-974C-41E65B7F4366} = {D10CA4A9-F866-40E1-B658-F69051236C71}
|
||||
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3} = {8904C536-C67D-420F-9971-51B26574C3AA}
|
||||
{2E399654-26A2-46F6-B9CA-1B496A3F370A} = {92470CBD-9047-4C3C-8EA3-D972D6622D84}
|
||||
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D} = {2E399654-26A2-46F6-B9CA-1B496A3F370A}
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6} = {D10CA4A9-F866-40E1-B658-F69051236C71}
|
||||
{599E0201-420A-4C3E-A7BA-5349F72E0B15} = {D10CA4A9-F866-40E1-B658-F69051236C71}
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545} = {D10CA4A9-F866-40E1-B658-F69051236C71}
|
||||
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39} = {8904C536-C67D-420F-9971-51B26574C3AA}
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0} = {8904C536-C67D-420F-9971-51B26574C3AA}
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655} = {D10CA4A9-F866-40E1-B658-F69051236C71}
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A} = {D10CA4A9-F866-40E1-B658-F69051236C71}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {7D436EA3-8B7E-45D2-8D14-0730BD2E0410}
|
||||
SolutionGuid = {3B3A9B6C-D325-4BB3-97D3-8070630C5D3B}
|
||||
EndGlobalSection
|
||||
GlobalSection(MonoDevelopProperties) = preSolution
|
||||
Policies = $0
|
||||
$0.DotNetNamingPolicy = $1
|
||||
$1.DirectoryNamespaceAssociation = PrefixedHierarchical
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{971FDF07-E288-4239-B47A-E9E7E912193B} = {B972BBFA-917F-4A10-B07E-B89CFEC6BBDC}
|
||||
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C} = {B972BBFA-917F-4A10-B07E-B89CFEC6BBDC}
|
||||
{83449CC4-1F76-4CFE-92B1-D2E13A62506F} = {B972BBFA-917F-4A10-B07E-B89CFEC6BBDC}
|
||||
{E71F3053-056C-4381-9638-048ED73BDFF6} = {B972BBFA-917F-4A10-B07E-B89CFEC6BBDC}
|
||||
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545} = {B972BBFA-917F-4A10-B07E-B89CFEC6BBDC}
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655} = {B972BBFA-917F-4A10-B07E-B89CFEC6BBDC}
|
||||
{137959BD-073B-4EC7-8ED5-31D73FA7DBC6} = {BB702EBD-3B79-4ECA-A2A6-1237B07F0AF0}
|
||||
{1AC5ED7F-301E-4B3C-ACDE-C0EADFA5AE44} = {BB702EBD-3B79-4ECA-A2A6-1237B07F0AF0}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
103
build.cake
103
build.cake
@@ -15,16 +15,18 @@ abstract record VariantConfig(
|
||||
string AppName,
|
||||
string AndroidPackageName,
|
||||
string iOSBundleId,
|
||||
string ApsEnvironment
|
||||
string ApsEnvironment,
|
||||
string DistProvisioningProfilePrefix
|
||||
);
|
||||
|
||||
const string BASE_BUNDLE_ID_DROID = "com.x8bit.bitwarden";
|
||||
const string BASE_BUNDLE_ID_IOS = "com.8bit.bitwarden";
|
||||
|
||||
record Dev(): VariantConfig("Bitwarden Dev", $"{BASE_BUNDLE_ID_DROID}.dev", $"{BASE_BUNDLE_ID_IOS}.dev", "development");
|
||||
record QA(): VariantConfig("Bitwarden QA", $"{BASE_BUNDLE_ID_DROID}.qa", $"{BASE_BUNDLE_ID_IOS}.qa", "development");
|
||||
record Beta(): VariantConfig("Bitwarden Beta", $"{BASE_BUNDLE_ID_DROID}.beta", $"{BASE_BUNDLE_ID_IOS}.beta", "production");
|
||||
record Prod(): VariantConfig("Bitwarden", $"{BASE_BUNDLE_ID_DROID}", $"{BASE_BUNDLE_ID_IOS}", "production");
|
||||
//NOTE: Beta iOS variants have a different ITSEncryptionExportComplianceCode
|
||||
record Dev(): VariantConfig("Bitwarden Dev", $"{BASE_BUNDLE_ID_DROID}.dev", $"{BASE_BUNDLE_ID_IOS}.dev", "development", "Dist:");
|
||||
record QA(): VariantConfig("Bitwarden QA", $"{BASE_BUNDLE_ID_DROID}.qa", $"{BASE_BUNDLE_ID_IOS}.qa", "development", "Dist:");
|
||||
record Beta(): VariantConfig("Bitwarden Beta", $"{BASE_BUNDLE_ID_DROID}.beta", $"{BASE_BUNDLE_ID_IOS}.beta", "production", "Dist: Beta");
|
||||
record Prod(): VariantConfig("Bitwarden", $"{BASE_BUNDLE_ID_DROID}", $"{BASE_BUNDLE_ID_IOS}", "production", "Dist:");
|
||||
|
||||
VariantConfig GetVariant() => variant.ToLower() switch{
|
||||
"qa" => new QA(),
|
||||
@@ -67,7 +69,7 @@ Task("UpdateAndroidManifest")
|
||||
.Does(()=>
|
||||
{
|
||||
var buildVariant = GetVariant();
|
||||
var manifestPath = Path.Combine(_slnPath, "src", "Android", "Properties", "AndroidManifest.xml");
|
||||
var manifestPath = Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "AndroidManifest.xml");
|
||||
|
||||
// Cake.AndroidAppManifest doesn't currently enable us to access nested items so, quick (not ideal) fix:
|
||||
var manifestText = FileReadText(manifestPath);
|
||||
@@ -119,26 +121,26 @@ Task("UpdateAndroidCodeFiles")
|
||||
//We're not using _androidPackageName here because the codefile is currently slightly different string than the one in AndroidManifest.xml
|
||||
var keyName = "com.8bit.bitwarden";
|
||||
var fixedPackageName = buildVariant.AndroidPackageName.Replace("x8bit", "8bit");
|
||||
var filePath = Path.Combine(_slnPath, "src", "Android", "Services", "BiometricService.cs");
|
||||
var filePath = Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Services", "BiometricService.cs");
|
||||
ReplaceInFile(filePath, keyName, fixedPackageName);
|
||||
|
||||
var packageFileList = new string[] {
|
||||
Path.Combine(_slnPath, "src", "Android", "MainActivity.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "MainApplication.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Constants.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Accessibility", "AccessibilityService.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Autofill", "AutofillHelpers.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Autofill", "AutofillService.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Receivers", "ClearClipboardAlarmReceiver.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Receivers", "EventUploadReceiver.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Receivers", "PackageReplacedReceiver.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Receivers", "RestrictionsChangedReceiver.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Services", "DeviceActionService.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Services", "FileService.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Tiles", "AutofillTileService.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Tiles", "GeneratorTileService.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Tiles", "MyVaultTileService.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "google-services.json"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "MainActivity.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "MainApplication.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Constants.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Accessibility", "AccessibilityService.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Autofill", "AutofillHelpers.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Autofill", "AutofillService.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Receivers", "ClearClipboardAlarmReceiver.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Receivers", "EventUploadReceiver.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Receivers", "PackageReplacedReceiver.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Receivers", "RestrictionsChangedReceiver.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Services", "DeviceActionService.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Services", "FileService.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Tiles", "AutofillTileService.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Tiles", "GeneratorTileService.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Tiles", "MyVaultTileService.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "google-services.json"),
|
||||
Path.Combine(_slnPath, "store", "google", "Publisher", "Program.cs"),
|
||||
};
|
||||
|
||||
@@ -148,7 +150,7 @@ Task("UpdateAndroidCodeFiles")
|
||||
}
|
||||
|
||||
var labelFileList = new string[] {
|
||||
Path.Combine(_slnPath, "src", "Android", "Autofill", "AutofillService.cs"),
|
||||
Path.Combine(_slnPath, "src", "App", "Platforms", "Android", "Autofill", "AutofillService.cs"),
|
||||
};
|
||||
|
||||
foreach(string path in labelFileList)
|
||||
@@ -197,7 +199,8 @@ private void UpdateiOSInfoPlist(string plistPath, VariantConfig buildVariant, Gi
|
||||
var prevBundleId = plist["CFBundleIdentifier"];
|
||||
var prevBundleName = plist["CFBundleName"];
|
||||
//var newVersion = CreateBuildNumber(prevVersion).ToString();
|
||||
var newVersionName = GetVersionName(prevVersionName, buildVariant, git);
|
||||
// we need to maintain version formatting here composed of one to three period-separated integers, so we cannot use the GetVersionName method as in Android for non-Prod.
|
||||
var newVersionName = prevVersionName;
|
||||
var newBundleId = GetiOSBundleId(buildVariant, projectType);
|
||||
var newBundleName = GetiOSBundleName(buildVariant, projectType);
|
||||
|
||||
@@ -219,6 +222,11 @@ private void UpdateiOSInfoPlist(string plistPath, VariantConfig buildVariant, Gi
|
||||
plist["NSExtension"]["NSExtensionAttributes"]["NSExtensionActivationRule"] = keyText.Replace("com.8bit.bitwarden", buildVariant.iOSBundleId);
|
||||
}
|
||||
|
||||
if(buildVariant is Beta)
|
||||
{
|
||||
plist["ITSEncryptionExportComplianceCode"] = "3dd3e32f-efa6-4d99-b410-28aa28b1cb77";
|
||||
}
|
||||
|
||||
SerializePlist(plistFile, plist);
|
||||
|
||||
Information($"Changed app name from {prevBundleName} to {newBundleName}");
|
||||
@@ -228,12 +236,15 @@ private void UpdateiOSInfoPlist(string plistPath, VariantConfig buildVariant, Gi
|
||||
Information($"{plistPath} updated with success!");
|
||||
}
|
||||
|
||||
private void UpdateiOSEntitlementsPlist(string entitlementsPath, VariantConfig buildVariant)
|
||||
private void UpdateiOSEntitlementsPlist(string entitlementsPath, VariantConfig buildVariant, bool updateApsEnv)
|
||||
{
|
||||
var EntitlementlistFile = File(entitlementsPath);
|
||||
dynamic Entitlements = DeserializePlist(EntitlementlistFile);
|
||||
|
||||
Entitlements["aps-environment"] = buildVariant.ApsEnvironment;
|
||||
if (updateApsEnv)
|
||||
{
|
||||
Entitlements["aps-environment"] = buildVariant.ApsEnvironment;
|
||||
}
|
||||
Entitlements["keychain-access-groups"] = new List<string>() { "$(AppIdentifierPrefix)" + buildVariant.iOSBundleId };
|
||||
Entitlements["com.apple.security.application-groups"] = new List<string>() { $"group.{buildVariant.iOSBundleId}" };;
|
||||
|
||||
@@ -272,9 +283,10 @@ private void UpdateWatchPbxproj(string pbxprojPath, string newVersion)
|
||||
const string pattern = @"MARKETING_VERSION = [^;]*;";
|
||||
|
||||
fileText = Regex.Replace(fileText, pattern, $"MARKETING_VERSION = {newVersion};");
|
||||
|
||||
|
||||
FileWriteText(pbxprojPath, fileText);
|
||||
Information($"{pbxprojPath} modified successfully.");
|
||||
|
||||
Information($"{pbxprojPath} modified Marketing Version successfully.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -315,7 +327,7 @@ private void UpdateAppleIcons(string target, string appiconsetTarget)
|
||||
|
||||
Task("UpdateiOSIcons")
|
||||
.Does(()=>{
|
||||
UpdateAppleIcons("ios", Path.Combine(_slnPath, "src", "iOS", "Resources", "Assets.xcassets", "AppIcons.appiconset"));
|
||||
UpdateAppleIcons("ios", Path.Combine(_slnPath, "src", "App", "Platforms", "iOS", "Resources", "Assets.xcassets", "AppIcons.appiconset"));
|
||||
UpdateAppleIcons("watch", Path.Combine(_slnPath, "src", "watchOS", "bitwarden", "bitwarden WatchKit App", "Assets.xcassets", "AppIcon.appiconset"));
|
||||
// TODO: Update complication icons when they start working
|
||||
});
|
||||
@@ -324,10 +336,10 @@ Task("UpdateiOSPlist")
|
||||
.IsDependentOn("GetGitInfo")
|
||||
.Does(()=> {
|
||||
var buildVariant = GetVariant();
|
||||
var infoPath = Path.Combine(_slnPath, "src", "iOS", "Info.plist");
|
||||
var entitlementsPath = Path.Combine(_slnPath, "src", "iOS", "Entitlements.plist");
|
||||
var infoPath = Path.Combine(_slnPath, "src", "App", "Platforms", "iOS", "Info.plist");
|
||||
var entitlementsPath = Path.Combine(_slnPath, "src", "App", "Platforms", "iOS", "Entitlements.plist");
|
||||
UpdateiOSInfoPlist(infoPath, buildVariant, _gitVersion, iOSProjectType.MainApp);
|
||||
UpdateiOSEntitlementsPlist(entitlementsPath, buildVariant);
|
||||
UpdateiOSEntitlementsPlist(entitlementsPath, buildVariant, true);
|
||||
});
|
||||
|
||||
Task("UpdateiOSAutofillPlist")
|
||||
@@ -338,7 +350,7 @@ Task("UpdateiOSAutofillPlist")
|
||||
var infoPath = Path.Combine(_slnPath, "src", "iOS.Autofill", "Info.plist");
|
||||
var entitlementsPath = Path.Combine(_slnPath, "src", "iOS.Autofill", "Entitlements.plist");
|
||||
UpdateiOSInfoPlist(infoPath, buildVariant, _gitVersion, iOSProjectType.Autofill);
|
||||
UpdateiOSEntitlementsPlist(entitlementsPath, buildVariant);
|
||||
UpdateiOSEntitlementsPlist(entitlementsPath, buildVariant, false);
|
||||
});
|
||||
|
||||
Task("UpdateiOSExtensionPlist")
|
||||
@@ -349,7 +361,7 @@ Task("UpdateiOSExtensionPlist")
|
||||
var infoPath = Path.Combine(_slnPath, "src", "iOS.Extension", "Info.plist");
|
||||
var entitlementsPath = Path.Combine(_slnPath, "src", "iOS.Extension", "Entitlements.plist");
|
||||
UpdateiOSInfoPlist(infoPath, buildVariant, _gitVersion, iOSProjectType.Extension);
|
||||
UpdateiOSEntitlementsPlist(entitlementsPath, buildVariant);
|
||||
UpdateiOSEntitlementsPlist(entitlementsPath, buildVariant, false);
|
||||
});
|
||||
|
||||
Task("UpdateiOSShareExtensionPlist")
|
||||
@@ -360,7 +372,7 @@ Task("UpdateiOSShareExtensionPlist")
|
||||
var infoPath = Path.Combine(_slnPath, "src", "iOS.ShareExtension", "Info.plist");
|
||||
var entitlementsPath = Path.Combine(_slnPath, "src", "iOS.ShareExtension", "Entitlements.plist");
|
||||
UpdateiOSInfoPlist(infoPath, buildVariant, _gitVersion, iOSProjectType.ShareExtension);
|
||||
UpdateiOSEntitlementsPlist(entitlementsPath, buildVariant);
|
||||
UpdateiOSEntitlementsPlist(entitlementsPath, buildVariant, false);
|
||||
});
|
||||
|
||||
Task("UpdateiOSCodeFiles")
|
||||
@@ -397,6 +409,22 @@ Task("UpdateWatchKitAppInfoPlist")
|
||||
UpdateWatchKitAppInfoPlist(infoPath, buildVariant);
|
||||
});
|
||||
|
||||
Task("UpdateDistProfiles")
|
||||
.IsDependentOn("UpdateiOSCodeFiles")
|
||||
.Does(()=> {
|
||||
var buildVariant = GetVariant();
|
||||
|
||||
var filesToReplace = new string[] {
|
||||
Path.Combine(".github", "resources", "export-options-app-store.plist"),
|
||||
Path.Combine(_slnPath, "src", "watchOS", "bitwarden", "bitwarden.xcodeproj", "project.pbxproj")
|
||||
};
|
||||
|
||||
foreach(string path in filesToReplace)
|
||||
{
|
||||
ReplaceInFile(path, "Dist:", buildVariant.DistProvisioningProfilePrefix);
|
||||
}
|
||||
});
|
||||
|
||||
#endregion iOS
|
||||
|
||||
#region Main Tasks
|
||||
@@ -418,6 +446,7 @@ Task("iOS")
|
||||
.IsDependentOn("UpdateiOSCodeFiles")
|
||||
.IsDependentOn("UpdateWatchProject")
|
||||
.IsDependentOn("UpdateWatchKitAppInfoPlist")
|
||||
.IsDependentOn("UpdateDistProfiles")
|
||||
.Does(()=>
|
||||
{
|
||||
Information("iOS app updated");
|
||||
@@ -437,4 +466,4 @@ Options:
|
||||
});
|
||||
#endregion Main Tasks
|
||||
|
||||
RunTarget(target);
|
||||
RunTarget(target);
|
||||
|
||||
18
crowdin.yml
18
crowdin.yml
@@ -2,9 +2,9 @@ project_id_env: _CROWDIN_PROJECT_ID
|
||||
api_token_env: CROWDIN_API_TOKEN
|
||||
preserve_hierarchy: true
|
||||
files:
|
||||
- source: /src/App/Resources/AppResources.resx
|
||||
dest: /src/App/Resources/%original_file_name%
|
||||
translation: /src/App/Resources/AppResources.%two_letters_code%.resx
|
||||
- source: /src/Core/Resources/Localization/AppResources.resx
|
||||
dest: /src/Core/Resources/Localization/%original_file_name%
|
||||
translation: /src/Core/Resources/Localization/AppResources.%two_letters_code%.resx
|
||||
update_option: update_as_unapproved
|
||||
languages_mapping:
|
||||
two_letters_code:
|
||||
@@ -38,3 +38,15 @@ files:
|
||||
pt-PT: pt-PT
|
||||
en-GB: en-GB
|
||||
en-IN: en-IN
|
||||
- source: "/src/watchOS/bitwarden/bitwarden WatchKit Extension/Localization/en.lproj/Localizable.strings"
|
||||
dest: "/src/watchOS/bitwarden/bitwarden WatchKit Extension/Localization/en.lproj/%original_file_name%"
|
||||
translation: "/src/watchOS/bitwarden/bitwarden WatchKit Extension/Localization//%two_letters_code%.lproj/%original_file_name%"
|
||||
update_option: update_as_unapproved
|
||||
languages_mapping:
|
||||
two_letters_code:
|
||||
zh-CN: zh-Hans
|
||||
zh-TW: zh-Hant
|
||||
pt-BR: pt-BR
|
||||
pt-PT: pt-PT
|
||||
en-GB: en-GB
|
||||
en-IN: en-IN
|
||||
|
||||
6
global.json
Normal file
6
global.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "8.0.402",
|
||||
"rollForward": "disable"
|
||||
}
|
||||
}
|
||||
Submodule lib/MessagePack deleted from 1ecb15e311
19
lib/MessagePack/LICENSE.md
Normal file
19
lib/MessagePack/LICENSE.md
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright 2018 Read Evaluate Press, LLC
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
32
lib/MessagePack/MessagePack-FlightSchool.podspec
Normal file
32
lib/MessagePack/MessagePack-FlightSchool.podspec
Normal file
@@ -0,0 +1,32 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'MessagePack-FlightSchool'
|
||||
s.module_name = 'MessagePack'
|
||||
s.version = '1.2.4'
|
||||
s.summary = 'A MessagePack encoder and decoder for Codable types.'
|
||||
|
||||
s.description = <<-DESC
|
||||
This functionality is discussed in Chapter 7 of
|
||||
Flight School Guide to Swift Codable.
|
||||
DESC
|
||||
|
||||
s.homepage = 'https://flight.school/books/codable/'
|
||||
|
||||
s.license = { type: 'MIT', file: 'LICENSE.md' }
|
||||
|
||||
s.author = { 'Mattt' => 'mattt@flight.school' }
|
||||
|
||||
s.social_media_url = 'https://twitter.com/mattt'
|
||||
|
||||
s.ios.deployment_target = '8.0'
|
||||
s.osx.deployment_target = '10.10'
|
||||
s.watchos.deployment_target = '2.0'
|
||||
s.tvos.deployment_target = '9.0'
|
||||
|
||||
s.source = { git: 'https://github.com/Flight-School/MessagePack.git',
|
||||
tag: s.version.to_s }
|
||||
|
||||
s.source_files = 'Sources/**/*.swift'
|
||||
|
||||
s.swift_version = '4.2'
|
||||
s.static_framework = true
|
||||
end
|
||||
13
lib/MessagePack/MessagePack.playground/Contents.swift
Normal file
13
lib/MessagePack/MessagePack.playground/Contents.swift
Normal file
@@ -0,0 +1,13 @@
|
||||
import MessagePack
|
||||
|
||||
let encoder = MessagePackEncoder()
|
||||
|
||||
let value: String = "hello"
|
||||
let encodedData = try encoder.encode(value)
|
||||
|
||||
print("Bytes: ", encodedData.map{ String($0, radix: 16, uppercase: true) })
|
||||
|
||||
let decoder = MessagePackDecoder()
|
||||
let decodedValue = try decoder.decode(String.self, from: encodedData)
|
||||
|
||||
decodedValue == value
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<playground version='5.0' target-platform='macos' executeOnSourceChanges='false'>
|
||||
<timeline fileName='timeline.xctimeline'/>
|
||||
</playground>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
25
lib/MessagePack/MessagePack.xcodeproj/MessagePack_Info.plist
Normal file
25
lib/MessagePack/MessagePack.xcodeproj/MessagePack_Info.plist
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
543
lib/MessagePack/MessagePack.xcodeproj/project.pbxproj
Normal file
543
lib/MessagePack/MessagePack.xcodeproj/project.pbxproj
Normal file
@@ -0,0 +1,543 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXAggregateTarget section */
|
||||
"MessagePack::MessagePackPackageTests::ProductTarget" /* MessagePackPackageTests */ = {
|
||||
isa = PBXAggregateTarget;
|
||||
buildConfigurationList = OBJ_57 /* Build configuration list for PBXAggregateTarget "MessagePackPackageTests" */;
|
||||
buildPhases = (
|
||||
);
|
||||
dependencies = (
|
||||
OBJ_60 /* PBXTargetDependency */,
|
||||
);
|
||||
name = MessagePackPackageTests;
|
||||
productName = MessagePackPackageTests;
|
||||
};
|
||||
/* End PBXAggregateTarget section */
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1BC312FF2992DE9C00177F2A /* DataSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BC312FE2992DE9C00177F2A /* DataSpec.swift */; };
|
||||
OBJ_38 /* AnyCodingKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* AnyCodingKey.swift */; };
|
||||
OBJ_39 /* Box.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_10 /* Box.swift */; };
|
||||
OBJ_40 /* KeyedDecodingContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* KeyedDecodingContainer.swift */; };
|
||||
OBJ_41 /* MessagePackDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_13 /* MessagePackDecoder.swift */; };
|
||||
OBJ_42 /* SingleValueDecodingContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_14 /* SingleValueDecodingContainer.swift */; };
|
||||
OBJ_43 /* UnkeyedDecodingContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_15 /* UnkeyedDecodingContainer.swift */; };
|
||||
OBJ_44 /* KeyedEncodingContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_17 /* KeyedEncodingContainer.swift */; };
|
||||
OBJ_45 /* MessagePackEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_18 /* MessagePackEncoder.swift */; };
|
||||
OBJ_46 /* SingleValueEncodingContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_19 /* SingleValueEncodingContainer.swift */; };
|
||||
OBJ_47 /* UnkeyedEncodingContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_20 /* UnkeyedEncodingContainer.swift */; };
|
||||
OBJ_48 /* FixedWidthInteger+Bytes.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_21 /* FixedWidthInteger+Bytes.swift */; };
|
||||
OBJ_55 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_6 /* Package.swift */; };
|
||||
OBJ_66 /* Airport.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_24 /* Airport.swift */; };
|
||||
OBJ_67 /* MessagePackDecodingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_25 /* MessagePackDecodingTests.swift */; };
|
||||
OBJ_68 /* MessagePackEncodingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_26 /* MessagePackEncodingTests.swift */; };
|
||||
OBJ_69 /* MessagePackPerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_27 /* MessagePackPerformanceTests.swift */; };
|
||||
OBJ_70 /* MessagePackRoundTripTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_28 /* MessagePackRoundTripTests.swift */; };
|
||||
OBJ_72 /* MessagePack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "MessagePack::MessagePack::Product" /* MessagePack.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
1BC312FC2989A1AD00177F2A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = OBJ_1 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = "MessagePack::MessagePack";
|
||||
remoteInfo = MessagePack;
|
||||
};
|
||||
1BC312FD2989A1B200177F2A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = OBJ_1 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = "MessagePack::MessagePackTests";
|
||||
remoteInfo = MessagePackTests;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
1BC312FE2992DE9C00177F2A /* DataSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataSpec.swift; sourceTree = "<group>"; };
|
||||
"MessagePack::MessagePack::Product" /* MessagePack.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = MessagePack.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
"MessagePack::MessagePackTests::Product" /* MessagePackTests.xctest */ = {isa = PBXFileReference; lastKnownFileType = file; path = MessagePackTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
OBJ_10 /* Box.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Box.swift; sourceTree = "<group>"; };
|
||||
OBJ_12 /* KeyedDecodingContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyedDecodingContainer.swift; sourceTree = "<group>"; };
|
||||
OBJ_13 /* MessagePackDecoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagePackDecoder.swift; sourceTree = "<group>"; };
|
||||
OBJ_14 /* SingleValueDecodingContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleValueDecodingContainer.swift; sourceTree = "<group>"; };
|
||||
OBJ_15 /* UnkeyedDecodingContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnkeyedDecodingContainer.swift; sourceTree = "<group>"; };
|
||||
OBJ_17 /* KeyedEncodingContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyedEncodingContainer.swift; sourceTree = "<group>"; };
|
||||
OBJ_18 /* MessagePackEncoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagePackEncoder.swift; sourceTree = "<group>"; };
|
||||
OBJ_19 /* SingleValueEncodingContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleValueEncodingContainer.swift; sourceTree = "<group>"; };
|
||||
OBJ_20 /* UnkeyedEncodingContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnkeyedEncodingContainer.swift; sourceTree = "<group>"; };
|
||||
OBJ_21 /* FixedWidthInteger+Bytes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FixedWidthInteger+Bytes.swift"; sourceTree = "<group>"; };
|
||||
OBJ_24 /* Airport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Airport.swift; sourceTree = "<group>"; };
|
||||
OBJ_25 /* MessagePackDecodingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagePackDecodingTests.swift; sourceTree = "<group>"; };
|
||||
OBJ_26 /* MessagePackEncodingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagePackEncodingTests.swift; sourceTree = "<group>"; };
|
||||
OBJ_27 /* MessagePackPerformanceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagePackPerformanceTests.swift; sourceTree = "<group>"; };
|
||||
OBJ_28 /* MessagePackRoundTripTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagePackRoundTripTests.swift; sourceTree = "<group>"; };
|
||||
OBJ_29 /* MessagePack.xcworkspace */ = {isa = PBXFileReference; lastKnownFileType = wrapper.workspace; path = MessagePack.xcworkspace; sourceTree = SOURCE_ROOT; };
|
||||
OBJ_6 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; path = Package.swift; sourceTree = "<group>"; };
|
||||
OBJ_9 /* AnyCodingKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyCodingKey.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
OBJ_49 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 0;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
OBJ_71 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 0;
|
||||
files = (
|
||||
OBJ_72 /* MessagePack.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
OBJ_11 /* Decoder */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
OBJ_12 /* KeyedDecodingContainer.swift */,
|
||||
OBJ_13 /* MessagePackDecoder.swift */,
|
||||
OBJ_14 /* SingleValueDecodingContainer.swift */,
|
||||
OBJ_15 /* UnkeyedDecodingContainer.swift */,
|
||||
);
|
||||
path = Decoder;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
OBJ_16 /* Encoder */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
OBJ_17 /* KeyedEncodingContainer.swift */,
|
||||
OBJ_18 /* MessagePackEncoder.swift */,
|
||||
OBJ_19 /* SingleValueEncodingContainer.swift */,
|
||||
OBJ_20 /* UnkeyedEncodingContainer.swift */,
|
||||
);
|
||||
path = Encoder;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
OBJ_22 /* Tests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
OBJ_23 /* MessagePackTests */,
|
||||
);
|
||||
name = Tests;
|
||||
sourceTree = SOURCE_ROOT;
|
||||
};
|
||||
OBJ_23 /* MessagePackTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
OBJ_24 /* Airport.swift */,
|
||||
OBJ_25 /* MessagePackDecodingTests.swift */,
|
||||
OBJ_26 /* MessagePackEncodingTests.swift */,
|
||||
OBJ_27 /* MessagePackPerformanceTests.swift */,
|
||||
OBJ_28 /* MessagePackRoundTripTests.swift */,
|
||||
);
|
||||
name = MessagePackTests;
|
||||
path = Tests/MessagePackTests;
|
||||
sourceTree = SOURCE_ROOT;
|
||||
};
|
||||
OBJ_30 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
"MessagePack::MessagePackTests::Product" /* MessagePackTests.xctest */,
|
||||
"MessagePack::MessagePack::Product" /* MessagePack.framework */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
OBJ_5 /* */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
OBJ_6 /* Package.swift */,
|
||||
OBJ_7 /* Sources */,
|
||||
OBJ_22 /* Tests */,
|
||||
OBJ_29 /* MessagePack.xcworkspace */,
|
||||
OBJ_30 /* Products */,
|
||||
);
|
||||
name = "";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
OBJ_7 /* Sources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
OBJ_8 /* MessagePack */,
|
||||
);
|
||||
name = Sources;
|
||||
sourceTree = SOURCE_ROOT;
|
||||
};
|
||||
OBJ_8 /* MessagePack */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
OBJ_9 /* AnyCodingKey.swift */,
|
||||
OBJ_10 /* Box.swift */,
|
||||
OBJ_11 /* Decoder */,
|
||||
OBJ_16 /* Encoder */,
|
||||
OBJ_21 /* FixedWidthInteger+Bytes.swift */,
|
||||
1BC312FE2992DE9C00177F2A /* DataSpec.swift */,
|
||||
);
|
||||
name = MessagePack;
|
||||
path = Sources/MessagePack;
|
||||
sourceTree = SOURCE_ROOT;
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
"MessagePack::MessagePack" /* MessagePack */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = OBJ_34 /* Build configuration list for PBXNativeTarget "MessagePack" */;
|
||||
buildPhases = (
|
||||
OBJ_37 /* Sources */,
|
||||
OBJ_49 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = MessagePack;
|
||||
productName = MessagePack;
|
||||
productReference = "MessagePack::MessagePack::Product" /* MessagePack.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
"MessagePack::MessagePackTests" /* MessagePackTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = OBJ_62 /* Build configuration list for PBXNativeTarget "MessagePackTests" */;
|
||||
buildPhases = (
|
||||
OBJ_65 /* Sources */,
|
||||
OBJ_71 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
OBJ_73 /* PBXTargetDependency */,
|
||||
);
|
||||
name = MessagePackTests;
|
||||
productName = MessagePackTests;
|
||||
productReference = "MessagePack::MessagePackTests::Product" /* MessagePackTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
"MessagePack::SwiftPMPackageDescription" /* MessagePackPackageDescription */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = OBJ_51 /* Build configuration list for PBXNativeTarget "MessagePackPackageDescription" */;
|
||||
buildPhases = (
|
||||
OBJ_54 /* Sources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = MessagePackPackageDescription;
|
||||
productName = MessagePackPackageDescription;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
OBJ_1 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 9999;
|
||||
};
|
||||
buildConfigurationList = OBJ_2 /* Build configuration list for PBXProject "MessagePack" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
English,
|
||||
en,
|
||||
);
|
||||
mainGroup = OBJ_5 /* */;
|
||||
productRefGroup = OBJ_30 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
"MessagePack::MessagePack" /* MessagePack */,
|
||||
"MessagePack::SwiftPMPackageDescription" /* MessagePackPackageDescription */,
|
||||
"MessagePack::MessagePackPackageTests::ProductTarget" /* MessagePackPackageTests */,
|
||||
"MessagePack::MessagePackTests" /* MessagePackTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
OBJ_37 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 0;
|
||||
files = (
|
||||
OBJ_38 /* AnyCodingKey.swift in Sources */,
|
||||
OBJ_39 /* Box.swift in Sources */,
|
||||
OBJ_40 /* KeyedDecodingContainer.swift in Sources */,
|
||||
OBJ_41 /* MessagePackDecoder.swift in Sources */,
|
||||
OBJ_42 /* SingleValueDecodingContainer.swift in Sources */,
|
||||
OBJ_43 /* UnkeyedDecodingContainer.swift in Sources */,
|
||||
OBJ_44 /* KeyedEncodingContainer.swift in Sources */,
|
||||
OBJ_45 /* MessagePackEncoder.swift in Sources */,
|
||||
OBJ_46 /* SingleValueEncodingContainer.swift in Sources */,
|
||||
OBJ_47 /* UnkeyedEncodingContainer.swift in Sources */,
|
||||
1BC312FF2992DE9C00177F2A /* DataSpec.swift in Sources */,
|
||||
OBJ_48 /* FixedWidthInteger+Bytes.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
OBJ_54 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 0;
|
||||
files = (
|
||||
OBJ_55 /* Package.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
OBJ_65 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 0;
|
||||
files = (
|
||||
OBJ_66 /* Airport.swift in Sources */,
|
||||
OBJ_67 /* MessagePackDecodingTests.swift in Sources */,
|
||||
OBJ_68 /* MessagePackEncodingTests.swift in Sources */,
|
||||
OBJ_69 /* MessagePackPerformanceTests.swift in Sources */,
|
||||
OBJ_70 /* MessagePackRoundTripTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
OBJ_60 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = "MessagePack::MessagePackTests" /* MessagePackTests */;
|
||||
targetProxy = 1BC312FD2989A1B200177F2A /* PBXContainerItemProxy */;
|
||||
};
|
||||
OBJ_73 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = "MessagePack::MessagePack" /* MessagePack */;
|
||||
targetProxy = 1BC312FC2989A1AD00177F2A /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
OBJ_3 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_NS_ASSERTIONS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_SWIFT_FLAGS = "-DXcode";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = macosx;
|
||||
SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator";
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "SWIFT_PACKAGE DEBUG";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
USE_HEADERMAP = NO;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
OBJ_35 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ENABLE_TESTABILITY = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PLATFORM_DIR)/Developer/Library/Frameworks",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = "$(inherited)";
|
||||
INFOPLIST_FILE = MessagePack.xcodeproj/MessagePack_Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx";
|
||||
OTHER_CFLAGS = "$(inherited)";
|
||||
OTHER_LDFLAGS = "$(inherited)";
|
||||
OTHER_SWIFT_FLAGS = "$(inherited)";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = MessagePack;
|
||||
PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)";
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGET_NAME = MessagePack;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
OBJ_36 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ENABLE_TESTABILITY = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PLATFORM_DIR)/Developer/Library/Frameworks",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = "$(inherited)";
|
||||
INFOPLIST_FILE = MessagePack.xcodeproj/MessagePack_Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx";
|
||||
OTHER_CFLAGS = "$(inherited)";
|
||||
OTHER_LDFLAGS = "$(inherited)";
|
||||
OTHER_SWIFT_FLAGS = "$(inherited)";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = MessagePack;
|
||||
PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)";
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGET_NAME = MessagePack;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
OBJ_4 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
GCC_OPTIMIZATION_LEVEL = s;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
OTHER_SWIFT_FLAGS = "-DXcode";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = macosx;
|
||||
SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator";
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = SWIFT_PACKAGE;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
USE_HEADERMAP = NO;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
OBJ_52 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
LD = /usr/bin/true;
|
||||
OTHER_SWIFT_FLAGS = "-swift-version 4 -I $(TOOLCHAIN_DIR)/usr/lib/swift/pm/4 -target x86_64-apple-macosx10.10 -sdk /Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk";
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
OBJ_53 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
LD = /usr/bin/true;
|
||||
OTHER_SWIFT_FLAGS = "-swift-version 4 -I $(TOOLCHAIN_DIR)/usr/lib/swift/pm/4 -target x86_64-apple-macosx10.10 -sdk /Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk";
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
OBJ_58 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
OBJ_59 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
OBJ_63 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
EMBEDDED_CONTENT_CONTAINS_SWIFT = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PLATFORM_DIR)/Developer/Library/Frameworks",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = "$(inherited)";
|
||||
INFOPLIST_FILE = MessagePack.xcodeproj/MessagePackTests_Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @loader_path/../Frameworks @loader_path/Frameworks";
|
||||
OTHER_CFLAGS = "$(inherited)";
|
||||
OTHER_LDFLAGS = "$(inherited)";
|
||||
OTHER_SWIFT_FLAGS = "$(inherited)";
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)";
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGET_NAME = MessagePackTests;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
OBJ_64 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
EMBEDDED_CONTENT_CONTAINS_SWIFT = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PLATFORM_DIR)/Developer/Library/Frameworks",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = "$(inherited)";
|
||||
INFOPLIST_FILE = MessagePack.xcodeproj/MessagePackTests_Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @loader_path/../Frameworks @loader_path/Frameworks";
|
||||
OTHER_CFLAGS = "$(inherited)";
|
||||
OTHER_LDFLAGS = "$(inherited)";
|
||||
OTHER_SWIFT_FLAGS = "$(inherited)";
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)";
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGET_NAME = MessagePackTests;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
OBJ_2 /* Build configuration list for PBXProject "MessagePack" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
OBJ_3 /* Debug */,
|
||||
OBJ_4 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
OBJ_34 /* Build configuration list for PBXNativeTarget "MessagePack" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
OBJ_35 /* Debug */,
|
||||
OBJ_36 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
OBJ_51 /* Build configuration list for PBXNativeTarget "MessagePackPackageDescription" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
OBJ_52 /* Debug */,
|
||||
OBJ_53 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
OBJ_57 /* Build configuration list for PBXAggregateTarget "MessagePackPackageTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
OBJ_58 /* Debug */,
|
||||
OBJ_59 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
OBJ_62 /* Build configuration list for PBXNativeTarget "MessagePackTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
OBJ_63 /* Debug */,
|
||||
OBJ_64 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = OBJ_1 /* Project object */;
|
||||
}
|
||||
7
lib/MessagePack/MessagePack.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
lib/MessagePack/MessagePack.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1010"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "MessagePack::MessagePack"
|
||||
BuildableName = "MessagePack.framework"
|
||||
BlueprintName = "MessagePack"
|
||||
ReferencedContainer = "container:MessagePack.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "MessagePack::MessagePackTests"
|
||||
BuildableName = "MessagePackTests.xctest"
|
||||
BlueprintName = "MessagePackTests"
|
||||
ReferencedContainer = "container:MessagePack.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "MessagePack::MessagePack"
|
||||
BuildableName = "MessagePack.framework"
|
||||
BlueprintName = "MessagePack"
|
||||
ReferencedContainer = "container:MessagePack.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "MessagePack::MessagePack"
|
||||
BuildableName = "MessagePack.framework"
|
||||
BlueprintName = "MessagePack"
|
||||
ReferencedContainer = "container:MessagePack.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "MessagePack::MessagePack"
|
||||
BuildableName = "MessagePack.framework"
|
||||
BlueprintName = "MessagePack"
|
||||
ReferencedContainer = "container:MessagePack.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
10
lib/MessagePack/MessagePack.xcworkspace/contents.xcworkspacedata
generated
Normal file
10
lib/MessagePack/MessagePack.xcworkspace/contents.xcworkspacedata
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:MessagePack.playground">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:MessagePack.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
28
lib/MessagePack/Package.swift
Normal file
28
lib/MessagePack/Package.swift
Normal file
@@ -0,0 +1,28 @@
|
||||
// swift-tools-version:4.0
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "MessagePack",
|
||||
products: [
|
||||
// Products define the executables and libraries produced by a package, and make them visible to other packages.
|
||||
.library(
|
||||
name: "MessagePack",
|
||||
targets: ["MessagePack"]),
|
||||
],
|
||||
dependencies: [
|
||||
// Dependencies declare other packages that this package depends on.
|
||||
// .package(url: /* package url */, from: "1.0.0"),
|
||||
],
|
||||
targets: [
|
||||
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
||||
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
|
||||
.target(
|
||||
name: "MessagePack",
|
||||
dependencies: []),
|
||||
.testTarget(
|
||||
name: "MessagePackTests",
|
||||
dependencies: ["MessagePack"]),
|
||||
]
|
||||
)
|
||||
87
lib/MessagePack/README.md
Normal file
87
lib/MessagePack/README.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# MessagePack
|
||||
|
||||
[![Build Status][build status badge]][build status]
|
||||
|
||||
A [MessagePack](https://msgpack.org/) encoder and decoder for `Codable` types.
|
||||
|
||||
This functionality is discussed in Chapter 7 of
|
||||
[Flight School Guide to Swift Codable](https://flight.school/books/codable).
|
||||
|
||||
## Requirements
|
||||
|
||||
- Swift 4.2+
|
||||
|
||||
## Usage
|
||||
|
||||
### Encoding Messages
|
||||
|
||||
```swift
|
||||
import MessagePack
|
||||
|
||||
let encoder = MessagePackEncoder()
|
||||
let value = try! encoder.encode(["a": 1, "b": 2, "c": 3])
|
||||
// [0x83, 0xA1, 0x62, 0x02, 0xA1, 0x61, 0x01, 0xA1, 0x63, 0x03]
|
||||
```
|
||||
|
||||
### Decoding Messages
|
||||
|
||||
```swift
|
||||
import MessagePack
|
||||
|
||||
let decoder = MessagePackDecoder()
|
||||
let data = Data(bytes: [0xCB, 0x40, 0x09, 0x21, 0xF9, 0xF0, 0x1B, 0x86, 0x6E])
|
||||
let value = try! decoder.decode(Double.self, from: data)
|
||||
// 3.14159
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
### Swift Package Manager
|
||||
|
||||
Add the MessagePack package to your target dependencies in `Package.swift`:
|
||||
|
||||
```swift
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "YourProject",
|
||||
dependencies: [
|
||||
.package(
|
||||
url: "https://github.com/Flight-School/MessagePack",
|
||||
from: "1.2.3"
|
||||
),
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
Then run the `swift build` command to build your project.
|
||||
|
||||
### CocoaPods
|
||||
|
||||
You can install `MessagePack` via CocoaPods,
|
||||
by adding the following line to your `Podfile`:
|
||||
|
||||
```ruby
|
||||
pod 'MessagePack-FlightSchool', '~> 1.2.4'
|
||||
```
|
||||
|
||||
Run the `pod install` command to download the library
|
||||
and integrate it into your Xcode project.
|
||||
|
||||
> **Note**
|
||||
> The module name for this library is "MessagePack" ---
|
||||
> that is, to use it, you add `import MessagePack` to the top of your Swift code
|
||||
> just as you would by any other installation method.
|
||||
> The pod is called "MessagePack-FlightSchool"
|
||||
> because there's an existing pod with the name "MessagePack".
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
## Contact
|
||||
|
||||
Mattt ([@mattt](https://twitter.com/mattt))
|
||||
|
||||
[build status]: https://github.com/Flight-School/MessagePack/actions?query=workflow%3ACI
|
||||
[build status badge]: https://github.com/Flight-School/MessagePack/workflows/CI/badge.svg
|
||||
28
lib/MessagePack/Sources/MessagePack/AnyCodingKey.swift
Normal file
28
lib/MessagePack/Sources/MessagePack/AnyCodingKey.swift
Normal file
@@ -0,0 +1,28 @@
|
||||
struct AnyCodingKey: CodingKey, Equatable {
|
||||
var stringValue: String
|
||||
var intValue: Int?
|
||||
|
||||
init?(stringValue: String) {
|
||||
self.stringValue = stringValue
|
||||
self.intValue = nil
|
||||
}
|
||||
|
||||
init?(intValue: Int) {
|
||||
self.stringValue = "\(intValue)"
|
||||
self.intValue = intValue
|
||||
}
|
||||
|
||||
init<Key>(_ base: Key) where Key : CodingKey {
|
||||
if let intValue = base.intValue {
|
||||
self.init(intValue: intValue)!
|
||||
} else {
|
||||
self.init(stringValue: base.stringValue)!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension AnyCodingKey: Hashable {
|
||||
var hashValue: Int {
|
||||
return self.intValue?.hashValue ?? self.stringValue.hashValue
|
||||
}
|
||||
}
|
||||
44
lib/MessagePack/Sources/MessagePack/Box.swift
Normal file
44
lib/MessagePack/Sources/MessagePack/Box.swift
Normal file
@@ -0,0 +1,44 @@
|
||||
import Foundation
|
||||
|
||||
struct Box<Value> {
|
||||
let value: Value
|
||||
init(_ value: Value) {
|
||||
self.value = value
|
||||
}
|
||||
}
|
||||
|
||||
extension Box: Encodable where Value: Encodable {
|
||||
func encode(to encoder: Encoder) throws {
|
||||
try self.value.encode(to: encoder)
|
||||
}
|
||||
}
|
||||
|
||||
extension Box: Decodable where Value: Decodable {
|
||||
init(from decoder: Decoder) throws {
|
||||
self.init(try Value(from: decoder))
|
||||
}
|
||||
}
|
||||
|
||||
extension Box where Value == Data {
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.singleValueContainer()
|
||||
self.init(try container.decode(Value.self))
|
||||
}
|
||||
|
||||
func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.singleValueContainer()
|
||||
try container.encode(self.value)
|
||||
}
|
||||
}
|
||||
|
||||
extension Box where Value == Date {
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.singleValueContainer()
|
||||
self.init(try container.decode(Value.self))
|
||||
}
|
||||
|
||||
func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.singleValueContainer()
|
||||
try container.encode(self.value)
|
||||
}
|
||||
}
|
||||
60
lib/MessagePack/Sources/MessagePack/DataSpec.swift
Normal file
60
lib/MessagePack/Sources/MessagePack/DataSpec.swift
Normal file
@@ -0,0 +1,60 @@
|
||||
import Foundation
|
||||
|
||||
public struct DataSpec {
|
||||
let name: String
|
||||
let isObj: Bool
|
||||
let isArray: Bool
|
||||
let dataSpecBuilder: DataSpecBuilder?
|
||||
|
||||
init(_ name: String, _ isObj: Bool, _ isArray: Bool, _ dataSpecBuilder: DataSpecBuilder?) {
|
||||
self.name = name
|
||||
self.isObj = isObj
|
||||
self.isArray = isArray
|
||||
self.dataSpecBuilder = dataSpecBuilder
|
||||
}
|
||||
}
|
||||
|
||||
public class DataSpecBuilder : NSCopying {
|
||||
var specs: [DataSpec] = []
|
||||
var specsIterator: IndexingIterator<[DataSpec]>
|
||||
|
||||
init() {
|
||||
specsIterator = IndexingIterator(_elements: [])
|
||||
}
|
||||
|
||||
func append(_ name: String) -> DataSpecBuilder {
|
||||
return append(DataSpec(name, false, false, nil))
|
||||
}
|
||||
|
||||
func appendObj(_ name: String, _ dataSpecBuilder: DataSpecBuilder) -> DataSpecBuilder {
|
||||
return append(DataSpec(name, true, false, dataSpecBuilder))
|
||||
}
|
||||
|
||||
func appendArray(_ name: String) -> DataSpecBuilder {
|
||||
return append(DataSpec(name, false, true, nil))
|
||||
}
|
||||
|
||||
func appendArray(_ name: String, _ dataSpecBuilder: DataSpecBuilder) -> DataSpecBuilder {
|
||||
return append(DataSpec(name, false, true, dataSpecBuilder))
|
||||
}
|
||||
|
||||
func append(_ spec: DataSpec) -> DataSpecBuilder {
|
||||
specs.append(spec)
|
||||
return self
|
||||
}
|
||||
|
||||
func build() -> DataSpecBuilder {
|
||||
specsIterator = specs.makeIterator()
|
||||
return self
|
||||
}
|
||||
|
||||
func next() -> DataSpec {
|
||||
return specsIterator.next()!
|
||||
}
|
||||
|
||||
public func copy(with zone: NSZone? = nil) -> Any {
|
||||
let b = DataSpecBuilder()
|
||||
b.specs = specs
|
||||
return b.build()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
import Foundation
|
||||
|
||||
extension _MessagePackDecoder {
|
||||
final class KeyedContainer<Key> where Key: CodingKey {
|
||||
lazy var nestedContainers: [String: MessagePackDecodingContainer] = {
|
||||
guard let count = self.count else {
|
||||
return [:]
|
||||
}
|
||||
|
||||
var nestedContainers: [String: MessagePackDecodingContainer] = [:]
|
||||
|
||||
let unkeyedContainer = UnkeyedContainer(data: self.data.suffix(from: self.index), codingPath: self.codingPath, userInfo: self.userInfo)
|
||||
if currentSpec != nil && currentSpec!.isObj {
|
||||
unkeyedContainer.count = count
|
||||
} else {
|
||||
unkeyedContainer.count = count * 2
|
||||
}
|
||||
|
||||
do {
|
||||
var iterator = unkeyedContainer.nestedContainers.makeIterator()
|
||||
|
||||
for _ in 0..<count {
|
||||
var key: String = ""
|
||||
if currentSpec == nil || !currentSpec!.isObj {
|
||||
guard let keyContainer = iterator.next() as? _MessagePackDecoder.SingleValueContainer else {
|
||||
fatalError() // FIXME
|
||||
}
|
||||
|
||||
key = try keyContainer.decode(String.self)
|
||||
}
|
||||
|
||||
guard let container = iterator.next() else {
|
||||
fatalError() // FIXME
|
||||
}
|
||||
|
||||
|
||||
if currentSpec != nil && currentSpec!.isObj {
|
||||
key = container.currentSpec!.name
|
||||
}
|
||||
|
||||
container.codingPath += [AnyCodingKey(stringValue: key)!]
|
||||
nestedContainers[key] = container
|
||||
}
|
||||
} catch {
|
||||
fatalError("\(error)") // FIXME
|
||||
}
|
||||
|
||||
self.index = unkeyedContainer.index
|
||||
|
||||
return nestedContainers
|
||||
}()
|
||||
|
||||
lazy var count: Int? = {
|
||||
do {
|
||||
let format = try self.readByte()
|
||||
|
||||
if currentSpec != nil && currentSpec!.isObj && 0x90...0x9f ~= format {
|
||||
return Int(format & 0x0F)
|
||||
}
|
||||
|
||||
switch format {
|
||||
case 0x80...0x8f:
|
||||
return Int(format & 0x0F)
|
||||
case 0xde:
|
||||
return Int(try read(UInt16.self))
|
||||
case 0xdf:
|
||||
return Int(try read(UInt32.self))
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
} catch {
|
||||
return nil
|
||||
}
|
||||
}()
|
||||
|
||||
var data: Data
|
||||
var index: Data.Index
|
||||
var codingPath: [CodingKey]
|
||||
var userInfo: [CodingUserInfoKey: Any]
|
||||
var currentSpec: DataSpec?
|
||||
|
||||
func nestedCodingPath(forKey key: CodingKey) -> [CodingKey] {
|
||||
return self.codingPath + [key]
|
||||
}
|
||||
|
||||
init(data: Data, codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) {
|
||||
self.codingPath = codingPath
|
||||
self.userInfo = userInfo
|
||||
self.data = data
|
||||
self.index = self.data.startIndex
|
||||
}
|
||||
|
||||
func checkCanDecodeValue(forKey key: Key) throws {
|
||||
guard self.contains(key) else {
|
||||
let context = DecodingError.Context(codingPath: self.codingPath, debugDescription: "key not found: \(key)")
|
||||
throw DecodingError.keyNotFound(key, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension _MessagePackDecoder.KeyedContainer: KeyedDecodingContainerProtocol {
|
||||
var allKeys: [Key] {
|
||||
return self.nestedContainers.keys.map{ Key(stringValue: $0)! }
|
||||
}
|
||||
|
||||
func contains(_ key: Key) -> Bool {
|
||||
return self.nestedContainers.keys.contains(key.stringValue)
|
||||
}
|
||||
|
||||
func decodeNil(forKey key: Key) throws -> Bool {
|
||||
try checkCanDecodeValue(forKey: key)
|
||||
|
||||
let nestedContainer = self.nestedContainers[key.stringValue]
|
||||
|
||||
switch nestedContainer {
|
||||
case let singleValueContainer as _MessagePackDecoder.SingleValueContainer:
|
||||
return singleValueContainer.decodeNil()
|
||||
case is _MessagePackDecoder.UnkeyedContainer,
|
||||
is _MessagePackDecoder.KeyedContainer<AnyCodingKey>:
|
||||
return false
|
||||
default:
|
||||
let context = DecodingError.Context(codingPath: self.codingPath, debugDescription: "cannot decode nil for key: \(key)")
|
||||
throw DecodingError.typeMismatch(Any?.self, context)
|
||||
}
|
||||
}
|
||||
|
||||
func decode<T>(_ type: T.Type, forKey key: Key) throws -> T where T : Decodable {
|
||||
try checkCanDecodeValue(forKey: key)
|
||||
|
||||
let container = self.nestedContainers[key.stringValue]!
|
||||
let decoder = MessagePackDecoder()
|
||||
|
||||
if userInfo.keys.contains(MessagePackDecoder.dataSpecKey) {
|
||||
decoder.userInfo[MessagePackDecoder.dataSpecKey] = container.currentSpec!.dataSpecBuilder?.copy() as? DataSpecBuilder
|
||||
if container.currentSpec!.isArray {
|
||||
decoder.userInfo[MessagePackDecoder.isArrayDataSpecKey] = true
|
||||
}
|
||||
}
|
||||
|
||||
let value = try decoder.decode(T.self, from: container.data)
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func nestedUnkeyedContainer(forKey key: Key) throws -> UnkeyedDecodingContainer {
|
||||
try checkCanDecodeValue(forKey: key)
|
||||
|
||||
guard let unkeyedContainer = self.nestedContainers[key.stringValue] as? _MessagePackDecoder.UnkeyedContainer else {
|
||||
throw DecodingError.dataCorruptedError(forKey: key, in: self, debugDescription: "cannot decode nested container for key: \(key)")
|
||||
}
|
||||
|
||||
return unkeyedContainer
|
||||
}
|
||||
|
||||
func nestedContainer<NestedKey>(keyedBy type: NestedKey.Type, forKey key: Key) throws -> KeyedDecodingContainer<NestedKey> where NestedKey : CodingKey {
|
||||
try checkCanDecodeValue(forKey: key)
|
||||
|
||||
guard let keyedContainer = self.nestedContainers[key.stringValue] as? _MessagePackDecoder.KeyedContainer<NestedKey> else {
|
||||
throw DecodingError.dataCorruptedError(forKey: key, in: self, debugDescription: "cannot decode nested container for key: \(key)")
|
||||
}
|
||||
|
||||
return KeyedDecodingContainer(keyedContainer)
|
||||
}
|
||||
|
||||
func superDecoder() throws -> Decoder {
|
||||
return _MessagePackDecoder(data: self.data)
|
||||
}
|
||||
|
||||
func superDecoder(forKey key: Key) throws -> Decoder {
|
||||
let decoder = _MessagePackDecoder(data: self.data)
|
||||
decoder.codingPath = [key]
|
||||
|
||||
return decoder
|
||||
}
|
||||
}
|
||||
|
||||
extension _MessagePackDecoder.KeyedContainer: MessagePackDecodingContainer {}
|
||||
@@ -0,0 +1,168 @@
|
||||
import Foundation
|
||||
|
||||
/**
|
||||
An object that decodes instances of a data type from MessagePack objects.
|
||||
*/
|
||||
final public class MessagePackDecoder {
|
||||
public init() {}
|
||||
|
||||
/**
|
||||
A dictionary you use to customize the decoding process
|
||||
by providing contextual information.
|
||||
*/
|
||||
public var userInfo: [CodingUserInfoKey : Any] = [:]
|
||||
|
||||
/**
|
||||
Returns a value of the type you specify,
|
||||
decoded from a MessagePack object.
|
||||
|
||||
- Parameters:
|
||||
- type: The type of the value to decode
|
||||
from the supplied MessagePack object.
|
||||
- data: The MessagePack object to decode.
|
||||
- Throws: `DecodingError.dataCorrupted(_:)`
|
||||
if the data is not valid MessagePack.
|
||||
*/
|
||||
public func decode<T>(_ type: T.Type, from data: Data) throws -> T where T : Decodable {
|
||||
let decoder = _MessagePackDecoder(data: data)
|
||||
decoder.userInfo = self.userInfo
|
||||
decoder.userInfo[MessagePackDecoder.nonMatchingFloatDecodingStrategyKey] = nonMatchingFloatDecodingStrategy
|
||||
|
||||
switch type {
|
||||
case is Data.Type:
|
||||
let box = try Box<Data>(from: decoder)
|
||||
return box.value as! T
|
||||
case is Date.Type:
|
||||
let box = try Box<Date>(from: decoder)
|
||||
return box.value as! T
|
||||
default:
|
||||
return try T(from: decoder)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
The strategy used by a decoder when it encounters format mismatches for floating point values.
|
||||
*/
|
||||
public var nonMatchingFloatDecodingStrategy: NonMatchingFloatDecodingStrategy = .strict
|
||||
|
||||
/**
|
||||
The strategies for decoding floating point values when their format doesn't match.
|
||||
*/
|
||||
public enum NonMatchingFloatDecodingStrategy {
|
||||
|
||||
/// Throws a DecodingError.typeMismatch
|
||||
case strict
|
||||
|
||||
/// Performs a cast
|
||||
case cast
|
||||
}
|
||||
|
||||
internal static var nonMatchingFloatDecodingStrategyKey: CodingUserInfoKey {
|
||||
return CodingUserInfoKey(rawValue: "nonMatchingFloatDecodingStrategyKey")!
|
||||
}
|
||||
|
||||
static var dataSpecKey : CodingUserInfoKey {
|
||||
return CodingUserInfoKey(rawValue: "dataSpecKey")!
|
||||
}
|
||||
|
||||
static var isArrayDataSpecKey : CodingUserInfoKey {
|
||||
return CodingUserInfoKey(rawValue: "isArrayDataSpecKey")!
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - TopLevelDecoder
|
||||
|
||||
#if canImport(Combine)
|
||||
import Combine
|
||||
|
||||
extension MessagePackDecoder: TopLevelDecoder {
|
||||
public typealias Input = Data
|
||||
}
|
||||
#endif
|
||||
|
||||
// MARK: -
|
||||
|
||||
final class _MessagePackDecoder {
|
||||
var codingPath: [CodingKey] = []
|
||||
|
||||
var userInfo: [CodingUserInfoKey : Any] = [:]
|
||||
|
||||
var container: MessagePackDecodingContainer?
|
||||
fileprivate var data: Data
|
||||
|
||||
init(data: Data) {
|
||||
self.data = data
|
||||
}
|
||||
}
|
||||
|
||||
extension _MessagePackDecoder: Decoder {
|
||||
fileprivate func assertCanCreateContainer() {
|
||||
precondition(self.container == nil)
|
||||
}
|
||||
|
||||
func container<Key>(keyedBy type: Key.Type) -> KeyedDecodingContainer<Key> where Key : CodingKey {
|
||||
assertCanCreateContainer()
|
||||
|
||||
let container = KeyedContainer<Key>(data: self.data, codingPath: self.codingPath, userInfo: self.userInfo)
|
||||
|
||||
if userInfo.keys.contains(MessagePackDecoder.dataSpecKey) {
|
||||
container.currentSpec = DataSpec("", true, false, nil)
|
||||
}
|
||||
|
||||
self.container = container
|
||||
|
||||
return KeyedDecodingContainer(container)
|
||||
}
|
||||
|
||||
func unkeyedContainer() -> UnkeyedDecodingContainer {
|
||||
assertCanCreateContainer()
|
||||
|
||||
let container = UnkeyedContainer(data: self.data, codingPath: self.codingPath, userInfo: self.userInfo)
|
||||
self.container = container
|
||||
|
||||
return container
|
||||
}
|
||||
|
||||
func singleValueContainer() -> SingleValueDecodingContainer {
|
||||
assertCanCreateContainer()
|
||||
|
||||
let container = SingleValueContainer(data: self.data, codingPath: self.codingPath, userInfo: self.userInfo)
|
||||
self.container = container
|
||||
|
||||
return container
|
||||
}
|
||||
}
|
||||
|
||||
protocol MessagePackDecodingContainer: class {
|
||||
var codingPath: [CodingKey] { get set }
|
||||
|
||||
var userInfo: [CodingUserInfoKey : Any] { get }
|
||||
|
||||
var data: Data { get set }
|
||||
var index: Data.Index { get set }
|
||||
|
||||
var currentSpec: DataSpec? { get set }
|
||||
}
|
||||
|
||||
extension MessagePackDecodingContainer {
|
||||
func readByte() throws -> UInt8 {
|
||||
return try read(1).first!
|
||||
}
|
||||
|
||||
func read(_ length: Int) throws -> Data {
|
||||
let nextIndex = self.index.advanced(by: length)
|
||||
guard nextIndex <= self.data.endIndex else {
|
||||
let context = DecodingError.Context(codingPath: self.codingPath, debugDescription: "Unexpected end of data")
|
||||
throw DecodingError.dataCorrupted(context)
|
||||
}
|
||||
defer { self.index = nextIndex }
|
||||
|
||||
return self.data.subdata(in: self.index..<nextIndex)
|
||||
}
|
||||
|
||||
func read<T>(_ type: T.Type) throws -> T where T : FixedWidthInteger {
|
||||
let stride = MemoryLayout<T>.stride
|
||||
let bytes = [UInt8](try read(stride))
|
||||
return T(bytes: bytes)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
import Foundation
|
||||
|
||||
#if os(Linux)
|
||||
let NSEC_PER_SEC: UInt64 = 1000000000
|
||||
#endif
|
||||
|
||||
extension _MessagePackDecoder {
|
||||
final class SingleValueContainer {
|
||||
var codingPath: [CodingKey]
|
||||
var userInfo: [CodingUserInfoKey: Any]
|
||||
var data: Data
|
||||
var index: Data.Index
|
||||
var currentSpec: DataSpec?
|
||||
|
||||
init(data: Data, codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) {
|
||||
self.codingPath = codingPath
|
||||
self.userInfo = userInfo
|
||||
self.data = data
|
||||
self.index = self.data.startIndex
|
||||
}
|
||||
|
||||
func checkCanDecode<T>(_ type: T.Type, format: UInt8) throws {
|
||||
guard self.index <= self.data.endIndex else {
|
||||
throw DecodingError.dataCorruptedError(in: self, debugDescription: "Unexpected end of data")
|
||||
}
|
||||
|
||||
guard self.data[self.index] == format else {
|
||||
let context = DecodingError.Context(codingPath: self.codingPath, debugDescription: "Invalid format: \(format)")
|
||||
throw DecodingError.typeMismatch(type, context)
|
||||
}
|
||||
}
|
||||
|
||||
var nonMatchingFloatDecodingStrategy: MessagePackDecoder.NonMatchingFloatDecodingStrategy {
|
||||
return userInfo[MessagePackDecoder.nonMatchingFloatDecodingStrategyKey] as? MessagePackDecoder.NonMatchingFloatDecodingStrategy ?? .strict
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension _MessagePackDecoder.SingleValueContainer: SingleValueDecodingContainer {
|
||||
func decodeNil() -> Bool {
|
||||
let format = try? readByte()
|
||||
return format == 0xc0
|
||||
}
|
||||
|
||||
func decode(_ type: Bool.Type) throws -> Bool {
|
||||
let format = try readByte()
|
||||
switch format {
|
||||
case 0xc2: return false
|
||||
case 0xc3: return true
|
||||
default:
|
||||
let context = DecodingError.Context(codingPath: self.codingPath, debugDescription: "Invalid format: \(format)")
|
||||
throw DecodingError.typeMismatch(Bool.self, context)
|
||||
}
|
||||
}
|
||||
|
||||
func decode(_ type: String.Type) throws -> String {
|
||||
let length: Int
|
||||
let format = try readByte()
|
||||
switch format {
|
||||
case 0xa0...0xbf:
|
||||
length = Int(format - 0xa0)
|
||||
case 0xd9:
|
||||
length = Int(try read(UInt8.self))
|
||||
case 0xda:
|
||||
length = Int(try read(UInt16.self))
|
||||
case 0xdb:
|
||||
length = Int(try read(UInt32.self))
|
||||
default:
|
||||
throw DecodingError.dataCorruptedError(in: self, debugDescription: "Invalid format for String length: \(format)")
|
||||
}
|
||||
|
||||
let data = try read(length)
|
||||
guard let string = String(data: data, encoding: .utf8) else {
|
||||
let context = DecodingError.Context(codingPath: self.codingPath, debugDescription: "Couldn't decode string with UTF-8 encoding")
|
||||
throw DecodingError.dataCorrupted(context)
|
||||
}
|
||||
|
||||
return string
|
||||
}
|
||||
|
||||
func decode(_ type: Double.Type) throws -> Double {
|
||||
let format = try readByte()
|
||||
switch format {
|
||||
case 0xca:
|
||||
switch nonMatchingFloatDecodingStrategy {
|
||||
case .strict:
|
||||
break
|
||||
case .cast:
|
||||
let bitPattern = try read(UInt32.self)
|
||||
return Double(Float(bitPattern: bitPattern))
|
||||
}
|
||||
case 0xcb:
|
||||
let bitPattern = try read(UInt64.self)
|
||||
return Double(bitPattern: bitPattern)
|
||||
default:
|
||||
break
|
||||
}
|
||||
let context = DecodingError.Context(codingPath: self.codingPath, debugDescription: "Invalid format: \(format)")
|
||||
throw DecodingError.typeMismatch(Double.self, context)
|
||||
}
|
||||
|
||||
func decode(_ type: Float.Type) throws -> Float {
|
||||
let format = try readByte()
|
||||
switch format {
|
||||
case 0xca:
|
||||
let bitPattern = try read(UInt32.self)
|
||||
return Float(bitPattern: bitPattern)
|
||||
case 0xcb:
|
||||
switch nonMatchingFloatDecodingStrategy {
|
||||
case .strict:
|
||||
break
|
||||
case .cast:
|
||||
let bitPattern = try read(UInt64.self)
|
||||
return Float(Double(bitPattern: bitPattern))
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
let context = DecodingError.Context(codingPath: self.codingPath, debugDescription: "Invalid format: \(format)")
|
||||
throw DecodingError.typeMismatch(Float.self, context)
|
||||
}
|
||||
|
||||
func decode<T>(_ type: T.Type) throws -> T where T : BinaryInteger & Decodable {
|
||||
let format = try readByte()
|
||||
var t: T?
|
||||
|
||||
switch format {
|
||||
case 0x00...0x7f:
|
||||
t = T(format)
|
||||
case 0xcc:
|
||||
t = T(exactly: try read(UInt8.self))
|
||||
case 0xcd:
|
||||
t = T(exactly: try read(UInt16.self))
|
||||
case 0xce:
|
||||
t = T(exactly: try read(UInt32.self))
|
||||
case 0xcf:
|
||||
t = T(exactly: try read(UInt64.self))
|
||||
case 0xd0:
|
||||
t = T(exactly: try read(Int8.self))
|
||||
case 0xd1:
|
||||
t = T(exactly: try read(Int16.self))
|
||||
case 0xd2:
|
||||
t = T(exactly: try read(Int32.self))
|
||||
case 0xd3:
|
||||
t = T(exactly: try read(Int64.self))
|
||||
case 0xe0...0xff:
|
||||
t = T(exactly: Int8(bitPattern: format))
|
||||
default:
|
||||
t = nil
|
||||
}
|
||||
|
||||
guard let value = t else {
|
||||
let context = DecodingError.Context(codingPath: self.codingPath, debugDescription: "Invalid format: \(format)")
|
||||
throw DecodingError.typeMismatch(T.self, context)
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func decode(_ type: Date.Type) throws -> Date {
|
||||
let format = try readByte()
|
||||
|
||||
var seconds: TimeInterval
|
||||
var nanoseconds: TimeInterval
|
||||
|
||||
switch format {
|
||||
case 0xd6:
|
||||
_ = try read(Int8.self) // -1
|
||||
nanoseconds = 0
|
||||
seconds = TimeInterval(try read(UInt32.self))
|
||||
case 0xd7:
|
||||
_ = try read(Int8.self) // -1
|
||||
let bitPattern = try read(UInt64.self)
|
||||
nanoseconds = TimeInterval(UInt32(bitPattern >> 34))
|
||||
seconds = TimeInterval(UInt32(bitPattern & 0x03_FF_FF_FF_FF))
|
||||
case 0xc7:
|
||||
_ = try read(Int8.self) // 12
|
||||
_ = try read(Int8.self) // -1
|
||||
nanoseconds = TimeInterval(try read(UInt32.self))
|
||||
seconds = TimeInterval(try read(Int64.self))
|
||||
default:
|
||||
let context = DecodingError.Context(codingPath: self.codingPath, debugDescription: "Invalid format: \(format)")
|
||||
throw DecodingError.typeMismatch(Date.self, context)
|
||||
}
|
||||
|
||||
let timeInterval = TimeInterval(seconds) + nanoseconds / Double(NSEC_PER_SEC)
|
||||
|
||||
return Date(timeIntervalSince1970: timeInterval)
|
||||
}
|
||||
|
||||
func decode(_ type: Data.Type) throws -> Data {
|
||||
let length: Int
|
||||
let format = try readByte()
|
||||
switch format {
|
||||
case 0xc4:
|
||||
length = Int(try read(UInt8.self))
|
||||
case 0xc5:
|
||||
length = Int(try read(UInt16.self))
|
||||
case 0xc6:
|
||||
length = Int(try read(UInt32.self))
|
||||
default:
|
||||
throw DecodingError.dataCorruptedError(in: self, debugDescription: "Invalid format for Data length: \(format)")
|
||||
}
|
||||
|
||||
return self.data.subdata(in: self.index..<self.index.advanced(by: length))
|
||||
}
|
||||
|
||||
func decode<T>(_ type: T.Type) throws -> T where T : Decodable {
|
||||
switch type {
|
||||
case is Data.Type:
|
||||
return try decode(Data.self) as! T
|
||||
case is Date.Type:
|
||||
return try decode(Date.self) as! T
|
||||
default:
|
||||
let decoder = _MessagePackDecoder(data: self.data)
|
||||
let value = try T(from: decoder)
|
||||
if let nextIndex = decoder.container?.index {
|
||||
self.index = nextIndex
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension _MessagePackDecoder.SingleValueContainer: MessagePackDecodingContainer {}
|
||||
@@ -0,0 +1,235 @@
|
||||
import Foundation
|
||||
|
||||
extension _MessagePackDecoder {
|
||||
final class UnkeyedContainer {
|
||||
var codingPath: [CodingKey]
|
||||
|
||||
var nestedCodingPath: [CodingKey] {
|
||||
return self.codingPath + [AnyCodingKey(intValue: self.count ?? 0)!]
|
||||
}
|
||||
|
||||
var userInfo: [CodingUserInfoKey: Any]
|
||||
|
||||
var data: Data
|
||||
var index: Data.Index
|
||||
var currentSpec: DataSpec?
|
||||
|
||||
lazy var count: Int? = {
|
||||
do {
|
||||
let format = try self.readByte()
|
||||
switch format {
|
||||
case 0x90...0x9f:
|
||||
return Int(format & 0x0F)
|
||||
case 0xdc:
|
||||
return Int(try read(UInt16.self))
|
||||
case 0xdd:
|
||||
return Int(try read(UInt32.self))
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
} catch {
|
||||
return nil
|
||||
}
|
||||
}()
|
||||
|
||||
var currentIndex: Int = 0
|
||||
|
||||
lazy var nestedContainers: [MessagePackDecodingContainer] = {
|
||||
guard let count = self.count else {
|
||||
return []
|
||||
}
|
||||
|
||||
var nestedContainers: [MessagePackDecodingContainer] = []
|
||||
|
||||
do {
|
||||
for _ in 0..<count {
|
||||
let container = try self.decodeContainer()
|
||||
nestedContainers.append(container)
|
||||
}
|
||||
} catch {
|
||||
fatalError("\(error)") // FIXME
|
||||
}
|
||||
|
||||
self.currentIndex = 0
|
||||
|
||||
return nestedContainers
|
||||
}()
|
||||
|
||||
init(data: Data, codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) {
|
||||
self.codingPath = codingPath
|
||||
self.userInfo = userInfo
|
||||
self.data = data
|
||||
self.index = self.data.startIndex
|
||||
}
|
||||
|
||||
var isAtEnd: Bool {
|
||||
guard let count = self.count else {
|
||||
return true
|
||||
}
|
||||
|
||||
return currentIndex >= count
|
||||
}
|
||||
|
||||
func checkCanDecodeValue() throws {
|
||||
guard !self.isAtEnd else {
|
||||
throw DecodingError.dataCorruptedError(in: self, debugDescription: "Unexpected end of data")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension _MessagePackDecoder.UnkeyedContainer: UnkeyedDecodingContainer {
|
||||
func decodeNil() throws -> Bool {
|
||||
try checkCanDecodeValue()
|
||||
defer { self.currentIndex += 1 }
|
||||
|
||||
let nestedContainer = self.nestedContainers[self.currentIndex]
|
||||
|
||||
switch nestedContainer {
|
||||
case let singleValueContainer as _MessagePackDecoder.SingleValueContainer:
|
||||
return singleValueContainer.decodeNil()
|
||||
case is _MessagePackDecoder.UnkeyedContainer,
|
||||
is _MessagePackDecoder.KeyedContainer<AnyCodingKey>:
|
||||
return false
|
||||
default:
|
||||
let context = DecodingError.Context(codingPath: self.codingPath, debugDescription: "cannot decode nil for index: \(self.currentIndex)")
|
||||
throw DecodingError.typeMismatch(Any?.self, context)
|
||||
}
|
||||
}
|
||||
|
||||
func decode<T>(_ type: T.Type) throws -> T where T : Decodable {
|
||||
try checkCanDecodeValue()
|
||||
defer { self.currentIndex += 1 }
|
||||
|
||||
if userInfo.keys.contains(MessagePackDecoder.isArrayDataSpecKey) {
|
||||
currentSpec = DataSpec("", false, true, (userInfo[MessagePackDecoder.dataSpecKey] as? DataSpecBuilder)?.copy() as? DataSpecBuilder)
|
||||
}
|
||||
|
||||
let container = self.nestedContainers[self.currentIndex]
|
||||
let decoder = MessagePackDecoder()
|
||||
|
||||
if userInfo.keys.contains(MessagePackDecoder.dataSpecKey) {
|
||||
decoder.userInfo[MessagePackDecoder.dataSpecKey] = (userInfo[MessagePackDecoder.dataSpecKey] as? DataSpecBuilder)?.copy() as? DataSpecBuilder
|
||||
}
|
||||
|
||||
let value = try decoder.decode(T.self, from: container.data)
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func nestedUnkeyedContainer() throws -> UnkeyedDecodingContainer {
|
||||
try checkCanDecodeValue()
|
||||
defer { self.currentIndex += 1 }
|
||||
|
||||
let container = self.nestedContainers[self.currentIndex] as! _MessagePackDecoder.UnkeyedContainer
|
||||
|
||||
return container
|
||||
}
|
||||
|
||||
func nestedContainer<NestedKey>(keyedBy type: NestedKey.Type) throws -> KeyedDecodingContainer<NestedKey> where NestedKey : CodingKey {
|
||||
try checkCanDecodeValue()
|
||||
defer { self.currentIndex += 1 }
|
||||
|
||||
let container = self.nestedContainers[self.currentIndex] as! _MessagePackDecoder.KeyedContainer<NestedKey>
|
||||
|
||||
return KeyedDecodingContainer(container)
|
||||
}
|
||||
|
||||
func superDecoder() throws -> Decoder {
|
||||
return _MessagePackDecoder(data: self.data)
|
||||
}
|
||||
}
|
||||
|
||||
extension _MessagePackDecoder.UnkeyedContainer {
|
||||
func decodeContainer() throws -> MessagePackDecodingContainer {
|
||||
try checkCanDecodeValue()
|
||||
defer { self.currentIndex += 1 }
|
||||
|
||||
let startIndex = self.index
|
||||
|
||||
var currDataSpec: DataSpec? = nil
|
||||
if currentSpec != nil && currentSpec!.isArray && currentSpec!.dataSpecBuilder != nil {
|
||||
currDataSpec = DataSpec("", true, false, currentSpec!.dataSpecBuilder!.copy() as? DataSpecBuilder)
|
||||
} else {
|
||||
let dataSpec = self.userInfo[MessagePackDecoder.dataSpecKey] as? DataSpecBuilder
|
||||
if let currDS = dataSpec?.next() {
|
||||
currDataSpec = DataSpec(currDS.name, currDS.isObj, currDS.isArray, currDS.dataSpecBuilder?.copy() as? DataSpecBuilder)
|
||||
}
|
||||
}
|
||||
|
||||
let length: Int
|
||||
let format = try self.readByte()
|
||||
switch format {
|
||||
case 0x00...0x7f,
|
||||
0xc0, 0xc2, 0xc3,
|
||||
0xe0...0xff:
|
||||
length = 0
|
||||
case 0xcc, 0xd0, 0xd4:
|
||||
length = 1
|
||||
case 0xcd, 0xd1, 0xd5:
|
||||
length = 2
|
||||
case 0xca, 0xce, 0xd2:
|
||||
length = 4
|
||||
case 0xcb, 0xcf, 0xd3:
|
||||
length = 8
|
||||
case 0xd6:
|
||||
length = 5
|
||||
case 0xd7:
|
||||
length = 9
|
||||
case 0xd8:
|
||||
length = 16
|
||||
case 0xa0...0xbf:
|
||||
length = Int(format - 0xa0)
|
||||
case 0xc4, 0xc7, 0xd9:
|
||||
length = Int(try read(UInt8.self))
|
||||
case 0xc5, 0xc8, 0xda:
|
||||
length = Int(try read(UInt16.self))
|
||||
case 0xc6, 0xc9, 0xdb:
|
||||
length = Int(try read(UInt32.self))
|
||||
case 0x80...0x8f, 0xde, 0xdf:
|
||||
let container = _MessagePackDecoder.KeyedContainer<AnyCodingKey>(data: self.data.suffix(from: startIndex), codingPath: self.nestedCodingPath, userInfo: self.userInfo)
|
||||
container.currentSpec = currDataSpec
|
||||
_ = container.nestedContainers // FIXME
|
||||
self.index = container.index
|
||||
|
||||
return container
|
||||
case 0x90...0x9f, 0xdc, 0xdd:
|
||||
if currDataSpec != nil && currDataSpec!.isObj {
|
||||
var objUserInfo = self.userInfo
|
||||
objUserInfo[MessagePackDecoder.dataSpecKey] = currDataSpec!.dataSpecBuilder!
|
||||
|
||||
let container = _MessagePackDecoder.KeyedContainer<AnyCodingKey>(data: self.data.suffix(from: startIndex), codingPath: self.nestedCodingPath, userInfo: objUserInfo)
|
||||
container.currentSpec = currDataSpec
|
||||
_ = container.nestedContainers // FIXME
|
||||
self.index = container.index
|
||||
|
||||
return container
|
||||
}
|
||||
|
||||
var arrUserInfo = self.userInfo
|
||||
if currDataSpec != nil && currDataSpec!.isArray {
|
||||
arrUserInfo[MessagePackDecoder.dataSpecKey] = currDataSpec!.dataSpecBuilder!
|
||||
}
|
||||
|
||||
let container = _MessagePackDecoder.UnkeyedContainer(data: self.data.suffix(from: startIndex), codingPath: self.nestedCodingPath, userInfo: arrUserInfo)
|
||||
container.currentSpec = currDataSpec
|
||||
_ = container.nestedContainers // FIXME
|
||||
|
||||
self.index = container.index
|
||||
|
||||
return container
|
||||
default:
|
||||
throw DecodingError.dataCorruptedError(in: self, debugDescription: "Invalid format: \(format)")
|
||||
}
|
||||
|
||||
let range: Range<Data.Index> = startIndex..<self.index.advanced(by: length)
|
||||
self.index = range.upperBound
|
||||
|
||||
let container = _MessagePackDecoder.SingleValueContainer(data: self.data.subdata(in: range), codingPath: self.codingPath, userInfo: self.userInfo)
|
||||
container.currentSpec = currDataSpec
|
||||
|
||||
return container
|
||||
}
|
||||
}
|
||||
|
||||
extension _MessagePackDecoder.UnkeyedContainer: MessagePackDecodingContainer {}
|
||||
@@ -0,0 +1,90 @@
|
||||
import Foundation
|
||||
|
||||
extension _MessagePackEncoder {
|
||||
final class KeyedContainer<Key> where Key: CodingKey {
|
||||
private var storage: [AnyCodingKey: _MessagePackEncodingContainer] = [:]
|
||||
|
||||
var codingPath: [CodingKey]
|
||||
var userInfo: [CodingUserInfoKey: Any]
|
||||
|
||||
func nestedCodingPath(forKey key: CodingKey) -> [CodingKey] {
|
||||
return self.codingPath + [key]
|
||||
}
|
||||
|
||||
init(codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) {
|
||||
self.codingPath = codingPath
|
||||
self.userInfo = userInfo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension _MessagePackEncoder.KeyedContainer: KeyedEncodingContainerProtocol {
|
||||
func encodeNil(forKey key: Key) throws {
|
||||
var container = self.nestedSingleValueContainer(forKey: key)
|
||||
try container.encodeNil()
|
||||
}
|
||||
|
||||
func encode<T>(_ value: T, forKey key: Key) throws where T : Encodable {
|
||||
var container = self.nestedSingleValueContainer(forKey: key)
|
||||
try container.encode(value)
|
||||
}
|
||||
|
||||
private func nestedSingleValueContainer(forKey key: Key) -> SingleValueEncodingContainer {
|
||||
let container = _MessagePackEncoder.SingleValueContainer(codingPath: self.nestedCodingPath(forKey: key), userInfo: self.userInfo)
|
||||
self.storage[AnyCodingKey(key)] = container
|
||||
return container
|
||||
}
|
||||
|
||||
func nestedUnkeyedContainer(forKey key: Key) -> UnkeyedEncodingContainer {
|
||||
let container = _MessagePackEncoder.UnkeyedContainer(codingPath: self.nestedCodingPath(forKey: key), userInfo: self.userInfo)
|
||||
self.storage[AnyCodingKey(key)] = container
|
||||
|
||||
return container
|
||||
}
|
||||
|
||||
func nestedContainer<NestedKey>(keyedBy keyType: NestedKey.Type, forKey key: Key) -> KeyedEncodingContainer<NestedKey> where NestedKey : CodingKey {
|
||||
let container = _MessagePackEncoder.KeyedContainer<NestedKey>(codingPath: self.nestedCodingPath(forKey: key), userInfo: self.userInfo)
|
||||
self.storage[AnyCodingKey(key)] = container
|
||||
|
||||
return KeyedEncodingContainer(container)
|
||||
}
|
||||
|
||||
func superEncoder() -> Encoder {
|
||||
fatalError("Unimplemented") // FIXME
|
||||
}
|
||||
|
||||
func superEncoder(forKey key: Key) -> Encoder {
|
||||
fatalError("Unimplemented") // FIXME
|
||||
}
|
||||
}
|
||||
|
||||
extension _MessagePackEncoder.KeyedContainer: _MessagePackEncodingContainer {
|
||||
var data: Data {
|
||||
var data = Data()
|
||||
|
||||
let length = storage.count
|
||||
if let uint16 = UInt16(exactly: length) {
|
||||
if length <= 15 {
|
||||
data.append(0x80 + UInt8(length))
|
||||
} else {
|
||||
data.append(0xde)
|
||||
data.append(contentsOf: uint16.bytes)
|
||||
}
|
||||
} else if let uint32 = UInt32(exactly: length) {
|
||||
data.append(0xdf)
|
||||
data.append(contentsOf: uint32.bytes)
|
||||
} else {
|
||||
fatalError()
|
||||
}
|
||||
|
||||
for (key, container) in self.storage {
|
||||
let keyContainer = _MessagePackEncoder.SingleValueContainer(codingPath: self.codingPath, userInfo: self.userInfo)
|
||||
try! keyContainer.encode(key.stringValue)
|
||||
data.append(keyContainer.data)
|
||||
|
||||
data.append(container.data)
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
import Foundation
|
||||
|
||||
/**
|
||||
An object that encodes instances of a data type as MessagePack objects.
|
||||
*/
|
||||
final public class MessagePackEncoder {
|
||||
public init() {}
|
||||
|
||||
/**
|
||||
A dictionary you use to customize the encoding process
|
||||
by providing contextual information.
|
||||
*/
|
||||
public var userInfo: [CodingUserInfoKey : Any] = [:]
|
||||
|
||||
/**
|
||||
Returns a MessagePack-encoded representation of the value you supply.
|
||||
|
||||
- Parameters:
|
||||
- value: The value to encode as MessagePack.
|
||||
- Throws: `EncodingError.invalidValue(_:_:)`
|
||||
if the value can't be encoded as a MessagePack object.
|
||||
*/
|
||||
public func encode<T>(_ value: T) throws -> Data where T : Encodable {
|
||||
let encoder = _MessagePackEncoder()
|
||||
encoder.userInfo = self.userInfo
|
||||
|
||||
switch value {
|
||||
case let data as Data:
|
||||
try Box<Data>(data).encode(to: encoder)
|
||||
case let date as Date:
|
||||
try Box<Date>(date).encode(to: encoder)
|
||||
default:
|
||||
try value.encode(to: encoder)
|
||||
}
|
||||
|
||||
return encoder.data
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - TopLevelEncoder
|
||||
|
||||
#if canImport(Combine)
|
||||
import Combine
|
||||
|
||||
extension MessagePackEncoder: TopLevelEncoder {
|
||||
public typealias Input = Data
|
||||
}
|
||||
#endif
|
||||
|
||||
// MARK: -
|
||||
|
||||
protocol _MessagePackEncodingContainer {
|
||||
var data: Data { get }
|
||||
}
|
||||
|
||||
class _MessagePackEncoder {
|
||||
var codingPath: [CodingKey] = []
|
||||
|
||||
var userInfo: [CodingUserInfoKey : Any] = [:]
|
||||
|
||||
fileprivate var container: _MessagePackEncodingContainer?
|
||||
|
||||
var data: Data {
|
||||
return container?.data ?? Data()
|
||||
}
|
||||
}
|
||||
|
||||
extension _MessagePackEncoder: Encoder {
|
||||
fileprivate func assertCanCreateContainer() {
|
||||
precondition(self.container == nil)
|
||||
}
|
||||
|
||||
func container<Key>(keyedBy type: Key.Type) -> KeyedEncodingContainer<Key> where Key : CodingKey {
|
||||
assertCanCreateContainer()
|
||||
|
||||
let container = KeyedContainer<Key>(codingPath: self.codingPath, userInfo: self.userInfo)
|
||||
self.container = container
|
||||
|
||||
return KeyedEncodingContainer(container)
|
||||
}
|
||||
|
||||
func unkeyedContainer() -> UnkeyedEncodingContainer {
|
||||
assertCanCreateContainer()
|
||||
|
||||
let container = UnkeyedContainer(codingPath: self.codingPath, userInfo: self.userInfo)
|
||||
self.container = container
|
||||
|
||||
return container
|
||||
}
|
||||
|
||||
func singleValueContainer() -> SingleValueEncodingContainer {
|
||||
assertCanCreateContainer()
|
||||
|
||||
let container = SingleValueContainer(codingPath: self.codingPath, userInfo: self.userInfo)
|
||||
self.container = container
|
||||
|
||||
return container
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
import Foundation
|
||||
|
||||
extension _MessagePackEncoder {
|
||||
final class SingleValueContainer {
|
||||
private var storage: Data = Data()
|
||||
|
||||
fileprivate var canEncodeNewValue = true
|
||||
fileprivate func checkCanEncode(value: Any?) throws {
|
||||
guard self.canEncodeNewValue else {
|
||||
let context = EncodingError.Context(codingPath: self.codingPath, debugDescription: "Attempt to encode value through single value container when previously value already encoded.")
|
||||
throw EncodingError.invalidValue(value as Any, context)
|
||||
}
|
||||
}
|
||||
|
||||
var codingPath: [CodingKey]
|
||||
var userInfo: [CodingUserInfoKey: Any]
|
||||
|
||||
init(codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) {
|
||||
self.codingPath = codingPath
|
||||
self.userInfo = userInfo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension _MessagePackEncoder.SingleValueContainer: SingleValueEncodingContainer {
|
||||
func encodeNil() throws {
|
||||
try checkCanEncode(value: nil)
|
||||
defer { self.canEncodeNewValue = false }
|
||||
|
||||
self.storage.append(0xc0)
|
||||
}
|
||||
|
||||
func encode(_ value: Bool) throws {
|
||||
try checkCanEncode(value: nil)
|
||||
defer { self.canEncodeNewValue = false }
|
||||
|
||||
switch value {
|
||||
case false:
|
||||
self.storage.append(0xc2)
|
||||
case true:
|
||||
self.storage.append(0xc3)
|
||||
}
|
||||
}
|
||||
|
||||
func encode(_ value: String) throws {
|
||||
try checkCanEncode(value: value)
|
||||
defer { self.canEncodeNewValue = false }
|
||||
|
||||
guard let data = value.data(using: .utf8) else {
|
||||
let context = EncodingError.Context(codingPath: self.codingPath, debugDescription: "Cannot encode string using UTF-8 encoding.")
|
||||
throw EncodingError.invalidValue(value, context)
|
||||
}
|
||||
|
||||
let length = data.count
|
||||
if let uint8 = UInt8(exactly: length) {
|
||||
if (uint8 <= 31) {
|
||||
self.storage.append(0xa0 + uint8)
|
||||
} else {
|
||||
self.storage.append(0xd9)
|
||||
self.storage.append(contentsOf: uint8.bytes)
|
||||
}
|
||||
} else if let uint16 = UInt16(exactly: length) {
|
||||
self.storage.append(0xda)
|
||||
self.storage.append(contentsOf: uint16.bytes)
|
||||
} else if let uint32 = UInt32(exactly: length) {
|
||||
self.storage.append(0xdb)
|
||||
self.storage.append(contentsOf: uint32.bytes)
|
||||
} else {
|
||||
let context = EncodingError.Context(codingPath: self.codingPath, debugDescription: "Cannot encode string with length \(length).")
|
||||
throw EncodingError.invalidValue(value, context)
|
||||
}
|
||||
|
||||
self.storage.append(data)
|
||||
}
|
||||
|
||||
func encode(_ value: Double) throws {
|
||||
try checkCanEncode(value: value)
|
||||
defer { self.canEncodeNewValue = false }
|
||||
|
||||
self.storage.append(0xcb)
|
||||
self.storage.append(contentsOf: value.bitPattern.bytes)
|
||||
}
|
||||
|
||||
func encode(_ value: Float) throws {
|
||||
try checkCanEncode(value: value)
|
||||
defer { self.canEncodeNewValue = false }
|
||||
|
||||
self.storage.append(0xca)
|
||||
self.storage.append(contentsOf: value.bitPattern.bytes)
|
||||
}
|
||||
|
||||
func encode<T>(_ value: T) throws where T : BinaryInteger & Encodable {
|
||||
try checkCanEncode(value: value)
|
||||
defer { self.canEncodeNewValue = false }
|
||||
|
||||
if value < 0 {
|
||||
if let int8 = Int8(exactly: value) {
|
||||
return try encode(int8)
|
||||
} else if let int16 = Int16(exactly: value) {
|
||||
return try encode(int16)
|
||||
} else if let int32 = Int32(exactly: value) {
|
||||
return try encode(int32)
|
||||
} else if let int64 = Int64(exactly: value) {
|
||||
return try encode(int64)
|
||||
}
|
||||
} else {
|
||||
if let uint8 = UInt8(exactly: value) {
|
||||
return try encode(uint8)
|
||||
} else if let uint16 = UInt16(exactly: value) {
|
||||
return try encode(uint16)
|
||||
} else if let uint32 = UInt32(exactly: value) {
|
||||
return try encode(uint32)
|
||||
} else if let uint64 = UInt64(exactly: value) {
|
||||
return try encode(uint64)
|
||||
}
|
||||
}
|
||||
|
||||
let context = EncodingError.Context(codingPath: self.codingPath, debugDescription: "Cannot encode integer \(value).")
|
||||
throw EncodingError.invalidValue(value, context)
|
||||
}
|
||||
|
||||
func encode(_ value: Int8) throws {
|
||||
try checkCanEncode(value: value)
|
||||
defer { self.canEncodeNewValue = false }
|
||||
|
||||
if (value >= 0 && value <= 127) {
|
||||
self.storage.append(UInt8(value))
|
||||
} else if (value < 0 && value >= -31) {
|
||||
self.storage.append(0xe0 + (0x1f & UInt8(truncatingIfNeeded: value)))
|
||||
} else {
|
||||
self.storage.append(0xd0)
|
||||
self.storage.append(contentsOf: value.bytes)
|
||||
}
|
||||
}
|
||||
|
||||
func encode(_ value: Int16) throws {
|
||||
try checkCanEncode(value: value)
|
||||
defer { self.canEncodeNewValue = false }
|
||||
|
||||
self.storage.append(0xd1)
|
||||
self.storage.append(contentsOf: value.bytes)
|
||||
}
|
||||
|
||||
func encode(_ value: Int32) throws {
|
||||
try checkCanEncode(value: value)
|
||||
defer { self.canEncodeNewValue = false }
|
||||
|
||||
self.storage.append(0xd2)
|
||||
self.storage.append(contentsOf: value.bytes)
|
||||
}
|
||||
|
||||
func encode(_ value: Int64) throws {
|
||||
try checkCanEncode(value: value)
|
||||
defer { self.canEncodeNewValue = false }
|
||||
|
||||
self.storage.append(0xd3)
|
||||
self.storage.append(contentsOf: value.bytes)
|
||||
}
|
||||
|
||||
func encode(_ value: UInt8) throws {
|
||||
try checkCanEncode(value: value)
|
||||
defer { self.canEncodeNewValue = false }
|
||||
|
||||
if (value <= 127) {
|
||||
self.storage.append(value)
|
||||
} else {
|
||||
self.storage.append(0xcc)
|
||||
self.storage.append(contentsOf: value.bytes)
|
||||
}
|
||||
}
|
||||
|
||||
func encode(_ value: UInt16) throws {
|
||||
try checkCanEncode(value: value)
|
||||
defer { self.canEncodeNewValue = false }
|
||||
|
||||
self.storage.append(0xcd)
|
||||
self.storage.append(contentsOf: value.bytes)
|
||||
}
|
||||
|
||||
func encode(_ value: UInt32) throws {
|
||||
try checkCanEncode(value: value)
|
||||
defer { self.canEncodeNewValue = false }
|
||||
|
||||
self.storage.append(0xce)
|
||||
self.storage.append(contentsOf: value.bytes)
|
||||
}
|
||||
|
||||
func encode(_ value: UInt64) throws {
|
||||
try checkCanEncode(value: value)
|
||||
defer { self.canEncodeNewValue = false }
|
||||
|
||||
self.storage.append(0xcf)
|
||||
self.storage.append(contentsOf: value.bytes)
|
||||
}
|
||||
|
||||
func encode(_ value: Date) throws {
|
||||
try checkCanEncode(value: value)
|
||||
defer { self.canEncodeNewValue = false }
|
||||
|
||||
let timeInterval = value.timeIntervalSince1970
|
||||
let (integral, fractional) = modf(timeInterval)
|
||||
|
||||
let seconds = Int64(integral)
|
||||
let nanoseconds = UInt32(fractional * Double(NSEC_PER_SEC))
|
||||
|
||||
if seconds < 0 || seconds > UInt32.max {
|
||||
self.storage.append(0xc7)
|
||||
self.storage.append(0x0C)
|
||||
self.storage.append(0xFF)
|
||||
self.storage.append(contentsOf: nanoseconds.bytes)
|
||||
self.storage.append(contentsOf: seconds.bytes)
|
||||
} else if nanoseconds > 0 {
|
||||
self.storage.append(0xd7)
|
||||
self.storage.append(0xFF)
|
||||
self.storage.append(contentsOf: ((UInt64(nanoseconds) << 34) + UInt64(seconds)).bytes)
|
||||
} else {
|
||||
self.storage.append(0xd6)
|
||||
self.storage.append(0xFF)
|
||||
self.storage.append(contentsOf: UInt32(seconds).bytes)
|
||||
}
|
||||
}
|
||||
|
||||
func encode(_ value: Data) throws {
|
||||
let length = value.count
|
||||
if let uint8 = UInt8(exactly: length) {
|
||||
self.storage.append(0xc4)
|
||||
self.storage.append(uint8)
|
||||
self.storage.append(value)
|
||||
} else if let uint16 = UInt16(exactly: length) {
|
||||
self.storage.append(0xc5)
|
||||
self.storage.append(contentsOf: uint16.bytes)
|
||||
self.storage.append(value)
|
||||
} else if let uint32 = UInt32(exactly: length) {
|
||||
self.storage.append(0xc6)
|
||||
self.storage.append(contentsOf: uint32.bytes)
|
||||
self.storage.append(value)
|
||||
} else {
|
||||
let context = EncodingError.Context(codingPath: self.codingPath, debugDescription: "Cannot encode data of length \(value.count).")
|
||||
throw EncodingError.invalidValue(value, context)
|
||||
}
|
||||
}
|
||||
|
||||
func encode<T>(_ value: T) throws where T : Encodable {
|
||||
try checkCanEncode(value: value)
|
||||
defer { self.canEncodeNewValue = false }
|
||||
|
||||
switch value {
|
||||
case let data as Data:
|
||||
try self.encode(data)
|
||||
case let date as Date:
|
||||
try self.encode(date)
|
||||
default:
|
||||
let encoder = _MessagePackEncoder()
|
||||
try value.encode(to: encoder)
|
||||
self.storage.append(encoder.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension _MessagePackEncoder.SingleValueContainer: _MessagePackEncodingContainer {
|
||||
var data: Data {
|
||||
return storage
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
import Foundation
|
||||
|
||||
extension _MessagePackEncoder {
|
||||
final class UnkeyedContainer {
|
||||
private var storage: [_MessagePackEncodingContainer] = []
|
||||
|
||||
var count: Int {
|
||||
return storage.count
|
||||
}
|
||||
|
||||
var codingPath: [CodingKey]
|
||||
|
||||
var nestedCodingPath: [CodingKey] {
|
||||
return self.codingPath + [AnyCodingKey(intValue: self.count)!]
|
||||
}
|
||||
|
||||
var userInfo: [CodingUserInfoKey: Any]
|
||||
|
||||
init(codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) {
|
||||
self.codingPath = codingPath
|
||||
self.userInfo = userInfo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension _MessagePackEncoder.UnkeyedContainer: UnkeyedEncodingContainer {
|
||||
func encodeNil() throws {
|
||||
var container = self.nestedSingleValueContainer()
|
||||
try container.encodeNil()
|
||||
}
|
||||
|
||||
func encode<T>(_ value: T) throws where T : Encodable {
|
||||
var container = self.nestedSingleValueContainer()
|
||||
try container.encode(value)
|
||||
}
|
||||
|
||||
private func nestedSingleValueContainer() -> SingleValueEncodingContainer {
|
||||
let container = _MessagePackEncoder.SingleValueContainer(codingPath: self.nestedCodingPath, userInfo: self.userInfo)
|
||||
self.storage.append(container)
|
||||
|
||||
return container
|
||||
}
|
||||
|
||||
func nestedContainer<NestedKey>(keyedBy keyType: NestedKey.Type) -> KeyedEncodingContainer<NestedKey> where NestedKey : CodingKey {
|
||||
let container = _MessagePackEncoder.KeyedContainer<NestedKey>(codingPath: self.nestedCodingPath, userInfo: self.userInfo)
|
||||
self.storage.append(container)
|
||||
|
||||
return KeyedEncodingContainer(container)
|
||||
}
|
||||
|
||||
func nestedUnkeyedContainer() -> UnkeyedEncodingContainer {
|
||||
let container = _MessagePackEncoder.UnkeyedContainer(codingPath: self.nestedCodingPath, userInfo: self.userInfo)
|
||||
self.storage.append(container)
|
||||
|
||||
return container
|
||||
}
|
||||
|
||||
func superEncoder() -> Encoder {
|
||||
fatalError("Unimplemented") // FIXME
|
||||
}
|
||||
}
|
||||
|
||||
extension _MessagePackEncoder.UnkeyedContainer: _MessagePackEncodingContainer {
|
||||
var data: Data {
|
||||
var data = Data()
|
||||
|
||||
let length = storage.count
|
||||
if let uint16 = UInt16(exactly: length) {
|
||||
if uint16 <= 15 {
|
||||
data.append(UInt8(0x90 + uint16))
|
||||
} else {
|
||||
data.append(0xdc)
|
||||
data.append(contentsOf: uint16.bytes)
|
||||
}
|
||||
} else if let uint32 = UInt32(exactly: length) {
|
||||
data.append(0xdd)
|
||||
data.append(contentsOf: uint32.bytes)
|
||||
} else {
|
||||
fatalError()
|
||||
}
|
||||
|
||||
for container in storage {
|
||||
data.append(container.data)
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
extension FixedWidthInteger {
|
||||
init(bytes: [UInt8]) {
|
||||
self = bytes.withUnsafeBufferPointer {
|
||||
$0.baseAddress!.withMemoryRebound(to: Self.self, capacity: 1) {
|
||||
$0.pointee
|
||||
}
|
||||
}.bigEndian
|
||||
}
|
||||
|
||||
var bytes: [UInt8] {
|
||||
let capacity = MemoryLayout<Self>.size
|
||||
var mutableValue = self.bigEndian
|
||||
return withUnsafePointer(to: &mutableValue) {
|
||||
return $0.withMemoryRebound(to: UInt8.self, capacity: capacity) {
|
||||
return Array(UnsafeBufferPointer(start: $0, count: capacity))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
8
lib/MessagePack/Tests/LinuxMain.swift
Normal file
8
lib/MessagePack/Tests/LinuxMain.swift
Normal file
@@ -0,0 +1,8 @@
|
||||
import XCTest
|
||||
@testable import MessagePackTests
|
||||
|
||||
XCTMain([
|
||||
testCase(MessagePackDecodingTests.allTests),
|
||||
testCase(MessagePackEncodingTests.allTests),
|
||||
testCase(MessagePackRoundTripTests.allTests),
|
||||
])
|
||||
63
lib/MessagePack/Tests/MessagePackTests/Airport.swift
Normal file
63
lib/MessagePack/Tests/MessagePackTests/Airport.swift
Normal file
@@ -0,0 +1,63 @@
|
||||
struct Airport: Codable, Equatable {
|
||||
let name: String
|
||||
let iata: String
|
||||
let icao: String
|
||||
let coordinates: [Double]
|
||||
|
||||
struct Runway: Codable, Equatable {
|
||||
enum Surface: String, Codable, Equatable {
|
||||
case rigid, flexible, gravel, sealed, unpaved, other
|
||||
}
|
||||
|
||||
let direction: String
|
||||
let distance: Int
|
||||
let surface: Surface
|
||||
}
|
||||
|
||||
let runways: [Runway]
|
||||
|
||||
let instrumentApproachProcedures: [String]
|
||||
|
||||
static var example: Airport {
|
||||
return Airport(
|
||||
name: "Portland International Airport",
|
||||
iata: "PDX",
|
||||
icao: "KPDX",
|
||||
coordinates: [-122.5975,
|
||||
45.5886111111111],
|
||||
runways: [
|
||||
Airport.Runway(
|
||||
direction: "3/21",
|
||||
distance: 1829,
|
||||
surface: .flexible
|
||||
)
|
||||
],
|
||||
instrumentApproachProcedures: [
|
||||
"HI-ILS OR LOC RWY 28",
|
||||
"HI-ILS OR LOC/DME RWY 10",
|
||||
"ILS OR LOC RWY 10L",
|
||||
"ILS OR LOC RWY 10R",
|
||||
"ILS OR LOC RWY 28L",
|
||||
"ILS OR LOC RWY 28R",
|
||||
"ILS RWY 10R (SA CAT I)",
|
||||
"ILS RWY 10R (CAT II - III)",
|
||||
"RNAV (RNP) Y RWY 28L",
|
||||
"RNAV (RNP) Y RWY 28R",
|
||||
"RNAV (RNP) Z RWY 10L",
|
||||
"RNAV (RNP) Z RWY 10R",
|
||||
"RNAV (RNP) Z RWY 28L",
|
||||
"RNAV (RNP) Z RWY 28R",
|
||||
"RNAV (GPS) X RWY 28L",
|
||||
"RNAV (GPS) X RWY 28R",
|
||||
"RNAV (GPS) Y RWY 10L",
|
||||
"RNAV (GPS) Y RWY 10R",
|
||||
"LOC/DME RWY 21",
|
||||
"VOR-A",
|
||||
"HI-TACAN RWY 10",
|
||||
"TACAN RWY 28",
|
||||
"COLUMBIA VISUAL RWY 10L/",
|
||||
"MILL VISUAL RWY 28L/R"
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
import XCTest
|
||||
@testable import MessagePack
|
||||
|
||||
class MessagePackDecodingTests: XCTestCase {
|
||||
var decoder: MessagePackDecoder!
|
||||
|
||||
override func setUp() {
|
||||
self.decoder = MessagePackDecoder()
|
||||
}
|
||||
|
||||
func assertTypeMismatch<T>(_ expression: @autoclosure () throws -> T,
|
||||
_ message: @autoclosure () -> String = "",
|
||||
file: StaticString = #file,
|
||||
line: UInt = #line) -> Any.Type? {
|
||||
var error: Error?
|
||||
XCTAssertThrowsError(expression, message,
|
||||
file: file, line: line) {
|
||||
error = $0
|
||||
}
|
||||
guard case .typeMismatch(let type, _) = error as? DecodingError else {
|
||||
XCTFail(file: file, line: line)
|
||||
return nil
|
||||
}
|
||||
return type
|
||||
}
|
||||
|
||||
func testDecodeNil() {
|
||||
let data = Data(bytes: [0xC0])
|
||||
let value = try! decoder.decode(Int?.self, from: data)
|
||||
XCTAssertNil(value)
|
||||
}
|
||||
|
||||
func testDecodeFalse() {
|
||||
let data = Data(bytes: [0xc2])
|
||||
let value = try! decoder.decode(Bool.self, from: data)
|
||||
XCTAssertEqual(value, false)
|
||||
}
|
||||
|
||||
func testDecodeTrue() {
|
||||
let data = Data(bytes: [0xc3])
|
||||
let value = try! decoder.decode(Bool.self, from: data)
|
||||
XCTAssertEqual(value, true)
|
||||
}
|
||||
|
||||
func testDecodeInt() {
|
||||
let data = Data(bytes: [0x2A])
|
||||
let value = try! decoder.decode(Int.self, from: data)
|
||||
XCTAssertEqual(value, 42)
|
||||
}
|
||||
|
||||
func testDecodeNegativeInt() {
|
||||
let data = Data(bytes: [0xFF])
|
||||
let value = try! decoder.decode(Int.self, from: data)
|
||||
XCTAssertEqual(value, -1)
|
||||
}
|
||||
|
||||
func testDecodeUInt() {
|
||||
let data = Data(bytes: [0xCC, 0x80])
|
||||
let value = try! decoder.decode(Int.self, from: data)
|
||||
XCTAssertEqual(value, 128)
|
||||
}
|
||||
|
||||
func testDecodeFloat() {
|
||||
let data = Data(bytes: [0xCA, 0x40, 0x48, 0xF5, 0xC3])
|
||||
let value = try! decoder.decode(Float.self, from: data)
|
||||
XCTAssertEqual(value, 3.14)
|
||||
}
|
||||
|
||||
func testDecodeFloatToDouble() {
|
||||
let data = Data(bytes: [0xCA, 0x40, 0x48, 0xF5, 0xC3])
|
||||
let type = assertTypeMismatch(try decoder.decode(Double.self, from: data))
|
||||
XCTAssertTrue(type is Double.Type)
|
||||
decoder.nonMatchingFloatDecodingStrategy = .cast
|
||||
let value = try! decoder.decode(Double.self, from: data)
|
||||
XCTAssertEqual(value, 3.14, accuracy: 1e-6)
|
||||
}
|
||||
|
||||
func testDecodeDouble() {
|
||||
let data = Data(bytes: [0xCB, 0x40, 0x09, 0x21, 0xF9, 0xF0, 0x1B, 0x86, 0x6E])
|
||||
let value = try! decoder.decode(Double.self, from: data)
|
||||
XCTAssertEqual(value, 3.14159)
|
||||
}
|
||||
|
||||
func testDecodeDoubleToFloat() {
|
||||
let data = Data(bytes: [0xCB, 0x40, 0x09, 0x21, 0xF9, 0xF0, 0x1B, 0x86, 0x6E])
|
||||
let type = assertTypeMismatch(try decoder.decode(Float.self, from: data))
|
||||
XCTAssertTrue(type is Float.Type)
|
||||
decoder.nonMatchingFloatDecodingStrategy = .cast
|
||||
let value = try! decoder.decode(Float.self, from: data)
|
||||
XCTAssertEqual(value, 3.14159)
|
||||
}
|
||||
|
||||
func testDecodeFixedArray() {
|
||||
let data = Data(bytes: [0x93, 0x01, 0x02, 0x03])
|
||||
let value = try! decoder.decode([Int].self, from: data)
|
||||
XCTAssertEqual(value, [1, 2, 3])
|
||||
}
|
||||
|
||||
func testDecodeVariableArray() {
|
||||
let data = Data(bytes: [0xdc] + [0x00, 0x10] + Array(0x01...0x10))
|
||||
let value = try! decoder.decode([Int].self, from: data)
|
||||
XCTAssertEqual(value, Array(1...16))
|
||||
}
|
||||
|
||||
func testDecodeFixedDictionary() {
|
||||
let data = Data(bytes: [0x83, 0xA1, 0x62, 0x02, 0xA1, 0x61, 0x01, 0xA1, 0x63, 0x03])
|
||||
let value = try! decoder.decode([String: Int].self, from: data)
|
||||
XCTAssertEqual(value, ["a": 1, "b": 2, "c": 3])
|
||||
}
|
||||
|
||||
func testDecodeData() {
|
||||
let data = Data(bytes: [0xC4, 0x05, 0x68, 0x65, 0x6C, 0x6C, 0x6F])
|
||||
let value = try! decoder.decode(Data.self, from: data)
|
||||
XCTAssertEqual(value, "hello".data(using: .utf8))
|
||||
}
|
||||
|
||||
func testDecodeDate() {
|
||||
let data = Data(bytes: [0xD6, 0xFF, 0x00, 0x00, 0x00, 0x01])
|
||||
let date = Date(timeIntervalSince1970: 1)
|
||||
let value = try! decoder.decode(Date.self, from: data)
|
||||
XCTAssertEqual(value, date)
|
||||
}
|
||||
|
||||
func testDecodeDistantPast() {
|
||||
let data = Data(bytes: [0xC7, 0x0C, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF1, 0x88, 0x6B, 0x66, 0x00])
|
||||
let date = Date.distantPast
|
||||
let value = try! decoder.decode(Date.self, from: data)
|
||||
XCTAssertEqual(value, date)
|
||||
}
|
||||
|
||||
func testDecodeDistantFuture() {
|
||||
let data = Data(bytes: [0xC7, 0x0C, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xEC, 0x31, 0x88, 0x00])
|
||||
let date = Date.distantFuture
|
||||
let value = try! decoder.decode(Date.self, from: data)
|
||||
XCTAssertEqual(value, date)
|
||||
}
|
||||
|
||||
func testDecodeArrayWithDate() {
|
||||
let data = Data(bytes: [0x91, 0xD6, 0xFF, 0x00, 0x00, 0x00, 0x01])
|
||||
let date = Date(timeIntervalSince1970: 1)
|
||||
let value = try! decoder.decode([Date].self, from: data)
|
||||
XCTAssertEqual(value, [date])
|
||||
}
|
||||
|
||||
func testDecodeDictionaryWithDate() {
|
||||
let data = Data(bytes: [0x81, 0xA1, 0x31, 0xD6, 0xFF, 0x00, 0x00, 0x00, 0x01])
|
||||
let date = Date(timeIntervalSince1970: 1)
|
||||
let value = try! decoder.decode([String: Date].self, from: data)
|
||||
XCTAssertEqual(value, ["1": date])
|
||||
}
|
||||
|
||||
func testDecodeBv() {
|
||||
let b64 = "lK50ZXN0aW5nIHN0cmluZyeSpnF3ZXF3ZagxMjNpY29uc5OU2SRlMTZkYTYwMi0zMjE1LTRiZDYtYjY5MC00Y2Q4NmEwZmU3NjSoQ2lwaGVyIDEBk61jaXBodXNlcm5hbWUxrWFkZmFmZHcyMzQxMzGSkblodHRwczovL3d3dy5nb29nbGUuY29tLmFykbVodHRwczovL3d3dy5hcHBsZS5jb22U2SRhNjExMWU2Ny1hMTMwLTRiM2ItODM5NS0xZjIzMDFjNjk3ZjeoQ2lwaGVyIDIBk6g0MzEzMjEzMatqbGpsbHl1bHVpecCU2SRiOGIwODM3MC0xNGU0LTQzZmUtYjBkOS04ZjJlMDlmODJkYzWoQ2lwaGVyIDMBk6twaW9waW9waXBpb6x6eGN6eHZ6eHZ4enaSkbdodHRwczovL3d3dy52aXNhLmNvbS5hcpG1aHR0cHM6Ly93d3cuZG9ja3MuY29t" // array mode with envData and ciphers
|
||||
|
||||
// let b64 = "hKFirnRlc3Rpbmcgc3RyaW5noWMnp2VudkRhdGGCpGJhc2WmcXdlcXdlpWljb25zqDEyM2ljb25zp2NpcGhlcnOThKJpZNkkMDA4YmE0NDctZjU0Mi00OWVjLWJjYTktMDMzZTQ2OTU0YTBipG5hbWWoQ2lwaGVyIDGkdHlwZQGlbG9naW6DqHVzZXJuYW1lrWNpcGh1c2VybmFtZTGkdG90cK1hZGZhZmR3MjM0MTMxpHVyaXOSgaN1cmm5aHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS5hcoGjdXJptWh0dHBzOi8vd3d3LmFwcGxlLmNvbYSiaWTZJDQ1ZTBhODJiLTgyZGQtNDJiZi05ODhhLTAyYTkyNGM4Yzg5M6RuYW1lqENpcGhlciAypHR5cGUBpWxvZ2lug6h1c2VybmFtZag0MzEzMjEzMaR0b3Rwq2psamxseXVsdWl5pHVyaXPAhKJpZNkkZTBjZWU5NDEtZDI1Ni00MjdiLWJkNWUtNDMxMmMwN2U1NDI5pG5hbWWoQ2lwaGVyIDOkdHlwZQGlbG9naW6DqHVzZXJuYW1lq3Bpb3Bpb3BpcGlvpHRvdHCsenhjenh2enh2eHp2pHVyaXOSgaN1cmm3aHR0cHM6Ly93d3cudmlzYS5jb20uYXKBo3VyabVodHRwczovL3d3dy5kb2Nrcy5jb20=" // dict mode with envData and ciphers
|
||||
|
||||
do {
|
||||
if let d = Data(base64Encoded: b64) {
|
||||
let decoder = MessagePackDecoder()
|
||||
decoder.userInfo[MessagePackDecoder.dataSpecKey] = DataSpecBuilder()
|
||||
.append("b")
|
||||
.append("c")
|
||||
.appendObj("envData", DataSpecBuilder()
|
||||
.append("base")
|
||||
.append("icons")
|
||||
.build())
|
||||
.appendArray("ciphers", DataSpecBuilder()
|
||||
.append("id")
|
||||
.append("name")
|
||||
.append("type")
|
||||
.appendObj("login", DataSpecBuilder()
|
||||
.append("username")
|
||||
.append("totp")
|
||||
.appendArray("uris", DataSpecBuilder()
|
||||
.append("uri")
|
||||
.build())
|
||||
.build())
|
||||
.build())
|
||||
.build()
|
||||
|
||||
let codTest = try decoder.decode(CodableTest.self, from: d)
|
||||
|
||||
XCTAssertEqual(codTest.b, "testing string")
|
||||
XCTAssertEqual(codTest.envData.base, "qweqwe")
|
||||
XCTAssertEqual(codTest.envData.icons, "123icons")
|
||||
XCTAssertTrue(codTest.ciphers!.count > 1)
|
||||
} else {
|
||||
XCTAssertEqual(1, 0)
|
||||
}
|
||||
} catch let error {
|
||||
XCTFail("E: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
static var allTests = [
|
||||
("testDecodeNil", testDecodeNil),
|
||||
("testDecodeFalse", testDecodeFalse),
|
||||
("testDecodeTrue", testDecodeTrue),
|
||||
("testDecodeInt", testDecodeInt),
|
||||
("testDecodeUInt", testDecodeUInt),
|
||||
("testDecodeFloat", testDecodeFloat),
|
||||
("testDecodeFloatToDouble", testDecodeFloatToDouble),
|
||||
("testDecodeDouble", testDecodeDouble),
|
||||
("testDecodeDoubleToFloat", testDecodeDoubleToFloat),
|
||||
("testDecodeFixedArray", testDecodeFixedArray),
|
||||
("testDecodeFixedDictionary", testDecodeFixedDictionary),
|
||||
("testDecodeData", testDecodeData),
|
||||
("testDecodeDistantPast", testDecodeDistantPast),
|
||||
("testDecodeDistantFuture", testDecodeDistantFuture),
|
||||
("testDecodeArrayWithDate", testDecodeArrayWithDate),
|
||||
("testDecodeDictionaryWithDate", testDecodeDictionaryWithDate),
|
||||
("testDecodeBv", testDecodeBv)
|
||||
]
|
||||
}
|
||||
|
||||
struct CodableTest : Codable {
|
||||
enum CodingKeys: Int, CodingKey {
|
||||
case b
|
||||
case c
|
||||
case envData
|
||||
case ciphers
|
||||
}
|
||||
|
||||
var b: String
|
||||
var c: Int
|
||||
var envData: EnvironmentUrlDataDto
|
||||
var ciphers: [Cipher]?
|
||||
|
||||
func printt() {
|
||||
print("B: \(b)")
|
||||
print("C: \(c)")
|
||||
print("ENVDATA")
|
||||
envData.printt()
|
||||
|
||||
if let cs = ciphers {
|
||||
print("CIPHERS")
|
||||
for c in cs {
|
||||
c.printt()
|
||||
print("----------------------------")
|
||||
}
|
||||
}
|
||||
|
||||
print("###########################")
|
||||
}
|
||||
}
|
||||
|
||||
struct EnvironmentUrlDataDto : Codable {
|
||||
var base: String?
|
||||
var icons: String?
|
||||
|
||||
func printt() {
|
||||
print("Base: \(base ?? "")")
|
||||
print("Icons: \(icons ?? "")")
|
||||
}
|
||||
}
|
||||
|
||||
struct Cipher:Identifiable,Codable{
|
||||
enum CodingKeys: Int, CodingKey {
|
||||
case id
|
||||
case name
|
||||
case login
|
||||
}
|
||||
|
||||
var id:String
|
||||
var name:String?
|
||||
var userId:String?
|
||||
var login:Login
|
||||
|
||||
func printt() {
|
||||
print("id: \(id)")
|
||||
print("name: \(name ?? "")")
|
||||
print("LOGIN")
|
||||
login.printt()
|
||||
}
|
||||
}
|
||||
|
||||
struct Login:Codable{
|
||||
var username:String?
|
||||
var totp:String?
|
||||
var uris:[LoginUri]?
|
||||
|
||||
func printt() {
|
||||
print("username: \(username ?? "")")
|
||||
print("totp: \(totp ?? "")")
|
||||
print("URIS")
|
||||
if let us = uris {
|
||||
for u in us {
|
||||
u.printt()
|
||||
print("----------------------------")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct LoginUri:Codable{
|
||||
var uri:String?
|
||||
|
||||
func printt() {
|
||||
print("Uri: \(uri ?? "")")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
import XCTest
|
||||
@testable import MessagePack
|
||||
|
||||
class MessagePackEncodingTests: XCTestCase {
|
||||
var encoder: MessagePackEncoder!
|
||||
|
||||
override func setUp() {
|
||||
self.encoder = MessagePackEncoder()
|
||||
}
|
||||
|
||||
func testEncodeNil() {
|
||||
let value = try! encoder.encode(nil as Int?)
|
||||
XCTAssertEqual(value, Data(bytes: [0xc0]))
|
||||
}
|
||||
|
||||
func testEncodeFalse() {
|
||||
let value = try! encoder.encode(false)
|
||||
XCTAssertEqual(value, Data(bytes: [0xc2]))
|
||||
}
|
||||
|
||||
func testEncodeTrue() {
|
||||
let value = try! encoder.encode(true)
|
||||
XCTAssertEqual(value, Data(bytes: [0xc3]))
|
||||
}
|
||||
|
||||
func testEncodeInt() {
|
||||
let value = try! encoder.encode(42 as Int)
|
||||
XCTAssertEqual(value, Data(bytes: [0x2A]))
|
||||
}
|
||||
|
||||
func testEncodeUInt() {
|
||||
let value = try! encoder.encode(128 as UInt)
|
||||
XCTAssertEqual(value, Data(bytes: [0xCC, 0x80]))
|
||||
}
|
||||
|
||||
func testEncodeFloat() {
|
||||
let value = try! encoder.encode(3.14 as Float)
|
||||
XCTAssertEqual(value, Data(bytes: [0xCA, 0x40, 0x48, 0xF5, 0xC3]))
|
||||
}
|
||||
|
||||
func testEncodeDouble() {
|
||||
let value = try! encoder.encode(3.14159 as Double)
|
||||
XCTAssertEqual(value, Data(bytes: [0xCB, 0x40, 0x09, 0x21, 0xF9, 0xF0, 0x1B, 0x86, 0x6E]))
|
||||
}
|
||||
|
||||
func testEncodeString() {
|
||||
let value = try! encoder.encode("hello")
|
||||
XCTAssertEqual(value, Data(bytes: [0xA5, 0x68, 0x65, 0x6C, 0x6C, 0x6F]))
|
||||
}
|
||||
|
||||
func testEncodeFixedArray() {
|
||||
let value = try! encoder.encode([1, 2, 3])
|
||||
XCTAssertEqual(value, Data(bytes: [0x93, 0x01, 0x02, 0x03]))
|
||||
}
|
||||
|
||||
func testEncodeVariableArray() {
|
||||
let value = try! encoder.encode(Array(1...16))
|
||||
XCTAssertEqual(value, Data(bytes: [0xdc] + [0x00, 0x10] + Array(0x01...0x10)))
|
||||
}
|
||||
|
||||
func testEncodeFixedDictionary() {
|
||||
let value = try! encoder.encode(["a": 1])
|
||||
XCTAssertEqual(value, Data(bytes: [0x81, 0xA1, 0x61, 0x01]))
|
||||
}
|
||||
|
||||
func testEncodeVariableDictionary() {
|
||||
let letters = "abcdefghijklmnopqrstuvwxyz".unicodeScalars
|
||||
let dictionary = Dictionary(uniqueKeysWithValues: zip(letters.map { String($0) }, 1...26))
|
||||
let value = try! encoder.encode(dictionary)
|
||||
XCTAssertEqual(value.count, 81)
|
||||
XCTAssert(value.starts(with: [0xde] + [0x00, 0x1A]))
|
||||
}
|
||||
|
||||
func testEncodeData() {
|
||||
let data = "hello".data(using: .utf8)
|
||||
let value = try! encoder.encode(data)
|
||||
XCTAssertEqual(value, Data(bytes: [0xC4, 0x05, 0x68, 0x65, 0x6C, 0x6C, 0x6F]))
|
||||
}
|
||||
|
||||
func testEncodeDate() {
|
||||
let date = Date(timeIntervalSince1970: 1)
|
||||
let value = try! encoder.encode(date)
|
||||
XCTAssertEqual(value, Data(bytes: [0xD6, 0xFF, 0x00, 0x00, 0x00, 0x01]))
|
||||
}
|
||||
|
||||
func testEncodeDistantPast() {
|
||||
let date = Date.distantPast
|
||||
let value = try! encoder.encode(date)
|
||||
XCTAssertEqual(value, Data(bytes: [0xC7, 0x0C, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF1, 0x88, 0x6B, 0x66, 0x00]))
|
||||
}
|
||||
|
||||
func testEncodeDistantFuture() {
|
||||
let date = Date.distantFuture
|
||||
let value = try! encoder.encode(date)
|
||||
XCTAssertEqual(value, Data(bytes: [0xC7, 0x0C, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xEC, 0x31, 0x88, 0x00]))
|
||||
}
|
||||
|
||||
func testEncodeArrayWithDate() {
|
||||
let date = Date(timeIntervalSince1970: 1)
|
||||
let value = try! encoder.encode([date])
|
||||
XCTAssertEqual(value, Data(bytes: [0x91, 0xD6, 0xFF, 0x00, 0x00, 0x00, 0x01]))
|
||||
}
|
||||
|
||||
func testEncodeDictionaryWithDate() {
|
||||
let date = Date(timeIntervalSince1970: 1)
|
||||
let value = try! encoder.encode(["1": date])
|
||||
XCTAssertEqual(value, Data(bytes: [0x81, 0xA1, 0x31, 0xD6, 0xFF, 0x00, 0x00, 0x00, 0x01]))
|
||||
}
|
||||
|
||||
static var allTests = [
|
||||
("testEncodeFalse", testEncodeFalse),
|
||||
("testEncodeTrue", testEncodeTrue),
|
||||
("testEncodeInt", testEncodeInt),
|
||||
("testEncodeUInt", testEncodeUInt),
|
||||
("testEncodeFloat", testEncodeFloat),
|
||||
("testEncodeDouble", testEncodeDouble),
|
||||
("testEncodeFixedArray", testEncodeFixedArray),
|
||||
("testEncodeVariableArray", testEncodeVariableArray),
|
||||
("testEncodeFixedDictionary", testEncodeFixedDictionary),
|
||||
("testEncodeVariableDictionary", testEncodeVariableDictionary),
|
||||
("testEncodeDate", testEncodeDate),
|
||||
("testEncodeDistantPast", testEncodeDistantPast),
|
||||
("testEncodeDistantFuture", testEncodeDistantFuture),
|
||||
("testEncodeArrayWithDate", testEncodeArrayWithDate),
|
||||
("testEncodeDictionaryWithDate", testEncodeDictionaryWithDate)
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import XCTest
|
||||
@testable import MessagePack
|
||||
|
||||
class MessagePackPerformanceTests: XCTestCase {
|
||||
var encoder: MessagePackEncoder!
|
||||
var decoder: MessagePackDecoder!
|
||||
|
||||
override func setUp() {
|
||||
self.encoder = MessagePackEncoder()
|
||||
self.decoder = MessagePackDecoder()
|
||||
}
|
||||
|
||||
func testPerformance() {
|
||||
let count = 100
|
||||
let values = [Airport](repeating: .example, count: count)
|
||||
|
||||
self.measure {
|
||||
let encoded = try! encoder.encode(values)
|
||||
let decoded = try! decoder.decode([Airport].self, from: encoded)
|
||||
XCTAssertEqual(decoded.count, count)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
import XCTest
|
||||
@testable import MessagePack
|
||||
|
||||
class MessagePackRoundTripTests: XCTestCase {
|
||||
var encoder: MessagePackEncoder!
|
||||
var decoder: MessagePackDecoder!
|
||||
|
||||
override func setUp() {
|
||||
self.encoder = MessagePackEncoder()
|
||||
self.decoder = MessagePackDecoder()
|
||||
}
|
||||
|
||||
func testRoundTripAirport() {
|
||||
let value = Airport.example
|
||||
let encoded = try! encoder.encode(value)
|
||||
let decoded = try! decoder.decode(Airport.self, from: encoded)
|
||||
|
||||
XCTAssertEqual(value.name, decoded.name)
|
||||
XCTAssertEqual(value.iata, decoded.iata)
|
||||
XCTAssertEqual(value.icao, decoded.icao)
|
||||
XCTAssertEqual(value.coordinates[0], decoded.coordinates[0], accuracy: 0.01)
|
||||
XCTAssertEqual(value.coordinates[1], decoded.coordinates[1], accuracy: 0.01)
|
||||
XCTAssertEqual(value.runways[0].direction, decoded.runways[0].direction)
|
||||
XCTAssertEqual(value.runways[0].distance, decoded.runways[0].distance)
|
||||
XCTAssertEqual(value.runways[0].surface, decoded.runways[0].surface)
|
||||
}
|
||||
|
||||
func testRoundTripParachutePack() {
|
||||
struct Parachute: Codable, Equatable {
|
||||
enum Canopy: String, Codable, Equatable {
|
||||
case round, cruciform, rogalloWing, annular, ramAir
|
||||
}
|
||||
|
||||
let canpoy: Canopy
|
||||
let surfaceArea: Double
|
||||
}
|
||||
|
||||
struct ParachutePack: Codable, Equatable {
|
||||
let main: Parachute?
|
||||
let reserve: Parachute?
|
||||
}
|
||||
|
||||
let value = ParachutePack(main: Parachute(canpoy: .ramAir, surfaceArea: 200), reserve: nil)
|
||||
let encoded = try! encoder.encode(value)
|
||||
let decoded = try! decoder.decode(ParachutePack.self, from: encoded)
|
||||
|
||||
XCTAssertEqual(value, decoded)
|
||||
}
|
||||
|
||||
func testRoundTripArray() {
|
||||
let count: UInt8 = 100
|
||||
var bytes: [UInt8] = [0xdc, 0x00, count]
|
||||
var encoded: [Int] = []
|
||||
for n in 1...count {
|
||||
bytes.append(n)
|
||||
encoded.append(Int(n))
|
||||
}
|
||||
|
||||
let data = Data(bytes: bytes)
|
||||
let decoded = try! decoder.decode([Int].self, from: data)
|
||||
XCTAssertEqual(encoded, decoded)
|
||||
}
|
||||
|
||||
func testRoundTripDictionary() {
|
||||
let (a, z): (UInt8, UInt8) = (0x61, 0x7a)
|
||||
var bytes: [UInt8] = [0xde, 0x00, 0x1A]
|
||||
var encoded: [String: Int] = [:]
|
||||
for n in a...z {
|
||||
bytes.append(contentsOf: [0xA1, n, n])
|
||||
encoded[String(Unicode.Scalar(n))] = Int(n)
|
||||
}
|
||||
|
||||
let data = Data(bytes: bytes)
|
||||
let decoded = try! decoder.decode([String: Int].self, from: data)
|
||||
XCTAssertEqual(encoded, decoded)
|
||||
}
|
||||
|
||||
func testRoundTripDate() {
|
||||
var bytes: [UInt8] = [0xD6, 0xFF]
|
||||
|
||||
let dateComponents = DateComponents(year: 2018, month: 4, day: 20)
|
||||
let encoded = Calendar.current.date(from: dateComponents)!
|
||||
|
||||
let secondsSince1970 = UInt32(encoded.timeIntervalSince1970)
|
||||
bytes.append(contentsOf: secondsSince1970.bytes)
|
||||
|
||||
let data = Data(bytes: bytes)
|
||||
let decoded = try! decoder.decode(Date.self, from: data)
|
||||
XCTAssertEqual(encoded, decoded)
|
||||
}
|
||||
|
||||
func testRoundTripDateWithNanoseconds() {
|
||||
let encoded = Date()
|
||||
let data = try! self.encoder.encode(encoded)
|
||||
let decoded = try! self.decoder.decode(Date.self, from: data)
|
||||
XCTAssertEqual(encoded.timeIntervalSinceReferenceDate, decoded.timeIntervalSinceReferenceDate, accuracy: 0.0001)
|
||||
}
|
||||
|
||||
static var allTests = [
|
||||
("testRoundTripAirport", testRoundTripAirport),
|
||||
("testRoundTripArray", testRoundTripArray),
|
||||
("testRoundTripDictionary", testRoundTripDictionary),
|
||||
("testRoundTripDate", testRoundTripDate),
|
||||
("testRoundTripDateWithNanoseconds", testRoundTripDateWithNanoseconds)
|
||||
]
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>Xamarin.AndroidX.Credentials</name>
|
||||
</assembly>
|
||||
<members>
|
||||
</members>
|
||||
</doc>
|
||||
Binary file not shown.
7
nuget.config
Normal file
7
nuget.config
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="MAUI Nightly builds" value="https://pkgs.dev.azure.com/xamarin/public/_packaging/maui-nightly/nuget/v3/index.json" />
|
||||
<add key="Local AndroidX Credentials" value="lib/android/Xamarin.AndroidX.Credentials" />
|
||||
</packageSources>
|
||||
</configuration>
|
||||
169
package-lock.json
generated
169
package-lock.json
generated
@@ -8,7 +8,7 @@
|
||||
"name": "bitwarden-mobile",
|
||||
"version": "0.0.0",
|
||||
"devDependencies": {
|
||||
"gh-pages": "^3.2.3"
|
||||
"gh-pages": "^6.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/array-union": {
|
||||
@@ -33,13 +33,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/async": {
|
||||
"version": "2.6.3",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
|
||||
"integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
|
||||
"version": "3.2.5",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",
|
||||
"integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.14"
|
||||
}
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
@@ -58,10 +56,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||
"dev": true
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
|
||||
"integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/commondir": {
|
||||
"version": "1.0.1",
|
||||
@@ -76,10 +78,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/email-addresses": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz",
|
||||
"integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==",
|
||||
"dev": true
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz",
|
||||
"integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
@@ -147,17 +150,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/fs-extra": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
|
||||
"version": "11.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
|
||||
"integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6 <7 || >=8"
|
||||
"node": ">=14.14"
|
||||
}
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
@@ -167,17 +171,18 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/gh-pages": {
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-3.2.3.tgz",
|
||||
"integrity": "sha512-jA1PbapQ1jqzacECfjUaO9gV8uBgU6XNMV0oXLtfCX3haGLe5Atq8BxlrADhbD6/UdG9j6tZLWAkAybndOXTJg==",
|
||||
"version": "6.1.1",
|
||||
"resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-6.1.1.tgz",
|
||||
"integrity": "sha512-upnohfjBwN5hBP9w2dPE7HO5JJTHzSGMV1JrLrHvNuqmjoYHg6TBrCcnEoorjG/e0ejbuvnwyKMdTyM40PEByw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"async": "^2.6.1",
|
||||
"commander": "^2.18.0",
|
||||
"email-addresses": "^3.0.1",
|
||||
"async": "^3.2.4",
|
||||
"commander": "^11.0.0",
|
||||
"email-addresses": "^5.0.0",
|
||||
"filenamify": "^4.3.0",
|
||||
"find-cache-dir": "^3.3.1",
|
||||
"fs-extra": "^8.1.0",
|
||||
"fs-extra": "^11.1.1",
|
||||
"globby": "^6.1.0"
|
||||
},
|
||||
"bin": {
|
||||
@@ -225,10 +230,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/graceful-fs": {
|
||||
"version": "4.2.8",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
|
||||
"integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
|
||||
"dev": true
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/inflight": {
|
||||
"version": "1.0.6",
|
||||
@@ -247,10 +253,14 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/jsonfile": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
@@ -267,12 +277,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/make-dir": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||
@@ -448,12 +452,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/universalify": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
|
||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 4.0.0"
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
@@ -480,13 +485,10 @@
|
||||
"dev": true
|
||||
},
|
||||
"async": {
|
||||
"version": "2.6.3",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
|
||||
"integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash": "^4.17.14"
|
||||
}
|
||||
"version": "3.2.5",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",
|
||||
"integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==",
|
||||
"dev": true
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.2",
|
||||
@@ -505,9 +507,9 @@
|
||||
}
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
|
||||
"integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
|
||||
"dev": true
|
||||
},
|
||||
"commondir": {
|
||||
@@ -523,9 +525,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"email-addresses": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz",
|
||||
"integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==",
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz",
|
||||
"integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==",
|
||||
"dev": true
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
@@ -573,14 +575,14 @@
|
||||
}
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
|
||||
"version": "11.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
|
||||
"integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"fs.realpath": {
|
||||
@@ -590,17 +592,17 @@
|
||||
"dev": true
|
||||
},
|
||||
"gh-pages": {
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-3.2.3.tgz",
|
||||
"integrity": "sha512-jA1PbapQ1jqzacECfjUaO9gV8uBgU6XNMV0oXLtfCX3haGLe5Atq8BxlrADhbD6/UdG9j6tZLWAkAybndOXTJg==",
|
||||
"version": "6.1.1",
|
||||
"resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-6.1.1.tgz",
|
||||
"integrity": "sha512-upnohfjBwN5hBP9w2dPE7HO5JJTHzSGMV1JrLrHvNuqmjoYHg6TBrCcnEoorjG/e0ejbuvnwyKMdTyM40PEByw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"async": "^2.6.1",
|
||||
"commander": "^2.18.0",
|
||||
"email-addresses": "^3.0.1",
|
||||
"async": "^3.2.4",
|
||||
"commander": "^11.0.0",
|
||||
"email-addresses": "^5.0.0",
|
||||
"filenamify": "^4.3.0",
|
||||
"find-cache-dir": "^3.3.1",
|
||||
"fs-extra": "^8.1.0",
|
||||
"fs-extra": "^11.1.1",
|
||||
"globby": "^6.1.0"
|
||||
}
|
||||
},
|
||||
@@ -632,9 +634,9 @@
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.8",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
|
||||
"integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
|
||||
"dev": true
|
||||
},
|
||||
"inflight": {
|
||||
@@ -654,12 +656,13 @@
|
||||
"dev": true
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
"graceful-fs": "^4.1.6",
|
||||
"universalify": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"locate-path": {
|
||||
@@ -671,12 +674,6 @@
|
||||
"p-locate": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"dev": true
|
||||
},
|
||||
"make-dir": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||
@@ -801,9 +798,9 @@
|
||||
}
|
||||
},
|
||||
"universalify": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
|
||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
||||
"dev": true
|
||||
},
|
||||
"wrappy": {
|
||||
|
||||
@@ -6,6 +6,6 @@
|
||||
"clean:l10n": "git push origin --delete l10n_master"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gh-pages": "^3.2.3"
|
||||
"gh-pages": "^6.1.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,307 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}</ProjectGuid>
|
||||
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<TemplateGuid>{c9e5eea5-ca05-42a1-839b-61506e0a37df}</TemplateGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>Bit.Droid</RootNamespace>
|
||||
<AssemblyName>BitwardenAndroid</AssemblyName>
|
||||
<AndroidApplication>True</AndroidApplication>
|
||||
<AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile>
|
||||
<AndroidResgenClass>Resource</AndroidResgenClass>
|
||||
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
|
||||
<MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
|
||||
<MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix>
|
||||
<TargetFrameworkVersion>v13.0</TargetFrameworkVersion>
|
||||
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>portable</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug</OutputPath>
|
||||
<DefineConstants>DEBUG;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>3</WarningLevel>
|
||||
<AndroidSupportedAbis />
|
||||
<JavaMaximumHeapSize>1G</JavaMaximumHeapSize>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AndroidManagedSymbols>true</AndroidManagedSymbols>
|
||||
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
|
||||
<AndroidSupportedAbis>armeabi-v7a;x86;x86_64;arm64-v8a</AndroidSupportedAbis>
|
||||
<JavaMaximumHeapSize>1G</JavaMaximumHeapSize>
|
||||
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
|
||||
<AndroidEnableProfiledAot>true</AndroidEnableProfiledAot>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'FDroid|AnyCPU'">
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<OutputPath>bin\FDroid\</OutputPath>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<DefineConstants>FDROID</DefineConstants>
|
||||
<AndroidSupportedAbis>armeabi-v7a;x86;x86_64;arm64-v8a</AndroidSupportedAbis>
|
||||
<JavaMaximumHeapSize>1G</JavaMaximumHeapSize>
|
||||
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
|
||||
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
|
||||
<AndroidEnableProfiledAot>true</AndroidEnableProfiledAot>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Mono.Android" />
|
||||
<Reference Include="Mono.Android.Export" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Net.Http" Condition="'$(Configuration)'=='FDroid'" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Plugin.CurrentActivity">
|
||||
<Version>2.1.0.4</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Portable.BouncyCastle">
|
||||
<Version>1.9.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.AndroidX.AppCompat" Version="1.5.1.1" />
|
||||
<PackageReference Include="Xamarin.AndroidX.AutoFill" Version="1.1.0.14" />
|
||||
<PackageReference Include="Xamarin.AndroidX.CardView" Version="1.0.0.17" />
|
||||
<PackageReference Include="Xamarin.AndroidX.Core" Version="1.9.0.1" />
|
||||
<PackageReference Include="Xamarin.AndroidX.Legacy.Support.V4" Version="1.0.0.15" />
|
||||
<PackageReference Include="Xamarin.AndroidX.MediaRouter" Version="1.3.1.1" />
|
||||
<PackageReference Include="Xamarin.Essentials">
|
||||
<Version>1.7.3</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Firebase.Messaging">
|
||||
<Version>123.0.8</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Google.Android.Material" Version="1.6.1.1" />
|
||||
<PackageReference Include="Xamarin.Google.Dagger" Version="2.41.0.2" />
|
||||
<PackageReference Include="Xamarin.GooglePlayServices.SafetyNet">
|
||||
<Version>118.0.1.2</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Accessibility\AccessibilityActivity.cs" />
|
||||
<Compile Include="Accessibility\AccessibilityHelpers.cs" />
|
||||
<Compile Include="Accessibility\Credentials.cs" />
|
||||
<Compile Include="Accessibility\AccessibilityService.cs" />
|
||||
<Compile Include="Accessibility\Browser.cs" />
|
||||
<Compile Include="Accessibility\NodeList.cs" />
|
||||
<Compile Include="Accessibility\KnownUsernameField.cs" />
|
||||
<Compile Include="Autofill\AutofillConstants.cs" />
|
||||
<Compile Include="Autofill\AutofillHelpers.cs" />
|
||||
<Compile Include="Autofill\AutofillService.cs" />
|
||||
<Compile Include="Autofill\AutofillExternalSelectionActivity.cs" />
|
||||
<Compile Include="Autofill\Field.cs" />
|
||||
<Compile Include="Autofill\FieldCollection.cs" />
|
||||
<Compile Include="Autofill\FilledItem.cs" />
|
||||
<Compile Include="Autofill\Parser.cs" />
|
||||
<Compile Include="Autofill\SavedItem.cs" />
|
||||
<Compile Include="Effects\FabShadowEffect.cs" />
|
||||
<Compile Include="Effects\FixedSizeEffect.cs" />
|
||||
<Compile Include="Effects\TabBarEffect.cs" />
|
||||
<Compile Include="Push\FirebaseMessagingService.cs" />
|
||||
<Compile Include="Receivers\ClearClipboardAlarmReceiver.cs" />
|
||||
<Compile Include="Receivers\RestrictionsChangedReceiver.cs" />
|
||||
<Compile Include="Receivers\EventUploadReceiver.cs" />
|
||||
<Compile Include="Receivers\PackageReplacedReceiver.cs" />
|
||||
<Compile Include="Renderers\ExtendedGridRenderer.cs" />
|
||||
<Compile Include="Renderers\ExtendedDatePickerRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomTabbedRenderer.cs" />
|
||||
<Compile Include="Renderers\ExtendedStackLayoutRenderer.cs" />
|
||||
<Compile Include="Renderers\ExtendedStepperRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomSwitchRenderer.cs" />
|
||||
<Compile Include="Renderers\ExtendedTimePickerRenderer.cs" />
|
||||
<Compile Include="Renderers\ExtendedSliderRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomEditorRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomPickerRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomEntryRenderer.cs" />
|
||||
<Compile Include="Renderers\CustomSearchBarRenderer.cs" />
|
||||
<Compile Include="Renderers\HybridWebViewRenderer.cs" />
|
||||
<Compile Include="Services\AndroidPushNotificationService.cs" />
|
||||
<Compile Include="Services\AndroidLogService.cs" />
|
||||
<Compile Include="MainApplication.cs" />
|
||||
<Compile Include="MainActivity.cs" />
|
||||
<Compile Include="Resources\Resource.designer.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Services\BiometricService.cs" />
|
||||
<Compile Include="Services\CryptoPrimitiveService.cs" />
|
||||
<Compile Include="Services\DeviceActionService.cs" />
|
||||
<Compile Include="Services\LocalizeService.cs" />
|
||||
<Compile Include="Tiles\AutofillTileService.cs" />
|
||||
<Compile Include="Tiles\GeneratorTileService.cs" />
|
||||
<Compile Include="Tiles\MyVaultTileService.cs" />
|
||||
<Compile Include="Utilities\AndroidHelpers.cs" />
|
||||
<Compile Include="Utilities\ThemeHelpers.cs" />
|
||||
<Compile Include="WebAuthCallbackActivity.cs" />
|
||||
<Compile Include="Renderers\SelectableLabelRenderer.cs" />
|
||||
<Compile Include="Services\ClipboardService.cs" />
|
||||
<Compile Include="Utilities\IntentExtensions.cs" />
|
||||
<Compile Include="Renderers\CustomPageRenderer.cs" />
|
||||
<Compile Include="Effects\NoEmojiKeyboardEffect.cs" />
|
||||
<Compile Include="Receivers\NotificationDismissReceiver.cs" />
|
||||
<Compile Include="Services\FileService.cs" />
|
||||
<Compile Include="Services\AutofillHandler.cs" />
|
||||
<Compile Include="Constants.cs" />
|
||||
<Compile Include="Effects\RemoveFontPaddingEffect.cs" />
|
||||
<Compile Include="Services\WatchDeviceService.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidAsset Include="Assets\bwi-font.ttf" />
|
||||
<AndroidAsset Include="Assets\RobotoMono_Regular.ttf" />
|
||||
<AndroidAsset Include="Assets\MaterialIcons_Regular.ttf" />
|
||||
<None Include="8bit.keystore.enc" />
|
||||
<GoogleServicesJson Include="google-services.json" />
|
||||
<GoogleServicesJson Include="google-services.json.enc" />
|
||||
<None Include="fdroid-keystore.jks.enc" />
|
||||
<AndroidNativeLibrary Include="lib\arm64-v8a\libargon2.so" />
|
||||
<AndroidNativeLibrary Include="lib\armeabi-v7a\libargon2.so" />
|
||||
<AndroidNativeLibrary Include="lib\x86\libargon2.so" />
|
||||
<AndroidNativeLibrary Include="lib\x86_64\libargon2.so" />
|
||||
<None Include="Properties\AndroidManifest.xml" />
|
||||
<None Include="upload-keystore.jks.enc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\logo_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable-hdpi\logo_white_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\logo_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\logo_white_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\logo_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\logo_white_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable\card.xml" />
|
||||
<AndroidResource Include="Resources\drawable\cog_environment.xml" />
|
||||
<AndroidResource Include="Resources\drawable\cog_settings.xml" />
|
||||
<AndroidResource Include="Resources\drawable\icon.xml" />
|
||||
<AndroidResource Include="Resources\drawable\ic_launcher_foreground.xml" />
|
||||
<AndroidResource Include="Resources\drawable\ic_launcher_monochrome.xml" />
|
||||
<AndroidResource Include="Resources\drawable\ic_warning.xml" />
|
||||
<AndroidResource Include="Resources\drawable\id.xml" />
|
||||
<AndroidResource Include="Resources\drawable\info.xml" />
|
||||
<AndroidResource Include="Resources\drawable\list_item_bg.xml" />
|
||||
<AndroidResource Include="Resources\drawable\lock.xml" />
|
||||
<AndroidResource Include="Resources\drawable\login.xml" />
|
||||
<AndroidResource Include="Resources\drawable\logo.xml" />
|
||||
<AndroidResource Include="Resources\drawable\logo_white.xml" />
|
||||
<AndroidResource Include="Resources\drawable\send.xml" />
|
||||
<AndroidResource Include="Resources\drawable\pencil.xml" />
|
||||
<AndroidResource Include="Resources\drawable\plus.xml" />
|
||||
<AndroidResource Include="Resources\drawable\generate.xml" />
|
||||
<AndroidResource Include="Resources\drawable\search.xml" />
|
||||
<AndroidResource Include="Resources\drawable\shield.xml" />
|
||||
<AndroidResource Include="Resources\drawable-v23\splash_screen.xml" />
|
||||
<AndroidResource Include="Resources\drawable-v23\splash_screen_dark.xml" />
|
||||
<AndroidResource Include="Resources\drawable\switch_thumb.xml" />
|
||||
<AndroidResource Include="Resources\layout\progress_dialog_layout.xml" />
|
||||
<AndroidResource Include="Resources\layout\Tabbar.axml" />
|
||||
<AndroidResource Include="Resources\layout\Toolbar.axml" />
|
||||
<AndroidResource Include="Resources\mipmap-anydpi-v26\ic_launcher.xml" />
|
||||
<AndroidResource Include="Resources\mipmap-anydpi-v26\ic_launcher_round.xml" />
|
||||
<AndroidResource Include="Resources\mipmap-hdpi\ic_launcher.png" />
|
||||
<AndroidResource Include="Resources\mipmap-hdpi\ic_launcher_round.png" />
|
||||
<AndroidResource Include="Resources\mipmap-mdpi\ic_launcher.png" />
|
||||
<AndroidResource Include="Resources\mipmap-mdpi\ic_launcher_round.png" />
|
||||
<AndroidResource Include="Resources\mipmap-xhdpi\ic_launcher.png" />
|
||||
<AndroidResource Include="Resources\mipmap-xhdpi\ic_launcher_round.png" />
|
||||
<AndroidResource Include="Resources\mipmap-xxhdpi\ic_launcher.png" />
|
||||
<AndroidResource Include="Resources\mipmap-xxhdpi\ic_launcher_round.png" />
|
||||
<AndroidResource Include="Resources\mipmap-xxxhdpi\ic_launcher.png" />
|
||||
<AndroidResource Include="Resources\mipmap-xxxhdpi\ic_launcher_round.png" />
|
||||
<AndroidResource Include="Resources\values-night\styles.xml" />
|
||||
<AndroidResource Include="Resources\values\styles.xml" />
|
||||
<AndroidResource Include="Resources\values\colors.xml" />
|
||||
<AndroidResource Include="Resources\values\manifest.xml" />
|
||||
<AndroidResource Include="Resources\values-v30\manifest.xml" />
|
||||
<AndroidResource Include="Resources\drawable-v26\splash_screen_round.xml" />
|
||||
<AndroidResource Include="Resources\drawable\logo_rounded.xml" />
|
||||
<AndroidResource Include="Resources\drawable-night-v26\splash_screen_round.xml" />
|
||||
<AndroidResource Include="Resources\drawable\ic_notification.xml">
|
||||
<SubType></SubType>
|
||||
<Generator></Generator>
|
||||
</AndroidResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\splash_screen.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\App\App.csproj">
|
||||
<Project>{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}</Project>
|
||||
<Name>App</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Core\Core.csproj">
|
||||
<Project>{4b8a8c41-9820-4341-974c-41e65b7f4366}</Project>
|
||||
<Name>Core</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\xml\accessibilityservice.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\xml\autofillservice.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\xml\filepaths.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\xml\network_security_config.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\values\strings.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\values\ic_launcher_background.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\layout\autofill_listitem.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\yubikey.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\yubikey.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\yubikey.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\slider_thumb.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\splash_screen_dark.xml">
|
||||
<Generator>MSBuild:UpdateGeneratedFiles</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\values\dimens.xml">
|
||||
<Generator>MSBuild:UpdateGeneratedFiles</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\xml\app_restrictions.xml">
|
||||
<Generator>MSBuild:UpdateGeneratedFiles</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Resources\values-v30\" />
|
||||
<Folder Include="Resources\drawable-v26\" />
|
||||
<Folder Include="Resources\drawable-night-v26\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace Bit.Droid
|
||||
{
|
||||
public static class Constants
|
||||
{
|
||||
public const string PACKAGE_NAME = "com.x8bit.bitwarden";
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
using Android.Graphics.Drawables;
|
||||
using Bit.Droid.Effects;
|
||||
using Bit.Droid.Utilities;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportEffect(typeof(FabShadowEffect), "FabShadowEffect")]
|
||||
namespace Bit.Droid.Effects
|
||||
{
|
||||
public class FabShadowEffect : PlatformEffect
|
||||
{
|
||||
protected override void OnAttached ()
|
||||
{
|
||||
if (Control is Android.Widget.Button button)
|
||||
{
|
||||
var gd = new GradientDrawable();
|
||||
gd.SetColor(ThemeHelpers.FabColor);
|
||||
gd.SetCornerRadius(100);
|
||||
|
||||
button.SetBackground(gd);
|
||||
button.Elevation = 6;
|
||||
button.TranslationZ = 20;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDetached ()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
using Android.Widget;
|
||||
using Bit.Droid.Effects;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportEffect(typeof(FixedSizeEffect), "FixedSizeEffect")]
|
||||
namespace Bit.Droid.Effects
|
||||
{
|
||||
public class FixedSizeEffect : PlatformEffect
|
||||
{
|
||||
protected override void OnAttached()
|
||||
{
|
||||
if (Element is Label label && Control is TextView textView)
|
||||
{
|
||||
textView.SetTextSize(Android.Util.ComplexUnitType.Pt, (float)label.FontSize);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDetached()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
using Android.Widget;
|
||||
using Bit.Droid.Effects;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportEffect(typeof(RemoveFontPaddingEffect), nameof(RemoveFontPaddingEffect))]
|
||||
namespace Bit.Droid.Effects
|
||||
{
|
||||
public class RemoveFontPaddingEffect : PlatformEffect
|
||||
{
|
||||
protected override void OnAttached()
|
||||
{
|
||||
if (Control is TextView textView)
|
||||
{
|
||||
textView.SetIncludeFontPadding(false);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDetached()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
using Android.Views;
|
||||
using Bit.Droid.Effects;
|
||||
using Google.Android.Material.BottomNavigation;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ResolutionGroupName("Bitwarden")]
|
||||
[assembly: ExportEffect(typeof(TabBarEffect), "TabBarEffect")]
|
||||
namespace Bit.Droid.Effects
|
||||
{
|
||||
public class TabBarEffect : PlatformEffect
|
||||
{
|
||||
protected override void OnAttached()
|
||||
{
|
||||
if (!(Container.GetChildAt(0) is ViewGroup layout))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!(layout.GetChildAt(1) is BottomNavigationView bottomNavigationView))
|
||||
{
|
||||
return;
|
||||
}
|
||||
bottomNavigationView.LabelVisibilityMode = LabelVisibilityMode.LabelVisibilityLabeled;
|
||||
}
|
||||
|
||||
protected override void OnDetached()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("BitwardenAndroid")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Bitwarden Inc.")]
|
||||
[assembly: AssemblyProduct("Bitwarden")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -1,69 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
using Android.Content;
|
||||
using Android.Content.Res;
|
||||
using Android.Views.InputMethods;
|
||||
using Bit.Droid.Renderers;
|
||||
using Bit.Droid.Utilities;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(Editor), typeof(CustomEditorRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class CustomEditorRenderer : EditorRenderer
|
||||
{
|
||||
public CustomEditorRenderer(Context context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
// Workaround for issue described here:
|
||||
// https://github.com/xamarin/Xamarin.Forms/issues/8291#issuecomment-617456651
|
||||
protected override void OnAttachedToWindow()
|
||||
{
|
||||
base.OnAttachedToWindow();
|
||||
EditText.Enabled = false;
|
||||
EditText.Enabled = true;
|
||||
}
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
UpdateBorderColor();
|
||||
if (Control != null && e.NewElement != null)
|
||||
{
|
||||
Control.SetPadding(Control.PaddingLeft, Control.PaddingTop - 10, Control.PaddingRight,
|
||||
Control.PaddingBottom + 20);
|
||||
Control.ImeOptions = Control.ImeOptions | (ImeAction)ImeFlags.NoPersonalizedLearning |
|
||||
(ImeAction)ImeFlags.NoExtractUi;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
|
||||
if (e.PropertyName == Entry.TextColorProperty.PropertyName)
|
||||
{
|
||||
UpdateBorderColor();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateBorderColor()
|
||||
{
|
||||
if (Control != null)
|
||||
{
|
||||
var states = new[]
|
||||
{
|
||||
new[] { Android.Resource.Attribute.StateFocused }, // focused
|
||||
new[] { -Android.Resource.Attribute.StateFocused }, // unfocused
|
||||
};
|
||||
var colors = new int[]
|
||||
{
|
||||
ThemeHelpers.PrimaryColor,
|
||||
ThemeHelpers.MutedColor
|
||||
};
|
||||
Control.BackgroundTintList = new ColorStateList(states, colors);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
using Android.Content;
|
||||
using Android.Content.Res;
|
||||
using Android.Graphics;
|
||||
using Android.Text;
|
||||
using Android.Views.InputMethods;
|
||||
using Android.Widget;
|
||||
using Bit.Droid.Renderers;
|
||||
using Bit.Droid.Utilities;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(Entry), typeof(CustomEntryRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class CustomEntryRenderer : EntryRenderer
|
||||
{
|
||||
public CustomEntryRenderer(Context context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
UpdateBorderColor();
|
||||
if (Control != null && e.NewElement != null)
|
||||
{
|
||||
Control.SetPadding(Control.PaddingLeft, Control.PaddingTop - 10, Control.PaddingRight,
|
||||
Control.PaddingBottom + 20);
|
||||
Control.ImeOptions = Control.ImeOptions | (ImeAction)ImeFlags.NoPersonalizedLearning |
|
||||
(ImeAction)ImeFlags.NoExtractUi;
|
||||
}
|
||||
}
|
||||
|
||||
// Workaround for bug preventing long-press -> copy/paste on Android 11
|
||||
// See https://issuetracker.google.com/issues/37095917
|
||||
protected override void OnAttachedToWindow()
|
||||
{
|
||||
base.OnAttachedToWindow();
|
||||
Control.Enabled = false;
|
||||
Control.Enabled = true;
|
||||
}
|
||||
|
||||
// Workaround for failure to disable text prediction on non-password fields
|
||||
// see https://github.com/xamarin/Xamarin.Forms/issues/10857
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
|
||||
// Check if changed property is "IsPassword", otherwise ignore
|
||||
if (e.PropertyName == Entry.IsPasswordProperty.PropertyName)
|
||||
{
|
||||
// Check if field type is text, otherwise ignore (numeric passwords, etc.)
|
||||
EditText.InputType = Element.Keyboard.ToInputType();
|
||||
bool isText = (EditText.InputType & InputTypes.ClassText) == InputTypes.ClassText,
|
||||
isNumber = (EditText.InputType & InputTypes.ClassNumber) == InputTypes.ClassNumber;
|
||||
if (isText || isNumber)
|
||||
{
|
||||
if (Element.IsPassword)
|
||||
{
|
||||
// Element is a password field, set inputType to TextVariationPassword which disables
|
||||
// predictive text by default
|
||||
EditText.InputType = EditText.InputType |
|
||||
(isText ? InputTypes.TextVariationPassword : InputTypes.NumberVariationPassword);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Element is not a password field, set inputType to TextVariationVisiblePassword to
|
||||
// disable predictive text while still displaying the content.
|
||||
EditText.InputType = EditText.InputType |
|
||||
(isText ? InputTypes.TextVariationVisiblePassword : InputTypes.NumberVariationNormal);
|
||||
}
|
||||
|
||||
// The workaround above forces a reset of the style properties, so we need to re-apply the font.
|
||||
// see https://xamarin.github.io/bugzilla-archives/33/33666/bug.html
|
||||
var typeface = Typeface.CreateFromAsset(Context.Assets, "RobotoMono_Regular.ttf");
|
||||
if (Control is TextView label)
|
||||
{
|
||||
label.Typeface = typeface;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (e.PropertyName == Entry.TextColorProperty.PropertyName)
|
||||
{
|
||||
UpdateBorderColor();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateBorderColor()
|
||||
{
|
||||
if (Control != null)
|
||||
{
|
||||
var states = new[]
|
||||
{
|
||||
new[] { Android.Resource.Attribute.StateFocused }, // focused
|
||||
new[] { -Android.Resource.Attribute.StateFocused }, // unfocused
|
||||
};
|
||||
var colors = new int[]
|
||||
{
|
||||
ThemeHelpers.PrimaryColor,
|
||||
ThemeHelpers.MutedColor
|
||||
};
|
||||
Control.BackgroundTintList = new ColorStateList(states, colors);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
using System;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using AndroidX.AppCompat.Widget;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Droid.Renderers;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(ContentPage), typeof(CustomPageRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class CustomPageRenderer : PageRenderer
|
||||
{
|
||||
public CustomPageRenderer(Context context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
|
||||
Activity context = (Activity)this.Context;
|
||||
var toolbar = context.FindViewById<Toolbar>(Resource.Id.toolbar);
|
||||
if(toolbar != null)
|
||||
{
|
||||
toolbar.NavigationContentDescription = AppResources.TapToGoBack;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
using Android.Content;
|
||||
using Android.Content.Res;
|
||||
using Bit.Droid.Renderers;
|
||||
using Bit.Droid.Utilities;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(Picker), typeof(CustomPickerRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class CustomPickerRenderer : PickerRenderer
|
||||
{
|
||||
public CustomPickerRenderer(Context context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
UpdateBorderColor();
|
||||
if (Control != null && e.NewElement != null)
|
||||
{
|
||||
Control.SetPadding(Control.PaddingLeft, Control.PaddingTop - 10, Control.PaddingRight,
|
||||
Control.PaddingBottom + 20);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
|
||||
if (e.PropertyName == Picker.TextColorProperty.PropertyName)
|
||||
{
|
||||
UpdateBorderColor();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateBorderColor()
|
||||
{
|
||||
if (Control != null)
|
||||
{
|
||||
var states = new[]
|
||||
{
|
||||
new[] { Android.Resource.Attribute.StateFocused }, // focused
|
||||
new[] { -Android.Resource.Attribute.StateFocused }, // unfocused
|
||||
};
|
||||
var colors = new int[]
|
||||
{
|
||||
ThemeHelpers.PrimaryColor,
|
||||
ThemeHelpers.MutedColor
|
||||
};
|
||||
Control.BackgroundTintList = new ColorStateList(states, colors);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
using Android.Content;
|
||||
using Android.Views.InputMethods;
|
||||
using Bit.Droid.Renderers;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(SearchBar), typeof(CustomSearchBarRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class CustomSearchBarRenderer : SearchBarRenderer
|
||||
{
|
||||
public CustomSearchBarRenderer(Context context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
if (Control != null && e.NewElement != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var magId = Resources.GetIdentifier("android:id/search_mag_icon", null, null);
|
||||
var magImage = (Android.Widget.ImageView)Control.FindViewById(magId);
|
||||
magImage.LayoutParameters = new Android.Widget.LinearLayout.LayoutParams(0, 0);
|
||||
}
|
||||
catch { }
|
||||
Control.SetImeOptions(Control.ImeOptions | (ImeAction)ImeFlags.NoPersonalizedLearning |
|
||||
(ImeAction)ImeFlags.NoExtractUi);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
using Android.Content;
|
||||
using Android.Content.Res;
|
||||
using Android.Graphics.Drawables;
|
||||
using Android.OS;
|
||||
using AndroidX.Core.Content.Resources;
|
||||
using Bit.Droid.Renderers;
|
||||
using Bit.Droid.Utilities;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(Switch), typeof(CustomSwitchRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class CustomSwitchRenderer : SwitchRenderer
|
||||
{
|
||||
public CustomSwitchRenderer(Context context)
|
||||
: base(context)
|
||||
{}
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Switch> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
UpdateColors();
|
||||
}
|
||||
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
|
||||
if (e.PropertyName == Switch.OnColorProperty.PropertyName)
|
||||
{
|
||||
UpdateColors();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateColors()
|
||||
{
|
||||
if (Build.VERSION.SdkInt <= BuildVersionCodes.LollipopMr1)
|
||||
{
|
||||
// Android 5.x doesn't support ThumbTintList, and using SwitchCompat on every version after 5.x
|
||||
// doesn't apply tinting the way we want. Let 5.x to do its own thing here.
|
||||
return;
|
||||
}
|
||||
if (Control != null)
|
||||
{
|
||||
Control.SetHintTextColor(ThemeHelpers.MutedColor);
|
||||
var t = ResourcesCompat.GetDrawable(Resources, Resource.Drawable.switch_thumb, null);
|
||||
if (t is GradientDrawable thumb)
|
||||
{
|
||||
Control.ThumbDrawable = thumb;
|
||||
}
|
||||
var thumbStates = new[]
|
||||
{
|
||||
new[] { Android.Resource.Attribute.StateChecked }, // checked
|
||||
new[] { -Android.Resource.Attribute.StateChecked }, // unchecked
|
||||
};
|
||||
var thumbColors = new int[]
|
||||
{
|
||||
ThemeHelpers.SwitchOnColor,
|
||||
ThemeHelpers.SwitchThumbColor
|
||||
};
|
||||
Control.ThumbTintList = new ColorStateList(thumbStates, thumbColors);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
using Android.Content;
|
||||
using Android.Views;
|
||||
using Bit.App.Pages;
|
||||
using Bit.Droid.Renderers;
|
||||
using Google.Android.Material.BottomNavigation;
|
||||
using Google.Android.Material.Navigation;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
using Xamarin.Forms.Platform.Android.AppCompat;
|
||||
|
||||
[assembly: ExportRenderer(typeof(TabbedPage), typeof(CustomTabbedRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class CustomTabbedRenderer : TabbedPageRenderer, NavigationBarView.IOnItemReselectedListener
|
||||
{
|
||||
private TabbedPage _page;
|
||||
|
||||
public CustomTabbedRenderer(Context context) : base(context) { }
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
if (e.NewElement != null)
|
||||
{
|
||||
_page = e.NewElement;
|
||||
GetBottomNavigationView()?.SetOnItemReselectedListener(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
_page = e.OldElement;
|
||||
}
|
||||
}
|
||||
|
||||
private BottomNavigationView GetBottomNavigationView()
|
||||
{
|
||||
for (var i = 0; i < ViewGroup.ChildCount; i++)
|
||||
{
|
||||
var childView = ViewGroup.GetChildAt(i);
|
||||
if (childView is ViewGroup viewGroup)
|
||||
{
|
||||
for (var j = 0; j < viewGroup.ChildCount; j++)
|
||||
{
|
||||
var childRelativeLayoutView = viewGroup.GetChildAt(j);
|
||||
if (childRelativeLayoutView is BottomNavigationView bottomNavigationView)
|
||||
{
|
||||
return bottomNavigationView;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void OnNavigationItemReselected(IMenuItem item)
|
||||
{
|
||||
if (_page?.CurrentPage?.Navigation != null && _page.CurrentPage.Navigation.NavigationStack.Count > 0)
|
||||
{
|
||||
if (_page is TabsPage tabsPage)
|
||||
{
|
||||
tabsPage.OnPageReselected();
|
||||
}
|
||||
Device.BeginInvokeOnMainThread(async () => await _page.CurrentPage.Navigation.PopToRootAsync());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
using Android.Content;
|
||||
using Android.Views;
|
||||
using Bit.App.Controls;
|
||||
using Bit.Droid.Renderers;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportRenderer(typeof(ExtendedDatePicker), typeof(ExtendedDatePickerRenderer))]
|
||||
namespace Bit.Droid.Renderers
|
||||
{
|
||||
public class ExtendedDatePickerRenderer : DatePickerRenderer
|
||||
{
|
||||
public ExtendedDatePickerRenderer(Context context)
|
||||
: base(context) { }
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
if (Control != null && Element is ExtendedDatePicker element)
|
||||
{
|
||||
// center text
|
||||
Control.Gravity = GravityFlags.CenterHorizontal;
|
||||
|
||||
// use placeholder until NullableDate set
|
||||
if (!element.NullableDate.HasValue)
|
||||
{
|
||||
Control.Text = element.PlaceHolder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == DatePicker.DateProperty.PropertyName ||
|
||||
e.PropertyName == DatePicker.FormatProperty.PropertyName)
|
||||
{
|
||||
if (Control != null && Element is ExtendedDatePicker element)
|
||||
{
|
||||
if (Element.Format == element.PlaceHolder)
|
||||
{
|
||||
Control.Text = element.PlaceHolder;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user